From 4d476fe94a407614e0f8ed1703678aa22fa7dbad Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Nov 30 2017 13:45:37 +0000 Subject: import autofs-5.0.7-70.el7_4.1 --- diff --git a/.autofs.metadata b/.autofs.metadata new file mode 100644 index 0000000..db485ac --- /dev/null +++ b/.autofs.metadata @@ -0,0 +1 @@ +b2604cbd78ed7a854cb434061a7c37e84a984870 SOURCES/autofs-5.0.7.tar.bz2 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1547ad7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +SOURCES/autofs-5.0.7.tar.bz2 diff --git a/README.md b/README.md deleted file mode 100644 index 0e7897f..0000000 --- a/README.md +++ /dev/null @@ -1,5 +0,0 @@ -The master branch has no content - -Look at the c7 branch if you are working with CentOS-7, or the c4/c5/c6 branch for CentOS-4, 5 or 6 - -If you find this file in a distro specific branch, it means that no content has been checked in yet diff --git a/SOURCES/autofs-5.0.6-fix-recursive-mount-deadlock.patch b/SOURCES/autofs-5.0.6-fix-recursive-mount-deadlock.patch new file mode 100644 index 0000000..e6549a7 --- /dev/null +++ b/SOURCES/autofs-5.0.6-fix-recursive-mount-deadlock.patch @@ -0,0 +1,78 @@ +autofs-5.0.6 - fix recursive mount deadlock + +From: Ian Kent + +Prior to the vfs-automount changes that went into 2.6.38 +and were finalized in 3.1 it was not possible to block +path walks into multi-mounts whose root was covered by +another mount. To deal with that a write lock was used +to ensure the mount tree construction was completed. This +restricts the types of recursively defined mount maps that +can be used and can lead to a deadlock during lookup. + +Now that we can prevent processes walking into multi-mounts +that are under construction we no longer need to use a +write lock. + +Also, in the patch below, a cache writelock is changed to +a read lock because a write lock isn't needed since the +map cache entry isn't being updated. +--- + + CHANGELOG | 1 + + daemon/direct.c | 14 ++++++++++++-- + 2 files changed, 13 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 936c9ab..9cdad6e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -12,6 +12,7 @@ + - configure.in: allow cross compilation. + - README: update mailing list subscription info. + - allow non root user to check status. ++- fix recursive mount deadlock. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/daemon/direct.c b/daemon/direct.c +index 7e2f0d7..3e09c5d 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1285,6 +1285,8 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + struct timespec wait; + struct timeval now; + int ioctlfd, len, state; ++ unsigned int kver_major = get_kver_major(); ++ unsigned int kver_minor = get_kver_minor(); + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state); + +@@ -1297,8 +1299,16 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + * cache entry we will not be able to find the mapent. So + * we must take the source writelock to ensure the parent + * has mount is complete before we look for the entry. ++ * ++ * Since the vfs-automount kernel changes we can now block ++ * on covered mounts during mount tree construction so a ++ * write lock is no longer needed. So we now can handle a ++ * wider class of recursively define mount lookups. + */ +- master_source_writelock(ap->entry); ++ if (kver_major > 5 || (kver_major == 5 && kver_minor > 1)) ++ master_source_readlock(ap->entry); ++ else ++ master_source_writelock(ap->entry); + map = ap->entry->maps; + while (map) { + /* +@@ -1311,7 +1321,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + } + + mc = map->mc; +- cache_writelock(mc); ++ cache_readlock(mc); + me = cache_lookup_ino(mc, pkt->dev, pkt->ino); + if (me) + break; diff --git a/SOURCES/autofs-5.0.6-increase-file-map-read-buffer-size.patch b/SOURCES/autofs-5.0.6-increase-file-map-read-buffer-size.patch new file mode 100644 index 0000000..39b2221 --- /dev/null +++ b/SOURCES/autofs-5.0.6-increase-file-map-read-buffer-size.patch @@ -0,0 +1,38 @@ +autofs-5.0.6 - increase file map read buffer size + +From: Ian Kent + +The file map entry read buffer can be too small for larger +multi-mount map entries so increase it. +--- + + CHANGELOG | 1 + + include/automount.h | 2 +- + 2 files changed, 2 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 9cdad6e..3bdf8a4 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -13,6 +13,7 @@ + - README: update mailing list subscription info. + - allow non root user to check status. + - fix recursive mount deadlock. ++- increase file map read buffer size. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/include/automount.h b/include/automount.h +index 561fcc2..37541f5 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -233,7 +233,7 @@ int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev); + #define AUTOFS_LOOKUP_VERSION 5 + + #define KEY_MAX_LEN NAME_MAX +-#define MAPENT_MAX_LEN 4095 ++#define MAPENT_MAX_LEN 16384 + #define PARSE_MAX_BUF KEY_MAX_LEN + MAPENT_MAX_LEN + 2 + + int lookup_nss_read_master(struct master *master, time_t age); diff --git a/SOURCES/autofs-5.0.7-README-update-mailing-list-subscription-info.patch b/SOURCES/autofs-5.0.7-README-update-mailing-list-subscription-info.patch new file mode 100644 index 0000000..99b6181 --- /dev/null +++ b/SOURCES/autofs-5.0.7-README-update-mailing-list-subscription-info.patch @@ -0,0 +1,56 @@ +autofs-5.0.7 - README: update mailing list subscription info + +From: Chris Packham + +Following the kernel.org compromise the mailing list was moved to +vger.kernel.org. Update the subscription info and add URLs for the gmane +mailing list archive. + +Signed-off-by: Chris Packham +--- + + CHANGELOG | 1 + + README | 17 ++++++++++++++--- + 2 files changed, 15 insertions(+), 3 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index fe801e8..44c9fb2 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -10,6 +10,7 @@ + - fix null map entry order handling. + - make description of default MOUNT_WAIT setting clear. + - configure.in: allow cross compilation. ++- README: update mailing list subscription info. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/README b/README +index cef16a9..9024e64 100644 +--- a/README ++++ b/README +@@ -43,9 +43,20 @@ Fitzhardinge's work on autofs 3. Further enhancements + have been made by Ian Kent . + + If you use or want to help develop autofs, please join the autofs +-mailing list by visiting: ++mailing list by sending an email to: + +- http://linux.kernel.org/mailman/listinfo/autofs ++ majordomo@vger.kernel.org + +-and folling the instructions there to subscribe to the autofs mailing list. ++With the body text: ++ ++ subscribe autofs ++ ++Once subscribed you can send patches to: ++ ++ autofs@vger.kernel.org ++ ++The autofs mailing list archive can be viewed on gmane: ++ ++ http://news.gmane.org/gmane.linux.kernel.autofs ++ http://blog.gmane.org/gmane.linux.kernel.autofs + diff --git a/SOURCES/autofs-5.0.7-add-after-sssd-dependency-to-unit-file.patch b/SOURCES/autofs-5.0.7-add-after-sssd-dependency-to-unit-file.patch new file mode 100644 index 0000000..5d7d1c2 --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-after-sssd-dependency-to-unit-file.patch @@ -0,0 +1,35 @@ +autofs-5.0.7 - add after sssd dependency to unit file + +From: Ian Kent + +When using sss as a map source autofs can sometimes start before +sssd is ready. +--- + CHANGELOG | 1 + + samples/autofs.service.in | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 7749f01..2734fe3 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -55,6 +55,7 @@ + - fix add null check in parse_server_string(). + - don't override LDFLAGS in make rules. + - fix a couple of compiler warnings. ++- add after sssd dependency to unit file. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/samples/autofs.service.in b/samples/autofs.service.in +index 056ab5e..777463d 100644 +--- a/samples/autofs.service.in ++++ b/samples/autofs.service.in +@@ -1,6 +1,6 @@ + [Unit] + Description=Automounts filesystems on demand +-After=network.target ypbind.service ++After=network.target ypbind.service sssd.service + + [Service] + Type=forking diff --git a/SOURCES/autofs-5.0.7-add-changlog-entry-for-coverity-fixes.patch b/SOURCES/autofs-5.0.7-add-changlog-entry-for-coverity-fixes.patch new file mode 100644 index 0000000..a628512 --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-changlog-entry-for-coverity-fixes.patch @@ -0,0 +1,48 @@ +autofs-5.0.7 - add changlog entry for coverity fixes + +From: Ian Kent + +A bunch of changes have been made based on a Covarity report. +Mostly I pust the changes into seperate patches so they can be kept simple. + +Changes: +- fix fcntl return check. +- fix spawn_umount() return check in mount_bind.c:lookup_init(). +- fix check mkdir_path() in mount_bind.c:mount_mount(). +- fix incorrect var name in test. +- remove debug only code in alarm.c. +- fix inconsistent use of cache lock in handle_packet_missing_direct(). +- fix several off by one errors. +- fix memory leak in get_dc_list(). +- fix host_addr null reference in add_new_host(). +- add null check in read_one(). +- add pgrp check in do_spawn(). +- fix inconsistent signed usage for __rpc_ping(). +- add null check in extract_version(). +- recheck valid map entry lookup return in do_readmap_mount(). +- add null check in parse_server_string(). +- add map entry null check in do_expire_direct(). +- add mapent null check in lookup_nisplus.c:lookup_mount(). +- fix potential null dereference in lookup_mount(). +- fix leaked ldap percent hack allocation in lookup_one(). +- fix incorrect value reference in parse_line(). +- add debug alert for waitpid in check_nfs_mount_version(). +- add initialization of bind_result in-do_sasl_bind(). +- fix incorrect check in flag_is_owned(). +- fix possible use after free in lookup_dir.c:lookup_init(). +--- + CHANGELOG | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 48e9806..25179b1 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -49,6 +49,7 @@ + - fix master map bogus keywork match. + - fix fix map entry duplicate offset detection. + - probe each nfs version in turn for singleton mounts. ++- add changlog entry for coverity fixes. + + 25/07/2012 autofs-5.0.7 + ======================= diff --git a/SOURCES/autofs-5.0.7-add-debug-alert-for-waitpid-in-check_nfs_mount_version.patch b/SOURCES/autofs-5.0.7-add-debug-alert-for-waitpid-in-check_nfs_mount_version.patch new file mode 100644 index 0000000..e8c239e --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-debug-alert-for-waitpid-in-check_nfs_mount_version.patch @@ -0,0 +1,24 @@ +autofs-5.0.7 - add debug alert for waitpid in check_nfs_mount_version() + +From: Ian Kent + +We don't really case if there's no process to wait for but add a debug +log alert for information. +--- + lib/mounts.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/mounts.c b/lib/mounts.c +index 7b959b8..a6f560e 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -287,7 +287,8 @@ int check_nfs_mount_version(struct nfs_mount_vers *vers, + ret = 0; + } + +- if (waitpid(f, &status, 0) != f) ; ++ if (waitpid(f, &status, 0) != f) ++ debug(LOGOPT_NONE, "no process found to wait for"); + + pthread_sigmask(SIG_SETMASK, &oldsig, NULL); + pthread_setcancelstate(cancel_state, NULL); diff --git a/SOURCES/autofs-5.0.7-add-enable-sloppy-mount-option-to-configure.patch b/SOURCES/autofs-5.0.7-add-enable-sloppy-mount-option-to-configure.patch new file mode 100644 index 0000000..c6dd8d5 --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-enable-sloppy-mount-option-to-configure.patch @@ -0,0 +1,691 @@ +autofs-5.0.7 - add enable sloppy mount option to configure + +From: Ian Kent + +Add an option --enable-sloppy-mount or --disable-sloppy-mount to force +or prevent the use of the -s option to mount, thus avoiding the +autodetection. This can be useful in setups where executing mount +might be undesirable, particularly in packaging environments. + +2013-04-04 Martin von Gagern + +References: + * https://bugs.gentoo.org/453778 +--- + CHANGELOG | 1 + aclocal.m4 | 2 + configure | 252 +++++++++++++++++++++++++++++++--------------------------- + configure.in | 10 ++ + 4 files changed, 146 insertions(+), 119 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 61edddf..66c11de 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -42,6 +42,7 @@ + - fix submount tree not all expiring. + - make dump maps check for duplicate indirect mounts. + - document allowed map sources in auto.master. ++- add enable sloppy mount option to configure. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/aclocal.m4 b/aclocal.m4 +index 47bca0c..c5de159 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -66,7 +66,7 @@ AC_DEFUN(AF_SLOPPY_MOUNT, + [if test -n "$MOUNT" ; then + AC_MSG_CHECKING([if mount accepts the -s option]) + if "$MOUNT" -s > /dev/null 2>&1 ; then +- AC_DEFINE(HAVE_SLOPPY_MOUNT, 1, [define if the mount command supports the -s option]) ++ enable_sloppy_mount=yes + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) +diff --git a/configure b/configure +index c1423d8..08b7ccc 100755 +--- a/configure ++++ b/configure +@@ -1,11 +1,9 @@ + #! /bin/sh + # Guess values for system-dependent variables and create Makefiles. +-# Generated by GNU Autoconf 2.68. ++# Generated by GNU Autoconf 2.69. + # + # +-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software +-# Foundation, Inc. ++# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. + # + # + # This configure script is free software; the Free Software Foundation +@@ -134,6 +132,31 @@ export LANGUAGE + # CDPATH. + (unset CDPATH) >/dev/null 2>&1 && unset CDPATH + ++# Use a proper internal environment variable to ensure we don't fall ++ # into an infinite loop, continuously re-executing ourselves. ++ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then ++ _as_can_reexec=no; export _as_can_reexec; ++ # We cannot yet assume a decent shell, so we have to provide a ++# neutralization value for shells without unset; and this also ++# works around shells that cannot unset nonexistent variables. ++# Preserve -v and -x to the replacement shell. ++BASH_ENV=/dev/null ++ENV=/dev/null ++(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV ++case $- in # (((( ++ *v*x* | *x*v* ) as_opts=-vx ;; ++ *v* ) as_opts=-v ;; ++ *x* ) as_opts=-x ;; ++ * ) as_opts= ;; ++esac ++exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} ++# Admittedly, this is quite paranoid, since all the known shells bail ++# out after a failed `exec'. ++$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 ++as_fn_exit 255 ++ fi ++ # We don't want this to propagate to other subprocesses. ++ { _as_can_reexec=; unset _as_can_reexec;} + if test "x$CONFIG_SHELL" = x; then + as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : + emulate sh +@@ -167,7 +190,8 @@ if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : + else + exitcode=1; echo positional parameters were not saved. + fi +-test x\$exitcode = x0 || exit 1" ++test x\$exitcode = x0 || exit 1 ++test -x / || exit 1" + as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO + as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO + eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && +@@ -212,21 +236,25 @@ IFS=$as_save_IFS + + + if test "x$CONFIG_SHELL" != x; then : +- # We cannot yet assume a decent shell, so we have to provide a +- # neutralization value for shells without unset; and this also +- # works around shells that cannot unset nonexistent variables. +- # Preserve -v and -x to the replacement shell. +- BASH_ENV=/dev/null +- ENV=/dev/null +- (unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV +- export CONFIG_SHELL +- case $- in # (((( +- *v*x* | *x*v* ) as_opts=-vx ;; +- *v* ) as_opts=-v ;; +- *x* ) as_opts=-x ;; +- * ) as_opts= ;; +- esac +- exec "$CONFIG_SHELL" $as_opts "$as_myself" ${1+"$@"} ++ export CONFIG_SHELL ++ # We cannot yet assume a decent shell, so we have to provide a ++# neutralization value for shells without unset; and this also ++# works around shells that cannot unset nonexistent variables. ++# Preserve -v and -x to the replacement shell. ++BASH_ENV=/dev/null ++ENV=/dev/null ++(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV ++case $- in # (((( ++ *v*x* | *x*v* ) as_opts=-vx ;; ++ *v* ) as_opts=-v ;; ++ *x* ) as_opts=-x ;; ++ * ) as_opts= ;; ++esac ++exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} ++# Admittedly, this is quite paranoid, since all the known shells bail ++# out after a failed `exec'. ++$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 ++exit 255 + fi + + if test x$as_have_required = xno; then : +@@ -328,6 +356,14 @@ $as_echo X"$as_dir" | + + + } # as_fn_mkdir_p ++ ++# as_fn_executable_p FILE ++# ----------------------- ++# Test if FILE is an executable regular file. ++as_fn_executable_p () ++{ ++ test -f "$1" && test -x "$1" ++} # as_fn_executable_p + # as_fn_append VAR VALUE + # ---------------------- + # Append the text in VALUE to the end of the definition contained in VAR. Take +@@ -449,6 +485,10 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits + chmod +x "$as_me.lineno" || + { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } + ++ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have ++ # already done that, so ensure we don't try to do so again and fall ++ # in an infinite loop. This has already happened in practice. ++ _as_can_reexec=no; export _as_can_reexec + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). +@@ -483,16 +523,16 @@ if (echo >conf$$.file) 2>/dev/null; then + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. +- # In both cases, we have to default to `cp -p'. ++ # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || +- as_ln_s='cp -p' ++ as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else +- as_ln_s='cp -p' ++ as_ln_s='cp -pR' + fi + else +- as_ln_s='cp -p' ++ as_ln_s='cp -pR' + fi + rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file + rmdir conf$$.dir 2>/dev/null +@@ -504,28 +544,8 @@ else + as_mkdir_p=false + fi + +-if test -x / >/dev/null 2>&1; then +- as_test_x='test -x' +-else +- if ls -dL / >/dev/null 2>&1; then +- as_ls_L_option=L +- else +- as_ls_L_option= +- fi +- as_test_x=' +- eval sh -c '\'' +- if test -d "$1"; then +- test -d "$1/."; +- else +- case $1 in #( +- -*)set "./$1";; +- esac; +- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( +- ???[sx]*):;;*)false;;esac;fi +- '\'' sh +- ' +-fi +-as_executable_p=$as_test_x ++as_test_x='test -x' ++as_executable_p=as_fn_executable_p + + # Sed expression to map a string onto a valid CPP name. + as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +@@ -715,6 +735,7 @@ with_fifodir + with_flagdir + with_libtirpc + with_dmalloc ++enable_sloppy_mount + with_hesiod + with_openldap + with_sasl +@@ -1187,8 +1208,6 @@ target=$target_alias + if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe +- $as_echo "$as_me: WARNING: if you wanted to set the --build type, don't use --host. +- If a cross compiler is detected then cross compile mode will be used" >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +@@ -1341,6 +1360,7 @@ Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] ++ --enable-sloppy-mount enable the use of the -s option to mount + --disable-ext-env disable search in environment for substitution variable + --disable-mount-locking disable use of locking when spawning mount command + --enable-force-shutdown enable USR1 signal to force unlink umount of any +@@ -1442,9 +1462,9 @@ test -n "$ac_init_help" && exit $ac_status + if $ac_init_version; then + cat <<\_ACEOF + configure +-generated by GNU Autoconf 2.68 ++generated by GNU Autoconf 2.69 + +-Copyright (C) 2010 Free Software Foundation, Inc. ++Copyright (C) 2012 Free Software Foundation, Inc. + This configure script is free software; the Free Software Foundation + gives unlimited permission to copy, distribute and modify it. + _ACEOF +@@ -1520,7 +1540,7 @@ $as_echo "$ac_try_echo"; } >&5 + test ! -s conftest.err + } && test -s conftest$ac_exeext && { + test "$cross_compiling" = yes || +- $as_test_x conftest$ac_exeext ++ test -x conftest$ac_exeext + }; then : + ac_retval=0 + else +@@ -1740,7 +1760,7 @@ This file contains any messages produced by compilers while + running configure, to aid debugging if configure makes a mistake. + + It was created by $as_me, which was +-generated by GNU Autoconf 2.68. Invocation command line was ++generated by GNU Autoconf 2.69. Invocation command line was + + $ $0 $@ + +@@ -2324,7 +2344,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -2364,7 +2384,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -2417,7 +2437,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -2458,7 +2478,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue +@@ -2516,7 +2536,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -2560,7 +2580,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3006,8 +3026,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + #include + #include +-#include +-#include ++struct stat; + /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ + struct buf { int x; }; + FILE * (*rcsopen) (struct buf *, struct stat *, int); +@@ -3209,7 +3228,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MOUNT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3269,7 +3288,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MOUNT_NFS="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3329,7 +3348,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_UMOUNT="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3389,7 +3408,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_E2FSCK="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3448,7 +3467,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_E3FSCK="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3507,7 +3526,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_E4FSCK="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3566,7 +3585,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_MODPROBE="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3626,7 +3645,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_LEX="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3682,7 +3701,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_YACC="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3738,7 +3757,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_RANLIB="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3794,7 +3813,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_RPCGEN="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3858,13 +3877,19 @@ fi + # Newer mounts have the -s (sloppy) option to ignore unknown options, + # good for portability + # +-if test -n "$MOUNT" ; then ++# Check whether --enable-sloppy-mount was given. ++if test "${enable_sloppy_mount+set}" = set; then : ++ enableval=$enable_sloppy_mount; ++else ++ enable_sloppy_mount=auto ++fi ++ ++if test x$enable_sloppy_mount = xauto; then ++ if test -n "$MOUNT" ; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking if mount accepts the -s option" >&5 + $as_echo_n "checking if mount accepts the -s option... " >&6; } + if "$MOUNT" -s > /dev/null 2>&1 ; then +- +-$as_echo "#define HAVE_SLOPPY_MOUNT 1" >>confdefs.h +- ++ enable_sloppy_mount=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 + $as_echo "yes" >&6; } + else +@@ -3872,6 +3897,12 @@ $as_echo "yes" >&6; } + $as_echo "no" >&6; } + fi + fi ++fi ++if test x$enable_sloppy_mount = xyes; then ++ ++$as_echo "#define HAVE_SLOPPY_MOUNT 1" >>confdefs.h ++ ++fi + + # LDAP SASL auth needs libxml and Kerberos + for ac_prog in xml2-config +@@ -3894,7 +3925,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_XML_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -3969,7 +4000,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_path_KRB5_CONFIG="$as_dir/$ac_word$ac_exec_ext" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -4387,7 +4418,7 @@ do + for ac_prog in grep ggrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" +- { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue ++ as_fn_executable_p "$ac_path_GREP" || continue + # Check for GNU ac_path_GREP and select it if it is found. + # Check for GNU $ac_path_GREP + case `"$ac_path_GREP" --version 2>&1` in +@@ -4453,7 +4484,7 @@ do + for ac_prog in egrep; do + for ac_exec_ext in '' $ac_executable_extensions; do + ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" +- { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue ++ as_fn_executable_p "$ac_path_EGREP" || continue + # Check for GNU ac_path_EGREP and select it if it is found. + # Check for GNU $ac_path_EGREP + case `"$ac_path_EGREP" --version 2>&1` in +@@ -4928,7 +4959,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -4968,7 +4999,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="gcc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -5021,7 +5052,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="${ac_tool_prefix}cc" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -5062,7 +5093,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then + ac_prog_rejected=yes + continue +@@ -5120,7 +5151,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_CC="$ac_tool_prefix$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -5164,7 +5195,7 @@ do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do +- if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ++ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_CC="$ac_prog" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 +@@ -5360,8 +5391,7 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ + #include + #include +-#include +-#include ++struct stat; + /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ + struct buf { int x; }; + FILE * (*rcsopen) (struct buf *, struct stat *, int); +@@ -5882,16 +5912,16 @@ if (echo >conf$$.file) 2>/dev/null; then + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. +- # In both cases, we have to default to `cp -p'. ++ # In both cases, we have to default to `cp -pR'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || +- as_ln_s='cp -p' ++ as_ln_s='cp -pR' + elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln + else +- as_ln_s='cp -p' ++ as_ln_s='cp -pR' + fi + else +- as_ln_s='cp -p' ++ as_ln_s='cp -pR' + fi + rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file + rmdir conf$$.dir 2>/dev/null +@@ -5951,28 +5981,16 @@ else + as_mkdir_p=false + fi + +-if test -x / >/dev/null 2>&1; then +- as_test_x='test -x' +-else +- if ls -dL / >/dev/null 2>&1; then +- as_ls_L_option=L +- else +- as_ls_L_option= +- fi +- as_test_x=' +- eval sh -c '\'' +- if test -d "$1"; then +- test -d "$1/."; +- else +- case $1 in #( +- -*)set "./$1";; +- esac; +- case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #(( +- ???[sx]*):;;*)false;;esac;fi +- '\'' sh +- ' +-fi +-as_executable_p=$as_test_x ++ ++# as_fn_executable_p FILE ++# ----------------------- ++# Test if FILE is an executable regular file. ++as_fn_executable_p () ++{ ++ test -f "$1" && test -x "$1" ++} # as_fn_executable_p ++as_test_x='test -x' ++as_executable_p=as_fn_executable_p + + # Sed expression to map a string onto a valid CPP name. + as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" +@@ -5994,7 +6012,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 + # values after options handling. + ac_log=" + This file was extended by $as_me, which was +-generated by GNU Autoconf 2.68. Invocation command line was ++generated by GNU Autoconf 2.69. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS +@@ -6056,10 +6074,10 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" + ac_cs_version="\\ + config.status +-configured by $0, generated by GNU Autoconf 2.68, ++configured by $0, generated by GNU Autoconf 2.69, + with options \\"\$ac_cs_config\\" + +-Copyright (C) 2010 Free Software Foundation, Inc. ++Copyright (C) 2012 Free Software Foundation, Inc. + This config.status script is free software; the Free Software Foundation + gives unlimited permission to copy, distribute and modify it." + +@@ -6147,7 +6165,7 @@ fi + _ACEOF + cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 + if \$ac_cs_recheck; then +- set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion ++ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion + shift + \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 + CONFIG_SHELL='$SHELL' +diff --git a/configure.in b/configure.in +index 4029375..559045a 100644 +--- a/configure.in ++++ b/configure.in +@@ -157,7 +157,15 @@ AC_SUBST(sssldir) + # Newer mounts have the -s (sloppy) option to ignore unknown options, + # good for portability + # +-AF_SLOPPY_MOUNT() ++AC_ARG_ENABLE(sloppy-mount, ++[ --enable-sloppy-mount enable the use of the -s option to mount],, ++ enable_sloppy_mount=auto) ++if test x$enable_sloppy_mount = xauto; then ++ AF_SLOPPY_MOUNT() ++fi ++if test x$enable_sloppy_mount = xyes; then ++ AC_DEFINE(HAVE_SLOPPY_MOUNT, 1, [define if the mount command supports the -s option]) ++fi + + # LDAP SASL auth needs libxml and Kerberos + AF_CHECK_LIBXML() diff --git a/SOURCES/autofs-5.0.7-add-initialization-of-bind_result-in.patch-do_sasl_bind.patch b/SOURCES/autofs-5.0.7-add-initialization-of-bind_result-in.patch-do_sasl_bind.patch new file mode 100644 index 0000000..0066b9b --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-initialization-of-bind_result-in.patch-do_sasl_bind.patch @@ -0,0 +1,23 @@ +autofs-5.0.7 - add initialization of bind_result in-do_sasl_bind() + +From: Ian Kent + +There is an unlikley code path where bind_result could be used uninitialized +so initialize it so it isn't incorrectly used if it has rubish in it. +--- + modules/cyrus-sasl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/modules/cyrus-sasl.c b/modules/cyrus-sasl.c +index b456333..68f9242 100644 +--- a/modules/cyrus-sasl.c ++++ b/modules/cyrus-sasl.c +@@ -210,7 +210,7 @@ int + do_sasl_bind(unsigned logopt, LDAP *ld, sasl_conn_t *conn, const char **clientout, + unsigned int *clientoutlen, const char *auth_mech, int sasl_result) + { +- int ret, msgid, bind_result; ++ int ret, msgid, bind_result = LDAP_OTHER; + struct berval client_cred, *server_cred, temp_cred; + LDAPMessage *results; + int have_data, expected_data; diff --git a/SOURCES/autofs-5.0.7-add-map-entry-null-check-in-do_expire_direct.patch b/SOURCES/autofs-5.0.7-add-map-entry-null-check-in-do_expire_direct.patch new file mode 100644 index 0000000..165eec5 --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-map-entry-null-check-in-do_expire_direct.patch @@ -0,0 +1,25 @@ +autofs-5.0.7 - add map entry null check in do_expire_direct() + +From: Ian Kent + +Since we've seen a mount failure for this map entry it should exist +but add a null check in case it's been removed while we waited on +the lock. +--- + daemon/direct.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/daemon/direct.c b/daemon/direct.c +index 399ad0a..f85e1b5 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1019,7 +1019,8 @@ static void *do_expire_direct(void *arg) + struct mapent *me; + cache_writelock(mt.mc); + me = cache_lookup_distinct(mt.mc, mt.name); +- me->ioctlfd = -1; ++ if (me) ++ me->ioctlfd = -1; + cache_unlock(mt.mc); + ops->send_ready(ap->logopt, mt.ioctlfd, mt.wait_queue_token); + ops->close(ap->logopt, mt.ioctlfd); diff --git a/SOURCES/autofs-5.0.7-add-mapent-null-check-in-lookup-nisplus-lookup_mount.patch b/SOURCES/autofs-5.0.7-add-mapent-null-check-in-lookup-nisplus-lookup_mount.patch new file mode 100644 index 0000000..9cda9df --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-mapent-null-check-in-lookup-nisplus-lookup_mount.patch @@ -0,0 +1,24 @@ +autofs-5.0.7 - add mapent null check in lookup_nisplus.c:lookup_mount() + +From: Ian Kent + +malloc(3) could return null under low memory conditions, add a null check +for this case. +--- + modules/lookup_nisplus.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 8237a1e..ef942a7 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -584,7 +584,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (me && (me->source == source || *me->key == '/')) { + mapent_len = strlen(me->mapent); + mapent = malloc(mapent_len + 1); +- strcpy(mapent, me->mapent); ++ if (mapent) ++ strcpy(mapent, me->mapent); + } + } + cache_unlock(mc); diff --git a/SOURCES/autofs-5.0.7-add-null-check-in-extract_version.patch b/SOURCES/autofs-5.0.7-add-null-check-in-extract_version.patch new file mode 100644 index 0000000..93bd2ac --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-null-check-in-extract_version.patch @@ -0,0 +1,23 @@ +autofs-5.0.7 - add null check in extract_version() + +From: Ian Kent + +A space should always be found in the passed in string but a check +should be done in case it isn't. +--- + lib/mounts.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/lib/mounts.c b/lib/mounts.c +index 0caa0aa..7b959b8 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -168,6 +168,8 @@ unsigned int get_kver_minor(void) + static int extract_version(char *start, struct nfs_mount_vers *vers) + { + char *s_ver = strchr(start, ' '); ++ if (!s_ver) ++ return 0; + while (*s_ver && !isdigit(*s_ver)) { + s_ver++; + if (!*s_ver) diff --git a/SOURCES/autofs-5.0.7-add-null-check-in-parse_server_string.patch b/SOURCES/autofs-5.0.7-add-null-check-in-parse_server_string.patch new file mode 100644 index 0000000..e5a0adb --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-null-check-in-parse_server_string.patch @@ -0,0 +1,26 @@ +autofs-5.0.7 - add null check in parse_server_string() + +From: Ian Kent + +Add an error check for the case there's no ':' server name delimiter in +parse_server_string(). +--- + modules/lookup_ldap.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 17cbe9a..a59de92 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -1212,6 +1212,11 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + /* Isolate the server. Include the port spec */ + if (*ptr != '[') + q = strchr(ptr, ':'); ++ if (!q) { ++ crit(logopt, MODPREFIX ++ "LDAP server name not found in %s", ptr); ++ return 0; ++ } + else { + q = ++ptr; + while (*q == ':' || isxdigit(*q)) diff --git a/SOURCES/autofs-5.0.7-add-null-check-in-read_one.patch b/SOURCES/autofs-5.0.7-add-null-check-in-read_one.patch new file mode 100644 index 0000000..a830bc9 --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-null-check-in-read_one.patch @@ -0,0 +1,26 @@ +autofs-5.0.7 - add null check in read_one() + +From: Ian Kent + +The pointter p shouldn't be null here but add a chack anyway. +--- + modules/lookup_file.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 65e5ee6..2836996 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -302,8 +302,10 @@ static int read_one(unsigned logopt, FILE *f, char *key, unsigned int *k_len, ch + if (gotten == got_real || gotten == getting) + goto got_it; + } else if (mapent_len < MAPENT_MAX_LEN) { +- mapent_len++; +- *(p++) = ch; ++ if (p) { ++ mapent_len++; ++ *(p++) = ch; ++ } + nch = getc(f); + if (nch == EOF && + (gotten == got_real || gotten == getting)) diff --git a/SOURCES/autofs-5.0.7-add-pgrp-check-in-do_spawn.patch b/SOURCES/autofs-5.0.7-add-pgrp-check-in-do_spawn.patch new file mode 100644 index 0000000..6674f6d --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-pgrp-check-in-do_spawn.patch @@ -0,0 +1,23 @@ +autofs-5.0.7 - add pgrp check in do_spawn() + +From: Ian Kent + +The process group should never be negative here but add a check anyway. +--- + daemon/spawn.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/daemon/spawn.c b/daemon/spawn.c +index 9b8d5a2..abb353a 100644 +--- a/daemon/spawn.c ++++ b/daemon/spawn.c +@@ -201,7 +201,8 @@ static int do_spawn(unsigned logopt, unsigned int wait, + + seteuid(0); + setegid(0); +- setpgid(0, pgrp); ++ if (pgrp >= 0) ++ setpgid(0, pgrp); + } + + execv(prog, (char *const *) argv); diff --git a/SOURCES/autofs-5.0.7-add-short-host-name-standard-marco-variable.patch b/SOURCES/autofs-5.0.7-add-short-host-name-standard-marco-variable.patch new file mode 100644 index 0000000..5d0a7e5 --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-short-host-name-standard-marco-variable.patch @@ -0,0 +1,70 @@ +autofs-5.0.7 - add short host name standard marco variable + +From: Ian Kent + +Sometimes the short hostname (without the domain part) could be useful. +Add this to the standard additional macro variables, in particular, to +compliment the ${HOST} macro. +--- + CHANGELOG | 1 + + man/autofs.5 | 2 +- + modules/parse_sun.c | 13 +++++++++++++ + 3 files changed, 15 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -77,6 +77,7 @@ + - fix fix options compare. + - fix max() declaration. + - setup program map env from macro table. ++- add short host name standard marco variable. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/autofs.5 ++++ autofs-5.0.7/man/autofs.5 +@@ -170,7 +170,7 @@ UID The user login ID + GROUP The user group name + GID The user group ID + HOME The user home directory +-HOST Hostname (uname -n) ++SHOST Short hostname (domain part removed if present) + .fi + .RE + .sp +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -107,6 +107,7 @@ static struct substvar *addstdenv(struct + + tsv = pthread_getspecific(key_thread_stdenv_vars); + if (tsv) { ++ struct substvar *mv; + int ret; + long num; + +@@ -121,6 +122,17 @@ static struct substvar *addstdenv(struct + list = macro_addvar(list, "USER", 4, tsv->user); + list = macro_addvar(list, "GROUP", 5, tsv->group); + list = macro_addvar(list, "HOME", 4, tsv->home); ++ mv = macro_findvar(list, "HOST", 4); ++ if (mv) { ++ char *shost = strdup(mv->val); ++ if (shost) { ++ char *dot = strchr(shost, '.'); ++ if (dot) ++ *dot = '\0'; ++ list = macro_addvar(list, "SHOST", 5, shost); ++ free(shost); ++ } ++ } + } + return list; + } +@@ -134,6 +146,7 @@ static struct substvar *removestdenv(str + list = macro_removevar(list, "HOME", 4); + list = macro_removevar(list, "GID", 3); + list = macro_removevar(list, "GROUP", 5); ++ list = macro_removevar(list, "SHOST", 5); + return list; + } + diff --git a/SOURCES/autofs-5.0.7-add-std-vars-to-program-map-invocation.patch b/SOURCES/autofs-5.0.7-add-std-vars-to-program-map-invocation.patch new file mode 100644 index 0000000..eb61bd0 --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-std-vars-to-program-map-invocation.patch @@ -0,0 +1,171 @@ +autofs-5.0.7 - add std vars to program map invocation + +From: Ian Kent + +Program maps currently don't have the standard macro variables set +in the environemt when they run. + +Also, program maps aren't necessarily executed within a shell so +setting the standard variables in the environment needs to be done +the same way it's done by the Sun map parser. +--- + CHANGELOG | 1 + include/mounts.h | 3 ++ + lib/mounts.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++ + modules/lookup_program.c | 2 + + modules/parse_sun.c | 51 ----------------------------------------------- + 5 files changed, 57 insertions(+), 51 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -79,6 +79,7 @@ + - setup program map env from macro table. + - add short host name standard marco variable. + - fix symlink fail message in mount_bind.c. ++- add std vars to program map invocation. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/mounts.h ++++ autofs-5.0.7/include/mounts.h +@@ -85,6 +85,9 @@ unsigned int linux_version_code(void); + int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *); + extern unsigned int nfs_mount_uses_string_options; + ++struct substvar *addstdenv(struct substvar *sv); ++struct substvar *removestdenv(struct substvar *sv); ++ + unsigned int query_kproto_ver(void); + unsigned int get_kver_major(void); + unsigned int get_kver_minor(void); +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -303,6 +303,57 @@ int check_nfs_mount_version(struct nfs_m + } + #endif + ++struct substvar *addstdenv(struct substvar *sv) ++{ ++ struct substvar *list = sv; ++ struct thread_stdenv_vars *tsv; ++ char numbuf[16]; ++ ++ tsv = pthread_getspecific(key_thread_stdenv_vars); ++ if (tsv) { ++ const struct substvar *mv; ++ int ret; ++ long num; ++ ++ num = (long) tsv->uid; ++ ret = sprintf(numbuf, "%ld", num); ++ if (ret > 0) ++ list = macro_addvar(list, "UID", 3, numbuf); ++ num = (long) tsv->gid; ++ ret = sprintf(numbuf, "%ld", num); ++ if (ret > 0) ++ list = macro_addvar(list, "GID", 3, numbuf); ++ list = macro_addvar(list, "USER", 4, tsv->user); ++ list = macro_addvar(list, "GROUP", 5, tsv->group); ++ list = macro_addvar(list, "HOME", 4, tsv->home); ++ mv = macro_findvar(list, "HOST", 4); ++ if (mv) { ++ char *shost = strdup(mv->val); ++ if (shost) { ++ char *dot = strchr(shost, '.'); ++ if (dot) ++ *dot = '\0'; ++ list = macro_addvar(list, "SHOST", 5, shost); ++ free(shost); ++ } ++ } ++ } ++ return list; ++} ++ ++struct substvar *removestdenv(struct substvar *sv) ++{ ++ struct substvar *list = sv; ++ ++ list = macro_removevar(list, "UID", 3); ++ list = macro_removevar(list, "USER", 4); ++ list = macro_removevar(list, "HOME", 4); ++ list = macro_removevar(list, "GID", 3); ++ list = macro_removevar(list, "GROUP", 5); ++ list = macro_removevar(list, "SHOST", 5); ++ return list; ++} ++ + /* + * Make common autofs mount options string + */ +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -271,6 +271,8 @@ int lookup_mount(struct autofs_point *ap + */ + if (ctxt->mapfmt && strcmp(ctxt->mapfmt, "MAPFMT_DEFAULT")) { + struct parse_context *pctxt = (struct parse_context *) ctxt->parse->context; ++ /* Add standard environment as seen by sun map parser */ ++ pctxt->subst = addstdenv(pctxt->subst); + macro_setenv(pctxt->subst); + } + execl(ctxt->mapname, ctxt->mapname, name, NULL); +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -99,57 +99,6 @@ static void kill_context(struct parse_co + free(ctxt); + } + +-static struct substvar *addstdenv(struct substvar *sv) +-{ +- struct substvar *list = sv; +- struct thread_stdenv_vars *tsv; +- char numbuf[16]; +- +- tsv = pthread_getspecific(key_thread_stdenv_vars); +- if (tsv) { +- struct substvar *mv; +- int ret; +- long num; +- +- num = (long) tsv->uid; +- ret = sprintf(numbuf, "%ld", num); +- if (ret > 0) +- list = macro_addvar(list, "UID", 3, numbuf); +- num = (long) tsv->gid; +- ret = sprintf(numbuf, "%ld", num); +- if (ret > 0) +- list = macro_addvar(list, "GID", 3, numbuf); +- list = macro_addvar(list, "USER", 4, tsv->user); +- list = macro_addvar(list, "GROUP", 5, tsv->group); +- list = macro_addvar(list, "HOME", 4, tsv->home); +- mv = macro_findvar(list, "HOST", 4); +- if (mv) { +- char *shost = strdup(mv->val); +- if (shost) { +- char *dot = strchr(shost, '.'); +- if (dot) +- *dot = '\0'; +- list = macro_addvar(list, "SHOST", 5, shost); +- free(shost); +- } +- } +- } +- return list; +-} +- +-static struct substvar *removestdenv(struct substvar *sv) +-{ +- struct substvar *list = sv; +- +- list = macro_removevar(list, "UID", 3); +- list = macro_removevar(list, "USER", 4); +- list = macro_removevar(list, "HOME", 4); +- list = macro_removevar(list, "GID", 3); +- list = macro_removevar(list, "GROUP", 5); +- list = macro_removevar(list, "SHOST", 5); +- return list; +-} +- + /* + * $- and &-expand a Sun-style map entry and return the length of the entry. + * If "dst" is NULL, just count the length. diff --git a/SOURCES/autofs-5.0.7-add-symlink-pseudo-option.patch b/SOURCES/autofs-5.0.7-add-symlink-pseudo-option.patch new file mode 100644 index 0000000..b0440f4 --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-symlink-pseudo-option.patch @@ -0,0 +1,217 @@ +autofs-5.0.7 - add symlink pseudo option + +From: Ian Kent + +Add a "symlink" pseudo option to tell the bind mount module to symlink +instead of bind when mounting mounts other than direct mounts and +non-root indirect mount offset mounts (aka. non-root multi-mount +entries). +--- + CHANGELOG | 1 + + include/automount.h | 3 +++ + lib/master_parse.y | 8 +++++++- + lib/master_tok.l | 1 + + man/auto.master.5.in | 8 ++++++++ + modules/mount_autofs.c | 5 +++++ + modules/mount_bind.c | 36 +++++++++++++++++++++++++++++++++++- + 7 files changed, 60 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index c189483..247d334 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -32,6 +32,7 @@ + - fix wildcard multi map regression. + - fix file descriptor leak when reloading the daemon. + - depricate nosymlink pseudo option. ++- add symlink pseudo option. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/include/automount.h b/include/automount.h +index 37541f5..e72fa0d 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -455,6 +455,9 @@ struct kernel_mod_version { + /* Don't use bind mounts even when system supports them */ + #define MOUNT_FLAG_NOBIND 0x0020 + ++/* Use symlinks instead of bind mounting local mounts */ ++#define MOUNT_FLAG_SYMLINK 0x0040 ++ + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ +diff --git a/lib/master_parse.y b/lib/master_parse.y +index f925b5a..11caf5b 100644 +--- a/lib/master_parse.y ++++ b/lib/master_parse.y +@@ -57,6 +57,7 @@ static char *type; + static char *format; + static long timeout; + static long negative_timeout; ++static unsigned symlnk; + static unsigned nobind; + static unsigned ghost; + extern unsigned global_selection_options; +@@ -100,7 +101,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 ++%token OPT_DEBUG OPT_RANDOM OPT_USE_WEIGHT OPT_SYMLINK + %token COLON COMMA NL DDASH + %type map + %type options +@@ -186,6 +187,7 @@ line: + | PATH OPT_USE_WEIGHT { master_notify($1); YYABORT; } + | PATH OPT_DEBUG { master_notify($1); YYABORT; } + | PATH OPT_TIMEOUT { master_notify($1); YYABORT; } ++ | PATH OPT_SYMLINK { master_notify($1); YYABORT; } + | PATH OPT_NOBIND { master_notify($1); YYABORT; } + | PATH OPT_GHOST { master_notify($1); YYABORT; } + | PATH OPT_NOGHOST { master_notify($1); YYABORT; } +@@ -557,6 +559,7 @@ option: daemon_option + + daemon_option: OPT_TIMEOUT NUMBER { timeout = $2; } + | OPT_NTIMEOUT NUMBER { negative_timeout = $2; } ++ | OPT_SYMLINK { symlnk = 1; } + | OPT_NOBIND { nobind = 1; } + | OPT_NOGHOST { ghost = 0; } + | OPT_GHOST { ghost = 1; } +@@ -627,6 +630,7 @@ static void local_init_vars(void) + debug = 0; + timeout = -1; + negative_timeout = 0; ++ symlnk = 0; + nobind = 0; + ghost = defaults_get_browse_mode(); + random_selection = global_selection_options & MOUNT_FLAG_RANDOM_SELECT; +@@ -811,6 +815,8 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne + entry->ap->flags |= MOUNT_FLAG_RANDOM_SELECT; + if (use_weight) + entry->ap->flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; ++ if (symlnk) ++ entry->ap->flags |= MOUNT_FLAG_SYMLINK; + if (negative_timeout) + entry->ap->negative_timeout = negative_timeout; + +diff --git a/lib/master_tok.l b/lib/master_tok.l +index 30abb15..f9b4e55 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -361,6 +361,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo + return(NUMBER); + } + ++ -?symlink { return(OPT_SYMLINK); } + -?nobind { return(OPT_NOBIND); } + -?nobrowse { return(OPT_NOGHOST); } + -g|--ghost|-?browse { return(OPT_GHOST); } +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index 8007542..bbea43a 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -159,6 +159,14 @@ on individual map entries of both types. Bind mounting of NFS file + systems can also be prevented for specific map entrys by adding the + "port=" mount option to the entries. + .TP ++.I "symlink" ++This option makes bind mounting use a symlink instead of an actual bind ++mount. It is an autofs specific option that is a pseudo mount option and ++so is given without a leading dash. It may be used with indirect map ++entries only, either in the master map (so it effects all map entries) ++or with individual map entries. The option is ignored for direct mounts ++and non-root offest mount entries. ++.TP + .I "\-r, \-\-random-multimount-selection" + Enables the use of ramdom selection when choosing a host from a + list of replicated servers. This option is applied to this mount +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index ef16020..8c1e600 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -51,6 +51,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + int argc, status; + int nobind = ap->flags & MOUNT_FLAG_NOBIND; + int ghost = ap->flags & MOUNT_FLAG_GHOST; ++ int symlnk = ap->flags & MOUNT_FLAG_SYMLINK; + time_t timeout = ap->entry->maps->exp_timeout; + unsigned logopt = ap->logopt; + struct map_type_info *info; +@@ -120,6 +121,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + nobind = 1; + else if (strncmp(cp, "browse", 6) == 0) + ghost = 1; ++ else if (strncmp(cp, "symlink", 7) == 0) ++ symlnk = 1; + else if (strncmp(cp, "timeout=", 8) == 0) { + char *val = strchr(cp, '='); + unsigned tout; +@@ -158,6 +161,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + } + nap = entry->ap; + nap->parent = ap; ++ if (symlnk) ++ nap->flags |= MOUNT_FLAG_SYMLINK; + + argc = 1; + +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index 9bce686..4975294 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -73,10 +73,44 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + char buf[MAX_ERR_BUF]; + int err; + int i, len; ++ int symlnk = (*name != '/' && (ap->flags & MOUNT_FLAG_SYMLINK)); + + if (ap->flags & MOUNT_FLAG_REMOUNT) + return 0; + ++ /* Extract "symlink" pseudo-option which forces local filesystems ++ * to be symlinked instead of bound. ++ */ ++ if (*name != '/' && !symlnk && options) { ++ const char *comma; ++ int o_len = strlen(options) + 1; ++ ++ for (comma = options; *comma != '\0';) { ++ const char *cp; ++ const char *end; ++ ++ while (*comma == ',') ++ comma++; ++ ++ /* Skip leading white space */ ++ while (*comma == ' ' || *comma == '\t') ++ comma++; ++ ++ cp = comma; ++ while (*comma != '\0' && *comma != ',') ++ comma++; ++ ++ /* Skip trailing white space */ ++ end = comma - 1; ++ while (*comma == ' ' || *comma == '\t') ++ end--; ++ ++ o_len = end - cp + 1; ++ if (strncmp("symlink", cp, o_len) == 0) ++ symlnk = 1; ++ } ++ } ++ + /* Root offset of multi-mount */ + len = strlen(root); + if (root[len - 1] == '/') { +@@ -100,7 +134,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + if (options == NULL || *options == '\0') + options = "defaults"; + +- if (bind_works) { ++ if (!symlnk && bind_works) { + int status, existed = 1; + + debug(ap->logopt, MODPREFIX "calling mkdir_path %s", fullpath); diff --git a/SOURCES/autofs-5.0.7-add-timeout-option-description-to-man-page.patch b/SOURCES/autofs-5.0.7-add-timeout-option-description-to-man-page.patch new file mode 100644 index 0000000..ac598dd --- /dev/null +++ b/SOURCES/autofs-5.0.7-add-timeout-option-description-to-man-page.patch @@ -0,0 +1,42 @@ +autofs-5.0.7 - add timeout option description to man page + +From: Ian Kent + +The pseudo option used t set the timeout for map entries is one of +the most most frequently used autofs options but is not mentioned +in auto.master(5). +--- + + CHANGELOG | 1 + + man/auto.master.5.in | 5 +++++ + 2 files changed, 6 insertions(+), 0 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 93b9c26..7b8d185 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -6,6 +6,7 @@ + - fix parse buffer initialization. + - fix typo in automount(8). + - dont wait forever to restart. ++- add timeout option description to man page. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index 54269f8..21d7544 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -167,6 +167,11 @@ server is specified in the map entry. If no server weights are given + then each available server will be tried in the order listed, within + proximity. + .TP ++.I "\-t, \-\-timeout " ++Set the expire timeout for map entries. This option can be used to ++override the global default given either on the command line ++or in the configuration. ++.TP + .I "\-n, \-\-negative\-timeout " + Set the timeout for caching failed key lookups. This option can be + used to override the global default given either on the command line diff --git a/SOURCES/autofs-5.0.7-allow-non-root-user-to-check-status.patch b/SOURCES/autofs-5.0.7-allow-non-root-user-to-check-status.patch new file mode 100644 index 0000000..6020c31 --- /dev/null +++ b/SOURCES/autofs-5.0.7-allow-non-root-user-to-check-status.patch @@ -0,0 +1,69 @@ +autofs-5.0.7 - allow non root user to check status + +From: Ian Kent + + +--- + + CHANGELOG | 1 + + redhat/autofs.init.in | 20 +++++++++++++------- + 2 files changed, 14 insertions(+), 7 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 44c9fb2..936c9ab 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -11,6 +11,7 @@ + - make description of default MOUNT_WAIT setting clear. + - configure.in: allow cross compilation. + - README: update mailing list subscription info. ++- allow non root user to check status. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in +index cd5cb34..fe18b3e 100644 +--- a/redhat/autofs.init.in ++++ b/redhat/autofs.init.in +@@ -167,6 +167,19 @@ function usage_message() { + + RETVAL=0 + ++# allow non-root users to read status / usage ++ ++case "$1" in ++ status) ++ status -p @@autofspiddir@@/autofs.pid -l autofs $prog ++ exit 0; ++ ;; ++ usage) ++ usage_message ++ exit 0; ++ ;; ++esac ++ + # Only the root user may change the service status + if [ `id -u` -ne 0 ] && [ "$1" != "status" ]; then + echo "insufficient privilege to change service status" +@@ -184,9 +197,6 @@ case "$1" in + stop) + stop + ;; +- status) +- status -p @@autofspiddir@@/autofs.pid -l autofs $prog +- ;; + restart|force-reload) + restart + ;; +@@ -202,10 +212,6 @@ case "$1" in + restart + fi + ;; +- usage) +- usage_message +- exit 0 +- ;; + *) + usage_message + exit 2 diff --git a/SOURCES/autofs-5.0.7-allow-nsswitch_conf-to-not-contain-automount-lines.patch b/SOURCES/autofs-5.0.7-allow-nsswitch_conf-to-not-contain-automount-lines.patch new file mode 100644 index 0000000..c342d10 --- /dev/null +++ b/SOURCES/autofs-5.0.7-allow-nsswitch_conf-to-not-contain-automount-lines.patch @@ -0,0 +1,50 @@ +autofs-5.0.7 - Allow nsswitch.conf to not contain "automount:" lines + +From: Michael Tokarev + +Current code does not allow a case when nsswitch.conf +does not mention automount map at all, like all new +installations. It logs a rather unpleasant error +message instead: + + syntax error in nsswitch config near [ syntax error ] + +this patch has a minimal fix, to allo "file" to be empty. + +Whole parser in C is about 25 lines of code, the "grammar" +is trivial, and it is better to ditch all this yacc/lex +stuff, but that will be much more intrusive change. + +Signed-off-by: Michael Tokarev +Cc: 682266@bugs.debian.org +--- + + CHANGELOG | 1 + + lib/nss_parse.y | 1 + + 2 files changed, 2 insertions(+), 0 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index bd0dd82..16ac2a0 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -16,6 +16,7 @@ + - increase file map read buffer size. + - handle new location of systemd. + - fix map entry duplicate offset detection. ++- Allow nsswitch.conf to not contain "automount:" lines. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/nss_parse.y b/lib/nss_parse.y +index a39fda4..055e9d7 100644 +--- a/lib/nss_parse.y ++++ b/lib/nss_parse.y +@@ -72,6 +72,7 @@ file: { + nss_debug = YYDEBUG; + #endif + } sources NL ++ | /* empty */ + ; + + sources: nss_source diff --git a/SOURCES/autofs-5.0.7-allow-use-of-hosts-map-in-maps.patch b/SOURCES/autofs-5.0.7-allow-use-of-hosts-map-in-maps.patch new file mode 100644 index 0000000..6a18673 --- /dev/null +++ b/SOURCES/autofs-5.0.7-allow-use-of-hosts-map-in-maps.patch @@ -0,0 +1,231 @@ +autofs-5.0.7 - allow use of hosts map in maps + +From: Ian Kent + +At the moment the internal hosts map can only be use as an entry in the +master map but there's no reason (I can think of so far) that it shouldn't +be possible to use it in map entries. +--- + lib/parse_subs.c | 17 ++++++----- + modules/mount_autofs.c | 29 ++++++++++++++++---- + modules/parse_sun.c | 71 +++++++++++++++++++++++++++++++------------------ + 3 files changed, 80 insertions(+), 37 deletions(-) + +--- autofs-5.0.7.orig/lib/parse_subs.c ++++ autofs-5.0.7/lib/parse_subs.c +@@ -35,6 +35,7 @@ static struct types map_type[] = { + { "ldaps", 5 }, + { "hesiod", 6 }, + { "userdir", 7 }, ++ { "hosts", 5 }, + }; + static unsigned int map_type_count = sizeof(map_type)/sizeof(struct types); + +@@ -384,7 +385,7 @@ struct map_type_info *parse_map_type_inf + return NULL; + } else { + *pos++ = '\0'; +- while (*pos == ' ') ++ while (*pos && *pos == ' ') + *pos++ = '\0'; + map = pos; + break; +@@ -412,7 +413,7 @@ struct map_type_info *parse_map_type_inf + return NULL; + } else { + *pos++ = '\0'; +- while (*pos == ' ') ++ while (*pos && *pos == ' ') + *pos++ = '\0'; + map = pos; + break; +@@ -458,11 +459,13 @@ struct map_type_info *parse_map_type_inf + } + } + +- info->map = strdup(map); +- if (!info->map) { +- free(buf); +- free_map_type_info(info); +- return NULL; ++ if (map) { ++ info->map = strdup(map); ++ if (!info->map) { ++ free(buf); ++ free_map_type_info(info); ++ return NULL; ++ } + } + + free(buf); +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -62,6 +62,7 @@ int mount_mount(struct autofs_point *ap, + char buf[MAX_ERR_BUF]; + char *options, *p; + int len, ret; ++ int hosts = 0; + + /* Root offset of multi-mount */ + len = strlen(root); +@@ -123,6 +124,8 @@ int mount_mount(struct autofs_point *ap, + ghost = 1; + else if (strncmp(cp, "symlink", 7) == 0) + symlnk = 1; ++ else if (strncmp(cp, "hosts", 5) == 0) ++ hosts = 1; + else if (strncmp(cp, "timeout=", 8) == 0) { + char *val = strchr(cp, '='); + unsigned tout; +@@ -164,7 +167,10 @@ int mount_mount(struct autofs_point *ap, + if (symlnk) + nap->flags |= MOUNT_FLAG_SYMLINK; + +- argc = 1; ++ if (hosts) ++ argc = 0; ++ else ++ argc = 1; + + if (options) { + char *t = options; +@@ -176,14 +182,27 @@ int mount_mount(struct autofs_point *ap, + } + argv = (const char **) alloca((argc + 1) * sizeof(char *)); + +- argc = 1; +- +- if (!(info = parse_map_type_info(what))) { ++ if (hosts) ++ argc = 0; ++ else ++ argc = 1; ++ ++ /* ++ * If a mount of a hosts map is being requested it will come ++ * ro us via the options. Catch that below when processing the ++ * option and create type info struct then. ++ */ ++ if (hosts) ++ info = parse_map_type_info("hosts:"); ++ else ++ info = parse_map_type_info(what); ++ if (!info) { + error(ap->logopt, MODPREFIX "failed to parse map info"); + master_free_mapent(entry); + return 1; + } +- argv[0] = info->map; ++ if (info->map) ++ argv[0] = info->map; + + if (options) { + p = options; +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -695,14 +695,18 @@ static int sun_mount(struct autofs_point + rv = mount_nfs->mount_mount(ap, root, mountpoint, strlen(mountpoint), + what, fstype, options, mount_nfs->context); + } else { +- what = alloca(loclen + 1); +- if (*loc == ':') { +- loclen--; +- memcpy(what, loc + 1, loclen); +- what[loclen] = '\0'; +- } else { +- memcpy(what, loc, loclen); +- what[loclen] = '\0'; ++ if (!loclen) ++ what = NULL; ++ else { ++ what = alloca(loclen + 1); ++ if (*loc == ':') { ++ loclen--; ++ memcpy(what, loc + 1, loclen); ++ what[loclen] = '\0'; ++ } else { ++ memcpy(what, loc, loclen); ++ what[loclen] = '\0'; ++ } + } + + debug(ap->logopt, MODPREFIX +@@ -799,7 +803,8 @@ update_offset_entry(struct autofs_point + + mc = source->mc; + +- if (!*path || !*loc) { ++ /* Internal hosts map may have loc == NULL */ ++ if (!*path) { + error(ap->logopt, + MODPREFIX "syntax error in offset %s -> %s", path, loc); + return CHE_FAIL; +@@ -833,8 +838,10 @@ update_offset_entry(struct autofs_point + if (*myoptions) { + strcpy(m_mapent, "-"); + strcat(m_mapent, myoptions); +- strcat(m_mapent, " "); +- strcat(m_mapent, loc); ++ if (loc) { ++ strcat(m_mapent, " "); ++ strcat(m_mapent, loc); ++ } + } else + strcpy(m_mapent, loc); + +@@ -1435,13 +1442,17 @@ int parse_mount(struct autofs_point *ap, + + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { +- cache_delete_offset_list(mc, name); +- cache_multi_unlock(me); +- cache_unlock(mc); +- free(path); +- free(options); +- pthread_setcancelstate(cur_state, NULL); +- return 1; ++ if (!(strstr(myoptions, "fstype=autofs") && ++ strstr(myoptions, "hosts"))) { ++ error(LOGOPT_ANY, "I think I'm a hosts map? l %d", l); ++ cache_delete_offset_list(mc, name); ++ cache_multi_unlock(me); ++ cache_unlock(mc); ++ free(path); ++ free(options); ++ pthread_setcancelstate(cur_state, NULL); ++ return 1; ++ } + } + + p += l; +@@ -1592,13 +1603,23 @@ int parse_mount(struct autofs_point *ap, + p = skipspace(p); + } + +- loclen = strlen(loc); +- if (loclen == 0) { +- free(loc); +- free(options); +- error(ap->logopt, +- MODPREFIX "entry %s is empty!", name); +- return 1; ++ /* ++ * If options are asking for a hosts map loc should be ++ * NULL but we see it can contain junk, so .... ++ */ ++ if ((strstr(options, "fstype=autofs") && ++ strstr(options, "hosts"))) { ++ loc = NULL; ++ loclen = 0; ++ } else { ++ loclen = strlen(loc); ++ if (loclen == 0) { ++ free(loc); ++ free(options); ++ error(ap->logopt, ++ MODPREFIX "entry %s is empty!", name); ++ return 1; ++ } + } + + debug(ap->logopt, diff --git a/SOURCES/autofs-5.0.7-check-for-protocol-option.patch b/SOURCES/autofs-5.0.7-check-for-protocol-option.patch new file mode 100644 index 0000000..5a3464b --- /dev/null +++ b/SOURCES/autofs-5.0.7-check-for-protocol-option.patch @@ -0,0 +1,38 @@ +autofs-5.0.7 - check for protocol option + +From: Ian Kent + +When a specific protocol is requested in the mount options only +that protocol should be probed for. +--- + modules/mount_nfs.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 9de8a73..3d2ccea 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -156,6 +156,12 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + if (port < 0) + port = 0; + port_opt = cp; ++ } else if (strncmp("proto=udp", cp, o_len) == 0 || ++ strncmp("udp", cp, o_len) == 0) { ++ vers &= ~TCP_SUPPORTED; ++ } else if (strncmp("proto=tcp", cp, o_len) == 0 || ++ strncmp("tcp", cp, o_len) == 0) { ++ vers &= ~UDP_SUPPORTED; + } + /* Check for options that also make sense + with bind mounts */ +@@ -167,6 +173,10 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + } + } + ++ /* In case both tcp and udp options were given */ ++ if ((vers & NFS_PROTO_MASK) == 0) ++ vers |= NFS_PROTO_MASK; ++ + debug(ap->logopt, MODPREFIX + "nfs options=\"%s\", nobind=%d, nosymlink=%d, ro=%d", + nfsoptions, nobind, nosymlink, ro); diff --git a/SOURCES/autofs-5.0.7-configure-allow-cross-compilation-update.patch b/SOURCES/autofs-5.0.7-configure-allow-cross-compilation-update.patch new file mode 100644 index 0000000..a8bc3ce --- /dev/null +++ b/SOURCES/autofs-5.0.7-configure-allow-cross-compilation-update.patch @@ -0,0 +1,28 @@ +autofs-5.0.7 - configure: allow cross compilation update + +From: Chris Packham + +Run "make distclean" to update configure. This should have been included +in 5936c738 when configure.in was updated but it was missed. +--- + + configure | 5 +---- + 1 files changed, 1 insertions(+), 4 deletions(-) + + +diff --git a/configure b/configure +index bf62203..ba3bba6 100755 +--- a/configure ++++ b/configure +@@ -5378,10 +5378,7 @@ DAEMON_LDFLAGS= + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether gcc -fPIE works" >&5 + $as_echo_n "checking whether gcc -fPIE works... " >&6; } + if test "$cross_compiling" = yes; then : +- { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +-as_fn_error $? "cannot run test program while cross compiling +-See \`config.log' for more details" "$LINENO" 5; } ++ gcc_supports_pie=no + else + cat confdefs.h - <<_ACEOF >conftest.$ac_ext + /* end confdefs.h. */ diff --git a/SOURCES/autofs-5.0.7-configure-in-allow-cross-compilation.patch b/SOURCES/autofs-5.0.7-configure-in-allow-cross-compilation.patch new file mode 100644 index 0000000..ac18bd9 --- /dev/null +++ b/SOURCES/autofs-5.0.7-configure-in-allow-cross-compilation.patch @@ -0,0 +1,41 @@ +autofs-5.0.7 - configure.in: allow cross compilation + +From: Chris Packham + +The default behaviour of AC_RUN_IFELSE is to stop with an error if cross +compiling. Avoid this by providing the optional 4th argument to set +gcc_supports_pie=no if support for PIE cannot be detected. + +Signed-off-by: Chris Packham +--- + + CHANGELOG | 1 + + configure.in | 2 +- + 2 files changed, 2 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 961e340..fe801e8 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -9,6 +9,7 @@ + - add timeout option description to man page. + - fix null map entry order handling. + - make description of default MOUNT_WAIT setting clear. ++- configure.in: allow cross compilation. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/configure.in b/configure.in +index 1a24e34..90bda62 100644 +--- a/configure.in ++++ b/configure.in +@@ -307,7 +307,7 @@ DAEMON_CFLAGS= + DAEMON_LDFLAGS= + AC_MSG_CHECKING([whether gcc -fPIE works]) + AC_RUN_IFELSE([AC_LANG_PROGRAM([[]], [[int main(void) {return 0;}]])], +- [gcc_supports_pie=yes], [gcc_supports_pie=no]) ++ [gcc_supports_pie=yes], [gcc_supports_pie=no], [gcc_supports_pie=no]) + AC_MSG_RESULT([$gcc_supports_pie]) + if test $gcc_supports_pie = yes ; then + DAEMON_CFLAGS="-fPIE" diff --git a/SOURCES/autofs-5.0.7-depricate-nosymlink-pseudo-option.patch b/SOURCES/autofs-5.0.7-depricate-nosymlink-pseudo-option.patch new file mode 100644 index 0000000..c784de7 --- /dev/null +++ b/SOURCES/autofs-5.0.7-depricate-nosymlink-pseudo-option.patch @@ -0,0 +1,40 @@ +autofs-5.0.7 - depricate nosymlink pseudo option + +From: Ian Kent + +The undocumented "nosymlink" option was the only way to force local +NFS mounting until the more descriptive "nobind" option was added. + +So depricate the "nosymlink" option in favour of the "nobind" option. +--- + CHANGELOG | 1 + + modules/mount_nfs.c | 4 ++++ + 2 files changed, 5 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index a7ed212..c189483 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -31,6 +31,7 @@ + - dont fail on master map self include. + - fix wildcard multi map regression. + - fix file descriptor leak when reloading the daemon. ++- depricate nosymlink pseudo option. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index bbbb1de..e61320b 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -125,6 +125,10 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + + o_len = end - cp + 1; + if (strncmp("nosymlink", cp, o_len) == 0) { ++ warn(ap->logopt, MODPREFIX ++ "the \"nosymlink\" option is depricated " ++ "and will soon be removed, " ++ "use the \"nobind\" option instead"); + nosymlink = 1; + } else if (strncmp("nobind", cp, o_len) == 0) { + nobind = 1; diff --git a/SOURCES/autofs-5.0.7-document-allowed-map-sources-in-auto_master.patch b/SOURCES/autofs-5.0.7-document-allowed-map-sources-in-auto_master.patch new file mode 100644 index 0000000..737b5d1 --- /dev/null +++ b/SOURCES/autofs-5.0.7-document-allowed-map-sources-in-auto_master.patch @@ -0,0 +1,48 @@ +autofs-5.0.7 - document allowed map sources in auto.master + +From: Ian Kent + +Direct map may have multiple map sources but indirect maps may have +only one map source. +--- + CHANGELOG | 1 + + man/auto.master.5.in | 7 +++++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 4576d47..61edddf 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -41,6 +41,7 @@ + - syncronize handle_mounts() shutdown. + - fix submount tree not all expiring. + - make dump maps check for duplicate indirect mounts. ++- document allowed map sources in auto.master. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index c552e56..7907ffa 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -40,7 +40,8 @@ For direct maps the mount point is always specified as: + .P + /- + .P +-and the key used within the direct map is the full path to the mount point. ++and the key used within the direct map is the full path to the mount point. The direct map ++may have multiple entries in the master map. + .P + For indirect maps access is by using the path scheme: + .P +@@ -60,7 +61,9 @@ present in the master map by including a line of the form: + and + .BR automount (8) + will process the map according to the specification described below for +-map entries. ++map entries. Indirect map entries must be unique in the master map so ++second and subsequent entries for an indirect mount point are ignored by ++.BR automount (8). + .SH "FORMAT" + Master map entries have three fields separated by an arbitrary number + of spaces or tabs. Lines beginning with # are comments. The first field diff --git a/SOURCES/autofs-5.0.7-document-browse-option-in-man-page.patch b/SOURCES/autofs-5.0.7-document-browse-option-in-man-page.patch new file mode 100644 index 0000000..4641342 --- /dev/null +++ b/SOURCES/autofs-5.0.7-document-browse-option-in-man-page.patch @@ -0,0 +1,46 @@ +autofs-5.0.7 - document browse option in man page + +From: Ian Kent + +The "browse" option has remained undocumented for a long time. +Finally add a section for it to auto.master(5) making special +note of the potential performance implications. +--- + CHANGELOG | 1 + + man/auto.master.5.in | 11 +++++++++++ + 2 files changed, 12 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index ecdea0b..d8e4049 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -36,6 +36,7 @@ + - fix requires in spec file. + - fix libtirpc build option to require libtirpc-devel if needed. + - fix systemd unidir in spec file. ++- document browse option in man page. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index bbea43a..c552e56 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -147,6 +147,17 @@ multiple file systems should be mounted (`multimounts'). If this option + is given, no file system is mounted at all if at least one file system + can't be mounted. + .TP ++.I "[no]browse" ++This is an autofs specific option that is a pseudo mount option and ++so is given without a leading dash. Use of the browse option pre-creates ++mount point directories for indirect mount maps so the map keys can be ++seen in a directory listing without being mounted. Use of this option ++can cause performance problem if the indirect map is large so it should ++be used with caution. The internal program default is to enable browse ++mode for indirect mounts but the default installed configuration overrides ++this by setting BROWSE_MODE to "no" because of the potential performance ++problem. ++.TP + .I "nobind" + This is an autofs specific option that is a pseudo mount option and + so is given without a leading dash. It may be used either in the master diff --git a/SOURCES/autofs-5.0.7-dont-fail-on-master-map-self-include.patch b/SOURCES/autofs-5.0.7-dont-fail-on-master-map-self-include.patch new file mode 100644 index 0000000..afb908b --- /dev/null +++ b/SOURCES/autofs-5.0.7-dont-fail-on-master-map-self-include.patch @@ -0,0 +1,59 @@ +autofs-5.0.7 - dont fail on master map self include + +From: Ian Kent + +When reading the master map a self included file map should skip the source +and proceed to the next so, in this case, return an nss status that will +allow the map read to continue. In particular not NSS_STATUS_UNAVAIL which +causes the lookup to record a failure or NSS_STATUS_SUCCESS which indicates +a successful lookup and termintes the reading of sources. +--- + CHANGELOG | 1 + + modules/lookup_file.c | 7 ++++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 39388a5..97d6f48 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -28,6 +28,7 @@ + - make yellow pages support optional. + - modules/replicated.c: use sin6_addr.s6_addr32. + - workaround missing GNU versionsort extension. ++- dont fail on master map self include. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index facb305..f37bed9 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -397,8 +397,9 @@ int lookup_read_master(struct master *master, time_t age, void *context) + unsigned int path_len, ent_len; + int entry, cur_state; + ++ /* Don't return fail on self include, skip source */ + if (master->recurse) +- return NSS_STATUS_UNAVAIL; ++ return NSS_STATUS_TRYAGAIN; + + if (master->depth > MAX_INCLUDE_DEPTH) { + error(logopt, MODPREFIX +@@ -443,7 +444,7 @@ int lookup_read_master(struct master *master, time_t age, void *context) + + inc = check_master_self_include(master, ctxt); + if (inc) +- master->recurse = 1;; ++ master->recurse = 1; + master->depth++; + status = lookup_nss_read_master(master, age); + if (!status) { +@@ -645,7 +646,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + mc = source->mc; + + if (source->recurse) +- return NSS_STATUS_UNAVAIL; ++ return NSS_STATUS_TRYAGAIN; + + if (source->depth > MAX_INCLUDE_DEPTH) { + error(ap->logopt, diff --git a/SOURCES/autofs-5.0.7-dont-override-LDFLAGS-in-make-rules.patch b/SOURCES/autofs-5.0.7-dont-override-LDFLAGS-in-make-rules.patch new file mode 100644 index 0000000..33db77c --- /dev/null +++ b/SOURCES/autofs-5.0.7-dont-override-LDFLAGS-in-make-rules.patch @@ -0,0 +1,46 @@ +autofs-5.0.7 - don't override LDFLAGS in make rules + +From: Ian Kent + +Ensure that externally defined LDFLAGS is not overridden. +--- + CHANGELOG | 1 + + Makefile.rules | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 5d90139..37eac72 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -53,6 +53,7 @@ + - fix probe each nfs version in turn for singleton mounts. + - misc man page fixes. + - fix add null check in parse_server_string(). ++- don't override LDFLAGS in make rules. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/Makefile.rules b/Makefile.rules +index f2ba386..6b5b2bd 100644 +--- a/Makefile.rules ++++ b/Makefile.rules +@@ -24,16 +24,16 @@ endif + + ifdef DEBUG + CFLAGS ?= -g -Wall -DDEBUG +-LDFLAGS = -g ++LDFLAGS ?= -g + STRIP = : + else + ifdef DONTSTRIP + CFLAGS ?= -O2 -g +-LDFLAGS = -g ++LDFLAGS ?= -g + STRIP = : + else + CFLAGS ?= -O2 -Wall +-LDFLAGS = -s ++LDFLAGS ?= -s + STRIP = strip --strip-debug + endif + endif diff --git a/SOURCES/autofs-5.0.7-dont-probe-rdma-mounts.patch b/SOURCES/autofs-5.0.7-dont-probe-rdma-mounts.patch new file mode 100644 index 0000000..7dda820 --- /dev/null +++ b/SOURCES/autofs-5.0.7-dont-probe-rdma-mounts.patch @@ -0,0 +1,68 @@ +autofs-5.0.7 - dont probe rdma mounts + +From: Ian Kent + +Since the change to pass text nfs mount options drectly to the kernel all autofs +mount requests now probe server availability. This was because of long delays +mounting from servers that aren't responding. + +This caused mounts requesting the rdma protocol to fail if udp or tcp was also +not available from the server. + +Since, AFAICT the rmda protocol can't be used with RPC fromn userspace, the only +way to work around it is to not probe servers when rdma is requested. +--- + CHANGELOG | 1 + + modules/mount_nfs.c | 13 ++++++++++++- + 2 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 50e83d7..f9bc987 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -44,6 +44,7 @@ + - document allowed map sources in auto.master. + - add enable sloppy mount option to configure. + - fix interface address null check. ++- dont probe rdma mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index e61320b..5424d74 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -71,6 +71,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + int nosymlink = 0; + int port = -1; + int ro = 0; /* Set if mount bind should be read-only */ ++ int rdma = 0; + + if (ap->flags & MOUNT_FLAG_REMOUNT) + return 0; +@@ -124,6 +125,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + end--; + + o_len = end - cp + 1; ++ ++ if (strncmp("proto=rdma", cp, o_len) == 0 || ++ strncmp("rdma", cp, o_len) == 0) ++ rdma = 1; ++ + if (strncmp("nosymlink", cp, o_len) == 0) { + warn(ap->logopt, MODPREFIX + "the \"nosymlink\" option is depricated " +@@ -170,7 +176,12 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + info(ap->logopt, MODPREFIX "no hosts available"); + return 1; + } +- prune_host_list(ap->logopt, &hosts, vers, port); ++ /* ++ * We can't probe protocol rdma so leave it to mount.nfs(8) ++ * and and suffer the delay if a server isn't available. ++ */ ++ if (!rdma) ++ prune_host_list(ap->logopt, &hosts, vers, port); + + if (!hosts) { + info(ap->logopt, MODPREFIX "no hosts available"); diff --git a/SOURCES/autofs-5.0.7-dont-schedule-new-alarms-after-readmap.patch b/SOURCES/autofs-5.0.7-dont-schedule-new-alarms-after-readmap.patch new file mode 100644 index 0000000..6444687 --- /dev/null +++ b/SOURCES/autofs-5.0.7-dont-schedule-new-alarms-after-readmap.patch @@ -0,0 +1,69 @@ +autofs-5.0.7 - don't schedule new alarms after readmap + +From: Leonardo Chiquitto + +Currently, a new alarm is scheduled every time the daemon receives +a SIGHUP (map re-read) or SIGUSR1 (forced expiration). Besides that, +map re-reads started on demand when a map is found to be outdated +also generate a new alarm. + +Once added, these alarms are never deleted and hence increase the +number of times the daemon wakes up to run the expiration procedure. +After a couple of months, in setups with many mount points, it's +normal to see automount waking up every second to handle the +expiration timer. + +This patch removes the alarm scheduling from the readmap cleanup +routine and makes sure the alarm is re-added after the expiration +process only when it was not triggered by SIGUSR1. + +I couldn't think of any use case to justify keeping these alarms: +it's critical to have the alarm ticking every timeout/4 seconds, +but more than one periodic alarm running doesn't seem to make +sense. +--- + + CHANGELOG | 1 + + daemon/state.c | 6 +----- + 2 files changed, 2 insertions(+), 5 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index c9be73e..4cf5621 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -22,6 +22,7 @@ + - fix init script status return. + - fix use get_proximity() without libtirpc. + - don't use dirent d_type to filter out files in scandir() ++- don't schedule new alarms after readmap. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/daemon/state.c b/daemon/state.c +index b451c56..6e23022 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -144,7 +144,7 @@ void expire_cleanup(void *arg) + ap->submount = 2; + } + +- if (!ap->submount) ++ if (ap->state == ST_EXPIRE && !ap->submount) + alarm_add(ap, ap->exp_runfreq); + + /* FALLTHROUGH */ +@@ -330,13 +330,9 @@ static void do_readmap_cleanup(void *arg) + ap = ra->ap; + + st_mutex_lock(); +- + ap->readmap_thread = 0; + st_set_done(ap); +- if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); + st_ready(ap); +- + st_mutex_unlock(); + + free(ra); diff --git a/SOURCES/autofs-5.0.7-dont-use-dirent-d_type-to-filter-out-files-in-scandir.patch b/SOURCES/autofs-5.0.7-dont-use-dirent-d_type-to-filter-out-files-in-scandir.patch new file mode 100644 index 0000000..9c9d99b --- /dev/null +++ b/SOURCES/autofs-5.0.7-dont-use-dirent-d_type-to-filter-out-files-in-scandir.patch @@ -0,0 +1,41 @@ +autofs-5.0.7 - don't use dirent d_type to filter out files in scandir() + +From: Leonardo Chiquitto + +The "d_type" field of a dirent structure is not filled in by all +file systems (XFS being one example), so we can't rely on it to +check file types. +--- + + CHANGELOG | 1 + + modules/lookup_dir.c | 4 ---- + 2 files changed, 1 insertions(+), 4 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 460bd27..c9be73e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -21,6 +21,7 @@ + - fix submount offset delete. + - fix init script status return. + - fix use get_proximity() without libtirpc. ++- don't use dirent d_type to filter out files in scandir() + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/lookup_dir.c b/modules/lookup_dir.c +index 658cc29..33901c0 100644 +--- a/modules/lookup_dir.c ++++ b/modules/lookup_dir.c +@@ -103,10 +103,6 @@ static int acceptable_dirent_p(const struct dirent *e) + { + size_t namesz; + +- +- if (!(e->d_type == DT_REG || e->d_type == DT_LNK)) +- return 0; +- + namesz = strlen(e->d_name); + if (!namesz) + return 0; diff --git a/SOURCES/autofs-5.0.7-dont-wait-forever-to-restart.patch b/SOURCES/autofs-5.0.7-dont-wait-forever-to-restart.patch new file mode 100644 index 0000000..9973b47 --- /dev/null +++ b/SOURCES/autofs-5.0.7-dont-wait-forever-to-restart.patch @@ -0,0 +1,54 @@ +autofs-5.0.7 - dont wait forever to restart + +From: Ian Kent + +When restarting autofs the daemon must be stopped before it is started +again if it is to function properly. At the moment the init script waits +forever which is not ok if the daemon won't exit for some reason. + +So, if the daemon is still running after the stop, run stop() again, wait +a bit longer and if it still hasn't stopped kill it with a SIGKILL to clear +the way for the startup. +--- + + CHANGELOG | 1 + + redhat/autofs.init.in | 13 ++++++++++--- + 2 files changed, 11 insertions(+), 3 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 6051723..93b9c26 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -5,6 +5,7 @@ + - fix ipv6 proximity calculation. + - fix parse buffer initialization. + - fix typo in automount(8). ++- dont wait forever to restart. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in +index ec6d5d6..cd5cb34 100644 +--- a/redhat/autofs.init.in ++++ b/redhat/autofs.init.in +@@ -129,9 +129,16 @@ function restart() { + status autofs > /dev/null 2>&1 + if [ $? -eq 0 ]; then + stop +- while [ -n "`pidof $prog`" ] ; do +- sleep 5 +- done ++ if [ -n "`pidof $prog`" ]; then ++ # If we failed to stop, try at least one more time ++ # after waiting a little while ++ sleep 20 ++ stop ++ auto_pid=`pidof $prog` ++ if [ -n "$auto_pid" ]; then ++ kill -9 $auto_pid ++ fi ++ fi + fi + start + } diff --git a/SOURCES/autofs-5.0.7-fix-a-couple-of-compiler-warnings.patch b/SOURCES/autofs-5.0.7-fix-a-couple-of-compiler-warnings.patch new file mode 100644 index 0000000..d1703d3 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-a-couple-of-compiler-warnings.patch @@ -0,0 +1,51 @@ +autofs-5.0.7 - fix a couple of compiler warnings + +From: Ian Kent + +Quiet a couple of ompiler warnings by making intention explicit using brackets. +--- + CHANGELOG | 1 + + modules/mount_bind.c | 2 +- + modules/mount_nfs.c | 4 ++-- + 3 files changed, 4 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 37eac72..7749f01 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -54,6 +54,7 @@ + - misc man page fixes. + - fix add null check in parse_server_string(). + - don't override LDFLAGS in make rules. ++- fix a couple of compiler warnings. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index 61a773c..2b70104 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -208,7 +208,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + MODPREFIX + "failed to create local mount %s -> %s", + fullpath, what); +- if (ap->flags & MOUNT_FLAG_GHOST && !status) ++ if ((ap->flags & MOUNT_FLAG_GHOST) && !status) + if (mkdir_path(fullpath, 0555) && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 3d2ccea..adf2002 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -202,8 +202,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + */ + if ((hosts && !hosts->next) && + mount_default_proto == 4 && +- vers & NFS_VERS_MASK != 0 && +- vers & NFS4_VERS_MASK != 0) { ++ (vers & NFS_VERS_MASK) != 0 && ++ (vers & NFS4_VERS_MASK) != 0) { + unsigned int v4_probe_ok = 0; + struct host *tmp = new_host(hosts->name, + hosts->addr, hosts->addr_len, diff --git a/SOURCES/autofs-5.0.7-fix-add-null-check-in-parse_server_string.patch b/SOURCES/autofs-5.0.7-fix-add-null-check-in-parse_server_string.patch new file mode 100644 index 0000000..1e3fc20 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-add-null-check-in-parse_server_string.patch @@ -0,0 +1,45 @@ +autofs-5.0.7 - fix add null check in parse_server_string() + +From: Ian Kent + +In a recent patch that added an error check for the case there's no ':' server +name delimiter parse_server_string() braces were not added which lead to an +incorrect parse error. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 503a21e..5d90139 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -52,6 +52,7 @@ + - add changlog entry for coverity fixes. + - fix probe each nfs version in turn for singleton mounts. + - misc man page fixes. ++- fix add null check in parse_server_string(). + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 35ea6ea..a2bfafd 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -1210,14 +1210,14 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c + const char *q = NULL; + + /* Isolate the server. Include the port spec */ +- if (*ptr != '[') ++ if (*ptr != '[') { + q = strchr(ptr, ':'); + if (!q) { + crit(logopt, MODPREFIX + "LDAP server name not found in %s", ptr); + return 0; + } +- else { ++ } else { + q = ++ptr; + while (*q == ':' || isxdigit(*q)) + q++; diff --git a/SOURCES/autofs-5.0.7-fix-automounter-support-on-parisc.patch b/SOURCES/autofs-5.0.7-fix-automounter-support-on-parisc.patch new file mode 100644 index 0000000..e00fdc1 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-automounter-support-on-parisc.patch @@ -0,0 +1,24 @@ +autofs-5.0.7 - fix automounter support on parisc + +From: Helge Deller + +This patch fixes automounter support on the parisc architecture with +64-bit kernel and 32-bit userspace. + +Signed-off-by: Helge Deller +--- + daemon/automount.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/daemon/automount.c b/daemon/automount.c +index 4a3eb3d..4c651cf 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -610,6 +610,7 @@ static size_t get_kpkt_len(void) + if (strcmp(un.machine, "alpha") == 0 || + strcmp(un.machine, "ia64") == 0 || + strcmp(un.machine, "x86_64") == 0 || ++ strcmp(un.machine, "parisc64") == 0 || + strcmp(un.machine, "ppc64") == 0) + pkt_len += 4; + diff --git a/SOURCES/autofs-5.0.7-fix-bad-mkdir-permission-on-create.patch b/SOURCES/autofs-5.0.7-fix-bad-mkdir-permission-on-create.patch new file mode 100644 index 0000000..2152c8a --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-bad-mkdir-permission-on-create.patch @@ -0,0 +1,38 @@ +autofs-5.0.7 - fix bad mkdir permission on create + +From: Ian Kent + +Reported by Gordon Lack (gordon[dot]m[dot]lack[at]gsk[dot]com). + +If the automount daemon needs to create a directory (hierarchy) for an +automount and it is started up with a umask of 027 (or similar) then it +creates unusable directories (permission == 550). +--- + CHANGELOG | 1 + + daemon/automount.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -88,6 +88,7 @@ + - check for bind onto self in mount_bind.c. + - fix symlink expire. + - fix master map type check. ++- fix bad mkdir permission on create. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -122,7 +122,10 @@ static int do_mkdir(const char *parent, + status = statfs(parent, &fs); + if ((status != -1 && fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) || + contained_in_local_fs(path)) { +- if (mkdir(path, mode) == -1) { ++ mode_t mask = umask(0022); ++ int ret = mkdir(path, mode); ++ (void) umask(mask); ++ if (ret == -1) { + errno = EACCES; + return 0; + } diff --git a/SOURCES/autofs-5.0.7-fix-check-mkdir_path-in-mount_bind-mount_mount.patch b/SOURCES/autofs-5.0.7-fix-check-mkdir_path-in-mount_bind-mount_mount.patch new file mode 100644 index 0000000..74ba6aa --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-check-mkdir_path-in-mount_bind-mount_mount.patch @@ -0,0 +1,27 @@ +autofs-5.0.7 - fix check mkdir_path() in mount_bind.c:mount_mount() + +From: Ian Kent + + +--- + modules/mount_bind.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index d6c6fe7..61a773c 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -209,7 +209,12 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + "failed to create local mount %s -> %s", + fullpath, what); + if (ap->flags & MOUNT_FLAG_GHOST && !status) +- mkdir_path(fullpath, 0555); ++ if (mkdir_path(fullpath, 0555) && errno != EEXIST) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ MODPREFIX "mkdir_path %s failed: %s", ++ fullpath, estr); ++ } + else { + if (ap->type == LKP_INDIRECT) + rmdir_path(ap, fullpath, ap->dev); diff --git a/SOURCES/autofs-5.0.7-fix-compilation-of-lookup_ldap_c-without-sasl.patch b/SOURCES/autofs-5.0.7-fix-compilation-of-lookup_ldap_c-without-sasl.patch new file mode 100644 index 0000000..1e0350a --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-compilation-of-lookup_ldap_c-without-sasl.patch @@ -0,0 +1,216 @@ +autofs-5.0.7 - fix compilation of lookup_ldap.c without sasl + +From: Dustin Polke + +See https://bugs.gentoo.org/show_bug.cgi?id=361899 for more info. + +Edited by: Ian Kent +- fix parse_ldap_config() is needed by ldap but previously excluded. +- exclude other references to ctxt->extern_cert and ctxt->extern_key. +- prevent memory leak if present in config but not used. +- remove now unused set_env(). +--- + CHANGELOG | 1 + + include/lookup_ldap.h | 4 ++-- + lib/Makefile | 4 ++++ + modules/Makefile | 6 ++++-- + modules/lookup_ldap.c | 18 +++++++++++++----- + 5 files changed, 24 insertions(+), 9 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -82,6 +82,7 @@ + - add std vars to program map invocation. + - check for existing offset mount before mounting. + - fix cache readlock not taken on lookup. ++- fix compilation of lookup_ldap.c without sasl. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/lookup_ldap.h ++++ autofs-5.0.7/include/lookup_ldap.h +@@ -11,6 +11,8 @@ + #include + #endif + ++#include ++ + #include "list.h" + #include "dclist.h" + +@@ -92,7 +94,6 @@ struct lookup_context { + }; + + +-#ifdef WITH_SASL + #define LDAP_AUTH_CONF_FILE "test" + + #define LDAP_TLS_DONT_USE 0 +@@ -104,7 +105,6 @@ struct lookup_context { + #define LDAP_AUTH_REQUIRED 0x0002 + #define LDAP_AUTH_AUTODETECT 0x0004 + #define LDAP_NEED_AUTH (LDAP_AUTH_REQUIRED|LDAP_AUTH_AUTODETECT) +-#endif + + #define LDAP_AUTH_USESIMPLE 0x0008 + +--- autofs-5.0.7.orig/lib/Makefile ++++ autofs-5.0.7/lib/Makefile +@@ -24,6 +24,10 @@ CFLAGS += -I../include -fPIC -D_GNU_SOUR + CFLAGS += -DAUTOFS_MAP_DIR=\"$(autofsmapdir)\" + CFLAGS += -DAUTOFS_CONF_DIR=\"$(autofsconfdir)\" + ++ifeq ($(LDAP), 1) ++ CFLAGS += $(XML_FLAGS) $(XML_LIBS) ++endif ++ + .PHONY: all install clean + + all: autofs.a +--- autofs-5.0.7.orig/modules/Makefile ++++ autofs-5.0.7/modules/Makefile +@@ -45,10 +45,12 @@ endif + ifeq ($(LDAP), 1) + SRCS += lookup_ldap.c + MODS += lookup_ldap.so ++ LDAP_FLAGS += $(XML_FLAGS) -DLDAP_THREAD_SAFE ++ LIBLDAP += $(XML_LIBS) + ifeq ($(SASL), 1) + SASL_OBJ = cyrus-sasl.o cyrus-sasl-extern.o +- LDAP_FLAGS += $(SASL_FLAGS) $(XML_FLAGS) $(KRB5_FLAGS) -DLDAP_THREAD_SAFE +- LIBLDAP += $(LIBSASL) $(XML_LIBS) $(KRB5_LIBS) ++ LDAP_FLAGS += $(SASL_FLAGS) $(KRB5_FLAGS) ++ LIBLDAP += $(LIBSASL) $(KRB5_LIBS) + endif + endif + +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -66,6 +66,7 @@ struct ldap_search_params { + + static int decode_percent_hack(const char *, char **); + ++#ifdef WITH_SASL + static int set_env(unsigned logopt, const char *name, const char *val) + { + int ret = setenv(name, val, 1); +@@ -75,6 +76,7 @@ static int set_env(unsigned logopt, cons + } + return 1; + } ++#endif + + #ifndef HAVE_LDAP_CREATE_PAGE_CONTROL + int ldap_create_page_control(LDAP *ldap, ber_int_t pagesize, +@@ -183,9 +185,9 @@ int unbind_ldap_connection(unsigned logo + { + int rv; + +-#ifdef WITH_SASL + if (ctxt->use_tls == LDAP_TLS_RELEASE) + ctxt->use_tls = LDAP_TLS_INIT; ++#ifdef WITH_SASL + autofs_sasl_unbind(ctxt); + #endif + +@@ -243,7 +245,6 @@ LDAP *init_ldap_connection(unsigned logo + info(logopt, MODPREFIX "failed to set connection timeout to %d", + net_timeout.tv_sec); + +-#ifdef WITH_SASL + if (ctxt->use_tls) { + if (ctxt->version == 2) { + if (ctxt->tls_required) { +@@ -272,7 +273,6 @@ LDAP *init_ldap_connection(unsigned logo + } + ctxt->use_tls = LDAP_TLS_RELEASE; + } +-#endif + + return ldap; + } +@@ -585,10 +585,12 @@ static LDAP *do_connect(unsigned logopt, + { + LDAP *ldap; + ++#ifdef WITH_SASL + if (ctxt->extern_cert && ctxt->extern_key) { + set_env(logopt, ENV_LDAPTLS_CERT, ctxt->extern_cert); + set_env(logopt, ENV_LDAPTLS_KEY, ctxt->extern_key); + } ++#endif + + ldap = init_ldap_connection(logopt, uri, ctxt); + if (ldap) { +@@ -791,7 +793,6 @@ find_server: + return ldap; + } + +-#ifdef WITH_SASL + int get_property(unsigned logopt, xmlNodePtr node, const char *prop, char **value) + { + xmlChar *ret; +@@ -812,6 +813,7 @@ int get_property(unsigned logopt, xmlNod + return 0; + } + ++#ifdef WITH_SASL + /* + * For plain text, login and digest-md5 authentication types, we need + * user and password credentials. +@@ -824,6 +826,7 @@ int authtype_requires_creds(const char * + return 1; + return 0; + } ++#endif + + /* + * Returns: +@@ -1056,6 +1059,7 @@ auth_fail: + } + } else if (auth_required == LDAP_AUTH_REQUIRED && + (authtype && !strncmp(authtype, "EXTERNAL", 8))) { ++#ifdef WITH_SASL + ret = get_property(logopt, root, "external_cert", &extern_cert); + ret |= get_property(logopt, root, "external_key", &extern_key); + /* +@@ -1074,6 +1078,7 @@ auth_fail: + if (extern_key) + free(extern_key); + } ++#endif + } + + /* +@@ -1094,8 +1099,10 @@ auth_fail: + ctxt->secret = secret; + ctxt->client_princ = client_princ; + ctxt->client_cc = client_cc; ++#ifdef WITH_SASL + ctxt->extern_cert = extern_cert; + ctxt->extern_key = extern_key; ++#endif + + debug(logopt, MODPREFIX + "ldap authentication configured with the following options:"); +@@ -1127,7 +1134,6 @@ out: + + return ret; + } +-#endif + + /* + * Take an input string as specified in the master map, and break it +@@ -1390,10 +1396,12 @@ static void free_context(struct lookup_c + defaults_free_searchdns(ctxt->sdns); + if (ctxt->dclist) + free_dclist(ctxt->dclist); ++#ifdef WITH_SASL + if (ctxt->extern_cert) + free(ctxt->extern_cert); + if (ctxt->extern_key) + free(ctxt->extern_key); ++#endif + free(ctxt); + + return; diff --git a/SOURCES/autofs-5.0.7-fix-crash-due-to-thread-unsafe-use-of-libldap.patch b/SOURCES/autofs-5.0.7-fix-crash-due-to-thread-unsafe-use-of-libldap.patch new file mode 100644 index 0000000..0de22a3 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-crash-due-to-thread-unsafe-use-of-libldap.patch @@ -0,0 +1,117 @@ +autofs-5.0.7 - fix crash due to thread unsafe use of libldap + +From: Leonardo Chiquitto + +Add locking around LDAP initialization calls + +To prevent corruption inside SSL and LDAP libraries, it's necessary to +serialize all calls to functions that initialize LDAP contexts. + +How to reproduce the problem: + +- Setup an LDAP server with SSL/TLS support enabled +- Configure AutoFS to fetch the maps from LDAP +- Make sure the OpenLDAP client library is configured to use SSL + connections and "usetls" is set to yes in autofs_ldap_auth.conf. + +In one directory handled by AutoFS (an indirect mount point), trigger in +parallel some dozens of invalid mounts (ie, try to access keys that do not +exist in the AutoFS map). Repeat until it crashes. + +Here it always crashes in less than 20 minutes, normally inside OpenSSL. +Core dump inspection shows that internal SSL structures are corrupted, +with function pointers pointing to random addresses. + +Trying to find similar reports on the web, I found this email from an +OpenLDAP developer (partial quote, emphasis mine) [1]: + +"As far as I know, libldap is thread safe in the sense that multiple +threads can use separate LDAP* handles without running into concurrency +issues; *except for library initialization*, all accesses to common data +(i.e. global variables) is read-only." + +[1]http://www.openldap.org/cgi-bin/wilma_hiliter/openldap-software/200606/msg00252.html + +AutoFS implements no locking around LDAP initialization libraries and +it's quite common to see multiple threads executing ldap_initialize() +or ldap_start_tls_s() at the same time. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 35 ++++++++++++++++++++++++++++++++++- + 2 files changed, 35 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -105,6 +105,7 @@ + - fix incorrect append options description in README.v5-release. + - fix mistake in assignment. + - use open(2) instead of access(2) to trigger dependent mounts. ++- fix crash due to thread unsafe use of libldap. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -52,6 +52,12 @@ static struct ldap_schema common_schema[ + }; + static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema); + ++/* ++ * Initialization of LDAP and OpenSSL must be always serialized to ++ * avoid corruption of context structures inside these libraries. ++ */ ++pthread_mutex_t ldapinit_mutex = PTHREAD_MUTEX_INITIALIZER; ++ + struct ldap_search_params { + struct autofs_point *ap; + LDAP *ldap; +@@ -138,6 +144,22 @@ int ldap_parse_page_control(LDAP *ldap, + } + #endif /* HAVE_LDAP_PARSE_PAGE_CONTROL */ + ++static void ldapinit_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&ldapinit_mutex); ++ if (status) ++ fatal(status); ++ return; ++} ++ ++static void ldapinit_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&ldapinit_mutex); ++ if (status) ++ fatal(status); ++ return; ++} ++ + static void uris_mutex_lock(struct lookup_context *ctxt) + { + int status = pthread_mutex_lock(&ctxt->uris_mutex); +@@ -198,7 +220,7 @@ int unbind_ldap_connection(unsigned logo + 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 }; +@@ -276,6 +298,17 @@ LDAP *init_ldap_connection(unsigned logo + + 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) + { diff --git a/SOURCES/autofs-5.0.7-fix-dumpmaps-multi-output.patch b/SOURCES/autofs-5.0.7-fix-dumpmaps-multi-output.patch new file mode 100644 index 0000000..fd2898e --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-dumpmaps-multi-output.patch @@ -0,0 +1,108 @@ +autofs-5.0.7 - fix dumpmaps multi output + +From: Ian Kent + +If the maps contain the old style "multi" type the dumped map information +isn't right. +--- + CHANGELOG | 1 + lib/master.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 50 insertions(+), 12 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -58,6 +58,7 @@ + - add after sssd dependency to unit file. + - fix syncronize handle_mounts() shutdown. + - fix fix wildcard multi map regression. ++- fix dumpmaps multi output. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -1281,6 +1281,54 @@ static void list_source_instances(struct + return; + } + ++static void print_map_info(struct map_source *source) ++{ ++ int argc = source->argc; ++ int i, multi, map_num; ++ ++ multi = (source->type && !strcmp(source->type, "multi")); ++ map_num = 1; ++ for (i = 0; i < argc; i++) { ++ if (source->argv[i] && *source->argv[i] != '-') { ++ if (!multi) ++ printf(" map: %s\n", source->argv[i]); ++ else ++ printf(" map[%i]: %s\n", map_num, source->argv[i]); ++ i++; ++ } ++ ++ if (i >= argc) ++ return; ++ ++ if (!strcmp(source->argv[i], "--")) ++ continue; ++ ++ if (source->argv[i]) { ++ int need_newline = 0; ++ int j; ++ ++ if (!multi) ++ printf(" arguments:"); ++ else ++ printf(" arguments[%i]:", map_num); ++ ++ for (j = i; j < source->argc; j++) { ++ if (!strcmp(source->argv[j], "--")) ++ break; ++ printf(" %s", source->argv[j]); ++ i++; ++ need_newline = 1; ++ } ++ if (need_newline) ++ printf("\n"); ++ } ++ if (multi) ++ map_num++; ++ } ++ ++ return; ++} ++ + int master_show_mounts(struct master *master) + { + struct list_head *p, *head; +@@ -1311,7 +1359,6 @@ int master_show_mounts(struct master *ma + struct autofs_point *ap; + time_t now = time(NULL); + unsigned int count = 0; +- int i; + + this = list_entry(p, struct master_mapent, list); + p = p->next; +@@ -1357,20 +1404,10 @@ int master_show_mounts(struct master *ma + } + + if (source->argc >= 1) { +- i = 0; +- if (source->argv[0] && *source->argv[0] != '-') { +- printf(" map: %s\n", source->argv[0]); +- i = 1; +- } ++ print_map_info(source); + if (count && ap->type == LKP_INDIRECT) + printf(" duplicate indirect map entry" + " will be ignored at run time\n"); +- if (source->argc > 1) { +- printf(" arguments: "); +- for (; i < source->argc; i++) +- printf("%s ", source->argv[i]); +- printf("\n"); +- } + } + + printf("\n"); diff --git a/SOURCES/autofs-5.0.7-fix-fcntl-return-check.patch b/SOURCES/autofs-5.0.7-fix-fcntl-return-check.patch new file mode 100644 index 0000000..ebe9ea8 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-fcntl-return-check.patch @@ -0,0 +1,25 @@ +autofs-5.0.7 - fix fcntl return check + +From: Ian Kent + +When checking for FD_CLOEXEC support the return of the fcntl(2) call to +get the file descriptor flags is not checked which could result in an +incorrect result. +--- + include/automount.h | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/include/automount.h b/include/automount.h +index e72fa0d..6ced842 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -547,7 +547,8 @@ static inline void check_cloexec(int fd) + { + if (cloexec_works == 0) { + int fl = fcntl(fd, F_GETFD); +- cloexec_works = (fl & FD_CLOEXEC) ? 1 : -1; ++ if (fl != -1) ++ cloexec_works = (fl & FD_CLOEXEC) ? 1 : -1; + } + if (cloexec_works > 0) + return; diff --git a/SOURCES/autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch b/SOURCES/autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch new file mode 100644 index 0000000..8ce6c0f --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch @@ -0,0 +1,179 @@ +autofs-5.0.7 - fix file descriptor leak when reloading the daemon + +From: Leonardo Chiquitto + +A customer reported that AutoFS may leak file descriptors when some +maps are modified and the daemon reloaded. I'm able to reproduce the +problem on 5.0.7 by following these steps: + +1. Configure a simple direct mount: + +# cat /etc/auto.master +/- /etc/auto.direct + +# cat /etc/auto.direct +/nfs server:/nfs + +2. Start the automounter and do NOT trigger the mount + +3. Replace /etc/auto.direct with: + +# cat /etc/auto.direct +/nfs/1 server:/nfs +/nfs/2 server:/nfs + +4. Reload: + +# kill -HUP $(pidof automount) + +>From now on, every reload will leak a file descriptor: + +# ls -la /proc/$(pidof automount)/fd | grep /nfs +lr-x------ 1 root root 64 Aug 14 22:08 11 -> /nfs +lr-x------ 1 root root 64 Aug 14 22:08 12 -> /nfs +lr-x------ 1 root root 64 Aug 14 22:08 13 -> /nfs +lr-x------ 1 root root 64 Aug 14 22:08 14 -> /nfs +lr-x------ 1 root root 64 Aug 14 22:08 5 -> /nfs + +I've investigated the problem and discovered that the leak happens in +do_umount_autofs_direct(): + +- edit imk +The same leak is present in umount_autofs_offset() also. +Updated patch to cover that too. +- end edit + +int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list +*mnts, struct mapent *me) +{ +(...) + if (me->ioctlfd != -1) { + if (tree_is_mounted(mnts, me->key, MNTS_REAL)) { + error(ap->logopt, + "attempt to umount busy direct mount %s", + me->key); + return 1; + } + ioctlfd = me->ioctlfd; + } else // ioctlfd == -1 + ops->open(ap->logopt, &ioctlfd, me->dev, me->key); <= we open it here + + if (ioctlfd >= 0) { + unsigned int status = 1; + + rv = ops->askumount(ap->logopt, ioctlfd, &status); + /// at this point, rv == 0 and status == 0 + if (rv) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, "ioctl failed: %s", estr); + return 1; + } else if (!status) { + /// at this point, ap->state == ST_READMAP + if (ap->state != ST_SHUTDOWN_FORCE) { + error(ap->logopt, + "ask umount returned busy for %s", + me->key); + return 1; <= we return here, without closing the fd + } else { + me->ioctlfd = -1; + ops->catatonic(ap->logopt, ioctlfd); + ops->close(ap->logopt, ioctlfd); + goto force_umount; + } +(...) +--- + CHANGELOG | 1 + + daemon/direct.c | 19 ++++++++++++++++--- + 2 files changed, 17 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 46ef335..a7ed212 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -30,6 +30,7 @@ + - workaround missing GNU versionsort extension. + - dont fail on master map self include. + - fix wildcard multi map regression. ++- fix file descriptor leak when reloading the daemon. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/daemon/direct.c b/daemon/direct.c +index 3e09c5d..228a666 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -86,7 +86,8 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru + { + struct ioctl_ops *ops = get_ioctl_ops(); + char buf[MAX_ERR_BUF]; +- int ioctlfd, rv, left, retries; ++ int ioctlfd = -1, rv, left, retries; ++ int opened = 0; + + left = umount_multi(ap, me->key, 0); + if (left) { +@@ -103,8 +104,10 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru + return 1; + } + ioctlfd = me->ioctlfd; +- } else ++ } else { + ops->open(ap->logopt, &ioctlfd, me->dev, me->key); ++ opened = 1; ++ } + + if (ioctlfd >= 0) { + unsigned int status = 1; +@@ -113,12 +116,16 @@ int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, stru + if (rv) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, "ioctl failed: %s", estr); ++ if (opened && ioctlfd != -1) ++ ops->close(ap->logopt, ioctlfd); + return 1; + } else if (!status) { + if (ap->state != ST_SHUTDOWN_FORCE) { + error(ap->logopt, + "ask umount returned busy for %s", + me->key); ++ if (opened && ioctlfd != -1) ++ ops->close(ap->logopt, ioctlfd); + return 1; + } else { + me->ioctlfd = -1; +@@ -536,7 +543,8 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) + { + struct ioctl_ops *ops = get_ioctl_ops(); + char buf[MAX_ERR_BUF]; +- int ioctlfd, rv = 1, retries; ++ int ioctlfd = -1, rv = 1, retries; ++ int opened = 0; + + if (me->ioctlfd != -1) { + if (is_mounted(_PATH_MOUNTED, me->key, MNTS_REAL)) { +@@ -554,6 +562,7 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) + return 0; + } + ops->open(ap->logopt, &ioctlfd, me->dev, me->key); ++ opened = 1; + } + + if (ioctlfd >= 0) { +@@ -563,6 +572,8 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) + if (rv) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("ioctl failed: %s", estr); ++ if (opened && ioctlfd != -1) ++ ops->close(ap->logopt, ioctlfd); + return 1; + } else if (!status) { + if (ap->state != ST_SHUTDOWN_FORCE) { +@@ -570,6 +581,8 @@ int umount_autofs_offset(struct autofs_point *ap, struct mapent *me) + error(ap->logopt, + "ask umount returned busy for %s", + me->key); ++ if (opened && ioctlfd != -1) ++ ops->close(ap->logopt, ioctlfd); + return 1; + } else { + me->ioctlfd = -1; diff --git a/SOURCES/autofs-5.0.7-fix-fix-map-entry-duplicate-offset-detection.patch b/SOURCES/autofs-5.0.7-fix-fix-map-entry-duplicate-offset-detection.patch new file mode 100644 index 0000000..82092c0 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-fix-map-entry-duplicate-offset-detection.patch @@ -0,0 +1,37 @@ +autofs-5.0.7 - fix fix map entry duplicate offset detection + +From: Ian Kent + +Map entry duplicate detection was still broken. +This hopefully will fix it, at least the Conectathon duplicate offset entry +tests pass now. +--- + CHANGELOG | 1 + + lib/cache.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index e15aa1f..39d7889 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -47,6 +47,7 @@ + - dont probe rdma mounts. + - fix master map mount options matching. + - fix master map bogus keywork match. ++- fix fix map entry duplicate offset detection. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/cache.c b/lib/cache.c +index 1e05a99..ecace4a 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -659,7 +659,7 @@ int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *k + + me = cache_lookup_distinct(mc, key); + if (me && me->age == age) { +- if (me->multi == owner) ++ if (me == owner || strcmp(me->key, key) == 0) + return CHE_DUPLICATE; + } + diff --git a/SOURCES/autofs-5.0.7-fix-fix-wildcard-multi-map-regression.patch b/SOURCES/autofs-5.0.7-fix-fix-wildcard-multi-map-regression.patch new file mode 100644 index 0000000..22ff41a --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-fix-wildcard-multi-map-regression.patch @@ -0,0 +1,283 @@ +autofs-5.0.7 - fix fix wildcard multi map regression + +From: Ian Kent + +A recent patch to fix a wildcard multi map mount regression has a +side effect of causing a deadlock at startup when trying to re-connect +to existing mounts. + +The patch required the map entry cache write lock be taken so the cache +could be updated. But when starting and trying to re-connect to existing +mounts there's no need to update the cache. +--- + CHANGELOG | 1 + + modules/lookup_file.c | 25 ++++++++++++++++++++----- + modules/lookup_ldap.c | 23 +++++++++++++++++++---- + modules/lookup_nisplus.c | 26 +++++++++++++++++++++----- + modules/lookup_sss.c | 22 ++++++++++++++++++---- + modules/lookup_yp.c | 23 +++++++++++++++++++---- + 6 files changed, 98 insertions(+), 22 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -57,6 +57,7 @@ + - fix a couple of compiler warnings. + - add after sssd dependency to unit file. + - fix syncronize handle_mounts() shutdown. ++- fix fix wildcard multi map regression. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_file.c ++++ autofs-5.0.7/modules/lookup_file.c +@@ -1042,7 +1042,7 @@ int lookup_mount(struct autofs_point *ap + return NSS_STATUS_UNAVAIL; + } + +- cache_writelock(mc); ++ cache_readlock(mc); + me = cache_lookup_first(mc); + if (me && st.st_mtime <= me->age) { + /* +@@ -1084,7 +1084,18 @@ int lookup_mount(struct autofs_point *ap + } + } + +- cache_writelock(mc); ++ /* ++ * We can't take the writelock for direct mounts. If we're ++ * starting up or trying to re-connect to an existing direct ++ * mount we could be iterating through the map entries with ++ * the readlock held. But we don't need to update the cache ++ * when we're starting up so just take the readlock in that ++ * case. ++ */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ cache_readlock(mc); ++ else ++ cache_writelock(mc); + do_cache_lookup: + me = cache_lookup(mc, key); + /* +@@ -1102,10 +1113,11 @@ do_cache_lookup: + } + if (me && me->mapent) { + /* +- * Add wildcard match for later validation checks and +- * negative cache lookups. ++ * If this is a lookup add wildcard match for later validation ++ * checks and negative cache lookups. + */ +- if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ if (!(ap->flags & MOUNT_FLAG_REMOUNT) && ++ ap->type == LKP_INDIRECT && *me->key == '*') { + ret = cache_update(mc, source, key, me->mapent, me->age); + if (!(ret & (CHE_OK | CHE_UPDATED))) + me = NULL; +@@ -1130,6 +1142,9 @@ do_cache_lookup: + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); + if (ret) { ++ /* Don't update negative cache when re-connecting */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ return NSS_STATUS_TRYAGAIN; + cache_writelock(mc); + cache_update_negative(mc, source, key, ap->negative_timeout); + cache_unlock(mc); +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -2975,7 +2975,18 @@ int lookup_mount(struct autofs_point *ap + return status; + } + +- cache_writelock(mc); ++ /* ++ * We can't take the writelock for direct mounts. If we're ++ * starting up or trying to re-connect to an existing direct ++ * mount we could be iterating through the map entries with ++ * the readlock held. But we don't need to update the cache ++ * when we're starting up so just take the readlock in that ++ * case. ++ */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ cache_readlock(mc); ++ else ++ cache_writelock(mc); + me = cache_lookup(mc, key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { +@@ -2987,10 +2998,11 @@ int lookup_mount(struct autofs_point *ap + } + if (me && me->mapent) { + /* +- * Add wildcard match for later validation checks and +- * negative cache lookups. ++ * If this is a lookup add wildcard match for later validation ++ * checks and negative cache lookups. + */ +- if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ if (!(ap->flags & MOUNT_FLAG_REMOUNT) && ++ ap->type == LKP_INDIRECT && *me->key == '*') { + ret = cache_update(mc, source, key, me->mapent, me->age); + if (!(ret & (CHE_OK | CHE_UPDATED))) + me = NULL; +@@ -3012,6 +3024,9 @@ int lookup_mount(struct autofs_point *ap + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); + if (ret) { ++ /* Don't update negative cache when re-connecting */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ return NSS_STATUS_TRYAGAIN; + cache_writelock(mc); + cache_update_negative(mc, source, key, ap->negative_timeout); + cache_unlock(mc); +--- autofs-5.0.7.orig/modules/lookup_nisplus.c ++++ autofs-5.0.7/modules/lookup_nisplus.c +@@ -561,7 +561,18 @@ int lookup_mount(struct autofs_point *ap + return status; + } + +- cache_writelock(mc); ++ /* ++ * We can't take the writelock for direct mounts. If we're ++ * starting up or trying to re-connect to an existing direct ++ * mount we could be iterating through the map entries with ++ * the readlock held. But we don't need to update the cache ++ * when we're starting up so just take the readlock in that ++ * case. ++ */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ cache_readlock(mc); ++ else ++ cache_writelock(mc); + me = cache_lookup(mc, key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { +@@ -573,10 +584,11 @@ int lookup_mount(struct autofs_point *ap + } + if (me && me->mapent) { + /* +- * Add wildcard match for later validation checks and +- * negative cache lookups. ++ * If this is a lookup add wildcard match for later validation ++ * checks and negative cache lookups. + */ +- if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ if (!(ap->flags & MOUNT_FLAG_REMOUNT) && ++ ap->type == LKP_INDIRECT && *me->key == '*') { + ret = cache_update(mc, source, key, me->mapent, me->age); + if (!(ret & (CHE_OK | CHE_UPDATED))) + me = NULL; +@@ -603,6 +615,11 @@ int lookup_mount(struct autofs_point *ap + time_t now = time(NULL); + int rv = CHE_OK; + ++ free(mapent); ++ ++ /* Don't update negative cache when re-connecting */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ return NSS_STATUS_TRYAGAIN; + cache_writelock(mc); + me = cache_lookup_distinct(mc, key); + if (!me) +@@ -612,7 +629,6 @@ int lookup_mount(struct autofs_point *ap + me->status = time(NULL) + ap->negative_timeout; + } + cache_unlock(mc); +- free(mapent); + return NSS_STATUS_TRYAGAIN; + } + free(mapent); +--- autofs-5.0.7.orig/modules/lookup_sss.c ++++ autofs-5.0.7/modules/lookup_sss.c +@@ -635,7 +635,17 @@ int lookup_mount(struct autofs_point *ap + return status; + } + +- cache_readlock(mc); ++ /* ++ * We can't take the writelock for direct mounts. If we're ++ * starting up or trying to re-connect to an existing direct ++ * mount we could be iterating through the map entries with ++ * the readlock held. But we don't need to update the cache ++ * when we're starting up so just take the readlock in that ++ */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ cache_writelock(mc); ++ else ++ cache_readlock(mc); + me = cache_lookup(mc, key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { +@@ -647,10 +657,11 @@ int lookup_mount(struct autofs_point *ap + } + if (me && me->mapent) { + /* +- * Add wildcard match for later validation checks and +- * negative cache lookups. ++ * If this is a lookup add wildcard match for later validation ++ * checks and negative cache lookups. + */ +- if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ if (ap->type == LKP_INDIRECT && *me->key == '*' && ++ !(ap->flags & MOUNT_FLAG_REMOUNT)) { + ret = cache_update(mc, source, key, me->mapent, me->age); + if (!(ret & (CHE_OK | CHE_UPDATED))) + me = NULL; +@@ -672,6 +683,9 @@ int lookup_mount(struct autofs_point *ap + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); + if (ret) { ++ /* Don't update negative cache when re-connecting */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ return NSS_STATUS_TRYAGAIN; + cache_writelock(mc); + cache_update_negative(mc, source, key, ap->negative_timeout); + cache_unlock(mc); +--- autofs-5.0.7.orig/modules/lookup_yp.c ++++ autofs-5.0.7/modules/lookup_yp.c +@@ -662,7 +662,18 @@ int lookup_mount(struct autofs_point *ap + return status; + } + +- cache_writelock(mc); ++ /* ++ * We can't take the writelock for direct mounts. If we're ++ * starting up or trying to re-connect to an existing direct ++ * mount we could be iterating through the map entries with ++ * the readlock held. But we don't need to update the cache ++ * when we're starting up so just take the readlock in that ++ * case. ++ */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ cache_readlock(mc); ++ else ++ cache_writelock(mc); + me = cache_lookup(mc, key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { +@@ -674,10 +685,11 @@ int lookup_mount(struct autofs_point *ap + } + if (me && me->mapent) { + /* +- * Add wildcard match for later validation checks and +- * negative cache lookups. ++ * If this is a lookup add wildcard match for later validation ++ * checks and negative cache lookups. + */ +- if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ if (ap->type == LKP_INDIRECT && *me->key == '*' && ++ !(ap->flags & MOUNT_FLAG_REMOUNT)) { + ret = cache_update(mc, source, key, me->mapent, me->age); + if (!(ret & (CHE_OK | CHE_UPDATED))) + me = NULL; +@@ -698,6 +710,9 @@ int lookup_mount(struct autofs_point *ap + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); + if (ret) { ++ /* Don't update negative cache when re-connecting */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ return NSS_STATUS_TRYAGAIN; + cache_writelock(mc); + cache_update_negative(mc, source, key, ap->negative_timeout); + cache_unlock(mc); diff --git a/SOURCES/autofs-5.0.7-fix-get_nfs_info-probe.patch b/SOURCES/autofs-5.0.7-fix-get_nfs_info-probe.patch new file mode 100644 index 0000000..88b82b9 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-get_nfs_info-probe.patch @@ -0,0 +1,94 @@ +autofs-5.0.7 - fix get_nfs_info() probe + +From: Ian Kent + +A recent contributed patch series changed the behaviour of server +probing to use port specification in the same way as mount.nfs(8). + +Unfortunately, if NFSv2 only is to be probed and the NFS port +needs to be obtained, the probe fails unconditionally because +no rpc client has yet been created. +--- + CHANGELOG | 1 + + modules/replicated.c | 32 ++++++++++++++++++++------------ + 2 files changed, 21 insertions(+), 12 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -61,6 +61,7 @@ + - fix dumpmaps multi output. + - try and cleanup after dumpmaps. + - teach dumpmaps to output simple key value pairs. ++- fix get_nfs_info() probe. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/replicated.c ++++ autofs-5.0.7/modules/replicated.c +@@ -444,6 +444,11 @@ static unsigned int get_nfs_info(unsigne + host->name, proto, version); + + rpc_info->proto = proto; ++ if (port < 0) ++ rpc_info->port = NFS_PORT; ++ else if (port > 0) ++ rpc_info->port = port; ++ + memset(&parms, 0, sizeof(struct pmap)); + parms.pm_prog = NFS_PROGRAM; + parms.pm_prot = proto; +@@ -451,11 +456,7 @@ static unsigned int get_nfs_info(unsigne + if (!(version & NFS4_REQUESTED)) + goto v3_ver; + +- if (port < 0) +- rpc_info->port = NFS_PORT; +- else if (port > 0) +- rpc_info->port = port; +- else { ++ if (!port) { + status = rpc_portmap_getclient(pm_info, + host->name, host->addr, host->addr_len, + proto, RPC_CLOSE_DEFAULT); +@@ -515,7 +516,7 @@ v3_ver: + if (!(version & NFS3_REQUESTED)) + goto v2_ver; + +- if (port <= 0 && !(version & NFS4_REQUESTED && port == 0)) { ++ if (!port && !pm_info->client) { + status = rpc_portmap_getclient(pm_info, + host->name, host->addr, host->addr_len, + proto, RPC_CLOSE_DEFAULT); +@@ -526,9 +527,7 @@ v3_ver: + goto done_ver; + } + +- if (port > 0) +- rpc_info->port = port; +- else { ++ if (!port) { + parms.pm_vers = NFS3_VERSION; + status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port); + if (status == -EHOSTUNREACH || status == -ETIMEDOUT) { +@@ -573,9 +572,18 @@ v2_ver: + if (!(version & NFS2_REQUESTED)) + goto done_ver; + +- if (port > 0) +- rpc_info->port = port; +- else { ++ if (!port && !pm_info->client) { ++ status = rpc_portmap_getclient(pm_info, ++ host->name, host->addr, host->addr_len, ++ proto, RPC_CLOSE_DEFAULT); ++ if (status == -EHOSTUNREACH) { ++ supported = status; ++ goto done_ver; ++ } else if (status) ++ goto done_ver; ++ } ++ ++ if (!port) { + parms.pm_vers = NFS2_VERSION; + status = rpc_portmap_getport(pm_info, &parms, &rpc_info->port); + if (status == -EHOSTUNREACH || status == -ETIMEDOUT) { diff --git a/SOURCES/autofs-5.0.7-fix-host_addr-null-reference-in-add_new_host.patch b/SOURCES/autofs-5.0.7-fix-host_addr-null-reference-in-add_new_host.patch new file mode 100644 index 0000000..45bd53f --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-host_addr-null-reference-in-add_new_host.patch @@ -0,0 +1,55 @@ +autofs-5.0.7 - fix host_addr null reference in add_new_host() + +From: Ian Kent + +The function add_new_host() is always called from a loop that depends +on host_addr being non-null. + +Remove the redundant check. +--- + modules/replicated.c | 29 ++++++++++------------------- + 1 file changed, 10 insertions(+), 19 deletions(-) + +diff --git a/modules/replicated.c b/modules/replicated.c +index 0a044b9..e793ca4 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -1030,28 +1030,19 @@ static int add_new_host(struct host **list, + unsigned int prx; + int addr_len; + ++ prx = get_proximity(host_addr->ai_addr); ++ + /* +- * If we are using random selection we pretend all hosts are at +- * the same proximity so hosts further away don't get excluded. +- * We can't use PROXIMITY_LOCAL or we won't perform an RPC ping +- * to remove hosts that may be down. ++ * If we want the weight to be the determining factor ++ * when selecting a host, or we are using random selection, ++ * then all hosts must have the same proximity. However, ++ * if this is the local machine it should always be used ++ * since it is certainly available. + */ +- if (!host_addr) ++ if (prx != PROXIMITY_LOCAL && ++ (options & (MOUNT_FLAG_USE_WEIGHT_ONLY | ++ MOUNT_FLAG_RANDOM_SELECT))) + prx = PROXIMITY_SUBNET; +- else { +- prx = get_proximity(host_addr->ai_addr); +- /* +- * If we want the weight to be the determining factor +- * when selecting a host, or we are using random selection, +- * then all hosts must have the same proximity. However, +- * if this is the local machine it should always be used +- * since it is certainly available. +- */ +- if (prx != PROXIMITY_LOCAL && +- (options & (MOUNT_FLAG_USE_WEIGHT_ONLY | +- MOUNT_FLAG_RANDOM_SELECT))) +- prx = PROXIMITY_SUBNET; +- } + + /* + * If we tried to add an IPv6 address and we don't have IPv6 diff --git a/SOURCES/autofs-5.0.7-fix-inconsistent-signed-usage-for-__rpc_ping.patch b/SOURCES/autofs-5.0.7-fix-inconsistent-signed-usage-for-__rpc_ping.patch new file mode 100644 index 0000000..661685f --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-inconsistent-signed-usage-for-__rpc_ping.patch @@ -0,0 +1,41 @@ +autofs-5.0.7 - fix inconsistent signed usage for __rpc_ping() + +From: Ian Kent + +There is some incosistent usage of unsigned int variables with the usage +of __rpc_ping(). +--- + lib/rpc_subs.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 718caf9..f5742e8 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -670,13 +670,11 @@ int rpc_ping_proto(struct conn_info *info) + return 1; + } + +-static unsigned int __rpc_ping(const char *host, +- unsigned long version, +- int proto, +- long seconds, long micros, +- unsigned int option) ++static int __rpc_ping(const char *host, ++ unsigned long version, int proto, ++ long seconds, long micros, unsigned int option) + { +- unsigned int status; ++ int status; + struct conn_info info; + struct pmap parms; + +@@ -713,7 +711,7 @@ int rpc_ping(const char *host, long seconds, long micros, unsigned int option) + { + unsigned long vers3 = NFS3_VERSION; + unsigned long vers2 = NFS2_VERSION; +- unsigned int status; ++ int status; + + status = __rpc_ping(host, vers2, IPPROTO_UDP, seconds, micros, option); + if (status > 0) diff --git a/SOURCES/autofs-5.0.7-fix-inconsistent-use-of-cache-lock-in-handle_packet_missing_direct.patch b/SOURCES/autofs-5.0.7-fix-inconsistent-use-of-cache-lock-in-handle_packet_missing_direct.patch new file mode 100644 index 0000000..9d59e34 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-inconsistent-use-of-cache-lock-in-handle_packet_missing_direct.patch @@ -0,0 +1,23 @@ +autofs-5.0.7 - fix inconsistent use of cache lock in handle_packet_missing_direct() + +From: Ian Kent + +All references here except this one refer to the same variable so change the odd +one out for consistency. +--- + daemon/direct.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/daemon/direct.c b/daemon/direct.c +index 228a666..399ad0a 100644 +--- a/daemon/direct.c ++++ b/daemon/direct.c +@@ -1392,7 +1392,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_ + ops->send_fail(ap->logopt, + ioctlfd, pkt->wait_queue_token, -ENOENT); + ops->close(ap->logopt, ioctlfd); +- cache_unlock(me->mc); ++ cache_unlock(mc); + master_source_unlock(ap->entry); + master_mutex_unlock(); + pthread_setcancelstate(state, NULL); diff --git a/SOURCES/autofs-5.0.7-fix-incorrect-check-in-flag_is_owned.patch b/SOURCES/autofs-5.0.7-fix-incorrect-check-in-flag_is_owned.patch new file mode 100644 index 0000000..63312f8 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-incorrect-check-in-flag_is_owned.patch @@ -0,0 +1,30 @@ +autofs-5.0.7 - fix incorrect check in flag_is_owned() + +From: Ian Kent + +The flag file code isn't used any more but this is clearly incorrect +so fix it in case it gets used sometime in the future. +--- + daemon/flag.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/daemon/flag.c b/daemon/flag.c +index f8fe163..db9a4bd 100644 +--- a/daemon/flag.c ++++ b/daemon/flag.c +@@ -66,12 +66,11 @@ static int flag_is_owned(int fd) + + continue; + } +- +- /* Stale flagfile */ +- if (!tries) +- return 0; + } + ++ /* Stale flagfile */ ++ if (!tries) ++ return 0; + + if (pid) { + int ret; diff --git a/SOURCES/autofs-5.0.7-fix-incorrect-name-in-test.patch b/SOURCES/autofs-5.0.7-fix-incorrect-name-in-test.patch new file mode 100644 index 0000000..bce7c45 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-incorrect-name-in-test.patch @@ -0,0 +1,22 @@ +autofs-5.0.7 - fix incorrect var name in test + +From: Ian Kent + +Fix incorrect variable name used for test of buffer size for getgrgid_r. +--- + lib/mounts.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/mounts.c b/lib/mounts.c +index 550445c..0caa0aa 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -1222,7 +1222,7 @@ void set_tsd_user_vars(unsigned int logopt, uid_t uid, gid_t gid) + /* Try to get group info */ + + grplen = sysconf(_SC_GETGR_R_SIZE_MAX); +- if (tmplen < 0) { ++ if (grplen < 0) { + error(logopt, "failed to get buffer size for getgrgid_r"); + goto free_tsv_home; + } diff --git a/SOURCES/autofs-5.0.7-fix-incorrect-value-reference-in-parse_line.patch b/SOURCES/autofs-5.0.7-fix-incorrect-value-reference-in-parse_line.patch new file mode 100644 index 0000000..a9c2031 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-incorrect-value-reference-in-parse_line.patch @@ -0,0 +1,22 @@ +autofs-5.0.7 - fix incorrect value reference in parse_line() + +From: Ian Kent + +This chack should clearly be on the contents of key not the pointer value. +--- + lib/defaults.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/lib/defaults.c b/lib/defaults.c +index 1e89509..7c65387 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -167,7 +167,7 @@ static int parse_line(char *line, char **res, char **value) + while (*key && *key == ' ') + key++; + +- if (!key) ++ if (!*key) + return 0; + + if (!(val = strchr(key, '='))) diff --git a/SOURCES/autofs-5.0.7-fix-init-script-status-return.patch b/SOURCES/autofs-5.0.7-fix-init-script-status-return.patch new file mode 100644 index 0000000..a08d62f --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-init-script-status-return.patch @@ -0,0 +1,39 @@ +autofs-5.0.7 - fix init script status return + +From: Ian Kent + +The patch that added the piddir to configure to fix incorrect init +script status() function returns failed to actually return the value +to the user. +--- + + CHANGELOG | 1 + + redhat/autofs.init.in | 2 +- + 2 files changed, 2 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 76c1f73..5bcb1af 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -19,6 +19,7 @@ + - Allow nsswitch.conf to not contain "automount:" lines. + - fix nobind man page description. + - fix submount offset delete. ++- fix init script status return. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in +index fe18b3e..9d008ff 100644 +--- a/redhat/autofs.init.in ++++ b/redhat/autofs.init.in +@@ -172,7 +172,7 @@ RETVAL=0 + case "$1" in + status) + status -p @@autofspiddir@@/autofs.pid -l autofs $prog +- exit 0; ++ exit $?; + ;; + usage) + usage_message diff --git a/SOURCES/autofs-5.0.7-fix-interface-address-null-check.patch b/SOURCES/autofs-5.0.7-fix-interface-address-null-check.patch new file mode 100644 index 0000000..f1a209b --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-interface-address-null-check.patch @@ -0,0 +1,55 @@ +autofs-5.0.7 - fix interface address null check + +From: Doug Nazar + +Since commit aa6f7793 [autofs-5.0.7 - fix ipv6 proximity calculation] +get_proximity() uses getifaddrs however it crashes on interfaces with +no addresses. + +Fix the NULL check to ignore interfaces with no addresses. +Also skip interfaces which are not currently running. +--- + CHANGELOG | 1 + + modules/replicated.c | 10 ++++++---- + 2 files changed, 7 insertions(+), 4 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 66c11de..50e83d7 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -43,6 +43,7 @@ + - make dump maps check for duplicate indirect mounts. + - document allowed map sources in auto.master. + - add enable sloppy mount option to configure. ++- fix interface address null check. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/replicated.c b/modules/replicated.c +index 26f64b8..6dbdade 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -165,8 +165,9 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + + this = ifa; + while (this) { +- if (this->ifa_flags & IFF_POINTOPOINT || +- this->ifa_addr->sa_data == NULL) { ++ if (!(this->ifa_flags & IFF_UP) || ++ this->ifa_flags & IFF_POINTOPOINT || ++ this->ifa_addr == NULL) { + this = this->ifa_next; + continue; + } +@@ -202,8 +203,9 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + + this = ifa; + while (this) { +- if (this->ifa_flags & IFF_POINTOPOINT || +- this->ifa_addr->sa_data == NULL) { ++ if (!(this->ifa_flags & IFF_UP) || ++ this->ifa_flags & IFF_POINTOPOINT || ++ this->ifa_addr == NULL) { + this = this->ifa_next; + continue; + } diff --git a/SOURCES/autofs-5.0.7-fix-ipv6-proximity-calculation.patch b/SOURCES/autofs-5.0.7-fix-ipv6-proximity-calculation.patch new file mode 100644 index 0000000..b341ecd --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-ipv6-proximity-calculation.patch @@ -0,0 +1,297 @@ +autofs-5.0.7 - fix ipv6 proximity calculation + +From: Ian Kent + +The socket based ioctl used to get interface information only +return IPv4 information. Change get_proximity() function to use +getifaddrs(3) instead. +--- + + CHANGELOG | 1 + modules/replicated.c | 149 ++++++++++++++------------------------------------ + 2 files changed, 42 insertions(+), 108 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index dc38580..34c70fa 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -2,6 +2,7 @@ + ======================= + - fix nobind sun escaped map entries. + - fix use cache entry after free in lookup_prune_one_cache(). ++- fix ipv6 proximity calculation. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/replicated.c b/modules/replicated.c +index 78046c6..bd6003b 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + + #include "rpc_subs.h" + #include "replicated.h" +@@ -110,58 +111,18 @@ void seed_random(void) + return; + } + +-static int alloc_ifreq(struct ifconf *ifc, int sock) +-{ +- int ret, lastlen = ifc_last_len, len = ifc_buf_len; +- char err_buf[MAX_ERR_BUF], *buf; +- +- while (1) { +- buf = malloc(len); +- if (!buf) { +- char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF); +- logerr("malloc: %s", estr); +- return 0; +- } +- +- ifc->ifc_len = len; +- ifc->ifc_req = (struct ifreq *) buf; +- +- ret = ioctl(sock, SIOCGIFCONF, ifc); +- if (ret == -1) { +- char *estr = strerror_r(errno, err_buf, MAX_ERR_BUF); +- logerr("ioctl: %s", estr); +- free(buf); +- return 0; +- } +- +- if (ifc->ifc_len <= lastlen) +- break; +- +- lastlen = ifc->ifc_len; +- len += MAX_IFC_BUF; +- free(buf); +- } +- +- if (lastlen != ifc_last_len) { +- ifc_last_len = lastlen; +- ifc_buf_len = len; +- } +- +- return 1; +-} +- + static unsigned int get_proximity(struct sockaddr *host_addr) + { ++ struct ifaddrs *ifa = NULL; ++ struct ifaddrs *this; + struct sockaddr_in *addr, *msk_addr, *if_addr; + struct sockaddr_in6 *addr6, *msk6_addr, *if6_addr; + struct in_addr *hst_addr; + struct in6_addr *hst6_addr; + int addr_len; +- char buf[MAX_ERR_BUF], *ptr; +- struct ifconf ifc; +- struct ifreq *ifr, nmptr; +- int sock, ret, i; ++ char buf[MAX_ERR_BUF]; + uint32_t mask, ha, ia, *mask6, *ha6, *ia6; ++ int ret; + + addr = NULL; + addr6 = NULL; +@@ -170,13 +131,14 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + mask6 = NULL; + ha6 = NULL; + ia6 = NULL; ++ ha = 0; + + switch (host_addr->sa_family) { + case AF_INET: + addr = (struct sockaddr_in *) host_addr; + hst_addr = (struct in_addr *) &addr->sin_addr; + ha = ntohl((uint32_t) hst_addr->s_addr); +- addr_len = sizeof(hst_addr); ++ addr_len = sizeof(*hst_addr); + break; + + case AF_INET6: +@@ -186,7 +148,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + addr6 = (struct sockaddr_in6 *) host_addr; + hst6_addr = (struct in6_addr *) &addr6->sin6_addr; + ha6 = &hst6_addr->s6_addr32[0]; +- addr_len = sizeof(hst6_addr); ++ addr_len = sizeof(*hst6_addr); + break; + #endif + +@@ -194,36 +156,29 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + return PROXIMITY_ERROR; + } + +- sock = open_sock(AF_INET, SOCK_DGRAM, 0); +- if (sock < 0) { ++ ret = getifaddrs(&ifa); ++ if (ret) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr("socket creation failed: %s", estr); ++ logerr("getifaddrs: %s", estr); + return PROXIMITY_ERROR; + } + +- if (!alloc_ifreq(&ifc, sock)) { +- close(sock); +- return PROXIMITY_ERROR; +- } +- +- /* For each interface */ +- +- /* Is the address a local interface */ +- i = 0; +- ptr = (char *) &ifc.ifc_buf[0]; +- +- while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) { +- ifr = (struct ifreq *) ptr; ++ this = ifa; ++ while (this) { ++ if (this->ifa_flags & IFF_POINTOPOINT || ++ this->ifa_addr->sa_data == NULL) { ++ this = this->ifa_next; ++ continue; ++ } + +- switch (ifr->ifr_addr.sa_family) { ++ switch (this->ifa_addr->sa_family) { + case AF_INET: + if (host_addr->sa_family == AF_INET6) + break; +- if_addr = (struct sockaddr_in *) &ifr->ifr_addr; ++ if_addr = (struct sockaddr_in *) this->ifa_addr; + ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len); + if (!ret) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_LOCAL; + } + break; +@@ -234,55 +189,41 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + #else + if (host_addr->sa_family == AF_INET) + break; +- +- if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr; ++ if6_addr = (struct sockaddr_in6 *) this->ifa_addr; + ret = memcmp(&if6_addr->sin6_addr, hst6_addr, addr_len); + if (!ret) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_LOCAL; + } + #endif +- + default: + break; + } +- +- i++; +- ptr = (char *) &ifc.ifc_req[i]; ++ this = this->ifa_next; + } + +- i = 0; +- ptr = (char *) &ifc.ifc_buf[0]; +- +- while (ptr < (char *) ifc.ifc_req + ifc.ifc_len) { +- ifr = (struct ifreq *) ptr; +- +- nmptr = *ifr; +- ret = ioctl(sock, SIOCGIFNETMASK, &nmptr); +- if (ret == -1) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr("ioctl: %s", estr); +- close(sock); +- free(ifc.ifc_req); +- return PROXIMITY_ERROR; ++ this = ifa; ++ while (this) { ++ if (this->ifa_flags & IFF_POINTOPOINT || ++ this->ifa_addr->sa_data == NULL) { ++ this = this->ifa_next; ++ continue; + } + +- switch (ifr->ifr_addr.sa_family) { ++ switch (this->ifa_addr->sa_family) { + case AF_INET: + if (host_addr->sa_family == AF_INET6) + break; +- if_addr = (struct sockaddr_in *) &ifr->ifr_addr; ++ if_addr = (struct sockaddr_in *) this->ifa_addr; + ia = ntohl((uint32_t) if_addr->sin_addr.s_addr); + +- /* Is the address within a localiy attached subnet */ ++ /* Is the address within a localy attached subnet */ + +- msk_addr = (struct sockaddr_in *) &nmptr.ifr_netmask; ++ msk_addr = (struct sockaddr_in *) this->ifa_netmask; + mask = ntohl((uint32_t) msk_addr->sin_addr.s_addr); + + if ((ia & mask) == (ha & mask)) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_SUBNET; + } + +@@ -304,8 +245,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + break; + + if ((ia & mask) == (ha & mask)) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_NET; + } + break; +@@ -316,35 +256,28 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + #else + if (host_addr->sa_family == AF_INET) + break; +- +- if6_addr = (struct sockaddr_in6 *) &ifr->ifr_addr; ++ if6_addr = (struct sockaddr_in6 *) this->ifa_addr; + ia6 = &if6_addr->sin6_addr.s6_addr32[0]; + + /* Is the address within the network of the interface */ + +- msk6_addr = (struct sockaddr_in6 *) &nmptr.ifr_netmask; ++ msk6_addr = (struct sockaddr_in6 *) this->ifa_netmask; + mask6 = &msk6_addr->sin6_addr.s6_addr32[0]; + + if (ipv6_mask_cmp(ha6, ia6, mask6)) { +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + return PROXIMITY_SUBNET; + } + + /* How do we define "local network" in ipv6? */ + #endif +- break; +- + default: + break; + } +- +- i++; +- ptr = (char *) &ifc.ifc_req[i]; ++ this = this->ifa_next; + } + +- close(sock); +- free(ifc.ifc_req); ++ freeifaddrs(ifa); + + return PROXIMITY_OTHER; + } diff --git a/SOURCES/autofs-5.0.7-fix-leaked-ldap-percent-hack-allocation-in-lookup_one.patch b/SOURCES/autofs-5.0.7-fix-leaked-ldap-percent-hack-allocation-in-lookup_one.patch new file mode 100644 index 0000000..d113eea --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-leaked-ldap-percent-hack-allocation-in-lookup_one.patch @@ -0,0 +1,21 @@ +autofs-5.0.7 - fix leaked ldap percent hack allocation in lookup_one() + +From: Ian Kent + +Fix a resource leak when calling the percent hack transforms in lookup_one(). +--- + modules/lookup_ldap.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 26481a8..35ea6ea 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -2525,6 +2525,7 @@ static int lookup_one(struct autofs_point *ap, + if (enc_len1 != 0) { + enc_len2 = encode_percent_hack(qKey, &enc_key2, 1); + if (enc_len2 < 0) { ++ free(enc_key1); + crit(ap->logopt, + "could not use percent hack encode key %s", + qKey); diff --git a/SOURCES/autofs-5.0.7-fix-libtirpc-build-option.patch b/SOURCES/autofs-5.0.7-fix-libtirpc-build-option.patch new file mode 100644 index 0000000..8ad2afa --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-libtirpc-build-option.patch @@ -0,0 +1,66 @@ +autofs-5.0.7 - fix libtirpc build option + +From: Ian Kent + + +--- + CHANGELOG | 1 + + autofs.spec | 17 ++++++++++++++++- + 2 files changed, 17 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index e848bcd..b6b2679 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -34,6 +34,7 @@ + - depricate nosymlink pseudo option. + - add symlink pseudo option. + - fix requires in spec file. ++- fix libtirpc build option to require libtirpc-devel if needed. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/autofs.spec b/autofs.spec +index 703f7a9..f77acc1 100644 +--- a/autofs.spec ++++ b/autofs.spec +@@ -12,6 +12,10 @@ + # disable them. + %define with_systemd %{?_without_systemd: 0} %{?!_without_systemd: 1} + ++# Use --without libtirpc in your rpmbuild command or force values to 0 to ++# disable them. ++%define with_libtirpc %{?_without_libtirpc: 0} %{?!_without_libtirpc: 1} ++ + Summary: A tool from automatically mounting and umounting filesystems. + Name: autofs + %define version 5.0.7 +@@ -25,6 +29,9 @@ Buildroot: %{_tmppath}/%{name}-tmp + %if %{with_systemd} + BuildRequires: systemd-units + %endif ++%if %{with_libtirpc} ++BuildRequires: libtirpc-devel ++%endif + BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, cyrus-sasl-devel + Requires: chkconfig + Requires: /bin/bash mktemp sed textutils sh-utils grep /bin/ps +@@ -72,9 +79,17 @@ echo %{version}-%{release} > .version + %define _unitdir %{?_unitdir:/lib/systemd/system} + %define systemd_configure_arg --with-systemd + %endif ++%if %{with_libtirpc} ++ %define libtirpc_configure_arg --with-libtirpc ++%endif + + %build +-CFLAGS="$RPM_OPT_FLAGS -Wall" ./configure --libdir=%{_libdir} --disable-mount-locking --enable-ignore-busy --with-libtirpc %{?systemd_configure_arg:} ++CFLAGS="$RPM_OPT_FLAGS -Wall" \ ++./configure --libdir=%{_libdir} \ ++ --disable-mount-locking \ ++ --enable-ignore-busy \ ++ %{?systemd_configure_arg:} \ ++ %{?libtirpc_configure_arg:} + CFLAGS="$RPM_OPT_FLAGS -Wall" make initdir=/etc/rc.d/init.d DONTSTRIP=1 + + %install diff --git a/SOURCES/autofs-5.0.7-fix-map-entry-duplicate-offset-detection.patch b/SOURCES/autofs-5.0.7-fix-map-entry-duplicate-offset-detection.patch new file mode 100644 index 0000000..126d9a2 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-map-entry-duplicate-offset-detection.patch @@ -0,0 +1,37 @@ +autofs-5.0.7 - fix map entry duplicate offset detection + +From: Ian Kent + +Recent changes broke the detection of duplicate offsets in map entries. +--- + + CHANGELOG | 1 + + lib/cache.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 8f6bb3a..bd0dd82 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -15,6 +15,7 @@ + - fix recursive mount deadlock. + - increase file map read buffer size. + - handle new location of systemd. ++- fix map entry duplicate offset detection. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/cache.c b/lib/cache.c +index 9179ad5..1e05a99 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -659,7 +659,7 @@ int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *k + + me = cache_lookup_distinct(mc, key); + if (me && me->age == age) { +- if (me->multi != owner) ++ if (me->multi == owner) + return CHE_DUPLICATE; + } + diff --git a/SOURCES/autofs-5.0.7-fix-master-map-bogus-keywork-match.patch b/SOURCES/autofs-5.0.7-fix-master-map-bogus-keywork-match.patch new file mode 100644 index 0000000..7c003ff --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-master-map-bogus-keywork-match.patch @@ -0,0 +1,62 @@ +autofs-5.0.7 - fix master map bogus keywork match + +From: Ian Kent + +If we have a map name in the master map that ends with a keyword +of one of the map types or "multi" we mistakenly match the trailing +white space and include that in the map name. This has to be wrong +since we can't handle quoting in the master map and embedded white +space must be escaped. It would be good if we handled quoted strings +but that has proven a bit of a nightmare so far for the current +tokenizer. +--- + CHANGELOG | 1 + + lib/master_tok.l | 16 ++++++++++++++++ + 2 files changed, 17 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 00eaff2..e15aa1f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -46,6 +46,7 @@ + - fix interface address null check. + - dont probe rdma mounts. + - fix master map mount options matching. ++- fix master map bogus keywork match. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/master_tok.l b/lib/master_tok.l +index 8d1f1a2..a55cc76 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -202,6 +202,14 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo + {MULTI} { + tlen = master_leng - 1; + if (bptr != buff && isblank(master_text[tlen])) { ++ /* ++ * We can't handle unescaped white space in map names ++ * so just eat the white space. We always have the ++ * "multi" at the beginning of the string so the while ++ * will not fall off the end. ++ */ ++ while (isblank(master_text[tlen - 1])) ++ tlen--; + strncat(buff, master_text, tlen); + bptr += tlen; + yyless(tlen); +@@ -216,6 +224,14 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo + {MTYPE}/{DNATTRSTR}= { + tlen = master_leng - 1; + if (bptr != buff && isblank(master_text[tlen])) { ++ /* ++ * We can't handle unescaped white space in map names ++ * so just eat the white space. We always have the ++ * maptype keyword at the beginning of the string so ++ * the while will not fall off the end. ++ */ ++ while (isblank(master_text[tlen - 1])) ++ tlen--; + strncat(buff, master_text, tlen); + bptr += tlen; + yyless(tlen); diff --git a/SOURCES/autofs-5.0.7-fix-master-map-mount-options-matching.patch b/SOURCES/autofs-5.0.7-fix-master-map-mount-options-matching.patch new file mode 100644 index 0000000..a360618 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-master-map-mount-options-matching.patch @@ -0,0 +1,43 @@ +autofs-5.0.7 - fix master map mount options matching + +From: Ian Kent + +The master map options pattern matching is fairly primitive since it +doesn't need to be very sophisticated. The current mount option pattern +matching can't match mount options with quotes or embedded colons and so +it can't pass these options through as a global options string. + +But it must be able to match a fairly large class of strings, including +the above case, so they can be passed through as global options. Of +course it can't try and validate them since it can't know what mount type +they may be used with. +--- + CHANGELOG | 1 + + lib/master_tok.l | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 1156cc9..00eaff2 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -45,6 +45,7 @@ + - add enable sloppy mount option to configure. + - fix interface address null check. + - dont probe rdma mounts. ++- fix master map mount options matching. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/master_tok.l b/lib/master_tok.l +index f9b4e55..8d1f1a2 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -91,7 +91,7 @@ OPTWS [[:blank:]]* + NL \r?\n + CONT \\\n{OPTWS} + +-OPTIONSTR ([\-]?([[:alpha:]_]([[:alnum:]_\-])*(=([[:alnum:]_\-])+)*)+) ++OPTIONSTR ([\-]?([[:alpha:]_]([[:alnum:]_\-])*(=(\"?([[:alnum:]_\-\:])+\"?))?)+) + MACROSTR (-D{OPTWS}([[:alpha:]_]([[:alnum:]_\-\.])*)=([[:alnum:]_\-\.])+) + SLASHIFYSTR (--(no-)?slashify-colons) + NUMBER [0-9]+ diff --git a/SOURCES/autofs-5.0.7-fix-memory-leak-in-get_dc_list.patch b/SOURCES/autofs-5.0.7-fix-memory-leak-in-get_dc_list.patch new file mode 100644 index 0000000..01a9236 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-memory-leak-in-get_dc_list.patch @@ -0,0 +1,30 @@ +autofs-5.0.7 - fix memory leak in get_dc_list() + +From: Ian Kent + +In get_dc_list() if an invalid port is found the allocated list storage +isn't freed on the error exit. +--- + modules/dclist.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/modules/dclist.c b/modules/dclist.c +index d16b913..af21ce0 100644 +--- a/modules/dclist.c ++++ b/modules/dclist.c +@@ -536,6 +536,7 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri) + else + strcat(tmp, " "); + ++ list = NULL; + for (i = 0; i < numdcs; i++) { + if (i > 0) + strcat(tmp, " "); +@@ -549,6 +550,7 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri) + error(logopt, + "invalid port: %u", dcs[i].port); + free_srv_rrs(dcs, numdcs); ++ free(tmp); + goto out_error; + } + strcat(tmp, port); diff --git a/SOURCES/autofs-5.0.7-fix-nobind-man-page-description.patch b/SOURCES/autofs-5.0.7-fix-nobind-man-page-description.patch new file mode 100644 index 0000000..41328a0 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-nobind-man-page-description.patch @@ -0,0 +1,46 @@ +autofs-5.0.7 - fix nobind man page description + +From: Ian Kent + +Update auto.master(5) to better describe the behavior of the "nobind" +option when used with direct mounts maps. +--- + + CHANGELOG | 1 + + man/auto.master.5.in | 10 +++++++--- + 2 files changed, 8 insertions(+), 3 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 16ac2a0..7eb7235 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -17,6 +17,7 @@ + - handle new location of systemd. + - fix map entry duplicate offset detection. + - Allow nsswitch.conf to not contain "automount:" lines. ++- fix nobind man page description. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index 21d7544..8007542 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -151,9 +151,13 @@ can't be mounted. + This is an autofs specific option that is a pseudo mount option and + so is given without a leading dash. It may be used either in the master + map entry (so it effects all the map entries) or with individual map +-entries to prevent bind mounting of local NFS filesystems. Bind mounting +-of NFS file systems can also be prevented for specific map entrys by +-adding the "port=" mount option to the entries. ++entries to prevent bind mounting of local NFS filesystems. For direct ++mount maps the option is only effective if specified on the first direct ++map entry and is applied to all direct mount maps in the master map. It ++is ignored if given on subsequent direct map entries. It may be used ++on individual map entries of both types. Bind mounting of NFS file ++systems can also be prevented for specific map entrys by adding the ++"port=" mount option to the entries. + .TP + .I "\-r, \-\-random-multimount-selection" + Enables the use of ramdom selection when choosing a host from a diff --git a/SOURCES/autofs-5.0.7-fix-nobind-sun-escaped-map-entries.patch b/SOURCES/autofs-5.0.7-fix-nobind-sun-escaped-map-entries.patch new file mode 100644 index 0000000..b5d7ad2 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-nobind-sun-escaped-map-entries.patch @@ -0,0 +1,47 @@ +autofs-5.0.7 - fix nobind sun escaped map entries + +From: Ian Kent + +If a map contains a Sun colon escape to indicate the mount is a local +file system and the "nobind" option is present there is no hostname in +the mount location and the mount fails. +--- + + CHANGELOG | 4 ++++ + modules/mount_nfs.c | 5 +++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 67fdcec..faf4c80 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,3 +1,7 @@ ++??/??/2012 autofs-5.0.8 ++======================= ++- fix nobind sun escaped map entries. ++ + 25/07/2012 autofs-5.0.7 + ======================= + - fix ipv6 name for lookup fix. +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 9b8e5f1..bbbb1de 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -263,13 +263,14 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + } else + strcpy(loc, n_addr); + } else { +- loc = malloc(strlen(this->name) + strlen(this->path) + 2); ++ char *host = this->name ? this->name : "localhost"; ++ loc = malloc(strlen(host) + strlen(this->path) + 2); + if (!loc) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, "malloc: %s", estr); + goto forced_fail; + } +- strcpy(loc, this->name); ++ strcpy(loc, host); + } + strcat(loc, ":"); + strcat(loc, this->path); diff --git a/SOURCES/autofs-5.0.7-fix-null-map-entry-order-handling.patch b/SOURCES/autofs-5.0.7-fix-null-map-entry-order-handling.patch new file mode 100644 index 0000000..610afaa --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-null-map-entry-order-handling.patch @@ -0,0 +1,81 @@ +autofs-5.0.7 - fix null map entry order handling + +From: Ian Kent + +If a null map entry appears after a corresponding indirect map entry +autofs doesn't handle it properly. + +Since it appears after the map entry it should'nt affect it but autofs +doesn't account for this case and assumes the map entry is already +mounted and tries to shut it down causing attempted access to facilities +that don't exist. +--- + + CHANGELOG | 1 + + lib/master.c | 32 +++++++++++++++++++++++++++++--- + 2 files changed, 30 insertions(+), 3 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 7b8d185..79cf673 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -7,6 +7,7 @@ + - fix typo in automount(8). + - dont wait forever to restart. + - add timeout option description to man page. ++- fix null map entry order handling. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/master.c b/lib/master.c +index 904b13d..a0e62f2 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -1179,9 +1179,35 @@ int master_mount_mounts(struct master *master, time_t age, int readall) + + cache_readlock(nc); + ne = cache_lookup_distinct(nc, this->path); +- if (ne && this->age > ne->age) { ++ /* ++ * If this path matched a nulled entry the master map entry ++ * must be an indirect mount so the master map entry line ++ * number may be obtained from this->maps. ++ */ ++ if (ne) { ++ int lineno = ne->age; + cache_unlock(nc); +- st_add_task(ap, ST_SHUTDOWN_PENDING); ++ ++ /* null entry appears after map entry */ ++ if (this->maps->master_line < lineno) { ++ warn(ap->logopt, ++ "ignoring null entry that appears after " ++ "existing entry for %s", this->path); ++ goto cont; ++ } ++ if (ap->state != ST_INIT) { ++ st_add_task(ap, ST_SHUTDOWN_PENDING); ++ continue; ++ } ++ /* ++ * The map entry hasn't been started yet and we've ++ * seen a preceeding null map entry for it so just ++ * delete it from the master map entry list so it ++ * doesn't get in the road. ++ */ ++ list_del_init(&this->list); ++ master_free_mapent_sources(ap->entry, 1); ++ master_free_mapent(ap->entry); + continue; + } + nested = cache_partial_match(nc, this->path); +@@ -1194,7 +1220,7 @@ int master_mount_mounts(struct master *master, time_t age, int readall) + cache_delete(nc, nested->key); + } + cache_unlock(nc); +- ++cont: + st_mutex_lock(); + + state_pipe = this->ap->state_pipe[1]; diff --git a/SOURCES/autofs-5.0.7-fix-parse-buffer-initialization.patch b/SOURCES/autofs-5.0.7-fix-parse-buffer-initialization.patch new file mode 100644 index 0000000..22bd5da --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-parse-buffer-initialization.patch @@ -0,0 +1,51 @@ +autofs-5.0.7 - fix parse buffer initialization + +From: Ian Kent + +When parsing a master map entry, if the mount point path is longer than +the following map string the lexical analyzer buffer may not have a null +terminator where it is expected. If the map name string also contains a +string that is the same as a map type at the end the map name the map +name is not constructed correctly because of this lack of a string +terminator in the buffer. +--- + + CHANGELOG | 1 + + lib/master_tok.l | 4 +++- + 2 files changed, 4 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 34c70fa..276d6ba 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -3,6 +3,7 @@ + - fix nobind sun escaped map entries. + - fix use cache entry after free in lookup_prune_one_cache(). + - fix ipv6 proximity calculation. ++- fix parse buffer initialization. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/master_tok.l b/lib/master_tok.l +index 0d6edb7..30abb15 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -74,7 +74,8 @@ int my_yyinput(char *, int); + #define unput(c) (*(char *) --line = c) + #endif + +-char buff[1024]; ++#define BUFF_LEN 1024 ++char buff[BUFF_LEN]; + char *bptr; + char *optr = buff; + unsigned int tlen; +@@ -174,6 +175,7 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|--negative-timeout{OPTWS}|--negative-timeo + *bptr = '\0'; + strcpy(master_lval.strtype, buff); + bptr = buff; ++ memset(buff, 0, BUFF_LEN); + return(PATH); + } + diff --git a/SOURCES/autofs-5.0.7-fix-portmap-lookup.patch b/SOURCES/autofs-5.0.7-fix-portmap-lookup.patch new file mode 100644 index 0000000..cac651f --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-portmap-lookup.patch @@ -0,0 +1,285 @@ +autofs-5.0.7 - fix portmap lookup + +From: Ian Kent + +The autofs RPC library has fallen behind some. + +When using IPv6 (rpbbind) version 3 or 4 is available whereas with IPv4 +(portmap) verions 2 and 3 are available. + +autofs uses the version defined by PMAPVERS in the portmap include files +whereas it should be using the RPCBVERS defines when using libtirpc. + +In addition /etc/rpc should be used for program number lookup and +/etc/services should be used to lookup rpcbind/protmap port number. + +This incompatibility only shows up when using IPv6 only. +--- + CHANGELOG | 1 + aclocal.m4 | 2 + + configure | 80 +++++++++++++++++++++++++++++++++++++++++++++ + include/config.h.in | 6 +++ + lib/rpc_subs.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++---- + 5 files changed, 175 insertions(+), 6 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -62,6 +62,7 @@ + - try and cleanup after dumpmaps. + - teach dumpmaps to output simple key value pairs. + - fix get_nfs_info() probe. ++- fix portmap lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/aclocal.m4 ++++ autofs-5.0.7/aclocal.m4 +@@ -421,6 +421,8 @@ if test "$af_have_libtirpc" = "yes"; the + TIRPCLIB="-ltirpc" + fi + ++AC_CHECK_FUNCS([getrpcbyname getservbyname]) ++ + # restore flags + CFLAGS="$af_check_libtirpc_save_cflags" + LDFLAGS="$af_check_libtirpc_save_ldflags" +--- autofs-5.0.7.orig/configure ++++ autofs-5.0.7/configure +@@ -1559,6 +1559,73 @@ fi + + } # ac_fn_c_try_link + ++# ac_fn_c_check_func LINENO FUNC VAR ++# ---------------------------------- ++# Tests whether FUNC exists, setting the cache variable VAR accordingly ++ac_fn_c_check_func () ++{ ++ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack ++ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 ++$as_echo_n "checking for $2... " >&6; } ++if eval \${$3+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++/* Define $2 to an innocuous variant, in case declares $2. ++ For example, HP-UX 11i declares gettimeofday. */ ++#define $2 innocuous_$2 ++ ++/* System header to define __stub macros and hopefully few prototypes, ++ which can conflict with char $2 (); below. ++ Prefer to if __STDC__ is defined, since ++ exists even on freestanding compilers. */ ++ ++#ifdef __STDC__ ++# include ++#else ++# include ++#endif ++ ++#undef $2 ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char $2 (); ++/* The GNU C library defines this for functions which it implements ++ to always fail with ENOSYS. Some functions are actually named ++ something starting with __ and the normal name is an alias. */ ++#if defined __stub_$2 || defined __stub___$2 ++choke me ++#endif ++ ++int ++main () ++{ ++return $2 (); ++ ; ++ return 0; ++} ++_ACEOF ++if ac_fn_c_try_link "$LINENO"; then : ++ eval "$3=yes" ++else ++ eval "$3=no" ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext conftest.$ac_ext ++fi ++eval ac_res=\$$3 ++ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 ++$as_echo "$ac_res" >&6; } ++ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno ++ ++} # ac_fn_c_check_func ++ + # ac_fn_c_try_cpp LINENO + # ---------------------- + # Try to preprocess conftest.$ac_ext, and return whether this succeeded. +@@ -3161,6 +3228,19 @@ $as_echo "#define TIRPC_WORKAROUND 1" >> + TIRPCLIB="-ltirpc" + fi + ++for ac_func in getrpcbyname getservbyname ++do : ++ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` ++ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" ++if eval test \"x\$"$as_ac_var"\" = x"yes"; then : ++ cat >>confdefs.h <<_ACEOF ++#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 ++_ACEOF ++ ++fi ++done ++ ++ + # restore flags + CFLAGS="$af_check_libtirpc_save_cflags" + LDFLAGS="$af_check_libtirpc_save_ldflags" +--- autofs-5.0.7.orig/include/config.h.in ++++ autofs-5.0.7/include/config.h.in +@@ -21,6 +21,12 @@ + /* define if you have E4FSCK */ + #undef HAVE_E4FSCK + ++/* Define to 1 if you have the `getrpcbyname' function. */ ++#undef HAVE_GETRPCBYNAME ++ ++/* Define to 1 if you have the `getservbyname' function. */ ++#undef HAVE_GETSERVBYNAME ++ + /* Define to 1 if you have the header file. */ + #undef HAVE_INTTYPES_H + +--- autofs-5.0.7.orig/lib/rpc_subs.c ++++ autofs-5.0.7/lib/rpc_subs.c +@@ -43,6 +43,14 @@ + } while (0) + #endif + ++#ifdef WITH_LIBTIRPC ++const rpcprog_t rpcb_prog = RPCBPROG; ++const rpcvers_t rpcb_version = RPCBVERS; ++#else ++const rpcprog_t rpcb_prog = PMAPPROG; ++const rpcvers_t rpcb_version = PMAPVERS; ++#endif ++ + #include "mount.h" + #include "rpc_subs.h" + #include "automount.h" +@@ -259,6 +267,9 @@ static int rpc_do_create_client(struct s + laddr = (struct sockaddr *) &in4_laddr; + in4_raddr->sin_port = htons(info->port); + slen = sizeof(struct sockaddr_in); ++ /* Use rpcbind v2 for AF_INET */ ++ if (info->program == rpcb_prog) ++ info->version = PMAPVERS; + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6 *in6_raddr = (struct sockaddr_in6 *) addr; + in6_laddr.sin6_family = AF_INET6; +@@ -315,6 +326,63 @@ static int rpc_do_create_client(struct s + } + #endif + ++#if defined(HAVE_GETRPCBYNAME) || defined(HAVE_GETSERVBYNAME) ++static pthread_mutex_t rpcb_mutex = PTHREAD_MUTEX_INITIALIZER; ++#endif ++ ++static rpcprog_t rpc_getrpcbyname(const rpcprog_t program) ++{ ++#ifdef HAVE_GETRPCBYNAME ++ static const char *rpcb_pgmtbl[] = { ++ "rpcbind", "portmap", "portmapper", "sunrpc", NULL, ++ }; ++ struct rpcent *entry; ++ rpcprog_t prog_number; ++ unsigned int i; ++ ++ pthread_mutex_lock(&rpcb_mutex); ++ for (i = 0; rpcb_pgmtbl[i] != NULL; i++) { ++ entry = getrpcbyname(rpcb_pgmtbl[i]); ++ if (entry) { ++ prog_number = entry->r_number; ++ pthread_mutex_unlock(&rpcb_mutex); ++ return prog_number; ++ } ++ } ++ pthread_mutex_unlock(&rpcb_mutex); ++#endif ++ return program; ++} ++ ++static unsigned short rpc_getrpcbport(const int proto) ++{ ++#ifdef HAVE_GETSERVBYNAME ++ static const char *rpcb_netnametbl[] = { ++ "rpcbind", "portmapper", "sunrpc", NULL, ++ }; ++ struct servent *entry; ++ struct protoent *p_ent; ++ unsigned short port; ++ unsigned int i; ++ ++ pthread_mutex_lock(&rpcb_mutex); ++ p_ent = getprotobynumber(proto); ++ if (!p_ent) ++ goto done; ++ for (i = 0; rpcb_netnametbl[i] != NULL; i++) { ++ entry = getservbyname(rpcb_netnametbl[i], p_ent->p_name); ++ if (entry) { ++ port = entry->s_port; ++ pthread_mutex_unlock(&rpcb_mutex); ++ return port; ++ } ++ } ++done: ++ pthread_mutex_unlock(&rpcb_mutex); ++#endif ++ return (unsigned short) PMAPPORT; ++} ++ + /* + * Create an RPC client + */ +@@ -510,9 +578,15 @@ int rpc_portmap_getclient(struct conn_in + info->host = host; + info->addr = addr; + info->addr_len = addr_len; +- info->program = PMAPPROG; +- info->port = PMAPPORT; +- info->version = PMAPVERS; ++ info->program = rpc_getrpcbyname(rpcb_prog); ++ info->port = ntohs(rpc_getrpcbport(proto)); ++ /* ++ * When using libtirpc we might need to change the rpcbind version ++ * to qurey AF_INET addresses. Since we might not have an address ++ * yet set AF_INET rpcbind version in rpc_do_create_client() when ++ * we always have an address. ++ */ ++ info->version = rpcb_version; + info->proto = proto; + info->send_sz = RPCSMALLMSGSIZE; + info->recv_sz = RPCSMALLMSGSIZE; +@@ -555,9 +629,15 @@ int rpc_portmap_getport(struct conn_info + pmap_info.host = info->host; + pmap_info.addr = info->addr; + pmap_info.addr_len = info->addr_len; +- pmap_info.port = PMAPPORT; +- pmap_info.program = PMAPPROG; +- pmap_info.version = PMAPVERS; ++ pmap_info.port = ntohs(rpc_getrpcbport(info->proto)); ++ pmap_info.program = rpc_getrpcbyname(rpcb_prog); ++ /* ++ * When using libtirpc we might need to change the rpcbind ++ * version to qurey AF_INET addresses. Since we might not ++ * have an address yet set AF_INET rpcbind version in ++ * rpc_do_create_client() when we always have an address. ++ */ ++ pmap_info.version = rpcb_version; + pmap_info.proto = info->proto; + pmap_info.send_sz = RPCSMALLMSGSIZE; + pmap_info.recv_sz = RPCSMALLMSGSIZE; diff --git a/SOURCES/autofs-5.0.7-fix-possible-use-after-free-in-lookup_dir-lookup_init.patch b/SOURCES/autofs-5.0.7-fix-possible-use-after-free-in-lookup_dir-lookup_init.patch new file mode 100644 index 0000000..99aef1f --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-possible-use-after-free-in-lookup_dir-lookup_init.patch @@ -0,0 +1,21 @@ +autofs-5.0.7 - fix possible use after free in lookup_dir.c:lookup_init() + +From: Ian Kent + +Add a missing error return in lookup_dir.c:lookup_init(). +--- + modules/lookup_dir.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/modules/lookup_dir.c b/modules/lookup_dir.c +index 07471b7..cbeda1f 100644 +--- a/modules/lookup_dir.c ++++ b/modules/lookup_dir.c +@@ -98,6 +98,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + free(ctxt); + warn(LOGOPT_NONE, MODPREFIX + "dir map %s, is not a directory", argv[0]); ++ return 1; + } + + *context = ctxt; diff --git a/SOURCES/autofs-5.0.7-fix-potential-null-dereference-in-lookup_mount.patch b/SOURCES/autofs-5.0.7-fix-potential-null-dereference-in-lookup_mount.patch new file mode 100644 index 0000000..d0b33ad --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-potential-null-dereference-in-lookup_mount.patch @@ -0,0 +1,157 @@ +autofs-5.0.7 - fix potential null dereference in lookup_mount() + +From: Ian Kent + +Updating a negative cache entry should always find an entry but the entry +lookup return isn't checked and probably should be. + +Since this code is duplicated in several modules add it as a function to +the cache handling code. +--- + include/automount.h | 1 + + lib/cache.c | 20 ++++++++++++++++++++ + modules/lookup_file.c | 11 +---------- + modules/lookup_ldap.c | 12 +----------- + modules/lookup_sss.c | 12 +----------- + modules/lookup_yp.c | 12 ++---------- + 6 files changed, 26 insertions(+), 42 deletions(-) + +diff --git a/include/automount.h b/include/automount.h +index 6ced842..71787a5 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -189,6 +189,7 @@ struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int s + struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix); + int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); + int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age); ++void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); + int cache_set_parents(struct mapent *mm); + int cache_update(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); + int cache_delete(struct mapent_cache *mc, const char *key); +diff --git a/lib/cache.c b/lib/cache.c +index ecace4a..be4917b 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -680,6 +680,26 @@ done: + return ret; + } + ++void cache_update_negative(struct mapent_cache *mc, ++ struct map_source *ms, const char *key, ++ time_t timeout) ++{ ++ time_t now = time(NULL); ++ struct mapent *me; ++ int rv = CHE_OK; ++ ++ me = cache_lookup_distinct(mc, key); ++ if (!me) ++ rv = cache_update(mc, ms, key, NULL, now); ++ if (rv != CHE_FAIL) { ++ me = cache_lookup_distinct(mc, key); ++ if (me) ++ me->status = now + timeout; ++ } ++ return; ++} ++ ++ + static struct mapent *get_parent(const char *key, struct list_head *head, struct list_head **pos) + { + struct list_head *next; +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 2836996..4b4ee89 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -1130,17 +1130,8 @@ do_cache_lookup: + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); + if (ret) { +- time_t now = time(NULL); +- int rv = CHE_OK; +- + cache_writelock(mc); +- me = cache_lookup_distinct(mc, key); +- if (!me) +- rv = cache_update(mc, source, key, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, key); +- me->status = now + ap->negative_timeout; +- } ++ cache_update_negative(mc, source, key, ap->negative_timeout); + cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; + } +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index a59de92..26481a8 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -3011,18 +3011,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); + if (ret) { +- time_t now = time(NULL); +- int rv = CHE_OK; +- +- /* Record the the mount fail in the cache */ + cache_writelock(mc); +- me = cache_lookup_distinct(mc, key); +- if (!me) +- rv = cache_update(mc, source, key, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, key); +- me->status = now + ap->negative_timeout; +- } ++ cache_update_negative(mc, source, key, ap->negative_timeout); + cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; + } +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 5c2ed0a..1fe740b 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -672,18 +672,8 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); + if (ret) { +- time_t now = time(NULL); +- int rv = CHE_OK; +- +- /* Record the the mount fail in the cache */ + cache_writelock(mc); +- me = cache_lookup_distinct(mc, key); +- if (!me) +- rv = cache_update(mc, source, key, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, key); +- me->status = now + ap->negative_timeout; +- } ++ cache_update_negative(mc, source, key, ap->negative_timeout); + cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; + } +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index a716e1f..e99e3c0 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -698,18 +698,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); + if (ret) { +- time_t now = time(NULL); +- int rv = CHE_OK; +- + cache_writelock(mc); +- me = cache_lookup_distinct(mc, key); +- if (!me) +- rv = cache_update(mc, source, key, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, key); +- me->status = now + ap->negative_timeout; +- } ++ cache_update_negative(mc, source, key, ap->negative_timeout); + cache_unlock(mc); ++ return NSS_STATUS_TRYAGAIN; + } + } + diff --git a/SOURCES/autofs-5.0.7-fix-probe-each-nfs-version-in-turn-for-singleton-mounts.patch b/SOURCES/autofs-5.0.7-fix-probe-each-nfs-version-in-turn-for-singleton-mounts.patch new file mode 100644 index 0000000..1801878 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-probe-each-nfs-version-in-turn-for-singleton-mounts.patch @@ -0,0 +1,36 @@ +autofs-5.0.7 - fix probe each nfs version in turn for singleton mounts + +From: Ian Kent + +If there aren't any hosts in the list returned from parse_location() make sure +the probe checks are skipped. +--- + CHANGELOG | 1 + + modules/mount_nfs.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 25179b1..0242c11 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -50,6 +50,7 @@ + - fix fix map entry duplicate offset detection. + - probe each nfs version in turn for singleton mounts. + - add changlog entry for coverity fixes. ++- fix probe each nfs version in turn for singleton mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 81ba3ca..9de8a73 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -190,7 +190,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + * to NFSv3 (if it can). If the NFSv4 probe fails then probe as + * normal. + */ +- if (!hosts->next && ++ if ((hosts && !hosts->next) && + mount_default_proto == 4 && + vers & NFS_VERS_MASK != 0 && + vers & NFS4_VERS_MASK != 0) { diff --git a/SOURCES/autofs-5.0.7-fix-requires-in-spec-file.patch b/SOURCES/autofs-5.0.7-fix-requires-in-spec-file.patch new file mode 100644 index 0000000..404c848 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-requires-in-spec-file.patch @@ -0,0 +1,37 @@ +autofs-5.0.7 - fix requires in spec file + +From: Ian Kent + +Fix the use of depricated reqires in tar spec file. +--- + CHANGELOG | 1 + + autofs.spec | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 247d334..e848bcd 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -33,6 +33,7 @@ + - fix file descriptor leak when reloading the daemon. + - depricate nosymlink pseudo option. + - add symlink pseudo option. ++- fix requires in spec file. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/autofs.spec b/autofs.spec +index b8a3b7a..703f7a9 100644 +--- a/autofs.spec ++++ b/autofs.spec +@@ -25,8 +25,8 @@ Buildroot: %{_tmppath}/%{name}-tmp + %if %{with_systemd} + BuildRequires: systemd-units + %endif +-BuildPrereq: autoconf, hesiod-devel, openldap-devel, bison, flex, cyrus-sasl-devel +-Prereq: chkconfig ++BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, cyrus-sasl-devel ++Requires: chkconfig + Requires: /bin/bash mktemp sed textutils sh-utils grep /bin/ps + %if %{with_systemd} + Requires(post): systemd-sysv diff --git a/SOURCES/autofs-5.0.7-fix-several-off-by-one-errors.patch b/SOURCES/autofs-5.0.7-fix-several-off-by-one-errors.patch new file mode 100644 index 0000000..bb94957 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-several-off-by-one-errors.patch @@ -0,0 +1,128 @@ +autofs-5.0.7 - fix several off by one errors + +From: Ian Kent + +Fix several off-by-one array reference errors and a couple of short allocation +errors. +--- + daemon/spawn.c | 10 +++++----- + lib/defaults.c | 2 +- + modules/lookup_ldap.c | 8 ++++---- + modules/parse_hesiod.c | 2 +- + modules/parse_sun.c | 2 +- + 5 files changed, 12 insertions(+), 12 deletions(-) + +diff --git a/daemon/spawn.c b/daemon/spawn.c +index 3b4a009..9b8d5a2 100644 +--- a/daemon/spawn.c ++++ b/daemon/spawn.c +@@ -320,7 +320,7 @@ int spawn_mount(unsigned logopt, ...) + unsigned int retries = MTAB_LOCK_RETRIES; + int update_mtab = 1, ret, printed = 0; + unsigned int wait = defaults_get_mount_wait(); +- char buf[PATH_MAX]; ++ char buf[PATH_MAX + 1]; + + /* If we use mount locking we can't validate the location */ + #ifdef ENABLE_MOUNT_LOCKING +@@ -346,7 +346,7 @@ int spawn_mount(unsigned logopt, ...) + } + + /* Alloc 1 extra slot in case we need to use the "-f" option */ +- if (!(argv = alloca(sizeof(char *) * argc + 2))) ++ if (!(argv = alloca(sizeof(char *) * (argc + 2)))) + return -1; + + argv[0] = arg0; +@@ -448,7 +448,7 @@ int spawn_bind_mount(unsigned logopt, ...) + unsigned int options; + unsigned int retries = MTAB_LOCK_RETRIES; + int update_mtab = 1, ret, printed = 0; +- char buf[PATH_MAX]; ++ char buf[PATH_MAX + 1]; + + /* If we use mount locking we can't validate the location */ + #ifdef ENABLE_MOUNT_LOCKING +@@ -477,7 +477,7 @@ int spawn_bind_mount(unsigned logopt, ...) + } + } + +- if (!(argv = alloca(sizeof(char *) * argc + 2))) ++ if (!(argv = alloca(sizeof(char *) * (argc + 2)))) + return -1; + + argv[0] = arg0; +@@ -556,7 +556,7 @@ int spawn_umount(unsigned logopt, ...) + unsigned int retries = MTAB_LOCK_RETRIES; + int update_mtab = 1, ret, printed = 0; + unsigned int wait = defaults_get_umount_wait(); +- char buf[PATH_MAX]; ++ char buf[PATH_MAX + 1]; + + #ifdef ENABLE_MOUNT_LOCKING + options = SPAWN_OPT_LOCK; +diff --git a/lib/defaults.c b/lib/defaults.c +index ae1162f..1e89509 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -227,7 +227,7 @@ void defaults_free_uris(struct list_head *list) + static unsigned int add_uris(char *value, struct list_head *list) + { + char *str, *tok, *ptr = NULL; +- size_t len = strlen(value); ++ size_t len = strlen(value) + 1; + + str = alloca(len); + if (!str) +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 83e3215..17cbe9a 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -2234,8 +2234,8 @@ static int do_get_entries(struct ldap_search_params *sp, struct map_source *sour + mapent = new_me; + strcat(mapent, " "); + strncat(mapent, v_val, v_len); +- mapent[new_size] = '\0'; +- mapent_len = new_size; ++ mapent[new_size - 1] = '\0'; ++ mapent_len = new_size - 1; + } else { + char *estr; + estr = strerror_r(errno, buf, sizeof(buf)); +@@ -2723,8 +2723,8 @@ static int lookup_one(struct autofs_point *ap, + mapent = new_me; + strcat(mapent, " "); + strncat(mapent, v_val, v_len); +- mapent[new_size] = '\0'; +- mapent_len = new_size; ++ mapent[new_size - 1] = '\0'; ++ mapent_len = new_size - 1; + } else { + char *estr; + estr = strerror_r(errno, buf, sizeof(buf)); +diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c +index 7a6a57d..237fd50 100644 +--- a/modules/parse_hesiod.c ++++ b/modules/parse_hesiod.c +@@ -117,7 +117,7 @@ static int parse_nfs(struct autofs_point *ap, + p++; + + /* Isolate the remote mountpoint for this NFS fs. */ +- for (i = 0; (!isspace(p[i]) && i < (int) sizeof(mount)); i++) { ++ for (i = 0; (!isspace(p[i]) && i < ((int) sizeof(mount) - 1)); i++) { + if (!p[i]) { + error(ap->logopt, MODPREFIX + "unexpeced end of input looking for NFS " +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index ae1caf7..c1fc528 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1135,7 +1135,7 @@ static int mount_subtree(struct autofs_point *ap, struct mapent *me, + } + ro_len = strlen(ro_loc); + +- tmp = alloca(mnt_root_len + 1); ++ tmp = alloca(mnt_root_len + 2); + strcpy(tmp, mnt_root); + tmp[mnt_root_len] = '/'; + tmp[mnt_root_len + 1] = '\0'; diff --git a/SOURCES/autofs-5.0.7-fix-some-automount_8-typos.patch b/SOURCES/autofs-5.0.7-fix-some-automount_8-typos.patch new file mode 100644 index 0000000..5e84c6c --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-some-automount_8-typos.patch @@ -0,0 +1,45 @@ +autofs-5.0.7 - fix some automount(8) typos + +From: Ian Kent + +Fix a couple of spelling errors in the automount(8) man page +that have been around for a long time. +--- + CHANGELOG | 1 + + man/automount.8 | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index d8e4049..488ad1e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -37,6 +37,7 @@ + - fix libtirpc build option to require libtirpc-devel if needed. + - fix systemd unidir in spec file. + - document browse option in man page. ++- fix some automount(8) typos. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/man/automount.8 b/man/automount.8 +index dddebce..7cc32c5 100644 +--- a/man/automount.8 ++++ b/man/automount.8 +@@ -43,7 +43,7 @@ autofs managed mounts. + .TP + .I "\-d, \-\-debug" + Enables logging of general status and progress messages as well as +-debuging messages for all autofs managed mounts. ++debugging messages for all autofs managed mounts. + .TP + .I "\-Dvariable=value" + Define a global macro substitution variable. Global definitions +@@ -133,7 +133,7 @@ unused. If the force umount at exit option is used the filesystems + will be umounted but the mount will not be released by the kernel + until they are no longer in use by the processes that held them busy. + If automount managed filesystems are found mounted when autofs is +-started they will be recoverd unless they are no longer present in ++started they will be recovered unless they are no longer present in + the map in which case they need to umounted manually. + .P + If the option to disable the check to see if the daemon is already diff --git a/SOURCES/autofs-5.0.7-fix-spawn_umount-return-check-in-mount_bind-lookup_init.patch b/SOURCES/autofs-5.0.7-fix-spawn_umount-return-check-in-mount_bind-lookup_init.patch new file mode 100644 index 0000000..2d02023 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-spawn_umount-return-check-in-mount_bind-lookup_init.patch @@ -0,0 +1,23 @@ +autofs-5.0.7 - fix spawn_umount() return check in mount_bind.c:lookup_init() + +From: Ian Kent + +Check return of spawn_umount() and report it if it fails. +--- + modules/mount_bind.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index 4975294..d6c6fe7 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -57,7 +57,8 @@ int mount_init(void **context) + bind_works = 1; + } + +- spawn_umount(LOGOPT_NONE, "-n", t2_dir, NULL); ++ if (spawn_umount(LOGOPT_NONE, "-n", t2_dir, NULL) != 0) ++ debug(LOGOPT_ANY, MODPREFIX "umount failed for %s", t2_dir); + + out: + rmdir(t1_dir); diff --git a/SOURCES/autofs-5.0.7-fix-submount-offset-delete.patch b/SOURCES/autofs-5.0.7-fix-submount-offset-delete.patch new file mode 100644 index 0000000..b38e214 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-submount-offset-delete.patch @@ -0,0 +1,45 @@ +autofs-5.0.7 - fix submount offset delete + +From: Ian Kent + +As part of the implementation to allow for limited update of +the internal hosts map by using a HUP signal some code that +deleted any offset entries from the cache on lookup was removed +as it appeared to not be needed. + +There is however a case where it is needed to avoid a duplicate +cache entry failure on lookup. +--- + + CHANGELOG | 1 + + daemon/automount.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 7eb7235..76c1f73 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -18,6 +18,7 @@ + - fix map entry duplicate offset detection. + - Allow nsswitch.conf to not contain "automount:" lines. + - fix nobind man page description. ++- fix submount offset delete. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/daemon/automount.c b/daemon/automount.c +index e56f9e1..4a3eb3d 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -544,8 +544,8 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl) + * If we are a submount we need to umount any offsets our + * parent may have mounted over top of us. + */ +- /*if (ap->submount) +- left += umount_subtree_mounts(ap->parent, path, is_autofs_fs);*/ ++ if (ap->submount) ++ left += umount_subtree_mounts(ap->parent, path, is_autofs_fs); + + left += umount_subtree_mounts(ap, path, is_autofs_fs); + diff --git a/SOURCES/autofs-5.0.7-fix-submount-tree-not-all-expiring.patch b/SOURCES/autofs-5.0.7-fix-submount-tree-not-all-expiring.patch new file mode 100644 index 0000000..09ed383 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-submount-tree-not-all-expiring.patch @@ -0,0 +1,70 @@ +autofs-5.0.7 - fix submount tree not all expiring + +From: Ian Kent + +Due to the change in the expire-specific-submount-only patch, sub-mounts +within an indirect mount that follow a submount (in the check order) won't +be expired if that submount is busy. +--- + CHANGELOG | 1 + + lib/master.c | 24 +++++++++++++++--------- + 2 files changed, 16 insertions(+), 9 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index f1ec1e5..4106e7f 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -39,6 +39,7 @@ + - document browse option in man page. + - fix some automount(8) typos. + - syncronize handle_mounts() shutdown. ++- fix submount tree not all expiring. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/master.c b/lib/master.c +index a0e62f2..64dbcb1 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -905,15 +905,24 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state + this = list_entry(p, struct autofs_point, mounts); + p = p->prev; + +- if (!master_submount_list_empty(this)) { +- mounts_mutex_unlock(ap); +- return master_notify_submount(this, path, state); +- } +- + /* path not the same */ + if (strcmp(this->path, path)) + continue; + ++ if (!master_submount_list_empty(this)) { ++ char *this_path = strdup(this->path); ++ if (this_path) { ++ mounts_mutex_unlock(ap); ++ master_notify_submount(this, path, state); ++ mounts_mutex_lock(ap); ++ if (!__master_find_submount(ap, this_path)) { ++ free(this_path); ++ continue; ++ } ++ free(this_path); ++ } ++ } ++ + /* Now we have found the submount we want to expire */ + + st_mutex_lock(); +@@ -959,10 +968,7 @@ int master_notify_submount(struct autofs_point *ap, const char *path, enum state + st_mutex_lock(); + } + st_mutex_unlock(); +- mounts_mutex_unlock(ap); +- +- return ret; +- ++ break; + } + + mounts_mutex_unlock(ap); diff --git a/SOURCES/autofs-5.0.7-fix-syncronize-handle_mounts-shutdown.patch b/SOURCES/autofs-5.0.7-fix-syncronize-handle_mounts-shutdown.patch new file mode 100644 index 0000000..c6a90af --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-syncronize-handle_mounts-shutdown.patch @@ -0,0 +1,36 @@ +autofs-5.0.7 - fix syncronize handle_mounts() shutdown + +From: Ian Kent + +A recent change to fix a problem where automount would exit when re-reading +the master map if more than on entry had been removed causes automount to +ignore HUP signals if the mount list is empty. + +Removing that check and testing shows that the remainder of the change still +fixes the original problem. +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -56,6 +56,7 @@ + - don't override LDFLAGS in make rules. + - fix a couple of compiler warnings. + - add after sssd dependency to unit file. ++- fix syncronize handle_mounts() shutdown. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -1286,7 +1286,7 @@ static int do_hup_signal(struct master * + + master_mutex_lock(); + /* Already doing a map read or shutdown or no mounts */ +- if (master->reading || list_empty(&master->mounts)) { ++ if (master->reading) { + status = pthread_mutex_unlock(&mrc.mutex); + if (status) + fatal(status); diff --git a/SOURCES/autofs-5.0.7-fix-systemd-unidir-in-spec-file.patch b/SOURCES/autofs-5.0.7-fix-systemd-unidir-in-spec-file.patch new file mode 100644 index 0000000..d856faf --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-systemd-unidir-in-spec-file.patch @@ -0,0 +1,72 @@ +autofs-5.0.7 - fix systemd unidir in spec file + +From: Ian Kent + + +--- + CHANGELOG | 1 + + autofs.spec | 16 ++++++++-------- + 2 files changed, 9 insertions(+), 8 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index b6b2679..ecdea0b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -35,6 +35,7 @@ + - add symlink pseudo option. + - fix requires in spec file. + - fix libtirpc build option to require libtirpc-devel if needed. ++- fix systemd unidir in spec file. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/autofs.spec b/autofs.spec +index f77acc1..a768e44 100644 +--- a/autofs.spec ++++ b/autofs.spec +@@ -76,7 +76,7 @@ inkludera n + %setup -q + echo %{version}-%{release} > .version + %if %{with_systemd} +- %define _unitdir %{?_unitdir:/lib/systemd/system} ++ %define unitdir %{?_unitdir:/lib/systemd/system} + %define systemd_configure_arg --with-systemd + %endif + %if %{with_libtirpc} +@@ -95,7 +95,7 @@ CFLAGS="$RPM_OPT_FLAGS -Wall" make initdir=/etc/rc.d/init.d DONTSTRIP=1 + %install + rm -rf $RPM_BUILD_ROOT + %if %{with_systemd} +-install -d -m 755 $RPM_BUILD_ROOT%{_unitdir} ++install -d -m 755 $RPM_BUILD_ROOT%{unitdir} + %else + mkdir -p -m755 $RPM_BUILD_ROOT/etc/rc.d/init.d + %endif +@@ -109,9 +109,13 @@ make install mandir=%{_mandir} initdir=/etc/rc.d/init.d INSTALLROOT=$RPM_BUILD_R + echo make -C redhat + make -C redhat + %if %{with_systemd} +-install -m 644 redhat/autofs.service $RPM_BUILD_ROOT%{_unitdir}/autofs.service ++# Configure can get this wrong when the unit files appear under /lib and /usr/lib ++find $RPM_BUILD_ROOT -type f -name autofs.service -exec rm -f {} \; ++install -m 644 redhat/autofs.service $RPM_BUILD_ROOT%{unitdir}/autofs.service ++%define init_file_name %{unitdir}/autofs.service + %else + install -m 755 redhat/autofs.init $RPM_BUILD_ROOT/etc/rc.d/init.d/autofs ++%define init_file_name /etc/rc.d/init.d/autofs + %endif + install -m 644 redhat/autofs.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/autofs + +@@ -170,11 +174,7 @@ fi + %files + %defattr(-,root,root) + %doc CREDITS CHANGELOG INSTALL COPY* README* samples/ldap* samples/autofs.schema samples/autofs_ldap_auth.conf +-%if %{with_systemd} +-%{_unitdir}/autofs.service +-%else +-%config /etc/rc.d/init.d/autofs +-%endif ++%config %{init_file_name} + %config(noreplace) /etc/auto.master + %config(noreplace,missingok) /etc/auto.misc + %config(noreplace,missingok) /etc/auto.net diff --git a/SOURCES/autofs-5.0.7-fix-typo-in-automount-8.patch b/SOURCES/autofs-5.0.7-fix-typo-in-automount-8.patch new file mode 100644 index 0000000..0dd7c2b --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-typo-in-automount-8.patch @@ -0,0 +1,33 @@ +autofs-5.0.7 - fix typo in automount(8) + +From: Ian Kent + + +--- + + CHANGELOG | 1 + + man/automount.8 | 2 +- + 2 files changed, 2 insertions(+), 1 deletions(-) + + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -4,6 +4,7 @@ + - fix use cache entry after free in lookup_prune_one_cache(). + - fix ipv6 proximity calculation. + - fix parse buffer initialization. ++- fix typo in automount(8). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/automount.8 ++++ autofs-5.0.7/man/automount.8 +@@ -51,7 +51,7 @@ are over-ridden macro definitions of the + mount entries. + .TP + .I "\-f, \-\-foreground" +-Run the daemon in the forground and log to stderr instead of syslog." ++Run the daemon in the foreground and log to stderr instead of syslog." + .TP + .I "\-r, \-\-random-multimount-selection" + Enables the use of ramdom selection when choosing a host from a diff --git a/SOURCES/autofs-5.0.7-fix-use-cache-entry-after-free-mistake.patch b/SOURCES/autofs-5.0.7-fix-use-cache-entry-after-free-mistake.patch new file mode 100644 index 0000000..a469c16 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-use-cache-entry-after-free-mistake.patch @@ -0,0 +1,49 @@ +autofs-5.0.7 - fix use cache entry after free mistake + +From: Ian Kent + +Fix an obvious use after free mistake in lookup_prune_one_cache(). +--- + + CHANGELOG | 1 + + daemon/lookup.c | 7 +++++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index faf4c80..dc38580 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -1,6 +1,7 @@ + ??/??/2012 autofs-5.0.8 + ======================= + - fix nobind sun escaped map entries. ++- fix use cache entry after free in lookup_prune_one_cache(). + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 7909536..e3d9536 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -1103,15 +1103,18 @@ void lookup_prune_one_cache(struct autofs_point *ap, struct mapent_cache *mc, ti + if (valid) + cache_delete(mc, key); + else if (!is_mounted(_PROC_MOUNTS, path, MNTS_AUTOFS)) { ++ dev_t devid = ap->dev; + status = CHE_FAIL; ++ if (ap->type == LKP_DIRECT) ++ devid = this->dev; + if (this->ioctlfd == -1) + status = cache_delete(mc, key); + if (status != CHE_FAIL) { + if (ap->type == LKP_INDIRECT) { + if (ap->flags & MOUNT_FLAG_GHOST) +- rmdir_path(ap, path, ap->dev); ++ rmdir_path(ap, path, devid); + } else +- rmdir_path(ap, path, this->dev); ++ rmdir_path(ap, path, devid); + } + } + cache_unlock(mc); diff --git a/SOURCES/autofs-5.0.7-fix-use-get_proximity-without-libtirpc.patch b/SOURCES/autofs-5.0.7-fix-use-get_proximity-without-libtirpc.patch new file mode 100644 index 0000000..74ed8fa --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-use-get_proximity-without-libtirpc.patch @@ -0,0 +1,54 @@ +autofs-5.0.7 - fix use get_proximity() without libtirpc + +From: Ian Kent + +If autofs is not using libtirpc and there are any configured IPv6 +interfaces then get_proximity() will fail with PROXIMITY_UNSUPPORTED. + +In this case when checking interfaces the IPv6 interfaces need to be +ignored. +--- + + CHANGELOG | 1 + + modules/replicated.c | 8 ++------ + 2 files changed, 3 insertions(+), 6 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 5bcb1af..460bd27 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -20,6 +20,7 @@ + - fix nobind man page description. + - fix submount offset delete. + - fix init script status return. ++- fix use get_proximity() without libtirpc. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/replicated.c b/modules/replicated.c +index bd6003b..6b96320 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -184,9 +184,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + break; + + case AF_INET6: +-#ifndef WITH_LIBTIRPC +- return PROXIMITY_UNSUPPORTED; +-#else ++#ifdef WITH_LIBTIRPC + if (host_addr->sa_family == AF_INET) + break; + if6_addr = (struct sockaddr_in6 *) this->ifa_addr; +@@ -251,9 +249,7 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + break; + + case AF_INET6: +-#ifndef WITH_LIBTIRPC +- return PROXIMITY_UNSUPPORTED; +-#else ++#ifdef WITH_LIBTIRPC + if (host_addr->sa_family == AF_INET) + break; + if6_addr = (struct sockaddr_in6 *) this->ifa_addr; diff --git a/SOURCES/autofs-5.0.7-fix-wildcard-multi-map-regression.patch b/SOURCES/autofs-5.0.7-fix-wildcard-multi-map-regression.patch new file mode 100644 index 0000000..44e4a18 --- /dev/null +++ b/SOURCES/autofs-5.0.7-fix-wildcard-multi-map-regression.patch @@ -0,0 +1,225 @@ +autofs-5.0.7 - fix wildcard multi map regression + +From: Ian Kent + +A recent patch that removed code to add the current map entry when +being parsed if it didn't already exist cause wildcard indirect +multi-mount map entries to fail to mount. + +Indirect multi-mount map entries need the entry matched by a wildcard +lookup to be added to the map entry cache because subsequent operations +expect a distinct map entry to be present or they will fail. This is +what the code that was removed did but it did so in the wrong place +which caused a deadlock situation. +--- + CHANGELOG | 1 + + modules/lookup_file.c | 23 ++++++++++++++++------- + modules/lookup_ldap.c | 19 +++++++++++++++---- + modules/lookup_nisplus.c | 21 ++++++++++++++++----- + modules/lookup_sss.c | 17 ++++++++++++++--- + modules/lookup_yp.c | 21 ++++++++++++++++----- + 6 files changed, 78 insertions(+), 24 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 97d6f48..46ef335 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -29,6 +29,7 @@ + - modules/replicated.c: use sin6_addr.s6_addr32. + - workaround missing GNU versionsort extension. + - dont fail on master map self include. ++- fix wildcard multi map regression. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index f37bed9..65e5ee6 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -1040,7 +1040,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + return NSS_STATUS_UNAVAIL; + } + +- cache_readlock(mc); ++ cache_writelock(mc); + me = cache_lookup_first(mc); + if (me && st.st_mtime <= me->age) { + /* +@@ -1082,7 +1082,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + } + } + +- cache_readlock(mc); ++ cache_writelock(mc); + do_cache_lookup: + me = cache_lookup(mc, key); + /* +@@ -1098,11 +1098,20 @@ do_cache_lookup: + if (!me) + me = cache_lookup_distinct(mc, "*"); + } +- if (me && me->mapent && (me->source == source || *me->key == '/')) { +- pthread_cleanup_push(cache_lock_cleanup, mc); +- strcpy(mapent_buf, me->mapent); +- mapent = mapent_buf; +- pthread_cleanup_pop(0); ++ if (me && me->mapent) { ++ /* ++ * Add wildcard match for later validation checks and ++ * negative cache lookups. ++ */ ++ if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ ret = cache_update(mc, source, key, me->mapent, me->age); ++ if (!(ret & (CHE_OK | CHE_UPDATED))) ++ me = NULL; ++ } ++ if (me && (me->source == source || *me->key == '/')) { ++ strcpy(mapent_buf, me->mapent); ++ mapent = mapent_buf; ++ } + } + cache_unlock(mc); + +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 431e50d..83e3215 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -2969,7 +2969,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + return status; + } + +- cache_readlock(mc); ++ cache_writelock(mc); + me = cache_lookup(mc, key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { +@@ -2979,9 +2979,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (!me) + me = cache_lookup_distinct(mc, "*"); + } +- if (me && me->mapent && (me->source == source || *me->key == '/')) { +- strcpy(mapent_buf, me->mapent); +- mapent = mapent_buf; ++ if (me && me->mapent) { ++ /* ++ * Add wildcard match for later validation checks and ++ * negative cache lookups. ++ */ ++ if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ ret = cache_update(mc, source, key, me->mapent, me->age); ++ if (!(ret & (CHE_OK | CHE_UPDATED))) ++ me = NULL; ++ } ++ if (me && (me->source == source || *me->key == '/')) { ++ strcpy(mapent_buf, me->mapent); ++ mapent = mapent_buf; ++ } + } + cache_unlock(mc); + +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 9fced96..8237a1e 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -561,7 +561,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + return status; + } + +- cache_readlock(mc); ++ cache_writelock(mc); + me = cache_lookup(mc, key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { +@@ -571,10 +571,21 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (!me) + me = cache_lookup_distinct(mc, "*"); + } +- if (me && me->mapent && (me->source == source || *me->key == '/')) { +- mapent_len = strlen(me->mapent); +- mapent = malloc(mapent_len + 1); +- strcpy(mapent, me->mapent); ++ if (me && me->mapent) { ++ /* ++ * Add wildcard match for later validation checks and ++ * negative cache lookups. ++ */ ++ if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ ret = cache_update(mc, source, key, me->mapent, me->age); ++ if (!(ret & (CHE_OK | CHE_UPDATED))) ++ me = NULL; ++ } ++ if (me && (me->source == source || *me->key == '/')) { ++ mapent_len = strlen(me->mapent); ++ mapent = malloc(mapent_len + 1); ++ strcpy(mapent, me->mapent); ++ } + } + cache_unlock(mc); + +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index e0b84cc..5c2ed0a 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -645,9 +645,20 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (!me) + me = cache_lookup_distinct(mc, "*"); + } +- if (me && me->mapent && (me->source == source || *me->key == '/')) { +- strcpy(mapent_buf, me->mapent); +- mapent = mapent_buf; ++ if (me && me->mapent) { ++ /* ++ * Add wildcard match for later validation checks and ++ * negative cache lookups. ++ */ ++ if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ ret = cache_update(mc, source, key, me->mapent, me->age); ++ if (!(ret & (CHE_OK | CHE_UPDATED))) ++ me = NULL; ++ } ++ if (me && (me->source == source || *me->key == '/')) { ++ strcpy(mapent_buf, me->mapent); ++ mapent = mapent_buf; ++ } + } + cache_unlock(mc); + +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index 720df2e..a716e1f 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -662,7 +662,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + return status; + } + +- cache_readlock(mc); ++ cache_writelock(mc); + me = cache_lookup(mc, key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { +@@ -672,10 +672,21 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (!me) + me = cache_lookup_distinct(mc, "*"); + } +- if (me && me->mapent && (me->source == source || *me->key == '/')) { +- mapent_len = strlen(me->mapent); +- mapent = alloca(mapent_len + 1); +- strcpy(mapent, me->mapent); ++ if (me && me->mapent) { ++ /* ++ * Add wildcard match for later validation checks and ++ * negative cache lookups. ++ */ ++ if (ap->type == LKP_INDIRECT && *me->key == '*') { ++ ret = cache_update(mc, source, key, me->mapent, me->age); ++ if (!(ret & (CHE_OK | CHE_UPDATED))) ++ me = NULL; ++ } ++ if (me && (me->source == source || *me->key == '/')) { ++ mapent_len = strlen(me->mapent); ++ mapent = alloca(mapent_len + 1); ++ strcpy(mapent, me->mapent); ++ } + } + cache_unlock(mc); + diff --git a/SOURCES/autofs-5.0.7-handle-new-location-of-systemd.patch b/SOURCES/autofs-5.0.7-handle-new-location-of-systemd.patch new file mode 100644 index 0000000..1c26794 --- /dev/null +++ b/SOURCES/autofs-5.0.7-handle-new-location-of-systemd.patch @@ -0,0 +1,57 @@ +autofs-5.0.7 - Handle new location of systemd + +From: Frederic Crozat + +Some distributions are moving systemd unit files from /lib to +/usr/lib, so we need to test both directories. + +edit: imk +It occurs to me I've forgotten to check for the 64 bit variants +of the directories, so add them as well. +end edit: imk +--- + + CHANGELOG | 1 + + aclocal.m4 | 2 +- + configure | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 3bdf8a4..8f6bb3a 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -14,6 +14,7 @@ + - allow non root user to check status. + - fix recursive mount deadlock. + - increase file map read buffer size. ++- handle new location of systemd. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/aclocal.m4 b/aclocal.m4 +index 1798c8b..47bca0c 100644 +--- a/aclocal.m4 ++++ b/aclocal.m4 +@@ -234,7 +234,7 @@ AC_DEFUN([AF_WITH_SYSTEMD], + [if test "$withval" = yes; then + if test -z "$systemddir"; then + AC_MSG_CHECKING([location of the systemd unit files directory]) +- for systemd_d in /lib/systemd/system; do ++ for systemd_d in /usr/lib/systemd/system /usr/lib64/systemd/system /lib/systemd/system /lib64/systemd/system; do + if test -z "$systemddir"; then + if test -d "$systemd_d"; then + systemddir="$systemd_d" +diff --git a/configure b/configure +index ba3bba6..3722a46 100755 +--- a/configure ++++ b/configure +@@ -2157,7 +2157,7 @@ if test "${with_systemd+set}" = set; then : + if test -z "$systemddir"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: checking location of the systemd unit files directory" >&5 + $as_echo_n "checking location of the systemd unit files directory... " >&6; } +- for systemd_d in /lib/systemd/system; do ++ for systemd_d in /usr/lib/systemd/system /usr/lib64/systemd/system /lib/systemd/system /lib64/systemd/system; do + if test -z "$systemddir"; then + if test -d "$systemd_d"; then + systemddir="$systemd_d" diff --git a/SOURCES/autofs-5.0.7-improve-timeout-option-description.patch b/SOURCES/autofs-5.0.7-improve-timeout-option-description.patch new file mode 100644 index 0000000..cb4cb4e --- /dev/null +++ b/SOURCES/autofs-5.0.7-improve-timeout-option-description.patch @@ -0,0 +1,84 @@ +autofs-5.0.7 - improve timeout option description + +From: Ian Kent + +The description of the configuration option is a little misleading. +So add some explaination about the internal default and the reason +the default installed configuration overrides it. +--- + CHANGELOG | 1 + + man/auto.master.5.in | 5 ++++- + man/automount.8 | 5 ++++- + redhat/autofs.sysconfig.in | 5 ++++- + samples/autofs.conf.default.in | 5 ++++- + 5 files changed, 17 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -65,6 +65,7 @@ + - fix portmap lookup. + - only probe specific nfs version if requested. + - fix ipv6 libtirpc getport. ++- improve timeout option description. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/auto.master.5.in ++++ autofs-5.0.7/man/auto.master.5.in +@@ -212,7 +212,10 @@ configuration file + They are: + .TP + .B TIMEOUT +-sets the default mount timeout (program default 600). ++Sets the default mount timeout in seconds. The internal program ++default is 10 minutes, but the default installed configuration ++overrides this and sets the timeout to 5 minutes to be consistent ++with earlier autofs releases. + .TP + .B NEGATIVE_TIMEOUT + Set the default timeout for caching failed key lookups (program default +--- autofs-5.0.7.orig/man/automount.8 ++++ autofs-5.0.7/man/automount.8 +@@ -29,10 +29,13 @@ Print brief help on program usage. + .I "\-p, \-\-pid-file" + Write the pid of the daemon to the specified file. + .TP +-.I "\-t, \-\-timeout" ++.I "\-t , \-\-timeout " + Set the global minimum timeout, in seconds, until directories + are unmounted. The default is 10 minutes. Setting the timeout + to zero disables umounts completely. ++The internal program default is 10 minutes, but the default ++installed configuration overrides this and sets the timeout ++to 5 minutes to be consistent with earlier autofs releases. + .TP + .I "\-n , \-\-negative\-timeout " + Set the default timeout for caching failed key lookups. The default is 60 seconds. +--- autofs-5.0.7.orig/redhat/autofs.sysconfig.in ++++ autofs-5.0.7/redhat/autofs.sysconfig.in +@@ -5,7 +5,10 @@ + # + #MASTER_MAP_NAME="auto.master" + # +-# TIMEOUT - set the default mount timeout (default 600). ++# TIMEOUT - set the default mount timeout in secons. The internal ++# program default is 10 minutes, but the default installed ++# configuration overrides this and sets the timeout to 5 ++# minutes to be consistent with earlier autofs releases. + # + TIMEOUT=300 + # +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -5,7 +5,10 @@ + # + #MASTER_MAP_NAME="auto.master" + # +-# TIMEOUT - set the default mount timeout (default 600). ++# TIMEOUT - set the default mount timeout in secons. The internal ++# program default is 10 minutes, but the default installed ++# configuration overrides this and sets the timeout to 5 ++# minutes to be consistent with earlier autofs releases. + # + TIMEOUT=300 + # diff --git a/SOURCES/autofs-5.0.7-include-usage-in-usage-message.patch b/SOURCES/autofs-5.0.7-include-usage-in-usage-message.patch new file mode 100644 index 0000000..1c8a565 --- /dev/null +++ b/SOURCES/autofs-5.0.7-include-usage-in-usage-message.patch @@ -0,0 +1,25 @@ +autofs-5.0.7 - include usage in usage message + +From: Ian Kent + +Since usage is a case entry we should also nclude it in the usage +message. +--- + + redhat/autofs.init.in | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + + +diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in +index 8e355da..ec6d5d6 100644 +--- a/redhat/autofs.init.in ++++ b/redhat/autofs.init.in +@@ -155,7 +155,7 @@ function reload() { + } + + function usage_message() { +- echo $"Usage: $0 {start|forcestart|stop|status|restart|force-reload|forcerestart|reload|condrestart|try-restart}" ++ echo $"Usage: $0 {start|forcestart|stop|status|restart|force-reload|forcerestart|reload|condrestart|try-restart|usage}" + } + + RETVAL=0 diff --git a/SOURCES/autofs-5.0.7-lib-defaults-use-WITH_LDAP-conditional-around-LDAP-types.patch b/SOURCES/autofs-5.0.7-lib-defaults-use-WITH_LDAP-conditional-around-LDAP-types.patch new file mode 100644 index 0000000..22e0418 --- /dev/null +++ b/SOURCES/autofs-5.0.7-lib-defaults-use-WITH_LDAP-conditional-around-LDAP-types.patch @@ -0,0 +1,448 @@ +autofs-5.0.7 - lib/defaults.c: use WITH_LDAP conditional around LDAP types + +From: Chris Packham + +Wrap the inclusion of lookup_ldap.h and functions that use ldap_uri or +ldap_schema with the WITH_LDAP conditional. WITH_LDAP is set by the +configure step when LDAP support is not desired. This also allows +compilation on a system that doesn't have any LDAP libraries. +--- + + CHANGELOG | 1 + include/defaults.h | 14 +- + include/lookup_ldap.h | 1 + lib/defaults.c | 325 +++++++++++++++++++++++++------------------------ + modules/lookup_ldap.c | 1 + 5 files changed, 175 insertions(+), 167 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index ba1d65b..1130db6 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -24,6 +24,7 @@ + - don't use dirent d_type to filter out files in scandir() + - don't schedule new alarms after readmap. + - use numeric protocol ids instead of protoent structs. ++- lib/defaults.c: use WITH_LDAP conditional around LDAP types. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/include/defaults.h b/include/defaults.h +index cda2174..871e14b 100644 +--- a/include/defaults.h ++++ b/include/defaults.h +@@ -44,8 +44,16 @@ + + #define DEFAULT_MAP_HASH_TABLE_SIZE 1024 + ++#ifdef WITH_LDAP + struct ldap_schema; + struct ldap_searchdn; ++void defaults_free_uris(struct list_head *); ++struct list_head *defaults_get_uris(void); ++struct ldap_schema *defaults_get_default_schema(void); ++void defaults_free_searchdns(struct ldap_searchdn *); ++struct ldap_searchdn *defaults_get_searchdns(void); ++struct ldap_schema *defaults_get_schema(void); ++#endif + + unsigned int defaults_read_config(unsigned int); + const char *defaults_get_master_map(void); +@@ -57,12 +65,6 @@ unsigned int defaults_get_logging(void); + const char *defaults_get_ldap_server(void); + unsigned int defaults_get_ldap_timeout(void); + unsigned int defaults_get_ldap_network_timeout(void); +-struct list_head *defaults_get_uris(void); +-void defaults_free_uris(struct list_head *); +-struct ldap_schema *defaults_get_default_schema(void); +-struct ldap_schema *defaults_get_schema(void); +-struct ldap_searchdn *defaults_get_searchdns(void); +-void defaults_free_searchdns(struct ldap_searchdn *); + unsigned int defaults_get_mount_nfs_default_proto(void); + unsigned int defaults_get_append_options(void); + unsigned int defaults_get_mount_wait(void); +diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h +index e441a61..9a4ce73 100644 +--- a/include/lookup_ldap.h ++++ b/include/lookup_ldap.h +@@ -8,7 +8,6 @@ + #include + #include + #include +-#include + #include + #endif + +diff --git a/lib/defaults.c b/lib/defaults.c +index 5ce71b7..ae1162f 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -17,9 +17,12 @@ + #include + #include + ++#include "config.h" + #include "list.h" + #include "defaults.h" ++#ifdef WITH_LDAP + #include "lookup_ldap.h" ++#endif + #include "log.h" + #include "automount.h" + +@@ -197,6 +200,7 @@ static int parse_line(char *line, char **res, char **value) + return 1; + } + ++#ifdef WITH_LDAP + void defaults_free_uris(struct list_head *list) + { + struct list_head *next; +@@ -290,166 +294,6 @@ struct list_head *defaults_get_uris(void) + return list; + } + +-/* +- * Read config env variables and check they have been set. +- * +- * This simple minded routine assumes the config file +- * is valid bourne shell script without spaces around "=" +- * and that it has valid values. +- */ +-unsigned int defaults_read_config(unsigned int to_syslog) +-{ +- FILE *f; +- char buf[MAX_LINE_LEN]; +- char *res; +- +- f = open_fopen_r(DEFAULTS_CONFIG_FILE); +- if (!f) +- return 0; +- +- while ((res = fgets(buf, MAX_LINE_LEN, f))) { +- char *key, *value; +- +- if (!parse_line(res, &key, &value)) +- continue; +- +- if (check_set_config_value(key, ENV_NAME_MASTER_MAP, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_TIMEOUT, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_NEGATIVE_TIMEOUT, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_BROWSE_MODE, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_LOGGING, value, to_syslog) || +- check_set_config_value(key, ENV_LDAP_TIMEOUT, value, to_syslog) || +- check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_MAP_ATTR, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_ENTRY_ATTR, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_VALUE_ATTR, value, to_syslog) || +- check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) || +- check_set_config_value(key, ENV_MOUNT_WAIT, value, to_syslog) || +- check_set_config_value(key, ENV_UMOUNT_WAIT, value, to_syslog) || +- check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog) || +- check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog) || +- check_set_config_value(key, ENV_MOUNT_NFS_DEFAULT_PROTOCOL, value, to_syslog)) +- ; +- } +- +- if (!feof(f) || ferror(f)) { +- if (!to_syslog) { +- fprintf(stderr, +- "fgets returned error %d while reading %s\n", +- ferror(f), DEFAULTS_CONFIG_FILE); +- } else { +- logmsg("fgets returned error %d while reading %s", +- ferror(f), DEFAULTS_CONFIG_FILE); +- } +- fclose(f); +- return 0; +- } +- +- fclose(f); +- return 1; +-} +- +-const char *defaults_get_master_map(void) +-{ +- char *master; +- +- master = get_env_string(ENV_NAME_MASTER_MAP); +- if (!master) +- return strdup(default_master_map_name); +- +- return (const char *) master; +-} +- +-int defaults_master_set(void) +-{ +- char *val = getenv(ENV_NAME_MASTER_MAP); +- if (!val) +- return 0; +- +- return 1; +-} +- +-unsigned int defaults_get_timeout(void) +-{ +- long timeout; +- +- timeout = get_env_number(ENV_NAME_TIMEOUT); +- if (timeout < 0) +- timeout = DEFAULT_TIMEOUT; +- +- return (unsigned int) timeout; +-} +- +-unsigned int defaults_get_negative_timeout(void) +-{ +- long n_timeout; +- +- n_timeout = get_env_number(ENV_NAME_NEGATIVE_TIMEOUT); +- if (n_timeout <= 0) +- n_timeout = DEFAULT_NEGATIVE_TIMEOUT; +- +- return (unsigned int) n_timeout; +-} +- +-unsigned int defaults_get_browse_mode(void) +-{ +- int res; +- +- res = get_env_yesno(ENV_NAME_BROWSE_MODE); +- if (res < 0) +- res = DEFAULT_BROWSE_MODE; +- +- return res; +-} +- +-unsigned int defaults_get_logging(void) +-{ +- char *res; +- unsigned int logging = DEFAULT_LOGGING; +- +- res = get_env_string(ENV_NAME_LOGGING); +- if (!res) +- return logging; +- +- if (!strcasecmp(res, "none")) +- logging = DEFAULT_LOGGING; +- else { +- if (!strcasecmp(res, "verbose")) +- logging |= LOGOPT_VERBOSE; +- +- if (!strcasecmp(res, "debug")) +- logging |= LOGOPT_DEBUG; +- } +- +- free(res); +- +- return logging; +-} +- +-unsigned int defaults_get_ldap_timeout(void) +-{ +- int res; +- +- res = get_env_number(ENV_LDAP_TIMEOUT); +- if (res < 0) +- res = DEFAULT_LDAP_TIMEOUT; +- +- return res; +-} +- +-unsigned int defaults_get_ldap_network_timeout(void) +-{ +- int res; +- +- res = get_env_number(ENV_LDAP_NETWORK_TIMEOUT); +- if (res < 0) +- res = DEFAULT_LDAP_NETWORK_TIMEOUT; +- +- return res; +-} +- + struct ldap_schema *defaults_get_default_schema(void) + { + struct ldap_schema *schema; +@@ -645,6 +489,167 @@ struct ldap_schema *defaults_get_schema(void) + + return schema; + } ++#endif ++ ++/* ++ * Read config env variables and check they have been set. ++ * ++ * This simple minded routine assumes the config file ++ * is valid bourne shell script without spaces around "=" ++ * and that it has valid values. ++ */ ++unsigned int defaults_read_config(unsigned int to_syslog) ++{ ++ FILE *f; ++ char buf[MAX_LINE_LEN]; ++ char *res; ++ ++ f = open_fopen_r(DEFAULTS_CONFIG_FILE); ++ if (!f) ++ return 0; ++ ++ while ((res = fgets(buf, MAX_LINE_LEN, f))) { ++ char *key, *value; ++ ++ if (!parse_line(res, &key, &value)) ++ continue; ++ ++ if (check_set_config_value(key, ENV_NAME_MASTER_MAP, value, to_syslog) || ++ check_set_config_value(key, ENV_NAME_TIMEOUT, value, to_syslog) || ++ check_set_config_value(key, ENV_NAME_NEGATIVE_TIMEOUT, value, to_syslog) || ++ check_set_config_value(key, ENV_NAME_BROWSE_MODE, value, to_syslog) || ++ check_set_config_value(key, ENV_NAME_LOGGING, value, to_syslog) || ++ check_set_config_value(key, ENV_LDAP_TIMEOUT, value, to_syslog) || ++ check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, value, to_syslog) || ++ check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value, to_syslog) || ++ check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value, to_syslog) || ++ check_set_config_value(key, ENV_NAME_MAP_ATTR, value, to_syslog) || ++ check_set_config_value(key, ENV_NAME_ENTRY_ATTR, value, to_syslog) || ++ check_set_config_value(key, ENV_NAME_VALUE_ATTR, value, to_syslog) || ++ check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) || ++ check_set_config_value(key, ENV_MOUNT_WAIT, value, to_syslog) || ++ check_set_config_value(key, ENV_UMOUNT_WAIT, value, to_syslog) || ++ check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog) || ++ check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog) || ++ check_set_config_value(key, ENV_MOUNT_NFS_DEFAULT_PROTOCOL, value, to_syslog)) ++ ; ++ } ++ ++ if (!feof(f) || ferror(f)) { ++ if (!to_syslog) { ++ fprintf(stderr, ++ "fgets returned error %d while reading %s\n", ++ ferror(f), DEFAULTS_CONFIG_FILE); ++ } else { ++ logmsg("fgets returned error %d while reading %s", ++ ferror(f), DEFAULTS_CONFIG_FILE); ++ } ++ fclose(f); ++ return 0; ++ } ++ ++ fclose(f); ++ return 1; ++} ++ ++const char *defaults_get_master_map(void) ++{ ++ char *master; ++ ++ master = get_env_string(ENV_NAME_MASTER_MAP); ++ if (!master) ++ return strdup(default_master_map_name); ++ ++ return (const char *) master; ++} ++ ++int defaults_master_set(void) ++{ ++ char *val = getenv(ENV_NAME_MASTER_MAP); ++ if (!val) ++ return 0; ++ ++ return 1; ++} ++ ++unsigned int defaults_get_timeout(void) ++{ ++ long timeout; ++ ++ timeout = get_env_number(ENV_NAME_TIMEOUT); ++ if (timeout < 0) ++ timeout = DEFAULT_TIMEOUT; ++ ++ return (unsigned int) timeout; ++} ++ ++unsigned int defaults_get_negative_timeout(void) ++{ ++ long n_timeout; ++ ++ n_timeout = get_env_number(ENV_NAME_NEGATIVE_TIMEOUT); ++ if (n_timeout <= 0) ++ n_timeout = DEFAULT_NEGATIVE_TIMEOUT; ++ ++ return (unsigned int) n_timeout; ++} ++ ++unsigned int defaults_get_browse_mode(void) ++{ ++ int res; ++ ++ res = get_env_yesno(ENV_NAME_BROWSE_MODE); ++ if (res < 0) ++ res = DEFAULT_BROWSE_MODE; ++ ++ return res; ++} ++ ++unsigned int defaults_get_logging(void) ++{ ++ char *res; ++ unsigned int logging = DEFAULT_LOGGING; ++ ++ res = get_env_string(ENV_NAME_LOGGING); ++ if (!res) ++ return logging; ++ ++ if (!strcasecmp(res, "none")) ++ logging = DEFAULT_LOGGING; ++ else { ++ if (!strcasecmp(res, "verbose")) ++ logging |= LOGOPT_VERBOSE; ++ ++ if (!strcasecmp(res, "debug")) ++ logging |= LOGOPT_DEBUG; ++ } ++ ++ free(res); ++ ++ return logging; ++} ++ ++unsigned int defaults_get_ldap_timeout(void) ++{ ++ int res; ++ ++ res = get_env_number(ENV_LDAP_TIMEOUT); ++ if (res < 0) ++ res = DEFAULT_LDAP_TIMEOUT; ++ ++ return res; ++} ++ ++unsigned int defaults_get_ldap_network_timeout(void) ++{ ++ int res; ++ ++ res = get_env_number(ENV_LDAP_NETWORK_TIMEOUT); ++ if (res < 0) ++ res = DEFAULT_LDAP_NETWORK_TIMEOUT; ++ ++ return res; ++} + + unsigned int defaults_get_mount_nfs_default_proto(void) + { +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 3bc4dc5..431e50d 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -28,6 +28,7 @@ + #include + #include + #include ++#include + + #define MODULE_LOOKUP + #include "automount.h" diff --git a/SOURCES/autofs-5.0.7-make-description-of-default-MOUNT_WAIT-setting-clear.patch b/SOURCES/autofs-5.0.7-make-description-of-default-MOUNT_WAIT-setting-clear.patch new file mode 100644 index 0000000..a3dd3fb --- /dev/null +++ b/SOURCES/autofs-5.0.7-make-description-of-default-MOUNT_WAIT-setting-clear.patch @@ -0,0 +1,57 @@ +autofs-5.0.7 - make description of default MOUNT_WAIT setting clear + +From: Ian Kent + + +--- + + CHANGELOG | 1 + + redhat/autofs.sysconfig.in | 5 +++-- + samples/autofs.conf.default.in | 5 +++-- + 3 files changed, 7 insertions(+), 4 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 79cf673..961e340 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -8,6 +8,7 @@ + - dont wait forever to restart. + - add timeout option description to man page. + - fix null map entry order handling. ++- make description of default MOUNT_WAIT setting clear. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/redhat/autofs.sysconfig.in b/redhat/autofs.sysconfig.in +index 36b924d..a8992c4 100644 +--- a/redhat/autofs.sysconfig.in ++++ b/redhat/autofs.sysconfig.in +@@ -18,8 +18,9 @@ TIMEOUT=300 + # Setting this timeout can cause problems when + # mount would otherwise wait for a server that + # is temporarily unavailable, such as when it's +-# restarting. The defailt of waiting for mount(8) +-# usually results in a wait of around 3 minutes. ++# restarting. The default setting (-1) of waiting ++# for mount(8) usually results in a wait of around ++# 3 minutes. + # + #MOUNT_WAIT=-1 + # +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index ac2f63b..1da89cf 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -18,8 +18,9 @@ TIMEOUT=300 + # Setting this timeout can cause problems when + # mount would otherwise wait for a server that + # is temporarily unavailable, such as when it's +-# restarting. The defailt of waiting for mount(8) +-# usually results in a wait of around 3 minutes. ++# restarting. The default setting (-1) of waiting ++# for mount(8) usually results in a wait of around ++# 3 minutes. + # + #MOUNT_WAIT=-1 + # diff --git a/SOURCES/autofs-5.0.7-make-dump-maps-check-for-duplicate-indirect-mounts.patch b/SOURCES/autofs-5.0.7-make-dump-maps-check-for-duplicate-indirect-mounts.patch new file mode 100644 index 0000000..abadcb5 --- /dev/null +++ b/SOURCES/autofs-5.0.7-make-dump-maps-check-for-duplicate-indirect-mounts.patch @@ -0,0 +1,64 @@ +autofs-5.0.7 - make dump maps check for duplicate indirect mounts + +From: Ian Kent + +The dumpmaps function was intended for users to find out how the configured +mounts would be seen by automount. It does a limited amount of checking and +in particular doesn't report that duplicate indirect map sources will be +ignored at runtime. +--- + CHANGELOG | 1 + + lib/master.c | 7 +++++++ + 2 files changed, 8 insertions(+) + +diff --git a/CHANGELOG b/CHANGELOG +index 4106e7f..4576d47 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -40,6 +40,7 @@ + - fix some automount(8) typos. + - syncronize handle_mounts() shutdown. + - fix submount tree not all expiring. ++- make dump maps check for duplicate indirect mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/lib/master.c b/lib/master.c +index 64dbcb1..eca3523 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -1310,6 +1310,7 @@ int master_show_mounts(struct master *master) + struct master_mapent *this; + struct autofs_point *ap; + time_t now = time(NULL); ++ unsigned int count = 0; + int i; + + this = list_entry(p, struct master_mapent, list); +@@ -1318,6 +1319,7 @@ int master_show_mounts(struct master *master) + ap = this->ap; + + printf("\nMount point: %s\n", ap->path); ++ + printf("\nsource(s):\n"); + + /* +@@ -1360,6 +1362,9 @@ int master_show_mounts(struct master *master) + printf(" map: %s\n", source->argv[0]); + i = 1; + } ++ if (count && ap->type == LKP_INDIRECT) ++ printf(" duplicate indirect map entry" ++ " will be ignored at run time\n"); + if (source->argc > 1) { + printf(" arguments: "); + for (; i < source->argc; i++) +@@ -1379,6 +1384,8 @@ int master_show_mounts(struct master *master) + } while ((me = cache_lookup_next(source->mc, me))); + } + ++ count++; ++ + source = source->next; + } + diff --git a/SOURCES/autofs-5.0.7-make-yellow-pages-support-optional.patch b/SOURCES/autofs-5.0.7-make-yellow-pages-support-optional.patch new file mode 100644 index 0000000..4199690 --- /dev/null +++ b/SOURCES/autofs-5.0.7-make-yellow-pages-support-optional.patch @@ -0,0 +1,156 @@ +autofs-5.0.7 - make yellow pages support optional + +From: Chris Packham + +If rpcsvc/ypclnt.h is not available don't compile in Yellow Pages +support. +--- + + CHANGELOG | 1 + + Makefile.conf.in | 3 +++ + configure | 16 ++++++++++++++++ + configure.in | 9 +++++++++ + include/config.h.in | 3 +++ + lib/rpc_subs.c | 1 - + modules/Makefile | 9 +++++++-- + 7 files changed, 39 insertions(+), 3 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 1130db6..ed17163 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -25,6 +25,7 @@ + - don't schedule new alarms after readmap. + - use numeric protocol ids instead of protoent structs. + - lib/defaults.c: use WITH_LDAP conditional around LDAP types. ++- make yellow pages support optional. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/Makefile.conf.in b/Makefile.conf.in +index 802318b..3766d45 100644 +--- a/Makefile.conf.in ++++ b/Makefile.conf.in +@@ -43,6 +43,9 @@ NISPLUS = @HAVE_NISPLUS@ + # SMBFS support: yes (1) no (0) + SMBFS = @HAVE_SMBMOUNT@ + ++# YellowPages support: yes (1) no (0) ++YPCLNT = @HAVE_YPCLNT@ ++ + # Support for calling e2fsck when mounting ext2 filesystems + EXT2FS = @HAVE_E2FSCK@ + +diff --git a/configure b/configure +index 3722a46..cf6428c 100755 +--- a/configure ++++ b/configure +@@ -614,6 +614,7 @@ XML_FLAGS + LIBLDAP + HAVE_LDAP + LDAP_FLAGS ++HAVE_YPCLNT + HAVE_NISPLUS + EGREP + GREP +@@ -4575,6 +4576,21 @@ fi + + + ++# YellowPages support? ++HAVE_YPCLNT=0 ++ac_fn_c_check_header_mongrel "$LINENO" "rpcsvc/ypclnt.h" "ac_cv_header_rpcsvc_ypclnt_h" "$ac_includes_default" ++if test "x$ac_cv_header_rpcsvc_ypclnt_h" = xyes; then : ++ HAVE_YPCLNT=1 ++fi ++ ++ ++ ++if test "$HAVE_YPCLNT" = "1"; then ++ ++$as_echo "#define HAVE_YPCLNT 1" >>confdefs.h ++ ++fi ++ + # + # OpenLDAP support? Expect that this may have a special directory... + # +diff --git a/configure.in b/configure.in +index 90bda62..363c376 100644 +--- a/configure.in ++++ b/configure.in +@@ -213,6 +213,15 @@ HAVE_NISPLUS=0 + AC_CHECK_HEADER(rpcsvc/nis.h, HAVE_NISPLUS=1) + AC_SUBST(HAVE_NISPLUS) + ++# YellowPages support? ++HAVE_YPCLNT=0 ++AC_CHECK_HEADER([rpcsvc/ypclnt.h], HAVE_YPCLNT=1) ++AC_SUBST(HAVE_YPCLNT) ++if test "$HAVE_YPCLNT" = "1"; then ++ AC_DEFINE(HAVE_YPCLNT, 1, ++ [Define if using YellowPages]) ++fi ++ + # + # OpenLDAP support? Expect that this may have a special directory... + # +diff --git a/include/config.h.in b/include/config.h.in +index 9bdf98a..7f1c5b5 100644 +--- a/include/config.h.in ++++ b/include/config.h.in +@@ -72,6 +72,9 @@ + /* Define to 1 if you have the header file. */ + #undef HAVE_UNISTD_H + ++/* Define if using YellowPages */ ++#undef HAVE_YPCLNT ++ + /* Use libxml2 tsd usage workaround */ + #undef LIBXML2_WORKAROUND + +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index ad1d557..718caf9 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -27,7 +27,6 @@ + #include + #include + #include +-#include + #include + #include + #include +diff --git a/modules/Makefile b/modules/Makefile +index 939da7c..c5deb24 100644 +--- a/modules/Makefile ++++ b/modules/Makefile +@@ -5,13 +5,13 @@ + -include ../Makefile.conf + include ../Makefile.rules + +-SRCS := lookup_yp.c lookup_file.c lookup_program.c lookup_userhome.c \ ++SRCS := lookup_file.c lookup_program.c lookup_userhome.c \ + lookup_multi.c lookup_hosts.c lookup_dir.c \ + parse_sun.c \ + mount_generic.c mount_nfs.c mount_afs.c mount_autofs.c \ + mount_changer.c mount_bind.c + +-MODS := lookup_yp.so lookup_file.so lookup_program.so lookup_userhome.so \ ++MODS := lookup_file.so lookup_program.so lookup_userhome.so \ + lookup_multi.so lookup_hosts.so lookup_dir.so \ + parse_sun.so \ + mount_generic.so mount_nfs.so mount_afs.so mount_autofs.so \ +@@ -37,6 +37,11 @@ ifeq ($(NISPLUS), 1) + MODS += lookup_nisplus.so + endif + ++ifeq ($(YPCLNT), 1) ++ SRCS += lookup_yp.c ++ MODS += lookup_yp.so ++endif ++ + ifeq ($(LDAP), 1) + SRCS += lookup_ldap.c + MODS += lookup_ldap.so diff --git a/SOURCES/autofs-5.0.7-misc-man-page-fixes.patch b/SOURCES/autofs-5.0.7-misc-man-page-fixes.patch new file mode 100644 index 0000000..3e2e1a8 --- /dev/null +++ b/SOURCES/autofs-5.0.7-misc-man-page-fixes.patch @@ -0,0 +1,73 @@ +autofs-5.0.7 - misc man page fixes + +From: Ian Kent + +- add missing long option for for macro define in automount(8). +- fix a couple of grammar mistakes in autofs(8). +- add missing force option to help. +--- + CHANGELOG | 1 + + daemon/automount.c | 1 + + man/autofs.8.in | 4 ++-- + man/automount.8 | 2 +- + 4 files changed, 5 insertions(+), 3 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 0242c11..503a21e 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -51,6 +51,7 @@ + - probe each nfs version in turn for singleton mounts. + - add changlog entry for coverity fixes. + - fix probe each nfs version in turn for singleton mounts. ++- misc man page fixes. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/daemon/automount.c b/daemon/automount.c +index 3f9337f..019637f 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1734,6 +1734,7 @@ static void usage(void) + " set daemon log verbosity\n" + " -C --dont-check-daemon\n" + " don't check if daemon is already running\n" ++ " -F --force forceably clean up known automounts at start\n" + " -V --version print version, build config and exit\n" + , program); + } +diff --git a/man/autofs.8.in b/man/autofs.8.in +index ac0670d..fae0b00 100644 +--- a/man/autofs.8.in ++++ b/man/autofs.8.in +@@ -6,7 +6,7 @@ + .I start|stop|restart|reload|status + .SH "DESCRIPTION" + .B autofs +-control the operation of the ++controls the operation of the + .BR automount (8) + daemons running on the Linux system. Usually + .B autofs +@@ -16,7 +16,7 @@ parameter and at shutdown time with the + .I stop + parameter. The + .B autofs +-script can also manually be invoked by the system administrator to shut ++script can also be manually invoked by the system administrator to shut + down, restart or reload the automounters. + .P + .SH "OPERATION" +diff --git a/man/automount.8 b/man/automount.8 +index 7cc32c5..844b876 100644 +--- a/man/automount.8 ++++ b/man/automount.8 +@@ -45,7 +45,7 @@ autofs managed mounts. + Enables logging of general status and progress messages as well as + debugging messages for all autofs managed mounts. + .TP +-.I "\-Dvariable=value" ++.I "\-Dvariable=value, --define variable=value" + Define a global macro substitution variable. Global definitions + are over-ridden macro definitions of the same name specified in + mount entries. diff --git a/SOURCES/autofs-5.0.7-modules-replicated-use-sin6.addr-s6_addr32.patch b/SOURCES/autofs-5.0.7-modules-replicated-use-sin6.addr-s6_addr32.patch new file mode 100644 index 0000000..4516bc5 --- /dev/null +++ b/SOURCES/autofs-5.0.7-modules-replicated-use-sin6.addr-s6_addr32.patch @@ -0,0 +1,39 @@ +autofs-5.0.7 - modules/replicated.c: use sin6_addr.s6_addr32 + +From: Chris Packham + +The exported in6.h kernel header provides a convenience macro s6_addr32 +for accessing the 32bit words of an ipv6 address. Use this instead of +__in6_u.__u6_addr32. +--- + + CHANGELOG | 1 + + modules/replicated.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index ed17163..4eaa9f9 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -26,6 +26,7 @@ + - use numeric protocol ids instead of protoent structs. + - lib/defaults.c: use WITH_LDAP conditional around LDAP types. + - make yellow pages support optional. ++- modules/replicated.c: use sin6_addr.s6_addr32. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/modules/replicated.c b/modules/replicated.c +index dbd5513..26f64b8 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -1146,7 +1146,7 @@ try_name: + rr4++; + } else if (this->ai_family == AF_INET6) { + struct sockaddr_in6 *addr = (struct sockaddr_in6 *) this->ai_addr; +- if (!IN6_IS_ADDR_LOOPBACK(addr->sin6_addr.__in6_u.__u6_addr32)) ++ if (!IN6_IS_ADDR_LOOPBACK(addr->sin6_addr.s6_addr32)) + rr6++; + } + this = this->ai_next; diff --git a/SOURCES/autofs-5.0.7-only-probe-specific-nfs-version-when-requested.patch b/SOURCES/autofs-5.0.7-only-probe-specific-nfs-version-when-requested.patch new file mode 100644 index 0000000..e70830a --- /dev/null +++ b/SOURCES/autofs-5.0.7-only-probe-specific-nfs-version-when-requested.patch @@ -0,0 +1,40 @@ +autofs-5.0.7 - only probe specific nfs version when requested + +From: Ian Kent + +If a specific NFS version is given as an option the set the probe flags +to probe only that version. +--- + CHANGELOG | 1 + + modules/mount_nfs.c | 10 +++++++++- + 2 files changed, 10 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -63,6 +63,7 @@ + - teach dumpmaps to output simple key value pairs. + - fix get_nfs_info() probe. + - fix portmap lookup. ++- only probe specific nfs version if requested. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/mount_nfs.c ++++ autofs-5.0.7/modules/mount_nfs.c +@@ -146,7 +146,15 @@ int mount_mount(struct autofs_point *ap, + if (strncmp("vers=4", cp, o_len) == 0 || + strncmp("nfsvers=4", cp, o_len) == 0) + vers = NFS4_VERS_MASK | TCP_SUPPORTED; +- else if (strstr(cp, "port=") == cp && ++ else if (strncmp("vers=3", cp, o_len) == 0 || ++ strncmp("nfsvers=3", cp, o_len) == 0) { ++ vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK); ++ vers |= NFS3_REQUESTED; ++ } else if (strncmp("vers=2", cp, o_len) == 0 || ++ strncmp("nfsvers=2", cp, o_len) == 0) { ++ vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK); ++ vers |= NFS2_REQUESTED; ++ } else if (strstr(cp, "port=") == cp && + o_len - 5 < 25) { + char optport[25]; + diff --git a/SOURCES/autofs-5.0.7-probe-each-nfs-version-in-turn-for-singleton-mounts.patch b/SOURCES/autofs-5.0.7-probe-each-nfs-version-in-turn-for-singleton-mounts.patch new file mode 100644 index 0000000..9b86306 --- /dev/null +++ b/SOURCES/autofs-5.0.7-probe-each-nfs-version-in-turn-for-singleton-mounts.patch @@ -0,0 +1,104 @@ +autofs-5.0.7 - probe each nfs version in turn for singleton mounts + +From: Ian Kent + + +--- + CHANGELOG | 1 + + include/replicated.h | 2 ++ + modules/mount_nfs.c | 35 ++++++++++++++++++++++++++++++++++- + modules/replicated.c | 8 ++++---- + 4 files changed, 41 insertions(+), 5 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 39d7889..48e9806 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -48,6 +48,7 @@ + - fix master map mount options matching. + - fix master map bogus keywork match. + - fix fix map entry duplicate offset detection. ++- probe each nfs version in turn for singleton mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/include/replicated.h b/include/replicated.h +index ff0e7b9..728f131 100644 +--- a/include/replicated.h ++++ b/include/replicated.h +@@ -68,6 +68,8 @@ struct host { + }; + + void seed_random(void); ++struct host *new_host(const char *, struct sockaddr *, size_t, ++ unsigned int, unsigned int, unsigned int); + void free_host_list(struct host **); + int parse_location(unsigned, struct host **, const char *, unsigned int); + int prune_host_list(unsigned, struct host **, unsigned int, int); +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 5424d74..81ba3ca 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -180,9 +180,42 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int + * We can't probe protocol rdma so leave it to mount.nfs(8) + * and and suffer the delay if a server isn't available. + */ +- if (!rdma) ++ if (rdma) ++ goto dont_probe; ++ ++ /* ++ * If this is a singleton mount, and NFSv4 only hasn't been asked ++ * for, and the default NFS protocol is set to v4 in the autofs ++ * configuration only probe NFSv4 and let mount.nfs(8) do fallback ++ * to NFSv3 (if it can). If the NFSv4 probe fails then probe as ++ * normal. ++ */ ++ if (!hosts->next && ++ mount_default_proto == 4 && ++ vers & NFS_VERS_MASK != 0 && ++ vers & NFS4_VERS_MASK != 0) { ++ unsigned int v4_probe_ok = 0; ++ struct host *tmp = new_host(hosts->name, ++ hosts->addr, hosts->addr_len, ++ hosts->proximity, ++ hosts->weight, hosts->options); ++ if (tmp) { ++ tmp->rr = hosts->rr; ++ prune_host_list(ap->logopt, &tmp, ++ NFS4_VERS_MASK|TCP_SUPPORTED, port); ++ /* If probe succeeds just try the mount with host in hosts */ ++ if (tmp) { ++ v4_probe_ok = 1; ++ free_host_list(&tmp); ++ } ++ } ++ if (!v4_probe_ok) ++ prune_host_list(ap->logopt, &hosts, vers, port); ++ } else { + prune_host_list(ap->logopt, &hosts, vers, port); ++ } + ++dont_probe: + if (!hosts) { + info(ap->logopt, MODPREFIX "no hosts available"); + return 1; +diff --git a/modules/replicated.c b/modules/replicated.c +index 6dbdade..0a044b9 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -280,10 +280,10 @@ static unsigned int get_proximity(struct sockaddr *host_addr) + return PROXIMITY_OTHER; + } + +-static struct host *new_host(const char *name, +- struct sockaddr *addr, size_t addr_len, +- unsigned int proximity, unsigned int weight, +- unsigned int options) ++struct host *new_host(const char *name, ++ struct sockaddr *addr, size_t addr_len, ++ unsigned int proximity, unsigned int weight, ++ unsigned int options) + { + struct host *new; + struct sockaddr *tmp2; diff --git a/SOURCES/autofs-5.0.7-recheck-valid-map-entry-lookup-return-in-do_readmap_mount.patch b/SOURCES/autofs-5.0.7-recheck-valid-map-entry-lookup-return-in-do_readmap_mount.patch new file mode 100644 index 0000000..c0ab30a --- /dev/null +++ b/SOURCES/autofs-5.0.7-recheck-valid-map-entry-lookup-return-in-do_readmap_mount.patch @@ -0,0 +1,30 @@ +autofs-5.0.7 - recheck valid map entry lookup return in do_readmap_mount() + +From: Ian Kent + +After looking for an expected existing valid map entry in do_readmap_mount() +add a check in case it isn't found. + +If it actually isn't found (although it always should be) the only thing +that can be done is log an error return. +--- + daemon/state.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/daemon/state.c b/daemon/state.c +index 6e23022..ddc5556 100644 +--- a/daemon/state.c ++++ b/daemon/state.c +@@ -405,6 +405,12 @@ static void do_readmap_mount(struct autofs_point *ap, struct mnt_list *mnts, + me->key); + cache_writelock(vmc); + valid = cache_lookup_distinct(vmc, me->key); ++ if (!valid) { ++ cache_unlock(vmc); ++ error(ap->logopt, ++ "failed to find expected existing valid map entry"); ++ return; ++ } + /* Take over the mount if there is one */ + valid->ioctlfd = me->ioctlfd; + me->ioctlfd = -1; diff --git a/SOURCES/autofs-5.0.7-remove-debug-only-code-in-alarm-c.patch b/SOURCES/autofs-5.0.7-remove-debug-only-code-in-alarm-c.patch new file mode 100644 index 0000000..111e460 --- /dev/null +++ b/SOURCES/autofs-5.0.7-remove-debug-only-code-in-alarm-c.patch @@ -0,0 +1,36 @@ +autofs-5.0.7 - remove debug only code in alarm.c + +From: Ian Kent + +This code is only ever used for "on-the-fly" debugging so just remove it. +--- + lib/alarm.c | 16 ---------------- + 1 file changed, 16 deletions(-) + +diff --git a/lib/alarm.c b/lib/alarm.c +index d5cdc05..0f04ef8 100755 +--- a/lib/alarm.c ++++ b/lib/alarm.c +@@ -40,22 +40,6 @@ do { \ + fatal(_alm_unlock); \ + } while (0) + +-void dump_alarms(void) +-{ +- struct list_head *head; +- struct list_head *p; +- +- pthread_mutex_lock(&mutex); +- head = &alarms; +- list_for_each(p, head) { +- struct alarm *this; +- +- this = list_entry(p, struct alarm, list); +- logmsg("alarm time = %d", this->time); +- } +- pthread_mutex_unlock(&mutex); +-} +- + /* Insert alarm entry on ordered list. */ + int alarm_add(struct autofs_point *ap, time_t seconds) + { diff --git a/SOURCES/autofs-5.0.7-setup-program-map-env-from-macro-table.patch b/SOURCES/autofs-5.0.7-setup-program-map-env-from-macro-table.patch new file mode 100644 index 0000000..039bc9e --- /dev/null +++ b/SOURCES/autofs-5.0.7-setup-program-map-env-from-macro-table.patch @@ -0,0 +1,125 @@ +autofs-5.0.7 - setup program map env from macro table + +From: Ian Kent + +The ability to pass parameters to program maps, in some way, is needed. +Standard autofs specifies that program maps have one argument so passing +parameters as arguments shouldn't be done. + +This patch sets the existing macro table definitions (for both global and +local table) as environment variables before calling the map. The values +are not checked after return so, at this stage, program maps can't change +macro definitions. +--- + CHANGELOG | 1 + + include/macros.h | 1 + + lib/macros.c | 28 ++++++++++++++++++++++++++++ + modules/lookup_program.c | 20 ++++++++++++++++++++ + 4 files changed, 50 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -76,6 +76,7 @@ + - fix options compare. + - fix fix options compare. + - fix max() declaration. ++- setup program map env from macro table. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/macros.h ++++ autofs-5.0.7/include/macros.h +@@ -40,5 +40,6 @@ void macro_free_global_table(void); + void macro_free_table(struct substvar *table); + const struct substvar * + macro_findvar(const struct substvar *table, const char *str, int len); ++void macro_setenv(struct substvar *table); + + #endif +--- autofs-5.0.7.orig/lib/macros.c ++++ autofs-5.0.7/lib/macros.c +@@ -421,3 +421,31 @@ macro_findvar(const struct substvar *tab + return NULL; + } + ++/* Set environment from macro variable table */ ++void macro_setenv(struct substvar *table) ++{ ++ const struct substvar *sv = system_table; ++ const struct substvar *lv = table; ++ ++ /* ++ * First set environment from global table, matching local ++ * variables will overwrite these. ++ */ ++ while (sv) { ++ if (sv->def) ++ setenv(sv->def, sv->val, 1); ++ sv = sv->next; ++ } ++ ++ error(LOGOPT_ANY, "table %p", table); ++ dump_table(table); ++ ++ /* Next set environment from the local table */ ++ while (lv) { ++ if (lv->def) ++ setenv(lv->def, lv->val, 1); ++ lv = lv->next; ++ } ++ ++ return; ++} +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -36,9 +36,17 @@ + + struct lookup_context { + const char *mapname; ++ char *mapfmt; + struct parse_mod *parse; + }; + ++struct parse_context { ++ char *optstr; /* Mount options */ ++ char *macros; /* Map wide macro defines */ ++ struct substvar *subst; /* $-substitutions */ ++ int slashify_colons; /* Change colons to slashes? */ ++}; ++ + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + + int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) +@@ -79,6 +87,8 @@ int lookup_init(const char *mapfmt, int + if (!mapfmt) + mapfmt = MAPFMT_DEFAULT; + ++ ctxt->mapfmt = strdup(mapfmt); ++ + ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); + if (!ctxt->parse) { + logmsg(MODPREFIX "failed to open parse context"); +@@ -255,6 +265,14 @@ int lookup_mount(struct autofs_point *ap + warn(ap->logopt, + MODPREFIX "failed to set PWD to %s for map %s", + ap->path, ctxt->mapname); ++ /* ++ * MAPFMT_DEFAULT must be "sun" for ->parse_init() to have setup ++ * the macro table. ++ */ ++ if (ctxt->mapfmt && strcmp(ctxt->mapfmt, "MAPFMT_DEFAULT")) { ++ struct parse_context *pctxt = (struct parse_context *) ctxt->parse->context; ++ macro_setenv(pctxt->subst); ++ } + execl(ctxt->mapname, ctxt->mapname, name, NULL); + _exit(255); /* execl() failed */ + } +@@ -448,6 +466,8 @@ int lookup_done(void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; + int rv = close_parse(ctxt->parse); ++ if (ctxt->mapfmt) ++ free(ctxt->mapfmt); + free(ctxt); + return rv; + } diff --git a/SOURCES/autofs-5.0.7-syncronize-handle_mounts-shutdown.patch b/SOURCES/autofs-5.0.7-syncronize-handle_mounts-shutdown.patch new file mode 100644 index 0000000..25b40aa --- /dev/null +++ b/SOURCES/autofs-5.0.7-syncronize-handle_mounts-shutdown.patch @@ -0,0 +1,73 @@ +autofs-5.0.7 - syncronize handle_mounts() shutdown + +From: Ian Kent + +When re-reading the master map the signal handler thread receives +a SIGTERM signal from handle_mounts_cleanup() for map entries that +have been removed. This is done to allow joining with handle_mounts() +threads before shutting down to ensure clean up has been completed +before the thread terminates. + +But, if more than one map entry is removed, multiple threads may be +cleaned up during the handling of a single signal so there can be no +work to do when a subsequent signal is received. In this case the +signal handler thread interprets the additional SIGTERM signal as a +request to shutdown and exits. +--- + CHANGELOG | 1 + + daemon/automount.c | 9 +++++++-- + 2 files changed, 8 insertions(+), 2 deletions(-) + +diff --git a/CHANGELOG b/CHANGELOG +index 488ad1e..f1ec1e5 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -38,6 +38,7 @@ + - fix systemd unidir in spec file. + - document browse option in man page. + - fix some automount(8) typos. ++- syncronize handle_mounts() shutdown. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/daemon/automount.c b/daemon/automount.c +index 4c651cf..3f9337f 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -1285,7 +1285,8 @@ static int do_hup_signal(struct master *master, time_t age) + nfs_mount_uses_string_options = check_nfs_mount_version(&vers, &check); + + master_mutex_lock(); +- if (master->reading) { ++ /* Already doing a map read or shutdown or no mounts */ ++ if (master->reading || list_empty(&master->mounts)) { + status = pthread_mutex_unlock(&mrc.mutex); + if (status) + fatal(status); +@@ -1449,6 +1450,7 @@ static void handle_mounts_cleanup(void *arg) + char path[PATH_MAX + 1]; + char buf[MAX_ERR_BUF]; + unsigned int clean = 0, submount, logopt; ++ unsigned int pending = 0; + + ap = (struct autofs_point *) arg; + +@@ -1466,6 +1468,9 @@ static void handle_mounts_cleanup(void *arg) + list_del_init(&ap->mounts); + } + ++ /* Don't signal the handler if we have already done so */ ++ if (!list_empty(&master_list->completed)) ++ pending = 1; + master_remove_mapent(ap->entry); + master_source_unlock(ap->entry); + +@@ -1498,7 +1503,7 @@ static void handle_mounts_cleanup(void *arg) + * so it can join with any completed handle_mounts() threads and + * perform final cleanup. + */ +- if (!submount) ++ if (!submount && !pending) + pthread_kill(state_mach_thid, SIGTERM); + + master_mutex_unlock(); diff --git a/SOURCES/autofs-5.0.7-teach-dumpmaps-to-output-simple-key-value-pairs.patch b/SOURCES/autofs-5.0.7-teach-dumpmaps-to-output-simple-key-value-pairs.patch new file mode 100644 index 0000000..1693a70 --- /dev/null +++ b/SOURCES/autofs-5.0.7-teach-dumpmaps-to-output-simple-key-value-pairs.patch @@ -0,0 +1,366 @@ +autofs-5.0.7 - teach dumpmaps to output simple key value pairs + +From: Ian Kent + +The dumpmaps option doesn't allow maps to be output in +pairs suitable for use as a file map. + +This could be useful to save current maps as a backup for emergency +use. + +If the dumpmaps option is given and is followed by two parameters, +" " then simple pairs that would +be read in by a map read are printed to stdout if the given map type +and map name are found in the map configuration. + +If the map is an LDAP map and there is more than one map of same name +in different base dns only the first map encountered by autofs will +be listed. + +If the map type is an old style multi-map and any one of the map +names in the multi-map entry matches the given map name the entries +that would be used by autofs for the whole multi-map will be listed. +--- + CHANGELOG | 1 + daemon/automount.c | 56 ++++++++++++--- + include/master.h | 1 + lib/master.c | 187 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + man/automount.8 | 20 +++++ + 5 files changed, 250 insertions(+), 15 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -60,6 +60,7 @@ + - fix fix wildcard multi map regression. + - fix dumpmaps multi output. + - try and cleanup after dumpmaps. ++- teach dumpmaps to output simple key value pairs. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -1725,7 +1725,8 @@ static void usage(void) + " -f --foreground do not fork into background\n" + " -r --random-multimount-selection\n" + " use ramdom replicated server selection\n" +- " -m --dumpmaps dump automounter maps and exit\n" ++ " -m --dumpmaps [ ]\n" ++ " dump automounter maps and exit\n" + " -n --negative-timeout n\n" + " set the timeout for failed key lookups.\n" + " -O --global-options\n" +@@ -2125,22 +2126,33 @@ int main(int argc, char *argv[]) + program); + #endif + +- if (argc == 0) +- master_list = master_new(NULL, timeout, ghost); +- else +- master_list = master_new(argv[0], timeout, ghost); +- +- if (!master_list) { +- printf("%s: can't create master map %s", program, argv[0]); +- exit(1); +- } +- + if (dumpmaps) { + struct master_mapent *entry; + struct list_head *head, *p; + struct mapent_cache *nc; ++ const char *type = NULL; ++ const char *name = NULL; ++ const char *master = NULL; ++ ++ if (argc > 0) { ++ if (argc >= 2) { ++ type = argv[0]; ++ name = argv[1]; ++ } ++ if (argc == 3) ++ master = argv[2]; ++ } + +- open_log(); ++ if (master) ++ master_list = master_new(NULL, timeout, ghost); ++ else ++ master_list = master_new(master, timeout, ghost); ++ if (!master_list) { ++ printf("%s: can't create master map", program); ++ exit(1); ++ } ++ ++ log_to_stderr(); + + master_init_scan(); + +@@ -2153,7 +2165,15 @@ int main(int argc, char *argv[]) + master_list->nc = nc; + + lookup_nss_read_master(master_list, 0); +- master_show_mounts(master_list); ++ if (type) { ++ const char *map = basename(name); ++ if (!map) ++ printf("%s: invalid map name %s\n", ++ program, name); ++ else ++ dump_map(master_list, type, map); ++ } else ++ master_show_mounts(master_list); + + head = &master_list->mounts; + p = head->next; +@@ -2168,6 +2188,16 @@ int main(int argc, char *argv[]) + exit(0); + } + ++ if (argc == 0) ++ master_list = master_new(NULL, timeout, ghost); ++ else ++ master_list = master_new(argv[0], timeout, ghost); ++ ++ if (!master_list) { ++ printf("%s: can't create master map %s", program, argv[0]); ++ exit(1); ++ } ++ + become_daemon(foreground, daemon_check); + + if (pthread_attr_init(&th_attr)) { +--- autofs-5.0.7.orig/include/master.h ++++ autofs-5.0.7/include/master.h +@@ -112,6 +112,7 @@ int master_submount_list_empty(struct au + int master_notify_submount(struct autofs_point *, const char *path, enum states); + void master_notify_state_change(struct master *, int); + int master_mount_mounts(struct master *, time_t, int); ++int dump_map(struct master *, const char *, const char *); + int master_show_mounts(struct master *); + extern inline unsigned int master_get_logopt(void); + int master_list_empty(struct master *); +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -1329,6 +1329,193 @@ static void print_map_info(struct map_so + return; + } + ++static int match_type(const char *source, const char *type) ++{ ++ if (!strcmp(source, type)) ++ return 1; ++ /* Sources file and files are synonymous */ ++ if (!strncmp(source, type, 4) && (strlen(source) <= 5)) ++ return 1; ++ return 0; ++} ++ ++static char *get_map_name(const char *string) ++{ ++ char *name, *tmp; ++ char *start, *end, *base; ++ ++ tmp = strdup(string); ++ if (!tmp) { ++ printf("error: allocation failure: %s\n", strerror(errno)); ++ return NULL; ++ } ++ ++ base = basename(tmp); ++ end = strchr(base, ','); ++ if (end) ++ *end = '\0'; ++ start = strchr(tmp, '='); ++ if (start) ++ start++; ++ else { ++ char *colon = strrchr(base, ':'); ++ if (colon) ++ start = ++colon; ++ else ++ start = base; ++ } ++ ++ name = strdup(start); ++ if (!name) ++ printf("error: allocation failure: %s\n", strerror(errno)); ++ free(tmp); ++ ++ return name; ++} ++ ++static int match_name(struct map_source *source, const char *name) ++{ ++ int argc = source->argc; ++ int ret = 0; ++ int i; ++ ++ /* ++ * This can't work for old style "multi" type sources since ++ * there's no way to know from which map the cache entry came ++ * from and duplicate entries are ignored at map read time. ++ * All we can really do is list all the entries for the given ++ * multi map if one of its map names matches. ++ */ ++ for (i = 0; i < argc; i++) { ++ if (i == 0 || !strcmp(source->argv[i], "--")) { ++ if (i != 0) { ++ i++; ++ if (i >= argc) ++ break; ++ } ++ ++ if (source->argv[i] && *source->argv[i] != '-') { ++ char *map = get_map_name(source->argv[i]); ++ if (!map) ++ break; ++ if (!strcmp(map, name)) { ++ ret = 1; ++ free(map); ++ break; ++ } ++ free(map); ++ } ++ } ++ } ++ ++ return ret; ++} ++ ++int dump_map(struct master *master, const char *type, const char *name) ++{ ++ struct list_head *p, *head; ++ ++ if (list_empty(&master->mounts)) { ++ printf("no master map entries found\n"); ++ return 1; ++ } ++ ++ head = &master->mounts; ++ p = head->next; ++ while (p != head) { ++ struct map_source *source; ++ struct master_mapent *this; ++ struct autofs_point *ap; ++ time_t now = time(NULL); ++ ++ this = list_entry(p, struct master_mapent, list); ++ p = p->next; ++ ++ ap = this->ap; ++ ++ /* ++ * Ensure we actually read indirect map entries so we can ++ * list them. The map reads won't read any indirect map ++ * entries (other than those in a file map) unless the ++ * browse option is set. ++ */ ++ if (ap->type == LKP_INDIRECT) ++ ap->flags |= MOUNT_FLAG_GHOST; ++ ++ /* Read the map content into the cache */ ++ if (lookup_nss_read_map(ap, NULL, now)) ++ lookup_prune_cache(ap, now); ++ else { ++ printf("failed to read map\n"); ++ lookup_close_lookup(ap); ++ continue; ++ } ++ ++ if (!this->maps) { ++ printf("no map sources found for %s\n", ap->path); ++ lookup_close_lookup(ap); ++ continue; ++ } ++ ++ source = this->maps; ++ while (source) { ++ struct map_source *instance; ++ struct mapent *me; ++ ++ instance = NULL; ++ if (source->type) { ++ if (!match_type(source->type, type)) { ++ source = source->next; ++ continue; ++ } ++ if (!match_name(source, name)) { ++ source = source->next; ++ continue; ++ } ++ instance = source; ++ } else { ++ struct map_source *map; ++ ++ map = source->instance; ++ while (map) { ++ if (!match_type(map->type, type)) { ++ map = map->next; ++ continue; ++ } ++ if (!match_name(map, name)) { ++ map = map->next; ++ continue; ++ } ++ instance = map; ++ break; ++ } ++ } ++ ++ if (!instance) { ++ source = source->next; ++ lookup_close_lookup(ap); ++ continue; ++ } ++ ++ me = cache_lookup_first(source->mc); ++ if (!me) ++ printf("no keys found in map\n"); ++ else { ++ do { ++ if (me->source == instance) ++ printf("%s\t%s\n", me->key, me->mapent); ++ } while ((me = cache_lookup_next(source->mc, me))); ++ } ++ ++ lookup_close_lookup(ap); ++ return 1; ++ } ++ lookup_close_lookup(ap); ++ } ++ ++ return 0; ++} ++ + int master_show_mounts(struct master *master) + { + struct list_head *p, *head; +--- autofs-5.0.7.orig/man/automount.8 ++++ autofs-5.0.7/man/automount.8 +@@ -57,8 +57,24 @@ Run the daemon in the foreground and log + Enables the use of ramdom selection when choosing a host from a + list of replicated servers. + .TP +-.I "\-m, \-\-dumpmaps" +-Dump configured automounter maps, then exit. ++.I "\-m, \-\-dumpmaps [ ]" ++With no parameters, list information about the configured automounter ++maps, then exit. ++ ++If the dumpmaps option is given and is followed by two parameters, ++" " then simple "" pairs that would ++be read in by a map read are printed to stdout if the given map type ++and map name are found in the map configuration. ++ ++If the map is an LDAP map and there is more than one map of same name ++in different base dns only the first map encountered by autofs will ++be listed. Similarly, if the map is a file map and there is more than ++one map of the same name in different directories, only the first map ++encountered will be listed. ++ ++If the map type is an old style multi-map and any one of the map ++names in the multi-map entry matches the given map name the entries ++that would be used by autofs for the whole multi-map will be listed. + .TP + .I "\-O, \-\-global-options" + Allows the specification of global mount options used for all master diff --git a/SOURCES/autofs-5.0.7-try-and-cleanup-after-dumpmaps.patch b/SOURCES/autofs-5.0.7-try-and-cleanup-after-dumpmaps.patch new file mode 100644 index 0000000..d626d21 --- /dev/null +++ b/SOURCES/autofs-5.0.7-try-and-cleanup-after-dumpmaps.patch @@ -0,0 +1,63 @@ +autofs-5.0.7 - try and cleanup after dumpmaps + +From: Ian Kent + +Try and cleanup a little after dumping maps. +It's not really necessary but but can help by reducing the noise +from valgrind when checking code. +--- + CHANGELOG | 1 + + daemon/automount.c | 13 +++++++++++++ + lib/master.c | 2 ++ + 3 files changed, 16 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -59,6 +59,7 @@ + - fix syncronize handle_mounts() shutdown. + - fix fix wildcard multi map regression. + - fix dumpmaps multi output. ++- try and cleanup after dumpmaps. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -2136,6 +2136,8 @@ int main(int argc, char *argv[]) + } + + if (dumpmaps) { ++ struct master_mapent *entry; ++ struct list_head *head, *p; + struct mapent_cache *nc; + + open_log(); +@@ -2152,6 +2154,17 @@ int main(int argc, char *argv[]) + + lookup_nss_read_master(master_list, 0); + master_show_mounts(master_list); ++ ++ head = &master_list->mounts; ++ p = head->next; ++ while (p != head) { ++ entry = list_entry(p, struct master_mapent, list); ++ p = p->next; ++ master_free_mapent_sources(entry, 1); ++ master_free_mapent(entry); ++ } ++ master_kill(master_list); ++ + exit(0); + } + +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -1426,6 +1426,8 @@ int master_show_mounts(struct master *ma + source = source->next; + } + ++ lookup_close_lookup(ap); ++ + printf("\n"); + } + diff --git a/SOURCES/autofs-5.0.7-update-kernel-include-files.patch b/SOURCES/autofs-5.0.7-update-kernel-include-files.patch new file mode 100644 index 0000000..3b6bb92 --- /dev/null +++ b/SOURCES/autofs-5.0.7-update-kernel-include-files.patch @@ -0,0 +1,92 @@ +autofs-5.0.7 - update kernel include files + +From: Ian Kent + +Update autofs include files to include the latest changes. +--- + include/linux/auto_fs.h | 33 ++++++++++----------------------- + include/linux/auto_fs4.h | 3 ++- + 2 files changed, 12 insertions(+), 24 deletions(-) + +diff --git a/include/linux/auto_fs.h b/include/linux/auto_fs.h +index 91d414f..64df1a6 100644 +--- a/include/linux/auto_fs.h ++++ b/include/linux/auto_fs.h +@@ -14,13 +14,8 @@ + #ifndef _LINUX_AUTO_FS_H + #define _LINUX_AUTO_FS_H + +-#ifdef __KERNEL__ +-#include +-#include + #include +-#include +-#else +-#include ++#ifndef __KERNEL__ + #include + #endif /* __KERNEL__ */ + +@@ -32,25 +27,16 @@ + #define AUTOFS_MIN_PROTO_VERSION AUTOFS_PROTO_VERSION + + /* +- * Architectures where both 32- and 64-bit binaries can be executed +- * on 64-bit kernels need this. This keeps the structure format +- * uniform, and makes sure the wait_queue_token isn't too big to be +- * passed back down to the kernel. +- * +- * This assumes that on these architectures: +- * mode 32 bit 64 bit +- * ------------------------- +- * int 32 bit 32 bit +- * long 32 bit 64 bit +- * +- * If so, 32-bit user-space code should be backwards compatible. ++ * The wait_queue_token (autofs_wqt_t) is part of a structure which is passed ++ * back to the kernel via ioctl from userspace. On architectures where 32- and ++ * 64-bit userspace binaries can be executed it's important that the size of ++ * autofs_wqt_t stays constant between 32- and 64-bit Linux kernels so that we ++ * do not break the binary ABI interface by changing the structure size. + */ +- +-#if defined(__sparc__) || defined(__mips__) || defined(__x86_64__) \ +- || defined(__powerpc__) || defined(__s390__) +-typedef unsigned int autofs_wqt_t; +-#else ++#if defined(__ia64__) || defined(__alpha__) /* pure 64bit architectures */ + typedef unsigned long autofs_wqt_t; ++#else ++typedef unsigned int autofs_wqt_t; + #endif + + /* Packet types */ +@@ -81,6 +67,7 @@ struct autofs_packet_expire { + #define AUTOFS_IOC_FAIL _IO(0x93,0x61) + #define AUTOFS_IOC_CATATONIC _IO(0x93,0x62) + #define AUTOFS_IOC_PROTOVER _IOR(0x93,0x63,int) ++#define AUTOFS_IOC_SETTIMEOUT32 _IOWR(0x93,0x64,compat_ulong_t) + #define AUTOFS_IOC_SETTIMEOUT _IOWR(0x93,0x64,unsigned long) + #define AUTOFS_IOC_EXPIRE _IOR(0x93,0x65,struct autofs_packet_expire) + +diff --git a/include/linux/auto_fs4.h b/include/linux/auto_fs4.h +index 55fa478..e02982f 100644 +--- a/include/linux/auto_fs4.h ++++ b/include/linux/auto_fs4.h +@@ -12,6 +12,7 @@ + #define _LINUX_AUTO_FS4_H + + /* Include common v3 definitions */ ++#include + #include + + /* autofs v4 definitions */ +@@ -23,7 +24,7 @@ + #define AUTOFS_MIN_PROTO_VERSION 3 + #define AUTOFS_MAX_PROTO_VERSION 5 + +-#define AUTOFS_PROTO_SUBVERSION 1 ++#define AUTOFS_PROTO_SUBVERSION 2 + + /* Mask for expire behaviour */ + #define AUTOFS_EXP_IMMEDIATE 1 diff --git a/SOURCES/autofs-5.0.7-use-numeric-protocol-ids-instead-of-protoent-structs.patch b/SOURCES/autofs-5.0.7-use-numeric-protocol-ids-instead-of-protoent-structs.patch new file mode 100644 index 0000000..113b0a0 --- /dev/null +++ b/SOURCES/autofs-5.0.7-use-numeric-protocol-ids-instead-of-protoent-structs.patch @@ -0,0 +1,471 @@ +autofs-5.0.7 - use numeric protocol ids instead of protoent structs + +From: Leonardo Chiquitto + +The function getprotobyname() is not reentrant, so we can't call +it simultaneously from multiple threads. Instead of switching to +the reentrant version which adds more complexity to the code, +lets use numeric protocol IDs instead of protoent structures. +--- + + CHANGELOG | 1 + + include/rpc_subs.h | 4 +-- + lib/rpc_subs.c | 80 ++++++++++++++++++-------------------------------- + modules/replicated.c | 42 +++++++++++--------------- + 4 files changed, 50 insertions(+), 77 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 4cf5621..ba1d65b 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -23,6 +23,7 @@ + - fix use get_proximity() without libtirpc. + - don't use dirent d_type to filter out files in scandir() + - don't schedule new alarms after readmap. ++- use numeric protocol ids instead of protoent structs. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/include/rpc_subs.h b/include/rpc_subs.h +index ca474d9..b6d59f9 100644 +--- a/include/rpc_subs.h ++++ b/include/rpc_subs.h +@@ -54,7 +54,7 @@ struct conn_info { + unsigned short port; + unsigned long program; + unsigned long version; +- struct protoent *proto; ++ int proto; + unsigned int send_sz; + unsigned int recv_sz; + struct timeval timeout; +@@ -66,7 +66,7 @@ int rpc_udp_getclient(struct conn_info *, unsigned int, unsigned int); + void rpc_destroy_udp_client(struct conn_info *); + int rpc_tcp_getclient(struct conn_info *, unsigned int, unsigned int); + void rpc_destroy_tcp_client(struct conn_info *); +-int rpc_portmap_getclient(struct conn_info *, const char *, struct sockaddr *, size_t, const char *, unsigned int); ++int rpc_portmap_getclient(struct conn_info *, const char *, struct sockaddr *, size_t, int, unsigned int); + 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); +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index d33a3c4..ad1d557 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -170,7 +170,7 @@ static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, i + + *client = NULL; + +- proto = info->proto->p_proto; ++ proto = info->proto; + if (proto == IPPROTO_UDP) + type = SOCK_DGRAM; + else +@@ -201,7 +201,7 @@ static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, i + in4_raddr = (struct sockaddr_in *) addr; + in4_raddr->sin_port = htons(info->port); + +- switch (info->proto->p_proto) { ++ switch (info->proto) { + case IPPROTO_UDP: + clnt = clntudp_bufcreate(in4_raddr, + info->program, info->version, +@@ -241,7 +241,7 @@ static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, i + + *client = NULL; + +- proto = info->proto->p_proto; ++ proto = info->proto; + if (proto == IPPROTO_UDP) + type = SOCK_DGRAM; + else +@@ -292,11 +292,11 @@ static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, i + nb_addr.maxlen = nb_addr.len = slen; + nb_addr.buf = addr; + +- if (info->proto->p_proto == IPPROTO_UDP) ++ if (info->proto == IPPROTO_UDP) + clnt = clnt_dg_create(*fd, &nb_addr, + info->program, info->version, + info->send_sz, info->recv_sz); +- else if (info->proto->p_proto == IPPROTO_TCP) { ++ else if (info->proto == IPPROTO_TCP) { + ret = connect_nb(*fd, addr, slen, &info->timeout); + if (ret < 0) + return ret; +@@ -355,7 +355,7 @@ static int create_client(struct conn_info *info, CLIENT **client) + memset(&hints, 0, sizeof(hints)); + hints.ai_flags = AI_ADDRCONFIG; + hints.ai_family = AF_UNSPEC; +- if (info->proto->p_proto == IPPROTO_UDP) ++ if (info->proto == IPPROTO_UDP) + hints.ai_socktype = SOCK_DGRAM; + else + hints.ai_socktype = SOCK_STREAM; +@@ -370,7 +370,7 @@ static int create_client(struct conn_info *info, CLIENT **client) + + haddr = ai; + while (haddr) { +- if (haddr->ai_protocol != info->proto->p_proto) { ++ if (haddr->ai_protocol != info->proto) { + haddr = haddr->ai_next; + continue; + } +@@ -417,16 +417,11 @@ out_close: + int rpc_udp_getclient(struct conn_info *info, + unsigned int program, unsigned int version) + { +- struct protoent *pe_proto; + CLIENT *client; + int ret; + + if (!info->client) { +- pe_proto = getprotobyname("udp"); +- if (!pe_proto) +- return -ENOENT; +- +- info->proto = pe_proto; ++ info->proto = IPPROTO_UDP; + info->timeout.tv_sec = RPC_TOUT_UDP; + info->timeout.tv_usec = 0; + info->send_sz = UDPMSGSIZE; +@@ -458,16 +453,11 @@ void rpc_destroy_udp_client(struct conn_info *info) + int rpc_tcp_getclient(struct conn_info *info, + unsigned int program, unsigned int version) + { +- struct protoent *pe_proto; + CLIENT *client; + int ret; + + if (!info->client) { +- pe_proto = getprotobyname("tcp"); +- if (!pe_proto) +- return -ENOENT; +- +- info->proto = pe_proto; ++ info->proto = IPPROTO_TCP; + info->timeout.tv_sec = RPC_TOUT_TCP; + info->timeout.tv_usec = 0; + info->send_sz = 0; +@@ -513,23 +503,18 @@ void rpc_destroy_tcp_client(struct conn_info *info) + + int rpc_portmap_getclient(struct conn_info *info, + const char *host, struct sockaddr *addr, size_t addr_len, +- const char *proto, unsigned int option) ++ int proto, unsigned int option) + { +- struct protoent *pe_proto; + CLIENT *client; + int ret; + +- pe_proto = getprotobyname(proto); +- if (!pe_proto) +- return -ENOENT; +- + info->host = host; + info->addr = addr; + info->addr_len = addr_len; + info->program = PMAPPROG; + info->port = PMAPPORT; + info->version = PMAPVERS; +- info->proto = pe_proto; ++ info->proto = proto; + info->send_sz = RPCSMALLMSGSIZE; + info->recv_sz = RPCSMALLMSGSIZE; + info->timeout.tv_sec = PMAP_TOUT_UDP; +@@ -537,7 +522,7 @@ int rpc_portmap_getclient(struct conn_info *info, + info->close_option = option; + info->client = NULL; + +- if (pe_proto->p_proto == IPPROTO_TCP) ++ if (info->proto == IPPROTO_TCP) + info->timeout.tv_sec = PMAP_TOUT_TCP; + + ret = create_client(info, &client); +@@ -555,7 +540,7 @@ int rpc_portmap_getport(struct conn_info *info, + struct conn_info pmap_info; + CLIENT *client; + enum clnt_stat status; +- int proto = info->proto->p_proto; ++ int proto = info->proto; + int ret; + + memset(&pmap_info, 0, sizeof(struct conn_info)); +@@ -633,13 +618,13 @@ int rpc_ping_proto(struct conn_info *info) + { + CLIENT *client; + enum clnt_stat status; +- int proto = info->proto->p_proto; ++ int proto = info->proto; + int ret; + + if (info->client) + client = info->client; + else { +- if (info->proto->p_proto == IPPROTO_UDP) { ++ if (info->proto == IPPROTO_UDP) { + info->send_sz = UDPMSGSIZE; + info->recv_sz = UDPMSGSIZE; + } +@@ -688,7 +673,7 @@ int rpc_ping_proto(struct conn_info *info) + + static unsigned int __rpc_ping(const char *host, + unsigned long version, +- char *proto, ++ int proto, + long seconds, long micros, + unsigned int option) + { +@@ -696,6 +681,7 @@ static unsigned int __rpc_ping(const char *host, + struct conn_info info; + struct pmap parms; + ++ info.proto = proto; + info.host = host; + info.addr = NULL; + info.addr_len = 0; +@@ -710,13 +696,9 @@ static unsigned int __rpc_ping(const char *host, + + status = RPC_PING_FAIL; + +- info.proto = getprotobyname(proto); +- if (!info.proto) +- return status; +- + parms.pm_prog = NFS_PROGRAM; + parms.pm_vers = version; +- parms.pm_prot = info.proto->p_proto; ++ parms.pm_prot = info.proto; + parms.pm_port = 0; + + status = rpc_portmap_getport(&info, &parms, &info.port); +@@ -734,19 +716,19 @@ int rpc_ping(const char *host, long seconds, long micros, unsigned int option) + unsigned long vers2 = NFS2_VERSION; + unsigned int status; + +- status = __rpc_ping(host, vers2, "udp", seconds, micros, option); ++ status = __rpc_ping(host, vers2, IPPROTO_UDP, seconds, micros, option); + if (status > 0) + return RPC_PING_V2 | RPC_PING_UDP; + +- status = __rpc_ping(host, vers3, "udp", seconds, micros, option); ++ status = __rpc_ping(host, vers3, IPPROTO_UDP, seconds, micros, option); + if (status > 0) + return RPC_PING_V3 | RPC_PING_UDP; + +- status = __rpc_ping(host, vers2, "tcp", seconds, micros, option); ++ status = __rpc_ping(host, vers2, IPPROTO_TCP, seconds, micros, option); + if (status > 0) + return RPC_PING_V2 | RPC_PING_TCP; + +- status = __rpc_ping(host, vers3, "tcp", seconds, micros, option); ++ status = __rpc_ping(host, vers3, IPPROTO_TCP, seconds, micros, option); + if (status > 0) + return RPC_PING_V3 | RPC_PING_TCP; + +@@ -769,7 +751,7 @@ int rpc_time(const char *host, + double taken; + struct timeval start, end; + struct timezone tz; +- char *proto = (ping_proto & RPC_PING_UDP) ? "udp" : "tcp"; ++ int proto = (ping_proto & RPC_PING_UDP) ? IPPROTO_UDP : IPPROTO_TCP; + unsigned long vers = ping_vers; + + gettimeofday(&start, &tz); +@@ -791,12 +773,12 @@ static int rpc_get_exports_proto(struct conn_info *info, exports *exp) + { + CLIENT *client; + enum clnt_stat status; +- int proto = info->proto->p_proto; ++ int proto = info->proto; + unsigned int option = info->close_option; + int vers_entry; + int ret; + +- if (info->proto->p_proto == IPPROTO_UDP) { ++ if (info->proto == IPPROTO_UDP) { + info->send_sz = UDPMSGSIZE; + info->recv_sz = UDPMSGSIZE; + } +@@ -903,11 +885,9 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in + parms.pm_port = 0; + + /* Try UDP first */ +- info.proto = getprotobyname("udp"); +- if (!info.proto) +- goto try_tcp; ++ info.proto = IPPROTO_UDP; + +- parms.pm_prot = info.proto->p_proto; ++ parms.pm_prot = info.proto; + + status = rpc_portmap_getport(&info, &parms, &info.port); + if (status < 0) +@@ -920,11 +900,9 @@ exports rpc_get_exports(const char *host, long seconds, long micros, unsigned in + return exportlist; + + try_tcp: +- info.proto = getprotobyname("tcp"); +- if (!info.proto) +- return NULL; ++ info.proto = IPPROTO_TCP; + +- parms.pm_prot = info.proto->p_proto; ++ parms.pm_prot = info.proto; + + status = rpc_portmap_getport(&info, &parms, &info.port); + if (status < 0) +diff --git a/modules/replicated.c b/modules/replicated.c +index 6b96320..dbd5513 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -419,7 +419,7 @@ void free_host_list(struct host **list) + + static unsigned int get_nfs_info(unsigned logopt, struct host *host, + struct conn_info *pm_info, struct conn_info *rpc_info, +- const char *proto, unsigned int version, int port) ++ int proto, unsigned int version, int port) + { + unsigned int random_selection = host->options & MOUNT_FLAG_RANDOM_SELECT; + unsigned int use_weight_only = host->options & MOUNT_FLAG_USE_WEIGHT_ONLY; +@@ -433,22 +433,18 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, + int status, count = 0; + + if (host->addr) +- debug(logopt, "called with host %s(%s) proto %s version 0x%x", ++ debug(logopt, "called with host %s(%s) proto %d version 0x%x", + host->name, get_addr_string(host->addr, buf, len), + proto, version); + else + debug(logopt, +- "called for host %s proto %s version 0x%x", ++ "called for host %s proto %d version 0x%x", + host->name, proto, version); + +- rpc_info->proto = getprotobyname(proto); +- if (!rpc_info->proto) +- return 0; +- ++ rpc_info->proto = proto; + memset(&parms, 0, sizeof(struct pmap)); +- + parms.pm_prog = NFS_PROGRAM; +- parms.pm_prot = rpc_info->proto->p_proto; ++ parms.pm_prot = proto; + + if (!(version & NFS4_REQUESTED)) + goto v3_ver; +@@ -479,7 +475,7 @@ static unsigned int get_nfs_info(unsigned logopt, struct host *host, + } + } + +- if (rpc_info->proto->p_proto == IPPROTO_UDP) ++ if (rpc_info->proto == IPPROTO_UDP) + status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS4_VERSION); + else + status = rpc_tcp_getclient(rpc_info, NFS_PROGRAM, NFS4_VERSION); +@@ -540,7 +536,7 @@ v3_ver: + goto v2_ver; + } + +- if (rpc_info->proto->p_proto == IPPROTO_UDP) ++ if (rpc_info->proto == IPPROTO_UDP) + status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS3_VERSION); + else + status = rpc_tcp_getclient(rpc_info, NFS_PROGRAM, NFS3_VERSION); +@@ -587,7 +583,7 @@ v2_ver: + goto done_ver; + } + +- if (rpc_info->proto->p_proto == IPPROTO_UDP) ++ if (rpc_info->proto == IPPROTO_UDP) + status = rpc_udp_getclient(rpc_info, NFS_PROGRAM, NFS2_VERSION); + else + status = rpc_tcp_getclient(rpc_info, NFS_PROGRAM, NFS2_VERSION); +@@ -618,7 +614,7 @@ v2_ver: + } + + done_ver: +- if (rpc_info->proto->p_proto == IPPROTO_UDP) { ++ if (rpc_info->proto == IPPROTO_UDP) { + rpc_destroy_udp_client(rpc_info); + rpc_destroy_udp_client(pm_info); + } else { +@@ -675,7 +671,7 @@ static int get_vers_and_cost(unsigned logopt, struct host *host, + + if (version & TCP_REQUESTED) { + supported = get_nfs_info(logopt, host, +- &pm_info, &rpc_info, "tcp", vers, port); ++ &pm_info, &rpc_info, IPPROTO_TCP, vers, port); + if (IS_ERR(supported)) { + if (ERR(supported) == EHOSTUNREACH || + ERR(supported) == ETIMEDOUT) +@@ -688,7 +684,7 @@ static int get_vers_and_cost(unsigned logopt, struct host *host, + + if (version & UDP_REQUESTED) { + supported = get_nfs_info(logopt, host, +- &pm_info, &rpc_info, "udp", vers, port); ++ &pm_info, &rpc_info, IPPROTO_UDP, vers, port); + if (IS_ERR(supported)) { + if (!ret && ERR(supported) == ETIMEDOUT) + return ret; +@@ -709,7 +705,7 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, + socklen_t len = INET6_ADDRSTRLEN; + char buf[len + 1]; + struct conn_info pm_info, rpc_info; +- const char *proto; ++ int proto; + unsigned int vers; + struct timeval start, end; + struct timezone tz; +@@ -748,10 +744,10 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, + * So, we do the conversion here. + */ + if (version & UDP_SELECTED_MASK) { +- proto = "udp"; ++ proto = IPPROTO_UDP; + version >>= 8; + } else +- proto = "tcp"; ++ proto = IPPROTO_TCP; + + switch (version) { + case NFS2_SUPPORTED: +@@ -768,9 +764,7 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, + return 0; + } + +- rpc_info.proto = getprotobyname(proto); +- if (!rpc_info.proto) +- return 0; ++ rpc_info.proto = proto; + + if (port > 0) + rpc_info.port = port; +@@ -786,14 +780,14 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, + + memset(&parms, 0, sizeof(struct pmap)); + parms.pm_prog = NFS_PROGRAM; +- parms.pm_prot = rpc_info.proto->p_proto; ++ parms.pm_prot = rpc_info.proto; + parms.pm_vers = vers; + ret = rpc_portmap_getport(&pm_info, &parms, &rpc_info.port); + if (ret < 0) + goto done; + } + +- if (rpc_info.proto->p_proto == IPPROTO_UDP) ++ if (rpc_info.proto == IPPROTO_UDP) + status = rpc_udp_getclient(&rpc_info, NFS_PROGRAM, vers); + else + status = rpc_tcp_getclient(&rpc_info, NFS_PROGRAM, vers); +@@ -815,7 +809,7 @@ static int get_supported_ver_and_cost(unsigned logopt, struct host *host, + } + } + done: +- if (rpc_info.proto->p_proto == IPPROTO_UDP) { ++ if (rpc_info.proto == IPPROTO_UDP) { + rpc_destroy_udp_client(&rpc_info); + rpc_destroy_udp_client(&pm_info); + } else { diff --git a/SOURCES/autofs-5.0.7-use-ulimit-max-open-files-if-greater-than-internal-maximum.patch b/SOURCES/autofs-5.0.7-use-ulimit-max-open-files-if-greater-than-internal-maximum.patch new file mode 100644 index 0000000..6574597 --- /dev/null +++ b/SOURCES/autofs-5.0.7-use-ulimit-max-open-files-if-greater-than-internal-maximum.patch @@ -0,0 +1,30 @@ +autofs-5.0.7 - use ulimit max open files if greater than internal maximum + +From: Ian Kent + +When setting the maximum number of allowed file handles the current setting +should be checked before setting it. If the ulimit command has been used to +increase the maximum to larger than what automount would ask for then honour +it. +--- + daemon/automount.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/daemon/automount.c b/daemon/automount.c +index 019637f..1d0b64e 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -2106,8 +2106,11 @@ int main(int argc, char *argv[]) + exit(1); + } + +- rlim.rlim_cur = MAX_OPEN_FILES; +- rlim.rlim_max = MAX_OPEN_FILES; ++ res = getrlimit(RLIMIT_NOFILE, &rlim); ++ if (res == -1 || rlim.rlim_max <= MAX_OPEN_FILES) { ++ rlim.rlim_cur = MAX_OPEN_FILES; ++ rlim.rlim_max = MAX_OPEN_FILES; ++ } + res = setrlimit(RLIMIT_NOFILE, &rlim); + if (res) + printf("%s: can't increase open file limit - continuing", diff --git a/SOURCES/autofs-5.0.7-workaround-missing-GNU-versionsort-extension.patch b/SOURCES/autofs-5.0.7-workaround-missing-GNU-versionsort-extension.patch new file mode 100644 index 0000000..6a1a49e --- /dev/null +++ b/SOURCES/autofs-5.0.7-workaround-missing-GNU-versionsort-extension.patch @@ -0,0 +1,149 @@ +autofs-5.0.7 - workaround missing GNU versionsort extension + +From: Chris Packham + +alphasort() and scandir() are specified in POSIX.1-2008, versionsort() +is a GNU extension. When versionsort isn't available fallback to using +alphasort. +--- + + CHANGELOG | 1 + + configure | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++ + configure.in | 6 +++++ + include/config.h.in | 3 ++ + modules/lookup_dir.c | 5 ++++ + 5 files changed, 77 insertions(+), 0 deletions(-) + + +diff --git a/CHANGELOG b/CHANGELOG +index 4eaa9f9..39388a5 100644 +--- a/CHANGELOG ++++ b/CHANGELOG +@@ -27,6 +27,7 @@ + - lib/defaults.c: use WITH_LDAP conditional around LDAP types. + - make yellow pages support optional. + - modules/replicated.c: use sin6_addr.s6_addr32. ++- workaround missing GNU versionsort extension. + + 25/07/2012 autofs-5.0.7 + ======================= +diff --git a/configure b/configure +index cf6428c..c1423d8 100755 +--- a/configure ++++ b/configure +@@ -4010,6 +4010,68 @@ $as_echo "yes" >&6; } + KRB5_FLAGS=`$KRB5_CONFIG --cflags` + fi + ++{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing versionsort" >&5 ++$as_echo_n "checking for library containing versionsort... " >&6; } ++if ${ac_cv_search_versionsort+:} false; then : ++ $as_echo_n "(cached) " >&6 ++else ++ ac_func_search_save_LIBS=$LIBS ++cat confdefs.h - <<_ACEOF >conftest.$ac_ext ++/* end confdefs.h. */ ++ ++/* Override any GCC internal prototype to avoid an error. ++ Use char because int might match the return type of a GCC ++ builtin and then its argument prototype would still apply. */ ++#ifdef __cplusplus ++extern "C" ++#endif ++char versionsort (); ++int ++main () ++{ ++return versionsort (); ++ ; ++ return 0; ++} ++_ACEOF ++for ac_lib in '' ; do ++ if test -z "$ac_lib"; then ++ ac_res="none required" ++ else ++ ac_res=-l$ac_lib ++ LIBS="-l$ac_lib $ac_func_search_save_LIBS" ++ fi ++ if ac_fn_c_try_link "$LINENO"; then : ++ ac_cv_search_versionsort=$ac_res ++fi ++rm -f core conftest.err conftest.$ac_objext \ ++ conftest$ac_exeext ++ if ${ac_cv_search_versionsort+:} false; then : ++ break ++fi ++done ++if ${ac_cv_search_versionsort+:} false; then : ++ ++else ++ ac_cv_search_versionsort=no ++fi ++rm conftest.$ac_ext ++LIBS=$ac_func_search_save_LIBS ++fi ++{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_versionsort" >&5 ++$as_echo "$ac_cv_search_versionsort" >&6; } ++ac_res=$ac_cv_search_versionsort ++if test "$ac_res" != no; then : ++ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" ++ ++fi ++ ++if test "$ac_cv_search_versionsort" = "no"; then ++ ++$as_echo "#define WITHOUT_VERSIONSORT 1" >>confdefs.h ++ ++fi ++ + # + # glibc/libc 6 new libraries + # +diff --git a/configure.in b/configure.in +index 363c376..4029375 100644 +--- a/configure.in ++++ b/configure.in +@@ -163,6 +163,12 @@ AF_SLOPPY_MOUNT() + AF_CHECK_LIBXML() + AF_CHECK_KRB5() + ++AC_SEARCH_LIBS([versionsort],[]) ++if test "$ac_cv_search_versionsort" = "no"; then ++ AC_DEFINE(WITHOUT_VERSIONSORT, 1, ++ [Define if your C library does not provide versionsort]) ++fi ++ + # + # glibc/libc 6 new libraries + # +diff --git a/include/config.h.in b/include/config.h.in +index 7f1c5b5..a2a05a8 100644 +--- a/include/config.h.in ++++ b/include/config.h.in +@@ -135,6 +135,9 @@ + /* Define to 1 to use the libtirpc tsd usage workaround */ + #undef TIRPC_WORKAROUND + ++/* Define if your C library does not provide versionsort */ ++#undef WITHOUT_VERSIONSORT ++ + /* Define if using the dmalloc debugging malloc package */ + #undef WITH_DMALLOC + +diff --git a/modules/lookup_dir.c b/modules/lookup_dir.c +index 33901c0..07471b7 100644 +--- a/modules/lookup_dir.c ++++ b/modules/lookup_dir.c +@@ -39,6 +39,11 @@ + #define AUTOFS_DIR_EXT ".autofs" + #define AUTOFS_DIR_EXTSIZ (sizeof(AUTOFS_DIR_EXT) - 1) + ++/* Work around non-GNU systems that don't provide versionsort */ ++#ifdef WITHOUT_VERSIONSORT ++#define versionsort alphasort ++#endif ++ + struct lookup_context { + const char *mapname; + }; diff --git a/SOURCES/autofs-5.0.8-add-negative-cache-lookup-to-hesiod-lookup.patch b/SOURCES/autofs-5.0.8-add-negative-cache-lookup-to-hesiod-lookup.patch new file mode 100644 index 0000000..2e5b90f --- /dev/null +++ b/SOURCES/autofs-5.0.8-add-negative-cache-lookup-to-hesiod-lookup.patch @@ -0,0 +1,89 @@ +autofs-5.0.8 - add negative cache lookup to hesiod lookup + +From: Ian Kent + +Warning, this is completely untested. + +I don't have a hesiod test environment so I can't test this at all. +If we do in fact have hesiod users then I'll need to work with them +to fix any reported problems. +--- + CHANGELOG | 1 + + modules/lookup_hesiod.c | 39 ++++++++++++++++++++++++++++++++++++++- + 2 files changed, 39 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -91,6 +91,7 @@ + - fix bad mkdir permission on create. + - fix macro_addvar() and move init to main thread. + - change walk_tree() to take ap. ++- add negative cache lookup to hesiod lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_hesiod.c ++++ autofs-5.0.7/modules/lookup_hesiod.c +@@ -99,10 +99,11 @@ int lookup_read_map(struct autofs_point + */ + int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) context; + struct map_source *source; + struct mapent_cache *mc; ++ struct mapent *me; + char **hes_result; +- struct lookup_context *ctxt = (struct lookup_context *) context; + int status, rv; + char **record, *best_record = NULL, *p; + int priority, lowest_priority = INT_MAX; +@@ -117,6 +118,32 @@ int lookup_mount(struct autofs_point *ap + MODPREFIX "looking up root=\"%s\", name=\"%s\"", + ap->path, name); + ++ /* 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)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } else { ++ struct mapent_cache *smc = me->mc; ++ struct mapent *sme; ++ ++ if (me->mapent) ++ cache_unlock(smc); ++ else { ++ cache_unlock(smc); ++ cache_writelock(smc); ++ sme = cache_lookup_distinct(smc, name); ++ /* Negative timeout expired for non-existent entry. */ ++ if (sme && !sme->mapent) { ++ if (cache_pop_mapent(sme) == CHE_FAIL) ++ cache_delete(smc, name); ++ } ++ cache_unlock(smc); ++ } ++ } ++ } ++ + chdir("/"); /* If this is not here the filesystem stays + busy, for some reason... */ + +@@ -171,6 +198,16 @@ int lookup_mount(struct autofs_point *ap + if (status) + fatal(status); + ++ if (rv) { ++ /* Don't update negative cache when re-connecting */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ return NSS_STATUS_TRYAGAIN; ++ cache_writelock(mc); ++ cache_update_negative(mc, source, name, ap->negative_timeout); ++ cache_unlock(mc); ++ return NSS_STATUS_TRYAGAIN; ++ } ++ + /* + * Unavailable due to error such as module load fail + * or out of memory, etc. diff --git a/SOURCES/autofs-5.0.8-amd-lookup-update-lookup-hesiod-to-handle-amd-keys.patch b/SOURCES/autofs-5.0.8-amd-lookup-update-lookup-hesiod-to-handle-amd-keys.patch new file mode 100644 index 0000000..e14ea19 --- /dev/null +++ b/SOURCES/autofs-5.0.8-amd-lookup-update-lookup-hesiod-to-handle-amd-keys.patch @@ -0,0 +1,406 @@ +autofs-5.0.8 - amd lookup update lookup hesiod to handle amd keys + +From: Ian Kent + +Warning, this is completely untested. + +I don't have a hesiod test environment so I can't test this at all. +If we do in fact have hesiod users then I'll need to work with them +to fix any reported problems. +--- + modules/lookup_hesiod.c | 330 +++++++++++++++++++++++++++++++++++++++--------- + 1 file changed, 270 insertions(+), 60 deletions(-) + +--- autofs-5.0.7.orig/modules/lookup_hesiod.c ++++ autofs-5.0.7/modules/lookup_hesiod.c +@@ -20,12 +20,15 @@ + #include "automount.h" + #include "nsswitch.h" + +-#define MAPFMT_DEFAULT "hesiod" ++#define MAPFMT_DEFAULT "hesiod" ++#define AMD_MAP_PREFIX "hesiod." ++#define AMD_MAP_PREFIX_LEN 7 + + #define MODPREFIX "lookup(hesiod): " + #define HESIOD_LEN 512 + + struct lookup_context { ++ const char *mapname; + struct parse_mod *parser; + void *hesiod_context; + }; +@@ -50,6 +53,7 @@ int lookup_init(const char *mapfmt, int + logerr(MODPREFIX "malloc: %s", estr); + return 1; + } ++ memset(ctxt, 0, sizeof(struct lookup_context)); + + /* Initialize the resolver. */ + res_init(); +@@ -66,6 +70,20 @@ int lookup_init(const char *mapfmt, int + if (!mapfmt) + mapfmt = MAPFMT_DEFAULT; + ++ if (!strcmp(mapfmt, "amd")) { ++ /* amd formated hesiod maps have a map name */ ++ const char *mapname = argv[0]; ++ if (strncmp(mapname, AMD_MAP_PREFIX, AMD_MAP_PREFIX_LEN)) { ++ logerr(MODPREFIX ++ "incorrect prefix for hesiod map %s", mapname); ++ free(ctxt); ++ return 1; ++ } ++ ctxt->mapname = mapname; ++ argc--; ++ argv++; ++ } ++ + /* Open the parser, if we can. */ + ctxt->parser = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); + if (!ctxt->parser) { +@@ -97,16 +115,203 @@ int lookup_read_map(struct autofs_point + * it's an ERR filesystem, it's an error message we should log. Otherwise, + * assume it's something we know how to deal with already (generic). + */ ++static int lookup_one(struct autofs_point *ap, ++ struct map_source *source, ++ const char *key, int key_len, ++ struct lookup_context *ctxt) ++{ ++ struct mapent_cache *mc; ++ char **hes_result; ++ char **record, *best_record = NULL, *p; ++ int priority, lowest_priority = INT_MAX; ++ int ret, status; ++ ++ mc = source->mc; ++ ++ status = pthread_mutex_lock(&hesiod_mutex); ++ if (status) ++ fatal(status); ++ ++ hes_result = hesiod_resolve(ctxt->hesiod_context, key, "filsys"); ++ if (!hes_result || !hes_result[0]) { ++ int err = errno; ++ error(ap->logopt, ++ MODPREFIX "key \"%s\" not found in map", key); ++ status = pthread_mutex_unlock(&hesiod_mutex); ++ if (status) ++ fatal(status); ++ if (err == HES_ER_NOTFOUND) ++ return CHE_MISSING; ++ else ++ return CHE_FAIL; ++ } ++ ++ /* autofs doesn't support falling back to alternate records, so just ++ find the record with the lowest priority and hope it works. ++ -- Aaron Ucko 2002-03-11 */ ++ for (record = hes_result; *record; ++record) { ++ p = strrchr(*record, ' '); ++ if ( p && isdigit(p[1]) ) { ++ priority = atoi(p+1); ++ } else { ++ priority = INT_MAX - 1; ++ } ++ if (priority < lowest_priority) { ++ lowest_priority = priority; ++ best_record = *record; ++ } ++ } ++ ++ cache_writelock(mc); ++ ret = cache_update(mc, source, key, best_record, time(NULL)); ++ cache_unlock(mc); ++ if (ret == CHE_FAIL) { ++ hesiod_free_list(ctxt->hesiod_context, hes_result); ++ status = pthread_mutex_unlock(&hesiod_mutex); ++ if (status) ++ fatal(status); ++ return ret; ++ } ++ ++ debug(ap->logopt, ++ MODPREFIX "lookup for \"%s\" gave \"%s\"", ++ key, best_record); ++ ++ hesiod_free_list(ctxt->hesiod_context, hes_result); ++ ++ status = pthread_mutex_unlock(&hesiod_mutex); ++ if (status) ++ fatal(status); ++ ++ return ret; ++} ++ ++static int lookup_one_amd(struct autofs_point *ap, ++ struct map_source *source, ++ const char *key, int key_len, ++ struct lookup_context *ctxt) ++{ ++ struct mapent_cache *mc; ++ char *hesiod_base; ++ char **hes_result; ++ char *lkp_key; ++ int status, ret; ++ ++ mc = source->mc; ++ ++ hesiod_base = conf_amd_get_hesiod_base(); ++ if (!hesiod_base) ++ return CHE_FAIL; ++ ++ lkp_key = malloc(key_len + strlen(ctxt->mapname) - 7 + 2); ++ if (!lkp_key) { ++ free(hesiod_base); ++ return CHE_FAIL; ++ } ++ ++ strcpy(lkp_key, key); ++ strcat(lkp_key, "."); ++ strcat(lkp_key, ctxt->mapname + AMD_MAP_PREFIX_LEN); ++ ++ status = pthread_mutex_lock(&hesiod_mutex); ++ if (status) ++ fatal(status); ++ ++ hes_result = hesiod_resolve(ctxt->hesiod_context, lkp_key, hesiod_base); ++ if (!hes_result || !hes_result[0]) { ++ int err = errno; ++ if (err == HES_ER_NOTFOUND) ++ ret = CHE_MISSING; ++ else ++ ret = CHE_FAIL; ++ goto done; ++ } ++ ++ cache_writelock(mc); ++ ret = cache_update(mc, source, lkp_key, *hes_result, time(NULL)); ++ cache_unlock(mc); ++ ++ if (hes_result) ++ hesiod_free_list(ctxt->hesiod_context, hes_result); ++done: ++ free(lkp_key); ++ ++ status = pthread_mutex_unlock(&hesiod_mutex); ++ if (status) ++ fatal(status); ++ ++ return ret; ++} ++ ++static int match_amd_key(struct autofs_point *ap, ++ struct map_source *source, ++ const char *key, int key_len, ++ struct lookup_context *ctxt) ++{ ++ char buf[MAX_ERR_BUF]; ++ char *lkp_key; ++ char *prefix; ++ int ret; ++ ++ ret = lookup_one_amd(ap, source, key, key_len, ctxt); ++ if (ret == CHE_OK || ret == CHE_UPDATED) ++ return ret; ++ ++ lkp_key = strdup(key); ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "strdup: %s", estr); ++ return CHE_FAIL; ++ } ++ ++ ret = CHE_MISSING; ++ ++ /* ++ * Now strip successive directory components and try a ++ * match against map entries ending with a wildcard and ++ * finally try the wilcard entry itself. ++ */ ++ while ((prefix = strrchr(lkp_key, '/'))) { ++ char *match; ++ size_t len; ++ *prefix = '\0'; ++ len = strlen(lkp_key) + 3; ++ match = malloc(len); ++ if (!match) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ ret = CHE_FAIL; ++ goto done; ++ } ++ len--; ++ strcpy(match, lkp_key); ++ strcat(match, "/*"); ++ ret = lookup_one_amd(ap, source, match, len, ctxt); ++ free(match); ++ if (ret == CHE_OK || ret == CHE_UPDATED) ++ goto done; ++ } ++ ++ /* Lastly try the wildcard */ ++ ret = lookup_one_amd(ap, source, "*", 1, ctxt); ++done: ++ free(lkp_key); ++ return ret; ++} ++ + int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; + struct mapent_cache *mc; ++ char buf[MAX_ERR_BUF]; ++ struct map_source *source; + struct mapent *me; +- char **hes_result; +- int status, rv; +- char **record, *best_record = NULL, *p; +- int priority, lowest_priority = INT_MAX; ++ char key[KEY_MAX_LEN + 1]; ++ size_t key_len; ++ char *lkp_key; ++ size_t len; ++ char *mapent; ++ int rv; + + source = ap->entry->current; + ap->entry->current = NULL; +@@ -118,6 +323,19 @@ int lookup_mount(struct autofs_point *ap + MODPREFIX "looking up root=\"%s\", name=\"%s\"", + ap->path, name); + ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { ++ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ } else { ++ key_len = expandamdent(name, NULL, NULL); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ expandamdent(name, key, NULL); ++ key[key_len] = '\0'; ++ debug(ap->logopt, MODPREFIX "expanded key: \"%s\"", key); ++ } ++ + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, name, LKP_DISTINCT); + if (me) { +@@ -144,69 +362,61 @@ int lookup_mount(struct autofs_point *ap + } + } + +- chdir("/"); /* If this is not here the filesystem stays +- busy, for some reason... */ +- +- status = pthread_mutex_lock(&hesiod_mutex); +- if (status) +- fatal(status); +- +- hes_result = hesiod_resolve(ctxt->hesiod_context, name, "filsys"); +- if (!hes_result || !hes_result[0]) { +- /* Note: it is not clear to me how to distinguish between +- * the "no search results" case and other failures. --JM */ +- error(ap->logopt, +- MODPREFIX "key \"%s\" not found in map", name); +- status = pthread_mutex_unlock(&hesiod_mutex); +- if (status) +- fatal(status); +- return NSS_STATUS_NOTFOUND; ++ /* If this is not here the filesystem stays busy, for some reason... */ ++ if (chdir("/")) ++ warn(ap->logopt, ++ MODPREFIX "failed to set working directory to \"/\""); ++ ++ len = key_len; ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) ++ lkp_key = strdup(key); ++ else { ++ rv = lookup_one_amd(ap, source, "/defaults", 9, ctxt); ++ if (rv == CHE_FAIL) ++ warn(ap->logopt, ++ MODPREFIX "failed to lookup \"/defaults\" entry"); ++ ++ if (!ap->pref) ++ lkp_key = strdup(key); ++ else { ++ len += strlen(ap->pref); ++ lkp_key = malloc(len + 1); ++ if (lkp_key) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, name); ++ } ++ } + } + +- /* autofs doesn't support falling back to alternate records, so just +- find the record with the lowest priority and hope it works. +- -- Aaron Ucko 2002-03-11 */ +- for (record = hes_result; *record; ++record) { +- p = strrchr(*record, ' '); +- if ( p && isdigit(p[1]) ) { +- priority = atoi(p+1); +- } else { +- priority = INT_MAX - 1; +- } +- if (priority < lowest_priority) { +- lowest_priority = priority; +- best_record = *record; +- } ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, "malloc: %s", estr); ++ return NSS_STATUS_UNKNOWN; + } + +- cache_writelock(mc); +- rv = cache_update(mc, source, name, best_record, time(NULL)); +- cache_unlock(mc); +- if (rv == CHE_FAIL) +- return NSS_STATUS_UNAVAIL; ++ if (source->flags & MAP_FLAG_FORMAT_AMD) ++ rv = match_amd_key(ap, source, lkp_key, len, ctxt); ++ else ++ rv = lookup_one(ap, source, lkp_key, len, ctxt); + +- debug(ap->logopt, +- MODPREFIX "lookup for \"%s\" gave \"%s\"", +- name, best_record); ++ if (rv == CHE_FAIL) { ++ free(lkp_key); ++ return NSS_STATUS_UNAVAIL; ++ } + +- rv = ctxt->parser->parse_mount(ap, name, name_len, best_record, +- ctxt->parser->context); ++ me = match_cached_key(ap, MODPREFIX, source, lkp_key); ++ free(lkp_key); ++ if (!me) ++ return NSS_STATUS_NOTFOUND; + +- hesiod_free_list(ctxt->hesiod_context, hes_result); ++ if (!me->mapent) ++ return NSS_STATUS_UNAVAIL; + +- status = pthread_mutex_unlock(&hesiod_mutex); +- if (status) +- fatal(status); ++ mapent = strdup(me->mapent); + +- if (rv) { +- /* Don't update negative cache when re-connecting */ +- if (ap->flags & MOUNT_FLAG_REMOUNT) +- return NSS_STATUS_TRYAGAIN; +- cache_writelock(mc); +- cache_update_negative(mc, source, name, ap->negative_timeout); +- cache_unlock(mc); +- return NSS_STATUS_TRYAGAIN; +- } ++ rv = ctxt->parser->parse_mount(ap, key, key_len, ++ mapent, ctxt->parser->context); ++ free(mapent); + + /* + * Unavailable due to error such as module load fail diff --git a/SOURCES/autofs-5.0.8-amd-lookup-update-lookup-ldap-to-handle-amd-keys.patch b/SOURCES/autofs-5.0.8-amd-lookup-update-lookup-ldap-to-handle-amd-keys.patch new file mode 100644 index 0000000..28f6816 --- /dev/null +++ b/SOURCES/autofs-5.0.8-amd-lookup-update-lookup-ldap-to-handle-amd-keys.patch @@ -0,0 +1,935 @@ +autofs-5.0.8 - amd lookup update lookup ldap to handle amd keys + +From: Ian Kent + + +--- + include/lookup_ldap.h | 3 + modules/lookup_ldap.c | 707 +++++++++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 651 insertions(+), 59 deletions(-) + +--- autofs-5.0.7.orig/include/lookup_ldap.h ++++ autofs-5.0.7/include/lookup_ldap.h +@@ -36,6 +36,7 @@ struct ldap_searchdn { + + struct lookup_context { + char *mapname; ++ unsigned int format; + + char *server; + int port; +@@ -43,6 +44,8 @@ struct lookup_context { + char *qdn; + unsigned int timeout; + unsigned int network_timeout; ++ unsigned long timestamp; ++ unsigned int check_defaults; + + /* LDAP version 2 or 3 */ + int version; +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -29,6 +29,7 @@ + #include + #include + #include ++#include + + #define MODULE_LOOKUP + #include "automount.h" +@@ -52,6 +53,14 @@ static struct ldap_schema common_schema[ + }; + static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema); + ++static struct ldap_schema amd_timestamp = { ++ "madmap", "amdmapName", "amdmapTimestamp", NULL, "amdmapTimestamp" ++}; ++ ++static struct ldap_schema amd_schema = { ++ "amdmap", "amdmapName", "amdmap", "amdmapKey", "amdmapValue" ++}; ++ + /* + * Initialization and de-initialization of LDAP and OpenSSL must be + * always serialized to avoid corruption of context structures inside +@@ -62,6 +71,7 @@ pthread_mutex_t ldapinit_mutex = PTHREAD + struct ldap_search_params { + struct autofs_point *ap; + LDAP *ldap; ++ char *base; + char *query, **attrs; + struct berval *cookie; + ber_int_t pageSize; +@@ -531,6 +541,16 @@ static int find_query_dn(unsigned logopt + if (ctxt->schema) + return 0; + ++ if (ctxt->format & MAP_FLAG_FORMAT_AMD) { ++ schema = alloc_common_schema(&amd_schema); ++ if (!schema) { ++ error(logopt, MODPREFIX "failed to allocate schema"); ++ return 0; ++ } ++ ctxt->schema = schema; ++ return 1; ++ } ++ + for (i = 0; i < common_schema_count; i++) { + const char *class = common_schema[i].map_class; + const char *key = common_schema[i].map_attr; +@@ -587,8 +607,10 @@ static int do_bind(unsigned logopt, LDAP + + if (!ctxt->cur_host) { + ctxt->cur_host = nhost; +- /* Check if schema defined in conf first time only */ +- ctxt->schema = defaults_get_schema(); ++ if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) { ++ /* Check if schema defined in conf first time only */ ++ ctxt->schema = defaults_get_schema(); ++ } + } else { + /* If connection host has changed update */ + if (strcmp(ctxt->cur_host, nhost)) { +@@ -614,7 +636,7 @@ static int do_bind(unsigned logopt, LDAP + MODPREFIX "failed to find valid query dn"); + return 0; + } +- } else { ++ } 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)) { +@@ -648,6 +670,126 @@ static LDAP *do_connect(unsigned logopt, + return ldap; + } + ++static unsigned long get_amd_timestamp(struct lookup_context *ctxt) ++{ ++ LDAP *ldap; ++ LDAPMessage *result = NULL, *e; ++ char *query; ++ int scope = LDAP_SCOPE_SUBTREE; ++ char *map, *class, *value; ++ char *attrs[2]; ++ struct berval **bvValues; ++ unsigned long timestamp = 0; ++ int rv, l, ql; ++ ++ ldap = do_connect(LOGOPT_ANY, ctxt->server, ctxt); ++ if (!ldap) ++ return 0; ++ ++ map = amd_timestamp.map_attr; ++ class = amd_timestamp.entry_class; ++ value = amd_timestamp.value_attr; ++ ++ attrs[0] = value; ++ attrs[1] = NULL; ++ ++ /* Build a query string. */ ++ l = strlen(class) + ++ strlen(map) + strlen(ctxt->mapname) + 21; ++ ++ query = malloc(l); ++ if (query == NULL) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ crit(LOGOPT_ANY, MODPREFIX "malloc: %s", estr); ++ return 0; ++ } ++ ++ /* ++ * Look for an entry in class under ctxt-base ++ * whose entry is equal to qKey. ++ */ ++ ql = sprintf(query, "(&(objectclass=%s)(%s=%s))", ++ class, map, ctxt->mapname); ++ if (ql >= l) { ++ error(LOGOPT_ANY, ++ MODPREFIX "error forming query string"); ++ free(query); ++ return 0; ++ } ++ ++ 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); ++ if (result) ++ ldap_msgfree(result); ++ free(query); ++ return 0; ++ } ++ ++ e = ldap_first_entry(ldap, result); ++ if (!e) { ++ debug(LOGOPT_ANY, ++ MODPREFIX "got answer, but no entry for timestamp"); ++ ldap_msgfree(result); ++ unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt); ++ free(query); ++ return CHE_MISSING; ++ } ++ ++ while (e) { ++ char *v_val; ++ char *endptr; ++ ++ bvValues = ldap_get_values_len(ldap, e, value); ++ if (!bvValues || !*bvValues) { ++ debug(LOGOPT_ANY, ++ MODPREFIX "no value found in timestamp"); ++ goto next; ++ } ++ ++ /* There should be one value for a timestamp */ ++ v_val = bvValues[0]->bv_val; ++ ++ timestamp = strtol(v_val, &endptr, 0); ++ if ((errno == ERANGE && ++ (timestamp == LONG_MAX || timestamp == LONG_MIN)) || ++ (errno != 0 && timestamp == 0)) { ++ debug(LOGOPT_ANY, ++ MODPREFIX "invalid value in timestamp"); ++ free(query); ++ return 0; ++ } ++ ++ if (endptr == v_val) { ++ debug(LOGOPT_ANY, ++ MODPREFIX "no digits found in timestamp"); ++ free(query); ++ return 0; ++ } ++ ++ if (*endptr != '\0') { ++ warn(LOGOPT_ANY, MODPREFIX ++ "characters found after number: %s", endptr); ++ warn(LOGOPT_ANY, ++ MODPREFIX "timestamp may be invalid"); ++ } ++ ++ ldap_value_free_len(bvValues); ++ break; ++next: ++ ldap_value_free_len(bvValues); ++ e = ldap_next_entry(ldap, e); ++ } ++ ++ ldap_msgfree(result); ++ unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt); ++ free(query); ++ ++ return timestamp; ++} ++ + static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_context *ctxt) + { + LDAP *ldap; +@@ -1215,7 +1357,7 @@ static int parse_server_string(unsigned + const char *q = NULL; + + /* Isolate the server(s). */ +- if ((q = strchr(s, '/'))) { ++ if ((q = strchr(s, '/')) || (q = strchr(s, '\0'))) { + l = q - s; + if (*proto) { + al_len = l + strlen(proto) + 2; +@@ -1318,8 +1460,7 @@ static int parse_server_string(unsigned + ptr += l + 1; + } + +- /* TODO: why did I do this - how can the map name "and" base dn be missing? */ +- if (!ptr) ++ if (!ptr || ctxt->format & MAP_FLAG_FORMAT_AMD) + goto done; + + /* +@@ -1505,36 +1646,83 @@ int lookup_init(const char *mapfmt, int + /* If a map type isn't explicitly given, parse it like sun entries. */ + if (mapfmt == NULL) + mapfmt = MAPFMT_DEFAULT; +- +- /* +- * Parse out the server name and base dn, and fill them +- * into the proper places in the lookup context structure. +- */ +- if (!parse_server_string(LOGOPT_NONE, argv[0], ctxt)) { +- error(LOGOPT_ANY, MODPREFIX "cannot parse server string"); +- free_context(ctxt); +- return 1; ++ if (!strcmp(mapfmt, "amd")) { ++ ctxt->format = MAP_FLAG_FORMAT_AMD; ++ ctxt->check_defaults = 1; + } + +- if (!ctxt->base) +- ctxt->sdns = defaults_get_searchdns(); +- + ctxt->timeout = defaults_get_ldap_timeout(); + ctxt->network_timeout = defaults_get_ldap_network_timeout(); + +- if (!ctxt->server) { +- struct list_head *uris = defaults_get_uris(); +- if (uris) { +- validate_uris(uris); +- if (!list_empty(uris)) +- ctxt->uris = uris; +- else { +- error(LOGOPT_ANY, +- "no valid uris found in config list" +- ", using default system config"); +- free(uris); ++ if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) { ++ /* ++ * Parse out the server name and base dn, and fill them ++ * into the proper places in the lookup context structure. ++ */ ++ if (!parse_server_string(LOGOPT_NONE, argv[0], ctxt)) { ++ error(LOGOPT_ANY, MODPREFIX "cannot parse server string"); ++ free_context(ctxt); ++ return 1; ++ } ++ ++ if (!ctxt->base) ++ ctxt->sdns = defaults_get_searchdns(); ++ ++ if (!ctxt->server) { ++ struct list_head *uris = defaults_get_uris(); ++ if (uris) { ++ validate_uris(uris); ++ if (!list_empty(uris)) ++ ctxt->uris = uris; ++ else { ++ error(LOGOPT_ANY, MODPREFIX ++ "no valid uris found in config list" ++ ", using default system config"); ++ free(uris); ++ } + } + } ++ } else { ++ 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; ++ ++ tmp = conf_amd_get_ldap_hostports(); ++ if (!tmp) { ++ error(LOGOPT_ANY, ++ MODPREFIX "failed to get ldap_hostports"); ++ free_context(ctxt); ++ return 1; ++ } ++ ++ /* ++ * Parse out the server name and port, and save them in ++ * the proper places in the lookup context structure. ++ */ ++ 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; + } + + /* +@@ -1558,6 +1746,8 @@ int lookup_init(const char *mapfmt, int + } + #endif + ++ 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) { +@@ -2029,7 +2219,7 @@ static int do_paged_query(struct ldap_se + if (sp->morePages == TRUE) + goto do_paged; + +- rv = ldap_search_s(sp->ldap, ctxt->qdn, scope, sp->query, sp->attrs, 0, &sp->result); ++ rv = ldap_search_s(sp->ldap, sp->base, scope, sp->query, sp->attrs, 0, &sp->result); + if ((rv != LDAP_SUCCESS) || !sp->result) { + /* + * Check for Size Limit exceeded and force run through loop +@@ -2063,7 +2253,7 @@ do_paged: + + /* Search for entries in the directory using the parmeters. */ + rv = ldap_search_ext_s(sp->ldap, +- ctxt->qdn, scope, sp->query, sp->attrs, ++ sp->base, scope, sp->query, sp->attrs, + 0, controls, NULL, NULL, 0, &sp->result); + if ((rv != LDAP_SUCCESS) && (rv != LDAP_PARTIAL_RESULTS)) { + ldap_control_free(pageControl); +@@ -2364,6 +2554,115 @@ next: + return LDAP_SUCCESS; + } + ++static int do_get_amd_entries(struct ldap_search_params *sp, ++ struct map_source *source, ++ struct lookup_context *ctxt) ++{ ++ struct autofs_point *ap = sp->ap; ++ struct mapent_cache *mc = source->mc; ++ struct berval **bvKey; ++ struct berval **bvValues; ++ LDAPMessage *e; ++ char *entry, *value; ++ int rv, ret, count; ++ ++ entry = ctxt->schema->entry_attr; ++ value = ctxt->schema->value_attr; ++ ++ e = ldap_first_entry(sp->ldap, sp->result); ++ if (!e) { ++ debug(ap->logopt, ++ MODPREFIX "query succeeded, no matches for %s", ++ sp->query); ++ ret = ldap_parse_result(sp->ldap, sp->result, ++ &rv, NULL, NULL, NULL, NULL, 0); ++ if (ret == LDAP_SUCCESS) ++ return rv; ++ else ++ return LDAP_OPERATIONS_ERROR; ++ } else ++ debug(ap->logopt, MODPREFIX "examining entries"); ++ ++ while (e) { ++ char *k_val, *v_val; ++ ber_len_t k_len; ++ char *s_key; ++ ++ bvKey = ldap_get_values_len(sp->ldap, e, entry); ++ if (!bvKey || !*bvKey) { ++ e = ldap_next_entry(sp->ldap, e); ++ if (!e) { ++ debug(ap->logopt, MODPREFIX ++ "failed to get next entry for query %s", ++ sp->query); ++ ret = ldap_parse_result(sp->ldap, ++ sp->result, &rv, ++ NULL, NULL, NULL, NULL, 0); ++ if (ret == LDAP_SUCCESS) ++ return rv; ++ else ++ return LDAP_OPERATIONS_ERROR; ++ } ++ continue; ++ } ++ ++ /* By definition keys should be unique within each map entry */ ++ k_val = NULL; ++ k_len = 0; ++ ++ count = ldap_count_values_len(bvKey); ++ if (count > 1) ++ warn(ap->logopt, MODPREFIX ++ "more than one %s, using first", entry); ++ ++ k_val = bvKey[0]->bv_val; ++ k_len = bvKey[0]->bv_len; ++ ++ bvValues = ldap_get_values_len(sp->ldap, e, value); ++ if (!bvValues || !*bvValues) { ++ debug(ap->logopt, ++ MODPREFIX "no %s defined for %s", ++ value, sp->query); ++ goto next; ++ } ++ ++ count = ldap_count_values_len(bvValues); ++ if (count > 1) ++ warn(ap->logopt, MODPREFIX ++ "more than one %s, using first", value); ++ ++ v_val = bvValues[0]->bv_val; ++ ++ /* Don't fail on "/" in key => type == 0 */ ++ s_key = sanitize_path(k_val, k_len, 0, ap->logopt); ++ if (!s_key) ++ goto next; ++ ++ cache_writelock(mc); ++ cache_update(mc, source, s_key, v_val, sp->age); ++ cache_unlock(mc); ++ ++ free(s_key); ++next: ++ ldap_value_free_len(bvValues); ++ ldap_value_free_len(bvKey); ++ e = ldap_next_entry(sp->ldap, e); ++ if (!e) { ++ debug(ap->logopt, MODPREFIX ++ "failed to get next entry for query %s", ++ sp->query); ++ ret = ldap_parse_result(sp->ldap, ++ sp->result, &rv, ++ NULL, NULL, NULL, NULL, 0); ++ if (ret == LDAP_SUCCESS) ++ return rv; ++ else ++ return LDAP_OPERATIONS_ERROR; ++ } ++ } ++ ++ return LDAP_SUCCESS; ++} + + static int read_one_map(struct autofs_point *ap, + struct map_source *source, +@@ -2419,9 +2718,14 @@ static int read_one_map(struct autofs_po + return NSS_STATUS_UNAVAIL; + } + ++ if (ctxt->format & MAP_FLAG_FORMAT_AMD) ++ sp.base = ctxt->base; ++ else ++ sp.base = ctxt->qdn; ++ + /* Look around. */ + debug(ap->logopt, +- MODPREFIX "searching for \"%s\" under \"%s\"", sp.query, ctxt->qdn); ++ MODPREFIX "searching for \"%s\" under \"%s\"", sp.query, sp.base); + + sp.cookie = NULL; + sp.pageSize = 2000; +@@ -2465,7 +2769,10 @@ static int read_one_map(struct autofs_po + return NSS_STATUS_UNAVAIL; + } + +- rv = do_get_entries(&sp, source, ctxt); ++ if (source->flags & MAP_FLAG_FORMAT_AMD) ++ rv = do_get_amd_entries(&sp, source, ctxt); ++ else ++ rv = do_get_entries(&sp, source, ctxt); + if (rv != LDAP_SUCCESS) { + ldap_msgfree(sp.result); + unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); +@@ -2874,6 +3181,219 @@ next: + return ret; + } + ++static int lookup_one_amd(struct autofs_point *ap, ++ struct map_source *source, ++ char *qKey, int qKey_len, ++ struct lookup_context *ctxt) ++{ ++ struct mapent_cache *mc = source->mc; ++ LDAP *ldap; ++ LDAPMessage *result = NULL, *e; ++ char *query; ++ int scope = LDAP_SCOPE_SUBTREE; ++ char *map, *class, *entry, *value; ++ char *attrs[3]; ++ struct berval **bvKey; ++ struct berval **bvValues; ++ char buf[MAX_ERR_BUF]; ++ time_t age = time(NULL); ++ int rv, l, ql, count; ++ int ret = CHE_MISSING; ++ ++ if (ctxt == NULL) { ++ crit(ap->logopt, MODPREFIX "context was NULL"); ++ return CHE_FAIL; ++ } ++ ++ /* Initialize the LDAP context. */ ++ ldap = do_reconnect(ap->logopt, ctxt); ++ if (!ldap) ++ return CHE_UNAVAIL; ++ ++ map = ctxt->schema->map_attr; ++ class = ctxt->schema->entry_class; ++ entry = ctxt->schema->entry_attr; ++ value = ctxt->schema->value_attr; ++ ++ attrs[0] = entry; ++ attrs[1] = value; ++ attrs[2] = NULL; ++ ++ /* Build a query string. */ ++ l = strlen(class) + ++ strlen(map) + strlen(ctxt->mapname) + ++ strlen(entry) + strlen(qKey) + 24; ++ ++ query = malloc(l); ++ if (query == NULL) { ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ crit(ap->logopt, MODPREFIX "malloc: %s", estr); ++ return CHE_FAIL; ++ } ++ ++ /* ++ * Look for an entry in class under ctxt-base ++ * whose entry is equal to qKey. ++ */ ++ ql = sprintf(query, "(&(objectclass=%s)(%s=%s)(%s=%s))", ++ class, map, ctxt->mapname, entry, qKey); ++ if (ql >= l) { ++ error(ap->logopt, ++ MODPREFIX "error forming query string"); ++ free(query); ++ return CHE_FAIL; ++ } ++ ++ debug(ap->logopt, ++ MODPREFIX "searching for \"%s\" under \"%s\"", query, ctxt->base); ++ ++ 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); ++ if (result) ++ ldap_msgfree(result); ++ free(query); ++ return CHE_FAIL; ++ } ++ ++ debug(ap->logopt, ++ MODPREFIX "getting first entry for %s=\"%s\"", entry, qKey); ++ ++ e = ldap_first_entry(ldap, result); ++ if (!e) { ++ debug(ap->logopt, ++ MODPREFIX "got answer, but no entry for %s", query); ++ ldap_msgfree(result); ++ unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ free(query); ++ return CHE_MISSING; ++ } ++ ++ while (e) { ++ char *k_val, *v_val; ++ ber_len_t k_len; ++ char *s_key; ++ ++ bvKey = ldap_get_values_len(ldap, e, entry); ++ if (!bvKey || !*bvKey) { ++ e = ldap_next_entry(ldap, e); ++ continue; ++ } ++ ++ /* By definition keys should be unique within each map entry */ ++ k_val = NULL; ++ k_len = 0; ++ ++ count = ldap_count_values_len(bvKey); ++ if (count > 1) ++ warn(ap->logopt, MODPREFIX ++ "more than one %s, using first", entry); ++ ++ k_val = bvKey[0]->bv_val; ++ k_len = bvKey[0]->bv_len; ++ ++ debug(ap->logopt, MODPREFIX "examining first entry"); ++ ++ bvValues = ldap_get_values_len(ldap, e, value); ++ if (!bvValues || !*bvValues) { ++ debug(ap->logopt, ++ MODPREFIX "no %s defined for %s", value, query); ++ goto next; ++ } ++ ++ count = ldap_count_values_len(bvValues); ++ if (count > 1) ++ warn(ap->logopt, MODPREFIX ++ "more than one %s, using first", value); ++ ++ /* There should be one value for a key, use first value */ ++ v_val = bvValues[0]->bv_val; ++ ++ /* Don't fail on "/" in key => type == 0 */ ++ s_key = sanitize_path(k_val, k_len, 0, ap->logopt); ++ if (!s_key) ++ goto next; ++ ++ cache_writelock(mc); ++ ret = cache_update(mc, source, s_key, v_val, age); ++ cache_unlock(mc); ++ ++ free(s_key); ++next: ++ ldap_value_free_len(bvValues); ++ ldap_value_free_len(bvKey); ++ e = ldap_next_entry(ldap, e); ++ } ++ ++ ldap_msgfree(result); ++ unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ free(query); ++ ++ return ret; ++} ++ ++static int match_key(struct autofs_point *ap, ++ struct map_source *source, ++ char *key, int key_len, ++ struct lookup_context *ctxt) ++{ ++ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD; ++ char buf[MAX_ERR_BUF]; ++ char *lkp_key; ++ char *prefix; ++ int ret; ++ ++ if (is_amd_format) ++ ret = lookup_one_amd(ap, source, key, key_len, ctxt); ++ else ++ ret = lookup_one(ap, source, key, key_len, ctxt); ++ ++ if (ret == CHE_OK || ret == CHE_UPDATED) ++ return ret; ++ ++ if (!is_amd_format) ++ return CHE_FAIL; ++ ++ lkp_key = strdup(key); ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "strdup: %s", estr); ++ return CHE_FAIL; ++ } ++ ++ ret = CHE_MISSING; ++ ++ /* ++ * Now strip successive directory components and try a ++ * match against map entries ending with a wildcard and ++ * finally try the wilcard entry itself. ++ */ ++ while ((prefix = strrchr(lkp_key, '/'))) { ++ char *match; ++ size_t len; ++ *prefix = '\0'; ++ len = strlen(lkp_key + 3); ++ match = malloc(len); ++ if (!match) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ ret = CHE_FAIL; ++ goto done; ++ } ++ len--; ++ strcpy(match, lkp_key); ++ strcat(match, "/*"); ++ ret = lookup_one_amd(ap, source, match, len, ctxt); ++ free(match); ++ if (ret == CHE_OK || ret == CHE_UPDATED) ++ goto done; ++ } ++done: ++ free(lkp_key); ++ return ret; ++} ++ + static int check_map_indirect(struct autofs_point *ap, + struct map_source *source, + char *key, int key_len, +@@ -2888,16 +3408,43 @@ static int check_map_indirect(struct aut + mc = source->mc; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = lookup_one(ap, source, key, key_len, ctxt); ++ ++ pthread_mutex_lock(&ap->entry->current_mutex); ++ if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ unsigned long timestamp = get_amd_timestamp(ctxt); ++ if (timestamp > ctxt->timestamp) { ++ ctxt->timestamp = timestamp; ++ source->stale = 1; ++ ctxt->check_defaults = 1; ++ } ++ ++ if (ctxt->check_defaults) { ++ /* Check for a /defaults entry */ ++ ret = lookup_one_amd(ap, source, "/defaults", 9, ctxt); ++ if (ret == CHE_FAIL) { ++ warn(ap->logopt, MODPREFIX ++ "error getting /defaults from map %s", ++ ctxt->mapname); ++ } else ++ ctxt->check_defaults = 0; ++ } ++ } ++ pthread_mutex_unlock(&ap->entry->current_mutex); ++ ++ ret = match_key(ap, source, key, key_len, ctxt); + if (ret == CHE_FAIL) { + pthread_setcancelstate(cur_state, NULL); + return NSS_STATUS_NOTFOUND; + } else if (ret == CHE_UNAVAIL) { ++ struct mapent *exists; + /* + * If the server is down and the entry exists in the cache + * and belongs to this map return success and use the entry. + */ +- struct mapent *exists = cache_lookup(mc, key); ++ if (source->flags & MAP_FLAG_FORMAT_AMD) ++ exists = match_cached_key(ap, MODPREFIX, source, key); ++ else ++ exists = cache_lookup(mc, key); + if (exists && exists->source == source) { + pthread_setcancelstate(cur_state, NULL); + return NSS_STATUS_SUCCESS; +@@ -2910,24 +3457,28 @@ static int check_map_indirect(struct aut + } + pthread_setcancelstate(cur_state, NULL); + +- /* +- * Check for map change and update as needed for +- * following cache lookup. +- */ +- cache_readlock(mc); +- t_last_read = ap->exp_runfreq + 1; +- me = cache_lookup_first(mc); +- while (me) { +- if (me->source == source) { +- t_last_read = now - me->age; +- break; ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { ++ /* ++ * Check for map change and update as needed for ++ * following cache lookup. ++ */ ++ cache_readlock(mc); ++ t_last_read = ap->exp_runfreq + 1; ++ me = cache_lookup_first(mc); ++ while (me) { ++ if (me->source == source) { ++ t_last_read = now - me->age; ++ break; ++ } ++ me = cache_lookup_next(mc, me); + } +- me = cache_lookup_next(mc, me); +- } +- cache_unlock(mc); ++ cache_unlock(mc); + +- if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED) +- source->stale = 1; ++ pthread_mutex_lock(&ap->entry->current_mutex); ++ if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED) ++ source->stale = 1; ++ pthread_mutex_unlock(&ap->entry->current_mutex); ++ } + + cache_readlock(mc); + me = cache_lookup_distinct(mc, "*"); +@@ -2948,8 +3499,10 @@ int lookup_mount(struct autofs_point *ap + struct mapent *me; + char key[KEY_MAX_LEN + 1]; + int key_len; ++ char *lkp_key; + char *mapent = NULL; + char mapent_buf[MAPENT_MAX_LEN + 1]; ++ char buf[MAX_ERR_BUF]; + int status = 0; + int ret = 1; + +@@ -2961,9 +3514,18 @@ int lookup_mount(struct autofs_point *ap + + debug(ap->logopt, MODPREFIX "looking up %s", name); + +- key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); +- if (key_len > KEY_MAX_LEN) +- return NSS_STATUS_NOTFOUND; ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { ++ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ } else { ++ key_len = expandamdent(name, NULL, NULL); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ expandamdent(name, key, NULL); ++ key[key_len] = '\0'; ++ debug(ap->logopt, MODPREFIX "expanded key: \"%s\"", key); ++ } + + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, key, LKP_DISTINCT); +@@ -2997,18 +3559,26 @@ int lookup_mount(struct autofs_point *ap + * we never know about it. + */ + if (ap->type == LKP_INDIRECT && *key != '/') { +- char *lkp_key; +- + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); + if (me && me->multi) + lkp_key = strdup(me->multi->key); +- else ++ else if (!ap->pref) + lkp_key = strdup(key); ++ else { ++ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1); ++ if (lkp_key) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, key); ++ } ++ } + cache_unlock(mc); + +- if (!lkp_key) ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); + return NSS_STATUS_UNKNOWN; ++ } + + status = check_map_indirect(ap, source, + lkp_key, strlen(lkp_key), ctxt); +@@ -3029,7 +3599,25 @@ int lookup_mount(struct autofs_point *ap + cache_readlock(mc); + else + cache_writelock(mc); +- me = cache_lookup(mc, key); ++ ++ if (!ap->pref) ++ lkp_key = strdup(key); ++ else { ++ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1); ++ if (lkp_key) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, key); ++ } ++ } ++ ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ cache_unlock(mc); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ me = match_cached_key(ap, MODPREFIX, source, lkp_key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { + while ((me = cache_lookup_key_next(me))) +@@ -3055,6 +3643,7 @@ int lookup_mount(struct autofs_point *ap + } + } + cache_unlock(mc); ++ free(lkp_key); + + if (!mapent) + return NSS_STATUS_TRYAGAIN; diff --git a/SOURCES/autofs-5.0.8-change-walk_tree-to-take-ap.patch b/SOURCES/autofs-5.0.8-change-walk_tree-to-take-ap.patch new file mode 100644 index 0000000..02be4cf --- /dev/null +++ b/SOURCES/autofs-5.0.8-change-walk_tree-to-take-ap.patch @@ -0,0 +1,226 @@ +autofs-5.0.8 - change walk_tree() to take ap + +From: Ian Kent + +Change walk_tree() to take an autofs_point pointer instead of +logopt. +--- + CHANGELOG | 1 + + daemon/automount.c | 49 +++++++++++++++++++++++++++++-------------------- + daemon/direct.c | 2 +- + daemon/indirect.c | 6 +++--- + include/automount.h | 4 ++-- + 5 files changed, 36 insertions(+), 26 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -90,6 +90,7 @@ + - fix master map type check. + - fix bad mkdir permission on create. + - fix macro_addvar() and move init to main thread. ++- change walk_tree() to take ap. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -254,10 +254,12 @@ int rmdir_path(struct autofs_point *ap, + /* Like ftw, except fn gets called twice: before a directory is + entered, and after. If the before call returns 0, the directory + isn't entered. */ +-static int walk_tree(const char *base, int (*fn) (unsigned logopt, ++static int walk_tree(const char *base, int (*fn) (struct autofs_point *ap, + const char *file, + const struct stat * st, +- int, void *), int incl, unsigned logopt, void *arg) ++ int, void *), int incl, ++ struct autofs_point *ap, ++ void *arg) + { + char buf[PATH_MAX + 1]; + struct stat st, *pst = &st; +@@ -270,7 +272,7 @@ static int walk_tree(const char *base, i + ret = 0; + } + +- if (ret != -1 && (fn) (logopt, base, pst, 0, arg)) { ++ if (ret != -1 && (fn) (ap, base, pst, 0, arg)) { + if (S_ISDIR(st.st_mode)) { + struct dirent **de; + int n; +@@ -298,18 +300,20 @@ static int walk_tree(const char *base, i + return -1; + } + +- walk_tree(buf, fn, 1, logopt, arg); ++ walk_tree(buf, fn, 1, ap, arg); + free(de[n]); + } + free(de); + } + if (incl) +- (fn) (logopt, base, pst, 1, arg); ++ (fn) (ap, base, pst, 1, arg); + } + return 0; + } + +-static int rm_unwanted_fn(unsigned logopt, const char *file, const struct stat *st, int when, void *arg) ++static int rm_unwanted_fn(struct autofs_point *ap, ++ const char *file, const struct stat *st, ++ int when, void *arg) + { + dev_t dev = *(dev_t *) arg; + char buf[MAX_ERR_BUF]; +@@ -325,38 +329,40 @@ static int rm_unwanted_fn(unsigned logop + } + + if (lstat(file, &newst)) { +- crit(logopt, "unable to stat file, possible race condition"); ++ crit(ap->logopt, ++ "unable to stat file, possible race condition"); + return 0; + } + + if (newst.st_dev != dev) { +- crit(logopt, "file %s has the wrong device, possible race condition", ++ crit(ap->logopt, ++ "file %s has the wrong device, possible race condition", + file); + return 0; + } + + if (S_ISDIR(newst.st_mode)) { +- debug(logopt, "removing directory %s", file); ++ debug(ap->logopt, "removing directory %s", file); + if (rmdir(file)) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- warn(logopt, ++ warn(ap->logopt, + "unable to remove directory %s: %s", file, estr); + return 0; + } + } else if (S_ISREG(newst.st_mode)) { +- crit(logopt, "attempting to remove files from a mounted " ++ crit(ap->logopt, "attempting to remove files from a mounted " + "directory. file %s", file); + return 0; + } else if (S_ISLNK(newst.st_mode)) { +- debug(logopt, "removing symlink %s", file); ++ debug(ap->logopt, "removing symlink %s", file); + unlink(file); + } + return 1; + } + +-void rm_unwanted(unsigned logopt, const char *path, int incl, dev_t dev) ++void rm_unwanted(struct autofs_point *ap, const char *path, int incl) + { +- walk_tree(path, rm_unwanted_fn, incl, logopt, &dev); ++ walk_tree(path, rm_unwanted_fn, incl, ap, &ap->dev); + } + + struct counter_args { +@@ -364,7 +370,8 @@ struct counter_args { + dev_t dev; + }; + +-static int counter_fn(unsigned logopt, const char *file, const struct stat *st, int when, void *arg) ++static int counter_fn(struct autofs_point *ap, const char *file, ++ const struct stat *st, int when, void *arg) + { + struct counter_args *counter = (struct counter_args *) arg; + +@@ -378,14 +385,14 @@ static int counter_fn(unsigned logopt, c + } + + /* Count mounted filesystems and symlinks */ +-int count_mounts(unsigned logopt, const char *path, dev_t dev) ++int count_mounts(struct autofs_point *ap, const char *path, dev_t dev) + { + struct counter_args counter; + + counter.count = 0; + counter.dev = dev; + +- if (walk_tree(path, counter_fn, 0, logopt, &counter) == -1) ++ if (walk_tree(path, counter_fn, 0, ap, &counter) == -1) + return -1; + + return counter.count; +@@ -409,9 +416,9 @@ static void check_rm_dirs(struct autofs_ + (ap->state == ST_SHUTDOWN_PENDING || + ap->state == ST_SHUTDOWN_FORCE || + ap->state == ST_SHUTDOWN)) +- rm_unwanted(ap->logopt, path, incl, ap->dev); ++ rm_unwanted(ap, path, incl); + else if ((ap->flags & MOUNT_FLAG_GHOST) && (ap->type == LKP_INDIRECT)) +- rm_unwanted(ap->logopt, path, 0, ap->dev); ++ rm_unwanted(ap, path, 0); + } + + /* Try to purge cache entries kept around due to existing mounts */ +@@ -553,7 +560,9 @@ int umount_multi(struct autofs_point *ap + left += umount_subtree_mounts(ap, path, is_autofs_fs); + + /* Delete detritus like unwanted mountpoints and symlinks */ +- if (left == 0 && ap->state != ST_READMAP) { ++ if (left == 0 && ++ ap->state != ST_READMAP && ++ !count_mounts(ap, path, ap->dev)) { + update_map_cache(ap, path); + check_rm_dirs(ap, path, incl); + } +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -912,7 +912,7 @@ void *expire_proc_direct(void *arg) + cache_writelock(me->mc); + if (me->ioctlfd != -1 && + fstat(me->ioctlfd, &st) != -1 && +- !count_mounts(ap->logopt, next->path, st.st_dev)) { ++ !count_mounts(ap, next->path, st.st_dev)) { + ops->close(ap->logopt, me->ioctlfd); + me->ioctlfd = -1; + cache_unlock(me->mc); +--- autofs-5.0.7.orig/daemon/indirect.c ++++ autofs-5.0.7/daemon/indirect.c +@@ -365,7 +365,7 @@ force_umount: + } else { + info(ap->logopt, "umounted indirect mount %s", mountpoint); + if (ap->submount) +- rm_unwanted(ap->logopt, mountpoint, 1, ap->dev); ++ rm_unwanted(ap, mountpoint, 1); + } + + return rv; +@@ -476,7 +476,7 @@ void *expire_proc_indirect(void *arg) + + /* Check for manual umount */ + if (fstat(me->ioctlfd, &st) == -1 || +- !count_mounts(ap->logopt, me->key, st.st_dev)) { ++ !count_mounts(ap, me->key, st.st_dev)) { + ops->close(ap->logopt, me->ioctlfd); + me->ioctlfd = -1; + } +@@ -538,7 +538,7 @@ void *expire_proc_indirect(void *arg) + * so we need to umount or unlink them here. + */ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- retries = (count_mounts(ap->logopt, ap->path, ap->dev) + 1); ++ retries = (count_mounts(ap, ap->path, ap->dev) + 1); + while (retries--) { + ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, now); + if (ret) +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -526,8 +526,8 @@ int handle_packet_expire_indirect(struct + int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_direct_t *pkt); + int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missing_indirect_t *pkt); + int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_direct_t *pkt); +-void rm_unwanted(unsigned logopt, const char *path, int incl, dev_t dev); +-int count_mounts(unsigned logopt, const char *path, dev_t dev); ++void rm_unwanted(struct autofs_point *ap, const char *path, int incl); ++int count_mounts(struct autofs_point *ap, const char *path, dev_t dev); + + #define mounts_mutex_lock(ap) \ + do { \ diff --git a/SOURCES/autofs-5.0.8-check-for-bind-onto-self-in-mount_bind-c.patch b/SOURCES/autofs-5.0.8-check-for-bind-onto-self-in-mount_bind-c.patch new file mode 100644 index 0000000..8f2913b --- /dev/null +++ b/SOURCES/autofs-5.0.8-check-for-bind-onto-self-in-mount_bind-c.patch @@ -0,0 +1,36 @@ +autofs-5.0.8 - check for bind onto self in mount_bind.c + +From: Ian Kent + +Check for an obviously impossible request to bind or symlink to the +same patch for source and target. +--- + CHANGELOG | 1 + + modules/mount_bind.c | 6 ++++++ + 2 files changed, 7 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -85,6 +85,7 @@ + - fix compilation of lookup_ldap.c without sasl. + - fix undefined authtype_requires_creds err if ldap enabled but without sasl. + - pass map_source as function paramter where possible. ++- check for bind onto self in mount_bind.c. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/mount_bind.c ++++ autofs-5.0.7/modules/mount_bind.c +@@ -135,6 +135,12 @@ int mount_mount(struct autofs_point *ap, + if (options == NULL || *options == '\0') + options = "defaults"; + ++ if (!strcmp(what, fullpath)) { ++ debug(ap->logopt, MODPREFIX ++ "cannot mount or symlink %s to itself", fullpath); ++ return 1; ++ } ++ + if (!symlnk && bind_works) { + int status, existed = 1; + diff --git a/SOURCES/autofs-5.0.8-check-for-existing-offset-mount-before-mounting.patch b/SOURCES/autofs-5.0.8-check-for-existing-offset-mount-before-mounting.patch new file mode 100644 index 0000000..8600444 --- /dev/null +++ b/SOURCES/autofs-5.0.8-check-for-existing-offset-mount-before-mounting.patch @@ -0,0 +1,46 @@ +autofs-5.0.8 - check for existing offset mount before mounting + +From: Ian Kent + +The change that introduced the miscellaneous device for autofs +mount control removed a mount point mounted check from the +mount_autofs_offset() function for when the miscellaneous +device is not used. + +But a subsequent change that enabled limited update of the exports +of a hosts mount needed that check. Without it a second occurance +of the offset (corresponding to an export) could be mounted upon +a map re-read. +--- + CHANGELOG | 1 + + daemon/direct.c | 3 +-- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -80,6 +80,7 @@ + - add short host name standard marco variable. + - fix symlink fail message in mount_bind.c. + - add std vars to program map invocation. ++- check for existing offset mount before mounting. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -671,14 +671,13 @@ int mount_autofs_offset(struct autofs_po + if (!(ret == -1 && errno == ENOENT)) + return MOUNT_OFFSET_FAIL; + } else { +-/* + if (is_mounted(_PROC_MOUNTS, me->key, MNTS_AUTOFS)) { + if (ap->state != ST_READMAP) + warn(ap->logopt, + "trigger %s already mounted", me->key); + return MOUNT_OFFSET_OK; + } +-*/ ++ + if (me->ioctlfd != -1) { + error(ap->logopt, "active offset mount %s", me->key); + return MOUNT_OFFSET_FAIL; diff --git a/SOURCES/autofs-5.0.8-dont-clobber-mapent-for-negative-cache.patch b/SOURCES/autofs-5.0.8-dont-clobber-mapent-for-negative-cache.patch new file mode 100644 index 0000000..b38fdf0 --- /dev/null +++ b/SOURCES/autofs-5.0.8-dont-clobber-mapent-for-negative-cache.patch @@ -0,0 +1,343 @@ +autofs-5.0.8 - dont clobber mapent for negative cache + +From: Ian Kent + +When negative caching a map entry on mount fail don't save the mapent +and restore it when the negative cache timeout expires. + +Deleting the mapent, as is done now, can be expensive especially when +it causes a file read for a large file map. +--- + daemon/lookup.c | 6 ++- + include/automount.h | 9 ++++ + lib/cache.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++- + modules/lookup_file.c | 6 ++- + modules/lookup_hosts.c | 10 +++-- + modules/lookup_ldap.c | 6 ++- + modules/lookup_nisplus.c | 10 +++-- + modules/lookup_program.c | 10 +++-- + modules/lookup_sss.c | 6 ++- + modules/lookup_yp.c | 6 ++- + 10 files changed, 135 insertions(+), 19 deletions(-) + +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -860,7 +860,11 @@ static void update_negative_cache(struct + int rv = CHE_FAIL; + + cache_writelock(map->mc); +- rv = cache_update(map->mc, map, name, NULL, now); ++ me = cache_lookup_distinct(map->mc, name); ++ if (me) ++ rv = cache_push_mapent(me, NULL); ++ else ++ rv = cache_update(map->mc, map, name, NULL, now); + if (rv != CHE_FAIL) { + me = cache_lookup_distinct(map->mc, name); + me->status = now + ap->negative_timeout; +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -146,6 +146,12 @@ struct mapent_cache { + struct mapent **hash; + }; + ++struct stack { ++ char *mapent; ++ time_t age; ++ struct stack *next; ++}; ++ + struct mapent { + struct mapent *next; + struct list_head ino_index; +@@ -159,6 +165,7 @@ struct mapent { + struct mapent *parent; + char *key; + char *mapent; ++ struct stack *stack; + time_t age; + /* Time of last mount fail */ + time_t status; +@@ -175,6 +182,8 @@ void cache_readlock(struct mapent_cache + void cache_writelock(struct mapent_cache *mc); + int cache_try_writelock(struct mapent_cache *mc); + void cache_unlock(struct mapent_cache *mc); ++int cache_push_mapent(struct mapent *me, char *mapent); ++int cache_pop_mapent(struct mapent *me); + struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map); + struct mapent_cache *cache_init_null_cache(struct master *master); + int cache_set_ino_index(struct mapent_cache *mc, const char *key, dev_t dev, ino_t ino); +--- autofs-5.0.7.orig/lib/cache.c ++++ autofs-5.0.7/lib/cache.c +@@ -177,6 +177,69 @@ static inline void ino_index_unlock(stru + return; + } + ++/* Save the cache entry mapent field onto a stack and set a new mapent */ ++int cache_push_mapent(struct mapent *me, char *mapent) ++{ ++ struct stack *s; ++ char *new; ++ ++ if (!me->mapent) ++ return CHE_FAIL; ++ ++ if (!mapent) ++ new = NULL; ++ else { ++ new = strdup(mapent); ++ if (!new) ++ return CHE_FAIL; ++ } ++ ++ s = malloc(sizeof(struct stack)); ++ if (!s) { ++ if (new) ++ free(new); ++ return CHE_FAIL; ++ } ++ memset(s, 0, sizeof(*s)); ++ ++ s->mapent = me->mapent; ++ s->age = me->age; ++ me->mapent = mapent; ++ ++ if (me->stack) ++ s->next = me->stack; ++ me->stack = s; ++ ++ return CHE_OK; ++} ++ ++/* Restore cache entry mapent to a previously saved mapent, discard current */ ++int cache_pop_mapent(struct mapent *me) ++{ ++ struct stack *s = me->stack; ++ char *mapent; ++ time_t age; ++ ++ if (!s || !s->mapent) ++ return CHE_FAIL; ++ ++ mapent = s->mapent; ++ age = s->age; ++ me->stack = s->next; ++ free(s); ++ ++ if (age < me->age) { ++ free(mapent); ++ return CHE_OK; ++ } ++ ++ if (me->mapent) ++ free(me->mapent); ++ me->mapent = mapent; ++ ++ return CHE_OK; ++} ++ + struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map) + { + struct mapent_cache *mc; +@@ -578,6 +641,8 @@ int cache_add(struct mapent_cache *mc, s + } else + me->mapent = NULL; + ++ me->stack = NULL; ++ + me->age = age; + me->status = 0; + me->mc = mc; +@@ -689,7 +754,9 @@ void cache_update_negative(struct mapent + int rv = CHE_OK; + + me = cache_lookup_distinct(mc, key); +- if (!me) ++ if (me) ++ rv = cache_push_mapent(me, NULL); ++ else + rv = cache_update(mc, ms, key, NULL, now); + if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, key); +@@ -858,6 +925,7 @@ int cache_delete(struct mapent_cache *mc + pred = me; + me = me->next; + if (strcmp(this, me->key) == 0) { ++ struct stack *s = me->stack; + if (me->multi && !list_empty(&me->multi_list)) { + ret = CHE_FAIL; + goto done; +@@ -872,6 +940,13 @@ int cache_delete(struct mapent_cache *mc + free(me->key); + if (me->mapent) + free(me->mapent); ++ while (s) { ++ struct stack *next = s->next; ++ if (s->mapent) ++ free(s->mapent); ++ free(s); ++ s = next; ++ } + free(me); + me = pred; + } +@@ -882,6 +957,7 @@ int cache_delete(struct mapent_cache *mc + goto done; + + if (strcmp(this, me->key) == 0) { ++ struct stack *s = me->stack; + if (me->multi && !list_empty(&me->multi_list)) { + ret = CHE_FAIL; + goto done; +@@ -896,6 +972,13 @@ int cache_delete(struct mapent_cache *mc + free(me->key); + if (me->mapent) + free(me->mapent); ++ while (s) { ++ struct stack *next = s->next; ++ if (s->mapent) ++ free(s->mapent); ++ free(s); ++ s = next; ++ } + free(me); + } + done: +--- autofs-5.0.7.orig/modules/lookup_file.c ++++ autofs-5.0.7/modules/lookup_file.c +@@ -988,8 +988,10 @@ int lookup_mount(struct autofs_point *ap + cache_writelock(smc); + sme = cache_lookup_distinct(smc, key); + /* Negative timeout expired for non-existent entry. */ +- if (sme && !sme->mapent) +- cache_delete(smc, key); ++ if (sme && !sme->mapent) { ++ if (cache_pop_mapent(sme) == CHE_FAIL) ++ cache_delete(smc, key); ++ } + cache_unlock(smc); + } + } +--- autofs-5.0.7.orig/modules/lookup_hosts.c ++++ autofs-5.0.7/modules/lookup_hosts.c +@@ -155,7 +155,9 @@ static int do_parse_mount(struct autofs_ + + cache_writelock(mc); + me = cache_lookup_distinct(mc, name); +- if (!me) ++ if (me) ++ rv = cache_push_mapent(me, NULL); ++ else + rv = cache_update(mc, source, name, NULL, now); + if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, name); +@@ -315,8 +317,10 @@ int lookup_mount(struct autofs_point *ap + cache_writelock(smc); + sme = cache_lookup_distinct(smc, name); + /* Negative timeout expired for non-existent entry. */ +- if (sme && !sme->mapent) +- cache_delete(smc, name); ++ if (sme && !sme->mapent) { ++ if (cache_pop_mapent(sme) == CHE_FAIL) ++ cache_delete(smc, name); ++ } + cache_unlock(smc); + } + } +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -2937,8 +2937,10 @@ int lookup_mount(struct autofs_point *ap + cache_writelock(smc); + sme = cache_lookup_distinct(smc, key); + /* Negative timeout expired for non-existent entry. */ +- if (sme && !sme->mapent) +- cache_delete(smc, key); ++ if (sme && !sme->mapent) { ++ if (cache_pop_mapent(sme) == CHE_FAIL) ++ cache_delete(smc, key); ++ } + cache_unlock(smc); + } + } +--- autofs-5.0.7.orig/modules/lookup_nisplus.c ++++ autofs-5.0.7/modules/lookup_nisplus.c +@@ -509,8 +509,10 @@ int lookup_mount(struct autofs_point *ap + cache_writelock(smc); + sme = cache_lookup_distinct(smc, key); + /* Negative timeout expired for non-existent entry. */ +- if (sme && !sme->mapent) +- cache_delete(smc, key); ++ if (sme && !sme->mapent) { ++ if (cache_pop_mapent(sme) == CHE_FAIL) ++ cache_delete(smc, key); ++ } + cache_unlock(smc); + } + } +@@ -602,7 +604,9 @@ int lookup_mount(struct autofs_point *ap + return NSS_STATUS_TRYAGAIN; + cache_writelock(mc); + me = cache_lookup_distinct(mc, key); +- if (!me) ++ if (me) ++ rv = cache_push_mapent(me, NULL); ++ else + rv = cache_update(mc, source, key, NULL, now); + if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, key); +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -156,8 +156,10 @@ int lookup_mount(struct autofs_point *ap + cache_writelock(smc); + sme = cache_lookup_distinct(smc, name); + /* Negative timeout expired for non-existent entry. */ +- if (sme && !sme->mapent) +- cache_delete(smc, name); ++ if (sme && !sme->mapent) { ++ if (cache_pop_mapent(sme) == CHE_FAIL) ++ cache_delete(smc, name); ++ } + cache_unlock(smc); + } + } +@@ -451,7 +453,9 @@ out_free: + + cache_writelock(mc); + me = cache_lookup_distinct(mc, name); +- if (!me) ++ if (me) ++ rv = cache_push_mapent(me, NULL); ++ else + rv = cache_update(mc, source, name, NULL, now); + if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, name); +--- autofs-5.0.7.orig/modules/lookup_sss.c ++++ autofs-5.0.7/modules/lookup_sss.c +@@ -599,8 +599,10 @@ int lookup_mount(struct autofs_point *ap + cache_writelock(smc); + sme = cache_lookup_distinct(smc, key); + /* Negative timeout expired for non-existent entry. */ +- if (sme && !sme->mapent) +- cache_delete(smc, key); ++ if (sme && !sme->mapent) { ++ if (cache_pop_mapent(sme) == CHE_FAIL) ++ cache_delete(smc, key); ++ } + cache_unlock(smc); + } + } +--- autofs-5.0.7.orig/modules/lookup_yp.c ++++ autofs-5.0.7/modules/lookup_yp.c +@@ -613,8 +613,10 @@ int lookup_mount(struct autofs_point *ap + cache_writelock(smc); + sme = cache_lookup_distinct(smc, key); + /* Negative timeout expired for non-existent entry. */ +- if (sme && !sme->mapent) +- cache_delete(smc, key); ++ if (sme && !sme->mapent) { ++ if (cache_pop_mapent(sme) == CHE_FAIL) ++ cache_delete(smc, key); ++ } + cache_unlock(smc); + } + } diff --git a/SOURCES/autofs-5.0.8-dont-ignore-null-cache-entries-on-multi-mount-umount.patch b/SOURCES/autofs-5.0.8-dont-ignore-null-cache-entries-on-multi-mount-umount.patch new file mode 100644 index 0000000..0a36a2a --- /dev/null +++ b/SOURCES/autofs-5.0.8-dont-ignore-null-cache-entries-on-multi-mount-umount.patch @@ -0,0 +1,47 @@ +autofs-5.0.8 - dont ignore null cache entries on multi mount umount + +From: Ian Kent + +When umounting the offsets of a multi-mount negative cache entries +shouldn't be ignored. Even if the mount they correspond to failed to +mount the trigger still needs to be umounted. + +Not ignoring negative entries when cleaning stale multi-mount entries +isn't obviously the right thing to do but, since the multi-mount entry +should have been refreshed, there shouldn't be any valid negative entries +so they must be stale and need to go. +--- + CHANGELOG | 1 + + lib/mounts.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -97,6 +97,7 @@ + - fix map source with type lookup. + - fix fix map source with type lookup. + - fix lookup_nss_mount() map lookup. ++- dont ignore null cache entries on multi mount umount. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -1804,7 +1804,7 @@ int umount_multi_triggers(struct autofs_ + + oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); + /* root offset is a special case */ +- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) ++ if (!oe || (strlen(oe->key) - start) == 1) + continue; + + /* +@@ -1926,7 +1926,7 @@ int clean_stale_multi_triggers(struct au + + oe = cache_lookup_offset(mm_base, offset, start, &me->multi_list); + /* root offset is a special case */ +- if (!oe || !oe->mapent || (strlen(oe->key) - start) == 1) ++ if (!oe || (strlen(oe->key) - start) == 1) + continue; + + /* Check for and umount stale subtree offsets */ diff --git a/SOURCES/autofs-5.0.8-extend-libldap-serialization.patch b/SOURCES/autofs-5.0.8-extend-libldap-serialization.patch new file mode 100644 index 0000000..52ee891 --- /dev/null +++ b/SOURCES/autofs-5.0.8-extend-libldap-serialization.patch @@ -0,0 +1,71 @@ +autofs-5.0.8 - extend libldap serialization + +From: Leonardo Chiquitto + +It's necessary to serialize calls to ldap_unbind() as well as the +initial bind. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 20 ++++++++++++++++---- + 2 files changed, 17 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -107,6 +107,7 @@ + - use open(2) instead of access(2) to trigger dependent mounts. + - fix crash due to thread unsafe use of libldap. + - fix deadlock in init_ldap_connection. ++- extend fix for crash due to thread unsafe use of libldap. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -53,8 +53,9 @@ static struct ldap_schema common_schema[ + static unsigned int common_schema_count = sizeof(common_schema)/sizeof(struct ldap_schema); + + /* +- * Initialization of LDAP and OpenSSL must be always serialized to +- * avoid corruption of context structures inside these libraries. ++ * Initialization and de-initialization of LDAP and OpenSSL must be ++ * always serialized to avoid corruption of context structures inside ++ * these libraries. + */ + pthread_mutex_t ldapinit_mutex = PTHREAD_MUTEX_INITIALIZER; + +@@ -203,7 +204,7 @@ int bind_ldap_simple(unsigned logopt, LD + return 0; + } + +-int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + { + int rv; + +@@ -220,6 +221,17 @@ int unbind_ldap_connection(unsigned logo + return rv; + } + ++int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++{ ++ int rv; ++ ++ ldapinit_mutex_lock(); ++ rv = __unbind_ldap_connection(logopt, ldap, ctxt); ++ ldapinit_mutex_unlock(); ++ ++ return rv; ++} ++ + LDAP *__init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt) + { + LDAP *ldap = NULL; +@@ -280,7 +292,7 @@ LDAP *__init_ldap_connection(unsigned lo + + rv = ldap_start_tls_s(ldap, NULL, NULL); + if (rv != LDAP_SUCCESS) { +- unbind_ldap_connection(logopt, ldap, ctxt); ++ __unbind_ldap_connection(logopt, ldap, ctxt); + if (ctxt->tls_required) { + error(logopt, MODPREFIX + "TLS required but START_TLS failed: %s", diff --git a/SOURCES/autofs-5.0.8-fix-append-options-description-in-README_v5-release.patch b/SOURCES/autofs-5.0.8-fix-append-options-description-in-README_v5-release.patch new file mode 100644 index 0000000..5f40a4d --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-append-options-description-in-README_v5-release.patch @@ -0,0 +1,37 @@ +autofs-5.0.8 - fix incorrect append options description in README.v5-release + +From: Ian Kent + +The statement about options not being appended by default isn't correct +any more. +--- + CHANGELOG | 1 + + README.v5.release | 7 ++++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -102,6 +102,7 @@ + - simple coverity fixes. + - fixes for samples/auto.master. + - fix variable substitution description. ++- fix incorrect append options description in README.v5-release. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/README.v5.release ++++ autofs-5.0.7/README.v5.release +@@ -27,9 +27,10 @@ Differences between version 4 and versio + - `autofs' version 5.0.0 will refuse to run if it cannot find an + autofs4 kernel module that supports protocol version 5.00 or above. + +-- mount options present in the master map are now overridden by mount +- options in map entries instead of being accumulated. This behaviour +- is in line with other industry automount implementations. ++- mount options present in the master map are accumulated by default ++ which is different to the behavior of some other autofs ++ implementations. A configuration option is available to change this ++ behavior if required. + + New in 5.0.0 is: + diff --git a/SOURCES/autofs-5.0.8-fix-cache-readlock-not-taken-on-lookup.patch b/SOURCES/autofs-5.0.8-fix-cache-readlock-not-taken-on-lookup.patch new file mode 100644 index 0000000..d38258d --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-cache-readlock-not-taken-on-lookup.patch @@ -0,0 +1,38 @@ +autofs-5.0.8 - fix cache readlock not taken on lookup + +From: Ian Kent + +In modules/lookup_yp.c:check_map_indirect() there's a missing cache +readlock. +--- + CHANGELOG | 1 + + modules/lookup_yp.c | 6 +++++- + 2 files changed, 6 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -81,6 +81,7 @@ + - fix symlink fail message in mount_bind.c. + - add std vars to program map invocation. + - check for existing offset mount before mounting. ++- fix cache readlock not taken on lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_yp.c ++++ autofs-5.0.7/modules/lookup_yp.c +@@ -517,9 +517,13 @@ static int check_map_indirect(struct aut + * If the server is down and the entry exists in the cache + * and belongs to this map return success and use the entry. + */ ++ cache_readlock(mc); + exists = cache_lookup(mc, key); +- if (exists && exists->source == source) ++ if (exists && exists->source == source) { ++ cache_unlock(mc); + return NSS_STATUS_SUCCESS; ++ } ++ cache_unlock(mc); + + warn(ap->logopt, + MODPREFIX "lookup for %s failed: %s", diff --git a/SOURCES/autofs-5.0.8-fix-deadlock-in-init-ldap-connection.patch b/SOURCES/autofs-5.0.8-fix-deadlock-in-init-ldap-connection.patch new file mode 100644 index 0000000..835768d --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-deadlock-in-init-ldap-connection.patch @@ -0,0 +1,35 @@ +Fix deadlock in init_ldap_connection() + +From: Leonardo Chiquitto + +Commit 9fc20db13 ("fix crash due to thread unsafe use of libldap") +introduced a deadlock in init_ldap_connection(). When TLS is on, +this function will call itself recursively and try to lock a mutex +that's already owned by the thread. Fix the problem by using the +lockless version. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -106,6 +106,7 @@ + - fix mistake in assignment. + - use open(2) instead of access(2) to trigger dependent mounts. + - fix crash due to thread unsafe use of libldap. ++- fix deadlock in init_ldap_connection. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -288,7 +288,7 @@ LDAP *__init_ldap_connection(unsigned lo + return NULL; + } + ctxt->use_tls = LDAP_TLS_DONT_USE; +- ldap = init_ldap_connection(logopt, uri, ctxt); ++ ldap = __init_ldap_connection(logopt, uri, ctxt); + if (ldap) + ctxt->use_tls = LDAP_TLS_INIT; + return ldap; diff --git a/SOURCES/autofs-5.0.8-fix-external-env-configure.patch b/SOURCES/autofs-5.0.8-fix-external-env-configure.patch new file mode 100644 index 0000000..0d77d21 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-external-env-configure.patch @@ -0,0 +1,45 @@ +autofs-5.0.8 - fix external env configure + +From: Ian Kent + +Macro lookup can also resolve names in the external environment. +The configure script disables this by default but the configure +help implies it is enabled by default. +--- + CHANGELOG | 1 + + configure | 2 +- + configure.in | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -92,6 +92,7 @@ + - fix macro_addvar() and move init to main thread. + - change walk_tree() to take ap. + - add negative cache lookup to hesiod lookup. ++- fix external env configure. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/configure ++++ autofs-5.0.7/configure +@@ -5608,7 +5608,7 @@ else + enableval=yes + fi + +-if test x$enable_ext_env = xyes; then ++if test x$enable_ext_env = xyes -o x$enableval = xyes; then + + $as_echo "#define ENABLE_EXT_ENV 1" >>confdefs.h + +--- autofs-5.0.7.orig/configure.in ++++ autofs-5.0.7/configure.in +@@ -346,7 +346,7 @@ AC_SUBST(DAEMON_LDFLAGS) + AC_ARG_ENABLE(ext-env, + [ --disable-ext-env disable search in environment for substitution variable],, + enableval=yes) +-if test x$enable_ext_env = xyes; then ++if test x$enable_ext_env = xyes -o x$enableval = xyes; then + AC_DEFINE(ENABLE_EXT_ENV, 1, [leave this alone]) + fi + diff --git a/SOURCES/autofs-5.0.8-fix-fix-ipv6-libtirpc-getport.patch b/SOURCES/autofs-5.0.8-fix-fix-ipv6-libtirpc-getport.patch new file mode 100644 index 0000000..da17cd8 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-fix-ipv6-libtirpc-getport.patch @@ -0,0 +1,43 @@ +autofs-5.0.8 - fix fix ipv6 libtirpc getport + +From: Ian Kent + +Remove a duplicated case entry and remove redundant check, since it +can never be reached, in rpc_rpcb_getport(). +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 6 +----- + 2 files changed, 2 insertions(+), 5 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -66,6 +66,7 @@ + - only probe specific nfs version if requested. + - fix ipv6 libtirpc getport. + - improve timeout option description. ++- fix fix ipv6 libtirpc getport. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/rpc_subs.c ++++ autofs-5.0.7/lib/rpc_subs.c +@@ -524,7 +524,6 @@ static enum clnt_stat rpc_rpcb_getport(C + if (rpcerr.re_vers.low > RPCBVERS4) + return status; + continue; +- case RPC_PROCUNAVAIL: + case RPC_PROGUNAVAIL: + continue; + default: +@@ -533,10 +532,7 @@ static enum clnt_stat rpc_rpcb_getport(C + } + } + +- if (s_port == 0) +- return RPC_PROGNOTREGISTERED; +- +- return RPC_PROCUNAVAIL; ++ return RPC_PROGNOTREGISTERED; + } + + static enum clnt_stat rpc_getport(struct conn_info *info, diff --git a/SOURCES/autofs-5.0.8-fix-fix-map-source-with-type-lookup.patch b/SOURCES/autofs-5.0.8-fix-fix-map-source-with-type-lookup.patch new file mode 100644 index 0000000..bf80577 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-fix-map-source-with-type-lookup.patch @@ -0,0 +1,51 @@ +autofs-5.0.8 - fix fix map source with type lookup + +From: Ian Kent + +The recent change to make autofs look in the defined map directory +for map source file (or nss source files) when the map doesn't start +with a "/" broke the internal hosts map (thanks for alerting me to +this Leonardo). +--- + CHANGELOG | 1 + + daemon/lookup.c | 10 ++++++++-- + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -95,6 +95,7 @@ + - fix external env configure. + - make autofs(5) consistent with auto.master(5). + - fix map source with type lookup. ++- fix fix map source with type lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -418,8 +418,11 @@ static int lookup_map_read_map(struct au + { + char *path; + +- if (!map->argv[0]) ++ if (!map->argv[0]) { ++ if (!strcmp(map->type, "hosts")) ++ return do_read_map(ap, map, age); + return NSS_STATUS_UNKNOWN; ++ } + + /* + * This is only called when map->type != NULL. +@@ -817,8 +820,11 @@ static int do_name_lookup_mount(struct a + { + char *path; + +- if (!map->argv[0]) ++ if (!map->argv[0]) { ++ if (!strcmp(map->type, "hosts")) ++ return do_lookup_mount(ap, map, name, name_len); + return NSS_STATUS_UNKNOWN; ++ } + + /* + * This is only called when map->type != NULL. diff --git a/SOURCES/autofs-5.0.8-fix-fix-options-compare.patch b/SOURCES/autofs-5.0.8-fix-fix-options-compare.patch new file mode 100644 index 0000000..1c7c1ba --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-fix-options-compare.patch @@ -0,0 +1,37 @@ +autofs-5.0.8 - fix fix options compare + +From: Ian Kent + +The change to fix the mount options compare replaced the strncmp() +function used to compare substrings of options with an internal +function that also used the passed in length for the compare. + +But the case of a passed in length of 0 was not handled and for +that case the function returned a value different to strncmp() +and code that relied on that behaviour n longer behaves as expected. +--- + CHANGELOG | 1 + + lib/cat_path.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -74,6 +74,7 @@ + - fix fix negative status being reset on map read. + - check for non existent negative entries in lookup_ghost(). + - fix options compare. ++- fix fix options compare. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/cat_path.c ++++ autofs-5.0.7/lib/cat_path.c +@@ -92,7 +92,7 @@ int _strncmp(const char *s1, const char + { + size_t len = strlen(s1); + +- if (n != len) ++ if (n && n != len) + return n - len; + return strncmp(s1, s2, n); + } diff --git a/SOURCES/autofs-5.0.8-fix-inconsistent-error-returns-in-handle_packet_missing_direct.patch b/SOURCES/autofs-5.0.8-fix-inconsistent-error-returns-in-handle_packet_missing_direct.patch new file mode 100644 index 0000000..cc5cab4 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-inconsistent-error-returns-in-handle_packet_missing_direct.patch @@ -0,0 +1,68 @@ +autofs-5.0.8 - fix inconsistent error returns in handle_packet_missing_direct() + +From: Ian Kent + +How to handle mount requests that arrive during a shutdown is a big +problem. + +Currently common cases result in the requesting process being sent a +fail status and success being returned to the calling autofs process. + +There are a number of places where a fail is returned to the calling +process (such as memeory allocation errors) which should cause the +daemon to exit. But when a request arrives during a shutdown the +daemon is usually not ready to shutdown and instead performs recovery +and returns to a ready state instead of shutting down. + +There were a few places in handle_packet_missing_direct() where a fail +was being returned when a success should have been returned which was +preventing the completion of the shutdown. + +This is not ideal because during a restart of the daemon processes +requesting a mount could receive a mount failure. But this has been +the policy for while now and it's very difficult to do in a different +way. +--- + CHANGELOG | 1 + + daemon/direct.c | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -98,6 +98,7 @@ + - fix fix map source with type lookup. + - fix lookup_nss_mount() map lookup. + - dont ignore null cache entries on multi mount umount. ++- fix inconsistent error returns in handle_packet_missing_direct(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -1384,7 +1384,7 @@ int handle_packet_missing_direct(struct + master_source_unlock(ap->entry); + master_mutex_unlock(); + pthread_setcancelstate(state, NULL); +- return 1; ++ return 0; + } + + /* Check if we recorded a mount fail for this key */ +@@ -1409,7 +1409,7 @@ int handle_packet_missing_direct(struct + master_source_unlock(ap->entry); + master_mutex_unlock(); + pthread_setcancelstate(state, NULL); +- return 1; ++ return 0; + } + + mt = malloc(sizeof(struct pending_args)); +@@ -1423,7 +1423,7 @@ int handle_packet_missing_direct(struct + master_source_unlock(ap->entry); + master_mutex_unlock(); + pthread_setcancelstate(state, NULL); +- return 1; ++ return 0; + } + memset(mt, 0, sizeof(struct pending_args)); + diff --git a/SOURCES/autofs-5.0.8-fix-ipv6-libtirpc-getport-proto-not-set.patch b/SOURCES/autofs-5.0.8-fix-ipv6-libtirpc-getport-proto-not-set.patch new file mode 100644 index 0000000..0b79b44 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-ipv6-libtirpc-getport-proto-not-set.patch @@ -0,0 +1,41 @@ +autofs-5.0.8 - fix rpc_portmap_getport() proto not set + +From: Ian Kent + +Recent changes to fix libtirpc usage problems when getting a server +exports list cause later server probing to fail. + +When getting an exports list a new rpc client is always created for +the query, which includes setting the protocol in the parameters +structure. But when probing availability the client is reused where +possible and the protocol is not set in the parameters structure in +this case. + +The rpc_portmap_getport() changes require that the protocol is set +in oder to function. +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 2 ++ + 2 files changed, 3 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -68,6 +68,7 @@ + - improve timeout option description. + - fix fix ipv6 libtirpc getport. + - get_nfs_info() should query portmapper if port is not given. ++- fix rpc_portmap_getport() proto not set. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/rpc_subs.c ++++ autofs-5.0.7/lib/rpc_subs.c +@@ -877,6 +877,8 @@ int rpc_portmap_getport(struct conn_info + + memset(&pmap_info, 0, sizeof(struct conn_info)); + ++ pmap_info.proto = proto; ++ + if (proto == IPPROTO_TCP) + pmap_info.timeout.tv_sec = PMAP_TOUT_TCP; + else diff --git a/SOURCES/autofs-5.0.8-fix-ipv6-libtirpc-getport.patch b/SOURCES/autofs-5.0.8-fix-ipv6-libtirpc-getport.patch new file mode 100644 index 0000000..96c5634 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-ipv6-libtirpc-getport.patch @@ -0,0 +1,341 @@ +autofs-5.0.8 - fix ipv6 libtirpc getport + +From: Ian Kent + +The method that was being used to obtain a service port number +when using libtirpc was wrong. +--- + CHANGELOG | 1 + lib/rpc_subs.c | 283 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 267 insertions(+), 17 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -64,6 +64,7 @@ + - fix get_nfs_info() probe. + - fix portmap lookup. + - only probe specific nfs version if requested. ++- fix ipv6 libtirpc getport. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/rpc_subs.c ++++ autofs-5.0.7/lib/rpc_subs.c +@@ -234,6 +234,28 @@ static int rpc_do_create_client(struct s + + return 0; + } ++static int rpc_getport(struct conn_info *info, ++ struct pmap *parms, CLIENT *client) ++{ ++ enum clnt_stat status; ++ ++ /* ++ * Check to see if server is up otherwise a getport will take ++ * forever to timeout. ++ */ ++ status = clnt_call(client, PMAPPROC_NULL, ++ (xdrproc_t) xdr_void, 0, (xdrproc_t) xdr_void, 0, ++ info->timeout); ++ ++ if (status == RPC_SUCCESS) { ++ status = clnt_call(client, PMAPPROC_GETPORT, ++ (xdrproc_t) xdr_pmap, (caddr_t) parms, ++ (xdrproc_t) xdr_u_short, (caddr_t) port, ++ info->timeout); ++ } ++ ++ return status; ++} + #else + static int rpc_do_create_client(struct sockaddr *addr, struct conn_info *info, int *fd, CLIENT **client) + { +@@ -267,9 +289,6 @@ static int rpc_do_create_client(struct s + laddr = (struct sockaddr *) &in4_laddr; + in4_raddr->sin_port = htons(info->port); + slen = sizeof(struct sockaddr_in); +- /* Use rpcbind v2 for AF_INET */ +- if (info->program == rpcb_prog) +- info->version = PMAPVERS; + } else if (addr->sa_family == AF_INET6) { + struct sockaddr_in6 *in6_raddr = (struct sockaddr_in6 *) addr; + in6_laddr.sin6_family = AF_INET6; +@@ -324,6 +343,244 @@ static int rpc_do_create_client(struct s + + return 0; + } ++ ++/* ++ * Thankfully nfs-utils had already dealt with this. ++ * Thanks to Chuck Lever for his nfs-utils patch series, much of ++ * which is used here. ++ */ ++static pthread_mutex_t proto_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++static enum clnt_stat rpc_get_netid(const sa_family_t family, ++ const int protocol, char **netid) ++{ ++ char *nc_protofmly, *nc_proto, *nc_netid; ++ struct netconfig *nconf; ++ struct protoent *proto; ++ void *handle; ++ ++ switch (family) { ++ case AF_LOCAL: ++ case AF_INET: ++ nc_protofmly = NC_INET; ++ break; ++ case AF_INET6: ++ nc_protofmly = NC_INET6; ++ break; ++ default: ++ return RPC_UNKNOWNPROTO; ++ } ++ ++ pthread_mutex_lock(&proto_mutex); ++ proto = getprotobynumber(protocol); ++ if (!proto) { ++ pthread_mutex_unlock(&proto_mutex); ++ return RPC_UNKNOWNPROTO; ++ } ++ nc_proto = strdup(proto->p_name); ++ pthread_mutex_unlock(&proto_mutex); ++ if (!nc_proto) ++ return RPC_SYSTEMERROR; ++ ++ handle = setnetconfig(); ++ while ((nconf = getnetconfig(handle)) != NULL) { ++ if (nconf->nc_protofmly != NULL && ++ strcmp(nconf->nc_protofmly, nc_protofmly) != 0) ++ continue; ++ if (nconf->nc_proto != NULL && ++ strcmp(nconf->nc_proto, nc_proto) != 0) ++ continue; ++ ++ nc_netid = strdup(nconf->nc_netid); ++ if (!nc_netid) { ++ free(nc_proto); ++ return RPC_SYSTEMERROR; ++ } ++ ++ *netid = nc_netid; ++ } ++ endnetconfig(handle); ++ free(nc_proto); ++ ++ return RPC_SUCCESS; ++} ++ ++static char *rpc_sockaddr2universal(const struct sockaddr *addr) ++{ ++ const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *) addr; ++ const struct sockaddr_un *sun = (const struct sockaddr_un *) addr; ++ const struct sockaddr_in *sin = (const struct sockaddr_in *) addr; ++ char buf[INET6_ADDRSTRLEN + 8 /* for port information */]; ++ uint16_t port; ++ size_t count; ++ char *result; ++ int len; ++ ++ switch (addr->sa_family) { ++ case AF_LOCAL: ++ return strndup(sun->sun_path, sizeof(sun->sun_path)); ++ case AF_INET: ++ if (inet_ntop(AF_INET, (const void *)&sin->sin_addr.s_addr, ++ buf, (socklen_t)sizeof(buf)) == NULL) ++ goto out_err; ++ port = ntohs(sin->sin_port); ++ break; ++ case AF_INET6: ++ if (inet_ntop(AF_INET6, (const void *)&sin6->sin6_addr, ++ buf, (socklen_t)sizeof(buf)) == NULL) ++ goto out_err; ++ port = ntohs(sin6->sin6_port); ++ break; ++ default: ++ goto out_err; ++ } ++ ++ count = sizeof(buf) - strlen(buf); ++ len = snprintf(buf + strlen(buf), count, ".%u.%u", ++ (unsigned)(port >> 8), (unsigned)(port & 0xff)); ++ /* before glibc 2.0.6, snprintf(3) could return -1 */ ++ if (len < 0 || (size_t)len > count) ++ goto out_err; ++ ++ result = strdup(buf); ++ return result; ++ ++out_err: ++ return NULL; ++} ++ ++static int rpc_universal2port(const char *uaddr) ++{ ++ char *addrstr; ++ char *p, *endptr; ++ unsigned long portlo, porthi; ++ int port = -1; ++ ++ addrstr = strdup(uaddr); ++ if (!addrstr) ++ return -1; ++ ++ p = strrchr(addrstr, '.'); ++ if (!p) ++ goto out; ++ ++ portlo = strtoul(p + 1, &endptr, 10); ++ if (*endptr != '\0' || portlo > 255) ++ goto out; ++ *p = '\0'; ++ ++ p = strrchr(addrstr, '.'); ++ if (!p) ++ goto out; ++ ++ porthi = strtoul(p + 1, &endptr, 10); ++ if (*endptr != '\0' || porthi > 255) ++ goto out; ++ *p = '\0'; ++ ++ port = (porthi << 8) | portlo; ++ ++out: ++ free(addrstr); ++ return port; ++} ++ ++static enum clnt_stat rpc_rpcb_getport(CLIENT *client, ++ struct rpcb *parms, ++ struct timeval timeout, ++ unsigned short *port) ++{ ++ rpcvers_t rpcb_version; ++ struct rpc_err rpcerr; ++ int s_port = 0; ++ ++ for (rpcb_version = RPCBVERS_4; ++ rpcb_version >= RPCBVERS_3; ++ rpcb_version--) { ++ enum clnt_stat status; ++ char *uaddr = NULL; ++ ++ CLNT_CONTROL(client, CLSET_VERS, (void *) &rpcb_version); ++ status = CLNT_CALL(client, (rpcproc_t) RPCBPROC_GETADDR, ++ (xdrproc_t) xdr_rpcb, (void *) parms, ++ (xdrproc_t) xdr_wrapstring, (void *) &uaddr, ++ timeout); ++ ++ switch (status) { ++ case RPC_SUCCESS: ++ if ((uaddr == NULL) || (uaddr[0] == '\0')) ++ return RPC_PROGNOTREGISTERED; ++ ++ s_port = rpc_universal2port(uaddr); ++ xdr_free((xdrproc_t) xdr_wrapstring, (char *) &uaddr); ++ if (s_port == -1) { ++ return RPC_N2AXLATEFAILURE; ++ } ++ *port = s_port; ++ return RPC_SUCCESS; ++ ++ case RPC_PROGVERSMISMATCH: ++ clnt_geterr(client, &rpcerr); ++ if (rpcerr.re_vers.low > RPCBVERS4) ++ return status; ++ continue; ++ case RPC_PROCUNAVAIL: ++ case RPC_PROGUNAVAIL: ++ continue; ++ default: ++ /* Most likely RPC_TIMEDOUT or RPC_CANTRECV */ ++ return status; ++ } ++ } ++ ++ if (s_port == 0) ++ return RPC_PROGNOTREGISTERED; ++ ++ return RPC_PROCUNAVAIL; ++} ++ ++static enum clnt_stat rpc_getport(struct conn_info *info, ++ struct pmap *parms, CLIENT *client, ++ unsigned short *port) ++{ ++ enum clnt_stat status; ++ struct sockaddr *paddr, addr; ++ struct rpcb rpcb_parms; ++ char *netid, *raddr; ++ ++ if (info->addr) ++ paddr = info->addr; ++ else { ++ if (!clnt_control(client, CLGET_SERVER_ADDR, (char *) &addr)) ++ return RPC_UNKNOWNADDR; ++ paddr = &addr; ++ } ++ ++ netid = NULL; ++ status = rpc_get_netid(paddr->sa_family, info->proto, &netid); ++ if (status != RPC_SUCCESS) ++ return status; ++ ++ raddr = rpc_sockaddr2universal(paddr); ++ if (!raddr) { ++ free(netid); ++ return RPC_UNKNOWNADDR; ++ } ++ ++ memset(&rpcb_parms, 0, sizeof(rpcb_parms)); ++ rpcb_parms.r_prog = parms->pm_prog; ++ rpcb_parms.r_vers = parms->pm_vers; ++ rpcb_parms.r_netid = netid; ++ rpcb_parms.r_addr = raddr; ++ rpcb_parms.r_owner = ""; ++ ++ status = rpc_rpcb_getport(client, &rpcb_parms, info->timeout, port); ++ ++ free(netid); ++ free(raddr); ++ ++ return status; ++} + #endif + + #if defined(HAVE_GETRPCBYNAME) || defined(HAVE_GETSERVBYNAME) +@@ -647,20 +904,7 @@ int rpc_portmap_getport(struct conn_info + return ret; + } + +- /* +- * Check to see if server is up otherwise a getport will take +- * forever to timeout. +- */ +- status = clnt_call(client, PMAPPROC_NULL, +- (xdrproc_t) xdr_void, 0, (xdrproc_t) xdr_void, 0, +- pmap_info.timeout); +- +- if (status == RPC_SUCCESS) { +- status = clnt_call(client, PMAPPROC_GETPORT, +- (xdrproc_t) xdr_pmap, (caddr_t) parms, +- (xdrproc_t) xdr_u_short, (caddr_t) port, +- pmap_info.timeout); +- } ++ status = rpc_getport(&pmap_info, parms, client, port); + + if (!info->client) { + /* +@@ -867,6 +1111,11 @@ static int rpc_get_exports_proto(struct + clnt_control(client, CLSET_RETRY_TIMEOUT, (char *) &info->timeout); + + client->cl_auth = authunix_create_default(); ++ if (client->cl_auth == NULL) { ++ error(LOGOPT_ANY, "auth create failed"); ++ clnt_destroy(client); ++ return 0; ++ } + + vers_entry = 0; + while (1) { diff --git a/SOURCES/autofs-5.0.8-fix-ipv6-link-local-address-handling.patch b/SOURCES/autofs-5.0.8-fix-ipv6-link-local-address-handling.patch new file mode 100644 index 0000000..3ca8439 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-ipv6-link-local-address-handling.patch @@ -0,0 +1,37 @@ +autofs-5.0.8 - fix ipv6 link local address handling + +From: Ian Kent + +Stop the validate_location() function from choking on link local +ipv6 addresses. +--- + lib/rpc_subs.c | 6 ++++++ + modules/parse_sun.c | 2 +- + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/lib/rpc_subs.c ++++ autofs-5.0.7/lib/rpc_subs.c +@@ -669,6 +669,12 @@ static int create_client(struct conn_inf + goto done; + if (ret == -EHOSTUNREACH) + goto out_close; ++ if (ret == -EINVAL) { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(-ret, buf, MAX_ERR_BUF); ++ error(LOGOPT_ANY, "connect() failed: %s", estr); ++ goto out_close; ++ } + + if (!info->client && fd != RPC_ANYSOCK) { + close(fd); +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -893,7 +893,7 @@ static int validate_location(unsigned in + *ptr == '-' || *ptr == '.' || *ptr == '_' || + *ptr == ',' || *ptr == '(' || *ptr == ')' || + *ptr == '#' || *ptr == '@' || *ptr == ':' || +- *ptr == '[' || *ptr == ']')) { ++ *ptr == '[' || *ptr == ']' || *ptr == '%')) { + error(logopt, "invalid character \"%c\" " + "found in location %s", *ptr, loc); + return 0; diff --git a/SOURCES/autofs-5.0.8-fix-lookup_nss_mount-map-lookup.patch b/SOURCES/autofs-5.0.8-fix-lookup_nss_mount-map-lookup.patch new file mode 100644 index 0000000..c4e7d6d --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-lookup_nss_mount-map-lookup.patch @@ -0,0 +1,38 @@ +autofs-5.0.8 - fix lookup_nss_mount() map lookup + +From: Ian Kent + +A mount that may have multiple maps (direct mounts) should try each +source and if nsswicth is used then each instance should be tried +before moving to the next map. + +Moving to the next map if an nss instance is not found makes no sense. +--- + CHANGELOG | 1 + + daemon/lookup.c | 4 +--- + 2 files changed, 2 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -96,6 +96,7 @@ + - make autofs(5) consistent with auto.master(5). + - fix map source with type lookup. + - fix fix map source with type lookup. ++- fix lookup_nss_mount() map lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -1045,10 +1045,8 @@ int lookup_nss_mount(struct autofs_point + + result = lookup_map_name(this, ap, map, name, name_len); + +- if (result == NSS_STATUS_UNKNOWN) { +- map = map->next; ++ if (result == NSS_STATUS_UNKNOWN) + continue; +- } + + status = check_nss_result(this, result); + if (status >= 0) { diff --git a/SOURCES/autofs-5.0.8-fix-macro_addvar-and-move-init-to-main-thread.patch b/SOURCES/autofs-5.0.8-fix-macro_addvar-and-move-init-to-main-thread.patch new file mode 100644 index 0000000..5fa3e4c --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-macro_addvar-and-move-init-to-main-thread.patch @@ -0,0 +1,242 @@ +autofs-5.0.8 - fix macro_addvar() and move init to main thread + +From: Ian Kent + +- move macro table initialization to the main thread. +- change to using malloc() instead of realloc() in macro_global_addvar() + and macro_addvar(). +- fix possible incorrect return from macro_addvar(). +--- + CHANGELOG | 1 + + daemon/automount.c | 16 ++++++++++++++++ + lib/macros.c | 25 ++++++++++++++++++++----- + modules/parse_sun.c | 9 --------- + 4 files changed, 37 insertions(+), 14 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -89,6 +89,7 @@ + - fix symlink expire. + - fix master map type check. + - fix bad mkdir permission on create. ++- fix macro_addvar() and move init to main thread. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -2129,6 +2129,9 @@ int main(int argc, char *argv[]) + program); + #endif + ++ /* Get processor information for predefined escapes */ ++ macro_init(); ++ + if (dumpmaps) { + struct master_mapent *entry; + struct list_head *head, *p; +@@ -2152,6 +2155,7 @@ int main(int argc, char *argv[]) + master_list = master_new(master, timeout, ghost); + if (!master_list) { + printf("%s: can't create master map", program); ++ macro_free_global_table(); + exit(1); + } + +@@ -2163,6 +2167,7 @@ int main(int argc, char *argv[]) + if (!nc) { + printf("%s: failed to init null map cache for %s", + program, master_list->name); ++ macro_free_global_table(); + exit(1); + } + master_list->nc = nc; +@@ -2187,6 +2192,7 @@ int main(int argc, char *argv[]) + master_free_mapent(entry); + } + master_kill(master_list); ++ macro_free_global_table(); + + exit(0); + } +@@ -2198,6 +2204,7 @@ int main(int argc, char *argv[]) + + if (!master_list) { + printf("%s: can't create master map %s", program, argv[0]); ++ macro_free_global_table(); + exit(1); + } + +@@ -2209,6 +2216,7 @@ int main(int argc, char *argv[]) + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); ++ macro_free_global_table(); + exit(1); + } + +@@ -2218,6 +2226,7 @@ int main(int argc, char *argv[]) + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); ++ macro_free_global_table(); + exit(1); + } + +@@ -2228,6 +2237,7 @@ int main(int argc, char *argv[]) + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); ++ macro_free_global_table(); + exit(1); + } + +@@ -2239,6 +2249,7 @@ int main(int argc, char *argv[]) + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); ++ macro_free_global_table(); + exit(1); + } + #endif +@@ -2257,6 +2268,7 @@ int main(int argc, char *argv[]) + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); ++ macro_free_global_table(); + exit(1); + } + +@@ -2268,6 +2280,7 @@ int main(int argc, char *argv[]) + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); ++ macro_free_global_table(); + exit(1); + } + +@@ -2277,6 +2290,7 @@ int main(int argc, char *argv[]) + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); ++ macro_free_global_table(); + exit(1); + } + +@@ -2299,6 +2313,7 @@ int main(int argc, char *argv[]) + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); ++ macro_free_global_table(); + exit(3); + } + +@@ -2323,6 +2338,7 @@ int main(int argc, char *argv[]) + } + closelog(); + release_flag_file(); ++ macro_free_global_table(); + + #ifdef TIRPC_WORKAROUND + if (dh_tirpc) +--- autofs-5.0.7.orig/lib/macros.c ++++ autofs-5.0.7/lib/macros.c +@@ -35,6 +35,7 @@ static struct substvar + }; + + static struct substvar *system_table = &sv_osvers; ++static unsigned int macro_init_done = 0; + + static pthread_mutex_t table_mutex = PTHREAD_MUTEX_INITIALIZER; + static pthread_mutex_t macro_mutex = PTHREAD_MUTEX_INITIALIZER; +@@ -62,6 +63,12 @@ void dump_table(struct substvar *table) + /* Get processor information for predefined macro definitions */ + void macro_init(void) + { ++ macro_lock(); ++ if (macro_init_done) { ++ macro_unlock(); ++ return; ++ } ++ + uname(&un); + /* + * uname -p is not defined on Linux. Make it the same as +@@ -71,6 +78,10 @@ void macro_init(void) + if (processor[0] == 'i' && processor[1] >= '3' && + !strcmp(processor + 2, "86")) + processor[1] = '3'; ++ ++ macro_init_done = 1; ++ macro_unlock(); ++ return; + } + + int macro_is_systemvar(const char *str, int len) +@@ -118,10 +129,11 @@ int macro_global_addvar(const char *str, + } + + if (sv && !sv->readonly) { +- char *this = realloc(sv->val, strlen(value) + 1); ++ char *this = malloc(strlen(value) + 1); + if (!this) + goto done; +- strcat(this, value); ++ strcpy(this, value); ++ free(sv->val); + sv->val = this; + ret = 1; + } else { +@@ -213,13 +225,16 @@ macro_addvar(struct substvar *table, con + } + + if (lv) { +- char *this = realloc(lv->val, strlen(value) + 1); ++ char *this = malloc(strlen(value) + 1); + if (!this) { + lv = table; + goto done; + } +- strcat(this, value); ++ strcpy(this, value); ++ free(lv->val); + lv->val = this; ++ if (lv != table) ++ lv = table; + } else { + struct substvar *new; + char *def, *val; +@@ -413,7 +428,7 @@ macro_findvar(const struct substvar *tab + etmp[len]='\0'; + + if ((value=getenv(etmp)) != NULL) { +- lv_var = macro_addvar(table, str, len, value); ++ lv_var = macro_addvar((struct substvar *) table, str, len, value); + return(lv_var); + } + #endif +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -41,7 +41,6 @@ int parse_version = AUTOFS_PARSE_VERSION + + static struct mount_mod *mount_nfs = NULL; + static int init_ctr = 0; +-static int macro_init_done = 0; + static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER; + + static void instance_mutex_lock(void) +@@ -243,14 +242,6 @@ int parse_init(int argc, const char *con + int i, bval; + unsigned int append_options; + +- /* Get processor information for predefined escapes */ +- macro_lock(); +- if (!macro_init_done) { +- macro_init_done = 1; +- macro_init(); +- } +- macro_unlock(); +- + /* Set up context and escape chain */ + + if (!(ctxt = (struct parse_context *) malloc(sizeof(struct parse_context)))) { diff --git a/SOURCES/autofs-5.0.8-fix-map-source-with-type-lookup.patch b/SOURCES/autofs-5.0.8-fix-map-source-with-type-lookup.patch new file mode 100644 index 0000000..6713551 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-map-source-with-type-lookup.patch @@ -0,0 +1,192 @@ +autofs-5.0.8 - fix map source with type lookup + +From: Ian Kent + +If the map source type is specified the map name must be a full +path. + +But we should be able to give a plain map name and expect autofs +to look in the compiled in maps directory. +--- + CHANGELOG | 1 + daemon/lookup.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++------- + 2 files changed, 99 insertions(+), 13 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -94,6 +94,7 @@ + - add negative cache lookup to hesiod lookup. + - fix external env configure. + - make autofs(5) consistent with auto.master(5). ++- fix map source with type lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -100,6 +100,27 @@ static int do_read_master(struct master + return status; + } + ++static char *find_map_path(struct map_source *map) ++{ ++ struct stat st; ++ char *path; ++ ++ path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(map->argv[0]) + 2); ++ if (!path) ++ return NULL; ++ ++ strcpy(path, AUTOFS_MAP_DIR); ++ strcat(path, "/"); ++ strcat(path, map->argv[0]); ++ ++ if (!stat(path, &st)) ++ return path; ++ ++ free(path); ++ ++ return NULL; ++} ++ + static int read_master_map(struct master *master, char *type, time_t age) + { + unsigned int logopt = master->logopt; +@@ -392,6 +413,42 @@ static void argv_cleanup(void *arg) + return; + } + ++static int lookup_map_read_map(struct autofs_point *ap, ++ struct map_source *map, time_t age) ++{ ++ char *path; ++ ++ if (!map->argv[0]) ++ return NSS_STATUS_UNKNOWN; ++ ++ /* ++ * This is only called when map->type != NULL. ++ * We only need to look for a map if source type is ++ * file and the map name doesn't begin with a "/". ++ */ ++ if (strncmp(map->type, "file", 4)) ++ return do_read_map(ap, map, age); ++ ++ if (map->argv[0][0] == '/') ++ return do_read_map(ap, map, age); ++ ++ path = find_map_path(map); ++ if (!path) ++ return NSS_STATUS_UNKNOWN; ++ ++ if (map->argc >= 1) { ++ if (map->argv[0]) ++ free((char *) map->argv[0]); ++ map->argv[0] = path; ++ } else { ++ error(ap->logopt, "invalid arguments for autofs_point"); ++ free(path); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ return do_read_map(ap, map, age); ++} ++ + static enum nsswitch_status read_map_source(struct nss_source *this, + struct autofs_point *ap, struct map_source *map, time_t age) + { +@@ -428,14 +485,10 @@ static enum nsswitch_status read_map_sou + tmap.argc = 0; + tmap.argv = NULL; + +- path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(map->argv[0]) + 2); ++ path = find_map_path(map); + if (!path) + return NSS_STATUS_UNKNOWN; + +- strcpy(path, AUTOFS_MAP_DIR); +- strcat(path, "/"); +- strcat(path, map->argv[0]); +- + if (map->argc >= 1) { + tmap.argc = map->argc; + tmap.argv = copy_argv(map->argc, map->argv); +@@ -496,7 +549,7 @@ int lookup_nss_read_map(struct autofs_po + debug(ap->logopt, + "reading map %s %s", + map->type, map->argv[0]); +- result = do_read_map(ap, map, age); ++ result = lookup_map_read_map(ap, map, age); + map = map->next; + continue; + } +@@ -758,6 +811,43 @@ static int lookup_name_source_instance(s + return do_lookup_mount(ap, instance, name, name_len); + } + ++static int do_name_lookup_mount(struct autofs_point *ap, ++ struct map_source *map, ++ const char *name, int name_len) ++{ ++ char *path; ++ ++ if (!map->argv[0]) ++ return NSS_STATUS_UNKNOWN; ++ ++ /* ++ * This is only called when map->type != NULL. ++ * We only need to look for a map if source type is ++ * file and the map name doesn't begin with a "/". ++ */ ++ if (strncmp(map->type, "file", 4)) ++ return do_lookup_mount(ap, map, name, name_len); ++ ++ if (map->argv[0][0] == '/') ++ return do_lookup_mount(ap, map, name, name_len); ++ ++ path = find_map_path(map); ++ if (!path) ++ return NSS_STATUS_UNKNOWN; ++ ++ if (map->argc >= 1) { ++ if (map->argv[0]) ++ free((char *) map->argv[0]); ++ map->argv[0] = path; ++ } else { ++ error(ap->logopt, "invalid arguments for autofs_point"); ++ free(path); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ return do_lookup_mount(ap, map, name, name_len); ++} ++ + static enum nsswitch_status lookup_map_name(struct nss_source *this, + struct autofs_point *ap, struct map_source *map, + const char *name, int name_len) +@@ -793,14 +883,10 @@ static enum nsswitch_status lookup_map_n + tmap.argc = 0; + tmap.argv = NULL; + +- path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(map->argv[0]) + 2); ++ path = find_map_path(map); + if (!path) + return NSS_STATUS_UNKNOWN; + +- strcpy(path, AUTOFS_MAP_DIR); +- strcat(path, "/"); +- strcat(path, map->argv[0]); +- + if (map->argc >= 1) { + tmap.argc = map->argc; + tmap.argv = copy_argv(map->argc, map->argv); +@@ -909,8 +995,7 @@ int lookup_nss_mount(struct autofs_point + sched_yield(); + + if (map->type) { +- result = do_lookup_mount(ap, map, name, name_len); +- ++ result = do_name_lookup_mount(ap, map, name, name_len); + if (result == NSS_STATUS_SUCCESS) + break; + diff --git a/SOURCES/autofs-5.0.8-fix-master-map-type-check.patch b/SOURCES/autofs-5.0.8-fix-master-map-type-check.patch new file mode 100644 index 0000000..77a9e4b --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-master-map-type-check.patch @@ -0,0 +1,54 @@ +autofs-5.0.8 - fix master map type check + +From: Ian Kent + +Map type has format [,] but the master map type check +for old style map syntax doesn't allow for . +--- + CHANGELOG | 1 + + daemon/lookup.c | 24 ++++++++++++++++-------- + 2 files changed, 17 insertions(+), 8 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -87,6 +87,7 @@ + - pass map_source as function paramter where possible. + - check for bind onto self in mount_bind.c. + - fix symlink expire. ++- fix master map type check. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -171,14 +171,22 @@ int lookup_nss_read_master(struct master + char source[10]; + + memset(source, 0, 10); +- if (!strncmp(name, "file:", 5) || +- !strncmp(name, "yp:", 3) || +- !strncmp(name, "nis:", 4) || +- !strncmp(name, "nisplus:", 8) || +- !strncmp(name, "ldap:", 5) || +- !strncmp(name, "ldaps:", 6) || +- !strncmp(name, "sss:", 4) || +- !strncmp(name, "dir:", 4)) { ++ if ((!strncmp(name, "file", 4) && ++ (name[4] == ',' || name[4] == ':')) || ++ (!strncmp(name, "yp", 3) && ++ (name[3] == ',' || name[3] == ':')) || ++ (!strncmp(name, "nis", 3) && ++ (name[3] == ',' || name[3] == ':')) || ++ (!strncmp(name, "nisplus", 7) && ++ (name[7] == ',' || name[7] == ':')) || ++ (!strncmp(name, "ldap", 4) && ++ (name[4] == ',' || name[4] == ':')) || ++ (!strncmp(name, "ldaps", 5) && ++ (name[5] == ',' || name[5] == ':')) || ++ (!strncmp(name, "sss", 3) || ++ (name[3] == ',' || name[3] == ':')) || ++ (!strncmp(name, "dir", 3) && ++ (name[3] == ',' || name[3] == ':'))) { + strncpy(source, name, tmp - name); + + /* diff --git a/SOURCES/autofs-5.0.8-fix-max-declaration.patch b/SOURCES/autofs-5.0.8-fix-max-declaration.patch new file mode 100644 index 0000000..6b9f41e --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-max-declaration.patch @@ -0,0 +1,42 @@ +autofs-5.0.8 - fix max() declaration + +From: Ian Kent + +Use a name other than the already defined max(). +--- + CHANGELOG | 1 + + modules/replicated.c | 6 +++--- + 2 files changed, 4 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -75,6 +75,7 @@ + - check for non existent negative entries in lookup_ghost(). + - fix options compare. + - fix fix options compare. ++- fix max() declaration. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/replicated.c ++++ autofs-5.0.7/modules/replicated.c +@@ -73,8 +73,8 @@ static int volatile ifc_last_len = 0; + /* Get numeric value of the n bits starting at position p */ + #define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) + +-#define max(x, y) (x >= y ? x : y) +-#define mmax(x, y, z) (max(x, y) == x ? max(x, z) : max(y, z)) ++#define mymax(x, y) (x >= y ? x : y) ++#define mmax(x, y, z) (mymax(x, y) == x ? mymax(x, z) : mymax(y, z)) + + unsigned int ipv6_mask_cmp(uint32_t *host, uint32_t *iface, uint32_t *mask) + { +@@ -961,7 +961,7 @@ int prune_host_list(unsigned logopt, str + + max_tcp_count = mmax(v4_tcp_count, v3_tcp_count, v2_tcp_count); + max_udp_count = mmax(v4_udp_count, v3_udp_count, v2_udp_count); +- max_count = max(max_tcp_count, max_udp_count); ++ max_count = mymax(max_tcp_count, max_udp_count); + + if (max_count == v4_tcp_count) { + selected_version = NFS4_TCP_SUPPORTED; diff --git a/SOURCES/autofs-5.0.8-fix-negative-status-being-reset-on-map-read.patch b/SOURCES/autofs-5.0.8-fix-negative-status-being-reset-on-map-read.patch new file mode 100644 index 0000000..99ca48f --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-negative-status-being-reset-on-map-read.patch @@ -0,0 +1,41 @@ +autofs-5.0.8 - fix negative status being reset on map read + +From: Ian Kent + +The map entry status field, which holds the negative cache timeout, +gets reset on a map re-read. + +If the negative map entry was added at the same time as the map +read and it was for an entry that was never in the map, the +status gets reset even though the entry is still a valid +negative entry. + +Consequently lookups for non-existent map entries are never +seen as negative and the lookup always continues. +--- + CHANGELOG | 1 + + daemon/lookup.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -70,6 +70,7 @@ + - get_nfs_info() should query portmapper if port is not given. + - fix rpc_portmap_getport() proto not set. + - fix protmap not trying proto v2. ++- fix negative status being reset on map read. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -1042,7 +1042,8 @@ void lookup_prune_one_cache(struct autof + * Reset time of last fail for valid map entries to + * force entry update and subsequent mount retry. + */ +- me->status = 0; ++ if (me->mapent) ++ me->status = 0; + me = cache_enumerate(mc, me); + continue; + } diff --git a/SOURCES/autofs-5.0.8-fix-options-compare.patch b/SOURCES/autofs-5.0.8-fix-options-compare.patch new file mode 100644 index 0000000..5c6b127 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-options-compare.patch @@ -0,0 +1,212 @@ +autofs-5.0.8 - fix options compare + +From: Ian Kent + +When checking for options in mount locations incorrect matches +can occur when the length of the option string is not also used +for the check. +--- + CHANGELOG | 1 + + include/automount.h | 1 + + lib/cat_path.c | 9 +++++++++ + modules/mount_autofs.c | 12 ++++++------ + modules/mount_bind.c | 2 +- + modules/mount_ext2.c | 2 +- + modules/mount_nfs.c | 34 +++++++++++++++++----------------- + modules/parse_sun.c | 20 ++++++++++---------- + 8 files changed, 46 insertions(+), 35 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -73,6 +73,7 @@ + - fix negative status being reset on map read. + - fix fix negative status being reset on map read. + - check for non existent negative entries in lookup_ghost(). ++- fix options compare. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -335,6 +335,7 @@ size_t _strlen(const char *str, size_t m + int cat_path(char *buf, size_t len, const char *dir, const char *base); + int ncat_path(char *buf, size_t len, + const char *dir, const char *base, size_t blen); ++int _strncmp(const char *s1, const char *s2, size_t n); + + /* Core automount definitions */ + +--- autofs-5.0.7.orig/lib/cat_path.c ++++ autofs-5.0.7/lib/cat_path.c +@@ -87,3 +87,12 @@ int ncat_path(char *buf, size_t len, + return cat_path(buf, len, dir, name); + } + ++/* Compare first n bytes of s1 and s2 and that n == strlen(s1) */ ++int _strncmp(const char *s1, const char *s2, size_t n) ++{ ++ size_t len = strlen(s1); ++ ++ if (n != len) ++ return n - len; ++ return strncmp(s1, s2, n); ++} +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -116,17 +116,17 @@ int mount_mount(struct autofs_point *ap, + while (*comma != '\0' && *comma != ',') + comma++; + +- if (strncmp(cp, "nobrowse", 8) == 0) ++ if (_strncmp(cp, "nobrowse", 8) == 0) + ghost = 0; +- else if (strncmp(cp, "nobind", 6) == 0) ++ else if (_strncmp(cp, "nobind", 6) == 0) + nobind = 1; +- else if (strncmp(cp, "browse", 6) == 0) ++ else if (_strncmp(cp, "browse", 6) == 0) + ghost = 1; +- else if (strncmp(cp, "symlink", 7) == 0) ++ else if (_strncmp(cp, "symlink", 7) == 0) + symlnk = 1; +- else if (strncmp(cp, "hosts", 5) == 0) ++ else if (_strncmp(cp, "hosts", 5) == 0) + hosts = 1; +- else if (strncmp(cp, "timeout=", 8) == 0) { ++ else if (_strncmp(cp, "timeout=", 8) == 0) { + char *val = strchr(cp, '='); + unsigned tout; + if (val) { +--- autofs-5.0.7.orig/modules/mount_bind.c ++++ autofs-5.0.7/modules/mount_bind.c +@@ -107,7 +107,7 @@ int mount_mount(struct autofs_point *ap, + end--; + + o_len = end - cp + 1; +- if (strncmp("symlink", cp, o_len) == 0) ++ if (_strncmp("symlink", cp, o_len) == 0) + symlnk = 1; + } + } +--- autofs-5.0.7.orig/modules/mount_ext2.c ++++ autofs-5.0.7/modules/mount_ext2.c +@@ -77,7 +77,7 @@ int mount_mount(struct autofs_point *ap, + + if (options && options[0]) { + for (p = options; (p1 = strchr(p, ',')); p = p1) +- if (!strncmp(p, "ro", p1 - p) && ++p1 - p == sizeof("ro")) ++ if (!_strncmp(p, "ro", p1 - p) && ++p1 - p == sizeof("ro")) + ro = 1; + if (!strcmp(p, "ro")) + ro = 1; +--- autofs-5.0.7.orig/modules/mount_nfs.c ++++ autofs-5.0.7/modules/mount_nfs.c +@@ -126,32 +126,32 @@ int mount_mount(struct autofs_point *ap, + + o_len = end - cp + 1; + +- if (strncmp("proto=rdma", cp, o_len) == 0 || +- strncmp("rdma", cp, o_len) == 0) ++ if (_strncmp("proto=rdma", cp, o_len) == 0 || ++ _strncmp("rdma", cp, o_len) == 0) + rdma = 1; + +- if (strncmp("nosymlink", cp, o_len) == 0) { ++ if (_strncmp("nosymlink", cp, o_len) == 0) { + warn(ap->logopt, MODPREFIX + "the \"nosymlink\" option is depricated " + "and will soon be removed, " + "use the \"nobind\" option instead"); + nosymlink = 1; +- } else if (strncmp("nobind", cp, o_len) == 0) { ++ } else if (_strncmp("nobind", cp, o_len) == 0) { + nobind = 1; +- } else if (strncmp("no-use-weight-only", cp, o_len) == 0) { ++ } else if (_strncmp("no-use-weight-only", cp, o_len) == 0) { + flags &= ~MOUNT_FLAG_USE_WEIGHT_ONLY; +- } else if (strncmp("use-weight-only", cp, o_len) == 0) { ++ } else if (_strncmp("use-weight-only", cp, o_len) == 0) { + flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; + } else { +- if (strncmp("vers=4", cp, o_len) == 0 || +- strncmp("nfsvers=4", cp, o_len) == 0) ++ if (_strncmp("vers=4", cp, o_len) == 0 || ++ _strncmp("nfsvers=4", cp, o_len) == 0) + vers = NFS4_VERS_MASK | TCP_SUPPORTED; +- else if (strncmp("vers=3", cp, o_len) == 0 || +- strncmp("nfsvers=3", cp, o_len) == 0) { ++ else if (_strncmp("vers=3", cp, o_len) == 0 || ++ _strncmp("nfsvers=3", cp, o_len) == 0) { + vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK); + vers |= NFS3_REQUESTED; +- } else if (strncmp("vers=2", cp, o_len) == 0 || +- strncmp("nfsvers=2", cp, o_len) == 0) { ++ } else if (_strncmp("vers=2", cp, o_len) == 0 || ++ _strncmp("nfsvers=2", cp, o_len) == 0) { + vers &= ~(NFS4_VERS_MASK | NFS_VERS_MASK); + vers |= NFS2_REQUESTED; + } else if (strstr(cp, "port=") == cp && +@@ -164,16 +164,16 @@ int mount_mount(struct autofs_point *ap, + if (port < 0) + port = 0; + port_opt = cp; +- } else if (strncmp("proto=udp", cp, o_len) == 0 || +- strncmp("udp", cp, o_len) == 0) { ++ } else if (_strncmp("proto=udp", cp, o_len) == 0 || ++ _strncmp("udp", cp, o_len) == 0) { + vers &= ~TCP_SUPPORTED; +- } else if (strncmp("proto=tcp", cp, o_len) == 0 || +- strncmp("tcp", cp, o_len) == 0) { ++ } else if (_strncmp("proto=tcp", cp, o_len) == 0 || ++ _strncmp("tcp", cp, o_len) == 0) { + vers &= ~UDP_SUPPORTED; + } + /* Check for options that also make sense + with bind mounts */ +- else if (strncmp("ro", cp, o_len) == 0) ++ else if (_strncmp("ro", cp, o_len) == 0) + ro = 1; + /* and jump over trailing white space */ + memcpy(nfsp, cp, comma - cp + 1); +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -549,29 +549,29 @@ static int sun_mount(struct autofs_point + while (*comma != '\0' && *comma != ',') + comma++; + +- if (strncmp("fstype=", cp, 7) == 0) { ++ if (_strncmp("fstype=", cp, 7) == 0) { + int typelen = comma - (cp + 7); + fstype = alloca(typelen + 1); + memcpy(fstype, cp + 7, typelen); + fstype[typelen] = '\0'; +- } else if (strncmp("nonstrict", cp, 9) == 0) { ++ } else if (_strncmp("nonstrict", cp, 9) == 0) { + nonstrict = 1; +- } else if (strncmp("strict", cp, 6) == 0) { ++ } else if (_strncmp("strict", cp, 6) == 0) { + nonstrict = 0; +- } else if (strncmp("nobrowse", cp, 8) == 0 || +- strncmp("browse", cp, 6) == 0 || +- strncmp("timeout=", cp, 8) == 0) { ++ } else if (_strncmp("nobrowse", cp, 8) == 0 || ++ _strncmp("browse", cp, 6) == 0 || ++ _strncmp("timeout=", cp, 8) == 0) { + if (strcmp(fstype, "autofs") == 0 || + strstr(cp, "fstype=autofs")) { + memcpy(np, cp, comma - cp + 1); + np += comma - cp + 1; + } +- } else if (strncmp("no-use-weight-only", cp, 18) == 0) { ++ } else if (_strncmp("no-use-weight-only", cp, 18) == 0) { + use_weight_only = -1; +- } else if (strncmp("use-weight-only", cp, 15) == 0) { ++ } else if (_strncmp("use-weight-only", cp, 15) == 0) { + use_weight_only = MOUNT_FLAG_USE_WEIGHT_ONLY; +- } else if (strncmp("bg", cp, 2) == 0 || +- strncmp("nofg", cp, 4) == 0) { ++ } else if (_strncmp("bg", cp, 2) == 0 || ++ _strncmp("nofg", cp, 4) == 0) { + continue; + } else { + memcpy(np, cp, comma - cp + 1); diff --git a/SOURCES/autofs-5.0.8-fix-portmap-not-trying-proto-v2.patch b/SOURCES/autofs-5.0.8-fix-portmap-not-trying-proto-v2.patch new file mode 100644 index 0000000..c493391 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-portmap-not-trying-proto-v2.patch @@ -0,0 +1,59 @@ +autofs-5.0.8 - fix portmap not trying proto v2 + +From: Ian Kent + +The latest change to fix a problem with getting an exports list +from a server doesn't try portmap version 2 when trying to get +a service port number. This causes servers that offer only +version 2 to not be able to provide a service port number. +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 17 ++++++++++++++++- + 2 files changed, 17 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -69,6 +69,7 @@ + - fix fix ipv6 libtirpc getport. + - get_nfs_info() should query portmapper if port is not given. + - fix rpc_portmap_getport() proto not set. ++- fix protmap not trying proto v2. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/rpc_subs.c ++++ autofs-5.0.7/lib/rpc_subs.c +@@ -524,10 +524,15 @@ static enum clnt_stat rpc_rpcb_getport(C + if (rpcerr.re_vers.low > RPCBVERS4) + return status; + continue; ++ + case RPC_PROGUNAVAIL: + continue; ++ ++ case RPC_PROGNOTREGISTERED: ++ continue; ++ + default: +- /* Most likely RPC_TIMEDOUT or RPC_CANTRECV */ ++ /* Most likely RPC_TIMEDOUT or RPC_CANTRECV */ + return status; + } + } +@@ -575,6 +580,16 @@ static enum clnt_stat rpc_getport(struct + free(netid); + free(raddr); + ++ if (status == RPC_PROGNOTREGISTERED) { ++ /* Last chance, version 2 uses a different procedure */ ++ rpcvers_t rpcb_version = PMAPVERS; ++ CLNT_CONTROL(client, CLSET_VERS, (void *) &rpcb_version); ++ status = clnt_call(client, PMAPPROC_GETPORT, ++ (xdrproc_t) xdr_pmap, (caddr_t) parms, ++ (xdrproc_t) xdr_u_short, (caddr_t) port, ++ info->timeout); ++ } ++ + return status; + } + #endif diff --git a/SOURCES/autofs-5.0.8-fix-symlink-expire.patch b/SOURCES/autofs-5.0.8-fix-symlink-expire.patch new file mode 100644 index 0000000..606e7d5 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-symlink-expire.patch @@ -0,0 +1,66 @@ +autofs-5.0.8 - fix symlink expire + +From: Ian Kent + +The expire code uses the list of mounts to decide if additional expire +check requests should be sent to the kernel. This doesn't take into +account the possibility there could be symlinks that might be able to +be expired. + +count_mounts() does count symlinks so use that only when working out +how many expire requests should be sent. +--- + CHANGELOG | 1 + + daemon/indirect.c | 22 ++++++++++------------ + 2 files changed, 11 insertions(+), 12 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -86,6 +86,7 @@ + - fix undefined authtype_requires_creds err if ldap enabled but without sasl. + - pass map_source as function paramter where possible. + - check for bind onto self in mount_bind.c. ++- fix symlink expire. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/indirect.c ++++ autofs-5.0.7/daemon/indirect.c +@@ -388,6 +388,7 @@ void *expire_proc_indirect(void *arg) + struct expire_args ec; + unsigned int now; + int offsets, submnts, count; ++ int retries; + int ioctlfd, cur_state; + int status, ret, left; + +@@ -533,20 +534,17 @@ void *expire_proc_indirect(void *arg) + + /* + * If there are no more real mounts left we could still +- * have some offset mounts with no '/' offset so we need to +- * umount them here. ++ * have some offset mounts with no '/' offset or symlinks ++ * so we need to umount or unlink them here. + */ +- if (mnts) { +- int retries; +- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- retries = (count_mounts(ap->logopt, ap->path, ap->dev) + 1); +- while (retries--) { +- ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, now); +- if (ret) +- left++; +- } +- pthread_setcancelstate(cur_state, NULL); ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); ++ retries = (count_mounts(ap->logopt, ap->path, ap->dev) + 1); ++ while (retries--) { ++ ret = ops->expire(ap->logopt, ap->ioctlfd, ap->path, now); ++ if (ret) ++ left++; + } ++ pthread_setcancelstate(cur_state, NULL); + pthread_cleanup_pop(1); + + count = offsets = submnts = 0; diff --git a/SOURCES/autofs-5.0.8-fix-symlink-fail-message-in-mount_bind-c.patch b/SOURCES/autofs-5.0.8-fix-symlink-fail-message-in-mount_bind-c.patch new file mode 100644 index 0000000..3c677c9 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-symlink-fail-message-in-mount_bind-c.patch @@ -0,0 +1,31 @@ +autofs-5.0.8 - fix symlink fail message in mount_bind.c + +From: Ian Kent + + +--- + CHANGELOG | 1 + + modules/mount_bind.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -78,6 +78,7 @@ + - fix max() declaration. + - setup program map env from macro table. + - add short host name standard marco variable. ++- fix symlink fail message in mount_bind.c. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/mount_bind.c ++++ autofs-5.0.7/modules/mount_bind.c +@@ -206,7 +206,7 @@ int mount_mount(struct autofs_point *ap, + if (symlink(what, fullpath) && errno != EEXIST) { + error(ap->logopt, + MODPREFIX +- "failed to create local mount %s -> %s", ++ "failed to create symlink %s -> %s", + fullpath, what); + if ((ap->flags & MOUNT_FLAG_GHOST) && !status) + if (mkdir_path(fullpath, 0555) && errno != EEXIST) { diff --git a/SOURCES/autofs-5.0.8-fix-undefined-authtype_requires_creds-err-if-ldap-en.patch b/SOURCES/autofs-5.0.8-fix-undefined-authtype_requires_creds-err-if-ldap-en.patch new file mode 100644 index 0000000..cd14bca --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-undefined-authtype_requires_creds-err-if-ldap-en.patch @@ -0,0 +1,48 @@ +autofs-5.0.8 - fix undefined authtype_requires_creds err if ldap enabled but without sasl + +From: Lan Yixun (dlan) + +This patch is moving "WITH_SASL" into authtype_requires_creds function +make it return 0 if sasl not enabled, which mean authtype_requires_creds is not enabled + +https://bugs.gentoo.org/show_bug.cgi?id=489128 +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -83,6 +83,7 @@ + - check for existing offset mount before mounting. + - fix cache readlock not taken on lookup. + - fix compilation of lookup_ldap.c without sasl. ++- fix undefined authtype_requires_creds err if ldap enabled but without sasl. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -813,20 +813,20 @@ int get_property(unsigned logopt, xmlNod + return 0; + } + +-#ifdef WITH_SASL + /* + * For plain text, login and digest-md5 authentication types, we need + * user and password credentials. + */ + int authtype_requires_creds(const char *authtype) + { ++#ifdef WITH_SASL + if (!strncmp(authtype, "PLAIN", strlen("PLAIN")) || + !strncmp(authtype, "DIGEST-MD5", strlen("DIGEST-MD5")) || + !strncmp(authtype, "LOGIN", strlen("LOGIN"))) + return 1; ++#endif + return 0; + } +-#endif + + /* + * Returns: diff --git a/SOURCES/autofs-5.0.8-fix-variable-substitution-description.patch b/SOURCES/autofs-5.0.8-fix-variable-substitution-description.patch new file mode 100644 index 0000000..e845779 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fix-variable-substitution-description.patch @@ -0,0 +1,44 @@ +autofs-5.0.8 - fix variable substitution description + +From: Ian Kent + +The desription about Variable substitution in autofs(5) says that +translation is done on the key and location fields which is not +correct. + +Expecting to be able to receive a key from the kernel that +contains variables to be substituted doesn't make sense and +to be able to use map keys with substitution would mean a full +map scan for every lookup for all map sources. That is not +unacceptable for large maps. +--- + CHANGELOG | 1 + + man/autofs.5 | 7 ++++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -101,6 +101,7 @@ + - fix inconsistent error returns in handle_packet_missing_direct(). + - simple coverity fixes. + - fixes for samples/auto.master. ++- fix variable substitution description. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/autofs.5 ++++ autofs-5.0.7/man/autofs.5 +@@ -157,9 +157,10 @@ The special character '&' will be replac + in the example above, a lookup for the key 'foo' would yield a mount + of server:/export/home/foo. + .SS Variable Substitution +-The following special variables will be substituted in the key and location +-fields of an automounter map if prefixed with $ as customary from shell +-scripts (Curly braces can be used to separate the field name): ++The following special variables will be substituted in the location ++field of an automounter map entry if prefixed with $ as customary ++from shell scripts (curly braces can be used to separate the field ++name): + .sp + .RS +.2i + .ta 1.5i diff --git a/SOURCES/autofs-5.0.8-fixes-for-samples-auto_master.patch b/SOURCES/autofs-5.0.8-fixes-for-samples-auto_master.patch new file mode 100644 index 0000000..6829c13 --- /dev/null +++ b/SOURCES/autofs-5.0.8-fixes-for-samples-auto_master.patch @@ -0,0 +1,59 @@ +autofs-5.0.8 - fixes for samples/auto.master + +From: Vincent McIntyre + +Replace description that described regular automount maps, not +master maps. Add a note about the format of included files. +Clarify what happens to master map options not consumed by +'mount'. + +Signed-off-by: +--- + CHANGELOG | 1 + + man/auto.master.5.in | 2 +- + samples/auto.master | 7 ++++--- + 3 files changed, 6 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -100,6 +100,7 @@ + - dont ignore null cache entries on multi mount umount. + - fix inconsistent error returns in handle_packet_missing_direct(). + - simple coverity fixes. ++- fixes for samples/auto.master. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/auto.master.5.in ++++ autofs-5.0.7/man/auto.master.5.in +@@ -139,7 +139,7 @@ the \fBdn\fP of an LDAP entry for maps o + .br + Any remaining command line arguments without leading dashes (\-) are + taken as options (\fI\-o\fP) to \fBmount\fP. Arguments with leading +-dashes are considered options for the maps. ++dashes are considered options for the maps and are passed to automount (8). + .sp + The \fBsun\fP format supports the following options: + .RS +--- autofs-5.0.7.orig/samples/auto.master ++++ autofs-5.0.7/samples/auto.master +@@ -1,8 +1,8 @@ + # + # Sample auto.master file +-# This is an automounter map and it has the following format +-# key [ -mount-options-separated-by-comma ] location +-# For details of the format look at autofs(5). ++# This is a 'master' automounter map and it has the following format: ++# mount-point [map-type[,format]:]map [options] ++# For details of the format look at auto.master(5). + # + /misc /etc/auto.misc + # +@@ -13,6 +13,7 @@ + /net -hosts + # + # Include /etc/auto.master.d/*.autofs ++# The included files must conform to the format of this file. + # + +dir:/etc/auto.master.d + # diff --git a/SOURCES/autofs-5.0.8-get_nfs_info-should-query-portmapper-if-port-is-not-given.patch b/SOURCES/autofs-5.0.8-get_nfs_info-should-query-portmapper-if-port-is-not-given.patch new file mode 100644 index 0000000..de50c4c --- /dev/null +++ b/SOURCES/autofs-5.0.8-get_nfs_info-should-query-portmapper-if-port-is-not-given.patch @@ -0,0 +1,40 @@ +autofs-5.0.8 - get_nfs_info() should query portmapper if port is not given + +From: Scott Mayhew + +It shouldn't just assume it can use port 2049. + +Signed-off-by: Scott Mayhew +--- + CHANGELOG | 1 + + modules/replicated.c | 9 ++++++--- + 2 files changed, 7 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -67,6 +67,7 @@ + - fix ipv6 libtirpc getport. + - improve timeout option description. + - fix fix ipv6 libtirpc getport. ++- get_nfs_info() should query portmapper if port is not given. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/replicated.c ++++ autofs-5.0.7/modules/replicated.c +@@ -444,9 +444,12 @@ static unsigned int get_nfs_info(unsigne + host->name, proto, version); + + rpc_info->proto = proto; +- if (port < 0) +- rpc_info->port = NFS_PORT; +- else if (port > 0) ++ if (port < 0) { ++ if (version & NFS4_REQUESTED) ++ rpc_info->port = NFS_PORT; ++ else ++ port = 0; ++ } else if (port > 0) + rpc_info->port = port; + + memset(&parms, 0, sizeof(struct pmap)); diff --git a/SOURCES/autofs-5.0.8-make-autofs-5-consistent-with-auto-master-5.patch b/SOURCES/autofs-5.0.8-make-autofs-5-consistent-with-auto-master-5.patch new file mode 100644 index 0000000..4eeb5db --- /dev/null +++ b/SOURCES/autofs-5.0.8-make-autofs-5-consistent-with-auto-master-5.patch @@ -0,0 +1,167 @@ +autofs-5.0.8 - make autofs(5) consistent with auto.master(5) + +From: Ian Kent + +The presentation in autofs(5) isn't the same as that in auto.master(5). +--- + CHANGELOG | 1 + + man/auto.master.5.in | 18 +++++++++++------- + man/autofs.5 | 41 +++++++++++++++++++++++++++-------------- + 3 files changed, 39 insertions(+), 21 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -93,6 +93,7 @@ + - change walk_tree() to take ap. + - add negative cache lookup to hesiod lookup. + - fix external env configure. ++- make autofs(5) consistent with auto.master(5). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/auto.master.5.in ++++ autofs-5.0.7/man/auto.master.5.in +@@ -38,14 +38,14 @@ Access to mounts in maps is governed by + .P + For direct maps the mount point is always specified as: + .P +-/- ++.BR /- + .P + and the key used within the direct map is the full path to the mount point. The direct map + may have multiple entries in the master map. + .P + For indirect maps access is by using the path scheme: + .P +-.RI / mount-point / key ++.BR /mount-point/key + .P + where + .I mount-point +@@ -57,7 +57,9 @@ map given in the entry (See + .P + Additionally, a map may be included from its source as if it were itself + present in the master map by including a line of the form: +-.BR +\ [ maptype , format :] map [ options ] ++.P ++.BR + [ maptype [, format ]:] map\ [ options ] ++.P + and + .BR automount (8) + will process the map according to the specification described below for +@@ -73,14 +75,14 @@ which contains options to be applied to + .P + The format of a master map entry is: + .TP +-.IR mount-point\ [ map-type [, format ]:] map\ [ options ] ++.BR mount-point\ [ map-type [, format ]:] map\ [ options ] + .TP +-\fBmount-point\fP ++.B mount-point + Base location for the \fBautofs\fP filesystem to be mounted. For + indirect maps this directory will be created (as with \fBmkdir \-p\fP) + and is removed when the \fBautofs\fP filesystem is umounted. + .TP +-\fBmap-type\fP ++.B map-type + Type of map used for this mount point. The following are + valid map types: + .RS +@@ -133,7 +135,8 @@ for maps of types \fBfile\fP, \fBdir\fP, + in the case for maps of type \fByp\fP, \fBnisplus\fP, or \fBhesiod\fP or + the \fBdn\fP of an LDAP entry for maps of type \fBldap\fP. + .TP +-\fBoptions\fP ++.B options ++.br + Any remaining command line arguments without leading dashes (\-) are + taken as options (\fI\-o\fP) to \fBmount\fP. Arguments with leading + dashes are considered options for the maps. +@@ -287,6 +290,7 @@ it will used for subsequent lookups. + There are three common schemas in use: + .TP + .I nisMap ++.br + Entries in the \fBnisMap\fP schema are \fBnisObject\fP objects in + the specified subtree, where the \fBcn\fP attribute is the key + (the wildcard key is "/"), and the \fBnisMapEntry\fP attribute +--- autofs-5.0.7.orig/man/autofs.5 ++++ autofs-5.0.7/man/autofs.5 +@@ -22,42 +22,56 @@ This is a description of the text file f + these files may exist. All empty lines or lines beginning with # are + ignored. The basic format of one line in such maps is: + .P +-.BI "key [" -options "] location" +- +-.SS key ++.BR key\ [ -options ]\ location ++.TP ++.B key ++.br + For indirect mounts this is the part of the path name between the mount point + and the path into the filesystem when it is mounted. Usually you can think about the + key as a sub-directory name below the autofs managed mount point. + + For direct mounts this is the full path of each mount point. This map is always + associated with the /- mount point in the master map. +- +-.SS options ++.TP ++.B options ++.br + Zero or more options may be given. Options can also be given in the + .B auto.master + file in which case both values are cumulative (this is a difference + from SunOS). The options are a list of comma separated options as + customary for the + .BR mount (8) +-command. There are two special options +-.I -fstype= +-used to specify a filesystem type if the filesystem is not of the default ++command. ++ ++There are several special options ++.RS ++.TP ++.B -fstype= ++.br ++is used to specify a filesystem type if the filesystem is not of the default + NFS type. This option is processed by the automounter and not by the mount + command. +-.I -strict ++.TP ++.B -strict ++.br + is used to treat errors when mounting file systems as fatal. This is important when + multiple file systems should be mounted (`multi-mounts'). If this option + is given, no file system is mounted at all if at least one file system + can't be mounted. +-.I -use-weight-only ++.TP ++.B -use-weight-only ++.br + is used to make the weight the sole factor in selecting a server when multiple + servers are present in a map entry. + and +-.I -no-use-weight-only ++.TP ++.B -no-use-weight-only ++.br + can be used to negate the option if it is present in the master map entry + for the map but is not wanted for the given mount. +- +-.SS location ++.RE ++.TP ++.B location + The location specifies from where the file system is to be mounted. In the + most cases this will be an NFS volume and the usual notation + .I host:pathname +@@ -227,7 +241,6 @@ Anything else is questionable and unsupp + host1(3),host:/blah + .fi + .RE +-.sp + .SH UNSUPPORTED + This version of the automounter supports direct maps stored in FILE, NIS, NISPLUS + and LDAP only. diff --git a/SOURCES/autofs-5.0.8-pass-map_source-as-function-paramter-where-possible.patch b/SOURCES/autofs-5.0.8-pass-map_source-as-function-paramter-where-possible.patch new file mode 100644 index 0000000..20faa6f --- /dev/null +++ b/SOURCES/autofs-5.0.8-pass-map_source-as-function-paramter-where-possible.patch @@ -0,0 +1,538 @@ +autofs-5.0.8 - pass map_source as function paramter where possible + +From: Ian Kent + +Some unnecessary complexity has been added along the way when passing +the map source to functions in lookup modules. Improve that where +possible. +--- + CHANGELOG | 1 + modules/lookup_file.c | 82 +++++++++++++++-------------------------------- + modules/lookup_ldap.c | 37 ++++++--------------- + modules/lookup_nisplus.c | 36 ++++---------------- + modules/lookup_yp.c | 36 ++++---------------- + 5 files changed, 56 insertions(+), 136 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -84,6 +84,7 @@ + - fix cache readlock not taken on lookup. + - fix compilation of lookup_ldap.c without sasl. + - fix undefined authtype_requires_creds err if ldap enabled but without sasl. ++- pass map_source as function paramter where possible. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_file.c ++++ autofs-5.0.7/modules/lookup_file.c +@@ -529,21 +529,17 @@ static int check_self_include(const char + + static struct map_source * + prepare_plus_include(struct autofs_point *ap, ++ struct map_source *source, + time_t age, char *key, unsigned int inc, + struct lookup_context *ctxt) + { +- struct map_source *current; +- struct map_source *source; ++ struct map_source *new; + struct map_type_info *info; + const char *argv[2]; + char **tmp_argv, **tmp_opts; + int argc; + char *buf; + +- current = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + /* + * TODO: + * Initially just consider the passed in key to be a simple map +@@ -596,21 +592,21 @@ prepare_plus_include(struct autofs_point + } + argc += ctxt->opts_argc; + +- source = master_find_source_instance(current, +- info->type, info->format, +- argc, (const char **) tmp_argv); +- if (source) { ++ new = master_find_source_instance(source, ++ info->type, info->format, ++ argc, (const char **) tmp_argv); ++ if (new) { + /* + * Make sure included map age is in sync with its owner + * or we could incorrectly wipe out its entries. + */ +- source->age = age; +- source->stale = 1; ++ new->age = age; ++ new->stale = 1; + } else { +- source = master_add_source_instance(current, +- info->type, info->format, age, +- argc, (const char **) tmp_argv); +- if (!source) { ++ new = master_add_source_instance(source, ++ info->type, info->format, age, ++ argc, (const char **) tmp_argv); ++ if (!new) { + free_argv(argc, (const char **) tmp_argv); + free_map_type_info(info); + free(buf); +@@ -620,14 +616,14 @@ prepare_plus_include(struct autofs_point + } + free_argv(argc, (const char **) tmp_argv); + +- source->depth = current->depth + 1; ++ new->depth = source->depth + 1; + if (inc) +- source->recurse = 1; ++ new->recurse = 1; + + free_map_type_info(info); + free(buf); + +- return source; ++ return new; + } + + int lookup_read_map(struct autofs_point *ap, time_t age, void *context) +@@ -689,10 +685,8 @@ int lookup_read_map(struct autofs_point + + inc = check_self_include(key, ctxt); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- inc_source = prepare_plus_include(ap, age, key, inc, ctxt); ++ inc_source = prepare_plus_include(ap, source, ++ age, key, inc, ctxt); + if (!inc_source) { + debug(ap->logopt, + "failed to select included map %s", key); +@@ -731,10 +725,10 @@ int lookup_read_map(struct autofs_point + } + + static int lookup_one(struct autofs_point *ap, ++ struct map_source *source, + const char *key, int key_len, + struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + char mkey[KEY_MAX_LEN + 1]; + char mapent[MAPENT_MAX_LEN + 1]; +@@ -743,10 +737,6 @@ static int lookup_one(struct autofs_poin + unsigned int k_len, m_len; + int entry, ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + + f = open_fopen_r(ctxt->mapname); +@@ -773,10 +763,8 @@ static int lookup_one(struct autofs_poin + + inc = check_self_include(mkey, ctxt); + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- inc_source = prepare_plus_include(ap, age, mkey, inc, ctxt); ++ inc_source = prepare_plus_include(ap, source, ++ age, mkey, inc, ctxt); + if (!inc_source) { + debug(ap->logopt, + MODPREFIX +@@ -837,9 +825,9 @@ static int lookup_one(struct autofs_poin + return CHE_MISSING; + } + +-static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) ++static int lookup_wild(struct autofs_point *ap, ++ struct map_source *source, struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + char mkey[KEY_MAX_LEN + 1]; + char mapent[MAPENT_MAX_LEN + 1]; +@@ -848,10 +836,6 @@ static int lookup_wild(struct autofs_poi + unsigned int k_len, m_len; + int entry, ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + + f = open_fopen_r(ctxt->mapname); +@@ -895,24 +879,17 @@ static int lookup_wild(struct autofs_poi + } + + static int check_map_indirect(struct autofs_point *ap, ++ struct map_source *source, + char *key, int key_len, + struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + struct mapent *exists; + int ret = CHE_OK; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- ret = lookup_one(ap, key, key_len, ctxt); ++ ret = lookup_one(ap, source, key, key_len, ctxt); + if (ret == CHE_COMPLETED) + return NSS_STATUS_COMPLETED; + +@@ -935,10 +912,7 @@ static int check_map_indirect(struct aut + struct mapent *we; + int wild = CHE_MISSING; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- wild = lookup_wild(ap, ctxt); ++ wild = lookup_wild(ap, source, ctxt); + /* + * Check for map change and update as needed for + * following cache lookup. +@@ -1072,10 +1046,8 @@ int lookup_mount(struct autofs_point *ap + if (!lkp_key) + return NSS_STATUS_UNKNOWN; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt); ++ status = check_map_indirect(ap, source, ++ lkp_key, strlen(lkp_key), ctxt); + free(lkp_key); + if (status) { + if (status == NSS_STATUS_COMPLETED) +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -2321,20 +2321,16 @@ next: + + + static int read_one_map(struct autofs_point *ap, ++ struct map_source *source, + struct lookup_context *ctxt, + time_t age, int *result_ldap) + { +- struct map_source *source; + struct ldap_search_params sp; + char buf[MAX_ERR_BUF]; + char *class, *info, *entry; + char *attrs[3]; + int rv, l; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + /* + * If we don't need to create directories then there's no use + * reading the map. We always need to read the whole map for +@@ -2453,11 +2449,16 @@ static int read_one_map(struct autofs_po + int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; ++ struct map_source *source; + int rv = LDAP_SUCCESS; + int ret, cur_state; + ++ source = ap->entry->current; ++ ap->entry->current = NULL; ++ master_source_current_signal(ap->entry); ++ + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = read_one_map(ap, ctxt, age, &rv); ++ ret = read_one_map(ap, source, ctxt, age, &rv); + if (ret != NSS_STATUS_SUCCESS) { + switch (rv) { + case LDAP_SIZELIMIT_EXCEEDED: +@@ -2474,10 +2475,9 @@ int lookup_read_map(struct autofs_point + return ret; + } + +-static int lookup_one(struct autofs_point *ap, ++static int lookup_one(struct autofs_point *ap, struct map_source *source, + char *qKey, int qKey_len, struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + int rv, i, l, ql, count; + char buf[MAX_ERR_BUF]; +@@ -2496,10 +2496,6 @@ static int lookup_one(struct autofs_poin + unsigned int wild = 0; + int ret = CHE_MISSING; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + + if (ctxt == NULL) { +@@ -2834,27 +2830,20 @@ next: + } + + static int check_map_indirect(struct autofs_point *ap, ++ struct map_source *source, + char *key, int key_len, + struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + struct mapent *me; + time_t now = time(NULL); + time_t t_last_read; + int ret, cur_state; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- ret = lookup_one(ap, key, key_len, ctxt); ++ ret = lookup_one(ap, source, key, key_len, ctxt); + if (ret == CHE_FAIL) { + pthread_setcancelstate(cur_state, NULL); + return NSS_STATUS_NOTFOUND; +@@ -2974,10 +2963,8 @@ int lookup_mount(struct autofs_point *ap + if (!lkp_key) + return NSS_STATUS_UNKNOWN; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt); ++ status = check_map_indirect(ap, source, ++ lkp_key, strlen(lkp_key), ctxt); + free(lkp_key); + if (status) + return status; +--- autofs-5.0.7.orig/modules/lookup_nisplus.c ++++ autofs-5.0.7/modules/lookup_nisplus.c +@@ -267,10 +267,10 @@ int lookup_read_map(struct autofs_point + } + + static int lookup_one(struct autofs_point *ap, ++ struct map_source *source, + const char *key, int key_len, + struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + char *tablename; + nis_result *result; +@@ -280,10 +280,6 @@ static int lookup_one(struct autofs_poin + int ret, cur_state; + char buf[MAX_ERR_BUF]; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +@@ -326,9 +322,9 @@ static int lookup_one(struct autofs_poin + return ret; + } + +-static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) ++static int lookup_wild(struct autofs_point *ap, ++ struct map_source *source, struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + char *tablename; + nis_result *result; +@@ -338,10 +334,6 @@ static int lookup_wild(struct autofs_poi + int ret, cur_state; + char buf[MAX_ERR_BUF]; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +@@ -383,27 +375,20 @@ static int lookup_wild(struct autofs_poi + } + + static int check_map_indirect(struct autofs_point *ap, ++ struct map_source *source, + char *key, int key_len, + struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + struct mapent *me, *exists; + time_t now = time(NULL); + time_t t_last_read; + int ret = 0; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- + /* check map and if change is detected re-read map */ +- ret = lookup_one(ap, key, key_len, ctxt); ++ ret = lookup_one(ap, source, key, key_len, ctxt); + if (ret == CHE_FAIL) + return NSS_STATUS_NOTFOUND; + +@@ -452,10 +437,7 @@ static int check_map_indirect(struct aut + int wild = CHE_MISSING; + struct mapent *we; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- wild = lookup_wild(ap, ctxt); ++ wild = lookup_wild(ap, source, ctxt); + /* + * Check for map change and update as needed for + * following cache lookup. +@@ -553,10 +535,8 @@ int lookup_mount(struct autofs_point *ap + if (!lkp_key) + return NSS_STATUS_UNKNOWN; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt); ++ status = check_map_indirect(ap, source, ++ lkp_key, strlen(lkp_key), ctxt); + if (status) + return status; + } +--- autofs-5.0.7.orig/modules/lookup_yp.c ++++ autofs-5.0.7/modules/lookup_yp.c +@@ -377,10 +377,10 @@ int lookup_read_map(struct autofs_point + } + + static int lookup_one(struct autofs_point *ap, ++ struct map_source *source, + const char *key, int key_len, + struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + char *mapname; + char *mapent; +@@ -388,10 +388,6 @@ static int lookup_one(struct autofs_poin + time_t age = time(NULL); + int ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + + mapname = alloca(strlen(ctxt->mapname) + 1); +@@ -436,9 +432,9 @@ static int lookup_one(struct autofs_poin + return ret; + } + +-static int lookup_wild(struct autofs_point *ap, struct lookup_context *ctxt) ++static int lookup_wild(struct autofs_point *ap, ++ struct map_source *source, struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + char *mapname; + char *mapent; +@@ -446,10 +442,6 @@ static int lookup_wild(struct autofs_poi + time_t age = time(NULL); + int ret; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + + mapname = alloca(strlen(ctxt->mapname) + 1); +@@ -489,26 +481,19 @@ static int lookup_wild(struct autofs_poi + } + + static int check_map_indirect(struct autofs_point *ap, ++ struct map_source *source, + char *key, int key_len, + struct lookup_context *ctxt) + { +- struct map_source *source; + struct mapent_cache *mc; + struct mapent *exists; + unsigned int map_order; + int ret = 0; + +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- + mc = source->mc; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- + /* check map and if change is detected re-read map */ +- ret = lookup_one(ap, key, key_len, ctxt); ++ ret = lookup_one(ap, source, key, key_len, ctxt); + if (ret == CHE_FAIL) + return NSS_STATUS_NOTFOUND; + +@@ -556,10 +541,7 @@ static int check_map_indirect(struct aut + struct mapent *we; + int wild = CHE_MISSING; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- wild = lookup_wild(ap, ctxt); ++ wild = lookup_wild(ap, source, ctxt); + /* + * Check for map change and update as needed for + * following cache lookup. +@@ -657,10 +639,8 @@ int lookup_mount(struct autofs_point *ap + if (!lkp_key) + return NSS_STATUS_UNKNOWN; + +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- +- status = check_map_indirect(ap, lkp_key, strlen(lkp_key), ctxt); ++ status = check_map_indirect(ap, source, ++ lkp_key, strlen(lkp_key), ctxt); + free(lkp_key); + if (status) + return status; diff --git a/SOURCES/autofs-5.0.8-remove-macro-debug-prints.patch b/SOURCES/autofs-5.0.8-remove-macro-debug-prints.patch new file mode 100644 index 0000000..d78e059 --- /dev/null +++ b/SOURCES/autofs-5.0.8-remove-macro-debug-prints.patch @@ -0,0 +1,23 @@ +autofs-5.0.8 - remove macro debug prints + +From: Ian Kent + +Remove a couple of missed debugging prints from macro_setenv(); +--- + lib/macros.c | 3 --- + 1 file changed, 3 deletions(-) + +diff --git a/lib/macros.c b/lib/macros.c +index d7c392f..c858f41 100644 +--- a/lib/macros.c ++++ b/lib/macros.c +@@ -437,9 +437,6 @@ void macro_setenv(struct substvar *table) + sv = sv->next; + } + +- error(LOGOPT_ANY, "table %p", table); +- dump_table(table); +- + /* Next set environment from the local table */ + while (lv) { + if (lv->def) diff --git a/SOURCES/autofs-5.0.8-remove-stale-debug-message.patch b/SOURCES/autofs-5.0.8-remove-stale-debug-message.patch new file mode 100644 index 0000000..d317f4c --- /dev/null +++ b/SOURCES/autofs-5.0.8-remove-stale-debug-message.patch @@ -0,0 +1,21 @@ +autofs-5.0.8 - remove stale debug message + +From: Ian Kent + + +--- + modules/parse_sun.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 8e5c60c..6f0e3c9 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -1397,7 +1397,6 @@ int parse_mount(struct autofs_point *ap, const char *name, + if (!l) { + if (!(strstr(myoptions, "fstype=autofs") && + strstr(myoptions, "hosts"))) { +- error(LOGOPT_ANY, "I think I'm a hosts map? l %d", l); + cache_delete_offset_list(mc, name); + cache_multi_unlock(me); + cache_unlock(mc); diff --git a/SOURCES/autofs-5.0.8-simple-coverity-fixes.patch b/SOURCES/autofs-5.0.8-simple-coverity-fixes.patch new file mode 100644 index 0000000..4f9d63f --- /dev/null +++ b/SOURCES/autofs-5.0.8-simple-coverity-fixes.patch @@ -0,0 +1,94 @@ +autofs-5.0.8 - simple coverity fixes + +From: Ian Kent + +Add a couple of simple corrections reported by Coverity. +--- + CHANGELOG | 1 + + daemon/automount.c | 6 ------ + daemon/lookup.c | 3 ++- + modules/lookup_hosts.c | 3 ++- + modules/lookup_program.c | 3 ++- + modules/mount_bind.c | 4 ++-- + 6 files changed, 9 insertions(+), 11 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -99,6 +99,7 @@ + - fix lookup_nss_mount() map lookup. + - dont ignore null cache entries on multi mount umount. + - fix inconsistent error returns in handle_packet_missing_direct(). ++- simple coverity fixes. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -1776,12 +1776,6 @@ static void show_build_info(void) + #ifdef ENABLE_FORCED_SHUTDOWN + printf("ENABLE_FORCED_SHUTDOWN "); + count = count + 23; +- +- if (count > 60) { +- printf("\n "); +- count = 0; +- } +- + #endif + + #ifdef ENABLE_IGNORE_BUSY_MOUNTS +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -959,7 +959,8 @@ static void update_negative_cache(struct + rv = cache_update(map->mc, map, name, NULL, now); + if (rv != CHE_FAIL) { + me = cache_lookup_distinct(map->mc, name); +- me->status = now + ap->negative_timeout; ++ if (me) ++ me->status = now + ap->negative_timeout; + } + cache_unlock(map->mc); + } +--- autofs-5.0.7.orig/modules/lookup_hosts.c ++++ autofs-5.0.7/modules/lookup_hosts.c +@@ -161,7 +161,8 @@ static int do_parse_mount(struct autofs_ + rv = cache_update(mc, source, name, NULL, now); + if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, name); +- me->status = now + ap->negative_timeout; ++ if (me) ++ me->status = now + ap->negative_timeout; + } + cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -459,7 +459,8 @@ out_free: + rv = cache_update(mc, source, name, NULL, now); + if (rv != CHE_FAIL) { + me = cache_lookup_distinct(mc, name); +- me->status = now + ap->negative_timeout; ++ if (me) ++ me->status = now + ap->negative_timeout; + } + cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; +--- autofs-5.0.7.orig/modules/mount_bind.c ++++ autofs-5.0.7/modules/mount_bind.c +@@ -214,14 +214,14 @@ int mount_mount(struct autofs_point *ap, + MODPREFIX + "failed to create symlink %s -> %s", + fullpath, what); +- if ((ap->flags & MOUNT_FLAG_GHOST) && !status) ++ if ((ap->flags & MOUNT_FLAG_GHOST) && !status) { + if (mkdir_path(fullpath, 0555) && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, + MODPREFIX "mkdir_path %s failed: %s", + fullpath, estr); + } +- else { ++ } else { + if (ap->type == LKP_INDIRECT) + rmdir_path(ap, fullpath, ap->dev); + } diff --git a/SOURCES/autofs-5.0.8-use-open-instead-of-access.patch b/SOURCES/autofs-5.0.8-use-open-instead-of-access.patch new file mode 100644 index 0000000..809b905 --- /dev/null +++ b/SOURCES/autofs-5.0.8-use-open-instead-of-access.patch @@ -0,0 +1,127 @@ +autofs-5.0.8 - use open(2) instead of access(2) + +From: Ian Kent + +The access(2) system call has been used to trigger dependednt automounts +in the target path when mounting. But access(2) no longer triggers the +dependednt mounts. + +So use open(2) with flag O_DIRECTORY which will trigger these mounts. +--- + CHANGELOG | 1 + + daemon/spawn.c | 30 ++++++++++++++++++------------ + 2 files changed, 19 insertions(+), 12 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -104,6 +104,7 @@ + - fix variable substitution description. + - fix incorrect append options description in README.v5-release. + - fix mistake in assignment. ++- use open(2) instead of access(2) to trigger dependent mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/spawn.c ++++ autofs-5.0.7/daemon/spawn.c +@@ -32,7 +32,7 @@ static pthread_mutex_t spawn_mutex = PTH + + #define SPAWN_OPT_NONE 0x0000 + #define SPAWN_OPT_LOCK 0x0001 +-#define SPAWN_OPT_ACCESS 0x0002 ++#define SPAWN_OPT_OPEN 0x0002 + + #define MTAB_LOCK_RETRIES 3 + +@@ -126,7 +126,7 @@ static int do_spawn(unsigned logopt, uns + int errp, errn; + int cancel_state; + unsigned int use_lock = options & SPAWN_OPT_LOCK; +- unsigned int use_access = options & SPAWN_OPT_ACCESS; ++ unsigned int use_open = options & SPAWN_OPT_OPEN; + sigset_t allsigs, tmpsig, oldsig; + struct thread_stdenv_vars *tsv; + pid_t euid = 0; +@@ -166,6 +166,8 @@ static int do_spawn(unsigned logopt, uns + /* what to mount must always be second last */ + while (*pargv++) + loc++; ++ if (loc <= 3) ++ goto done; + loc -= 2; + + /* +@@ -176,7 +178,9 @@ static int do_spawn(unsigned logopt, uns + * + * I hope host names are never allowed "/" as first char + */ +- if (use_access && *(argv[loc]) == '/') { ++ if (use_open && *(argv[loc]) == '/') { ++ int fd; ++ + pid_t pgrp = getpgrp(); + + /* +@@ -192,19 +196,21 @@ static int do_spawn(unsigned logopt, uns + /* + * Trigger the recursive mount. + * +- * Ignore the access(2) return code as there may be ++ * Ignore the open(2) return code as there may be + * multiple waiters for this mount and we need to +- * let the VFS handle access returns to each +- * individual waiter. ++ * let the VFS handle returns to each individual ++ * waiter. + */ +- access(argv[loc], F_OK); ++ fd = open(argv[loc], O_DIRECTORY); ++ if (fd != -1) ++ close(fd); + + seteuid(0); + setegid(0); + if (pgrp >= 0) + setpgid(0, pgrp); + } +- ++done: + execv(prog, (char *const *) argv); + _exit(255); /* execv() failed */ + } else { +@@ -327,7 +333,7 @@ int spawn_mount(unsigned logopt, ...) + #ifdef ENABLE_MOUNT_LOCKING + options = SPAWN_OPT_LOCK; + #else +- options = SPAWN_OPT_ACCESS; ++ options = SPAWN_OPT_OPEN; + #endif + + va_start(arg, logopt); +@@ -360,7 +366,7 @@ int spawn_mount(unsigned logopt, ...) + p = argv + 2; + } + while ((*p = va_arg(arg, char *))) { +- if (options == SPAWN_OPT_ACCESS && !strcmp(*p, "-t")) { ++ if (options == SPAWN_OPT_OPEN && !strcmp(*p, "-t")) { + *(++p) = va_arg(arg, char *); + if (!*p) + break; +@@ -429,7 +435,7 @@ int spawn_mount(unsigned logopt, ...) + + /* + * For bind mounts that depend on the target being mounted (possibly +- * itself an automount) we attempt to mount the target using an access ++ * itself an automount) we attempt to mount the target using an open(2) + * call. For this to work the location must be the second last arg. + * + * NOTE: If mount locking is enabled this type of recursive mount cannot +@@ -455,7 +461,7 @@ int spawn_bind_mount(unsigned logopt, .. + #ifdef ENABLE_MOUNT_LOCKING + options = SPAWN_OPT_LOCK; + #else +- options = SPAWN_OPT_ACCESS; ++ options = SPAWN_OPT_OPEN; + #endif + + /* diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-REDAME-amd-maps.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-REDAME-amd-maps.patch new file mode 100644 index 0000000..0cf52ab --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-REDAME-amd-maps.patch @@ -0,0 +1,142 @@ +autofs-5.0.9 - amd lookup add README.amd-maps + +From: Ian Kent + + +--- + README.amd-maps | 126 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 126 insertions(+) + create mode 100644 README.amd-maps + +diff --git a/README.amd-maps b/README.amd-maps +new file mode 100644 +index 0000000..b31a7db +--- /dev/null ++++ b/README.amd-maps +@@ -0,0 +1,126 @@ ++ ++amd map parser ++============== ++ ++The ability to parse amd format maps has been added to autofs. ++ ++How to use amd maps in autofs ++----------------------------- ++ ++To add amd map parsing to autofs new "format" module has been added. ++To use this new map format module the existing master map syntax is ++used as described below. ++ ++The master map entry syntax is: ++ ++mount-point [map-type[,format]:]map [options] ++ ++For amd format maps this becomes: ++ ++/amd/mp   file,amd:amd.mp ++ ++which will use file as the map source and the amd format parser for ++the map. But see the section below on configuration below for how to ++eliminate the need to specify "map-type,format" in the master map. ++ ++Configuration sub-system changes ++-------------------------------- ++ ++The configuration sub-system has changed to accommodate the amd parser. ++See autofs.conf(5) for more information on format changes. ++ ++The configuration is now split into system initialization only ++configuration and the daemon configuration. Previously everything was ++located in the system initialization configuration file, but now the ++configuration is located in autofs.conf in the directory the distribution ++uses for the autofs configuration. ++ ++There is information about what amd configuration entries can be used ++in comments of the installed configuration so that's worth a look. ++ ++All that's needed to add an existing amd configuration to autofs is to ++add it below the autofs configuration. Apart from changing the amd ++"[ global ]" section name to "[ amd ]" nothing else should need to be ++changed. However, quite a few amd configuration options don't have ++meaning within autofs. When these options are seen it should be logged. ++ ++Be aware that, if the an old configuration exists and the configuration ++hasn't been updated after the installation, changes to the the old ++configuration will override changes to the new configuration because ++backward compatibility takes priority over the new implementation. ++ ++The amd per-map sections have two functions, to allow per-mount ++configuration, as it does in amd, and to allow master map entries to ++avoid the need to specify the "type,format" part of the master map ++entry so they can use the nsswitch map source functionality in the ++same way autofs master map entries do. ++ ++If a section for an amd mount is added below the global amd section ++using the mount point path (as is done in amd.conf) then autofs will ++know the map format is amd (it doesn't matter if there are no other ++configuration options in the mount point section). Since the map must ++be given in the master map entry the map_name option is not mandatory ++as it is in amd and will no be used. ++ ++If a mount point is present in the master map and the source of the ++map is nis then it should be sufficient to use (for example): ++ ++/amd/mp           amd.mp ++ ++in the master map and ++ ++automount: nis ++ ++in /etc/nsswitch.conf or ++ ++[ amd ] ++map_type = nis ++ ++in the configuration along with ++ ++[ /amd/mp ] ++ ++or ++ ++[ /amd/mp ] ++map_type = nis ++ ++ ++amd map options that can be used ++-------------------------------- ++ ++In an attempt to describe the usable amd map options, many of the amd ++map options have been added to autofs(5). ++ ++Not all the amd functionality has been implemented. The autofs(5) man ++page usually mentions if something hasn't been implemented so that's ++worth checking. ++ ++What hasn't been implemented ++---------------------------- ++ ++The configuration options fully_qualified_hosts, unmount_on_exit and ++browsable_dirs (and a couple of others) aren't implemented. ++ ++Map types (sources) ndbm, passwd are not implemented. ++The map source "sss" can't be used for amd format maps. ++ ++Map caching options aren't used, the existing autofs map caching is ++always used for available map sources. ++ ++The regex map key matching feature is not implemented. ++ ++Mount types lustre, nfsx, jfs, program and direct haven't been ++implemented and other mount types that aren't implemented in amd are ++also not available. ++ ++How to find out more ++-------------------- ++ ++Have a look at the man pages autofs.conf(5), autofs(5) and to a ++lesser extent auto.master(5). These may help. ++ ++But the best way to get more information is to ask on the ++autofs mailing list as described in the README file. ++ ++Ian diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-amd-config-descriptions-to-config.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-amd-config-descriptions-to-config.patch new file mode 100644 index 0000000..292c4a6 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-amd-config-descriptions-to-config.patch @@ -0,0 +1,458 @@ +autofs-5.0.9 - amd lookup add amd config descriptions to config + +From: Ian Kent + +Add amd configuration option descriptions to the default installed +configuration file. + +Including details about amd options that aren't used, haven't been +implemented or have different behaviour within autofs. +--- + redhat/autofs.conf.default.in | 214 ++++++++++++++++++++++++++++++++++++++++ + samples/autofs.conf.default.in | 214 ++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 428 insertions(+) + +diff --git a/redhat/autofs.conf.default.in b/redhat/autofs.conf.default.in +index c1362c7..ccccaab 100644 +--- a/redhat/autofs.conf.default.in ++++ b/redhat/autofs.conf.default.in +@@ -129,3 +129,217 @@ mount_nfs_default_protocol = 4 + # + #map_hash_table_size = 1024 + # ++# ++# Otions for the amd parser within autofs. ++# ++# amd configuration options that are aren't used, haven't been ++# implemented or have different behaviour within autofs. ++# ++# A number of the amd configuration options are not used by autofs, ++# some because they are not relevant within autofs, some because ++# they are done differently in autofs and others that are not yet ++# implemented. ++# ++# Since "mount_type" is always autofs (because there's no user space ++# NFS server) the configuration entries relating to that aren't used. ++# Also, server availability is done differently within autofs so the ++# options that relate to the amd server monitoring sub-system are ++# also not used. ++# ++# These options are mount_type, auto_attrcache, portmap_program, ++# nfs_vers_ping, nfs_allow_any_interface, nfs_allow_insecure_port, ++# nfs_proto, nfs_retransmit_counter, nfs_retransmit_counter_udp, ++# nfs_retransmit_counter_tcp, nfs_retransmit_counter_toplvl, ++# nfs_retry_interval, nfs_retry_interval_udp, nfs_retry_interval_tcp, ++# nfs_retry_interval_toplvl and nfs_vers. ++# ++# ++# Other options that are not used within the autofs implementation: ++# ++# log_file, truncate_log - autofs used either stderr when running in ++# the foreground or sends its output to syslog so an alternate ++# log file (or truncating the log) can't be used. ++# ++# print_pid - there's no corresponding option for this within autofs. ++# ++# use_tcpwrappers, show_statfs_entries - there's no user space NFS ++# server to control access to so this option isn't relevant. ++# The show_statfs_entries can't be implemented for the same ++# reason. ++# ++# debug_mtab_file - there's no user space NFS server and autofs ++# avoids using file based mtab whenever possible. ++# ++# sun_map_syntax - obviously, are provided by autofs itself. ++# ++# plock, show_statfs_entries, preferred_amq_port - not supported. ++# ++# ldap_cache_maxmem, ldap_cache_seconds - external ldap caching ++# is not used by autofs. ++# ++# ldap_proto_version - autofs always attempts to use the highest ++# available ldap protocol version. ++# ++# cache_duration, map_reload_interval, map_options - the map ++# entry cache is continually updated and stale entries ++# cleaned on re-load, which is done when map changes are ++# detected so these configuration entries are not used ++# by autofs. ++# ++# localhost_address - is not used within autofs. This ++# configuration option was only used in the amd user ++# space server code and is not relevant within autofs. ++# ++# ++# Options that are handled differently within autofs: ++# ++# pid_file - must be given as a command line option on startup. ++# ++# print_version - program version and feature information is obtained ++# by using the automount command line option "-V". ++# ++# debug_options, log_options - autofs has somewhat more limited ++# logging and debug logging options. When the log_options ++# options is encountered it is converted to the nearest ++# matching autofs logging option. Since the configuration ++# option debug_options would be handled the same way it ++# is ignored. ++# ++# restart_mounts - has no sensible meaning within autofs because autofs ++# always tries to re-connect to existing mounts. While this ++# has its own set of problems not re-connecting to existing ++# mounts always results in a non-functional automount tree if ++# mounts were busy at the last shutdown (as is also the case ++# with amd when using mount_type autofs). ++# ++# forced_unmounts - detaching mounts often causes serious problems ++# for users of existing mounts. It is used by autofs in some ++# cases, either at the explicit request of the user (with a ++# command line or init option) and in some special cases during ++# program operation but is avoided whenever possible. ++# ++# ++# A number of configuration options are not yet implemented: ++# ++# search_path - always a little frustrating, the compiled in ++# map location should be used to locate maps but isn't ++# in some cases. This requires work within autofs itself ++# and that will (obviously) include implementing this ++# configuration option for the amd map parser as well. ++# ++# fully_qualified_hosts - not yet implemented. ++# ++# unmount_on_exit - since autofs always tries to re-connect ++# to mounts left mounted from a previous shutdown this ++# is a sensible option to implement and that will be ++# done. ++# ++# browsable_dirs - not yet implemented. ++# ++# exec_map_timeout - a timeout is not currently used for ++# for program maps, might be implemented. ++# ++# tag - the tag option is not implemented within autofs. ++# ++# ++# Supported options: ++# ++# arch, karch, os, osver - these options default to what is returned ++# from uname(2) and can be overridden if required. ++# ++# full_os - has no default and must be set in the configuration ++# if used in maps. ++# ++# cluster - if not set defaults to the host domain name. This option ++# corresponds to the HP_UX cluster name (according to the amd ++# source) and is probably not used in Linux but is set anyway. ++# ++# vendor - has a default value of "unknown", it must be set in the ++# configuration if used in maps. ++# ++# auto_dir - is the base name of the mount tree used for external ++# mounts that are sometimes needed by amd maps. Its default ++# value is "/a". ++# ++# map_type - specifies the autofs map source, such as file, nis, ++# ldap etc. and has no default value set. ++# ++# map_defaults - is used to override /defaults entries within maps ++# and can be used to provide different defaults on specific ++# machines without having to modify centrally managed maps. ++# It is empty by default. ++# ++# dismount_interval - is equivalent to the autofs timeout option. It ++# is only possible to use this with type "auto" mounts due ++# to the way the autofs kernel module performs expiry. It ++# takes its default value from the autofs internal default ++# of 600 seconds. ++# ++# autofs_use_lofs - if set to "yes" autofs will attempt to use bind ++# mounts for type "auto" when possible. ++# ++# nis_domain - allows setting of a domain name other than the system ++# default. ++# ++# local_domain - is used to override (or set) the host domain name. ++# ++# normalize_hostnames - if set to "yes" then the contents of ${rhost} ++# is translated in its official host name. ++# ++# domain_strip - if set to "yes" the domain name part of the host ++# is strippped when normalizing hostnames. This can be useful ++# when using of the same maps in a multiple domain environment. ++# ++# normalize_slashes - is set to "yes" by default and will collapse ++# multiple unescaped occurrences of "/" to a single "/". ++# ++# selectors_in_defaults, selectors_on_default - has a default value ++# of "no". If set to "yes" then any defaults entry will be ++# checked for selectors to determine the values to be used. ++# selectors_in_defaults is the preferred option to use. ++# ++# ldap_base - has no default value. It must be set to the base dn ++# that is used for queries if ldap is to be used as a map ++# source. ++# ++# ldap_hostports - has no default value set. It must be set to ++# the URI of the LDAP server to be used for lookups when ++# ldap is used a map source. It may contain a comma or ++# space seperated list of LDAP URIs. ++# ++# hesiod_base - the base name used for hesiod map sources. ++# ++# Define global options for the amd parser within autofs. ++# ++[ amd ] ++# ++# Override the internal default with the same timeout that ++# is used by the override in the autofs configuration, sanity ++# only change. ++# ++dismount_interval = 300 ++# ++# map_type = file ++# ++# Overriding this can cause autofs to use less resources because ++# it will use symlinks instead of bind mounts in certain cases. ++# You should ensure that the autofs kernel module your using ++# supports expration of symlinks for best results (although this ++# appears to work reasonably well most of the time without the ++# update). ++# ++# autofs_use_lofs = no ++# ++# Several configuration options can be set per mount point. ++# In particulr map_type, map_name, map_defaults, search_path, ++# browsable_dirs, dismount_interval and selectors_in_defaults ++# (not all of which are currently implemented, see above). ++# ++# Also, if a section for an amd mount point is defined here ++# it isn't necessary to specify the format in the corresponding ++# master map entry and the format will be inherited for type ++# "auto" mounts. ++# ++# [ /expamle/mount ] ++# dismount_interval = 60 ++# map_type = nis +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index c8e4006..616bc66 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -128,3 +128,217 @@ browse_mode = no + # + #map_hash_table_size = 1024 + # ++# ++# Otions for the amd parser within autofs. ++# ++# amd configuration options that are aren't used, haven't been ++# implemented or have different behaviour within autofs. ++# ++# A number of the amd configuration options are not used by autofs, ++# some because they are not relevant within autofs, some because ++# they are done differently in autofs and others that are not yet ++# implemented. ++# ++# Since "mount_type" is always autofs (because there's no user space ++# NFS server) the configuration entries relating to that aren't used. ++# Also, server availability is done differently within autofs so the ++# options that relate to the amd server monitoring sub-system are ++# also not used. ++# ++# These options are mount_type, auto_attrcache, portmap_program, ++# nfs_vers_ping, nfs_allow_any_interface, nfs_allow_insecure_port, ++# nfs_proto, nfs_retransmit_counter, nfs_retransmit_counter_udp, ++# nfs_retransmit_counter_tcp, nfs_retransmit_counter_toplvl, ++# nfs_retry_interval, nfs_retry_interval_udp, nfs_retry_interval_tcp, ++# nfs_retry_interval_toplvl and nfs_vers. ++# ++# ++# Other options that are not used within the autofs implementation: ++# ++# log_file, truncate_log - autofs used either stderr when running in ++# the foreground or sends its output to syslog so an alternate ++# log file (or truncating the log) can't be used. ++# ++# print_pid - there's no corresponding option for this within autofs. ++# ++# use_tcpwrappers, show_statfs_entries - there's no user space NFS ++# server to control access to so this option isn't relevant. ++# The show_statfs_entries can't be implemented for the same ++# reason. ++# ++# debug_mtab_file - there's no user space NFS server and autofs ++# avoids using file based mtab whenever possible. ++# ++# sun_map_syntax - obviously, are provided by autofs itself. ++# ++# plock, show_statfs_entries, preferred_amq_port - not supported. ++# ++# ldap_cache_maxmem, ldap_cache_seconds - external ldap caching ++# is not used by autofs. ++# ++# ldap_proto_version - autofs always attempts to use the highest ++# available ldap protocol version. ++# ++# cache_duration, map_reload_interval, map_options - the map ++# entry cache is continually updated and stale entries ++# cleaned on re-load, which is done when map changes are ++# detected so these configuration entries are not used ++# by autofs. ++# ++# localhost_address - is not used within autofs. This ++# configuration option was only used in the amd user ++# space server code and is not relevant within autofs. ++# ++# ++# Options that are handled differently within autofs: ++# ++# pid_file - must be given as a command line option on startup. ++# ++# print_version - program version and feature information is obtained ++# by using the automount command line option "-V". ++# ++# debug_options, log_options - autofs has somewhat more limited ++# logging and debug logging options. When the log_options ++# options is encountered it is converted to the nearest ++# matching autofs logging option. Since the configuration ++# option debug_options would be handled the same way it ++# is ignored. ++# ++# restart_mounts - has no sensible meaning within autofs because autofs ++# always tries to re-connect to existing mounts. While this ++# has its own set of problems not re-connecting to existing ++# mounts always results in a non-functional automount tree if ++# mounts were busy at the last shutdown (as is also the case ++# with amd when using mount_type autofs). ++# ++# forced_unmounts - detaching mounts often causes serious problems ++# for users of existing mounts. It is used by autofs in some ++# cases, either at the explicit request of the user (with a ++# command line or init option) and in some special cases during ++# program operation but is avoided whenever possible. ++# ++# ++# A number of configuration options are not yet implemented: ++# ++# search_path - always a little frustrating, the compiled in ++# map location should be used to locate maps but isn't ++# in some cases. This requires work within autofs itself ++# and that will (obviously) include implementing this ++# configuration option for the amd map parser as well. ++# ++# fully_qualified_hosts - not yet implemented. ++# ++# unmount_on_exit - since autofs always tries to re-connect ++# to mounts left mounted from a previous shutdown this ++# is a sensible option to implement and that will be ++# done. ++# ++# browsable_dirs - not yet implemented. ++# ++# exec_map_timeout - a timeout is not currently used for ++# for program maps, might be implemented. ++# ++# tag - the tag option is not implemented within autofs. ++# ++# ++# Supported options: ++# ++# arch, karch, os, osver - these options default to what is returned ++# from uname(2) and can be overridden if required. ++# ++# full_os - has no default and must be set in the configuration ++# if used in maps. ++# ++# cluster - if not set defaults to the host domain name. This option ++# corresponds to the HP_UX cluster name (according to the amd ++# source) and is probably not used in Linux but is set anyway. ++# ++# vendor - has a default value of "unknown", it must be set in the ++# configuration if used in maps. ++# ++# auto_dir - is the base name of the mount tree used for external ++# mounts that are sometimes needed by amd maps. Its default ++# value is "/a". ++# ++# map_type - specifies the autofs map source, such as file, nis, ++# ldap etc. and has no default value set. ++# ++# map_defaults - is used to override /defaults entries within maps ++# and can be used to provide different defaults on specific ++# machines without having to modify centrally managed maps. ++# It is empty by default. ++# ++# dismount_interval - is equivalent to the autofs timeout option. It ++# is only possible to use this with type "auto" mounts due ++# to the way the autofs kernel module performs expiry. It ++# takes its default value from the autofs internal default ++# of 600 seconds. ++# ++# autofs_use_lofs - if set to "yes" autofs will attempt to use bind ++# mounts for type "auto" when possible. ++# ++# nis_domain - allows setting of a domain name other than the system ++# default. ++# ++# local_domain - is used to override (or set) the host domain name. ++# ++# normalize_hostnames - if set to "yes" then the contents of ${rhost} ++# is translated in its official host name. ++# ++# domain_strip - if set to "yes" the domain name part of the host ++# is strippped when normalizing hostnames. This can be useful ++# when using of the same maps in a multiple domain environment. ++# ++# normalize_slashes - is set to "yes" by default and will collapse ++# multiple unescaped occurrences of "/" to a single "/". ++# ++# selectors_in_defaults, selectors_on_default - has a default value ++# of "no". If set to "yes" then any defaults entry will be ++# checked for selectors to determine the values to be used. ++# selectors_in_defaults is the preferred option to use. ++# ++# ldap_base - has no default value. It must be set to the base dn ++# that is used for queries if ldap is to be used as a map ++# source. ++# ++# ldap_hostports - has no default value set. It must be set to ++# the URI of the LDAP server to be used for lookups when ++# ldap is used a map source. It may contain a comma or ++# space seperated list of LDAP URIs. ++# ++# hesiod_base - the base name used for hesiod map sources. ++# ++# Define global options for the amd parser within autofs. ++# ++[ amd ] ++# ++# Override the internal default with the same timeout that ++# is used by the override in the autofs configuration, sanity ++# only change. ++# ++dismount_interval = 300 ++# ++# map_type = file ++# ++# Overriding this can cause autofs to use less resources because ++# it will use symlinks instead of bind mounts in certain cases. ++# You should ensure that the autofs kernel module your using ++# supports expration of symlinks for best results (although this ++# appears to work reasonably well most of the time without the ++# update). ++# ++# autofs_use_lofs = no ++# ++# Several configuration options can be set per mount point. ++# In particulr map_type, map_name, map_defaults, search_path, ++# browsable_dirs, dismount_interval and selectors_in_defaults ++# (not all of which are currently implemented, see above). ++# ++# Also, if a section for an amd mount point is defined here ++# it isn't necessary to specify the format in the corresponding ++# master map entry and the format will be inherited for type ++# "auto" mounts. ++# ++# [ /expamle/mount ] ++# dismount_interval = 60 ++# map_type = nis diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-amd-global-macro-vars.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-amd-global-macro-vars.patch new file mode 100644 index 0000000..a1d8884 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-amd-global-macro-vars.patch @@ -0,0 +1,218 @@ +autofs-5.0.9 - amd lookup add amd global macro vars + +From: Ian Kent + + +--- + include/mounts.h | 2 + + lib/macros.c | 60 +++++++++++++++++++++++++++++++++++++++++- + lib/mounts.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 137 insertions(+), 2 deletions(-) + +diff --git a/include/mounts.h b/include/mounts.h +index 3bef086..ca99f8b 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -87,6 +87,8 @@ extern unsigned int nfs_mount_uses_string_options; + + struct substvar *addstdenv(struct substvar *sv); + struct substvar *removestdenv(struct substvar *sv); ++void add_std_amd_vars(struct substvar *sv); ++void remove_std_amd_vars(void); + + unsigned int query_kproto_ver(void); + unsigned int get_kver_major(void); +diff --git a/lib/macros.c b/lib/macros.c +index 5109abc..ff9ba89 100644 +--- a/lib/macros.c ++++ b/lib/macros.c +@@ -18,11 +18,17 @@ + #include + #include + #include ++#include + + #include "automount.h" + + static struct utsname un; + static char processor[65]; /* Not defined on Linux, so we make our own */ ++static char hostname[HOST_NAME_MAX + 1]; ++static char host[HOST_NAME_MAX]; ++static char domain[HOST_NAME_MAX]; ++static char hostd[HOST_NAME_MAX + 1]; ++static char endian[] = "unknown"; + + /* Predefined variables: tail of link chain */ + static struct substvar +@@ -31,10 +37,18 @@ static struct substvar + sv_host = {"HOST", un.nodename, 1, &sv_cpu}, + sv_osname = {"OSNAME", un.sysname, 1, &sv_host}, + sv_osrel = {"OSREL", un.release, 1, &sv_osname}, +- sv_osvers = {"OSVERS", un.version, 1, &sv_osrel ++ sv_osvers = {"OSVERS", un.version, 1, &sv_osrel}, ++ sv_dollar = {"dollar", "$", 1, &sv_osvers}, ++ sv_true = {"true", "1", 1, &sv_dollar}, ++ sv_false = {"false", "0", 1, &sv_true}, ++ sv_byte = {"byte", endian, 1, &sv_false}, ++ sv_host2 = {"host", host, 1, &sv_byte}, ++ sv_xhost = {"xhost", host, 1, &sv_host2}, ++ sv_domain = {"domain", domain, 1, &sv_xhost}, ++ sv_hostd = {"hostd", hostd, 1, &sv_domain + }; + +-static struct substvar *system_table = &sv_osvers; ++static struct substvar *system_table = &sv_hostd; + static unsigned int macro_init_done = 0; + + static pthread_mutex_t table_mutex = PTHREAD_MUTEX_INITIALIZER; +@@ -63,6 +77,13 @@ void dump_table(struct substvar *table) + /* Get processor information for predefined macro definitions */ + void macro_init(void) + { ++ char *local_domain; ++ ++ memset(hostname, 0, HOST_NAME_MAX + 1); ++ memset(host, 0, HOST_NAME_MAX); ++ memset(domain, 0, HOST_NAME_MAX); ++ memset(hostd, 0, HOST_NAME_MAX + 1); ++ + macro_lock(); + if (macro_init_done) { + macro_unlock(); +@@ -79,6 +100,41 @@ void macro_init(void) + !strcmp(processor + 2, "86")) + processor[1] = '3'; + ++ local_domain = conf_amd_get_sub_domain(); ++ ++ if (!gethostname(hostname, HOST_NAME_MAX)) { ++ char *dot; ++ dot = strchr(hostname, '.'); ++ if (dot) { ++ *dot++ = '\0'; ++ strcpy(domain, dot); ++ } ++ strcpy(host, hostname); ++ strcpy(hostd, host); ++ if (*domain || local_domain) { ++ strcat(hostd, "."); ++ if (!local_domain) ++ strcat(hostd, domain); ++ else { ++ strcat(hostd, local_domain); ++ strcpy(domain, local_domain); ++ } ++ } ++ } ++ ++ if (sizeof(short) == 2) { ++ union { short s; char c[sizeof(short)]; } order; ++ order.s = 0x0102; ++ if (order.c[0] == 1 && order.c[1] == 2) ++ strcpy(endian, "big"); ++ else if (order.c[0] == 2 && order.c[1] == 1) ++ strcpy(endian, "little"); ++ else ++ strcpy(endian, "unknown"); ++ } ++ ++ add_std_amd_vars(system_table); ++ + macro_init_done = 1; + macro_unlock(); + return; +diff --git a/lib/mounts.c b/lib/mounts.c +index aea6691..4306974 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -26,6 +26,7 @@ + #include + #include + #include ++#include + + #include "automount.h" + +@@ -365,6 +366,82 @@ struct substvar *removestdenv(struct substvar *sv) + return list; + } + ++void add_std_amd_vars(struct substvar *sv) ++{ ++ char *tmp; ++ ++ tmp = conf_amd_get_arch(); ++ if (tmp) { ++ macro_global_addvar("arch", 4, tmp); ++ free(tmp); ++ } ++ ++ tmp = conf_amd_get_karch(); ++ if (tmp) { ++ macro_global_addvar("karch", 5, tmp); ++ free(tmp); ++ } ++ ++ tmp = conf_amd_get_os(); ++ if (tmp) { ++ macro_global_addvar("os", 2, tmp); ++ free(tmp); ++ } ++ ++ tmp = conf_amd_get_full_os(); ++ if (tmp) { ++ macro_global_addvar("full_os", 7, tmp); ++ free(tmp); ++ } ++ ++ tmp = conf_amd_get_os_ver(); ++ if (tmp) { ++ macro_global_addvar("osver", 5, tmp); ++ free(tmp); ++ } ++ ++ tmp = conf_amd_get_vendor(); ++ if (tmp) { ++ macro_global_addvar("vendor", 6, tmp); ++ free(tmp); ++ } ++ ++ /* Umm ... HP_UX cluster name, probably not used */ ++ tmp = conf_amd_get_cluster(); ++ if (tmp) { ++ macro_global_addvar("cluster", 7, tmp); ++ free(tmp); ++ } else { ++ const struct substvar *v = macro_findvar(sv, "domain", 4); ++ if (v && *v->val) { ++ tmp = strdup(v->val); ++ if (tmp) ++ macro_global_addvar("cluster", 7, tmp); ++ } ++ } ++ ++ tmp = conf_amd_get_auto_dir(); ++ if (tmp) { ++ macro_global_addvar("autodir", 7, tmp); ++ free(tmp); ++ } ++ ++ return; ++} ++ ++void remove_std_amd_vars(void) ++{ ++ macro_global_removevar("autodir", 7); ++ macro_global_removevar("cluster", 7); ++ macro_global_removevar("vendor", 6); ++ macro_global_removevar("osver", 5); ++ macro_global_removevar("full_os", 7); ++ macro_global_removevar("os", 2); ++ macro_global_removevar("karch", 5); ++ macro_global_removevar("arch", 4); ++ return; ++ } ++ + /* + * Make common autofs mount options string + */ diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-cache-partial-match-functions.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-cache-partial-match-functions.patch new file mode 100644 index 0000000..29df044 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-cache-partial-match-functions.patch @@ -0,0 +1,92 @@ +autofs-5.0.9 - amd lookup add cache partial match functions + +From: Ian Kent + +Partial key matching is used for amd. A prefix is possibly added to the key +and if the map entry key has a trailing /* and matches the initial part of +the key+prefix the match succeeds. + +Update the existing partial match functions to help with this. +--- + include/automount.h | 1 + + lib/cache.c | 38 +++++++++++++++++++++++++++++++++----- + 2 files changed, 34 insertions(+), 5 deletions(-) + +diff --git a/include/automount.h b/include/automount.h +index 37133fe..ac6c4e3 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -215,6 +215,7 @@ struct mapent *cache_lookup(struct mapent_cache *mc, const char *key); + struct mapent *cache_lookup_distinct(struct mapent_cache *mc, const char *key); + struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int start, struct list_head *head); + struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix); ++struct mapent *cache_partial_match_wild(struct mapent_cache *mc, const char *prefix); + int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age); + int cache_update_offset(struct mapent_cache *mc, const char *mkey, const char *key, const char *mapent, time_t age); + void cache_update_negative(struct mapent_cache *mc, struct map_source *ms, const char *key, time_t timeout); +diff --git a/lib/cache.c b/lib/cache.c +index 9af1709..8d08094 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -566,7 +566,9 @@ struct mapent *cache_lookup_offset(const char *prefix, const char *offset, int s + } + + /* cache must be read locked by caller */ +-struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix) ++static struct mapent *__cache_partial_match(struct mapent_cache *mc, ++ const char *prefix, ++ unsigned int type) + { + struct mapent *me = NULL; + size_t len = strlen(prefix); +@@ -578,20 +580,46 @@ struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix) + continue; + + if (len < strlen(me->key) && +- (strncmp(prefix, me->key, len) == 0) && me->key[len] == '/') +- return me; ++ (strncmp(prefix, me->key, len) == 0) && ++ me->key[len] == '/') { ++ if (type == LKP_NORMAL) ++ return me; ++ if (type == LKP_WILD && ++ me->key[len] != '\0' && ++ me->key[len + 1] == '*') ++ return me; ++ } + + me = me->next; + while (me != NULL) { + if (len < strlen(me->key) && +- strncmp(prefix, me->key, len) == 0 && me->key[len] == '/') +- return me; ++ (strncmp(prefix, me->key, len) == 0 && ++ me->key[len] == '/')) { ++ if (type == LKP_NORMAL) ++ return me; ++ if (type == LKP_WILD && ++ me->key[len] != '\0' && ++ me->key[len + 1] == '*') ++ return me; ++ } + me = me->next; + } + } + return NULL; + } + ++/* cache must be read locked by caller */ ++struct mapent *cache_partial_match(struct mapent_cache *mc, const char *prefix) ++{ ++ return __cache_partial_match(mc, prefix, LKP_NORMAL); ++} ++ ++/* cache must be read locked by caller */ ++struct mapent *cache_partial_match_wild(struct mapent_cache *mc, const char *prefix) ++{ ++ return __cache_partial_match(mc, prefix, LKP_WILD); ++} ++ + /* cache must be write locked by caller */ + int cache_add(struct mapent_cache *mc, struct map_source *ms, const char *key, const char *mapent, time_t age) + { diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-cdfs-fs-type.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-cdfs-fs-type.patch new file mode 100644 index 0000000..68a8187 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-cdfs-fs-type.patch @@ -0,0 +1,63 @@ +autofs-5.0.8 - amd lookup add cdfs fs type + +From: Ian Kent + + +--- + include/parse_amd.h | 1 + + modules/amd_parse.y | 3 +++ + modules/amd_tok.l | 2 +- + modules/parse_amd.c | 1 + + 4 files changed, 6 insertions(+), 1 deletion(-) + +diff --git a/include/parse_amd.h b/include/parse_amd.h +index 4015e9f..401aadb 100644 +--- a/include/parse_amd.h ++++ b/include/parse_amd.h +@@ -28,6 +28,7 @@ + #define AMD_MOUNT_TYPE_XFS 0x00000200 + #define AMD_MOUNT_TYPE_JFS 0x00000400 + #define AMD_MOUNT_TYPE_CACHEFS 0x00000800 ++#define AMD_MOUNT_TYPE_CDFS 0x00001000 + #define AMD_MOUNT_TYPE_MASK 0x0000ffff + + #define AMD_ENTRY_CUT 0x00010000 +diff --git a/modules/amd_parse.y b/modules/amd_parse.y +index 1d4a0a3..87e3309 100644 +--- a/modules/amd_parse.y ++++ b/modules/amd_parse.y +@@ -269,6 +269,9 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + !strcmp($3, "ext4")) { + entry.flags |= AMD_MOUNT_TYPE_EXT; + entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "cdfs")) { ++ entry.flags |= AMD_MOUNT_TYPE_CDFS; ++ entry.type = amd_strdup("iso9660"); + } else if (!strcmp($3, "jfs") || + !strcmp($3, "nfsx") || + !strcmp($3, "program") || +diff --git a/modules/amd_tok.l b/modules/amd_tok.l +index 8a6d40c..10b1963 100644 +--- a/modules/amd_tok.l ++++ b/modules/amd_tok.l +@@ -99,7 +99,7 @@ MNTOPT (opts|addopts|remopts) + FSOPTS (rhost|rfs|dev|cachedir|mount|unmount|umount|delay) + CHEOPT (mapdefault|none|inc|re|regexp|all) + MAPTYPE (file|nis|nisplus|ldap|hesiod|exec|ndbm|passwd|union) +-FSTYPE_LOCAL (link|linkx|lofs|ext2|ext3|ext4|xfs|jfs|cachefs) ++FSTYPE_LOCAL (link|linkx|lofs|ext2|ext3|ext4|xfs|jfs|cdfs|cachefs) + FSTYPE_NET (nfs|nfsx|nfsl|host) + FSTYPE (auto|program|direct|lustre|{FSTYPE_LOCAL}|{FSTYPE_NET}) + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index bc53b1d..fa0f75d 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1286,6 +1286,7 @@ static int amd_mount(struct autofs_point *ap, const char *name, + + case AMD_MOUNT_TYPE_EXT: + case AMD_MOUNT_TYPE_XFS: ++ case AMD_MOUNT_TYPE_CDFS: + if (!validate_generic_options(ap->logopt, fstype, entry)) + return 1; + ret = do_generic_mount(ap, name, entry, entry->dev, flags); diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-conf-handling-for-amd-maps.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-conf-handling-for-amd-maps.patch new file mode 100644 index 0000000..413cfeb --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-conf-handling-for-amd-maps.patch @@ -0,0 +1,1063 @@ +autofs-5.0.9 - amd lookup add conf handling for amd maps + +From: Ian Kent + + +--- + include/defaults.h | 111 ++++++++ + lib/defaults.c | 753 ++++++++++++++++++++++++++++++++++++++++++++++++---- + 2 files changed, 811 insertions(+), 53 deletions(-) + +diff --git a/include/defaults.h b/include/defaults.h +index 3bfcd49..033acaf 100644 +--- a/include/defaults.h ++++ b/include/defaults.h +@@ -46,6 +46,91 @@ + + #define DEFAULT_MAP_HASH_TABLE_SIZE "1024" + ++/* Config entry flags */ ++#define CONF_NONE 0x00000000 ++#define CONF_ENV 0x00000001 ++#define CONF_NOTUSED 0x00000002 ++#define CONF_NOTSUP 0x00000004 ++#define CONF_BROWSABLE_DIRS 0x00000008 ++#define CONF_MOUNT_TYPE_AUTOFS 0x00000010 ++#define CONF_SELECTORS_IN_DEFAULTS 0x00000020 ++#define CONF_NORMALIZE_HOSTNAMES 0x00000040 ++#define CONF_PROCESS_LOCK 0x00000080 ++#define CONF_RESTART_EXISTING_MOUNTS 0x00000100 ++#define CONF_SHOW_STATFS_ENTRIES 0x00000200 ++#define CONF_FULLY_QUALIFIED_HOSTS 0x00000400 ++#define CONF_UNMOUNT_ON_EXIT 0x00000800 ++#define CONF_AUTOFS_USE_LOFS 0x00001000 ++#define CONF_DOMAIN_STRIP 0x00002000 ++#define CONF_NORMALIZE_SLASHES 0x00004000 ++#define CONF_FORCED_UNMOUNTS 0x00008000 ++ ++#define DEFAULT_AMD_NULL_VALUE NULL ++ ++#define DEFAULT_AMD_AUTO_ATTRCACHE DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_AUTO_DIR "/a" ++#define DEFAULT_AMD_AUTOFS_USE_LOFS "yes" ++#define DEFAULT_AMD_BROWSABLE_DIRS "no" ++#define DEFAULT_AMD_CACHE_DURATION "300" ++#define DEFAULT_AMD_CLUSTER DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_DEBUG_MTAB_FILE DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_DEBUG_OPTIONS DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_DISMOUNT_INTERVAL DEFAULT_TIMEOUT ++#define DEFAULT_AMD_DOMAIN_STRIP "yes" ++#define DEFAULT_AMD_EXEC_MAP_TIMEOUT "10" ++#define DEFAULT_AMD_FORCED_UMOUNTS "no" ++#define DEFAULT_AMD_FULLY_QUALIFIED_HOSTS "no" ++#define DEFAULT_AMD_FULL_OS DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_HESIOD_BASE "automount" ++#define DEFAULT_AMD_KARCH DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_LDAP_BASE DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_LDAP_CACHE_MAXMEM "131072" ++#define DEFAULT_AMD_LDAP_CACHE_SECONDS "0" ++#define DEFAULT_AMD_LDAP_HOSTPORTS DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_LDAP_PROTO_VERSION "2" ++#define DEFAULT_AMD_SUB_DOMAIN DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_LOCALHOST_ADDRESS "localhost" ++#define DEFAULT_AMD_LOG_FILE DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_LOG_OPTIONS "defaults" ++#define DEFAULT_AMD_MAP_DEFAULTS DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_MAP_OPTIONS DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_MAP_RELOAD_INTERVAL "3600" ++#define DEFAULT_AMD_MAP_TYPE DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_MOUNT_TYPE "autofs" ++#define DEFAULT_AMD_PID_FILE DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_PORTMAP_PROGRAM DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_PREFERRED_AMQ_PORT DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_ALLOW_ANY_INTERFACE DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_ALLOW_INSECURE_PORT DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_PROTO DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_RETRANSMIT_COUNTER DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_RETRANSMIT_COUNTER_UDP DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_RETRANSMIT_COUNTER_TCP DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_RETRANSMIT_COUNTER_TOPLVL DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_RETRY_INTERVAL DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_RETRY_INTERVAL_UDP DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_RETRY_INTERVAL_TCP DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_RETRY_INTERVAL_TOPLVL DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_VERS DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NFS_VERS_PING DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NIS_DOMAIN DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_NORMALIZE_HOSTNAMES "no" ++#define DEFAULT_AMD_NORMALIZE_SLASHES "yes" ++#define DEFAULT_AMD_OS DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_OSVER DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_PLOCK "yes" ++#define DEFAULT_AMD_PRINT_PID DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_PRINT_VERSION DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_RESTART_MOUNTS "no" ++#define DEFAULT_AMD_SEARCH_PATH DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_SELECTORS_IN_DEFAULTS "no" ++#define DEFAULT_AMD_SHOW_STATFS_ENTRIES DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_SUN_MAP_SYNTAX DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_TRUNCATE_LOG DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_UMOUNT_ON_EXIT "yes" ++#define DEFAULT_AMD_USE_TCPWRAPPERS DEFAULT_AMD_NULL_VALUE ++#define DEFAULT_AMD_VENDOR "unknown" ++ + #ifdef WITH_LDAP + struct ldap_schema; + struct ldap_searchdn; +@@ -75,5 +160,31 @@ 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 conf_amd_mount_section_exists(const char *); ++char *conf_amd_get_arch(void); ++char *conf_amd_get_karch(void); ++char *conf_amd_get_os(void); ++char *conf_amd_get_os_ver(void); ++char *conf_amd_get_vendor(void); ++char *conf_amd_get_full_os(void); ++char *conf_amd_get_auto_dir(void); ++char *conf_amd_get_cluster(void); ++unsigned int conf_amd_get_exec_map_timeout(void); ++char *conf_amd_get_hesiod_base(void); ++char *conf_amd_get_karch(void); ++char *conf_amd_get_ldap_base(void); ++char *conf_amd_get_ldap_hostports(void); ++char *conf_amd_get_sub_domain(void); ++char *conf_amd_get_localhost_address(void); ++unsigned int conf_amd_get_log_options(void); ++char *conf_amd_get_nfs_proto(void); ++char *conf_amd_get_nis_domain(void); ++unsigned int conf_amd_set_nis_domain(const char *); ++char *conf_amd_get_map_defaults(const char *); ++char *conf_amd_get_map_type(const char *); ++char *conf_amd_get_search_path(const char *); ++unsigned int conf_amd_get_dismount_interval(const char *); ++unsigned long conf_amd_get_flags(const char *); ++ + #endif + +diff --git a/lib/defaults.c b/lib/defaults.c +index 29f3f00..bb304f3 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -18,6 +18,7 @@ + #include + #include + #include ++#include + #include + + #include "config.h" +@@ -30,9 +31,11 @@ + #include "automount.h" + + #define AUTOFS_GLOBAL_SECTION "autofs" ++#define AMD_GLOBAL_SECTION "amd" + + #define DEFAULT_CONFIG_FILE AUTOFS_CONF_DIR "/autofs" + #define MAX_LINE_LEN 256 ++#define MAX_SECTION_NAME MAX_LINE_LEN + + #define NAME_MASTER_MAP "master_map_name" + +@@ -61,20 +64,84 @@ + + #define NAME_MAP_HASH_TABLE_SIZE "map_hash_table_size" + ++#define NAME_AMD_ARCH "arch" ++#define NAME_AMD_AUTO_ATTRCACHE "auto_attrcache" ++#define NAME_AMD_AUTO_DIR "auto_dir" ++#define NAME_AMD_AUTOFS_USE_LOFS "autofs_use_lofs" ++#define NAME_AMD_BROWSABLE_DIRS "browsable_dirs" ++#define NAME_AMD_CACHE_DURATION "cache_duration" ++#define NAME_AMD_CLUSTER "cluster" ++#define NAME_AMD_DEBUG_MTAB_FILE "debug_mtab_file" ++#define NAME_AMD_DEBUG_OPTIONS "debug_options" ++#define NAME_AMD_DISMOUNT_INTERVAL "dismount_interval" ++#define NAME_AMD_DOMAIN_STRIP "domain_strip" ++#define NAME_AMD_EXEC_MAP_TIMEOUT "exec_map_timeout" ++#define NAME_AMD_FORCED_UMOUNTS "forced_unmounts" ++#define NAME_AMD_FULLY_QUALIFIED_HOSTS "fully_qualified_hosts" ++#define NAME_AMD_FULL_OS "full_os" ++#define NAME_AMD_HESIOD_BASE "hesiod_base" ++#define NAME_AMD_KARCH "karch" ++#define NAME_AMD_LDAP_BASE "ldap_base" ++#define NAME_AMD_LDAP_CACHE_MAXMEM "ldap_cache_maxmem" ++#define NAME_AMD_LDAP_CACHE_SECONDS "ldap_cache_seconds" ++#define NAME_AMD_LDAP_HOSTPORTS "ldap_hostports" ++#define NAME_AMD_LDAP_PROTO_VERSION "ldap_proto_version" ++#define NAME_AMD_SUB_DOMAIN "local_domain" ++#define NAME_AMD_LOCALHOST_ADDRESS "localhost_address" ++#define NAME_AMD_LOG_FILE "log_file" ++#define NAME_AMD_LOG_OPTIONS "log_options" ++#define NAME_AMD_MAP_DEFAULTS "map_defaults" ++#define NAME_AMD_MAP_OPTIONS "map_options" ++#define NAME_AMD_MAP_RELOAD_INTERVAL "map_reload_interval" ++#define NAME_AMD_MAP_TYPE "map_type" ++#define NAME_AMD_MOUNT_TYPE "mount_type" ++#define NAME_AMD_PID_FILE "pid_file" ++#define NAME_AMD_PORTMAP_PROGRAM "portmap_program" ++#define NAME_AMD_PREFERRED_AMQ_PORT "preferred_amq_port" ++#define NAME_AMD_NFS_ALLOW_ANY_INTERFACE "nfs_allow_any_interface" ++#define NAME_AMD_NFS_ALLOW_INSECURE_PORT "nfs_allow_insecure_port" ++#define NAME_AMD_NFS_PROTO "nfs_proto" ++#define NAME_AMD_NFS_RETRANSMIT_COUNTER "nfs_retransmit_counter" ++#define NAME_AMD_NFS_RETRANSMIT_COUNTER_UDP "nfs_retransmit_counter_udp" ++#define NAME_AMD_NFS_RETRANSMIT_COUNTER_TCP "nfs_retransmit_counter_tcp" ++#define NAME_AMD_NFS_RETRANSMIT_COUNTER_TOPLVL "nfs_retransmit_counter_toplvl" ++#define NAME_AMD_NFS_RETRY_INTERVAL "nfs_retry_interval" ++#define NAME_AMD_NFS_RETRY_INTERVAL_UDP "nfs_retry_interval_udp" ++#define NAME_AMD_NFS_RETRY_INTERVAL_TCP "nfs_retry_interval_tcp" ++#define NAME_AMD_NFS_RETRY_INTERVAL_TOPLVL "nfs_retry_interval_toplvl" ++#define NAME_AMD_NFS_VERS "nfs_vers" ++#define NAME_AMD_NFS_VERS_PING "nfs_vers_ping" ++#define NAME_AMD_NIS_DOMAIN "nis_domain" ++#define NAME_AMD_NORMALIZE_HOSTNAMES "normalize_hostnames" ++#define NAME_AMD_NORMALIZE_SLASHES "normalize_slashes" ++#define NAME_AMD_OS "os" ++#define NAME_AMD_OSVER "osver" ++#define NAME_AMD_PLOCK "plock" ++#define NAME_AMD_PRINT_PID "print_pid" ++#define NAME_AMD_PRINT_VERSION "print_version" ++#define NAME_AMD_RESTART_MOUNTS "restart_mounts" ++#define NAME_AMD_SEARCH_PATH "search_path" ++#define NAME_AMD_SELECTORS_ON_DEFAULT "selectors_on_default" ++#define NAME_AMD_SELECTORS_IN_DEFAULTS "selectors_in_defaults" ++#define NAME_AMD_SHOW_STATFS_ENTRIES "show_statfs_entries" ++#define NAME_AMD_SUN_MAP_SYNTAX "sun_map_syntax" ++#define NAME_AMD_TRUNCATE_LOG "truncate_log" ++#define NAME_AMD_UMOUNT_ON_EXIT "unmount_on_exit" ++#define NAME_AMD_USE_TCPWRAPPERS "use_tcpwrappers" ++#define NAME_AMD_VENDOR "vendor" ++ + /* Status returns */ + #define CFG_OK 0x0000 + #define CFG_FAIL 0x0001 + #define CFG_EXISTS 0x0002 + #define CFG_NOTFOUND 0x0004 + +-/* Config entry flags */ +-#define CONF_ENV 0x00000001 +- + #define CFG_TABLE_SIZE 128 + + static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME; + static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE; + static const char *autofs_gbl_sec = AUTOFS_GLOBAL_SECTION; ++static const char *amd_gbl_sec = AMD_GLOBAL_SECTION; + + struct conf_option { + char *section; +@@ -288,30 +355,211 @@ error: + return 0; + } + ++static int conf_load_amd_defaults(void) ++{ ++ struct utsname uts; ++ const char *sec = amd_gbl_sec; ++ char *host_os_name, *host_os_version, *host_arch; ++ int ret; ++ ++ if (uname(&uts)) { ++ host_os_name = uts.sysname; ++ host_os_version = uts.release; ++ host_arch = uts.machine; ++ } else { ++ host_os_name = NULL; ++ host_os_version = NULL; ++ host_arch = NULL; ++ } ++ ++ ret = conf_update(sec, NAME_AMD_ARCH, host_arch, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_KARCH, host_arch, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_OS, host_os_name, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_OSVER, host_os_version, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_AUTO_DIR, ++ DEFAULT_AMD_AUTO_DIR, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_AUTOFS_USE_LOFS, ++ DEFAULT_AMD_AUTO_DIR, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_BROWSABLE_DIRS, ++ DEFAULT_AMD_BROWSABLE_DIRS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_CLUSTER, ++ DEFAULT_AMD_CLUSTER, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ /* ++ * DISMOUNT_INTERVAL defers to the autofs default so we ++ * don't set an amd default in the configuration. ++ */ ++ /*ret = conf_update(sec, NAME_AMD_DISMOUNT_INTERVAL, ++ DEFAULT_AMD_DISMOUNT_INTERVAL, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error;*/ ++ ++ ret = conf_update(sec, NAME_AMD_DOMAIN_STRIP, ++ DEFAULT_AMD_DOMAIN_STRIP, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_EXEC_MAP_TIMEOUT, ++ DEFAULT_AMD_EXEC_MAP_TIMEOUT, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_FORCED_UMOUNTS, ++ DEFAULT_AMD_FORCED_UMOUNTS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_FULLY_QUALIFIED_HOSTS, ++ DEFAULT_AMD_FULLY_QUALIFIED_HOSTS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_FULL_OS, ++ DEFAULT_AMD_FULL_OS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_HESIOD_BASE, ++ DEFAULT_AMD_HESIOD_BASE, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_KARCH, host_arch, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_LDAP_BASE, ++ DEFAULT_AMD_LDAP_BASE, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_LDAP_HOSTPORTS, ++ DEFAULT_AMD_LDAP_HOSTPORTS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_SUB_DOMAIN, ++ DEFAULT_AMD_SUB_DOMAIN, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_LOCALHOST_ADDRESS, ++ DEFAULT_AMD_LOCALHOST_ADDRESS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_LOG_OPTIONS, ++ DEFAULT_AMD_LOG_OPTIONS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_MAP_DEFAULTS, ++ DEFAULT_AMD_MAP_DEFAULTS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_MAP_TYPE, ++ DEFAULT_AMD_MAP_TYPE, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_NIS_DOMAIN, ++ DEFAULT_AMD_NIS_DOMAIN, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_NORMALIZE_HOSTNAMES, ++ DEFAULT_AMD_NORMALIZE_HOSTNAMES, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_NORMALIZE_SLASHES, ++ DEFAULT_AMD_NORMALIZE_SLASHES, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_OS, host_os_name, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_RESTART_MOUNTS, ++ DEFAULT_AMD_RESTART_MOUNTS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_SEARCH_PATH, ++ DEFAULT_AMD_SEARCH_PATH, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ /* selectors_on_default is depricated, use selectors_in_defaults */ ++ ret = conf_update(sec, NAME_AMD_SELECTORS_ON_DEFAULT, ++ DEFAULT_AMD_SELECTORS_IN_DEFAULTS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_SELECTORS_IN_DEFAULTS, ++ DEFAULT_AMD_SELECTORS_IN_DEFAULTS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_UMOUNT_ON_EXIT, ++ DEFAULT_AMD_UMOUNT_ON_EXIT, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AMD_VENDOR, ++ DEFAULT_AMD_VENDOR, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ return 1; ++ ++error: ++ return 0; ++} ++ + static int conf_add(const char *section, const char *key, const char *value, unsigned long flags) + { + struct conf_option *co; + char *sec, *name, *val, *tmp; + unsigned int size = CFG_TABLE_SIZE; + u_int32_t index; +- int ret; +- +- sec = name = val = NULL; +- +- co = conf_lookup(section, key); +- if (co) { +- ret = CFG_EXISTS; +- goto error; +- } ++ int ret = CFG_FAIL; + +- ret = CFG_FAIL; ++ sec = name = val = tmp = NULL; + + /* Environment overrides file value */ +- if (((flags & CFG_ENV) && (tmp = getenv(key))) || value) { ++ if (((flags & CONF_ENV) && (tmp = getenv(key))) || value) { + if (tmp) + val = strdup(tmp); +- else +- val = strdup(value); ++ else { ++ if (value) ++ val = strdup(value); ++ } + if (!val) + goto error; + } +@@ -335,7 +583,7 @@ static int conf_add(const char *section, const char *key, const char *value, uns + co->next = NULL; + + /* Don't change user set values in the environment */ +- if (flags & CONF_ENV) ++ if (flags & CONF_ENV && value) + setenv(name, value, 0); + + index = hash(key, size); +@@ -386,7 +634,7 @@ static void conf_delete(const char *section, const char *key) + + free(co->section); + free(co->name); +- if (co->value); ++ if (co->value) + free(co->value); + free(co); + } +@@ -403,13 +651,15 @@ static int conf_update(const char *section, + if (!co) + ret = conf_add(section, key, value, flags); + else { +- char *val = NULL, *tmp; ++ char *val = NULL, *tmp = NULL; + /* Environment overrides file value */ + if (((flags & CONF_ENV) && (tmp = getenv(key))) || value) { + if (tmp) + val = strdup(tmp); +- else +- val = strdup(value); ++ else { ++ if (value) ++ val = strdup(value); ++ } + if (!val) + goto error; + } +@@ -419,7 +669,7 @@ static int conf_update(const char *section, + if (flags) + co->flags = flags; + /* Don't change user set values in the environment */ +- if (flags & CONF_ENV) ++ if (flags & CONF_ENV && value) + setenv(key, value, 0); + } + +@@ -456,15 +706,39 @@ static struct conf_option *conf_lookup(const char *section, const char *key) + return co; + } + ++static unsigned int conf_section_exists(const char *section) ++{ ++ struct conf_option *co; ++ int ret; ++ ++ if (!section) ++ return 0; ++ ++ ret = 0; ++ pthread_mutex_lock(&conf_mutex); ++ co = conf_lookup(section, section); ++ if (co) ++ ret = 1; ++ pthread_mutex_unlock(&conf_mutex); ++ ++ return ret; ++} ++ + /* + * We've changed the key names so we need to check for the + * config key and it's old name for backward conpatibility. + */ +-static int check_set_config_value(const char *res, const char *value) ++static int check_set_config_value(const char *section, ++ const char *res, const char *value) + { +- const char *sec = autofs_gbl_sec; ++ const char *sec; + int ret; + ++ if (section) ++ sec = section; ++ else ++ sec = autofs_gbl_sec; ++ + if (!strcasecmp(res, NAME_LDAP_URI)) + ret = conf_add(sec, res, value, 0); + else if (!strcasecmp(res, NAME_SEARCH_BASE)) +@@ -475,14 +749,15 @@ static int check_set_config_value(const char *res, const char *value) + return ret; + } + +-static int parse_line(char *line, char **res, char **value) ++static int parse_line(char *line, char **sec, char **res, char **value) + { + char *key, *val, *trailer; ++ char *tmp; + int len; + + key = line; + +- if (*key == '#' || !isalpha(*key)) ++ if (*key == '#' || (*key != '[' && !isalpha(*key))) + return 0; + + while (*key && *key == ' ') +@@ -491,11 +766,34 @@ static int parse_line(char *line, char **res, char **value) + if (!*key) + return 0; + ++ if (*key == '[') { ++ char *tmp; ++ while (*key && (*key == '[' || *key == ' ')) ++ key++; ++ tmp = strchr(key, ']'); ++ if (!tmp) ++ return 0; ++ *tmp = ' '; ++ while (*tmp && *tmp == ' ') { ++ *tmp = '\0'; ++ tmp--; ++ } ++ *sec = key; ++ *res = NULL; ++ *value = NULL; ++ return 1; ++ } ++ + if (!(val = strchr(key, '='))) + return 0; + ++ tmp = val; ++ + *val++ = '\0'; + ++ while (*(--tmp) == ' ') ++ *tmp = '\0'; ++ + while (*val && (*val == '"' || isblank(*val))) + val++; + +@@ -515,12 +813,97 @@ static int parse_line(char *line, char **res, char **value) + while (*trailer && (*trailer == '"' || isblank(*trailer))) + *(trailer--) = '\0';; + ++ *sec = NULL; + *res = key; + *value = val; + + return 1; + } + ++static int read_config(unsigned int to_syslog, FILE *f, const char *name) ++{ ++ char buf[MAX_LINE_LEN]; ++ char secbuf[MAX_SECTION_NAME]; ++ char *new_sec; ++ char *res; ++ ++ new_sec = NULL; ++ while ((res = fgets(buf, MAX_LINE_LEN, f))) { ++ char *sec, *key, *value; ++ sec = key = value = NULL; ++ if (!parse_line(res, &sec, &key, &value)) ++ continue; ++ if (sec) { ++ strcpy(secbuf, sec); ++ new_sec = &secbuf[0]; ++ conf_update(sec, sec, NULL, 0); ++ continue; ++ } ++ if (!strcasecmp(res, NAME_AMD_MOUNT_TYPE)) { ++ message(to_syslog, ++ "%s is always autofs, ignored", res); ++ continue; ++ } ++ if (!strcasecmp(res, NAME_AMD_PID_FILE)) { ++ message(to_syslog, ++ "%s must be specified as a command line" ++ " option, ignored", res); ++ continue; ++ } ++ if (!strcasecmp(res, NAME_AMD_RESTART_MOUNTS)) { ++ message(to_syslog, ++ "%s is always done by autofs, ignored", res); ++ continue; ++ } ++ if (!strcasecmp(res, NAME_AMD_USE_TCPWRAPPERS) || ++ !strcasecmp(res, NAME_AMD_AUTO_ATTRCACHE) || ++ !strcasecmp(res, NAME_AMD_PRINT_PID) || ++ !strcasecmp(res, NAME_AMD_PRINT_VERSION) || ++ !strcasecmp(res, NAME_AMD_LOG_FILE) || ++ !strcasecmp(res, NAME_AMD_PREFERRED_AMQ_PORT) || ++ !strcasecmp(res, NAME_AMD_TRUNCATE_LOG) || ++ !strcasecmp(res, NAME_AMD_DEBUG_MTAB_FILE) || ++ !strcasecmp(res, NAME_AMD_DEBUG_OPTIONS) || ++ !strcasecmp(res, NAME_AMD_SUN_MAP_SYNTAX) || ++ !strcasecmp(res, NAME_AMD_PORTMAP_PROGRAM) || ++ !strcasecmp(res, NAME_AMD_NFS_VERS) || ++ !strcasecmp(res, NAME_AMD_NFS_VERS_PING) || ++ !strcasecmp(res, NAME_AMD_NFS_PROTO) || ++ !strcasecmp(res, NAME_AMD_NFS_ALLOW_ANY_INTERFACE) || ++ !strcasecmp(res, NAME_AMD_NFS_ALLOW_INSECURE_PORT) || ++ !strcasecmp(res, NAME_AMD_NFS_RETRANSMIT_COUNTER) || ++ !strcasecmp(res, NAME_AMD_NFS_RETRANSMIT_COUNTER_UDP) || ++ !strcasecmp(res, NAME_AMD_NFS_RETRANSMIT_COUNTER_TCP) || ++ !strcasecmp(res, NAME_AMD_NFS_RETRANSMIT_COUNTER_TOPLVL) || ++ !strcasecmp(res, NAME_AMD_NFS_RETRY_INTERVAL) || ++ !strcasecmp(res, NAME_AMD_NFS_RETRY_INTERVAL_UDP) || ++ !strcasecmp(res, NAME_AMD_NFS_RETRY_INTERVAL_TCP) || ++ !strcasecmp(res, NAME_AMD_NFS_RETRY_INTERVAL_TOPLVL) || ++ !strcasecmp(res, NAME_AMD_LDAP_CACHE_MAXMEM) || ++ !strcasecmp(res, NAME_AMD_LDAP_CACHE_SECONDS) || ++ !strcasecmp(res, NAME_AMD_LDAP_PROTO_VERSION) || ++ !strcasecmp(res, NAME_AMD_SHOW_STATFS_ENTRIES) || ++ !strcasecmp(res, NAME_AMD_CACHE_DURATION) || ++ !strcasecmp(res, NAME_AMD_MAP_RELOAD_INTERVAL) || ++ !strcasecmp(res, NAME_AMD_MAP_OPTIONS) || ++ !strcasecmp(res, NAME_AMD_PLOCK)) { ++ message(to_syslog, ++ "%s is not used by autofs, ignored", res); ++ continue; ++ } ++ check_set_config_value(new_sec, key, value); ++ } ++ ++ if (!feof(f) || ferror(f)) { ++ message(to_syslog, ++ "fgets returned error %d while reading config %s", ++ ferror(f), name); ++ return 0; ++ } ++ ++ return 0; ++} ++ + /* + * Read config env variables and check they have been set. + * +@@ -531,23 +914,11 @@ static int parse_line(char *line, char **res, char **value) + unsigned int defaults_read_config(unsigned int to_syslog) + { + FILE *f; +- char buf[MAX_LINE_LEN]; + struct stat stb; +- char *res; + int ret; + +- f = open_fopen_r(DEFAULT_CONFIG_FILE); +- if (!f) +- return 0; +- + pthread_mutex_lock(&conf_mutex); +- if (config) { +- if (fstat(fileno(f), &stb) != -1) { +- /* Config hasn't been updated */ +- if (stb.st_mtime <= config->modified) +- goto out; +- } +- } else { ++ if (!config) { + if (conf_init()) { + pthread_mutex_unlock(&conf_mutex); + message(to_syslog, "failed to init config"); +@@ -563,29 +934,39 @@ unsigned int defaults_read_config(unsigned int to_syslog) + return 0; + } + +- while ((res = fgets(buf, MAX_LINE_LEN, f))) { +- char *key, *value; +- if (!parse_line(res, &key, &value)) +- continue; +- check_set_config_value(key, value); ++ ret = conf_load_amd_defaults(); ++ if (!ret) { ++ pthread_mutex_unlock(&conf_mutex); ++ message(to_syslog, "failed to reset amd default config"); ++ return 0; ++ } ++ ++ f = open_fopen_r(DEFAULT_CONFIG_FILE); ++ if (!f) { ++ message(to_syslog, "failed to to open config %s", ++ DEFAULT_CONFIG_FILE); ++ goto out; ++ } ++ ++ if (fstat(fileno(f), &stb) != -1) { ++ /* Config hasn't been updated */ ++ if (stb.st_mtime <= config->modified) { ++ fclose(f); ++ goto out; ++ } + } + ++ ret = read_config(to_syslog, f, DEFAULT_CONFIG_FILE); ++ + if (fstat(fileno(f), &stb) != -1) + config->modified = stb.st_mtime; + else + message(to_syslog, "failed to update config modified time"); + +- if (!feof(f) || ferror(f)) { +- pthread_mutex_unlock(&conf_mutex); +- message(to_syslog, +- "fgets returned error %d while reading %s", +- ferror(f), DEFAULT_CONFIG_FILE); +- fclose(f); +- return 0; +- } ++ fclose(f); ++ + out: + pthread_mutex_unlock(&conf_mutex); +- fclose(f); + return 1; + } + +@@ -1101,3 +1482,269 @@ unsigned int defaults_get_map_hash_table_size(void) + return (unsigned int) size; + } + ++unsigned int conf_amd_mount_section_exists(const char *section) ++{ ++ return conf_section_exists(section); ++} ++ ++char *conf_amd_get_arch(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_ARCH); ++} ++ ++char *conf_amd_get_karch(void) ++{ ++ char *tmp = conf_get_string(amd_gbl_sec, NAME_AMD_KARCH); ++ if (!tmp) ++ tmp = conf_amd_get_arch(); ++ ++ return tmp; ++} ++ ++char *conf_amd_get_os(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_OS); ++} ++ ++char *conf_amd_get_os_ver(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_OSVER); ++} ++ ++char *conf_amd_get_vendor(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_VENDOR); ++} ++ ++char *conf_amd_get_full_os(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_FULL_OS); ++} ++ ++char *conf_amd_get_auto_dir(void) ++{ ++ char *tmp = conf_get_string(amd_gbl_sec, NAME_AMD_AUTO_DIR); ++ if (!tmp) ++ return strdup(DEFAULT_AMD_AUTO_DIR); ++ ++ return tmp; ++} ++ ++char *conf_amd_get_cluster(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_CLUSTER); ++} ++ ++unsigned int conf_amd_get_exec_map_timeout(void) ++{ ++ long tmp = conf_get_number(amd_gbl_sec, NAME_AMD_EXEC_MAP_TIMEOUT); ++ if (tmp == -1) ++ tmp = atoi(DEFAULT_AMD_EXEC_MAP_TIMEOUT); ++ ++ return (unsigned int) tmp; ++} ++ ++char *conf_amd_get_hesiod_base(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_HESIOD_BASE); ++} ++ ++char *conf_amd_get_ldap_base(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_LDAP_BASE); ++} ++ ++char *conf_amd_get_ldap_hostports(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_LDAP_HOSTPORTS); ++} ++ ++unsigned int conf_amd_get_ldap_proto_version(void) ++{ ++ long tmp = conf_get_number(amd_gbl_sec, NAME_AMD_LDAP_PROTO_VERSION); ++ if (tmp == -1) ++ tmp = atoi(DEFAULT_AMD_LDAP_PROTO_VERSION); ++ ++ return (unsigned int) tmp; ++} ++ ++char *conf_amd_get_sub_domain(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_SUB_DOMAIN); ++} ++ ++char *conf_amd_get_localhost_address(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_LOCALHOST_ADDRESS); ++} ++ ++unsigned int conf_amd_get_log_options(void) ++{ ++ int log_level = -1; ++ char *tmp = conf_get_string(amd_gbl_sec, NAME_AMD_LOG_OPTIONS); ++ if (tmp) { ++ if (strstr(tmp, "debug") || strstr(tmp, "all")) { ++ if (log_level < LOG_DEBUG) ++ log_level = LOG_DEBUG; ++ } ++ if (strstr(tmp, "info") || ++ strstr(tmp, "user") || ++ strcmp(tmp, "defaults")) { ++ if (log_level < LOG_INFO) ++ log_level = LOG_INFO; ++ } ++ if (strstr(tmp, "notice")) { ++ if (log_level < LOG_NOTICE) ++ log_level = LOG_NOTICE; ++ } ++ if (strstr(tmp, "warn") || ++ strstr(tmp, "map") || ++ strstr(tmp, "stats") || ++ strstr(tmp, "warning")) { ++ if (log_level < LOG_WARNING) ++ log_level = LOG_WARNING; ++ } ++ if (strstr(tmp, "error")) { ++ if (log_level < LOG_ERR) ++ log_level = LOG_ERR; ++ } ++ if (strstr(tmp, "fatal")) { ++ if (log_level < LOG_CRIT) ++ log_level = LOG_CRIT; ++ } ++ } ++ ++ if (log_level == -1) ++ log_level = LOG_ERR; ++ ++ return (unsigned int) log_level; ++} ++ ++char *conf_amd_get_nis_domain(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_NIS_DOMAIN); ++} ++ ++unsigned int conf_amd_set_nis_domain(const char *domain) ++{ ++ int ret; ++ ret = conf_update(amd_gbl_sec, NAME_AMD_NIS_DOMAIN, domain, CONF_NONE); ++ ++ return (unsigned int) ret; ++} ++ ++char *conf_amd_get_map_defaults(const char *section) ++{ ++ char *tmp = NULL; ++ if (section) ++ tmp = conf_get_string(section, NAME_AMD_MAP_DEFAULTS); ++ if (!tmp) ++ tmp = conf_get_string(amd_gbl_sec, NAME_AMD_MAP_DEFAULTS); ++ ++ return tmp; ++} ++ ++char *conf_amd_get_map_type(const char *section) ++{ ++ char *tmp = NULL; ++ if (section) ++ tmp = conf_get_string(section, NAME_AMD_MAP_TYPE); ++ if (!tmp) ++ tmp = conf_get_string(amd_gbl_sec, NAME_AMD_MAP_TYPE); ++ ++ return tmp; ++} ++ ++char *conf_amd_get_search_path(const char *section) ++{ ++ char *tmp = NULL; ++ if (section) ++ tmp = conf_get_string(section, NAME_AMD_SEARCH_PATH); ++ if (!tmp) ++ tmp = conf_get_string(amd_gbl_sec, NAME_AMD_SEARCH_PATH); ++ ++ return tmp; ++} ++ ++unsigned int conf_amd_get_dismount_interval(const char *section) ++{ ++ long tmp = -1; ++ if (section) ++ tmp = conf_get_number(section, NAME_AMD_DISMOUNT_INTERVAL); ++ if (tmp == -1) ++ tmp = conf_get_number(amd_gbl_sec, NAME_AMD_DISMOUNT_INTERVAL); ++ if (tmp == -1) ++ tmp = defaults_get_timeout(); ++ /* ++ * This won't happen as defaults_get_timeout() will return ++ * the autofs setting which is used if no other setting is ++ * found. ++ */ ++ if (tmp == -1) ++ tmp = atoi(DEFAULT_TIMEOUT); ++ ++ return (unsigned int) tmp; ++} ++ ++unsigned long conf_amd_get_flags(const char *section) ++{ ++ const char *amd = amd_gbl_sec; ++ unsigned long flags, tmp; ++ ++ /* Always true for us */ ++ flags = CONF_MOUNT_TYPE_AUTOFS; ++ ++ tmp = -1; ++ if (section) ++ tmp = conf_get_yesno(section, NAME_AMD_BROWSABLE_DIRS); ++ if (tmp == -1) ++ tmp = conf_get_yesno(amd, NAME_AMD_BROWSABLE_DIRS); ++ if (tmp) ++ flags |= CONF_BROWSABLE_DIRS; ++ ++ tmp = -1; ++ if (section) ++ tmp = conf_get_yesno(section, NAME_AMD_SELECTORS_IN_DEFAULTS); ++ if (tmp == -1) ++ tmp = conf_get_yesno(amd, NAME_AMD_SELECTORS_IN_DEFAULTS); ++ if (tmp) ++ flags |= CONF_SELECTORS_IN_DEFAULTS; ++ ++ tmp = conf_get_yesno(amd, NAME_AMD_NORMALIZE_HOSTNAMES); ++ if (tmp) ++ flags |= CONF_NORMALIZE_HOSTNAMES; ++ ++ tmp = conf_get_yesno(amd, NAME_AMD_RESTART_MOUNTS); ++ if (tmp) ++ flags |= CONF_RESTART_EXISTING_MOUNTS; ++ ++ tmp = conf_get_yesno(amd, NAME_AMD_FULLY_QUALIFIED_HOSTS); ++ if (tmp) ++ flags |= CONF_FULLY_QUALIFIED_HOSTS; ++ ++ tmp = conf_get_yesno(amd, NAME_AMD_UMOUNT_ON_EXIT); ++ if (tmp) ++ flags |= CONF_UNMOUNT_ON_EXIT; ++ ++ tmp = -1; ++ if (section) ++ tmp = conf_get_yesno(section, NAME_AMD_AUTOFS_USE_LOFS); ++ if (tmp == -1) ++ tmp = conf_get_yesno(amd, NAME_AMD_AUTOFS_USE_LOFS); ++ if (tmp) ++ flags |= CONF_AUTOFS_USE_LOFS; ++ ++ tmp = conf_get_yesno(amd, NAME_AMD_DOMAIN_STRIP); ++ if (tmp) ++ flags |= CONF_DOMAIN_STRIP; ++ ++ tmp = conf_get_yesno(amd, NAME_AMD_NORMALIZE_SLASHES); ++ if (tmp) ++ flags |= CONF_NORMALIZE_SLASHES; ++ ++ tmp = conf_get_yesno(amd, NAME_AMD_FORCED_UMOUNTS); ++ if (tmp) ++ flags |= CONF_FORCED_UNMOUNTS; ++ ++ return flags; ++} diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-cut-handling.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-cut-handling.patch new file mode 100644 index 0000000..afa2366 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-cut-handling.patch @@ -0,0 +1,49 @@ +autofs-5.0.9 - amd lookup add cut handling + +From: Ian Kent + +Now we have the added the selector handling we can add the cut location +handling. +--- + modules/parse_amd.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index d9c7d9b..5d8617e 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1425,6 +1425,7 @@ int parse_mount(struct autofs_point *ap, const char *name, + struct map_source *source; + struct mapent_cache *mc; + struct mapent *me; ++ unsigned int at_least_one; + struct list_head entries, *p, *head; + struct amd_entry *defaults_entry; + struct amd_entry *cur_defaults; +@@ -1517,6 +1518,7 @@ int parse_mount(struct autofs_point *ap, const char *name, + goto done; + } + ++ at_least_one = 0; + head = &entries; + p = head->next; + while (p != head) { +@@ -1540,9 +1542,18 @@ int parse_mount(struct autofs_point *ap, const char *name, + continue; + } + ++ if (this->flags & AMD_ENTRY_CUT && at_least_one) { ++ info(ap->logopt, MODPREFIX ++ "at least one entry tried before cut selector, " ++ "not continuing"); ++ break; ++ } ++ + if (!match_selectors(ap->logopt, this, sv)) + continue; + ++ at_least_one = 1; ++ + update_with_defaults(cur_defaults, this, sv); + sv = expand_entry(ap, this, flags, sv); + sv = merge_entry_options(ap, this, sv); diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-expandamdent-function.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-expandamdent-function.patch new file mode 100644 index 0000000..75b570b --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-expandamdent-function.patch @@ -0,0 +1,259 @@ +autofs-5.0.9 - amd lookup add expandamdent() function + +From: Ian Kent + + +--- + include/parse_subs.h | 2 + lib/parse_subs.c | 211 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 213 insertions(+) + +diff --git a/include/parse_subs.h b/include/parse_subs.h +index e57cf4a..675411d 100644 +--- a/include/parse_subs.h ++++ b/include/parse_subs.h +@@ -42,6 +42,8 @@ char *dequote(const char *, int, unsigned int); + int span_space(const char *, unsigned int); + char *sanitize_path(const char *, int, unsigned int, unsigned int); + char *merge_options(const char *, const char *); ++int expandamdent(const char *, char *, const struct substvar *); ++int expand_selectors(struct autofs_point *, const char *, char **, struct substvar *); + void free_map_type_info(struct map_type_info *); + struct map_type_info *parse_map_type_info(const char *); + +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index 99075b1..279f40e 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -20,6 +20,7 @@ + #include + #include + #include ++#include + #include + #include "automount.h" + +@@ -39,6 +40,11 @@ static int volatile ifc_last_len = 0; + /* Get numeric value of the n bits starting at position p */ + #define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) + ++#define EXPAND_LEADING_SLASH 0x0001 ++#define EXPAND_TRAILING_SLASH 0x0002 ++#define EXPAND_LEADING_DOT 0x0004 ++#define EXPAND_TRAILING_DOT 0x0008 ++ + struct types { + char *type; + unsigned int len; +@@ -636,6 +642,211 @@ next: + return strdup(result); + } + ++static char *expand_slash_or_dot(char *str, unsigned int type) ++{ ++ char *val = NULL; ++ ++ if (!str) ++ return NULL; ++ ++ if (!type) ++ return str; ++ ++ if (type & EXPAND_LEADING_SLASH) ++ val = basename(str); ++ else if (type & EXPAND_TRAILING_SLASH) ++ val = dirname(str); ++ else if (type & (EXPAND_LEADING_DOT | EXPAND_TRAILING_DOT)) { ++ char *dot = strchr(str, '.'); ++ if (dot) ++ *dot++ = '\0'; ++ if (type & EXPAND_LEADING_DOT) ++ val = dot; ++ else ++ val = str; ++ } ++ ++ return val; ++} ++ ++/* ++ * $-expand an amd-style map entry and return the length of the entry. ++ * If "dst" is NULL, just count the length. ++ */ ++/* TODO: how should quoting be handled? */ ++int expandamdent(const char *src, char *dst, const struct substvar *svc) ++{ ++ unsigned int flags = conf_amd_get_flags(NULL); ++ const struct substvar *sv; ++ const char *o_src = src; ++ int len, l; ++ const char *p; ++ char ch; ++ ++ len = 0; ++ ++ while ((ch = *src++)) { ++ switch (ch) { ++ case '$': ++ if (*src == '{') { ++ char *start, *end; ++ unsigned int type = 0; ++ p = strchr(++src, '}'); ++ if (!p) { ++ /* Ignore rest of string */ ++ if (dst) ++ *dst = '\0'; ++ return len; ++ } ++ start = (char *) src; ++ if (*src == '/' || *src == '.') { ++ start++; ++ type = EXPAND_LEADING_SLASH; ++ if (*src == '.') ++ type = EXPAND_LEADING_DOT; ++ } ++ end = (char *) p; ++ if (*(p - 1) == '/' || *(p - 1) == '.') { ++ end--; ++ type = EXPAND_TRAILING_SLASH; ++ if (*(p - 1) == '.') ++ type = EXPAND_TRAILING_DOT; ++ } ++ sv = macro_findvar(svc, start, end - start); ++ if (sv) { ++ char *val; ++ char *str = strdup(sv->val); ++ val = expand_slash_or_dot(str, type); ++ if (!val) ++ val = sv->val; ++ l = strlen(val); ++ if (dst) { ++ if (*dst) ++ strcat(dst, val); ++ else ++ strcpy(dst, val); ++ dst += l; ++ } ++ len += l; ++ if (str) ++ free(str); ++ } else { ++ if (dst) { ++ *dst++ = ch; ++ *dst++ = '{'; ++ strncat(dst, src, p - src); ++ dst += (p - src); ++ *dst++ = '}'; ++ } ++ len += 1 + 1 + (p - src) + 1; ++ } ++ src = p + 1; ++ } else { ++ if (dst) ++ *(dst++) = ch; ++ len++; ++ } ++ break; ++ ++ case '\\': ++ if (!(flags & CONF_NORMALIZE_SLASHES)) { ++ len++; ++ if (dst) ++ *dst++ = ch; ++ break; ++ } ++ ++ if (*src) { ++ len++; ++ if (dst) ++ *dst++ = *src; ++ src++; ++ } ++ break; ++ ++ case '/': ++ len++; ++ if (dst) ++ *dst++ = ch; ++ ++ if (!(flags & CONF_NORMALIZE_SLASHES)) ++ break; ++ ++ /* Double slash at start is allowed */ ++ if (src == (o_src + 1) && *src == '/') { ++ len++; ++ if (dst) ++ *dst++ = *src; ++ src++; ++ } ++ while (*src == '/') ++ src++; ++ break; ++ ++ case '"': ++ len++; ++ if (dst) ++ *dst++ = ch; ++ ++ while (*src && *src != '"') { ++ len++; ++ if (dst) ++ *dst++ = *src; ++ src++; ++ } ++ if (*src) { ++ len++; ++ if (dst) ++ *dst++ = *src; ++ src++; ++ } ++ break; ++ ++ default: ++ if (dst) ++ *(dst++) = ch; ++ len++; ++ break; ++ } ++ } ++ if (dst) ++ *dst = '\0'; ++ ++ return len; ++} ++ ++int expand_selectors(struct autofs_point *ap, ++ const char *mapstr, char **pmapstr, ++ struct substvar *sv) ++{ ++ char buf[MAX_ERR_BUF]; ++ char *expand; ++ size_t len; ++ ++ if (!mapstr) ++ return 0; ++ ++ len = expandamdent(mapstr, NULL, sv); ++ if (len == 0) { ++ error(ap->logopt, "failed to expand map entry"); ++ return 0; ++ } ++ ++ expand = malloc(len + 1); ++ if (!expand) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, "malloc: %s", estr); ++ return 0; ++ } ++ memset(expand, 0, len + 1); ++ ++ expandamdent(mapstr, expand, sv); ++ ++ *pmapstr = expand; ++ ++ return len; ++} ++ + void free_map_type_info(struct map_type_info *info) + { + if (info->type) diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-external-mounts-tracking-functions.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-external-mounts-tracking-functions.patch new file mode 100644 index 0000000..727535d --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-external-mounts-tracking-functions.patch @@ -0,0 +1,188 @@ +autofs-5.0.9 - amd lookup add external mounts tracking functions + +From: Ian Kent + +Amd automounts can use what's called a sublink option. Using this +option a single containing mount can be specified and symlinks +that point to directories within the mount created instead of a +mount for every directory. + +In some cases this can greatly reduce the number of mounts needed +for a map but complicates automounting when using an "in-place" +automounter such as autofs. + +Clearly we can't perform the mount and create symlinks within it +so we must us a mount lookaside directory like amd. Those external +mounts also need to be managed. + +This patch adds functions to maintain a list of these mounts (much +like a reference counter) so we know if an external mount is present +and if it's time to umount it. +--- + include/mounts.h | 2 + + lib/mounts.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 134 insertions(+) + +diff --git a/include/mounts.h b/include/mounts.h +index c2f92ec..3bef086 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -93,6 +93,8 @@ unsigned int get_kver_major(void); + unsigned int get_kver_minor(void); + char *make_options_string(char *path, int kernel_pipefd, const char *extra); + char *make_mnt_name_string(char *path); ++int ext_mount_add(struct list_head *, const char *); ++int ext_mount_remove(struct list_head *, const char *); + struct mnt_list *get_mnt_list(const char *table, const char *path, int include); + struct mnt_list *reverse_mnt_list(struct mnt_list *list); + void free_mnt_list(struct mnt_list *list); +diff --git a/lib/mounts.c b/lib/mounts.c +index 868dcb1..aea6691 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -46,6 +46,17 @@ static const char mnt_name_template[] = "automount(pid%u)"; + static struct kernel_mod_version kver = {0, 0}; + static const char kver_options_template[] = "fd=%d,pgrp=%u,minproto=3,maxproto=5"; + ++#define EXT_MOUNTS_HASH_SIZE 50 ++ ++struct ext_mount { ++ char *mountpoint; ++ struct list_head mount; ++ struct list_head mounts; ++}; ++static struct list_head ext_mounts_hash[EXT_MOUNTS_HASH_SIZE]; ++static unsigned int ext_mounts_hash_init_done = 0; ++static pthread_mutex_t ext_mount_hash_mutex = PTHREAD_MUTEX_INITIALIZER; ++ + unsigned int linux_version_code(void) + { + struct utsname my_utsname; +@@ -422,6 +433,127 @@ char *make_mnt_name_string(char *path) + return mnt_name; + } + ++static void ext_mounts_hash_init(void) ++{ ++ int i; ++ for (i = 0; i < EXT_MOUNTS_HASH_SIZE; i++) ++ INIT_LIST_HEAD(&ext_mounts_hash[i]); ++ ext_mounts_hash_init_done = 1; ++} ++ ++static struct ext_mount *ext_mount_lookup(const char *mountpoint) ++{ ++ u_int32_t hval = hash(mountpoint, EXT_MOUNTS_HASH_SIZE); ++ struct list_head *p, *head; ++ ++ if (!ext_mounts_hash_init_done) ++ ext_mounts_hash_init(); ++ ++ if (list_empty(&ext_mounts_hash[hval])) ++ return NULL; ++ ++ head = &ext_mounts_hash[hval]; ++ list_for_each(p, head) { ++ struct ext_mount *this = list_entry(p, struct ext_mount, mount); ++ if (!strcmp(this->mountpoint, mountpoint)) ++ return this; ++ } ++ return NULL; ++} ++ ++int ext_mount_add(struct list_head *entry, const char *path) ++{ ++ struct ext_mount *em; ++ char *auto_dir; ++ u_int32_t hval; ++ int ret = 0; ++ ++ /* Not a mount in the external mount directory */ ++ auto_dir = conf_amd_get_auto_dir(); ++ if (strncmp(path, auto_dir, strlen(auto_dir))) { ++ free(auto_dir); ++ return 0; ++ } ++ free(auto_dir); ++ ++ pthread_mutex_lock(&ext_mount_hash_mutex); ++ ++ em = ext_mount_lookup(path); ++ if (em) { ++ struct list_head *p, *head; ++ head = &em->mounts; ++ list_for_each(p, head) { ++ if (p == entry) ++ goto done; ++ } ++ list_add_tail(entry, &em->mounts); ++ ret = 1; ++ goto done; ++ } ++ ++ em = malloc(sizeof(struct ext_mount)); ++ if (!em) { ++ ret = -1; ++ goto done; ++ } ++ ++ em->mountpoint = strdup(path); ++ if (!em->mountpoint) { ++ free(em); ++ ret = -1; ++ goto done; ++ } ++ INIT_LIST_HEAD(&em->mount); ++ INIT_LIST_HEAD(&em->mounts); ++ ++ hval = hash(path, EXT_MOUNTS_HASH_SIZE); ++ list_add_tail(&em->mount, &ext_mounts_hash[hval]); ++ ++ list_add_tail(entry, &em->mounts); ++ ++ ret = 1; ++done: ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ return ret; ++} ++ ++int ext_mount_remove(struct list_head *entry, const char *path) ++{ ++ struct ext_mount *em; ++ char *auto_dir; ++ int ret = 0; ++ ++ /* Not a mount in the external mount directory */ ++ auto_dir = conf_amd_get_auto_dir(); ++ if (strncmp(path, auto_dir, strlen(auto_dir))) { ++ free(auto_dir); ++ return 0; ++ } ++ free(auto_dir); ++ ++ pthread_mutex_lock(&ext_mount_hash_mutex); ++ ++ em = ext_mount_lookup(path); ++ if (!em) ++ goto done; ++ ++ list_del_init(entry); ++ ++ if (!list_empty(&em->mounts)) ++ goto done; ++ else { ++ list_del_init(&em->mount); ++ if (list_empty(&em->mount)) { ++ free(em->mountpoint); ++ free(em); ++ } ++ ret = 1; ++ } ++done: ++ pthread_mutex_unlock(&ext_mount_hash_mutex); ++ return ret; ++} ++ + /* + * Get list of mounts under path in longest->shortest order + */ diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-handling-of-amd-maps-in-the-master-map.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-handling-of-amd-maps-in-the-master-map.patch new file mode 100644 index 0000000..f18e40d --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-handling-of-amd-maps-in-the-master-map.patch @@ -0,0 +1,361 @@ +autofs-5.0.9 - amd lookup add handling of amd maps in the master map + +From: Ian Kent + + +--- + daemon/automount.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++- + include/automount.h | 1 + + include/master.h | 2 + + lib/master.c | 44 +++++++++++++++++++++++++++ + lib/master_parse.y | 23 ++++++++++++-- + lib/master_tok.l | 2 + + lib/parse_subs.c | 1 + + modules/mount_autofs.c | 24 +++++++++++++++ + modules/parse_amd.c | 12 +++++++ + 9 files changed, 182 insertions(+), 6 deletions(-) + +diff --git a/daemon/automount.c b/daemon/automount.c +index fd5a19b..0ba3580 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -512,6 +512,9 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + left++; + } + cache_multi_unlock(me->parent); ++ if (ap->entry->maps && ++ (ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD)) ++ cache_pop_mapent(me); + pthread_setcancelstate(cur_state, NULL); + } + +@@ -525,13 +528,36 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + * it already to ensure it's ok to remove any offset triggers. + */ + if (!is_mm_root && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { ++ struct amd_entry *entry; + debug(ap->logopt, "unmounting dir = %s", path); + if (umount_ent(ap, path)) { + warn(ap->logopt, "could not umount dir %s", path); + left++; ++ goto done; + } +- } + ++ /* Check for an external mount and umount if possible */ ++ mounts_mutex_lock(ap); ++ entry = __master_find_amdmount(ap, path); ++ if (!entry) { ++ mounts_mutex_unlock(ap); ++ goto done; ++ } ++ list_del(&entry->entries); ++ mounts_mutex_unlock(ap); ++ if (ext_mount_remove(&entry->ext_mount, entry->fs)) { ++ if (umount_ent(ap, entry->fs)) ++ debug(ap->logopt, ++ "failed to umount external mount %s", ++ entry->fs); ++ else ++ debug(ap->logopt, ++ "umounted external mount %s", ++ entry->fs); ++ } ++ free_amd_entry(entry); ++ } ++done: + return left; + } + +@@ -540,10 +566,55 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + int umount_multi(struct autofs_point *ap, const char *path, int incl) + { + int is_autofs_fs; ++ struct stat st; + int left; + + debug(ap->logopt, "path %s incl %d", path, incl); + ++ if (lstat(path, &st)) { ++ warn(ap->logopt, ++ "failed to stat mount point directory %s", path); ++ return 1; ++ } ++ ++ /* if this is a symlink we can handle it now */ ++ if (S_ISLNK(st.st_mode)) { ++ struct amd_entry *entry; ++ if (st.st_dev != ap->dev) { ++ crit(ap->logopt, ++ "symlink %s has the wrong device, " ++ "possible race condition", path); ++ return 1; ++ } ++ debug(ap->logopt, "removing symlink %s", path); ++ if (unlink(path)) { ++ error(ap->logopt, ++ "failed to remove symlink %s", path); ++ return 1; ++ } ++ /* Check for an external mount and attempt umount if needed */ ++ mounts_mutex_lock(ap); ++ entry = __master_find_amdmount(ap, path); ++ if (!entry) { ++ mounts_mutex_unlock(ap); ++ return 0; ++ } ++ list_del(&entry->entries); ++ mounts_mutex_unlock(ap); ++ if (ext_mount_remove(&entry->ext_mount, entry->fs)) { ++ if (umount_ent(ap, entry->fs)) ++ debug(ap->logopt, ++ "failed to umount external mount %s", ++ entry->fs); ++ else ++ debug(ap->logopt, ++ "umounted external mount %s", ++ entry->fs); ++ } ++ free_amd_entry(entry); ++ return 0; ++ } ++ + is_autofs_fs = 0; + if (master_find_submount(ap, path)) + is_autofs_fs = 1; +@@ -1475,9 +1546,15 @@ static void handle_mounts_cleanup(void *arg) + clean = 1; + + if (submount) { ++ struct amd_entry *am; + /* We are finishing up */ + ap->parent->submnt_count--; + list_del_init(&ap->mounts); ++ am = __master_find_amdmount(ap->parent, ap->path); ++ if (am) { ++ list_del_init(&am->entries); ++ free_amd_entry(am); ++ } + } + + /* Don't signal the handler if we have already done so */ +diff --git a/include/automount.h b/include/automount.h +index 615efcc..37133fe 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -510,6 +510,7 @@ struct autofs_point { + struct autofs_point *parent; /* Owner of mounts list for submount */ + pthread_mutex_t mounts_mutex; /* Protect mount lists */ + struct list_head mounts; /* List of autofs mounts at current level */ ++ struct list_head amdmounts; /* List of non submount amd mounts */ + unsigned int submount; /* Is this a submount */ + unsigned int shutdown; /* Shutdown notification */ + unsigned int submnt_count; /* Number of submounts */ +diff --git a/include/master.h b/include/master.h +index 8833ddf..bcc8eeb 100644 +--- a/include/master.h ++++ b/include/master.h +@@ -104,6 +104,8 @@ void master_source_current_signal(struct master_mapent *); + struct master_mapent *master_find_mapent(struct master *, const char *); + struct autofs_point *__master_find_submount(struct autofs_point *, const char *); + struct autofs_point *master_find_submount(struct autofs_point *, const char *); ++struct amd_entry *__master_find_amdmount(struct autofs_point *, const char *); ++struct amd_entry *master_find_amdmount(struct autofs_point *, const char *); + struct master_mapent *master_new_mapent(struct master *, const char *, time_t); + void master_add_mapent(struct master *, struct master_mapent *); + void master_remove_mapent(struct master_mapent *); +diff --git a/lib/master.c b/lib/master.c +index df4aef6..5e4ab51 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -120,6 +120,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, + ap->submount = submount; + INIT_LIST_HEAD(&ap->mounts); + INIT_LIST_HEAD(&ap->submounts); ++ INIT_LIST_HEAD(&ap->amdmounts); + ap->shutdown = 0; + + status = pthread_mutex_init(&ap->mounts_mutex, NULL); +@@ -136,11 +137,26 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, + + void master_free_autofs_point(struct autofs_point *ap) + { ++ struct list_head *p, *head; + int status; + + if (!ap) + return; + ++ mounts_mutex_lock(ap); ++ head = &ap->amdmounts; ++ p = head->next; ++ while (p != head) { ++ struct amd_entry *entry = list_entry(p, struct amd_entry, entries); ++ p = p->next; ++ if (!list_empty(&entry->ext_mount)) ++ ext_mount_remove(&entry->ext_mount, entry->fs); ++ if (!list_empty(&entry->entries)) ++ list_del(&entry->entries); ++ free(entry); ++ } ++ mounts_mutex_unlock(ap); ++ + status = pthread_mutex_destroy(&ap->mounts_mutex); + if (status) + fatal(status); +@@ -694,6 +710,34 @@ struct autofs_point *master_find_submount(struct autofs_point *ap, const char *p + return submount; + } + ++struct amd_entry *__master_find_amdmount(struct autofs_point *ap, const char *path) ++{ ++ struct list_head *head, *p; ++ ++ head = &ap->amdmounts; ++ list_for_each(p, head) { ++ struct amd_entry *entry; ++ ++ entry = list_entry(p, struct amd_entry, entries); ++ ++ if (!strcmp(entry->path, path)) ++ return entry; ++ } ++ ++ return NULL; ++} ++ ++struct amd_entry *master_find_amdmount(struct autofs_point *ap, const char *path) ++{ ++ struct amd_entry *entry; ++ ++ mounts_mutex_lock(ap); ++ entry = __master_find_amdmount(ap, path); ++ mounts_mutex_unlock(ap); ++ ++ return entry; ++} ++ + struct master_mapent *master_new_mapent(struct master *master, const char *path, time_t age) + { + struct master_mapent *entry; +diff --git a/lib/master_parse.y b/lib/master_parse.y +index 11caf5b..03aedf7 100644 +--- a/lib/master_parse.y ++++ b/lib/master_parse.y +@@ -790,12 +790,29 @@ int master_parse_entry(const char *buffer, unsigned int default_timeout, unsigne + } + } + ++ if (!format) { ++ if (conf_amd_mount_section_exists(path)) ++ format = strdup("amd"); ++ } ++ ++ if (format && !strcmp(format, "amd")) { ++ unsigned int loglevel = conf_amd_get_log_options(); ++ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) ++ logopt = LOGOPT_DEBUG; ++ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) ++ logopt = LOGOPT_VERBOSE; ++ } ++ ++ + if (timeout < 0) { + /* +- * If no timeout is given get the timout from first +- * map (if it exists). ++ * If no timeout is given get the timout from the ++ * first map (if it exists) or the config for amd ++ * maps. + */ +- if (entry->maps) ++ if (format && !strcmp(format, "amd")) ++ timeout = conf_amd_get_dismount_interval(path); ++ else if (entry->maps) + timeout = entry->maps->exp_timeout; + else + timeout = default_timeout; +diff --git a/lib/master_tok.l b/lib/master_tok.l +index a55cc76..d43c1dd 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -119,7 +119,7 @@ DNNAMESTR2 ([[:alnum:]_.\-]+) + INTMAP (-hosts|-null) + MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS})) + MULTISEP ([\-]{2}[[:blank:]]+) +-MTYPE ((file|program|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?(:{OPTWS}|{WS})) ++MTYPE ((file|program|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod|amd))?(:{OPTWS}|{WS})) + + + OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index de5319f..421d18c 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -109,6 +109,7 @@ static unsigned int map_type_count = sizeof(map_type)/sizeof(struct types); + static struct types format_type[] = { + { "sun", 3 }, + { "hesiod", 6 }, ++ { "amd", 3}, + }; + static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types); + +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index 61aec70..ab5a8e3 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -203,6 +203,30 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + } + if (info->map) + argv[0] = info->map; ++ /* ++ * If the parent map format is amd and the format isn't ++ * specified in the map entry set it from the parent map ++ * source. ++ */ ++ if (!info->format && ap->entry->maps) { ++ struct map_source *s = ap->entry->maps; ++ /* ++ * For amd maps, if the format and source type aren't ++ * specified try and set them from the parent. ++ */ ++ if (s->flags & MAP_FLAG_FORMAT_AMD) { ++ info->format = strdup("amd"); ++ if (!info->format) ++ warn(ap->logopt, MODPREFIX ++ "failed to set amd map format"); ++ if (!info->type && s->type) { ++ info->type = strdup(s->type); ++ if (!info->type) ++ warn(ap->logopt, MODPREFIX ++ "failed to set amd map type"); ++ } ++ } ++ } + + if (options) { + p = options; +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 5d8617e..4322479 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1563,8 +1563,18 @@ int parse_mount(struct autofs_point *ap, const char *name, + dequote_entry(ap, this); + + rv = amd_mount(ap, name, this, source, sv, flags, ctxt); +- if (!rv) ++ mounts_mutex_lock(ap); ++ if (!rv) { ++ /* Add to the parent list of mounts */ ++ list_add_tail(&this->entries, &ap->amdmounts); ++ /* Mounted, leave it on the parent list */ ++ list_del_init(&this->list); ++ mounts_mutex_unlock(ap); + break; ++ } ++ /* Not mounted, remove it from the parent list */ ++ list_del_init(&this->entries); ++ mounts_mutex_unlock(ap); + } + free_amd_entry(cur_defaults); + diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-handling-of-unhandled-options.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-handling-of-unhandled-options.patch new file mode 100644 index 0000000..352b5e8 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-handling-of-unhandled-options.patch @@ -0,0 +1,202 @@ +autofs-5.0.9 - amd lookup add handling of unhandled options + +From: Ian Kent + +There are a number of map options that are either not yet implemented +or aren't planned on being supported. + +Add log message feedback for these. +--- + modules/amd_parse.y | 84 +++++++++++++++++++++++++++++++++++++++++++++++++-- + modules/amd_tok.l | 12 +++++-- + 2 files changed, 90 insertions(+), 6 deletions(-) + +diff --git a/modules/amd_parse.y b/modules/amd_parse.y +index cd69c49..77adbe5 100644 +--- a/modules/amd_parse.y ++++ b/modules/amd_parse.y +@@ -28,6 +28,7 @@ + + #include "automount.h" + #include "parse_amd.h" ++#include "log.h" + + #define MAX_OPTS_LEN 1024 + #define MAX_ERR_LEN 512 +@@ -45,6 +46,7 @@ static void local_free_vars(void); + + static int amd_error(const char *s); + static int amd_notify(const char *s); ++static int amd_info(const char *s); + static int amd_msg(const char *s); + + static int add_location(void); +@@ -59,6 +61,7 @@ static struct autofs_point *pap; + struct substvar *psv; + static char opts[MAX_OPTS_LEN]; + static void prepend_opt(char *, char *); ++static char msg_buf[MAX_ERR_LEN]; + + #define YYDEBUG 0 + +@@ -99,6 +102,7 @@ static int amd_fprintf(FILE *, char *, ...); + + %token MAP_OPTION + %token MAP_TYPE ++%token CACHE_OPTION + %token FS_TYPE + %token FS_OPTION + %token FS_OPT_VALUE +@@ -259,6 +263,20 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + !strcmp($3, "ext4")) { + entry.flags |= AMD_MOUNT_TYPE_EXT; + entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "jfs") || ++ !strcmp($3, "linkx") || ++ !strcmp($3, "nfsx") || ++ !strcmp($3, "nfsl") || ++ !strcmp($3, "program") || ++ !strcmp($3, "lustre") || ++ !strcmp($3, "direct")) { ++ sprintf(msg_buf, "file system type %s is " ++ "not yet implemented", $3); ++ amd_msg(msg_buf); ++ YYABORT; ++ } else if (!strcmp($3, "cachefs")) { ++ sprintf(msg_buf, "file syatem %s is not " ++ "supported by autofs, ignored", $3); + } else { + amd_notify($1); + YYABORT; +@@ -275,7 +293,18 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + else if (!strcmp($3, "exec")) + /* autofs uses "program" for "exec" map type */ + entry.map_type = amd_strdup("program"); +- else { ++ else if (!strcmp($3, "passwd")) { ++ sprintf(msg_buf, "map type %s is " ++ "not yet implemented", $3); ++ amd_msg(msg_buf); ++ YYABORT; ++ } else if (!strcmp($3, "ndbm") || ++ !strcmp($3, "union")) { ++ sprintf(msg_buf, "map type %s is not " ++ "supported by autofs", $3); ++ amd_msg(msg_buf); ++ YYABORT; ++ } else { + amd_notify($1); + YYABORT; + } +@@ -304,7 +333,17 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + entry.rfs = amd_strdup($3); + else if (!strcmp($1, "dev")) + entry.dev = amd_strdup($3); +- else { ++ else if (!strcmp($1, "mount") || ++ !strcmp($1, "unmount") || ++ !strcmp($1, "umount")) { ++ amd_info("file system type program is not " ++ "yet implemented, option ignored"); ++ YYABORT; ++ } else if (!strcmp($1, "delay") || ++ !strcmp($1, "cachedir")) { ++ sprintf(msg_buf, "option %s is not used by autofs", $1); ++ amd_info(msg_buf); ++ } else { + amd_notify($1); + YYABORT; + } +@@ -326,11 +365,44 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + YYABORT; + } + } ++ | MAP_OPTION OPTION_ASSIGN CACHE_OPTION ++ { ++ sprintf(msg_buf, "option %s is not used, autofs " ++ "default caching is always used", $1); ++ amd_info(msg_buf); ++ } + ; + + options: OPTION + { +- prepend_opt(opts, $1); ++ if (!strcmp($1, "browsable") || ++ !strcmp($1, "fullybrowsable") || ++ !strcmp($1, "nounmount") || ++ !strcmp($1, "unmount")) { ++ sprintf(msg_buf, "option %s is not currently " ++ "implemented, ignored", $1); ++ amd_info(msg_buf); ++ } else if (!strncmp($1, "ping=", 5) || ++ !strncmp($1, "retry=", 6) || ++ !strcmp($1, "public") || ++ !strcmp($1, "softlookup") || ++ !strcmp($1, "xlatecookie")) { ++ sprintf(msg_buf, "option %s is not used by " ++ "autofs, ignored", $1); ++ amd_info(msg_buf); ++ } else if (!strncmp($1, "utimeout=", 9)) { ++ if (entry.flags & AMD_MOUNT_TYPE_AUTO) { ++ char *opt = $1; ++ prepend_opt(opts, ++opt); ++ } else { ++ sprintf(msg_buf, "umount timeout can't be " ++ "used for other than type " ++ "\"auto\" with autofs, " ++ "ignored"); ++ amd_info(msg_buf); ++ } ++ } else ++ prepend_opt(opts, $1); + } + | OPTION COMMA options + { +@@ -387,6 +459,12 @@ static int amd_notify(const char *s) + return(0); + } + ++static int amd_info(const char *s) ++{ ++ info(pap->logopt, "%s\n", s); ++ return 0; ++} ++ + static int amd_msg(const char *s) + { + logmsg("%s\n", s); +diff --git a/modules/amd_tok.l b/modules/amd_tok.l +index fdc8899..8a6d40c 100644 +--- a/modules/amd_tok.l ++++ b/modules/amd_tok.l +@@ -94,13 +94,14 @@ OPTS ({OSTR}(=({VSTR}|{QSTR}|{MACRO})+)?) + SOPT (({SSTR}|{QSTR}|{MACRO})+) + NOPT ({SSTR}|(({IP4ADDR}(\/{V4MASK})?)|({IP6ADDR}(\/{V6MASK})?))) + +-MAPOPT (fs|type|maptype|pref|sublink|delay) ++MAPOPT (fs|type|maptype|pref|sublink|cache) + MNTOPT (opts|addopts|remopts) +-FSOPTS (rhost|rfs|dev|cachedir) ++FSOPTS (rhost|rfs|dev|cachedir|mount|unmount|umount|delay) ++CHEOPT (mapdefault|none|inc|re|regexp|all) + MAPTYPE (file|nis|nisplus|ldap|hesiod|exec|ndbm|passwd|union) + FSTYPE_LOCAL (link|linkx|lofs|ext2|ext3|ext4|xfs|jfs|cachefs) + FSTYPE_NET (nfs|nfsx|nfsl|host) +-FSTYPE (auto|program|direct|{FSTYPE_LOCAL}|{FSTYPE_NET}) ++FSTYPE (auto|program|direct|lustre|{FSTYPE_LOCAL}|{FSTYPE_NET}) + + OSSEL (arch|karch|os|osver|full_os|vendor) + HSTSEL (host|hostd|domain|byte|cluster) +@@ -204,6 +205,11 @@ CUTSEP (\|\||\/) + return MAP_TYPE; + } + ++ {CHEOPT} { ++ strcpy(amd_lval.strtype, amd_text); ++ return CACHE_OPTION; ++ } ++ + {FOPT} { + strcpy(amd_lval.strtype, amd_text); + return FS_OPT_VALUE; diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-key-matching-helper-function.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-key-matching-helper-function.patch new file mode 100644 index 0000000..1627e04 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-key-matching-helper-function.patch @@ -0,0 +1,119 @@ +autofs-5.0.9 - amd lookup add key matching helper function + +From: Ian Kent + +Add helper function and match_cached_key() that perform the progressive +key+prefix matching procedure. +--- + include/parse_subs.h | 2 + + lib/parse_subs.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 86 insertions(+) + +diff --git a/include/parse_subs.h b/include/parse_subs.h +index 43da182..1e87716 100644 +--- a/include/parse_subs.h ++++ b/include/parse_subs.h +@@ -113,6 +113,8 @@ struct map_type_info { + unsigned int get_proximity(struct sockaddr *); + unsigned int get_network_proximity(const char *); + unsigned int in_network(char *); ++struct mapent *match_cached_key(struct autofs_point *, const char *, ++ struct map_source *, const char *); + const char *skipspace(const char *); + int check_colon(const char *); + int chunklen(const char *, int); +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index 421d18c..1e4825d 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -498,6 +498,90 @@ unsigned int in_network(char *network) + return 1; + } + ++struct mapent *match_cached_key(struct autofs_point *ap, ++ const char *err_prefix, ++ struct map_source *source, ++ const char *key) ++{ ++ char buf[MAX_ERR_BUF]; ++ struct mapent_cache *mc; ++ struct mapent *me; ++ ++ mc = source->mc; ++ ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { ++ int ret; ++ ++ me = cache_lookup(mc, key); ++ /* ++ * Stale mapent => check for entry in alternate source or ++ * wildcard. Note, plus included direct mount map entries ++ * are included as an instance (same map entry cache), not ++ * in a distinct source. ++ */ ++ if (me && (!me->mapent || ++ (me->source != source && *me->key != '/'))) { ++ while ((me = cache_lookup_key_next(me))) ++ if (me->source == source) ++ break; ++ if (!me) ++ me = cache_lookup_distinct(mc, "*"); ++ } ++ ++ if (!me) ++ goto done; ++ ++ /* ++ * If this is a lookup add wildcard match for later validation ++ * checks and negative cache lookups. ++ */ ++ if (!(ap->flags & MOUNT_FLAG_REMOUNT) && ++ ap->type == LKP_INDIRECT && *me->key == '*') { ++ ret = cache_update(mc, source, key, me->mapent, me->age); ++ if (!(ret & (CHE_OK | CHE_UPDATED))) ++ me = NULL; ++ } ++ } else { ++ char *lkp_key = strdup(key); ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, "%s strdup: %s", err_prefix, estr); ++ return NULL; ++ } ++ ++ /* If it's found we're done */ ++ me = cache_lookup_distinct(mc, lkp_key); ++ if (me) ++ goto free; ++ ++ /* ++ * Otherwise strip successive directory components and try ++ * a match against map entries ending with a wildcard and ++ * finally try the wilcard entry itself. ++ */ ++ while (!me) { ++ char *prefix; ++ ++ while ((prefix = strrchr(lkp_key, '/'))) { ++ *prefix = '\0'; ++ me = cache_partial_match_wild(mc, lkp_key); ++ if (me) ++ goto free; ++ } ++ ++ me = cache_lookup_distinct(mc, "*"); ++ if (me) ++ goto free; ++ ++ break; ++ } ++free: ++ free(lkp_key); ++ } ++done: ++ return me; ++} ++ + /* + * Skip whitespace in a string; if we hit a #, consider the rest of the + * entry a comment. diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-lofs-ext-and-xfs-fs-types.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-lofs-ext-and-xfs-fs-types.patch new file mode 100644 index 0000000..c6c4f76 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-lofs-ext-and-xfs-fs-types.patch @@ -0,0 +1,167 @@ +autofs-5.0.9 - amd lookup add fs types lofs, ext, and xfs + +From: Ian Kent + + +--- + include/parse_amd.h | 9 +++++++++ + modules/amd_parse.y | 13 +++++++++++++ + modules/amd_tok.l | 4 +++- + modules/parse_amd.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 75 insertions(+), 1 deletion(-) + +diff --git a/include/parse_amd.h b/include/parse_amd.h +index a8521b5..4015e9f 100644 +--- a/include/parse_amd.h ++++ b/include/parse_amd.h +@@ -20,6 +20,14 @@ + #define AMD_MOUNT_TYPE_NFS 0x00000002 + #define AMD_MOUNT_TYPE_LINK 0x00000004 + #define AMD_MOUNT_TYPE_HOST 0x00000008 ++#define AMD_MOUNT_TYPE_NFSL 0x00000010 ++#define AMD_MOUNT_TYPE_NFSX 0x00000020 ++#define AMD_MOUNT_TYPE_LINKX 0x00000040 ++#define AMD_MOUNT_TYPE_LOFS 0x00000080 ++#define AMD_MOUNT_TYPE_EXT 0x00000100 ++#define AMD_MOUNT_TYPE_XFS 0x00000200 ++#define AMD_MOUNT_TYPE_JFS 0x00000400 ++#define AMD_MOUNT_TYPE_CACHEFS 0x00000800 + #define AMD_MOUNT_TYPE_MASK 0x0000ffff + + #define AMD_ENTRY_CUT 0x00010000 +@@ -38,6 +46,7 @@ struct amd_entry { + char *fs; + char *rhost; + char *rfs; ++ char *dev; + char *opts; + char *addopts; + char *remopts; +diff --git a/modules/amd_parse.y b/modules/amd_parse.y +index 71fd569..cd69c49 100644 +--- a/modules/amd_parse.y ++++ b/modules/amd_parse.y +@@ -248,6 +248,17 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + } else if (!strcmp($3, "host")) { + entry.flags |= AMD_MOUNT_TYPE_HOST; + entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "lofs")) { ++ entry.flags |= AMD_MOUNT_TYPE_LOFS; ++ entry.type = amd_strdup("bind"); ++ } else if (!strcmp($3, "xfs")) { ++ entry.flags |= AMD_MOUNT_TYPE_XFS; ++ entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "ext2") || ++ !strcmp($3, "ext3") || ++ !strcmp($3, "ext4")) { ++ entry.flags |= AMD_MOUNT_TYPE_EXT; ++ entry.type = amd_strdup($3); + } else { + amd_notify($1); + YYABORT; +@@ -291,6 +302,8 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + entry.rhost = amd_strdup($3); + else if (!strcmp($1, "rfs")) + entry.rfs = amd_strdup($3); ++ else if (!strcmp($1, "dev")) ++ entry.dev = amd_strdup($3); + else { + amd_notify($1); + YYABORT; +diff --git a/modules/amd_tok.l b/modules/amd_tok.l +index cea9ea5..fdc8899 100644 +--- a/modules/amd_tok.l ++++ b/modules/amd_tok.l +@@ -98,7 +98,9 @@ MAPOPT (fs|type|maptype|pref|sublink|delay) + MNTOPT (opts|addopts|remopts) + FSOPTS (rhost|rfs|dev|cachedir) + MAPTYPE (file|nis|nisplus|ldap|hesiod|exec|ndbm|passwd|union) +-FSTYPE (auto|nfs|link|host|nfsx|ufs|xfs|efs) ++FSTYPE_LOCAL (link|linkx|lofs|ext2|ext3|ext4|xfs|jfs|cachefs) ++FSTYPE_NET (nfs|nfsx|nfsl|host) ++FSTYPE (auto|program|direct|{FSTYPE_LOCAL}|{FSTYPE_NET}) + + OSSEL (arch|karch|os|osver|full_os|vendor) + HSTSEL (host|hostd|domain|byte|cluster) +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 4322479..e27a195 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -598,6 +598,12 @@ static void update_with_defaults(struct amd_entry *defaults, + } + } + ++ if (!entry->dev && defaults->dev) { ++ tmp = strdup(defaults->dev); ++ if (tmp) ++ entry->dev = tmp; ++ } ++ + if (!entry->opts && defaults->opts) { + tmp = merge_options(defaults->opts, entry->opts); + if (tmp) +@@ -949,6 +955,35 @@ out: + return ret; + } + ++static int do_generic_mount(struct autofs_point *ap, const char *name, ++ struct amd_entry *entry, const char *target, ++ unsigned int flags) ++{ ++ int ret = 0; ++ ++ if (!entry->sublink) { ++ ret = do_mount(ap, ap->path, name, strlen(name), ++ target, entry->type, entry->opts); ++ } else { ++ /* ++ * Careful, external mounts may get mounted ++ * multiple times since they are outside of ++ * the automount filesystem. ++ */ ++ if (!is_mounted(_PATH_MOUNTED, entry->fs, MNTS_REAL)) { ++ ret = do_mount(ap, entry->fs, "/", 1, ++ target, entry->type, entry->opts); ++ if (ret) ++ goto out; ++ } ++ /* We might be using an external mount */ ++ ext_mount_add(&entry->ext_mount, entry->fs); ++ ret = do_link_mount(ap, name, entry, flags); ++ } ++out: ++ return ret; ++} ++ + static int do_nfs_mount(struct autofs_point *ap, const char *name, + struct amd_entry *entry, unsigned int flags) + { +@@ -1024,6 +1059,15 @@ static int amd_mount(struct autofs_point *ap, const char *name, + ret = do_auto_mount(ap, name, entry, flags); + break; + ++ case AMD_MOUNT_TYPE_LOFS: ++ ret = do_generic_mount(ap, name, entry, entry->rfs, flags); ++ break; ++ ++ case AMD_MOUNT_TYPE_EXT: ++ case AMD_MOUNT_TYPE_XFS: ++ ret = do_generic_mount(ap, name, entry, entry->dev, flags); ++ break; ++ + case AMD_MOUNT_TYPE_NFS: + ret = do_nfs_mount(ap, name, entry, flags); + break; +@@ -1260,6 +1304,12 @@ static struct amd_entry *dup_defaults_entry(struct amd_entry *defaults) + entry->rhost = tmp; + } + ++ if (defaults->dev) { ++ tmp = strdup(defaults->dev); ++ if (tmp) ++ entry->dev = tmp; ++ } ++ + if (defaults->opts) { + tmp = strdup(defaults->opts); + if (tmp) diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-lookup-vars.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-lookup-vars.patch new file mode 100644 index 0000000..11659d5 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-lookup-vars.patch @@ -0,0 +1,202 @@ +autofs-5.0.9 - amd lookup add lookup vars + +From: Ian Kent + + +--- + modules/parse_amd.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 141 insertions(+), 16 deletions(-) + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 295a10f..35cc5dc 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -129,6 +129,100 @@ int parse_init(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, ++ struct substvar *sv) ++{ ++ struct substvar *list = sv; ++ struct thread_stdenv_vars *tsv; ++ char lkp_key[PATH_MAX + 1]; ++ char path[PATH_MAX + 1]; ++ struct mapent *me; ++ int len; ++ ++ len = strlen(ap->path) + 1 + key_len + 1; ++ if (len > PATH_MAX) { ++ error(ap->logopt, MODPREFIX ++ "error: lookup key is greater than PATH_MAX"); ++ return NULL; ++ } ++ ++ if (ap->pref) { ++ if (snprintf(lkp_key, sizeof(lkp_key), "%s%s", ++ ap->pref, key) >= sizeof(lkp_key)) { ++ error(ap->logopt, MODPREFIX "key too long"); ++ return NULL; ++ } ++ } else { ++ if (snprintf(lkp_key, sizeof(lkp_key), "%s", ++ key) >= sizeof(lkp_key)) { ++ error(ap->logopt, MODPREFIX "key too long"); ++ return NULL; ++ } ++ } ++ ++ if (*key == '/') ++ strcpy(path, key); ++ else { ++ strcpy(path, ap->path); ++ strcat(path, "/"); ++ strcat(path, key); ++ } ++ list = macro_addvar(list, "path", 4, path); ++ ++ me = cache_lookup_distinct(source->mc, lkp_key); ++ if (me) ++ list = macro_addvar(list, "key", 3, me->key); ++ ++ while (!me) { ++ char match[PATH_MAX + 1]; ++ char *prefix; ++ ++ strcpy(match, lkp_key); ++ while ((prefix = strrchr(match, '/'))) { ++ *prefix = '\0'; ++ me = cache_partial_match_wild(source->mc, match); ++ if (me) { ++ list = macro_addvar(list, "key", 3, lkp_key); ++ break; ++ } ++ } ++ ++ if (!me) { ++ me = cache_lookup_distinct(source->mc, "*"); ++ if (me) ++ list = macro_addvar(list, "key", 3, lkp_key); ++ } ++ ++ break; ++ } ++ ++ if (source->argv[0][0]) ++ list = macro_addvar(list, "map", 3, source->argv[0]); ++ ++ tsv = pthread_getspecific(key_thread_stdenv_vars); ++ if (tsv) { ++ char numbuf[16]; ++ long num; ++ int ret; ++ ++ num = (long) tsv->uid; ++ ret = sprintf(numbuf, "%ld", num); ++ if (ret > 0) ++ list = macro_addvar(list, "uid", 3, numbuf); ++ num = (long) tsv->gid; ++ ret = sprintf(numbuf, "%ld", num); ++ if (ret > 0) ++ list = macro_addvar(list, "gid", 3, numbuf); ++ } ++ ++ list = macro_addvar(list, "fs", 2, "${autodir}/${rhost}${rfs}"); ++ list = macro_addvar(list, "rfs", 3, path); ++ ++ return list; ++} ++ + static void update_with_defaults(struct amd_entry *defaults, + struct amd_entry *entry, + struct substvar *sv) +@@ -167,22 +261,40 @@ static void update_with_defaults(struct amd_entry *defaults, + entry->pref = tmp; + } + +- if (!entry->fs && defaults->fs) { +- tmp = strdup(defaults->fs); +- if (tmp) +- entry->fs = tmp; ++ if (!entry->fs) { ++ if (defaults->fs) { ++ tmp = strdup(defaults->fs); ++ if (tmp) ++ entry->fs = tmp; ++ } else { ++ v = macro_findvar(sv, "fs", 2); ++ if (v) ++ entry->fs = strdup(v->val); ++ } + } + +- if (!entry->rfs && defaults->rfs) { +- tmp = strdup(defaults->rfs); +- if (tmp) +- entry->rfs = tmp; ++ if (!entry->rfs) { ++ if (defaults->rfs) { ++ tmp = strdup(defaults->rfs); ++ if (tmp) ++ entry->rfs = tmp; ++ } else { ++ v = macro_findvar(sv, "rfs", 3); ++ if (v) ++ entry->rfs = strdup(v->val); ++ } + } + +- if (!entry->rhost && defaults->rhost) { +- tmp = strdup(defaults->rhost); +- if (tmp) +- entry->rhost = tmp; ++ if (!entry->rhost) { ++ if (defaults->rhost) { ++ tmp = strdup(defaults->rhost); ++ if (tmp) ++ entry->rhost = tmp; ++ } else { ++ v = macro_findvar(sv, "host", 4); ++ if (v) ++ entry->rhost = strdup(v->val); ++ } + } + + if (!entry->opts && defaults->opts) { +@@ -197,10 +309,16 @@ static void update_with_defaults(struct amd_entry *defaults, + entry->addopts = tmp; + } + +- if (!entry->remopts && defaults->remopts) { +- tmp = merge_options(defaults->remopts, entry->remopts); +- if (tmp) +- entry->remopts = tmp; ++ if (!entry->remopts) { ++ if (defaults->remopts) { ++ tmp = strdup(defaults->remopts); ++ if (tmp) ++ entry->remopts = tmp; ++ } else { ++ v = macro_findvar(sv, "remopts", 7); ++ if (v) ++ entry->remopts = strdup(v->val); ++ } + } + + return; +@@ -984,6 +1102,13 @@ int parse_mount(struct autofs_point *ap, const char *name, + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + ++ sv = add_lookup_vars(ap, name, name_len, source, sv); ++ if (!sv) { ++ macro_free_table(sv); ++ pthread_setcancelstate(cur_state, NULL); ++ return 1; ++ } ++ + len = expand_selectors(ap, mapent, &pmapent, sv); + if (!len) { + macro_free_table(sv); diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-merge_options-function.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-merge_options-function.patch new file mode 100644 index 0000000..3a57fe8 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-merge_options-function.patch @@ -0,0 +1,153 @@ +autofs-5.0.9 - mad lookup add merge_options() function + +From: Ian Kent + + +--- + include/parse_subs.h | 1 + lib/parse_subs.c | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 114 insertions(+) + +diff --git a/include/parse_subs.h b/include/parse_subs.h +index c0da5ae..e57cf4a 100644 +--- a/include/parse_subs.h ++++ b/include/parse_subs.h +@@ -41,6 +41,7 @@ int strmcmp(const char *, const char *, int); + char *dequote(const char *, int, unsigned int); + int span_space(const char *, unsigned int); + char *sanitize_path(const char *, int, unsigned int, unsigned int); ++char *merge_options(const char *, const char *); + void free_map_type_info(struct map_type_info *); + struct map_type_info *parse_map_type_info(const char *); + +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index b77d890..99075b1 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -23,6 +23,9 @@ + #include + #include "automount.h" + ++#define MAX_OPTIONS_LEN 256 ++#define MAX_OPTION_LEN 40 ++ + #define MAX_NETWORK_LEN 255 + + #define MAX_IFC_BUF 2048 +@@ -523,6 +526,116 @@ char *sanitize_path(const char *path, int origlen, unsigned int type, unsigned i + return s_path; + } + ++static char *hasopt(const char *str, const char *opt) ++{ ++ const size_t optlen = strlen(opt); ++ char *rest = (char *) str, *p; ++ ++ while ((p = strstr(rest, opt)) != NULL) { ++ if ((p == rest || p[-1] == ',') && ++ (p[optlen] == '\0' || p[optlen] == '=' || ++ p[optlen] == ',')) ++ return p; ++ ++ rest = strchr (p, ','); ++ if (rest == NULL) ++ break; ++ ++rest; ++ } ++ ++ return NULL; ++} ++ ++char *merge_options(const char *opt1, const char *opt2) ++{ ++ char str[MAX_OPTIONS_LEN]; ++ char result[MAX_OPTIONS_LEN]; ++ char neg[MAX_OPTION_LEN]; ++ char *tok, *ptr = NULL; ++ size_t len; ++ ++ if (!opt1 && !opt2) ++ return NULL; ++ ++ if (!opt2) ++ return strdup(opt1); ++ ++ if (!opt1) ++ return strdup(opt2); ++ ++ if (!strcmp(opt1, opt2)) ++ return strdup(opt1); ++ ++ memset(result, 0, sizeof(result)); ++ strcpy(str, opt1); ++ ++ tok = strtok_r(str, ",", &ptr); ++ while (tok) { ++ const char *this = (const char *) tok; ++ char *eq = strchr(this, '='); ++ if (eq) { ++ *eq = '\0'; ++ if (!hasopt(opt2, this)) { ++ *eq = '='; ++ if (!*result) ++ strcpy(result, this); ++ else ++ strcat(result, this); ++ strcat(result, ","); ++ goto next; ++ } ++ } ++ ++ if (!strcmp(this, "rw") && hasopt(opt2, "ro")) ++ goto next; ++ if (!strcmp(this, "ro") && hasopt(opt2, "rw")) ++ goto next; ++ if (!strcmp(this, "bg") && hasopt(opt2, "fg")) ++ goto next; ++ if (!strcmp(this, "fg") && hasopt(opt2, "bg")) ++ goto next; ++ if (!strcmp(this, "bg") && hasopt(opt2, "fg")) ++ goto next; ++ if (!strcmp(this, "soft") && hasopt(opt2, "hard")) ++ goto next; ++ if (!strcmp(this, "hard") && hasopt(opt2, "soft")) ++ goto next; ++ ++ if (!strncmp(this, "no", 2)) { ++ strcpy(neg, this + 2); ++ if (hasopt(opt2, neg)) ++ goto next; ++ } else { ++ strcpy(neg, "no"); ++ strcat(neg, this); ++ if (hasopt(opt2, neg)) ++ goto next; ++ } ++ ++ if (hasopt(opt2, tok)) ++ goto next; ++ ++ if (!*result) ++ strcpy(result, this); ++ else ++ strcat(result, this); ++ strcat(result, ","); ++next: ++ tok = strtok_r(NULL, ",", &ptr); ++ } ++ ++ if (!*result) ++ strcpy(result, opt2); ++ else ++ strcat(result, opt2); ++ ++ len = strlen(result); ++ if (len && result[len - 1] == ',') ++ result[len - 1] = '\0'; ++ ++ return strdup(result); ++} ++ + void free_map_type_info(struct map_type_info *info) + { + if (info->type) diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-nfsl-and-linkx-fs-types.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-nfsl-and-linkx-fs-types.patch new file mode 100644 index 0000000..409626c --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-nfsl-and-linkx-fs-types.patch @@ -0,0 +1,123 @@ +autofs-5.0.9 - amd lookup add nfsl and linkx fs types + +From: Ian Kent + + +--- + modules/amd_parse.y | 8 ++++++-- + modules/parse_amd.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 60 insertions(+), 2 deletions(-) + +diff --git a/modules/amd_parse.y b/modules/amd_parse.y +index 77adbe5..1d4a0a3 100644 +--- a/modules/amd_parse.y ++++ b/modules/amd_parse.y +@@ -246,9 +246,15 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + !strcmp($3, "nfs4")) { + entry.flags |= AMD_MOUNT_TYPE_NFS; + entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "nfsl")) { ++ entry.flags |= AMD_MOUNT_TYPE_NFSL; ++ entry.type = amd_strdup($3); + } else if (!strcmp($3, "link")) { + entry.flags |= AMD_MOUNT_TYPE_LINK; + entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "linkx")) { ++ entry.flags |= AMD_MOUNT_TYPE_LINKX; ++ entry.type = amd_strdup($3); + } else if (!strcmp($3, "host")) { + entry.flags |= AMD_MOUNT_TYPE_HOST; + entry.type = amd_strdup($3); +@@ -264,9 +270,7 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + entry.flags |= AMD_MOUNT_TYPE_EXT; + entry.type = amd_strdup($3); + } else if (!strcmp($3, "jfs") || +- !strcmp($3, "linkx") || + !strcmp($3, "nfsx") || +- !strcmp($3, "nfsl") || + !strcmp($3, "program") || + !strcmp($3, "lustre") || + !strcmp($3, "direct")) { +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 4cebce8..7e04beb 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -955,6 +955,23 @@ out: + return ret; + } + ++static int do_linkx_mount(struct autofs_point *ap, const char *name, ++ struct amd_entry *entry, unsigned int flags) ++{ ++ struct stat st; ++ char *target; ++ ++ if (entry->sublink) ++ target = entry->sublink; ++ else ++ target = entry->fs; ++ ++ if (lstat(target, &st) < 0) ++ return errno; ++ ++ return do_link_mount(ap, name, entry, flags); ++} ++ + static int do_generic_mount(struct autofs_point *ap, const char *name, + struct amd_entry *entry, const char *target, + unsigned int flags) +@@ -1020,6 +1037,35 @@ out: + return ret; + } + ++static int do_nfsl_mount(struct autofs_point *ap, const char *name, ++ struct amd_entry *entry, struct substvar *sv, ++ unsigned int flags) ++{ ++ const struct substvar *host, *hostd; ++ struct stat st; ++ char *target; ++ ++ host = macro_findvar(sv, "host", 4); ++ if (!host) ++ return do_nfs_mount(ap, name, entry, flags); ++ hostd = macro_findvar(sv, "hostd", 5); ++ if (!hostd || !*hostd->val) ++ return do_nfs_mount(ap, name, entry, flags); ++ ++ if (entry->sublink) ++ target = entry->sublink; ++ else ++ target = entry->fs; ++ ++ if (strcasecmp(host->val, entry->rhost) || ++ strcasecmp(hostd->val, entry->rhost)) ++ return do_nfs_mount(ap, name, entry, flags); ++ else if (lstat(target, &st) < 0) ++ return do_nfs_mount(ap, name, entry, flags); ++ ++ return do_link_mount(ap, name, entry, flags); ++} ++ + static int do_host_mount(struct autofs_point *ap, const char *name, + struct amd_entry *entry, struct map_source *source, + unsigned int flags) +@@ -1078,10 +1124,18 @@ static int amd_mount(struct autofs_point *ap, const char *name, + ret = do_nfs_mount(ap, name, entry, flags); + break; + ++ case AMD_MOUNT_TYPE_NFSL: ++ ret = do_nfsl_mount(ap, name, entry, sv, flags); ++ break; ++ + case AMD_MOUNT_TYPE_LINK: + ret = do_link_mount(ap, name, entry, flags); + break; + ++ case AMD_MOUNT_TYPE_LINKX: ++ ret = do_linkx_mount(ap, name, entry, flags); ++ break; ++ + case AMD_MOUNT_TYPE_HOST: + ret = do_host_mount(ap, name, entry, source, flags); + break; diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-parent-prefix-handling.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-parent-prefix-handling.patch new file mode 100644 index 0000000..2000a55 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-parent-prefix-handling.patch @@ -0,0 +1,93 @@ +autofs-5.0.9 - amd lookup add parent prefix handling + +From: Ian Kent + + +--- + include/automount.h | 1 + + lib/master.c | 3 +++ + modules/parse_amd.c | 31 +++++++++++++++++++++++++++++++ + 3 files changed, 35 insertions(+) + +diff --git a/include/automount.h b/include/automount.h +index b304517..615efcc 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -491,6 +491,7 @@ struct kernel_mod_version { + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ ++ char *pref; /* amd prefix */ + int pipefd; /* File descriptor for pipe */ + int kpipefd; /* Kernel end descriptor for pipe */ + int ioctlfd; /* File descriptor for ioctls */ +diff --git a/lib/master.c b/lib/master.c +index 4ac3c6a..df4aef6 100644 +--- a/lib/master.c ++++ b/lib/master.c +@@ -86,6 +86,7 @@ int master_add_autofs_point(struct master_mapent *entry, unsigned logopt, + free(ap); + return 0; + } ++ ap->pref = NULL; + + ap->entry = entry; + ap->exp_thread = 0; +@@ -144,6 +145,8 @@ void master_free_autofs_point(struct autofs_point *ap) + if (status) + fatal(status); + ++ if (ap->pref) ++ free(ap->pref); + free(ap->path); + free(ap); + } +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 54da1a5..295a10f 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -736,6 +736,36 @@ static void normalize_sublink(unsigned int logopt, + return; + } + ++/* ++ * Set the prefix. ++ * ++ * This is done in a couple of places, here is as good a place as ++ * any to describe it. ++ * ++ * If a prefix is present in the map entry then use it. ++ * ++ * A pref option with the value none is required to use no prefix, ++ * otherwise the prefix of the parent map, if any, will be used. ++ */ ++static void update_prefix(struct autofs_point *ap, ++ struct amd_entry *entry, const char *name) ++{ ++ size_t len; ++ char *new; ++ ++ if (!entry->pref && ap->pref) { ++ len = strlen(ap->pref) + strlen(name) + 2; ++ new = malloc(len); ++ if (new) { ++ strcpy(new, ap->pref); ++ strcat(new, name); ++ strcat(new, "/"); ++ entry->pref = new; ++ } ++ } ++ return; ++} ++ + static struct amd_entry *dup_defaults_entry(struct amd_entry *defaults) + { + struct amd_entry *entry; +@@ -1044,6 +1074,7 @@ int parse_mount(struct autofs_point *ap, const char *name, + sv = expand_entry(ap, this, flags, sv); + sv = merge_entry_options(ap, this, sv); + normalize_sublink(ap->logopt, this, sv); ++ update_prefix(ap, this, name); + + dequote_entry(ap, this); + diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-parse_amd-c.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-parse_amd-c.patch new file mode 100644 index 0000000..60b4eff --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-parse_amd-c.patch @@ -0,0 +1,2159 @@ +autofs-5.0.9 - amd lookup add parse_amd.c + +From: Ian Kent + +Add a yacc parser and an autofs parser module for amd format +maps. +--- + include/automount.h | 1 + include/mounts.h | 6 + include/parse_amd.h | 54 ++ + lib/mounts.c | 81 +++ + modules/Makefile | 21 - + modules/amd_parse.y | 511 ++++++++++++++++++++++++ + modules/amd_tok.l | 316 +++++++++++++++ + modules/parse_amd.c | 1081 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + 8 files changed, 2069 insertions(+), 2 deletions(-) + create mode 100644 include/parse_amd.h + create mode 100644 modules/amd_parse.y + create mode 100644 modules/amd_tok.l + create mode 100644 modules/parse_amd.c + +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -34,6 +34,7 @@ + #include "parse_subs.h" + #include "mounts.h" + #include "dev-ioctl-lib.h" ++#include "parse_amd.h" + + #ifdef WITH_DMALLOC + #include +--- autofs-5.0.7.orig/include/mounts.h ++++ autofs-5.0.7/include/mounts.h +@@ -85,10 +85,16 @@ unsigned int linux_version_code(void); + int check_nfs_mount_version(struct nfs_mount_vers *, struct nfs_mount_vers *); + extern unsigned int nfs_mount_uses_string_options; + ++struct amd_entry; ++ + struct substvar *addstdenv(struct substvar *sv); + struct substvar *removestdenv(struct substvar *sv); + void add_std_amd_vars(struct substvar *sv); + void remove_std_amd_vars(void); ++struct amd_entry *new_amd_entry(const struct substvar *sv); ++void clear_amd_entry(struct amd_entry *entry); ++void free_amd_entry(struct amd_entry *entry); ++void free_amd_entry_list(struct list_head *entries); + + unsigned int query_kproto_ver(void); + unsigned int get_kver_major(void); +--- /dev/null ++++ autofs-5.0.7/include/parse_amd.h +@@ -0,0 +1,54 @@ ++/* ----------------------------------------------------------------------- * ++ * ++ * Copyright 2004-2006 Ian Kent ++ * Copyright 2013 Red Hat, Inc. ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, ++ * USA; either version 2 of the License, or (at your option) any later ++ * version; incorporated herein by reference. ++ * ++ * ----------------------------------------------------------------------- */ ++ ++#ifndef PARSE_AMD_H ++#define PARSE_AMD_H ++ ++#define AMD_MOUNT_TYPE_NONE 0x00000000 ++#define AMD_MOUNT_TYPE_AUTO 0x00000001 ++#define AMD_MOUNT_TYPE_NFS 0x00000002 ++#define AMD_MOUNT_TYPE_LINK 0x00000004 ++#define AMD_MOUNT_TYPE_HOST 0x00000008 ++#define AMD_MOUNT_TYPE_MASK 0x0000ffff ++ ++#define AMD_ENTRY_CUT 0x00010000 ++#define AMD_ENTRY_MASK 0x00ff0000 ++ ++#define AMD_DEFAULTS_MERGE 0x01000000 ++#define AMD_DEFAULTS_RESET 0x02000000 ++#define AMD_DEFAULTS_MASK 0xff000000 ++ ++struct amd_entry { ++ char *path; ++ unsigned long flags; ++ char *type; ++ char *map_type; ++ char *pref; ++ char *fs; ++ char *rhost; ++ char *rfs; ++ char *opts; ++ char *addopts; ++ char *remopts; ++ char *sublink; ++ struct selector *selector; ++ struct list_head list; ++ struct list_head entries; ++ struct list_head ext_mount; ++}; ++ ++int amd_parse_list(struct autofs_point *, ++ const char *, struct list_head *, struct substvar **); ++ ++#endif +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -442,6 +442,87 @@ void remove_std_amd_vars(void) + return; + } + ++struct amd_entry *new_amd_entry(const struct substvar *sv) ++{ ++ struct amd_entry *new; ++ const struct substvar *v; ++ char *path; ++ ++ v = macro_findvar(sv, "path", 4); ++ if (!v) ++ return NULL; ++ ++ path = strdup(v->val); ++ if (!path) ++ return NULL; ++ ++ new = malloc(sizeof(struct amd_entry)); ++ if (!new) { ++ free(path); ++ return NULL; ++ } ++ ++ memset(new, 0, sizeof(*new)); ++ new->path = path; ++ INIT_LIST_HEAD(&new->list); ++ INIT_LIST_HEAD(&new->entries); ++ INIT_LIST_HEAD(&new->ext_mount); ++ ++ return new; ++} ++ ++void clear_amd_entry(struct amd_entry *entry) ++{ ++ if (!entry) ++ return; ++ if (entry->path) ++ free(entry->path); ++ if (entry->map_type) ++ free(entry->map_type); ++ if (entry->pref) ++ free(entry->pref); ++ if (entry->fs) ++ free(entry->fs); ++ if (entry->rhost) ++ free(entry->rhost); ++ if (entry->rfs) ++ free(entry->rfs); ++ if (entry->opts) ++ free(entry->opts); ++ if (entry->addopts) ++ free(entry->addopts); ++ if (entry->remopts) ++ free(entry->remopts); ++ if (entry->sublink) ++ free(entry->sublink); ++ if (entry->selector) ++ free_selector(entry->selector); ++ return; ++} ++ ++void free_amd_entry(struct amd_entry *entry) ++{ ++ clear_amd_entry(entry); ++ free(entry); ++ return; ++} ++ ++void free_amd_entry_list(struct list_head *entries) ++{ ++ if (!list_empty(entries)) { ++ struct list_head *head = entries; ++ struct amd_entry *this; ++ struct list_head *p; ++ ++ p = head->next; ++ while (p != head) { ++ this = list_entry(p, struct amd_entry, list); ++ p = p->next; ++ free_amd_entry(this); ++ } ++ } ++} ++ + /* + * Make common autofs mount options string + */ +--- autofs-5.0.7.orig/modules/Makefile ++++ autofs-5.0.7/modules/Makefile +@@ -7,16 +7,18 @@ include ../Makefile.rules + + SRCS := lookup_file.c lookup_program.c lookup_userhome.c \ + lookup_multi.c lookup_hosts.c lookup_dir.c \ +- parse_sun.c \ ++ parse_sun.c parse_amd.c \ + mount_generic.c mount_nfs.c mount_afs.c mount_autofs.c \ + mount_changer.c mount_bind.c + + MODS := lookup_file.so lookup_program.so lookup_userhome.so \ + lookup_multi.so lookup_hosts.so lookup_dir.so \ +- parse_sun.so \ ++ parse_sun.so parse_amd.so \ + mount_generic.so mount_nfs.so mount_afs.so mount_autofs.so \ + mount_changer.so mount_bind.so + ++YACCSRC = amd_tok.c amd_parse.tab.c amd_parse.tab.h \ ++ + ifeq ($(EXT2FS), 1) + SRCS += mount_ext2.c + MODS += mount_ext2.so +@@ -94,6 +96,21 @@ else ifeq ($(EXT4FS), 1) + mv $(INSTALLROOT)$(autofslibdir)/mount_ext2.so $(INSTALLROOT)$(autofslibdir)/mount_ext4.so + endif + ++amd_tok.c: amd_tok.l ++ $(LEX) -o$@ -Pamd_ $? ++ ++amd_tok.o: amd_tok.c amd_parse.tab.h ++ ++amd_parse.tab.c amd_parse.tab.h: amd_parse.y ++ $(YACC) -v -d -p amd_ -b amd_parse $? ++ ++amd_parse.tab.o: amd_parse.tab.c amd_parse.tab.h ++ ++parse_amd.so: parse_amd.c amd_parse.tab.o amd_tok.o ++ $(CC) $(LDFLAGS) $(SOLDFLAGS) $(CFLAGS) -o parse_amd.so \ ++ parse_amd.c amd_parse.tab.o amd_tok.o $(AUTOFS_LIB) $(LIBS) ++ $(STRIP) parse_amd.so ++ + # + # Ad hoc compilation rules for modules which need auxilliary libraries + # +--- /dev/null ++++ autofs-5.0.7/modules/amd_parse.y +@@ -0,0 +1,511 @@ ++%{ ++/* ----------------------------------------------------------------------- * ++ * ++ * Copyright 2013 Ian Kent ++ * Copyright 2013 Red Hat, Inc. ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, ++ * USA; either version 2 of the License, or (at your option) any later ++ * version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ----------------------------------------------------------------------- */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "automount.h" ++#include "parse_amd.h" ++ ++#define MAX_OPTS_LEN 1024 ++#define MAX_ERR_LEN 512 ++ ++static pthread_mutex_t parse_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++extern FILE *amd_in; ++extern char *amd_text; ++extern int amd_lex(void); ++extern void amd_set_scan_buffer(const char *); ++ ++static char *amd_strdup(char *); ++static void local_init_vars(void); ++static void local_free_vars(void); ++ ++static int amd_error(const char *s); ++static int amd_notify(const char *s); ++static int amd_msg(const char *s); ++ ++static int add_location(void); ++static int make_selector(char *name, ++ char *value1, char *value2, ++ unsigned int compare); ++static void add_selector(struct selector *selector); ++ ++static struct amd_entry entry; ++static struct list_head *entries; ++static struct autofs_point *pap; ++struct substvar *psv; ++static char opts[MAX_OPTS_LEN]; ++static void prepend_opt(char *, char *); ++ ++#define YYDEBUG 0 ++ ++#ifndef YYENABLE_NLS ++#define YYENABLE_NLS 0 ++#endif ++#ifndef YYLTYPE_IS_TRIVIAL ++#define YYLTYPE_IS_TRIVIAL 0 ++#endif ++ ++#if YYDEBUG ++static int amd_fprintf(FILE *, char *, ...); ++#undef YYFPRINTF ++#define YYFPRINTF amd_fprintf ++#endif ++ ++%} ++ ++%union { ++ char strtype[2048]; ++ int inttype; ++ long longtype; ++} ++ ++%token COMMENT ++%token SEPERATOR ++%token SPACE ++%token HYPHEN ++%token IS_EQUAL ++%token CUT ++%token NOT_EQUAL ++%token COMMA ++%token OPTION_ASSIGN ++%token NILL ++ ++%token MAP_OPTION ++%token MAP_TYPE ++%token FS_TYPE ++%token FS_OPTION ++%token FS_OPT_VALUE ++%token MNT_OPTION ++%token SELECTOR ++%token SELECTOR_VALUE ++%token OPTION ++%token MACRO ++%token OTHER ++ ++%type options ++ ++%start file ++ ++%% ++ ++file: { ++#if YYDEBUG != 0 ++ amd_debug = YYDEBUG; ++#endif ++ memset(opts, 0, sizeof(opts)); ++ } line ++ ; ++ ++line: ++ | location_selection_list ++ ; ++ ++location_selection_list: location ++ { ++ if (!add_location()) { ++ amd_msg("failed to allocate new location"); ++ YYABORT; ++ } ++ } ++ | location_selection_list SPACE location ++ { ++ if (!add_location()) { ++ amd_msg("failed to allocate new location"); ++ YYABORT; ++ } ++ } ++ | location_selection_list SPACE CUT SPACE location ++ { ++ entry.flags |= AMD_ENTRY_CUT; ++ if (!add_location()) { ++ amd_msg("failed to allocate new location"); ++ YYABORT; ++ } ++ } ++ ; ++ ++location: location_entry ++ { ++ } ++ | HYPHEN location_entry ++ { ++ entry.flags |= AMD_DEFAULTS_MERGE; ++ } ++ | HYPHEN ++ { ++ entry.flags |= AMD_DEFAULTS_RESET; ++ } ++ ; ++ ++location_entry: selector_or_option ++ { ++ } ++ | location_entry SEPERATOR selector_or_option ++ { ++ } ++ | location_entry SEPERATOR ++ { ++ } ++ ; ++ ++selector_or_option: selection ++ { ++ } ++ | option_assignment ++ { ++ } ++ | OTHER ++ { ++ amd_notify($1); ++ YYABORT; ++ } ++ ; ++ ++selection: SELECTOR IS_EQUAL SELECTOR_VALUE ++ { ++ if (!make_selector($1, $3, NULL, SEL_TYPE_EQUAL)) { ++ amd_notify($1); ++ YYABORT; ++ } ++ } ++ | SELECTOR NOT_EQUAL SELECTOR_VALUE ++ { ++ if (!make_selector($1, $3, NULL, SEL_TYPE_NOTEQUAL)) { ++ amd_notify($1); ++ YYABORT; ++ } ++ } ++ ; ++ ++option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE ++ { ++ if (!strcmp($3, "auto")) { ++ entry.flags |= AMD_MOUNT_TYPE_AUTO; ++ entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "nfs") || ++ !strcmp($3, "nfs4")) { ++ entry.flags |= AMD_MOUNT_TYPE_NFS; ++ entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "link")) { ++ entry.flags |= AMD_MOUNT_TYPE_LINK; ++ entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "host")) { ++ entry.flags |= AMD_MOUNT_TYPE_HOST; ++ entry.type = amd_strdup($3); ++ } else { ++ amd_notify($1); ++ YYABORT; ++ } ++ } ++ | MAP_OPTION OPTION_ASSIGN MAP_TYPE ++ { ++ if (!strcmp($3, "file") || ++ !strcmp($3, "nis") || ++ !strcmp($3, "nisplus") || ++ !strcmp($3, "ldap") || ++ !strcmp($3, "hesiod")) ++ entry.map_type = amd_strdup($3); ++ else if (!strcmp($3, "exec")) ++ /* autofs uses "program" for "exec" map type */ ++ entry.map_type = amd_strdup("program"); ++ else { ++ amd_notify($1); ++ YYABORT; ++ } ++ } ++ | MAP_OPTION OPTION_ASSIGN FS_OPT_VALUE ++ { ++ if (!strcmp($1, "fs")) ++ entry.fs = amd_strdup($3); ++ else if (!strcmp($1, "sublink")) ++ entry.sublink = amd_strdup($3); ++ else if (!strcmp($1, "pref")) { ++ if (!strcmp($3, "null")) ++ entry.pref = amd_strdup(""); ++ else ++ entry.pref = amd_strdup($3); ++ } else { ++ amd_notify($1); ++ YYABORT; ++ } ++ } ++ | FS_OPTION OPTION_ASSIGN FS_OPT_VALUE ++ { ++ if (!strcmp($1, "rhost")) ++ entry.rhost = amd_strdup($3); ++ else if (!strcmp($1, "rfs")) ++ entry.rfs = amd_strdup($3); ++ else { ++ amd_notify($1); ++ YYABORT; ++ } ++ } ++ | MNT_OPTION OPTION_ASSIGN options ++ { ++ if (!strcmp($1, "opts")) { ++ entry.opts = amd_strdup(opts); ++ memset(opts, 0, sizeof(opts)); ++ } else if (!strcmp($1, "addopts")) { ++ entry.addopts = amd_strdup(opts); ++ memset(opts, 0, sizeof(opts)); ++ } else if (!strcmp($1, "remopts")) { ++ entry.remopts = amd_strdup(opts); ++ memset(opts, 0, sizeof(opts)); ++ } else { ++ memset(opts, 0, sizeof(opts)); ++ amd_notify($1); ++ YYABORT; ++ } ++ } ++ ; ++ ++options: OPTION ++ { ++ prepend_opt(opts, $1); ++ } ++ | OPTION COMMA options ++ { ++ prepend_opt(opts, $1); ++ } ++ ; ++ ++%% ++ ++static void prepend_opt(char *dest, char *opt) ++{ ++ char new[MAX_OPTS_LEN]; ++ strcpy(new, opt); ++ if (*dest != '\0') { ++ strcat(new, ","); ++ strcat(new, dest); ++ } ++ memmove(dest, new, strlen(new)); ++} ++ ++#if YYDEBUG ++static int amd_fprintf(FILE *f, char *msg, ...) ++{ ++ va_list ap; ++ va_start(ap, msg); ++ vsyslog(LOG_DEBUG, msg, ap); ++ va_end(ap); ++ return 1; ++} ++#endif ++ ++static char *amd_strdup(char *str) ++{ ++ char *tmp; ++ ++ tmp = strdup(str); ++ if (!tmp) ++ amd_error("memory allocation error"); ++ return tmp; ++} ++ ++static int amd_error(const char *s) ++{ ++ if (strcmp(s, "syntax")) ++ logmsg("syntax error in location near [ %s ]\n", amd_text); ++ else ++ logmsg("%s while parsing location.\n", s); ++ return 0; ++} ++ ++static int amd_notify(const char *s) ++{ ++ logmsg("syntax error in location near [ %s ]\n", s); ++ return(0); ++} ++ ++static int amd_msg(const char *s) ++{ ++ logmsg("%s\n", s); ++ return 0; ++} ++ ++static void local_init_vars(void) ++{ ++ memset(&entry, 0, sizeof(entry)); ++ memset(opts, 0, sizeof(opts)); ++} ++ ++static void local_free_vars(void) ++{ ++ clear_amd_entry(&entry); ++ return; ++} ++ ++static void add_selector(struct selector *selector) ++{ ++ struct selector *s = entry.selector; ++ ++ if (!s) { ++ entry.selector = selector; ++ return; ++ } ++ ++ while (s->next) ++ s = s->next; ++ ++ selector->next = s; ++ entry.selector = selector; ++ ++ return; ++} ++ ++static int make_selector(char *name, ++ char *value1, char *value2, ++ unsigned int compare) ++{ ++ struct selector *s; ++ char *tmp; ++ ++ if (!sel_lookup(name)) ++ return 0; ++ ++ if (!value1) ++ return 0; ++ ++ s = get_selector(name); ++ if (!s) ++ return 0; ++ ++ if (s->sel->flags & SEL_FLAG_MACRO) { ++ tmp = amd_strdup(value1); ++ if (!tmp) ++ goto error; ++ s->comp.value = tmp; ++ } else if (s->sel->flags & SEL_FLAG_FUNC1) { ++ char *tmp = amd_strdup(value1); ++ if (!tmp) ++ goto error; ++ s->func.arg1 = tmp; ++ } else if (s->sel->flags & SEL_FLAG_FUNC2) { ++ char *tmp = amd_strdup(value1); ++ if (!tmp) ++ goto error; ++ s->func.arg1 = tmp; ++ if (value2) { ++ tmp = amd_strdup(value2); ++ if (tmp) ++ s->func.arg2 = tmp; ++ } ++ } ++ s->compare = compare; ++ ++ add_selector(s); ++ ++ return 1; ++error: ++ free_selector(s); ++ return 0; ++} ++ ++void amd_init_scan(void) ++{ ++} ++ ++static void parse_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&parse_mutex); ++ if (status) ++ fatal(status); ++ return; ++} ++ ++static void parse_mutex_unlock(void *arg) ++{ ++ int status = pthread_mutex_unlock(&parse_mutex); ++ if (status) ++ fatal(status); ++ return; ++} ++ ++static int add_location(void) ++{ ++ struct amd_entry *new; ++ ++ new = new_amd_entry(psv); ++ if (!new) ++ return 0; ++ ++ if (entry.path) { ++ free(new->path); ++ new->path = entry.path; ++ } ++ new->flags = entry.flags; ++ new->type = entry.type; ++ new->map_type = entry.map_type; ++ new->pref = entry.pref; ++ new->fs = entry.fs; ++ new->rhost = entry.rhost; ++ new->rfs = entry.rfs; ++ new->dev = entry.dev; ++ new->opts = entry.opts; ++ new->addopts = entry.addopts; ++ new->remopts = entry.remopts; ++ new->sublink = entry.sublink; ++ new->selector = entry.selector; ++ list_add_tail(&new->list, entries); ++ memset(&entry, 0, sizeof(struct amd_entry)); ++ ++ return 1; ++} ++ ++int amd_parse_list(struct autofs_point *ap, ++ const char *buffer, struct list_head *list, ++ struct substvar **sv) ++{ ++ char *buf; ++ size_t len; ++ int ret; ++ ++ len = strlen(buffer) + 2; ++ buf = malloc(len); ++ if (!buf) ++ return 0; ++ strcpy(buf, buffer); ++ ++ parse_mutex_lock(); ++ pthread_cleanup_push(parse_mutex_unlock, NULL); ++ ++ pap = ap; ++ psv = *sv; ++ entries = list; ++ amd_set_scan_buffer(buf); ++ ++ local_init_vars(); ++ ret = amd_parse(); ++ local_free_vars(); ++ *sv = psv; ++ ++ pthread_cleanup_pop(1); ++ free(buf); ++ ++ return ret; ++} +--- /dev/null ++++ autofs-5.0.7/modules/amd_tok.l +@@ -0,0 +1,316 @@ ++%{ ++/* ----------------------------------------------------------------------- * ++ * ++ * Copyright 2013 Ian Kent ++ * Copyright 2013 Red Hat, Inc. ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, ++ * USA; either version 2 of the License, or (at your option) any later ++ * version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * ----------------------------------------------------------------------- */ ++ ++#ifdef ECHO ++# undef ECHO ++#endif ++static void amd_echo(void); /* forward definition */ ++#define ECHO amd_echo() ++int amd_wrap(void); ++ ++#include ++#include ++#include ++#include ++#include "amd_parse.tab.h" ++ ++int amd_lex(void); ++int mad_wrap(void); ++ ++#define YY_SKIP_YYWRAP ++ ++#ifndef YY_STACK_USED ++#define YY_STACK_USED 0 ++#endif ++#ifndef YY_ALWAYS_INTERACTIVE ++#define YY_ALWAYS_INTERACTIVE 0 ++#endif ++#ifndef YY_NEVER_INTERACTIVE ++#define YY_NEVER_INTERACTIVE 0 ++#endif ++#ifndef YY_MAIN ++#define YY_MAIN 0 ++#endif ++ ++void amd_set_scan_buffer(const char *); ++static const char *line = NULL; ++ ++#ifdef FLEX_SCANNER ++static const char *line_pos = NULL; ++static const char *line_lim = NULL; ++int amd_yyinput(char *, int); ++ ++#undef YY_INPUT ++#define YY_INPUT(b, r, ms) (r = amd_yyinput(b, ms)) ++#else ++#undef input ++#undef unput ++#define input() (*(char *) line++) ++#define unput(c) (*(char *) --line = c) ++#endif ++ ++%} ++ ++%option nounput ++ ++%x MAPOPTVAL FSOPTVAL MNTOPTVAL SELOPTVAL ++ ++NL \r?\n ++OPTWS [[:blank:]]* ++OTHR [^!;:=/|\- \t\r\n#]* ++ ++MACRO (\$\{([[:alpha:]_/]([[:alnum:]_\-])([[:alnum:]_\-/])*)\}) ++QSTR (\"([^"\\]|\\.)*\") ++OSTR ([[:alpha:]]([[:alnum:]_\-])+) ++FSTR ([[:alnum:]_/\.]([[:alnum:]_\-/\.]|(\\.))*) ++VSTR (([[:alnum:]_\-\:/\.])+) ++SSTR ([[:alpha:]]([[:alnum:]\-\.])+) ++ ++FOPT (({QSTR}|{FSTR}|{MACRO})+) ++OPTS ({OSTR}(=({VSTR}|{QSTR}|{MACRO})+)?) ++SOPT (({SSTR}|{QSTR}|{MACRO})+) ++ ++MAPOPT (fs|type|maptype|pref|sublink|delay) ++MNTOPT (opts|addopts|remopts) ++FSOPTS (rhost|rfs|dev|cachedir) ++MAPTYPE (file|nis|nisplus|ldap|hesiod|exec|ndbm|passwd|union) ++FSTYPE (auto|nfs|link|host|nfsx|ufs|xfs|efs) ++ ++OSSEL (arch|karch|os|osver|full_os|vendor) ++HSTSEL (host|hostd|xhost|domain|byte|cluster) ++NETSEL (netnumber|network|wire|netgrp|netgrpd|in_network) ++USRSEL (uid|gid) ++MAPSEL (key|map|path) ++OTRSEL (exists|autodir|dollar) ++BOLSEL (true|false) ++SELOPT ({OSSEL}|{HSTSEL}|{NETSEL}|{BOLSEL}|{USRSEL}|{MAPSEL}|{OTRSEL}) ++ ++CUTSEP (\|\||\/) ++ ++%% ++ ++{ ++ {NL} | ++ \x00 { } ++ ++ {MAPOPT} { ++ BEGIN(MAPOPTVAL); ++ strcpy(amd_lval.strtype, amd_text); ++ return MAP_OPTION; ++ ++ } ++ ++ {FSOPTS} { ++ BEGIN(FSOPTVAL); ++ strcpy(amd_lval.strtype, amd_text); ++ return FS_OPTION; ++ } ++ ++ {MNTOPT} { ++ BEGIN(MNTOPTVAL); ++ strcpy(amd_lval.strtype, amd_text); ++ return MNT_OPTION; ++ } ++ ++ {SELOPT} { ++ BEGIN(SELOPTVAL); ++ strcpy(amd_lval.strtype, amd_text); ++ return SELECTOR; ++ } ++ ++ {CUTSEP} { return CUT; } ++ ++ "-" { return HYPHEN; } ++ ++ {OPTWS} { return SPACE; } ++ ++ #.* { return COMMENT; } ++ ++ {OTHR} { ++ strcpy(amd_lval.strtype, amd_text); ++ return OTHER; ++ } ++} ++ ++{ ++ {NL} | ++ \x00 { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ ++ ";" { ++ BEGIN(INITIAL); ++ return SEPERATOR; ++ } ++ ++ {OPTWS} { ++ BEGIN(INITIAL); ++ return SPACE; ++ } ++ ++ ":=" { return OPTION_ASSIGN; } ++ ++ {FSTYPE} { ++ strcpy(amd_lval.strtype, amd_text); ++ return FS_TYPE; ++ } ++ ++ {MAPTYPE} { ++ strcpy(amd_lval.strtype, amd_text); ++ return MAP_TYPE; ++ } ++ ++ {FOPT} { ++ strcpy(amd_lval.strtype, amd_text); ++ return FS_OPT_VALUE; ++ } ++} ++ ++{ ++ {NL} | ++ \x00 { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ ++ ";" { ++ BEGIN(INITIAL); ++ return SEPERATOR; ++ } ++ ++ {OPTWS} { ++ BEGIN(INITIAL); ++ return SPACE; ++ } ++ ++ ":=" { return OPTION_ASSIGN; } ++ ++ {FOPT} { ++ strcpy(amd_lval.strtype, amd_text); ++ return FS_OPT_VALUE; ++ } ++} ++ ++{ ++ {NL} | ++ \x00 { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ ++ ";" { ++ BEGIN(INITIAL); ++ return SEPERATOR; ++ } ++ ++ {OPTWS} { ++ BEGIN(INITIAL); ++ return SPACE; ++ } ++ ++ ":=" { return OPTION_ASSIGN; } ++ ++ "," { return COMMA; } ++ ++ {OPTS} { ++ strcpy(amd_lval.strtype, amd_text); ++ return OPTION; ++ } ++} ++ ++{ ++ {NL} | ++ \x00 { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ ++ ";" { ++ BEGIN(INITIAL); ++ return SEPERATOR; ++ } ++ ++ {OPTWS} { ++ BEGIN(INITIAL); ++ return SPACE; ++ } ++ ++ "==" { return IS_EQUAL; } ++ ++ "!=" { return NOT_EQUAL; } ++ ++ {SOPT} { ++ strcpy(amd_lval.strtype, amd_text); ++ return SELECTOR_VALUE; ++ } ++} ++ ++%% ++ ++#include "automount.h" ++ ++int amd_wrap(void) ++{ ++ return 1; ++} ++ ++static void amd_echo(void) ++{ ++ logmsg("%s\n", amd_text); ++ return; ++} ++ ++#ifdef FLEX_SCANNER ++ ++void amd_set_scan_buffer(const char *buffer) ++{ ++ line = buffer; ++ line_pos = &line[0]; ++ /* ++ * Ensure buffer is 1 greater than string and is zeroed before ++ * the parse so we can fit the extra NULL which allows us to ++ * explicitly match an end of line within the buffer (ie. the ++ * need for 2 NULLS when parsing in memeory buffers). ++ */ ++ line_lim = line + strlen(buffer) + 1; ++} ++ ++#define amd_min(a,b) (((a) < (b)) ? (a) : (b)) ++ ++int amd_yyinput(char *buffer, int max_size) ++{ ++ int n = amd_min(max_size, line_lim - line_pos); ++ ++ if (n > 0) { ++ memcpy(buffer, line_pos, n); ++ line_pos += n; ++ } ++ return n; ++} ++ ++#else ++ ++void amd_set_scan_buffer(const char *buffer) ++{ ++ line = buffer; ++} ++ ++#endif +--- /dev/null ++++ autofs-5.0.7/modules/parse_amd.c +@@ -0,0 +1,1081 @@ ++/* ----------------------------------------------------------------------- * ++ * ++ * Copyright 2013 Ian Kent ++ * Copyright 2013 Red Hat, Inc. ++ * All rights reserved. ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, Inc., 675 Mass Ave, Cambridge MA 02139, ++ * USA; either version 2 of the License, or (at your option) any later ++ * version; incorporated herein by reference. ++ * ++ * ----------------------------------------------------------------------- */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MODULE_PARSE ++#include "automount.h" ++ ++#define MODPREFIX "parse(amd): " ++ ++int parse_version = AUTOFS_PARSE_VERSION; /* Required by protocol */ ++ ++static struct mount_mod *mount_nfs = NULL; ++static int init_ctr = 0; ++static pthread_mutex_t instance_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++static void instance_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&instance_mutex); ++ if (status) ++ fatal(status); ++} ++ ++static void instance_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&instance_mutex); ++ if (status) ++ fatal(status); ++} ++ ++extern const char *global_options; ++ ++struct parse_context { ++ char *optstr; /* Mount options */ ++ char *macros; /* Map wide macro defines */ ++ struct substvar *subst; /* $-substitutions */ ++}; ++ ++struct multi_mnt { ++ char *path; ++ char *options; ++ char *location; ++ struct multi_mnt *next; ++}; ++ ++/* Default context */ ++ ++static struct parse_context default_context = { ++ NULL, /* No mount options */ ++ NULL, /* No map wide macros */ ++ NULL /* The substvar local vars table */ ++}; ++ ++/* Free all storage associated with this context */ ++static void kill_context(struct parse_context *ctxt) ++{ ++ macro_lock(); ++ macro_free_table(ctxt->subst); ++ macro_unlock(); ++ if (ctxt->optstr) ++ free(ctxt->optstr); ++ if (ctxt->macros) ++ free(ctxt->macros); ++ free(ctxt); ++} ++ ++int parse_init(int argc, const char *const *argv, void **context) ++{ ++ struct parse_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ sel_hash_init(); ++ ++ /* 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; ++ ++ /* We only need this once. NFS mounts are so common that we cache ++ this module. */ ++ instance_mutex_lock(); ++ if (mount_nfs) ++ init_ctr++; ++ else { ++ if ((mount_nfs = open_mount("nfs", MODPREFIX))) { ++ init_ctr++; ++ } else { ++ kill_context(ctxt); ++ *context = NULL; ++ instance_mutex_unlock(); ++ return 1; ++ } ++ } ++ instance_mutex_unlock(); ++ ++ return 0; ++} ++ ++static void update_with_defaults(struct amd_entry *defaults, ++ struct amd_entry *entry, ++ struct substvar *sv) ++{ ++ const struct substvar *v; ++ unsigned long fstype = entry->flags & AMD_MOUNT_TYPE_MASK; ++ char *tmp; ++ ++ if (fstype == AMD_MOUNT_TYPE_NONE) { ++ unsigned long deftype = defaults->flags & AMD_MOUNT_TYPE_MASK; ++ if (deftype != AMD_MOUNT_TYPE_NONE) ++ entry->flags |= (defaults->flags & AMD_MOUNT_TYPE_MASK); ++ else { ++ entry->flags = AMD_MOUNT_TYPE_NFS; ++ tmp = strdup("nfs"); ++ if (tmp) ++ entry->type = tmp; ++ } ++ } ++ ++ if (!entry->type && defaults->type) { ++ tmp = strdup(defaults->type); ++ if (tmp) ++ entry->type = tmp; ++ } ++ ++ if (!entry->map_type && defaults->map_type) { ++ tmp = strdup(defaults->map_type); ++ if (tmp) ++ entry->map_type = tmp; ++ } ++ ++ if (!entry->pref && defaults->pref) { ++ tmp = strdup(defaults->pref); ++ if (tmp) ++ entry->pref = tmp; ++ } ++ ++ if (!entry->fs && defaults->fs) { ++ tmp = strdup(defaults->fs); ++ if (tmp) ++ entry->fs = tmp; ++ } ++ ++ if (!entry->rfs && defaults->rfs) { ++ tmp = strdup(defaults->rfs); ++ if (tmp) ++ entry->rfs = tmp; ++ } ++ ++ if (!entry->rhost && defaults->rhost) { ++ tmp = strdup(defaults->rhost); ++ if (tmp) ++ entry->rhost = tmp; ++ } ++ ++ if (!entry->opts && defaults->opts) { ++ tmp = merge_options(defaults->opts, entry->opts); ++ if (tmp) ++ entry->opts = tmp; ++ } ++ ++ if (!entry->addopts && defaults->addopts) { ++ tmp = merge_options(defaults->addopts, entry->addopts); ++ if (tmp) ++ entry->addopts = tmp; ++ } ++ ++ if (!entry->remopts && defaults->remopts) { ++ tmp = merge_options(defaults->remopts, entry->remopts); ++ if (tmp) ++ entry->remopts = tmp; ++ } ++ ++ return; ++} ++ ++static char *normalize_hostname(unsigned int logopt, const char *host, ++ unsigned int flags, struct substvar *sv) ++{ ++ struct addrinfo hints, *ni; ++ char *name; ++ int ret; ++ ++ if (!(flags & CONF_NORMALIZE_HOSTNAMES)) ++ name = strdup(host); ++ else { ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_flags = AI_CANONNAME; ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_DGRAM; ++ ++ ret = getaddrinfo(host, NULL, &hints, &ni); ++ if (ret) { ++ error(logopt, "hostname lookup failed: %s", gai_strerror(ret)); ++ return NULL; ++ } ++ name = strdup(ni->ai_canonname); ++ freeaddrinfo(ni); ++ } ++ ++ if (!name) ++ return NULL; ++ ++ if (flags & CONF_DOMAIN_STRIP) { ++ const struct substvar *v = macro_findvar(sv, "hostd", 5); ++ if (v) { ++ char *d1 = strchr(name, '.'); ++ if (d1) { ++ char *d2 = strchr(v->val, '.'); ++ if (d2 && !strcmp(d1, d2)) ++ *d1 = '\0'; ++ } ++ } ++ } ++ ++ return name; ++} ++ ++static struct substvar *expand_entry(struct autofs_point *ap, ++ struct amd_entry *entry, ++ unsigned int flags, ++ struct substvar *sv) ++{ ++ unsigned int logopt = ap->logopt; ++ char *expand; ++ ++ if (entry->rhost) { ++ char *host = strdup(entry->rhost); ++ char *nn; ++ if (!host) { ++ error(ap->logopt, MODPREFIX ++ "failed to allocate storage for rhost"); ++ goto next; ++ } ++ if (expand_selectors(ap, host, &expand, sv)) { ++ free(host); ++ host = expand; ++ } ++ nn = normalize_hostname(ap->logopt, host, flags, sv); ++ if (!nn) ++ sv = macro_addvar(sv, "rhost", 5, host); ++ else { ++ sv = macro_addvar(sv, "rhost", 5, nn); ++ free(host); ++ host = nn; ++ } ++ debug(logopt, MODPREFIX ++ "rhost expand(\"%s\") -> %s", entry->rhost, host); ++ free(entry->rhost); ++ entry->rhost = host; ++ } ++next: ++ if (entry->sublink) { ++ if (expand_selectors(ap, entry->sublink, &expand, sv)) { ++ debug(logopt, MODPREFIX ++ "sublink expand(\"%s\") -> %s", ++ entry->sublink, expand); ++ free(entry->sublink); ++ entry->sublink = expand; ++ } ++ sv = macro_addvar(sv, "sublink", 7, entry->sublink); ++ } ++ ++ if (entry->rfs) { ++ if (expand_selectors(ap, entry->rfs, &expand, sv)) { ++ debug(logopt, MODPREFIX ++ "rfs expand(\"%s\") -> %s", entry->rfs, expand); ++ free(entry->rfs); ++ entry->rfs = expand; ++ } ++ sv = macro_addvar(sv, "rfs", 3, entry->rfs); ++ } ++ ++ if (entry->fs) { ++ if (expand_selectors(ap, entry->fs, &expand, sv)) { ++ debug(logopt, MODPREFIX ++ "fs expand(\"%s\") -> %s", entry->fs, expand); ++ free(entry->fs); ++ entry->fs = expand; ++ } ++ sv = macro_addvar(sv, "fs", 2, entry->fs); ++ } ++ ++ if (entry->opts) { ++ if (expand_selectors(ap, entry->opts, &expand, sv)) { ++ debug(logopt, MODPREFIX ++ "ops expand(\"%s\") -> %s", entry->opts, expand); ++ free(entry->opts); ++ entry->opts = expand; ++ } ++ sv = macro_addvar(sv, "opts", 4, entry->opts); ++ } ++ ++ if (entry->addopts) { ++ if (expand_selectors(ap, entry->addopts, &expand, sv)) { ++ debug(logopt, MODPREFIX ++ "addopts expand(\"%s\") -> %s", ++ entry->addopts, expand); ++ free(entry->addopts); ++ entry->addopts = expand; ++ } ++ sv = macro_addvar(sv, "addopts", 7, entry->addopts); ++ } ++ ++ if (entry->remopts) { ++ if (expand_selectors(ap, entry->remopts, &expand, sv)) { ++ debug(logopt, MODPREFIX ++ "remopts expand(\"%s\") -> %s", ++ entry->remopts, expand); ++ free(entry->remopts); ++ entry->remopts = expand; ++ } ++ sv = macro_addvar(sv, "remopts", 7, entry->remopts); ++ } ++ ++ return sv; ++} ++ ++static void expand_merge_options(struct autofs_point *ap, ++ struct amd_entry *entry, ++ struct substvar *sv) ++{ ++ char *tmp; ++ ++ if (entry->opts) { ++ if (!expand_selectors(ap, entry->opts, &tmp, sv)) ++ error(ap->logopt, MODPREFIX "failed to expand opts"); ++ else { ++ free(entry->opts); ++ entry->opts = tmp; ++ } ++ } ++ ++ if (entry->addopts) { ++ if (!expand_selectors(ap, entry->addopts, &tmp, sv)) ++ error(ap->logopt, MODPREFIX "failed to expand addopts"); ++ else { ++ free(entry->addopts); ++ entry->addopts = tmp; ++ } ++ } ++ ++ if (entry->remopts) { ++ if (!expand_selectors(ap, entry->remopts, &tmp, sv)) ++ error(ap->logopt, MODPREFIX "failed to expand remopts"); ++ else { ++ free(entry->remopts); ++ entry->remopts = tmp; ++ } ++ } ++ ++ return; ++} ++ ++static struct substvar *merge_entry_options(struct autofs_point *ap, ++ struct amd_entry *entry, ++ struct substvar *sv) ++{ ++ char *tmp; ++ ++ if (!entry->addopts) ++ return sv; ++ ++ if (entry->opts && entry->remopts && ++ !strcmp(entry->opts, entry->remopts)) { ++ expand_merge_options(ap, entry, sv); ++ tmp = merge_options(entry->opts, entry->addopts); ++ if (tmp) { ++ info(ap->logopt, MODPREFIX ++ "merge remopts \"%s\" addopts \"%s\" => \"%s\"", ++ entry->opts, entry->addopts, tmp); ++ free(entry->opts); ++ entry->opts = tmp; ++ sv = macro_addvar(sv, "opts", 4, entry->opts); ++ } ++ tmp = strdup(entry->opts); ++ if (tmp) { ++ free(entry->remopts); ++ entry->remopts = tmp; ++ sv = macro_addvar(sv, "remopts", 7, entry->remopts); ++ } ++ return sv; ++ } ++ ++ expand_merge_options(ap, entry, sv); ++ ++ if (entry->opts && entry->addopts) { ++ tmp = merge_options(entry->opts, entry->addopts); ++ if (tmp) { ++ info(ap->logopt, MODPREFIX ++ "merge opts \"%s\" addopts \"%s\" => \"%s\"", ++ entry->opts, entry->addopts, tmp); ++ free(entry->opts); ++ entry->opts = tmp; ++ sv = macro_addvar(sv, "opts", 4, entry->opts); ++ } ++ } else if (entry->addopts) { ++ tmp = strdup(entry->addopts); ++ if (tmp) { ++ info(ap->logopt, MODPREFIX ++ "opts add addopts \"%s\" => \"%s\"", entry->addopts, tmp); ++ entry->opts = tmp; ++ sv = macro_addvar(sv, "opts", 4, entry->opts); ++ } ++ } ++ ++ expand_merge_options(ap, entry, sv); ++ ++ if (entry->remopts && entry->addopts) { ++ tmp = merge_options(entry->remopts, entry->addopts); ++ if (tmp) { ++ info(ap->logopt, MODPREFIX ++ "merge remopts \"%s\" addopts \"%s\" => \"%s\"", ++ entry->remopts, entry->addopts, tmp); ++ free(entry->remopts); ++ entry->remopts = tmp; ++ sv = macro_addvar(sv, "remopts", 7, entry->remopts); ++ } ++ } else if (entry->addopts) { ++ tmp = strdup(entry->addopts); ++ if (tmp) { ++ info(ap->logopt, MODPREFIX ++ "remopts add addopts \"%s\" => \"%s\"", ++ entry->addopts, tmp); ++ entry->remopts = tmp; ++ sv = macro_addvar(sv, "remopts", 7, entry->remopts); ++ } ++ } ++ ++ return sv; ++} ++ ++static int do_auto_mount(struct autofs_point *ap, const char *name, ++ struct amd_entry *entry, unsigned int flags) ++{ ++ char target[PATH_MAX + 1]; ++ int ret; ++ ++ if (!entry->map_type) ++ strcpy(target, entry->fs); ++ else { ++ strcpy(target, entry->map_type); ++ strcat(target, ",amd:"); ++ strcat(target, entry->fs); ++ } ++ ++ ret = do_mount(ap, ap->path, ++ name, strlen(name), target, "autofs", NULL); ++ if (!ret) { ++ struct autofs_point *sm; ++ sm = master_find_submount(ap, entry->path); ++ if (sm) { ++ sm->pref = entry->pref; ++ entry->pref = NULL; ++ } ++ } ++ ++ return ret; ++} ++ ++static int do_link_mount(struct autofs_point *ap, const char *name, ++ struct amd_entry *entry, unsigned int flags) ++{ ++ char target[PATH_MAX + 1]; ++ int ret; ++ ++ if (entry->sublink) ++ strcpy(target, entry->sublink); ++ else ++ strcpy(target, entry->fs); ++ ++ if (!(flags & CONF_AUTOFS_USE_LOFS)) ++ goto symlink; ++ ++ /* For a sublink this might cause an external mount */ ++ ret = do_mount(ap, ap->path, ++ name, strlen(name), target, "bind", entry->opts); ++ if (!ret) ++ goto out; ++ ++ debug(ap->logopt, MODPREFIX "bind mount failed, symlinking"); ++ ++symlink: ++ ret = do_mount(ap, ap->path, ++ name, strlen(name), target, "bind", "symlink"); ++ if (!ret) ++ goto out; ++ ++ error(ap->logopt, MODPREFIX ++ "failed to symlink %s to %s", entry->path, target); ++ ++ if (entry->sublink) { ++ /* failed to complete sublink mount */ ++ if (ext_mount_remove(&entry->ext_mount, entry->fs)) ++ umount_ent(ap, entry->fs); ++ } ++out: ++ return ret; ++} ++ ++static int do_nfs_mount(struct autofs_point *ap, const char *name, ++ struct amd_entry *entry, unsigned int flags) ++{ ++ char target[PATH_MAX + 1]; ++ int ret = 0; ++ ++ strcpy(target, entry->rhost); ++ strcat(target, ":"); ++ strcat(target, entry->rfs); ++ ++ if (!entry->sublink) { ++ ret = mount_nfs->mount_mount(ap, ap->path, name, strlen(name), ++ target, entry->type, entry->opts, ++ mount_nfs->context); ++ } else { ++ if (!is_mounted(_PATH_MOUNTED, entry->fs, MNTS_REAL)) { ++ ret = mount_nfs->mount_mount(ap, entry->fs, "/", 1, ++ target, entry->type, entry->opts, ++ mount_nfs->context); ++ if (ret) ++ goto out; ++ } ++ /* We might be using an external mount */ ++ ext_mount_add(&entry->ext_mount, entry->fs); ++ ret = do_link_mount(ap, name, entry, flags); ++ } ++out: ++ return ret; ++} ++ ++static int do_host_mount(struct autofs_point *ap, const char *name, ++ struct amd_entry *entry, struct map_source *source, ++ unsigned int flags) ++{ ++ struct lookup_mod *lookup; ++ struct mapent *me; ++ const char *argv[2]; ++ int ret = 1; ++ ++ argv[0] = entry->opts; ++ argv[1] = NULL; ++ ++ lookup = open_lookup("hosts", MODPREFIX, NULL, 1, argv); ++ if (!lookup) { ++ debug(ap->logopt, "open lookup module hosts failed"); ++ goto out; ++ } ++ ++ me = cache_lookup_distinct(source->mc, name); ++ if (me) ++ cache_push_mapent(me, NULL); ++ ++ master_source_current_wait(ap->entry); ++ ap->entry->current = source; ++ ++ ret = lookup->lookup_mount(ap, name, strlen(name), lookup->context); ++ ++ close_lookup(lookup); ++out: ++ return ret; ++} ++ ++static int amd_mount(struct autofs_point *ap, const char *name, ++ struct amd_entry *entry, struct map_source *source, ++ struct substvar *sv, unsigned int flags, ++ struct parse_context *ctxt) ++{ ++ unsigned long fstype = entry->flags & AMD_MOUNT_TYPE_MASK; ++ int ret = 1; ++ ++ switch (fstype) { ++ case AMD_MOUNT_TYPE_AUTO: ++ ret = do_auto_mount(ap, name, entry, flags); ++ break; ++ ++ case AMD_MOUNT_TYPE_NFS: ++ ret = do_nfs_mount(ap, name, entry, flags); ++ break; ++ ++ case AMD_MOUNT_TYPE_LINK: ++ ret = do_link_mount(ap, name, entry, flags); ++ break; ++ ++ case AMD_MOUNT_TYPE_HOST: ++ ret = do_host_mount(ap, name, entry, source, flags); ++ break; ++ ++ default: ++ info(ap->logopt, ++ MODPREFIX "unkown file system type %x", fstype); ++ break; ++ } ++ ++ return ret; ++} ++ ++void dequote_entry(struct autofs_point *ap, struct amd_entry *entry) ++{ ++ char *res; ++ ++ if (entry->pref) { ++ res = dequote(entry->pref, strlen(entry->pref), ap->logopt); ++ if (res) { ++ debug(ap->logopt, ++ MODPREFIX "pref dequote(\"%.*s\") -> %s", ++ strlen(entry->pref), entry->pref, res); ++ free(entry->pref); ++ entry->pref = res; ++ } ++ } ++ ++ if (entry->sublink) { ++ res = dequote(entry->sublink, strlen(entry->sublink), ap->logopt); ++ if (res) { ++ debug(ap->logopt, ++ MODPREFIX "sublink dequote(\"%.*s\") -> %s", ++ strlen(entry->sublink), entry->sublink, res); ++ free(entry->sublink); ++ entry->sublink = res; ++ } ++ } ++ ++ if (entry->fs) { ++ res = dequote(entry->fs, strlen(entry->fs), ap->logopt); ++ if (res) { ++ debug(ap->logopt, ++ MODPREFIX "fs dequote(\"%.*s\") -> %s", ++ strlen(entry->fs), entry->fs, res); ++ free(entry->fs); ++ entry->fs = res; ++ } ++ } ++ ++ if (entry->rfs) { ++ res = dequote(entry->rfs, strlen(entry->rfs), ap->logopt); ++ if (res) { ++ debug(ap->logopt, ++ MODPREFIX "rfs dequote(\"%.*s\") -> %s", ++ strlen(entry->rfs), entry->rfs, res); ++ free(entry->rfs); ++ entry->rfs = res; ++ } ++ } ++ ++ if (entry->opts) { ++ res = dequote(entry->opts, strlen(entry->opts), ap->logopt); ++ if (res) { ++ debug(ap->logopt, ++ MODPREFIX "ops dequote(\"%.*s\") -> %s", ++ strlen(entry->opts), entry->opts, res); ++ free(entry->opts); ++ entry->opts = res; ++ } ++ } ++ ++ if (entry->remopts) { ++ res = dequote(entry->remopts, strlen(entry->remopts), ap->logopt); ++ if (res) { ++ debug(ap->logopt, ++ MODPREFIX "remopts dequote(\"%.*s\") -> %s", ++ strlen(entry->remopts), entry->remopts, res); ++ free(entry->remopts); ++ entry->remopts = res; ++ } ++ } ++ ++ if (entry->addopts) { ++ res = dequote(entry->addopts, strlen(entry->addopts), ap->logopt); ++ if (res) { ++ debug(ap->logopt, ++ MODPREFIX "addopts dequote(\"%.*s\") -> %s", ++ strlen(entry->addopts), entry->addopts, res); ++ free(entry->addopts); ++ entry->addopts = res; ++ } ++ } ++ ++ return; ++} ++ ++static void normalize_sublink(unsigned int logopt, ++ struct amd_entry *entry, struct substvar *sv) ++{ ++ char *new; ++ size_t len; ++ ++ if (entry->sublink && *entry->sublink != '/') { ++ len = strlen(entry->fs) + strlen(entry->sublink) + 2; ++ new = malloc(len); ++ if (!new) { ++ error(logopt, MODPREFIX ++ "error: couldn't allocate storage for sublink"); ++ return; ++ } ++ strcpy(new, entry->fs); ++ strcat(new, "/"); ++ strcat(new, entry->sublink); ++ debug(logopt, MODPREFIX ++ "rfs dequote(\"%.*s\") -> %s", ++ strlen(entry->sublink), entry->sublink, new); ++ free(entry->sublink); ++ entry->sublink = new; ++ } ++ return; ++} ++ ++static struct amd_entry *dup_defaults_entry(struct amd_entry *defaults) ++{ ++ struct amd_entry *entry; ++ char *tmp; ++ ++ entry = malloc(sizeof(struct amd_entry)); ++ if (!entry) ++ return NULL; ++ memset(entry, 0, sizeof(struct amd_entry)); ++ ++ entry->flags = defaults->flags; ++ ++ if (defaults->type) { ++ tmp = strdup(defaults->type); ++ if (tmp) ++ entry->type = tmp; ++ } ++ ++ if (defaults->map_type) { ++ tmp = strdup(defaults->map_type); ++ if (tmp) ++ entry->map_type = tmp; ++ } ++ ++ if (defaults->pref) { ++ tmp = strdup(defaults->pref); ++ if (tmp) ++ entry->pref = tmp; ++ } ++ ++ if (defaults->fs) { ++ tmp = strdup(defaults->fs); ++ if (tmp) ++ entry->fs = tmp; ++ } ++ ++ if (defaults->rfs) { ++ tmp = strdup(defaults->rfs); ++ if (tmp) ++ entry->rfs = tmp; ++ } ++ ++ if (defaults->rhost) { ++ tmp = strdup(defaults->rhost); ++ if (tmp) ++ entry->rhost = tmp; ++ } ++ ++ if (defaults->opts) { ++ tmp = strdup(defaults->opts); ++ if (tmp) ++ entry->opts = tmp; ++ } ++ ++ if (defaults->addopts) { ++ tmp = strdup(defaults->addopts); ++ if (tmp) ++ entry->addopts = tmp; ++ } ++ ++ if (defaults->remopts) { ++ tmp = strdup(defaults->remopts); ++ if (tmp) ++ entry->remopts = tmp; ++ } ++ ++ INIT_LIST_HEAD(&entry->list); ++ ++ return entry; ++} ++ ++struct amd_entry *make_default_entry(struct autofs_point *ap, ++ struct substvar *sv) ++{ ++ char *defaults = "opts:=rw,defaults"; ++ struct amd_entry *defaults_entry; ++ struct list_head dflts; ++ ++ INIT_LIST_HEAD(&dflts); ++ if (amd_parse_list(ap, defaults, &dflts, &sv)) ++ return NULL; ++ defaults_entry = list_entry(dflts.next, struct amd_entry, list); ++ list_del_init(&defaults_entry->list); ++ /* The list should now be empty .... */ ++ free_amd_entry_list(&dflts); ++ return defaults_entry; ++} ++ ++static struct amd_entry *select_default_entry(struct autofs_point *ap, ++ struct list_head *entries, ++ struct substvar *sv) ++{ ++ unsigned long flags = conf_amd_get_flags(ap->path); ++ struct amd_entry *defaults_entry = NULL; ++ struct amd_entry *entry_default = NULL; ++ struct list_head *p, *head; ++ ++ if (!(flags & CONF_SELECTORS_IN_DEFAULTS)) ++ goto no_sel; ++ ++ head = entries; ++ p = head->next; ++ while (p != head) { ++ struct amd_entry *this = list_entry(p, struct amd_entry, list); ++ ++ p = p->next; ++ ++ if (this->flags & AMD_DEFAULTS_MERGE) { ++ if (entry_default) ++ free_amd_entry(entry_default); ++ list_del_init(&this->list); ++ entry_default = this; ++ continue; ++ } else if (this->flags & AMD_DEFAULTS_RESET) { ++ struct amd_entry *new; ++ new = dup_defaults_entry(defaults_entry); ++ if (new) { ++ free_amd_entry(entry_default); ++ entry_default = new; ++ } ++ list_del_init(&this->list); ++ free_amd_entry(this); ++ continue; ++ } ++ } ++ ++ /* Not strickly amd semantics but ... */ ++ if (!defaults_entry && entry_default) { ++ defaults_entry = entry_default; ++ goto done; ++ } ++ ++ if (!defaults_entry) { ++ debug(ap->logopt, MODPREFIX ++ "no matching selector(s) found in defaults, " ++ "using internal defaults"); ++ goto ret_default; ++ } ++ ++ goto done; ++ ++no_sel: ++ if (list_empty(entries)) ++ goto ret_default; ++ ++ defaults_entry = list_entry(entries->next, struct amd_entry, list); ++ list_del_init(&defaults_entry->list); ++ if (!list_empty(entries)) { ++ free_amd_entry(defaults_entry); ++ goto ret_default; ++ } ++done: ++ /*merge_entry_options(ap, defaults_entry, sv);*/ ++ /*normalize_sublink(ap->logopt, defaults_entry, sv);*/ ++ return defaults_entry; ++ ++ret_default: ++ return make_default_entry(ap, sv); ++} ++ ++static struct amd_entry *get_defaults_entry(struct autofs_point *ap, ++ const char *defaults, ++ struct substvar *sv) ++{ ++ struct amd_entry *entry; ++ struct list_head dflts; ++ ++ INIT_LIST_HEAD(&dflts); ++ ++ entry = NULL; ++ if (!defaults) ++ goto out; ++ else { ++ char *expand; ++ if (!expand_selectors(ap, defaults, &expand, sv)) ++ goto out; ++ if (amd_parse_list(ap, expand, &dflts, &sv)) ++ goto out; ++ entry = select_default_entry(ap, &dflts, sv); ++ free(expand); ++ } ++ ++ return entry; ++out: ++ return make_default_entry(ap, sv); ++} ++ ++int parse_mount(struct autofs_point *ap, const char *name, ++ int name_len, const char *mapent, void *context) ++{ ++ struct parse_context *ctxt = (struct parse_context *) context; ++ unsigned int flags = conf_amd_get_flags(ap->path); ++ struct substvar *sv = NULL; ++ struct map_source *source; ++ struct mapent_cache *mc; ++ struct mapent *me; ++ struct list_head entries, *p, *head; ++ struct amd_entry *defaults_entry; ++ struct amd_entry *cur_defaults; ++ char *defaults; ++ char *pmapent; ++ int len, rv = 1; ++ int cur_state; ++ int ret; ++ ++ source = ap->entry->current; ++ ap->entry->current = NULL; ++ master_source_current_signal(ap->entry); ++ ++ mc = source->mc; ++ ++ if (!mapent) { ++ warn(ap->logopt, MODPREFIX "error: empty map entry"); ++ return 1; ++ } ++ ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); ++ ++ len = expand_selectors(ap, mapent, &pmapent, sv); ++ if (!len) { ++ macro_free_table(sv); ++ pthread_setcancelstate(cur_state, NULL); ++ return 1; ++ } ++ ++ pthread_setcancelstate(cur_state, NULL); ++ ++ debug(ap->logopt, MODPREFIX "expanded mapent: %s", pmapent); ++ ++ defaults = conf_amd_get_map_defaults(ap->path); ++ if (defaults) { ++ debug(ap->logopt, MODPREFIX ++ "using map_defaults %s for %s", defaults, ap->path); ++ } else if ((me = cache_lookup_distinct(mc, "/defaults"))) { ++ defaults = strdup(me->mapent); ++ if (defaults) ++ debug(ap->logopt, MODPREFIX ++ "using /defaults %s from map", defaults); ++ else { ++ char buf[MAX_ERR_BUF]; ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ } ++ } ++ ++ defaults_entry = get_defaults_entry(ap, defaults, sv); ++ if (!defaults_entry) { ++ error(ap->logopt, MODPREFIX "failed to get a defaults entry"); ++ if (defaults) ++ free(defaults); ++ free(pmapent); ++ macro_free_table(sv); ++ return 1; ++ } ++ if (defaults) ++ free(defaults); ++ ++ INIT_LIST_HEAD(&entries); ++ ++ ret = amd_parse_list(ap, pmapent, &entries, &sv); ++ if (ret) { ++ error(ap->logopt, ++ MODPREFIX "failed to parse entry: %s", pmapent); ++ free(pmapent); ++ goto done; ++ } ++ ++ free(pmapent); ++ ++ if (list_empty(&entries)) { ++ error(ap->logopt, MODPREFIX "no location found after parse"); ++ goto done; ++ } ++ ++ cur_defaults = dup_defaults_entry(defaults_entry); ++ if (!cur_defaults) { ++ error(ap->logopt, MODPREFIX ++ "failed to duplicate defaults entry"); ++ goto done; ++ } ++ ++ head = &entries; ++ p = head->next; ++ while (p != head) { ++ struct amd_entry *this = list_entry(p, struct amd_entry, list); ++ p = p->next; ++ ++ if (this->flags & AMD_DEFAULTS_MERGE) { ++ free_amd_entry(cur_defaults); ++ list_del_init(&this->list); ++ cur_defaults = this; ++ continue; ++ } else if (this->flags & AMD_DEFAULTS_RESET) { ++ struct amd_entry *new; ++ new = dup_defaults_entry(defaults_entry); ++ if (new) { ++ free_amd_entry(cur_defaults); ++ cur_defaults = new; ++ } ++ list_del_init(&this->list); ++ free_amd_entry(this); ++ continue; ++ } ++ ++ update_with_defaults(cur_defaults, this, sv); ++ sv = expand_entry(ap, this, flags, sv); ++ sv = merge_entry_options(ap, this, sv); ++ normalize_sublink(ap->logopt, this, sv); ++ ++ dequote_entry(ap, this); ++ ++ rv = amd_mount(ap, name, this, source, sv, flags, ctxt); ++ if (!rv) ++ break; ++ } ++ free_amd_entry(cur_defaults); ++ ++ if (rv) ++ debug(ap->logopt, "no more locations to try, returning fail"); ++done: ++ free_amd_entry_list(&entries); ++ free_amd_entry(defaults_entry); ++ macro_free_table(sv); ++ ++ return rv; ++} ++ ++int parse_done(void *context) ++{ ++ int rv = 0; ++ struct parse_context *ctxt = (struct parse_context *) context; ++ ++ instance_mutex_lock(); ++ if (--init_ctr == 0) { ++ rv = close_mount(mount_nfs); ++ mount_nfs = NULL; ++ } ++ instance_mutex_unlock(); ++ if (ctxt) ++ kill_context(ctxt); ++ ++ return rv; ++} diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-remopts-handling.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-remopts-handling.patch new file mode 100644 index 0000000..9f2ecd5 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-remopts-handling.patch @@ -0,0 +1,42 @@ +autofs-5.0.9 - amd lookup add remopts handling + +From: Ian Kent + + +--- + modules/parse_amd.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index bf673b3..4cebce8 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -988,20 +988,26 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name, + struct amd_entry *entry, unsigned int flags) + { + char target[PATH_MAX + 1]; ++ unsigned int proximity; ++ char *opts = entry->opts; + int ret = 0; + + strcpy(target, entry->rhost); + strcat(target, ":"); + strcat(target, entry->rfs); + ++ proximity = get_network_proximity(entry->rhost); ++ if (proximity == PROXIMITY_OTHER && entry->remopts) ++ opts = entry->remopts; ++ + if (!entry->sublink) { + ret = mount_nfs->mount_mount(ap, ap->path, name, strlen(name), +- target, entry->type, entry->opts, ++ target, entry->type, opts, + mount_nfs->context); + } else { + if (!is_mounted(_PATH_MOUNTED, entry->fs, MNTS_REAL)) { + ret = mount_nfs->mount_mount(ap, entry->fs, "/", 1, +- target, entry->type, entry->opts, ++ target, entry->type, opts, + mount_nfs->context); + if (ret) + goto out; diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-search_path-handling.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-search_path-handling.patch new file mode 100644 index 0000000..7c4ecd2 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-search_path-handling.patch @@ -0,0 +1,263 @@ +autofs-5.0.9 - amd lookup add search_path handling + +From: Ian Kent + + +--- + daemon/lookup.c | 75 +++++++++++++++++++++++++++++++---------- + include/master.h | 1 + lib/master.c | 6 +++ + man/autofs.conf.5.in | 5 ++ + modules/parse_amd.c | 4 +- + redhat/autofs.conf.default.in | 9 +--- + samples/autofs.conf.default.in | 9 +--- + 7 files changed, 79 insertions(+), 30 deletions(-) + +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -100,25 +100,64 @@ static int do_read_master(struct master + return status; + } + +-static char *find_map_path(struct map_source *map) ++static char *find_map_path(struct autofs_point *ap, struct map_source *map) + { ++ const char *mname = map->argv[0]; ++ unsigned int mlen = strlen(mname); ++ char *tok, *ptr = NULL; ++ char *path = NULL; ++ char *search_path; + struct stat st; +- char *path; + +- path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(map->argv[0]) + 2); +- if (!path) ++ /* ++ * This is different to the way it is in amd. ++ * autofs will always try to locate maps in AUTOFS_MAP_DIR ++ * but amd has no default and will not find a file map that ++ * isn't a full path when no search_path is configured, either ++ * in the mount point or global configuration. ++ */ ++ search_path = strdup(AUTOFS_MAP_DIR); ++ if (map->flags & MAP_FLAG_FORMAT_AMD) { ++ struct autofs_point *pap = ap; ++ char *tmp; ++ /* ++ * Make sure we get search_path from the root of the ++ * mount tree, if one is present in the configuration. ++ * Again different from amd, which ignores the submount ++ * case. ++ */ ++ while (pap->parent) ++ pap = pap->parent; ++ tmp = conf_amd_get_search_path(pap->path); ++ if (tmp) { ++ if (search_path) ++ free(search_path); ++ search_path = tmp; ++ } ++ } ++ if (!search_path) + return NULL; + +- strcpy(path, AUTOFS_MAP_DIR); +- strcat(path, "/"); +- strcat(path, map->argv[0]); +- +- if (!stat(path, &st)) +- return path; +- +- free(path); ++ tok = strtok_r(search_path, ":", &ptr); ++ while (tok) { ++ char *this = malloc(strlen(tok) + mlen + 2); ++ if (!this) { ++ free(search_path); ++ return NULL; ++ } ++ strcpy(this, tok); ++ strcat(this, "/"); ++ strcat(this, mname); ++ if (!stat(this, &st)) { ++ path = this; ++ break; ++ } ++ free(this); ++ tok = strtok_r(NULL, ":", &ptr); ++ } + +- return NULL; ++ free(search_path); ++ return path; + } + + static int read_master_map(struct master *master, char *type, time_t age) +@@ -435,7 +474,7 @@ static int lookup_map_read_map(struct au + if (map->argv[0][0] == '/') + return do_read_map(ap, map, age); + +- path = find_map_path(map); ++ path = find_map_path(ap, map); + if (!path) + return NSS_STATUS_UNKNOWN; + +@@ -479,6 +518,7 @@ static enum nsswitch_status read_map_sou + tmap.flags = map->flags; + tmap.type = this->source; + tmap.format = map->format; ++ tmap.name = map->name; + tmap.lookup = map->lookup; + tmap.mc = map->mc; + tmap.instance = map->instance; +@@ -489,7 +529,7 @@ static enum nsswitch_status read_map_sou + tmap.argc = 0; + tmap.argv = NULL; + +- path = find_map_path(map); ++ path = find_map_path(ap, map); + if (!path) + return NSS_STATUS_UNKNOWN; + +@@ -838,7 +878,7 @@ static int do_name_lookup_mount(struct a + if (map->argv[0][0] == '/') + return do_lookup_mount(ap, map, name, name_len); + +- path = find_map_path(map); ++ path = find_map_path(ap, map); + if (!path) + return NSS_STATUS_UNKNOWN; + +@@ -883,6 +923,7 @@ static enum nsswitch_status lookup_map_n + tmap.flags = map->flags; + tmap.type = this->source; + tmap.format = map->format; ++ tmap.name = map->name; + tmap.mc = map->mc; + tmap.instance = map->instance; + tmap.exp_timeout = map->exp_timeout; +@@ -891,7 +932,7 @@ static enum nsswitch_status lookup_map_n + tmap.argc = 0; + tmap.argv = NULL; + +- path = find_map_path(map); ++ path = find_map_path(ap, map); + if (!path) + return NSS_STATUS_UNKNOWN; + +--- autofs-5.0.7.orig/include/master.h ++++ autofs-5.0.7/include/master.h +@@ -26,6 +26,7 @@ struct map_source { + unsigned int flags; + char *type; + char *format; ++ char *name; + time_t exp_timeout; /* Timeout for expiring mounts */ + time_t age; + unsigned int master_line; +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -211,6 +211,8 @@ master_add_map_source(struct master_mape + } + source->argc = argc; + source->argv = tmpargv; ++ if (source->argv[0]) ++ source->name = strdup(source->argv[0]); + + master_source_writelock(entry); + +@@ -333,6 +335,8 @@ static void __master_free_map_source(str + free(source->type); + if (source->format) + free(source->format); ++ if (source->name) ++ free(source->name); + if (free_cache && source->mc) + cache_release(source); + if (source->lookup) { +@@ -468,6 +472,8 @@ master_add_source_instance(struct map_so + } + new->argc = argc; + new->argv = tmpargv; ++ if (source->name) ++ new->name = strdup(source->name); + + status = pthread_mutex_lock(&instance_mutex); + if (status) +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -327,6 +327,11 @@ and can be used to provide different def + without having to modify centrally managed maps. It is empty by + default. + .TP ++.B search_path ++.br ++Colon seperated paths to search for maps that are not specified ++as a full path. ++.TP + .B dismount_interval + .br + Is equivalent to the autofs timeout option. It is only possible +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -198,7 +198,9 @@ static struct substvar *add_lookup_vars( + break; + } + +- if (source->argv[0][0]) ++ if (source->name) ++ list = macro_addvar(list, "map", 3, source->name); ++ else if (source->argv[0][0]) + list = macro_addvar(list, "map", 3, source->argv[0]); + + tsv = pthread_getspecific(key_thread_stdenv_vars); +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -221,12 +221,6 @@ mount_nfs_default_protocol = 4 + # + # A number of configuration options are not yet implemented: + # +-# search_path - always a little frustrating, the compiled in +-# map location should be used to locate maps but isn't +-# in some cases. This requires work within autofs itself +-# and that will (obviously) include implementing this +-# configuration option for the amd map parser as well. +-# + # fully_qualified_hosts - not yet implemented. + # + # unmount_on_exit - since autofs always tries to re-connect +@@ -269,6 +263,9 @@ mount_nfs_default_protocol = 4 + # machines without having to modify centrally managed maps. + # It is empty by default. + # ++# search_path - colon seperated paths to search for maps that ++# are not specified as a full path. ++# + # dismount_interval - is equivalent to the autofs timeout option. It + # is only possible to use this with type "auto" mounts due + # to the way the autofs kernel module performs expiry. It +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -220,12 +220,6 @@ browse_mode = no + # + # A number of configuration options are not yet implemented: + # +-# search_path - always a little frustrating, the compiled in +-# map location should be used to locate maps but isn't +-# in some cases. This requires work within autofs itself +-# and that will (obviously) include implementing this +-# configuration option for the amd map parser as well. +-# + # fully_qualified_hosts - not yet implemented. + # + # unmount_on_exit - since autofs always tries to re-connect +@@ -268,6 +262,9 @@ browse_mode = no + # machines without having to modify centrally managed maps. + # It is empty by default. + # ++# search_path - colon seperated paths to search for maps that ++# are not specified as a full path. ++# + # dismount_interval - is equivalent to the autofs timeout option. It + # is only possible to use this with type "auto" mounts due + # to the way the autofs kernel module performs expiry. It diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-selector-handling-functions.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-selector-handling-functions.patch new file mode 100644 index 0000000..62cd55e --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-selector-handling-functions.patch @@ -0,0 +1,233 @@ +autofs-5.0.999999999 - amd lookup add selector handling functions + +From: Ian Kent + + +--- + include/parse_subs.h | 77 +++++++++++++++++++++++++++++++++ + lib/parse_subs.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 194 insertions(+) + +diff --git a/include/parse_subs.h b/include/parse_subs.h +index 675411d..a416c59 100644 +--- a/include/parse_subs.h ++++ b/include/parse_subs.h +@@ -25,6 +25,83 @@ + #define PROXIMITY_OTHER 0x0008 + #define PROXIMITY_UNSUPPORTED 0x0010 + ++#define SEL_ARCH 0x00000001 ++#define SEL_KARCH 0x00000002 ++#define SEL_OS 0x00000004 ++#define SEL_OSVER 0x00000008 ++#define SEL_FULL_OS 0x00000010 ++#define SEL_VENDOR 0x00000020 ++#define SEL_HOST 0x00000040 ++#define SEL_HOSTD 0x00000080 ++#define SEL_XHOST 0x00000100 ++#define SEL_DOMAIN 0x00000200 ++#define SEL_BYTE 0x00000400 ++#define SEL_CLUSTER 0x00000800 ++#define SEL_NETGRP 0x00001000 ++#define SEL_NETGRPD 0x00002000 ++#define SEL_IN_NETWORK 0x00004000 ++#define SEL_UID 0x00008000 ++#define SEL_GID 0x00010000 ++#define SEL_KEY 0x00020000 ++#define SEL_MAP 0x00040000 ++#define SEL_PATH 0x00080000 ++#define SEL_EXISTS 0x00100000 ++#define SEL_AUTODIR 0x00200000 ++#define SEL_DOLLAR 0x00400000 ++#define SEL_TRUE 0x00800000 ++#define SEL_FALSE 0x01000000 ++ ++#define SEL_COMP_NONE 0x0000 ++#define SEL_COMP_EQUAL 0x0001 ++#define SEL_COMP_NOTEQUAL 0x0002 ++#define SEL_COMP_NOT 0x0004 ++ ++#define SEL_FLAG_MACRO 0x0001 ++#define SEL_FLAG_FUNC1 0x0002 ++#define SEL_FLAG_FUNC2 0x0004 ++#define SEL_FLAG_STR 0x0100 ++#define SEL_FLAG_NUM 0x0200 ++#define SEL_FLAG_BOOL 0x0400 ++ ++#define SEL_FLAGS_TYPE_MASK 0x00FF ++#define SEL_FLAGS_VALUE_MASK 0xFF00 ++#define SEL_FREE_VALUE_MASK (SEL_FLAG_MACRO|SEL_FLAG_STR|SEL_FLAG_NUM) ++#define SEL_FREE_ARG1_MASK (SEL_FLAG_FUNC1) ++#define SEL_FREE_ARG2_MASK (SEL_FLAG_FUNC2) ++ ++struct type_compare { ++ char *value; ++}; ++ ++struct type_function { ++ char *arg1; ++ char *arg2; ++}; ++ ++struct sel { ++ unsigned long selector; ++ const char *name; ++ unsigned int flags; ++ struct sel *next; ++}; ++ ++struct selector { ++ struct sel *sel; ++ unsigned int compare; ++ ++ union { ++ struct type_compare comp; ++ struct type_function func; ++ }; ++ ++ struct selector *next; ++}; ++ ++void sel_hash_init(void); ++struct sel *sel_lookup(const char *); ++struct selector *get_selector(char *); ++void free_selector(struct selector *); ++ + struct mapent; + + struct map_type_info { +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index 279f40e..f485a4c 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -45,6 +45,44 @@ static int volatile ifc_last_len = 0; + #define EXPAND_LEADING_DOT 0x0004 + #define EXPAND_TRAILING_DOT 0x0008 + ++#define SELECTOR_HASH_SIZE 20 ++ ++static struct sel sel_table[] = { ++ { SEL_ARCH, "arch", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_KARCH, "karch", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_OS, "os", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_OSVER, "osver", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_FULL_OS, "full_os", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_VENDOR, "vendor", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_HOST, "host", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_HOSTD, "hostd", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_XHOST, "xhost", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, ++ { SEL_DOMAIN, "domain", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_BYTE, "byte", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_CLUSTER, "cluster", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_NETGRP, "netgrp", SEL_FLAG_FUNC2|SEL_FLAG_BOOL, NULL }, ++ { SEL_NETGRPD, "netgrpd", SEL_FLAG_FUNC2|SEL_FLAG_BOOL, NULL }, ++ { SEL_IN_NETWORK, "in_network", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, ++ { SEL_IN_NETWORK, "netnumber", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, ++ { SEL_IN_NETWORK, "network", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, ++ { SEL_IN_NETWORK, "wire", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, ++ { SEL_UID, "uid", SEL_FLAG_MACRO|SEL_FLAG_NUM, NULL }, ++ { SEL_GID, "gid", SEL_FLAG_MACRO|SEL_FLAG_NUM, NULL }, ++ { SEL_KEY, "key", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_MAP, "map", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_PATH, "path", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_EXISTS, "exists", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, ++ { SEL_AUTODIR, "autodir", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_DOLLAR, "dollar", SEL_FLAG_MACRO|SEL_FLAG_STR, NULL }, ++ { SEL_TRUE, "true", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, ++ { SEL_FALSE, "false", SEL_FLAG_FUNC1|SEL_FLAG_BOOL, NULL }, ++}; ++static unsigned int sel_count = sizeof(sel_table)/sizeof(struct sel); ++ ++static struct sel *sel_hash[SELECTOR_HASH_SIZE]; ++static unsigned int sel_hash_init_done = 0; ++static pthread_mutex_t sel_hash_mutex = PTHREAD_MUTEX_INITIALIZER; ++ + struct types { + char *type; + unsigned int len; +@@ -70,6 +108,85 @@ static struct types format_type[] = { + }; + static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types); + ++static void sel_add(struct sel *sel) ++{ ++ u_int32_t hval = hash(sel->name, SELECTOR_HASH_SIZE); ++ struct sel *old; ++ ++ old = sel_hash[hval]; ++ sel_hash[hval] = sel; ++ sel_hash[hval]->next = old; ++} ++ ++void sel_hash_init(void) ++{ ++ int i; ++ ++ pthread_mutex_lock(&sel_hash_mutex); ++ if (sel_hash_init_done) { ++ pthread_mutex_unlock(&sel_hash_mutex); ++ return; ++ } ++ for (i = 0; i < SELECTOR_HASH_SIZE; i++) ++ sel_hash[i] = NULL; ++ ++ for (i = 0; i < sel_count; i++) ++ sel_add(&sel_table[i]); ++ ++ sel_hash_init_done = 1; ++ pthread_mutex_unlock(&sel_hash_mutex); ++} ++ ++struct sel *sel_lookup(const char *name) ++{ ++ u_int32_t hval = hash(name, SELECTOR_HASH_SIZE); ++ struct sel *sel; ++ ++ pthread_mutex_lock(&sel_hash_mutex); ++ for (sel = sel_hash[hval]; sel != NULL; sel = sel->next) { ++ if (strcmp(name, sel->name) == 0) { ++ pthread_mutex_unlock(&sel_hash_mutex); ++ return sel; ++ } ++ } ++ pthread_mutex_unlock(&sel_hash_mutex); ++ return NULL; ++} ++ ++struct selector *get_selector(char *name) ++{ ++ struct sel *sel; ++ ++ sel = sel_lookup(name); ++ if (sel) { ++ struct selector *new = malloc(sizeof(struct selector)); ++ if (!new) ++ return NULL; ++ memset(new, 0, sizeof(*new)); ++ new->sel = sel; ++ return new; ++ } ++ return NULL; ++} ++ ++void free_selector(struct selector *selector) ++{ ++ struct selector *s = selector; ++ struct selector *next = s; ++ ++ while (s) { ++ next = s->next; ++ if (s->sel->flags & SEL_FREE_VALUE_MASK) ++ free(s->comp.value); ++ if (s->sel->flags & SEL_FREE_ARG1_MASK) ++ free(s->func.arg1); ++ if (s->sel->flags & SEL_FREE_ARG2_MASK) ++ free(s->func.arg2); ++ s = next; ++ } ++ return; ++} ++ + static unsigned int ipv6_mask_cmp(uint32_t *host, uint32_t *iface, uint32_t *mask) + { + unsigned int ret = 1; diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-selector-handling.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-selector-handling.patch new file mode 100644 index 0000000..c77ca64 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-selector-handling.patch @@ -0,0 +1,775 @@ +autofs-5.0.9 - amd lookup add selector handling + +From: Ian Kent + + +--- + include/parse_subs.h | 2 + lib/parse_subs.c | 127 ++++++++++++++++++ + modules/amd_parse.y | 49 ++++++- + modules/amd_tok.l | 73 ++++++++++ + modules/parse_amd.c | 348 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 586 insertions(+), 13 deletions(-) + +diff --git a/include/parse_subs.h b/include/parse_subs.h +index a416c59..43da182 100644 +--- a/include/parse_subs.h ++++ b/include/parse_subs.h +@@ -111,6 +111,8 @@ struct map_type_info { + }; + + unsigned int get_proximity(struct sockaddr *); ++unsigned int get_network_proximity(const char *); ++unsigned int in_network(char *); + const char *skipspace(const char *); + int check_colon(const char *); + int chunklen(const char *, int); +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index f485a4c..de5319f 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -19,9 +19,13 @@ + #include + #include + #include ++#include + #include + #include + #include ++#include ++#include ++ + #include "automount.h" + + #define MAX_OPTIONS_LEN 256 +@@ -370,6 +374,129 @@ unsigned int get_proximity(struct sockaddr *host_addr) + return PROXIMITY_OTHER; + } + ++static char *inet_fill_net(const char *net_num, char *net) ++{ ++ char *np; ++ unsigned int dots = 3; ++ ++ if (strlen(net_num) > INET_ADDRSTRLEN) ++ return NULL; ++ ++ if (!isdigit(*net_num)) ++ return NULL; ++ ++ *net = '\0'; ++ strcpy(net, net_num); ++ ++ np = net; ++ while (*np++) { ++ if (*np == '.') { ++ np++; ++ dots--; ++ if (!*np && dots) ++ strcat(net, "0"); ++ continue; ++ } ++ ++ if ((*np && !isdigit(*np)) || dots < 0) { ++ *net = '\0'; ++ return NULL; ++ } ++ } ++ ++ while (dots--) ++ strcat(net, ".0"); ++ ++ return net; ++} ++ ++static char *get_network_number(const char *network) ++{ ++ struct netent *netent; ++ char cnet[MAX_NETWORK_LEN]; ++ uint32_t h_net; ++ size_t len; ++ ++ len = strlen(network) + 1; ++ if (len > MAX_NETWORK_LEN) ++ return NULL; ++ ++ netent = getnetbyname(network); ++ if (!netent) ++ return NULL; ++ h_net = ntohl(netent->n_net); ++ ++ if (!inet_ntop(AF_INET, &h_net, cnet, INET_ADDRSTRLEN)) ++ return NULL; ++ ++ return strdup(cnet); ++} ++ ++unsigned int get_network_proximity(const char *name) ++{ ++ struct addrinfo hints; ++ struct addrinfo *ni, *this; ++ char name_or_num[NI_MAXHOST]; ++ unsigned int proximity; ++ char *net; ++ int ret; ++ ++ if (!name) ++ return PROXIMITY_ERROR; ++ ++ net = get_network_number(name); ++ if (net) ++ strcpy(name_or_num, net); ++ else { ++ char this[NI_MAXHOST]; ++ char *mask; ++ ++ strcpy(this, name); ++ if ((mask = strchr(this, '/'))) ++ *mask++ = '\0'; ++ if (!strchr(this, '.')) ++ strcpy(name_or_num, this); ++ else { ++ char buf[NI_MAXHOST], *new; ++ new = inet_fill_net(this, buf); ++ if (!new) ++ return PROXIMITY_ERROR; ++ strcpy(name_or_num, new); ++ } ++ } ++ ++ memset(&hints, 0, sizeof(struct addrinfo)); ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_DGRAM; ++ ++ ret = getaddrinfo(name_or_num, NULL, &hints, &ni); ++ if (ret) { ++ logerr("getaddrinfo: %s", gai_strerror(ret)); ++ return PROXIMITY_ERROR; ++ } ++ ++ proximity = PROXIMITY_OTHER; ++ ++ this = ni; ++ while (this) { ++ unsigned int prx = get_proximity(this->ai_addr); ++ if (prx < proximity) ++ proximity = prx; ++ this = this->ai_next; ++ } ++ ++ return proximity; ++} ++ ++unsigned int in_network(char *network) ++{ ++ unsigned int proximity = get_network_proximity(network); ++ if (proximity == PROXIMITY_ERROR || ++ proximity > PROXIMITY_SUBNET) ++ return 0; ++ return 1; ++} ++ + /* + * Skip whitespace in a string; if we hit a #, consider the rest of the + * entry a comment. +diff --git a/modules/amd_parse.y b/modules/amd_parse.y +index 33106a1..71fd569 100644 +--- a/modules/amd_parse.y ++++ b/modules/amd_parse.y +@@ -92,6 +92,9 @@ static int amd_fprintf(FILE *, char *, ...); + %token NOT_EQUAL + %token COMMA + %token OPTION_ASSIGN ++%token LBRACKET ++%token RBRACKET ++%token NOT + %token NILL + + %token MAP_OPTION +@@ -102,6 +105,7 @@ static int amd_fprintf(FILE *, char *, ...); + %token MNT_OPTION + %token SELECTOR + %token SELECTOR_VALUE ++%token SEL_ARG_VALUE + %token OPTION + %token MACRO + %token OTHER +@@ -187,18 +191,46 @@ selector_or_option: selection + + selection: SELECTOR IS_EQUAL SELECTOR_VALUE + { +- if (!make_selector($1, $3, NULL, SEL_TYPE_EQUAL)) { ++ if (!make_selector($1, $3, NULL, SEL_COMP_EQUAL)) { + amd_notify($1); + YYABORT; + } + } + | SELECTOR NOT_EQUAL SELECTOR_VALUE + { +- if (!make_selector($1, $3, NULL, SEL_TYPE_NOTEQUAL)) { ++ if (!make_selector($1, $3, NULL, SEL_COMP_NOTEQUAL)) { + amd_notify($1); + YYABORT; + } + } ++ | SELECTOR LBRACKET SEL_ARG_VALUE RBRACKET ++ { ++ if (!make_selector($1, $3, NULL, SEL_COMP_NONE)) { ++ amd_notify($1); ++ YYABORT; ++ } ++ } ++ | SELECTOR LBRACKET SEL_ARG_VALUE COMMA SEL_ARG_VALUE RBRACKET ++ { ++ if (!make_selector($1, $3, $5, SEL_COMP_NONE)) { ++ amd_notify($1); ++ YYABORT; ++ } ++ } ++ | NOT SELECTOR LBRACKET SEL_ARG_VALUE RBRACKET ++ { ++ if (!make_selector($2, $4, NULL, SEL_COMP_NOT)) { ++ amd_notify($2); ++ YYABORT; ++ } ++ } ++ | NOT SELECTOR LBRACKET SEL_ARG_VALUE COMMA SEL_ARG_VALUE RBRACKET ++ { ++ if (!make_selector($2, $4, $6, SEL_COMP_NOT)) { ++ amd_notify($2); ++ YYABORT; ++ } ++ } + ; + + option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE +@@ -388,9 +420,6 @@ static int make_selector(char *name, + if (!sel_lookup(name)) + return 0; + +- if (!value1) +- return 0; +- + s = get_selector(name); + if (!s) + return 0; +@@ -401,9 +430,13 @@ static int make_selector(char *name, + goto error; + s->comp.value = tmp; + } else if (s->sel->flags & SEL_FLAG_FUNC1) { +- char *tmp = amd_strdup(value1); +- if (!tmp) +- goto error; ++ if (!value1) ++ tmp = NULL; ++ else { ++ char *tmp = amd_strdup(value1); ++ if (!tmp) ++ goto error; ++ } + s->func.arg1 = tmp; + } else if (s->sel->flags & SEL_FLAG_FUNC2) { + char *tmp = amd_strdup(value1); +diff --git a/modules/amd_tok.l b/modules/amd_tok.l +index afa3a87..cea9ea5 100644 +--- a/modules/amd_tok.l ++++ b/modules/amd_tok.l +@@ -70,22 +70,29 @@ int amd_yyinput(char *, int); + + %option nounput + +-%x MAPOPTVAL FSOPTVAL MNTOPTVAL SELOPTVAL ++%x MAPOPTVAL FSOPTVAL MNTOPTVAL SELOPTVAL SELARGVAL + + NL \r?\n + OPTWS [[:blank:]]* + OTHR [^!;:=/|\- \t\r\n#]* + ++V4NUM ([01]?[0-9][0-9]?|2[0-4][0-9]|25[0-5]) ++ + MACRO (\$\{([[:alpha:]_/]([[:alnum:]_\-])([[:alnum:]_\-/])*)\}) + QSTR (\"([^"\\]|\\.)*\") + OSTR ([[:alpha:]]([[:alnum:]_\-])+) + FSTR ([[:alnum:]_/\.]([[:alnum:]_\-/\.]|(\\.))*) + VSTR (([[:alnum:]_\-\:/\.])+) + SSTR ([[:alpha:]]([[:alnum:]\-\.])+) ++IP4ADDR ({V4NUM}\.((({V4NUM}\.){0,2}){V4NUM}?)) ++V4MASK ({IP4ADDR}|([1-2][0-9]|3[0-2]|[1-9])) ++IP6ADDR ((([A-Fa-f0-9]{1,4}\:\:?){1,7}[A-Fa-f0-9]{1,4})|(\:\:1)) ++V6MASK (12[0-8]|1[0-1][0-9]|[1-9][0-9]|[1-9]) + + FOPT (({QSTR}|{FSTR}|{MACRO})+) + OPTS ({OSTR}(=({VSTR}|{QSTR}|{MACRO})+)?) + SOPT (({SSTR}|{QSTR}|{MACRO})+) ++NOPT ({SSTR}|(({IP4ADDR}(\/{V4MASK})?)|({IP6ADDR}(\/{V6MASK})?))) + + MAPOPT (fs|type|maptype|pref|sublink|delay) + MNTOPT (opts|addopts|remopts) +@@ -94,13 +101,16 @@ MAPTYPE (file|nis|nisplus|ldap|hesiod|exec|ndbm|passwd|union) + FSTYPE (auto|nfs|link|host|nfsx|ufs|xfs|efs) + + OSSEL (arch|karch|os|osver|full_os|vendor) +-HSTSEL (host|hostd|xhost|domain|byte|cluster) +-NETSEL (netnumber|network|wire|netgrp|netgrpd|in_network) ++HSTSEL (host|hostd|domain|byte|cluster) ++NETSEL (netnumber|network|wire|in_network) + USRSEL (uid|gid) + MAPSEL (key|map|path) +-OTRSEL (exists|autodir|dollar) ++OTRSEL (autodir|dollar) + BOLSEL (true|false) +-SELOPT ({OSSEL}|{HSTSEL}|{NETSEL}|{BOLSEL}|{USRSEL}|{MAPSEL}|{OTRSEL}) ++ ++SELOPT ({OSSEL}|{HSTSEL}|{USRSEL}|{MAPSEL}|{OTRSEL}) ++SEL1ARG (xhost|exists|{NETSEL}|{BOLSEL}) ++SEL2ARG (netgrp|netgrpd) + + CUTSEP (\|\||\/) + +@@ -135,6 +145,20 @@ CUTSEP (\|\||\/) + return SELECTOR; + } + ++ "!"/({SEL1ARG}|{SEL2ARG}) { return NOT; } ++ ++ {SEL1ARG} { ++ BEGIN(SELARGVAL); ++ strcpy(amd_lval.strtype, amd_text); ++ return SELECTOR; ++ } ++ ++ {SEL2ARG} { ++ BEGIN(SELARGVAL); ++ strcpy(amd_lval.strtype, amd_text); ++ return SELECTOR; ++ } ++ + {CUTSEP} { return CUT; } + + "-" { return HYPHEN; } +@@ -263,6 +287,45 @@ CUTSEP (\|\||\/) + } + } + ++{ ++ {NL} | ++ \x00 { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ ++ ";" { ++ BEGIN(INITIAL); ++ return SEPERATOR; ++ } ++ ++ "(" { return LBRACKET; } ++ ++ {NOPT} { ++ strcpy(amd_lval.strtype, amd_text); ++ return SEL_ARG_VALUE; ++ } ++ ++ {SOPT}/"," { ++ strcpy(amd_lval.strtype, amd_text); ++ return SEL_ARG_VALUE; ++ } ++ ++ "," { return COMMA; } ++ ++ {SOPT} { ++ strcpy(amd_lval.strtype, amd_text); ++ return SEL_ARG_VALUE; ++ } ++ ++ {FOPT} { ++ strcpy(amd_lval.strtype, amd_text); ++ return SEL_ARG_VALUE; ++ } ++ ++ ")" { return RBRACKET; } ++} ++ + %% + + #include "automount.h" +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 35cc5dc..d9c7d9b 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -223,6 +223,307 @@ static struct substvar *add_lookup_vars(struct autofs_point *ap, + return list; + } + ++static int match_my_name(unsigned int logopt, const char *name, struct substvar *sv) ++{ ++ struct addrinfo hints, *cni, *ni, *haddr; ++ char host[NI_MAXHOST + 1], numeric[NI_MAXHOST + 1]; ++ const struct substvar *v; ++ int rv = 0, ret; ++ ++ v = macro_findvar(sv, "host", 4); ++ if (v) { ++ if (!strcmp(v->val, name)) ++ return 1; ++ } ++ ++ /* Check if comparison value is an alias */ ++ ++ memset(&hints, 0, sizeof(hints)); ++ hints.ai_flags = AI_CANONNAME; ++ hints.ai_family = AF_UNSPEC; ++ hints.ai_socktype = SOCK_DGRAM; ++ ++ /* Get host canonical name */ ++ ret = getaddrinfo(v->val, NULL, &hints, &cni); ++ if (ret) { ++ error(logopt, ++ "hostname lookup failed: %s\n", gai_strerror(ret)); ++ goto out; ++ } ++ ++ hints.ai_flags = 0; ++ ++ /* Resolve comparison name to its names and compare */ ++ ret = getaddrinfo(name, NULL, &hints, &ni); ++ if (ret) { ++ error(logopt, ++ "hostname lookup failed: %s\n", gai_strerror(ret)); ++ freeaddrinfo(cni); ++ goto out; ++ } ++ ++ haddr = ni; ++ while (haddr) { ++ /* Translate the host address into a numeric string form */ ++ ret = getnameinfo(haddr->ai_addr, haddr->ai_addrlen, ++ numeric, sizeof(numeric), NULL, 0, ++ NI_NUMERICHOST); ++ if (ret) { ++ error(logopt, ++ "host address info lookup failed: %s\n", ++ gai_strerror(ret)); ++ freeaddrinfo(cni); ++ goto next; ++ } ++ ++ /* Try to resolve back again to get the canonical name */ ++ ret = getnameinfo(haddr->ai_addr, haddr->ai_addrlen, ++ host, NI_MAXHOST, NULL, 0, 0); ++ if (ret) { ++ error(logopt, ++ "host address info lookup failed: %s\n", ++ gai_strerror(ret)); ++ freeaddrinfo(cni); ++ goto next; ++ } ++ ++ if (!strcmp(host, cni->ai_canonname)) { ++ rv = 1; ++ break; ++ } ++next: ++ haddr = haddr->ai_next; ++ } ++ freeaddrinfo(ni); ++ freeaddrinfo(cni); ++out: ++ return rv; ++} ++ ++static int eval_selector(unsigned int logopt, ++ struct amd_entry *this, struct substvar *sv) ++{ ++ struct selector *s = this->selector; ++ const struct substvar *v; ++ unsigned int s_type; ++ unsigned int v_type; ++ struct stat st; ++ char *host; ++ int res, val, ret = 0; ++ ++ s_type = s->sel->flags & SEL_FLAGS_TYPE_MASK; ++ ++ switch (s_type) { ++ case SEL_FLAG_MACRO: ++ v = macro_findvar(sv, s->sel->name, strlen(s->sel->name)); ++ if (!v) { ++ error(logopt, "failed to get selector %s", s->sel->name); ++ return 0; ++ } ++ ++ v_type = s->sel->flags & SEL_FLAGS_VALUE_MASK; ++ ++ switch (v_type) { ++ case SEL_FLAG_STR: ++ res = strcmp(v->val, s->comp.value); ++ if (s->compare & SEL_COMP_EQUAL && !res) { ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s) == %s", ++ v->def, v->val, s->comp.value); ++ ret = 1; ++ break; ++ } else if (s->compare & SEL_COMP_NOTEQUAL && res) { ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s) != %s", ++ v->def, v->val, s->comp.value); ++ ret = 1; ++ break; ++ } ++ ++ debug(logopt, MODPREFIX ++ "did not match selector %s(%s) %s %s", ++ v->def, v->val, ++ (s->compare & SEL_COMP_EQUAL ? "==" : "!="), ++ s->comp.value); ++ break; ++ ++ case SEL_FLAG_NUM: ++ res = atoi(v->val); ++ val = atoi(s->comp.value); ++ if (s->compare & SEL_COMP_EQUAL && res == val) { ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s) equal to %s", ++ v->def, v->val, s->comp.value); ++ ret = 1; ++ break; ++ } else if (s->compare & SEL_COMP_NOTEQUAL && res != val) { ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s) not equal to %s", ++ v->def, v->val, s->comp.value); ++ ret = 1; ++ break; ++ } ++ ++ debug(logopt, MODPREFIX ++ "did not match selector %s(%s) %s %s", ++ v->def, v->val, ++ (s->compare & SEL_COMP_EQUAL ? "==" : "!="), ++ s->comp.value); ++ break; ++ ++ default: ++ break; ++ } ++ break; ++ ++ case SEL_FLAG_FUNC1: ++ if (s->sel->selector != SEL_TRUE && ++ s->sel->selector != SEL_FALSE && ++ !s->func.arg1) { ++ error(logopt, MODPREFIX ++ "expected argument missing for selector %s", ++ s->sel->name); ++ break; ++ } ++ ++ switch (s->sel->selector) { ++ case SEL_TRUE: ++ ret = 1; ++ if (s->compare == SEL_COMP_NOT) ++ ret = !ret; ++ if (ret) ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ else ++ debug(logopt, MODPREFIX ++ "did not match selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ break; ++ ++ case SEL_FALSE: ++ if (s->compare == SEL_COMP_NOT) ++ ret = !ret; ++ if (ret) ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ else ++ debug(logopt, MODPREFIX ++ "did not match selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ break; ++ ++ case SEL_XHOST: ++ ret = match_my_name(logopt, s->func.arg1, sv); ++ if (s->compare == SEL_COMP_NOT) ++ ret = !ret; ++ if (ret) ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s) to host name", ++ s->sel->name, s->func.arg1); ++ else ++ debug(logopt, MODPREFIX ++ "did not match selector %s(%s) to host name", ++ s->sel->name, s->func.arg1); ++ break; ++ ++ case SEL_EXISTS: ++ /* Sould be OK to fail on any error here */ ++ ret = !lstat(s->func.arg1, &st); ++ if (s->compare == SEL_COMP_NOT) ++ ret = !ret; ++ if (ret) ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ else ++ debug(logopt, MODPREFIX ++ "did not match selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ break; ++ ++ case SEL_IN_NETWORK: ++ ret = in_network(s->func.arg1); ++ if (s->compare == SEL_COMP_NOT) ++ ret = !ret; ++ if (ret) ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ else ++ debug(logopt, MODPREFIX ++ "did not match selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ break; ++ ++ default: ++ break; ++ } ++ break; ++ ++ case SEL_FLAG_FUNC2: ++ if (!s->func.arg1) { ++ error(logopt, MODPREFIX ++ "expected argument missing for selector %s", ++ s->sel->name); ++ break; ++ } ++ ++ switch (s->sel->selector) { ++ case SEL_NETGRP: ++ case SEL_NETGRPD: ++ if (s->func.arg2) ++ host = s->func.arg2; ++ else { ++ if (s->sel->selector == SEL_NETGRP) ++ v = macro_findvar(sv, "host", 4); ++ else ++ v = macro_findvar(sv, "hostd", 5); ++ if (!v || !*v->val) { ++ error(logopt, ++ "failed to get value of ${host}"); ++ break; ++ } ++ host = v->val; ++ } ++ ret = innetgr(s->func.arg1, host, NULL, NULL); ++ if (s->compare == SEL_COMP_NOT) ++ ret = !ret; ++ if (ret) { ++ if (!s->func.arg2) ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ else ++ debug(logopt, MODPREFIX ++ "matched selector %s(%s,%s)", ++ s->sel->name, s->func.arg1, ++ s->func.arg2); ++ } else { ++ if (!s->func.arg2) ++ debug(logopt, MODPREFIX ++ "did not match selector %s(%s)", ++ s->sel->name, s->func.arg1); ++ else ++ debug(logopt, MODPREFIX ++ "did not match selector %s(%s,%s)", ++ s->sel->name, s->func.arg1, s->func.arg2); ++ } ++ break; ++ ++ default: ++ break; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ return ret; ++} ++ + static void update_with_defaults(struct amd_entry *defaults, + struct amd_entry *entry, + struct substvar *sv) +@@ -884,6 +1185,33 @@ static void update_prefix(struct autofs_point *ap, + return; + } + ++static int match_selectors(unsigned int logopt, ++ struct amd_entry *entry, struct substvar *sv) ++{ ++ struct selector *s = entry->selector; ++ int ret; ++ ++ /* No selectors, always match */ ++ if (!s) { ++ debug(logopt, "no selectors found in location"); ++ return 1; ++ } ++ ++ ret = 0; ++ ++ /* All selectors must match */ ++ while (s) { ++ ret = eval_selector(logopt, entry, sv); ++ if (!ret) ++ break; ++ s = s->next; ++ } ++ if (!s) ++ ret = 1; ++ ++ return ret; ++} ++ + static struct amd_entry *dup_defaults_entry(struct amd_entry *defaults) + { + struct amd_entry *entry; +@@ -1008,6 +1336,23 @@ static struct amd_entry *select_default_entry(struct autofs_point *ap, + free_amd_entry(this); + continue; + } ++ ++ /* ++ * This probably should be a fail since we expect ++ * selectors to pick the default entry. ++ */ ++ if (!this->selector) ++ continue; ++ ++ if (match_selectors(ap->logopt, this, sv)) { ++ if (entry_default) { ++ /*update_with_defaults(entry_default, this, sv);*/ ++ free_amd_entry(entry_default); ++ } ++ list_del_init(&this->list); ++ defaults_entry = this; ++ break; ++ } + } + + /* Not strickly amd semantics but ... */ +@@ -1195,6 +1540,9 @@ int parse_mount(struct autofs_point *ap, const char *name, + continue; + } + ++ if (!match_selectors(ap->logopt, this, sv)) ++ continue; ++ + update_with_defaults(cur_defaults, this, sv); + sv = expand_entry(ap, this, flags, sv); + sv = merge_entry_options(ap, this, sv); diff --git a/SOURCES/autofs-5.0.9-amd-lookup-add-ufs-fs-type.patch b/SOURCES/autofs-5.0.9-amd-lookup-add-ufs-fs-type.patch new file mode 100644 index 0000000..5475e0f --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-add-ufs-fs-type.patch @@ -0,0 +1,227 @@ +autofs-5.0.9 - amd lookup add ufs fs type + +From: Ian Kent + +Completely overlooked mount type ufs, which should be the +system default filesystem. + +There's no simple way to determine what the system default +filesystem is and am-utils needs to be continually updated +to do this and can easily get it wrong anyway. + +A better approach is to use a configuration entry and set +it to be what it usually is in am-utils, allowing the user +to set it to what they would like it to be. +--- + include/defaults.h | 2 ++ + include/parse_amd.h | 9 +++++---- + lib/defaults.c | 10 ++++++++++ + man/autofs.conf.5.in | 9 +++++++++ + modules/amd_parse.y | 3 +++ + modules/amd_tok.l | 2 +- + modules/parse_amd.c | 21 +++++++++++++++++++++ + redhat/autofs.conf.default.in | 9 +++++++++ + samples/autofs.conf.default.in | 9 +++++++++ + 9 files changed, 69 insertions(+), 5 deletions(-) + +diff --git a/include/defaults.h b/include/defaults.h +index 033acaf..6ca20d0 100644 +--- a/include/defaults.h ++++ b/include/defaults.h +@@ -130,6 +130,7 @@ + #define DEFAULT_AMD_UMOUNT_ON_EXIT "yes" + #define DEFAULT_AMD_USE_TCPWRAPPERS DEFAULT_AMD_NULL_VALUE + #define DEFAULT_AMD_VENDOR "unknown" ++#define DEFAULT_AMD_LINUX_UFS_MOUNT_TYPE "ext3" + + #ifdef WITH_LDAP + struct ldap_schema; +@@ -184,6 +185,7 @@ char *conf_amd_get_map_defaults(const char *); + char *conf_amd_get_map_type(const char *); + char *conf_amd_get_search_path(const char *); + unsigned int conf_amd_get_dismount_interval(const char *); ++char *conf_amd_get_linux_ufs_mount_type(void); + unsigned long conf_amd_get_flags(const char *); + + #endif +diff --git a/include/parse_amd.h b/include/parse_amd.h +index 401aadb..313edd5 100644 +--- a/include/parse_amd.h ++++ b/include/parse_amd.h +@@ -25,10 +25,11 @@ + #define AMD_MOUNT_TYPE_LINKX 0x00000040 + #define AMD_MOUNT_TYPE_LOFS 0x00000080 + #define AMD_MOUNT_TYPE_EXT 0x00000100 +-#define AMD_MOUNT_TYPE_XFS 0x00000200 +-#define AMD_MOUNT_TYPE_JFS 0x00000400 +-#define AMD_MOUNT_TYPE_CACHEFS 0x00000800 +-#define AMD_MOUNT_TYPE_CDFS 0x00001000 ++#define AMD_MOUNT_TYPE_UFS 0x00000200 ++#define AMD_MOUNT_TYPE_XFS 0x00000400 ++#define AMD_MOUNT_TYPE_JFS 0x00000800 ++#define AMD_MOUNT_TYPE_CACHEFS 0x00001000 ++#define AMD_MOUNT_TYPE_CDFS 0x00002000 + #define AMD_MOUNT_TYPE_MASK 0x0000ffff + + #define AMD_ENTRY_CUT 0x00010000 +diff --git a/lib/defaults.c b/lib/defaults.c +index bdaba67..3fa2216 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -136,6 +136,7 @@ + #define NAME_AMD_UMOUNT_ON_EXIT "unmount_on_exit" + #define NAME_AMD_USE_TCPWRAPPERS "use_tcpwrappers" + #define NAME_AMD_VENDOR "vendor" ++#define NAME_AMD_LINUX_UFS_MOUNT_TYPE "linux_ufs_mount_type" + + /* Status returns */ + #define CFG_OK 0x0000 +@@ -543,6 +544,10 @@ static int conf_load_amd_defaults(void) + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_AMD_LINUX_UFS_MOUNT_TYPE, ++ DEFAULT_AMD_LINUX_UFS_MOUNT_TYPE, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; + return 1; + + error: +@@ -1706,6 +1711,11 @@ unsigned int conf_amd_get_dismount_interval(const char *section) + return (unsigned int) tmp; + } + ++char *conf_amd_get_linux_ufs_mount_type(void) ++{ ++ return conf_get_string(amd_gbl_sec, NAME_AMD_LINUX_UFS_MOUNT_TYPE); ++} ++ + unsigned long conf_amd_get_flags(const char *section) + { + const char *amd = amd_gbl_sec; +diff --git a/man/autofs.conf.5.in b/man/autofs.conf.5.in +index f25a918..c959b52 100644 +--- a/man/autofs.conf.5.in ++++ b/man/autofs.conf.5.in +@@ -390,6 +390,15 @@ LDAP URIs. + .B hesiod_base + .br + Sets the base name used for hesiod map sources. ++.TP ++.B linux_ufs_mount_type ++.br ++This is an aditional configuration option for the autofs amd format ++parser implementation. ++ ++There's no simple way to determine what the system default filesystem ++is and am-utils needs to be continually updated to do this and can ++easily get it wrong ayway. So allow it to be set in the configuration. + .SH EXAMPLE + .sp + .RS +.2i +diff --git a/modules/amd_parse.y b/modules/amd_parse.y +index 87e3309..8174fb2 100644 +--- a/modules/amd_parse.y ++++ b/modules/amd_parse.y +@@ -269,6 +269,9 @@ option_assignment: MAP_OPTION OPTION_ASSIGN FS_TYPE + !strcmp($3, "ext4")) { + entry.flags |= AMD_MOUNT_TYPE_EXT; + entry.type = amd_strdup($3); ++ } else if (!strcmp($3, "ufs")) { ++ entry.flags |= AMD_MOUNT_TYPE_UFS; ++ entry.type = conf_amd_get_linux_ufs_mount_type(); + } else if (!strcmp($3, "cdfs")) { + entry.flags |= AMD_MOUNT_TYPE_CDFS; + entry.type = amd_strdup("iso9660"); +diff --git a/modules/amd_tok.l b/modules/amd_tok.l +index 10b1963..618bc91 100644 +--- a/modules/amd_tok.l ++++ b/modules/amd_tok.l +@@ -99,7 +99,7 @@ MNTOPT (opts|addopts|remopts) + FSOPTS (rhost|rfs|dev|cachedir|mount|unmount|umount|delay) + CHEOPT (mapdefault|none|inc|re|regexp|all) + MAPTYPE (file|nis|nisplus|ldap|hesiod|exec|ndbm|passwd|union) +-FSTYPE_LOCAL (link|linkx|lofs|ext2|ext3|ext4|xfs|jfs|cdfs|cachefs) ++FSTYPE_LOCAL (link|linkx|lofs|ufs|ext2|ext3|ext4|xfs|jfs|cdfs|cachefs) + FSTYPE_NET (nfs|nfsx|nfsl|host) + FSTYPE (auto|program|direct|lustre|{FSTYPE_LOCAL}|{FSTYPE_NET}) + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 790f25e..0c708e6 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1245,6 +1245,22 @@ static unsigned int validate_generic_options(unsigned int logopt, + return 1; + } + ++static unsigned int validate_ufs_fstype(unsigned int logopt, ++ struct amd_entry *entry) ++{ ++ const char *type = (const char *) entry->type; ++ ++ if (strcmp(type, "ext") && strcmp(type, "ext2") && ++ strcmp(type, "ext3") && strcmp(type, "ext4") && ++ strcmp(type, "xfs") && strcmp(type, "jfs")) { ++ error(logopt, MODPREFIX ++ "%s: mount type %s not valid as ufs mount type on Linux", ++ type); ++ return 0; ++ } ++ return 1; ++} ++ + static unsigned int validate_host_options(unsigned int logopt, + struct amd_entry *entry) + { +@@ -1282,6 +1298,11 @@ static int amd_mount(struct autofs_point *ap, const char *name, + ret = do_generic_mount(ap, name, entry, entry->rfs, flags); + break; + ++ case AMD_MOUNT_TYPE_UFS: ++ if (!validate_ufs_fstype(ap->logopt, entry)) ++ return 1; ++ /* fall through to validate generic options */ ++ + case AMD_MOUNT_TYPE_EXT: + case AMD_MOUNT_TYPE_XFS: + case AMD_MOUNT_TYPE_CDFS: +diff --git a/redhat/autofs.conf.default.in b/redhat/autofs.conf.default.in +index 1fa951b..8ccd5d6 100644 +--- a/redhat/autofs.conf.default.in ++++ b/redhat/autofs.conf.default.in +@@ -306,6 +306,15 @@ mount_nfs_default_protocol = 4 + # + # hesiod_base - the base name used for hesiod map sources. + # ++# Additional configuration options added: ++# ++# linux_ufs_mount_type - set the default system filesystem type that's ++# used for mount type ufs. There's no simple way to determine ++# what the system default filesystem is and am-utils needs to ++# be continually updated to do this and can easily get it wrong ++# anyway. ++# ++# + # Define global options for the amd parser within autofs. + # + [ amd ] +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index 7a84566..934e411 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -305,6 +305,15 @@ browse_mode = no + # + # hesiod_base - the base name used for hesiod map sources. + # ++# Additional configuration options added: ++# ++# linux_ufs_mount_type - set the default system filesystem type that's ++# used for mount type ufs. There's no simple way to determine ++# what the system default filesystem is and am-utils needs to ++# be continually updated to do this and can easily get it wrong ++# anyway. ++# ++# + # Define global options for the amd parser within autofs. + # + [ amd ] diff --git a/SOURCES/autofs-5.0.9-amd-lookup-allow-exec-to-be-used-by-amd-maps-in-master-map.patch b/SOURCES/autofs-5.0.9-amd-lookup-allow-exec-to-be-used-by-amd-maps-in-master-map.patch new file mode 100644 index 0000000..f6979d4 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-allow-exec-to-be-used-by-amd-maps-in-master-map.patch @@ -0,0 +1,81 @@ +autofs-5.0.9 - amd lookup allow amd maps to use exec in master map + +From: Ian Kent + +Amd uses the keyword exec for program maps (as it has a program mount +type). Allow the use of the exec keyword to be used for executable +maps in amd format master map entries. So just allow the keyword exec +to be used as a synonym of program for both sun and amd format map +entries since exec isn't otherwise used in master map entries. +--- + lib/master_parse.y | 15 ++++++++++++--- + lib/master_tok.l | 2 +- + man/auto.master.5.in | 2 ++ + 3 files changed, 15 insertions(+), 4 deletions(-) + +diff --git a/lib/master_parse.y b/lib/master_parse.y +index 03aedf7..e31023d 100644 +--- a/lib/master_parse.y ++++ b/lib/master_parse.y +@@ -329,7 +329,10 @@ map: PATH + if ((tmp = strchr($1, ','))) + *tmp++ = '\0'; + +- type = master_strdup($1); ++ if (strcmp($1, "exec")) ++ type = master_strdup($1); ++ else ++ type = master_strdup("program"); + if (!type) { + master_error("memory allocation error"); + local_free_vars(); +@@ -360,7 +363,10 @@ map: PATH + if ((tmp = strchr($1, ','))) + *tmp++ = '\0'; + +- type = master_strdup($1); ++ if (strcmp($1, "exec")) ++ type = master_strdup($1); ++ else ++ type = master_strdup("program"); + if (!type) { + master_error("memory allocation error"); + local_free_vars(); +@@ -391,7 +397,10 @@ map: PATH + if ((tmp = strchr($1, ','))) + *tmp++ = '\0'; + +- type = master_strdup($1); ++ if (strcmp($1, "exec")) ++ type = master_strdup($1); ++ else ++ type = master_strdup("program"); + if (!type) { + master_error("memory allocation error"); + local_free_vars(); +diff --git a/lib/master_tok.l b/lib/master_tok.l +index d43c1dd..9ba53f6 100644 +--- a/lib/master_tok.l ++++ b/lib/master_tok.l +@@ -119,7 +119,7 @@ DNNAMESTR2 ([[:alnum:]_.\-]+) + INTMAP (-hosts|-null) + MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS})) + MULTISEP ([\-]{2}[[:blank:]]+) +-MTYPE ((file|program|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod|amd))?(:{OPTWS}|{WS})) ++MTYPE ((file|program|exec|sss|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod|amd))?(:{OPTWS}|{WS})) + + + OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index 2267550..83be83c 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -93,6 +93,8 @@ The map is a regular text file. + .B program + The map is an executable program, which is passed a key on the command + line and returns an entry (everything besides the key) on stdout if successful. ++Optinally, the keyword exec may be used as a synonym for program to avoid ++confusion with amd formated maps mount type program. + .TP + .B yp + The map is a NIS (YP) database. diff --git a/SOURCES/autofs-5.0.9-amd-lookup-check-for-required-options-for-mounts.patch b/SOURCES/autofs-5.0.9-amd-lookup-check-for-required-options-for-mounts.patch new file mode 100644 index 0000000..2c38f48 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-check-for-required-options-for-mounts.patch @@ -0,0 +1,173 @@ +autofs-5.0.9 - amd lookup check for required options for mounts + +From: Ian Kent + + +--- + modules/parse_amd.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 101 insertions(+), 2 deletions(-) + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 2056ed9..bc53b1d 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1070,7 +1070,7 @@ static int do_nfsl_mount(struct autofs_point *ap, const char *name, + + static int wait_for_expire(struct autofs_point *ap) + { +- int ret = 1; ++ int ret = 0; + + st_wait_task(ap, ST_EXPIRE, 0); + +@@ -1078,7 +1078,7 @@ static int wait_for_expire(struct autofs_point *ap) + if (ap->state != ST_SHUTDOWN && + ap->state != ST_SHUTDOWN_PENDING && + ap->state != ST_SHUTDOWN_FORCE) { +- ret = 0; ++ ret = 1; + } + st_mutex_unlock(); + +@@ -1181,6 +1181,88 @@ out: + return ret; + } + ++static unsigned int validate_auto_options(unsigned int logopt, ++ struct amd_entry *entry) ++{ ++ /* ++ * The amd manual implies all the mount type auto options ++ * are optional but I don't think there's much point if ++ * no map is given. ++ */ ++ if (!entry->fs) { ++ error(logopt, MODPREFIX ++ "%s: file system not given", entry->type); ++ return 0; ++ } ++ return 1; ++} ++ ++static unsigned int validate_link_options(unsigned int logopt, ++ struct amd_entry *entry) ++{ ++ /* fs is the destimation of the link */ ++ return validate_auto_options(logopt, entry); ++} ++ ++static unsigned int validate_nfs_options(unsigned int logopt, ++ struct amd_entry *entry) ++{ ++ /* ++ * Required option rhost will always have a value. ++ * It is set from ${host} if it is found to be NULL ++ * earlier in the parsing process. ++ */ ++ if (!entry->rfs) { ++ if (entry->fs) ++ entry->rfs = strdup(entry->fs); ++ if (!entry->rfs) { ++ error(logopt, MODPREFIX ++ "%s: remote file system not given", entry->type); ++ return 0; ++ } ++ } ++ return 1; ++} ++ ++static unsigned int validate_generic_options(unsigned int logopt, ++ unsigned long fstype, ++ struct amd_entry *entry) ++{ ++ if (fstype != AMD_MOUNT_TYPE_LOFS) { ++ if (!entry->dev) { ++ error(logopt, MODPREFIX ++ "%s: mount device not given", entry->type); ++ return 0; ++ } ++ } else { ++ if (!entry->rfs) { ++ /* ++ * Can't use entry->type as the mount type to reprot ++ * the error since entry->type == "bind" not "lofs". ++ */ ++ error(logopt, "lofs: mount device not given"); ++ return 0; ++ } ++ } ++ return 1; ++} ++ ++static unsigned int validate_host_options(unsigned int logopt, ++ struct amd_entry *entry) ++{ ++ /* ++ * Not really that useful since rhost is always non-null ++ * because it will have the the value of the host name if ++ * it isn't set in the map entry. ++ */ ++ if (!entry->rhost) { ++ error(logopt, MODPREFIX ++ "%s: remote host name not given", entry->type); ++ return 0; ++ } ++ return 1; ++} ++ + static int amd_mount(struct autofs_point *ap, const char *name, + struct amd_entry *entry, struct map_source *source, + struct substvar *sv, unsigned int flags, +@@ -1191,35 +1273,52 @@ static int amd_mount(struct autofs_point *ap, const char *name, + + switch (fstype) { + case AMD_MOUNT_TYPE_AUTO: ++ if (!validate_auto_options(ap->logopt, entry)) ++ return 1; + ret = do_auto_mount(ap, name, entry, flags); + break; + + case AMD_MOUNT_TYPE_LOFS: ++ if (!validate_generic_options(ap->logopt, fstype, entry)) ++ return 1; + ret = do_generic_mount(ap, name, entry, entry->rfs, flags); + break; + + case AMD_MOUNT_TYPE_EXT: + case AMD_MOUNT_TYPE_XFS: ++ if (!validate_generic_options(ap->logopt, fstype, entry)) ++ return 1; + ret = do_generic_mount(ap, name, entry, entry->dev, flags); + break; + + case AMD_MOUNT_TYPE_NFS: ++ if (!validate_nfs_options(ap->logopt, entry)) ++ return 1; + ret = do_nfs_mount(ap, name, entry, flags); + break; + + case AMD_MOUNT_TYPE_NFSL: ++ if (!validate_nfs_options(ap->logopt, entry) || ++ !validate_link_options(ap->logopt, entry)) ++ return 1; + ret = do_nfsl_mount(ap, name, entry, sv, flags); + break; + + case AMD_MOUNT_TYPE_LINK: ++ if (!validate_link_options(ap->logopt, entry)) ++ return 1; + ret = do_link_mount(ap, name, entry, flags); + break; + + case AMD_MOUNT_TYPE_LINKX: ++ if (!validate_link_options(ap->logopt, entry)) ++ return 1; + ret = do_linkx_mount(ap, name, entry, flags); + break; + + case AMD_MOUNT_TYPE_HOST: ++ if (!validate_host_options(ap->logopt, entry)) ++ return 1; + ret = do_host_mount(ap, name, entry, source, flags); + break; + diff --git a/SOURCES/autofs-5.0.9-amd-lookup-dont-umount-admin-mounted-external-mounts.patch b/SOURCES/autofs-5.0.9-amd-lookup-dont-umount-admin-mounted-external-mounts.patch new file mode 100644 index 0000000..3723747 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-dont-umount-admin-mounted-external-mounts.patch @@ -0,0 +1,112 @@ +autofs-5.0.9 - amd lookup dont umount admin mounted external mounts + +From: Ian Kent + +If an autofs doesn't mount an external mount then it shouldn't +umount it. +--- + include/mounts.h | 2 +- + lib/mounts.c | 7 +++++-- + modules/parse_amd.c | 8 ++++++-- + 3 files changed, 12 insertions(+), 5 deletions(-) + +diff --git a/include/mounts.h b/include/mounts.h +index 07a8c3b..17cae31 100644 +--- a/include/mounts.h ++++ b/include/mounts.h +@@ -101,7 +101,7 @@ unsigned int get_kver_major(void); + unsigned int get_kver_minor(void); + char *make_options_string(char *path, int kernel_pipefd, const char *extra); + char *make_mnt_name_string(char *path); +-int ext_mount_add(struct list_head *, const char *); ++int ext_mount_add(struct list_head *, const char *, unsigned int); + int ext_mount_remove(struct list_head *, const char *); + struct mnt_list *get_mnt_list(const char *table, const char *path, int include); + struct mnt_list *reverse_mnt_list(struct mnt_list *list); +diff --git a/lib/mounts.c b/lib/mounts.c +index d8357d0..c9e1237 100644 +--- a/lib/mounts.c ++++ b/lib/mounts.c +@@ -51,6 +51,7 @@ static const char kver_options_template[] = "fd=%d,pgrp=%u,minproto=3,maxproto= + + struct ext_mount { + char *mountpoint; ++ unsigned int umount; + struct list_head mount; + struct list_head mounts; + }; +@@ -619,7 +620,7 @@ static struct ext_mount *ext_mount_lookup(const char *mountpoint) + return NULL; + } + +-int ext_mount_add(struct list_head *entry, const char *path) ++int ext_mount_add(struct list_head *entry, const char *path, unsigned int umount) + { + struct ext_mount *em; + char *auto_dir; +@@ -661,6 +662,7 @@ int ext_mount_add(struct list_head *entry, const char *path) + ret = -1; + goto done; + } ++ em->umount = umount; + INIT_LIST_HEAD(&em->mount); + INIT_LIST_HEAD(&em->mounts); + +@@ -701,11 +703,12 @@ int ext_mount_remove(struct list_head *entry, const char *path) + goto done; + else { + list_del_init(&em->mount); ++ if (em->umount) ++ ret = 1; + if (list_empty(&em->mount)) { + free(em->mountpoint); + free(em); + } +- ret = 1; + } + done: + pthread_mutex_unlock(&ext_mount_hash_mutex); +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index fa0f75d..bc056a7 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -978,6 +978,7 @@ static int do_generic_mount(struct autofs_point *ap, const char *name, + struct amd_entry *entry, const char *target, + unsigned int flags) + { ++ unsigned int umount = 0; + int ret = 0; + + if (!entry->sublink) { +@@ -994,9 +995,10 @@ static int do_generic_mount(struct autofs_point *ap, const char *name, + target, entry->type, entry->opts); + if (ret) + goto out; ++ umount = 1; + } + /* We might be using an external mount */ +- ext_mount_add(&entry->ext_mount, entry->fs); ++ ext_mount_add(&entry->ext_mount, entry->fs, umount); + ret = do_link_mount(ap, name, entry, flags); + } + out: +@@ -1009,6 +1011,7 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name, + char target[PATH_MAX + 1]; + unsigned int proximity; + char *opts = entry->opts; ++ unsigned int umount = 0; + int ret = 0; + + strcpy(target, entry->rhost); +@@ -1030,9 +1033,10 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name, + mount_nfs->context); + if (ret) + goto out; ++ umount = 1; + } + /* We might be using an external mount */ +- ext_mount_add(&entry->ext_mount, entry->fs); ++ ext_mount_add(&entry->ext_mount, entry->fs, umount); + ret = do_link_mount(ap, name, entry, flags); + } + out: diff --git a/SOURCES/autofs-5.0.9-amd-lookup-fix-amd-entry-not-found-at-expire.patch b/SOURCES/autofs-5.0.9-amd-lookup-fix-amd-entry-not-found-at-expire.patch new file mode 100644 index 0000000..116a99b --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-fix-amd-entry-not-found-at-expire.patch @@ -0,0 +1,44 @@ +autofs-5.0.9 - fix amd entry not found at expire + +From: Ian Kent + +Due to the way amd matches keys in its map it's possible that +distinct key entries aren't present in the map. + +The indirect mount expire procedure needs to lookup cache entries +for offset mounts in order to get the control file handle needed +to send an expire check to them. + +So we need to make sure that when a distinct match isn't found +an expire check is still done. That's OK because the mounts in +the expire list are under the autofs directory so they should +be checked and the ap control file handle can be used for it. +--- + daemon/indirect.c | 12 +++++------- + 1 file changed, 5 insertions(+), 7 deletions(-) + +diff --git a/daemon/indirect.c b/daemon/indirect.c +index 6dfbd25..a04a624 100644 +--- a/daemon/indirect.c ++++ b/daemon/indirect.c +@@ -513,15 +513,13 @@ void *expire_proc_indirect(void *arg) + if (!me && ind_key) + me = lookup_source_mapent(ap, ind_key, LKP_NORMAL); + pthread_cleanup_pop(1); +- if (!me) +- continue; + +- if (*me->key == '/') { +- ioctlfd = me->ioctlfd; +- } else { +- ioctlfd = ap->ioctlfd; ++ ioctlfd = ap->ioctlfd; ++ if (me) { ++ if (*me->key == '/') ++ ioctlfd = me->ioctlfd; ++ cache_unlock(me->mc); + } +- cache_unlock(me->mc); + + debug(ap->logopt, "expire %s", next->path); + diff --git a/SOURCES/autofs-5.0.9-amd-lookup-fix-autofs_use_lofs-value-in-config.patch b/SOURCES/autofs-5.0.9-amd-lookup-fix-autofs_use_lofs-value-in-config.patch new file mode 100644 index 0000000..30827b4 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-fix-autofs_use_lofs-value-in-config.patch @@ -0,0 +1,37 @@ +autofs-5.0.9 - amd lookup fix autofs_use_lofs value in config + +From: Ian Kent + +The commented out setting in autofs.conf does not reflect its default +value. +--- + redhat/autofs.conf.default.in | 2 +- + samples/autofs.conf.default.in | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/redhat/autofs.conf.default.in b/redhat/autofs.conf.default.in +index 8b04617..1fa951b 100644 +--- a/redhat/autofs.conf.default.in ++++ b/redhat/autofs.conf.default.in +@@ -325,7 +325,7 @@ dismount_interval = 300 + # appears to work reasonably well most of the time without the + # update). + # +-# autofs_use_lofs = no ++# autofs_use_lofs = yes + # + # Several configuration options can be set per mount point. + # In particulr map_type, map_name, map_defaults, search_path, +diff --git a/samples/autofs.conf.default.in b/samples/autofs.conf.default.in +index d0a2002..7a84566 100644 +--- a/samples/autofs.conf.default.in ++++ b/samples/autofs.conf.default.in +@@ -324,7 +324,7 @@ dismount_interval = 300 + # appears to work reasonably well most of the time without the + # update). + # +-# autofs_use_lofs = no ++# autofs_use_lofs = yes + # + # Several configuration options can be set per mount point. + # In particulr map_type, map_name, map_defaults, search_path, diff --git a/SOURCES/autofs-5.0.9-amd-lookup-fix-expire-of-amd-nfs-mounts.patch b/SOURCES/autofs-5.0.9-amd-lookup-fix-expire-of-amd-nfs-mounts.patch new file mode 100644 index 0000000..ad794c3 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-fix-expire-of-amd-nfs-mounts.patch @@ -0,0 +1,67 @@ +autofs-5.0.9 - amd lookup fix expire of amd nfs mounts + +From: Ian Kent + +Becuase of the way map entries are matched for amd maps there +might not be an entry in the map entry cache for mounts. This +was causing mounts to not expire. +--- + daemon/automount.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/daemon/automount.c b/daemon/automount.c +index 0ba3580..9d9ba7b 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -462,7 +462,7 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + { + struct mapent_cache *mc; + struct mapent *me; +- unsigned int is_mm_root; ++ unsigned int is_mm_root = 0; + int left; + + me = lookup_source_mapent(ap, path, LKP_DISTINCT); +@@ -474,22 +474,22 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + ind_key++; + + me = lookup_source_mapent(ap, ind_key, LKP_NORMAL); +- if (!me) +- return 0; + } + +- mc = me->mc; +- is_mm_root = (me->multi == me); ++ if (me) { ++ mc = me->mc; ++ is_mm_root = (me->multi == me); ++ } + + left = 0; + +- pthread_cleanup_push(cache_lock_cleanup, mc); +- +- if (me->multi) { ++ if (me && me->multi) { + char root[PATH_MAX]; + char *base; + int cur_state; + ++ pthread_cleanup_push(cache_lock_cleanup, mc); ++ + if (!strchr(me->multi->key, '/')) + /* Indirect multi-mount root */ + /* sprintf okay - if it's mounted, it's +@@ -516,9 +516,11 @@ static int umount_subtree_mounts(struct autofs_point *ap, const char *path, unsi + (ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD)) + cache_pop_mapent(me); + pthread_setcancelstate(cur_state, NULL); ++ pthread_cleanup_pop(0); + } + +- pthread_cleanup_pop(1); ++ if (me) ++ cache_unlock(mc); + + if (left || is_autofs_fs) + return left; diff --git a/SOURCES/autofs-5.0.9-amd-lookup-fix-expire-of-external-mounts.patch b/SOURCES/autofs-5.0.9-amd-lookup-fix-expire-of-external-mounts.patch new file mode 100644 index 0000000..5b3af25 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-fix-expire-of-external-mounts.patch @@ -0,0 +1,33 @@ +autofs-5.0.9 - amd lookup fix expire of external mounts + +From: Ian Kent + +When expiring a submount it's necessary to ensure that any triggers +that may have been mounted over the top of the submount by its parent +are umounted so umount_subtree_mounts() is called with the parent ap. + +But this can lead to an out of order umount. So far this hasn't been +a problem but if this happens when expiring an amd mount that refers +to an external mount the amd mount structure can't be found (since +we are looking in the parent ap) and subsequently the external mount +doesn't get checked and umounted. + +So restrict the call to umount_subtree_mounts() to umount only offset +mounts by passing is_autofs_fs as 1 always. +--- + daemon/automount.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/daemon/automount.c b/daemon/automount.c +index 9d9ba7b..a6a9321 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -628,7 +628,7 @@ int umount_multi(struct autofs_point *ap, const char *path, int incl) + * parent may have mounted over top of us. + */ + if (ap->submount) +- left += umount_subtree_mounts(ap->parent, path, is_autofs_fs); ++ left += umount_subtree_mounts(ap->parent, path, 1); + + left += umount_subtree_mounts(ap, path, is_autofs_fs); + diff --git a/SOURCES/autofs-5.0.9-amd-lookup-fix-host-mount-lookup.patch b/SOURCES/autofs-5.0.9-amd-lookup-fix-host-mount-lookup.patch new file mode 100644 index 0000000..9478552 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-fix-host-mount-lookup.patch @@ -0,0 +1,173 @@ +autofs-5.0.9 - amd lookup fix host mount lookup + +From: Ian Kent + +The amd host mount type is implemented by using the autofs internal +hosts map module and the autofs sun parser. + +When using the amd mount type host we need to avoid calling back +into the lookup module of the amd map (as an amd format lookup) +since the lookup keys for mounts in the tree might not match +correctly. In any case it's a call into a lookup module that +isn't needed. +--- + daemon/lookup.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ + modules/parse_amd.c | 34 +++++++++++++++++++++++---- + 2 files changed, 94 insertions(+), 5 deletions(-) + +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -795,6 +795,62 @@ int do_lookup_mount(struct autofs_point + return status; + } + ++static int lookup_amd_instance(struct autofs_point *ap, ++ struct map_source *map, ++ const char *name, int name_len) ++{ ++ struct map_source *instance; ++ struct amd_entry *entry; ++ const char *argv[2]; ++ const char **pargv = NULL; ++ int argc = 0; ++ struct mapent *me; ++ char *m_key; ++ ++ me = cache_lookup_distinct(map->mc, name); ++ if (!me || !me->multi) { ++ error(ap->logopt, "expected multi mount entry not found"); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 1); ++ if (!m_key) { ++ error(ap->logopt, "failed to allocate storage for search key"); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ strcpy(m_key, ap->path); ++ strcat(m_key, "/"); ++ strcat(m_key, me->multi->key); ++ entry = master_find_amdmount(ap, m_key); ++ if (!entry) { ++ error(ap->logopt, "expected amd mount entry not found"); ++ free(m_key); ++ return NSS_STATUS_UNKNOWN; ++ } ++ free(m_key); ++ ++ if (strcmp(entry->type, "host")) { ++ error(ap->logopt, "unexpected map type %s", entry->type); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ if (entry->opts) { ++ argv[0] = entry->opts; ++ argv[1] = NULL; ++ pargv = argv; ++ argc = 1; ++ } ++ ++ instance = master_find_source_instance(map, "hosts", "sun", argc, pargv); ++ if (!instance) { ++ error(ap->logopt, "expected hosts map instance not found"); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ return do_lookup_mount(ap, instance, name, name_len); ++} ++ + static int lookup_name_file_source_instance(struct autofs_point *ap, struct map_source *map, const char *name, int name_len) + { + struct map_source *instance; +@@ -804,6 +860,9 @@ static int lookup_name_file_source_insta + struct stat st; + char *type, *format; + ++ if (*name == '/' && map->flags & MAP_FLAG_FORMAT_AMD) ++ return lookup_amd_instance(ap, map, name, name_len); ++ + if (stat(map->argv[0], &st) == -1) { + debug(ap->logopt, "file map not found"); + return NSS_STATUS_NOTFOUND; +@@ -839,6 +898,9 @@ static int lookup_name_source_instance(s + const char *format; + time_t age = time(NULL); + ++ if (*name == '/' && map->flags & MAP_FLAG_FORMAT_AMD) ++ return lookup_amd_instance(ap, map, name, name_len); ++ + format = map->format; + + instance = master_find_source_instance(map, type, format, 0, NULL); +@@ -867,6 +929,9 @@ static int do_name_lookup_mount(struct a + return NSS_STATUS_UNKNOWN; + } + ++ if (*name == '/' && map->flags & MAP_FLAG_FORMAT_AMD) ++ return lookup_amd_instance(ap, map, name, name_len); ++ + /* + * This is only called when map->type != NULL. + * We only need to look for a map if source type is +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -1073,29 +1073,53 @@ static int do_host_mount(struct autofs_p + unsigned int flags) + { + struct lookup_mod *lookup; ++ struct map_source *instance; + struct mapent *me; + const char *argv[2]; ++ const char **pargv = NULL; ++ int argc = 0; + int ret = 1; + +- argv[0] = entry->opts; +- argv[1] = NULL; ++ if (entry->opts) { ++ argv[0] = entry->opts; ++ argv[1] = NULL; ++ pargv = argv; ++ argc = 1; ++ } + +- lookup = open_lookup("hosts", MODPREFIX, NULL, 1, argv); ++ instance_mutex_lock(); ++ lookup = open_lookup("hosts", MODPREFIX, NULL, argc, pargv); + if (!lookup) { + debug(ap->logopt, "open lookup module hosts failed"); ++ instance_mutex_unlock(); + goto out; + } + ++ instance = master_find_source_instance(source, "hosts", "sun", argc, pargv); ++ if (!instance) { ++ instance = master_add_source_instance(source, ++ "hosts", "sun", time(NULL), argc, pargv); ++ if (!instance) { ++ error(ap->logopt, MODPREFIX ++ "failed to create source instance for hosts map"); ++ instance_mutex_unlock(); ++ close_lookup(lookup); ++ goto out; ++ } ++ } ++ instance->lookup = lookup; ++ instance_mutex_unlock(); ++ ++ cache_writelock(source->mc); + me = cache_lookup_distinct(source->mc, name); + if (me) + cache_push_mapent(me, NULL); ++ cache_unlock(source->mc); + + master_source_current_wait(ap->entry); + ap->entry->current = source; + + ret = lookup->lookup_mount(ap, name, strlen(name), lookup->context); +- +- close_lookup(lookup); + out: + return ret; + } diff --git a/SOURCES/autofs-5.0.9-amd-lookup-fix-host-mount-naming.patch b/SOURCES/autofs-5.0.9-amd-lookup-fix-host-mount-naming.patch new file mode 100644 index 0000000..e38cd0c --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-fix-host-mount-naming.patch @@ -0,0 +1,213 @@ +autofs-5.0.9 - amd lookup fix host mount naming + +From: Ian Kent + +Currently the amd host mount type assumes the lookup name is +the host name for the host mount but amd uses ${rhost} for +this. + +This introduces the possibility of multiple concurrent mount +requests since constructing a mount tree that isn't under the +lookup name can't take advantage of the kernel queuing other +concurrent lookups while the mount tree is constructed. +--- + daemon/lookup.c | 20 +++++++++++++---- + modules/parse_amd.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++-- + modules/parse_sun.c | 22 +++++++++++------- + 3 files changed, 89 insertions(+), 14 deletions(-) + +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -815,7 +815,8 @@ static int lookup_amd_instance(struct au + + m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 1); + if (!m_key) { +- error(ap->logopt, "failed to allocate storage for search key"); ++ error(ap->logopt, ++ "failed to allocate storage for search key"); + return NSS_STATUS_UNKNOWN; + } + +@@ -823,12 +824,12 @@ static int lookup_amd_instance(struct au + strcat(m_key, "/"); + strcat(m_key, me->multi->key); + entry = master_find_amdmount(ap, m_key); ++ free(m_key); ++ + if (!entry) { + error(ap->logopt, "expected amd mount entry not found"); +- free(m_key); + return NSS_STATUS_UNKNOWN; + } +- free(m_key); + + if (strcmp(entry->type, "host")) { + error(ap->logopt, "unexpected map type %s", entry->type); +@@ -843,6 +844,17 @@ static int lookup_amd_instance(struct au + } + + instance = master_find_source_instance(map, "hosts", "sun", argc, pargv); ++ /* If this is an nss map instance it may have an amd host map sub instance */ ++ if (!instance && map->instance) { ++ struct map_source *next = map->instance; ++ while (next) { ++ instance = master_find_source_instance(next, ++ "hosts", "sun", argc, pargv); ++ if (instance) ++ break; ++ next = next->next; ++ } ++ } + if (!instance) { + error(ap->logopt, "expected hosts map instance not found"); + return NSS_STATUS_UNKNOWN; +@@ -1174,7 +1186,6 @@ int lookup_nss_mount(struct autofs_point + } + if (ap->state != ST_INIT) + send_map_update_request(ap); +- pthread_cleanup_pop(1); + + /* + * The last source lookup will return NSS_STATUS_NOTFOUND if the +@@ -1183,6 +1194,7 @@ int lookup_nss_mount(struct autofs_point + */ + if (result == NSS_STATUS_NOTFOUND || result == NSS_STATUS_UNAVAIL) + update_negative_cache(ap, source, name); ++ pthread_cleanup_pop(1); + + return !result; + } +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -1068,6 +1068,23 @@ static int do_nfsl_mount(struct autofs_p + return do_link_mount(ap, name, entry, flags); + } + ++static int wait_for_expire(struct autofs_point *ap) ++{ ++ int ret = 1; ++ ++ st_wait_task(ap, ST_EXPIRE, 0); ++ ++ st_mutex_lock(); ++ if (ap->state != ST_SHUTDOWN && ++ ap->state != ST_SHUTDOWN_PENDING && ++ ap->state != ST_SHUTDOWN_FORCE) { ++ ret = 0; ++ } ++ st_mutex_unlock(); ++ ++ return ret; ++} ++ + static int do_host_mount(struct autofs_point *ap, const char *name, + struct amd_entry *entry, struct map_source *source, + unsigned int flags) +@@ -1080,6 +1097,36 @@ static int do_host_mount(struct autofs_p + int argc = 0; + int ret = 1; + ++ /* ++ * If the mount point name isn't the same as the host name ++ * then we need to symlink to it after the mount. Attempt ++ * the allocation and set entry->path to the base location ++ * of the hosts mount tree so we can find it in ++ * lookup_nss_mount() later. ++ */ ++ if (strcmp(name, entry->rhost)) { ++ char *target; ++ size_t len = strlen(ap->path) + strlen(entry->rhost) + 2; ++ target = malloc(len); ++ if (!target) { ++ warn(ap->logopt, MODPREFIX ++ "failed to alloc target to hosts mount base"); ++ goto out; ++ } ++ strcpy(target, ap->path); ++ strcat(target, "/"); ++ strcat(target, entry->rhost); ++ if (entry->path) ++ free(entry->path); ++ entry->path = target; ++ /* ++ * Wait for any expire before racing to mount the ++ * export tree or bail out if we're shutting down. ++ */ ++ if (!wait_for_expire(ap)) ++ goto out; ++ } ++ + if (entry->opts) { + argv[0] = entry->opts; + argv[1] = NULL; +@@ -1095,7 +1142,8 @@ static int do_host_mount(struct autofs_p + goto out; + } + +- instance = master_find_source_instance(source, "hosts", "sun", argc, pargv); ++ instance = master_find_source_instance(source, ++ "hosts", "sun", argc, pargv); + if (!instance) { + instance = master_add_source_instance(source, + "hosts", "sun", time(NULL), argc, pargv); +@@ -1119,7 +1167,16 @@ static int do_host_mount(struct autofs_p + master_source_current_wait(ap->entry); + ap->entry->current = source; + +- ret = lookup->lookup_mount(ap, name, strlen(name), lookup->context); ++ ret = lookup->lookup_mount(ap, entry->rhost, ++ strlen(entry->rhost), lookup->context); ++ ++ if (!strcmp(name, entry->rhost)) ++ goto out; ++ ++ if (do_mount(ap, ap->path, ++ name, strlen(name), entry->path, "bind", "symlink")) ++ warn(ap->logopt, MODPREFIX ++ "failed to create symlink to hosts mount base"); + out: + return ret; + } +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -1343,26 +1343,32 @@ int parse_mount(struct autofs_point *ap, + strcat(m_root, name); + } + ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + cache_readlock(mc); + me = cache_lookup_distinct(mc, name); +- if (me) { +- /* So we know we're the multi-mount root */ +- if (!me->multi) +- me->multi = me; +- } +- + if (!me) { + free(options); + cache_unlock(mc); ++ pthread_setcancelstate(cur_state, NULL); + error(ap->logopt, + MODPREFIX "can't find multi root %s", name); + return 1; + } + ++ cache_multi_writelock(me); ++ /* Someone beat us to it, return success */ ++ if (me->multi) { ++ free(options); ++ cache_multi_unlock(me); ++ cache_unlock(mc); ++ pthread_setcancelstate(cur_state, NULL); ++ return 0; ++ } ++ /* So we know we're the multi-mount root */ ++ me->multi = me; ++ + age = me->age; + +- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- cache_multi_writelock(me); + /* It's a multi-mount; deal with it */ + do { + char *path, *myoptions, *loc; diff --git a/SOURCES/autofs-5.0.9-amd-lookup-fix-lofs-mounting.patch b/SOURCES/autofs-5.0.9-amd-lookup-fix-lofs-mounting.patch new file mode 100644 index 0000000..71ec18a --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-fix-lofs-mounting.patch @@ -0,0 +1,99 @@ +autofs-5.0.9 - amd lookup fix lofs mounting + +From: Ian Kent + +The kernel leaves mount type autofs alone because they are supposed +to be autofs sub-mounts and they look after their own expiration. So +mounts bound to an autofs submount won't ever be expired. +--- + daemon/spawn.c | 42 ++++++++++++++++++++++++++++++++++++++---- + 1 file changed, 38 insertions(+), 4 deletions(-) + +diff --git a/daemon/spawn.c b/daemon/spawn.c +index a6c8c34..bfb8cfc 100644 +--- a/daemon/spawn.c ++++ b/daemon/spawn.c +@@ -111,6 +111,12 @@ static int timed_read(int pipe, char *buf, size_t len, int time) + return ret; + } + ++ if (pfd[0].fd == -1) ++ return 0; ++ ++ if ((pfd[0].revents & (POLLIN|POLLHUP)) == POLLHUP) ++ return 0; ++ + while ((ret = read(pipe, buf, len)) == -1 && errno == EINTR); + + return ret; +@@ -179,7 +185,8 @@ static int do_spawn(unsigned logopt, unsigned int wait, + * I hope host names are never allowed "/" as first char + */ + if (use_open && *(argv[loc]) == '/') { +- int fd; ++ char **p; ++ int is_bind, fd; + + pid_t pgrp = getpgrp(); + +@@ -209,6 +216,33 @@ static int do_spawn(unsigned logopt, unsigned int wait, + setegid(0); + if (pgrp >= 0) + setpgid(0, pgrp); ++ ++ /* ++ * The kernel leaves mount type autofs alone because ++ * they are supposed to be autofs sub-mounts and they ++ * look after their own expiration. So mounts bound ++ * to an autofs submount won't ever be expired. ++ */ ++ is_bind = 0; ++ p = (char **) argv; ++ while (*p) { ++ if (strcmp(*p, "--bind")) { ++ p++; ++ continue; ++ } ++ is_bind = 1; ++ break; ++ } ++ if (!is_bind) ++ goto done; ++ ++ if (is_mounted(_PROC_MOUNTS, argv[loc], MNTS_AUTOFS)) { ++ fprintf(stderr, ++ "error: can't bind to an autofs mount\n"); ++ close(STDOUT_FILENO); ++ close(STDERR_FILENO); ++ _exit(EINVAL); ++ } + } + done: + execv(prog, (char *const *) argv); +@@ -384,7 +418,7 @@ int spawn_mount(unsigned logopt, ...) + + while (retries--) { + ret = do_spawn(logopt, wait, options, prog, (const char **) argv); +- if (ret & MTAB_NOTUPDATED) { ++ if (ret == MTAB_NOTUPDATED) { + struct timespec tm = {3, 0}; + + /* +@@ -502,7 +536,7 @@ int spawn_bind_mount(unsigned logopt, ...) + + while (retries--) { + ret = do_spawn(logopt, -1, options, prog, (const char **) argv); +- if (ret & MTAB_NOTUPDATED) { ++ if (ret == MTAB_NOTUPDATED) { + struct timespec tm = {3, 0}; + + /* +@@ -604,7 +638,7 @@ int spawn_umount(unsigned logopt, ...) + + while (retries--) { + ret = do_spawn(logopt, wait, options, prog, (const char **) argv); +- if (ret & MTAB_NOTUPDATED) { ++ if (ret == MTAB_NOTUPDATED) { + /* + * If the mount succeeded but the mtab was not + * updated, then retry the umount just to update diff --git a/SOURCES/autofs-5.0.9-amd-lookup-fix-old-conf-handling.patch b/SOURCES/autofs-5.0.9-amd-lookup-fix-old-conf-handling.patch new file mode 100644 index 0000000..733305f --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-fix-old-conf-handling.patch @@ -0,0 +1,104 @@ +autofs-5.0.9 - amd lookup fix old conf handling + +From: Ian Kent + +When the configuration changed to using lower case option names +old configuration files with upper case names stopped working. + +This is because, for configuration option lookup the hash of +the option string always needs to be the same case, which was +overlooked at the time. + +Also fix a couple of other things, possible incorect return +from conf_update() what adding a new entry and change to using +isblank() instead of checking for a space only. +--- + lib/defaults.c | 27 +++++++++++++++++++++------ + 1 file changed, 21 insertions(+), 6 deletions(-) + +diff --git a/lib/defaults.c b/lib/defaults.c +index 3fa2216..7043dfc 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -43,6 +43,7 @@ + #define OLD_CONFIG_FILE AUTOFS_CONF_DIR "/autofs" + #define MAX_LINE_LEN 256 + #define MAX_SECTION_NAME MAX_LINE_LEN ++#define MAX_CFG_NAME_LEN 31 + + #define NAME_MASTER_MAP "master_map_name" + +@@ -661,7 +662,7 @@ static int conf_update(const char *section, + ret = CFG_FAIL; + co = conf_lookup(section, key); + if (!co) +- ret = conf_add(section, key, value, flags); ++ return conf_add(section, key, value, flags); + else { + char *val = NULL, *tmp = NULL; + /* Environment overrides file value */ +@@ -691,15 +692,29 @@ error: + return ret; + } + ++static u_int32_t get_hash(const char *key, unsigned int size) ++{ ++ const char *pkey = key; ++ char lkey[MAX_CFG_NAME_LEN]; ++ char *plkey = &lkey[0]; ++ ++ while (*pkey) ++ *plkey++ = tolower(*pkey++); ++ *plkey = '\0'; ++ return hash(lkey, size); ++} ++ + static struct conf_option *conf_lookup(const char *section, const char *key) + { + struct conf_option *co; ++ u_int32_t key_hash; + unsigned int size = CFG_TABLE_SIZE; + + if (!key || !section) + return NULL; + +- for (co = config->hash[hash(key, size)]; co != NULL; co = co->next) { ++ key_hash = get_hash(key, size); ++ for (co = config->hash[key_hash]; co != NULL; co = co->next) { + if (strcasecmp(section, co->section)) + continue; + if (!strcasecmp(key, co->name)) +@@ -772,7 +787,7 @@ static int parse_line(char *line, char **sec, char **res, char **value) + if (*key == '#' || (*key != '[' && !isalpha(*key))) + return 0; + +- while (*key && *key == ' ') ++ while (*key && isblank(*key)) + key++; + + if (!*key) +@@ -780,13 +795,13 @@ static int parse_line(char *line, char **sec, char **res, char **value) + + if (*key == '[') { + char *tmp; +- while (*key && (*key == '[' || *key == ' ')) ++ while (*key && (*key == '[' || isblank(*key))) + key++; + tmp = strchr(key, ']'); + if (!tmp) + return 0; + *tmp = ' '; +- while (*tmp && *tmp == ' ') { ++ while (*tmp && isblank(*tmp)) { + *tmp = '\0'; + tmp--; + } +@@ -803,7 +818,7 @@ static int parse_line(char *line, char **sec, char **res, char **value) + + *val++ = '\0'; + +- while (*(--tmp) == ' ') ++ while (isblank(*(--tmp))) + *tmp = '\0'; + + while (*val && (*val == '"' || isblank(*val))) diff --git a/SOURCES/autofs-5.0.9-amd-lookup-fix-prefix-not-set-on-mount-reconnect.patch b/SOURCES/autofs-5.0.9-amd-lookup-fix-prefix-not-set-on-mount-reconnect.patch new file mode 100644 index 0000000..3ef090b --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-fix-prefix-not-set-on-mount-reconnect.patch @@ -0,0 +1,101 @@ +autofs-5.0.9 - fix prefix not set on mount reconnect + +From: Ian Kent + +When autofs is started and there are pre-existing mounts the daemon +will attempt to reconnect to these mounts to reconstuct the mount +tree. + +This process is recursive so subordinate mounts can be reconstructed +before parent mounts complete reconnection. + +Also, amd subordinate mounts of type "auto" parent mounts may need +to use the parent mount prefix which was set post mount and wasn't +available. So, setting the parent mount prefix has to be done near +the beginning of parent mount operation. +--- + modules/mount_autofs.c | 8 ++++++++ + modules/parse_amd.c | 30 +++++++++++++----------------- + 2 files changed, 21 insertions(+), 17 deletions(-) + +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index ab5a8e3..c7cba3a 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -255,6 +255,14 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, + + mounts_mutex_lock(ap); + ++ if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ struct amd_entry *am_entry = __master_find_amdmount(ap, entry->path); ++ if (am_entry && am_entry->pref) { ++ nap->pref = am_entry->pref; ++ am_entry->pref = NULL; ++ } ++ } ++ + if (handle_mounts_startup_cond_init(&suc)) { + crit(ap->logopt, MODPREFIX + "failed to init startup cond for mount %s", entry->path); +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index bc056a7..410f6ff 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -893,7 +893,6 @@ static int do_auto_mount(struct autofs_point *ap, const char *name, + struct amd_entry *entry, unsigned int flags) + { + char target[PATH_MAX + 1]; +- int ret; + + if (!entry->map_type) + strcpy(target, entry->fs); +@@ -903,18 +902,8 @@ static int do_auto_mount(struct autofs_point *ap, const char *name, + strcat(target, entry->fs); + } + +- ret = do_mount(ap, ap->path, +- name, strlen(name), target, "autofs", NULL); +- if (!ret) { +- struct autofs_point *sm; +- sm = master_find_submount(ap, entry->path); +- if (sm) { +- sm->pref = entry->pref; +- entry->pref = NULL; +- } +- } +- +- return ret; ++ return do_mount(ap, ap->path, ++ name, strlen(name), target, "autofs", NULL); + } + + static int do_link_mount(struct autofs_point *ap, const char *name, +@@ -1878,17 +1867,24 @@ int parse_mount(struct autofs_point *ap, const char *name, + + dequote_entry(ap, this); + ++ /* ++ * Type "auto" needs to set the prefix at mount time so ++ * add parsed entry to parent amd mount list and remove ++ * on mount fail. ++ */ ++ mounts_mutex_lock(ap); ++ list_add_tail(&this->entries, &ap->amdmounts); ++ mounts_mutex_unlock(ap); ++ + rv = amd_mount(ap, name, this, source, sv, flags, ctxt); + mounts_mutex_lock(ap); + if (!rv) { +- /* Add to the parent list of mounts */ +- list_add_tail(&this->entries, &ap->amdmounts); +- /* Mounted, leave it on the parent list */ ++ /* Mounted, remove entry from parsed list */ + list_del_init(&this->list); + mounts_mutex_unlock(ap); + break; + } +- /* Not mounted, remove it from the parent list */ ++ /* Not mounted, remove entry from the parent list */ + list_del_init(&this->entries); + mounts_mutex_unlock(ap); + } diff --git a/SOURCES/autofs-5.0.9-amd-lookup-move-get_proximity-to-parse_subs-c.patch b/SOURCES/autofs-5.0.9-amd-lookup-move-get_proximity-to-parse_subs-c.patch new file mode 100644 index 0000000..4cd9058 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-move-get_proximity-to-parse_subs-c.patch @@ -0,0 +1,484 @@ +autofs-5.0.9 - amd lookup move get_proximity() to parse_subs.c + +From: Ian Kent + +Later we'll need to use get_proximity() from outside modules/replicated.c +so move it to the autofs library. +--- + include/parse_subs.h | 8 ++ + lib/parse_subs.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++++++ + modules/replicated.c | 197 ------------------------------------------------- + 3 files changed, 207 insertions(+), 197 deletions(-) + +diff --git a/include/parse_subs.h b/include/parse_subs.h +index ecc712d..c0da5ae 100644 +--- a/include/parse_subs.h ++++ b/include/parse_subs.h +@@ -18,6 +18,13 @@ + #ifndef PARSE_SUBS_H + #define PARSE_SUBS_H + ++#define PROXIMITY_ERROR 0x0000 ++#define PROXIMITY_LOCAL 0x0001 ++#define PROXIMITY_SUBNET 0x0002 ++#define PROXIMITY_NET 0x0004 ++#define PROXIMITY_OTHER 0x0008 ++#define PROXIMITY_UNSUPPORTED 0x0010 ++ + struct mapent; + + struct map_type_info { +@@ -26,6 +33,7 @@ struct map_type_info { + char *map; + }; + ++unsigned int get_proximity(struct sockaddr *); + const char *skipspace(const char *); + int check_colon(const char *); + int chunklen(const char *, int); +diff --git a/lib/parse_subs.c b/lib/parse_subs.c +index dd2a784..b77d890 100644 +--- a/lib/parse_subs.c ++++ b/lib/parse_subs.c +@@ -18,8 +18,24 @@ + #include + #include + #include ++#include ++#include ++#include + #include "automount.h" + ++#define MAX_NETWORK_LEN 255 ++ ++#define MAX_IFC_BUF 2048 ++static int volatile ifc_buf_len = MAX_IFC_BUF; ++static int volatile ifc_last_len = 0; ++ ++#define MASK_A 0x7F000000 ++#define MASK_B 0xBFFF0000 ++#define MASK_C 0xDFFFFF00 ++ ++/* Get numeric value of the n bits starting at position p */ ++#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) ++ + struct types { + char *type; + unsigned int len; +@@ -45,6 +61,189 @@ static struct types format_type[] = { + }; + static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types); + ++static unsigned int ipv6_mask_cmp(uint32_t *host, uint32_t *iface, uint32_t *mask) ++{ ++ unsigned int ret = 1; ++ unsigned int i; ++ ++ for (i = 0; i < 4; i++) { ++ if ((host[i] & mask[i]) != (iface[i] & mask[i])) { ++ ret = 0; ++ break; ++ } ++ } ++ return ret; ++} ++ ++unsigned int get_proximity(struct sockaddr *host_addr) ++{ ++ struct ifaddrs *ifa = NULL; ++ struct ifaddrs *this; ++ struct sockaddr_in *addr, *msk_addr, *if_addr; ++ struct sockaddr_in6 *addr6, *msk6_addr, *if6_addr; ++ struct in_addr *hst_addr; ++ struct in6_addr *hst6_addr; ++ int addr_len; ++ char buf[MAX_ERR_BUF]; ++ uint32_t mask, ha, ia, *mask6, *ha6, *ia6; ++ int ret; ++ ++ addr = NULL; ++ addr6 = NULL; ++ hst_addr = NULL; ++ hst6_addr = NULL; ++ mask6 = NULL; ++ ha6 = NULL; ++ ia6 = NULL; ++ ha = 0; ++ ++ switch (host_addr->sa_family) { ++ case AF_INET: ++ addr = (struct sockaddr_in *) host_addr; ++ hst_addr = (struct in_addr *) &addr->sin_addr; ++ ha = ntohl((uint32_t) hst_addr->s_addr); ++ addr_len = sizeof(*hst_addr); ++ break; ++ ++ case AF_INET6: ++#ifndef WITH_LIBTIRPC ++ return PROXIMITY_UNSUPPORTED; ++#else ++ addr6 = (struct sockaddr_in6 *) host_addr; ++ hst6_addr = (struct in6_addr *) &addr6->sin6_addr; ++ ha6 = &hst6_addr->s6_addr32[0]; ++ addr_len = sizeof(*hst6_addr); ++ break; ++#endif ++ ++ default: ++ return PROXIMITY_ERROR; ++ } ++ ++ ret = getifaddrs(&ifa); ++ if (ret) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr("getifaddrs: %s", estr); ++ return PROXIMITY_ERROR; ++ } ++ ++ this = ifa; ++ while (this) { ++ if (!(this->ifa_flags & IFF_UP) || ++ this->ifa_flags & IFF_POINTOPOINT || ++ this->ifa_addr == NULL) { ++ this = this->ifa_next; ++ continue; ++ } ++ ++ switch (this->ifa_addr->sa_family) { ++ case AF_INET: ++ if (host_addr->sa_family == AF_INET6) ++ break; ++ if_addr = (struct sockaddr_in *) this->ifa_addr; ++ ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len); ++ if (!ret) { ++ freeifaddrs(ifa); ++ return PROXIMITY_LOCAL; ++ } ++ break; ++ ++ case AF_INET6: ++#ifdef WITH_LIBTIRPC ++ if (host_addr->sa_family == AF_INET) ++ break; ++ if6_addr = (struct sockaddr_in6 *) this->ifa_addr; ++ ret = memcmp(&if6_addr->sin6_addr, hst6_addr, addr_len); ++ if (!ret) { ++ freeifaddrs(ifa); ++ return PROXIMITY_LOCAL; ++ } ++#endif ++ default: ++ break; ++ } ++ this = this->ifa_next; ++ } ++ ++ this = ifa; ++ while (this) { ++ if (!(this->ifa_flags & IFF_UP) || ++ this->ifa_flags & IFF_POINTOPOINT || ++ this->ifa_addr == NULL) { ++ this = this->ifa_next; ++ continue; ++ } ++ ++ switch (this->ifa_addr->sa_family) { ++ case AF_INET: ++ if (host_addr->sa_family == AF_INET6) ++ break; ++ if_addr = (struct sockaddr_in *) this->ifa_addr; ++ ia = ntohl((uint32_t) if_addr->sin_addr.s_addr); ++ ++ /* Is the address within a localy attached subnet */ ++ ++ msk_addr = (struct sockaddr_in *) this->ifa_netmask; ++ mask = ntohl((uint32_t) msk_addr->sin_addr.s_addr); ++ ++ if ((ia & mask) == (ha & mask)) { ++ freeifaddrs(ifa); ++ return PROXIMITY_SUBNET; ++ } ++ ++ /* ++ * Is the address within a local ipv4 network. ++ * ++ * Bit position 31 == 0 => class A. ++ * Bit position 30 == 0 => class B. ++ * Bit position 29 == 0 => class C. ++ */ ++ ++ if (!getbits(ia, 31, 1)) ++ mask = MASK_A; ++ else if (!getbits(ia, 30, 1)) ++ mask = MASK_B; ++ else if (!getbits(ia, 29, 1)) ++ mask = MASK_C; ++ else ++ break; ++ ++ if ((ia & mask) == (ha & mask)) { ++ freeifaddrs(ifa); ++ return PROXIMITY_NET; ++ } ++ break; ++ ++ case AF_INET6: ++#ifdef WITH_LIBTIRPC ++ if (host_addr->sa_family == AF_INET) ++ break; ++ if6_addr = (struct sockaddr_in6 *) this->ifa_addr; ++ ia6 = &if6_addr->sin6_addr.s6_addr32[0]; ++ ++ /* Is the address within the network of the interface */ ++ ++ msk6_addr = (struct sockaddr_in6 *) this->ifa_netmask; ++ mask6 = &msk6_addr->sin6_addr.s6_addr32[0]; ++ ++ if (ipv6_mask_cmp(ha6, ia6, mask6)) { ++ freeifaddrs(ifa); ++ return PROXIMITY_SUBNET; ++ } ++ ++ /* How do we define "local network" in ipv6? */ ++#endif ++ default: ++ break; ++ } ++ this = this->ifa_next; ++ } ++ ++ freeifaddrs(ifa); ++ ++ return PROXIMITY_OTHER; ++} ++ + /* + * Skip whitespace in a string; if we hit a #, consider the rest of the + * entry a comment. +diff --git a/modules/replicated.c b/modules/replicated.c +index d43f778..0c1a8a7 100644 +--- a/modules/replicated.c ++++ b/modules/replicated.c +@@ -48,11 +48,8 @@ + #include + #include + #include +-#include +-#include + #include + #include +-#include + + #include "rpc_subs.h" + #include "replicated.h" +@@ -62,34 +59,9 @@ + #define MAX_ERR_BUF 512 + #endif + +-#define MAX_IFC_BUF 2048 +-static int volatile ifc_buf_len = MAX_IFC_BUF; +-static int volatile ifc_last_len = 0; +- +-#define MASK_A 0x7F000000 +-#define MASK_B 0xBFFF0000 +-#define MASK_C 0xDFFFFF00 +- +-/* Get numeric value of the n bits starting at position p */ +-#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) +- + #define mymax(x, y) (x >= y ? x : y) + #define mmax(x, y, z) (mymax(x, y) == x ? mymax(x, z) : mymax(y, z)) + +-unsigned int ipv6_mask_cmp(uint32_t *host, uint32_t *iface, uint32_t *mask) +-{ +- unsigned int ret = 1; +- unsigned int i; +- +- for (i = 0; i < 4; i++) { +- if ((host[i] & mask[i]) != (iface[i] & mask[i])) { +- ret = 0; +- break; +- } +- } +- return ret; +-} +- + void seed_random(void) + { + int fd; +@@ -111,175 +83,6 @@ void seed_random(void) + return; + } + +-static unsigned int get_proximity(struct sockaddr *host_addr) +-{ +- struct ifaddrs *ifa = NULL; +- struct ifaddrs *this; +- struct sockaddr_in *addr, *msk_addr, *if_addr; +- struct sockaddr_in6 *addr6, *msk6_addr, *if6_addr; +- struct in_addr *hst_addr; +- struct in6_addr *hst6_addr; +- int addr_len; +- char buf[MAX_ERR_BUF]; +- uint32_t mask, ha, ia, *mask6, *ha6, *ia6; +- int ret; +- +- addr = NULL; +- addr6 = NULL; +- hst_addr = NULL; +- hst6_addr = NULL; +- mask6 = NULL; +- ha6 = NULL; +- ia6 = NULL; +- ha = 0; +- +- switch (host_addr->sa_family) { +- case AF_INET: +- addr = (struct sockaddr_in *) host_addr; +- hst_addr = (struct in_addr *) &addr->sin_addr; +- ha = ntohl((uint32_t) hst_addr->s_addr); +- addr_len = sizeof(*hst_addr); +- break; +- +- case AF_INET6: +-#ifndef WITH_LIBTIRPC +- return PROXIMITY_UNSUPPORTED; +-#else +- addr6 = (struct sockaddr_in6 *) host_addr; +- hst6_addr = (struct in6_addr *) &addr6->sin6_addr; +- ha6 = &hst6_addr->s6_addr32[0]; +- addr_len = sizeof(*hst6_addr); +- break; +-#endif +- +- default: +- return PROXIMITY_ERROR; +- } +- +- ret = getifaddrs(&ifa); +- if (ret) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr("getifaddrs: %s", estr); +- return PROXIMITY_ERROR; +- } +- +- this = ifa; +- while (this) { +- if (!(this->ifa_flags & IFF_UP) || +- this->ifa_flags & IFF_POINTOPOINT || +- this->ifa_addr == NULL) { +- this = this->ifa_next; +- continue; +- } +- +- switch (this->ifa_addr->sa_family) { +- case AF_INET: +- if (host_addr->sa_family == AF_INET6) +- break; +- if_addr = (struct sockaddr_in *) this->ifa_addr; +- ret = memcmp(&if_addr->sin_addr, hst_addr, addr_len); +- if (!ret) { +- freeifaddrs(ifa); +- return PROXIMITY_LOCAL; +- } +- break; +- +- case AF_INET6: +-#ifdef WITH_LIBTIRPC +- if (host_addr->sa_family == AF_INET) +- break; +- if6_addr = (struct sockaddr_in6 *) this->ifa_addr; +- ret = memcmp(&if6_addr->sin6_addr, hst6_addr, addr_len); +- if (!ret) { +- freeifaddrs(ifa); +- return PROXIMITY_LOCAL; +- } +-#endif +- default: +- break; +- } +- this = this->ifa_next; +- } +- +- this = ifa; +- while (this) { +- if (!(this->ifa_flags & IFF_UP) || +- this->ifa_flags & IFF_POINTOPOINT || +- this->ifa_addr == NULL) { +- this = this->ifa_next; +- continue; +- } +- +- switch (this->ifa_addr->sa_family) { +- case AF_INET: +- if (host_addr->sa_family == AF_INET6) +- break; +- if_addr = (struct sockaddr_in *) this->ifa_addr; +- ia = ntohl((uint32_t) if_addr->sin_addr.s_addr); +- +- /* Is the address within a localy attached subnet */ +- +- msk_addr = (struct sockaddr_in *) this->ifa_netmask; +- mask = ntohl((uint32_t) msk_addr->sin_addr.s_addr); +- +- if ((ia & mask) == (ha & mask)) { +- freeifaddrs(ifa); +- return PROXIMITY_SUBNET; +- } +- +- /* +- * Is the address within a local ipv4 network. +- * +- * Bit position 31 == 0 => class A. +- * Bit position 30 == 0 => class B. +- * Bit position 29 == 0 => class C. +- */ +- +- if (!getbits(ia, 31, 1)) +- mask = MASK_A; +- else if (!getbits(ia, 30, 1)) +- mask = MASK_B; +- else if (!getbits(ia, 29, 1)) +- mask = MASK_C; +- else +- break; +- +- if ((ia & mask) == (ha & mask)) { +- freeifaddrs(ifa); +- return PROXIMITY_NET; +- } +- break; +- +- case AF_INET6: +-#ifdef WITH_LIBTIRPC +- if (host_addr->sa_family == AF_INET) +- break; +- if6_addr = (struct sockaddr_in6 *) this->ifa_addr; +- ia6 = &if6_addr->sin6_addr.s6_addr32[0]; +- +- /* Is the address within the network of the interface */ +- +- msk6_addr = (struct sockaddr_in6 *) this->ifa_netmask; +- mask6 = &msk6_addr->sin6_addr.s6_addr32[0]; +- +- if (ipv6_mask_cmp(ha6, ia6, mask6)) { +- freeifaddrs(ifa); +- return PROXIMITY_SUBNET; +- } +- +- /* How do we define "local network" in ipv6? */ +-#endif +- default: +- break; +- } +- this = this->ifa_next; +- } +- +- freeifaddrs(ifa); +- +- return PROXIMITY_OTHER; +-} +- + struct host *new_host(const char *name, + struct sockaddr *addr, size_t addr_len, + unsigned int proximity, unsigned int weight, diff --git a/SOURCES/autofs-5.0.9-amd-lookup-rework-config-handling.patch b/SOURCES/autofs-5.0.9-amd-lookup-rework-config-handling.patch new file mode 100644 index 0000000..dfed20a --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-rework-config-handling.patch @@ -0,0 +1,1266 @@ +autofs-5.0.9 - amd lookup rework config handling + +From: Ian Kent + +Re-work the autofs configuration sub-system to use sections. +Initially this means we have an anonomous section (for backward +compatibility) and an "autofs" section for the autofs global +configuration. +--- + daemon/automount.c | 1 + include/automount.h | 18 + + include/defaults.h | 27 +- + lib/cache.c | 19 - + lib/defaults.c | 836 +++++++++++++++++++++++++++++++++++++-------------- + 5 files changed, 644 insertions(+), 257 deletions(-) + +diff --git a/daemon/automount.c b/daemon/automount.c +index 0dd6477..fd5a19b 100644 +--- a/daemon/automount.c ++++ b/daemon/automount.c +@@ -2339,6 +2339,7 @@ int main(int argc, char *argv[]) + unlink(pid_file); + pid_file = NULL; + } ++ defaults_conf_release(); + closelog(); + release_flag_file(); + macro_free_global_table(); +diff --git a/include/automount.h b/include/automount.h +index 1aabfa4..6da1926 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -136,6 +136,24 @@ struct autofs_point; + #define UMOUNT_RETRIES 8 + #define EXPIRE_RETRIES 3 + ++static u_int32_t inline hash(const char *key, unsigned int size) ++{ ++ u_int32_t hashval; ++ char *s = (char *) key; ++ ++ for (hashval = 0; *s != '\0';) { ++ hashval += (unsigned char) *s++; ++ hashval += (hashval << 10); ++ hashval ^= (hashval >> 6); ++ } ++ ++ hashval += (hashval << 3); ++ hashval ^= (hashval >> 11); ++ hashval += (hashval << 15); ++ ++ return hashval % size; ++} ++ + struct mapent_cache { + pthread_rwlock_t rwlock; + unsigned int size; +diff --git a/include/defaults.h b/include/defaults.h +index 871e14b..3bfcd49 100644 +--- a/include/defaults.h ++++ b/include/defaults.h +@@ -2,7 +2,9 @@ + * + * defaults.h - system initialization defaults. + * +- * Copyright 2006 Ian Kent ++ * Copyright 2013 Red Hat, Inc. ++ * Copyright 2006, 2013 Ian Kent ++ * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -22,15 +24,15 @@ + + #define DEFAULT_MASTER_MAP_NAME "auto.master" + +-#define DEFAULT_TIMEOUT 600 +-#define DEFAULT_NEGATIVE_TIMEOUT 60 +-#define DEFAULT_MOUNT_WAIT -1 +-#define DEFAULT_UMOUNT_WAIT 12 +-#define DEFAULT_BROWSE_MODE 1 +-#define DEFAULT_LOGGING 0 ++#define DEFAULT_TIMEOUT "600" ++#define DEFAULT_NEGATIVE_TIMEOUT "60" ++#define DEFAULT_MOUNT_WAIT "-1" ++#define DEFAULT_UMOUNT_WAIT "12" ++#define DEFAULT_BROWSE_MODE "1" ++#define DEFAULT_LOGGING "none" + +-#define DEFAULT_LDAP_TIMEOUT -1 +-#define DEFAULT_LDAP_NETWORK_TIMEOUT 8 ++#define DEFAULT_LDAP_TIMEOUT "-1" ++#define DEFAULT_LDAP_NETWORK_TIMEOUT "8" + + #define DEFAULT_MAP_OBJ_CLASS "nisMap" + #define DEFAULT_ENTRY_OBJ_CLASS "nisObject" +@@ -38,11 +40,11 @@ + #define DEFAULT_ENTRY_ATTR "cn" + #define DEFAULT_VALUE_ATTR "nisMapEntry" + +-#define DEFAULT_NFS_MOUNT_PROTOCOL 3 +-#define DEFAULT_APPEND_OPTIONS 1 ++#define DEFAULT_MOUNT_NFS_DEFAULT_PROTOCOL "3" ++#define DEFAULT_APPEND_OPTIONS "1" + #define DEFAULT_AUTH_CONF_FILE AUTOFS_MAP_DIR "/autofs_ldap_auth.conf" + +-#define DEFAULT_MAP_HASH_TABLE_SIZE 1024 ++#define DEFAULT_MAP_HASH_TABLE_SIZE "1024" + + #ifdef WITH_LDAP + struct ldap_schema; +@@ -56,6 +58,7 @@ struct ldap_schema *defaults_get_schema(void); + #endif + + unsigned int defaults_read_config(unsigned int); ++void defaults_conf_release(void); + const char *defaults_get_master_map(void); + int defaults_master_set(void); + unsigned int defaults_get_timeout(void); +diff --git a/lib/cache.c b/lib/cache.c +index f2efcd3..9af1709 100644 +--- a/lib/cache.c ++++ b/lib/cache.c +@@ -20,7 +20,6 @@ + #include + #include + #include +-#include + #include + + #include "automount.h" +@@ -362,24 +361,6 @@ struct mapent_cache *cache_init_null_cache(struct master *master) + return mc; + } + +-static u_int32_t hash(const char *key, unsigned int size) +-{ +- u_int32_t hashval; +- char *s = (char *) key; +- +- for (hashval = 0; *s != '\0';) { +- hashval += (unsigned char) *s++; +- hashval += (hashval << 10); +- hashval ^= (hashval >> 6); +- } +- +- hashval += (hashval << 3); +- hashval ^= (hashval >> 11); +- hashval += (hashval << 15); +- +- return hashval % size; +-} +- + static u_int32_t ino_hash(dev_t dev, ino_t ino, unsigned int size) + { + u_int32_t hashval; +diff --git a/lib/defaults.c b/lib/defaults.c +index 7c65387..29f3f00 100644 +--- a/lib/defaults.c ++++ b/lib/defaults.c +@@ -2,7 +2,9 @@ + * + * defaults.h - system initialization defaults. + * +- * Copyright 2006 Ian Kent - All Rights Reserved ++ * Copyright 2013 Red Hat, Inc. ++ * Copyright 2006, 2013 Ian Kent ++ * All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -16,6 +18,7 @@ + #include + #include + #include ++#include + + #include "config.h" + #include "list.h" +@@ -26,132 +29,450 @@ + #include "log.h" + #include "automount.h" + +-#define DEFAULTS_CONFIG_FILE AUTOFS_CONF_DIR "/autofs" ++#define AUTOFS_GLOBAL_SECTION "autofs" ++ ++#define DEFAULT_CONFIG_FILE AUTOFS_CONF_DIR "/autofs" + #define MAX_LINE_LEN 256 + +-#define ENV_NAME_MASTER_MAP "MASTER_MAP_NAME" ++#define NAME_MASTER_MAP "master_map_name" ++ ++#define NAME_TIMEOUT "timeout" ++#define NAME_NEGATIVE_TIMEOUT "negative_timeout" ++#define NAME_BROWSE_MODE "browse_mode" ++#define NAME_LOGGING "logging" ++ ++#define NAME_LDAP_URI "ldap_uri" ++#define NAME_LDAP_TIMEOUT "ldap_timeout" ++#define NAME_LDAP_NETWORK_TIMEOUT "ldap_network_timeout" ++ ++#define NAME_SEARCH_BASE "search_base" + +-#define ENV_NAME_TIMEOUT "TIMEOUT" +-#define ENV_NAME_NEGATIVE_TIMEOUT "NEGATIVE_TIMEOUT" +-#define ENV_NAME_BROWSE_MODE "BROWSE_MODE" +-#define ENV_NAME_LOGGING "LOGGING" ++#define NAME_MAP_OBJ_CLASS "map_object_class" ++#define NAME_ENTRY_OBJ_CLASS "entry_object_class" ++#define NAME_MAP_ATTR "map_attribute" ++#define NAME_ENTRY_ATTR "entry_attribute" ++#define NAME_VALUE_ATTR "value_attribute" + +-#define LDAP_URI "LDAP_URI" +-#define ENV_LDAP_TIMEOUT "LDAP_TIMEOUT" +-#define ENV_LDAP_NETWORK_TIMEOUT "LDAP_NETWORK_TIMEOUT" ++#define NAME_MOUNT_NFS_DEFAULT_PROTOCOL "mount_nfs_default_protocol" ++#define NAME_APPEND_OPTIONS "append_options" ++#define NAME_MOUNT_WAIT "mount_wait" ++#define NAME_UMOUNT_WAIT "umount_wait" ++#define NAME_AUTH_CONF_FILE "auth_conf_file" + +-#define SEARCH_BASE "SEARCH_BASE" ++#define NAME_MAP_HASH_TABLE_SIZE "map_hash_table_size" + +-#define ENV_NAME_MAP_OBJ_CLASS "MAP_OBJECT_CLASS" +-#define ENV_NAME_ENTRY_OBJ_CLASS "ENTRY_OBJECT_CLASS" +-#define ENV_NAME_MAP_ATTR "MAP_ATTRIBUTE" +-#define ENV_NAME_ENTRY_ATTR "ENTRY_ATTRIBUTE" +-#define ENV_NAME_VALUE_ATTR "VALUE_ATTRIBUTE" ++/* Status returns */ ++#define CFG_OK 0x0000 ++#define CFG_FAIL 0x0001 ++#define CFG_EXISTS 0x0002 ++#define CFG_NOTFOUND 0x0004 + +-#define ENV_MOUNT_NFS_DEFAULT_PROTOCOL "MOUNT_NFS_DEFAULT_PROTOCOL" +-#define ENV_APPEND_OPTIONS "APPEND_OPTIONS" +-#define ENV_MOUNT_WAIT "MOUNT_WAIT" +-#define ENV_UMOUNT_WAIT "UMOUNT_WAIT" +-#define ENV_AUTH_CONF_FILE "AUTH_CONF_FILE" ++/* Config entry flags */ ++#define CONF_ENV 0x00000001 + +-#define ENV_MAP_HASH_TABLE_SIZE "MAP_HASH_TABLE_SIZE" ++#define CFG_TABLE_SIZE 128 + + static const char *default_master_map_name = DEFAULT_MASTER_MAP_NAME; + static const char *default_auth_conf_file = DEFAULT_AUTH_CONF_FILE; ++static const char *autofs_gbl_sec = AUTOFS_GLOBAL_SECTION; ++ ++struct conf_option { ++ char *section; ++ char *name; ++ char *value; ++ unsigned long flags; ++ struct conf_option *next; ++}; ++ ++struct conf_cache { ++ struct conf_option **hash; ++ time_t modified; ++}; ++static pthread_mutex_t conf_mutex = PTHREAD_MUTEX_INITIALIZER; ++static struct conf_cache *config = NULL; ++ ++static int conf_load_autofs_defaults(void); ++static int conf_update(const char *, const char *, const char *, unsigned long); ++static void conf_delete(const char *, const char *); ++static struct conf_option *conf_lookup(const char *, const char *); ++ ++ ++static void message(unsigned int to_syslog, const char *msg, ...) ++{ ++ va_list ap; ++ ++ va_start(ap, msg); ++ if (to_syslog) ++ vsyslog(LOG_CRIT, msg, ap); ++ else { ++ vfprintf(stderr, msg, ap); ++ fputc('\n', stderr); ++ } ++ va_end(ap); ++ ++ return; ++} + +-static char *get_env_string(const char *name) ++static int conf_init(void) + { +- char *val, *res; ++ struct conf_cache *cc; ++ unsigned int size = CFG_TABLE_SIZE; ++ unsigned int i; ++ ++ cc = malloc(sizeof(struct conf_cache)); ++ if (!cc) ++ return CFG_FAIL; ++ cc->modified = 0; ++ ++ cc->hash = malloc(size * sizeof(struct conf_option *)); ++ if (!cc->hash) { ++ free(cc); ++ return CFG_FAIL; ++ } + +- val = getenv(name); +- if (!val) +- return NULL; ++ for (i = 0; i < size; i++) { ++ cc->hash[i] = NULL; ++ } + +- res = strdup(val); +- if (!res) +- return NULL; ++ config = cc; + +- return res; ++ return CFG_OK; + } + +-static long get_env_number(const char *name) ++static void __conf_release(void) + { +- char *val; +- long res = -1; +- +- val = getenv(name); +- if (!val) +- return -1; ++ struct conf_cache *cc = config; ++ unsigned int size = CFG_TABLE_SIZE; ++ struct conf_option *co, *next; ++ unsigned int i; ++ ++ for (i = 0; i < size; i++) { ++ co = cc->hash[i]; ++ if (co == NULL) ++ continue; ++ next = co->next; ++ free(co->section); ++ free(co->name); ++ if (co->value) ++ free(co->value); ++ free(co); ++ ++ while (next) { ++ co = next; ++ next = co->next; ++ free(co->section); ++ free(co->name); ++ if (co->value) ++ free(co->value); ++ free(co); ++ } ++ cc->hash[i] = NULL; ++ } + +- if (isdigit(*val)) +- res = atol(val); ++ free(cc->hash); ++ free(cc); ++ config = NULL; + +- if (res < 0) +- return -1; ++ return; ++} + +- return res; ++void defaults_conf_release(void) ++{ ++ pthread_mutex_lock(&conf_mutex); ++ __conf_release(); ++ pthread_mutex_unlock(&conf_mutex); ++ return; + } + +-static int get_env_yesno(const char *name) ++static int conf_load_autofs_defaults(void) + { +- const char *val; +- int res = -1; ++ struct conf_option *co; ++ const char *sec = autofs_gbl_sec; ++ int ret; + +- val = getenv(name); +- if (!val) +- return -1; ++ ret = conf_update(sec, NAME_MASTER_MAP, ++ DEFAULT_MASTER_MAP_NAME, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_TIMEOUT, ++ DEFAULT_TIMEOUT, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_NEGATIVE_TIMEOUT, ++ DEFAULT_NEGATIVE_TIMEOUT, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_BROWSE_MODE, ++ DEFAULT_BROWSE_MODE, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_LOGGING, ++ DEFAULT_LOGGING, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_LDAP_TIMEOUT, ++ DEFAULT_LDAP_TIMEOUT, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_LDAP_NETWORK_TIMEOUT, ++ DEFAULT_LDAP_NETWORK_TIMEOUT, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_MAP_OBJ_CLASS, ++ DEFAULT_MAP_OBJ_CLASS, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_ENTRY_OBJ_CLASS, ++ DEFAULT_ENTRY_OBJ_CLASS, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_MAP_ATTR, ++ DEFAULT_MAP_ATTR, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_ENTRY_ATTR, ++ DEFAULT_ENTRY_ATTR, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_VALUE_ATTR, ++ DEFAULT_VALUE_ATTR, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_APPEND_OPTIONS, ++ DEFAULT_APPEND_OPTIONS, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_MOUNT_WAIT, ++ DEFAULT_MOUNT_WAIT, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_UMOUNT_WAIT, ++ DEFAULT_UMOUNT_WAIT, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_AUTH_CONF_FILE, ++ DEFAULT_AUTH_CONF_FILE, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ ret = conf_update(sec, NAME_MOUNT_NFS_DEFAULT_PROTOCOL, ++ DEFAULT_MOUNT_NFS_DEFAULT_PROTOCOL, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ ++ /* LDAP_URI nad SEARCH_BASE can occur multiple times */ ++ while ((co = conf_lookup(sec, NAME_LDAP_URI))) ++ conf_delete(co->section, co->name); ++ ++ while ((co = conf_lookup(sec, NAME_SEARCH_BASE))) ++ conf_delete(co->section, co->name); + +- if (isdigit(*val)) +- res = atoi(val); +- else if (!strcasecmp(val, "yes")) +- return 1; +- else if (!strcasecmp(val, "no")) +- return 0; ++ return 1; + +- return res; ++error: ++ return 0; + } + +-/* +- * We've changed the key names so we need to check for the +- * config key and it's old name for backward conpatibility. +-*/ +-static int check_set_config_value(const char *res, const char *name, const char *value, unsigned to_syslog) ++static int conf_add(const char *section, const char *key, const char *value, unsigned long flags) + { +- char *old_name; ++ struct conf_option *co; ++ char *sec, *name, *val, *tmp; ++ unsigned int size = CFG_TABLE_SIZE; ++ u_int32_t index; + int ret; + +- if (!strcasecmp(res, name)) { +- ret = setenv(name, value, 0); +- if (ret) { +- if (!to_syslog) +- fprintf(stderr, +- "can't set config value for %s, " +- "error %d\n", name, ret); +- else +- logmsg("can't set config value for %s, " +- "error %d", name, ret); ++ sec = name = val = NULL; ++ ++ co = conf_lookup(section, key); ++ if (co) { ++ ret = CFG_EXISTS; ++ goto error; ++ } ++ ++ ret = CFG_FAIL; ++ ++ /* Environment overrides file value */ ++ if (((flags & CFG_ENV) && (tmp = getenv(key))) || value) { ++ if (tmp) ++ val = strdup(tmp); ++ else ++ val = strdup(value); ++ if (!val) ++ goto error; ++ } ++ ++ name = strdup(key); ++ if (!key) ++ goto error; ++ ++ sec = strdup(section); ++ if (!sec) ++ goto error; ++ ++ co = malloc(sizeof(struct conf_option)); ++ if (!co) ++ goto error; ++ ++ co->section = sec; ++ co->name = name; ++ co->value = val; ++ co->flags = flags; ++ co->next = NULL; ++ ++ /* Don't change user set values in the environment */ ++ if (flags & CONF_ENV) ++ setenv(name, value, 0); ++ ++ index = hash(key, size); ++ if (!config->hash[index]) ++ config->hash[index] = co; ++ else { ++ struct conf_option *last = NULL, *next; ++ next = config->hash[index]; ++ while (next) { ++ last = next; ++ next = last->next; + } +- return 1; ++ last->next = co; + } + +- old_name = alloca(strlen(name) + 9); +- strcpy(old_name, "DEFAULT_"); +- strcat(old_name, name); ++ return CFG_OK; ++ ++error: ++ if (name) ++ free(name); ++ if (val) ++ free(val); ++ if (sec) ++ free(sec); ++ ++ return ret; ++} + +- if (!strcasecmp(res, old_name)) { +- ret = setenv(name, value, 0); +- if (ret) { +- if (!to_syslog) +- fprintf(stderr, +- "can't set config value for %s, " +- "error %d\n", name, ret); ++static void conf_delete(const char *section, const char *key) ++{ ++ struct conf_option *co, *last; ++ unsigned int size = CFG_TABLE_SIZE; ++ ++ last = NULL; ++ for (co = config->hash[hash(key, size)]; co != NULL; co = co->next) { ++ if (strcasecmp(section, co->section)) ++ continue; ++ if (!strcasecmp(key, co->name)) ++ break; ++ last = co; ++ } ++ ++ if (!co) ++ return; ++ ++ if (last) ++ last->next = co->next; ++ ++ free(co->section); ++ free(co->name); ++ if (co->value); ++ free(co->value); ++ free(co); ++} ++ ++static int conf_update(const char *section, ++ const char *key, const char *value, ++ unsigned long flags) ++{ ++ struct conf_option *co = NULL; ++ int ret; ++ ++ ret = CFG_FAIL; ++ co = conf_lookup(section, key); ++ if (!co) ++ ret = conf_add(section, key, value, flags); ++ else { ++ char *val = NULL, *tmp; ++ /* Environment overrides file value */ ++ if (((flags & CONF_ENV) && (tmp = getenv(key))) || value) { ++ if (tmp) ++ val = strdup(tmp); + else +- logmsg("can't set config value for %s, " +- "error %d\n", name, ret); ++ val = strdup(value); ++ if (!val) ++ goto error; + } +- return 1; ++ if (co->value) ++ free(co->value); ++ co->value = val; ++ if (flags) ++ co->flags = flags; ++ /* Don't change user set values in the environment */ ++ if (flags & CONF_ENV) ++ setenv(key, value, 0); + } +- return 0; ++ ++ return CFG_OK; ++ ++error: ++ return ret; ++} ++ ++static struct conf_option *conf_lookup(const char *section, const char *key) ++{ ++ struct conf_option *co; ++ unsigned int size = CFG_TABLE_SIZE; ++ ++ if (!key || !section) ++ return NULL; ++ ++ for (co = config->hash[hash(key, size)]; co != NULL; co = co->next) { ++ if (strcasecmp(section, co->section)) ++ continue; ++ if (!strcasecmp(key, co->name)) ++ break; ++ /* ++ * Strip "DEFAULT_" and look for config entry for ++ * backward compatibility with old style config names. ++ */ ++ if (strlen(key) <= 8) ++ continue; ++ if (!strncasecmp("DEFAULT_", key, 8) && ++ !strcasecmp(key + 8, co->name)) ++ break; ++ } ++ ++ return co; ++} ++ ++/* ++ * We've changed the key names so we need to check for the ++ * config key and it's old name for backward conpatibility. ++*/ ++static int check_set_config_value(const char *res, const char *value) ++{ ++ const char *sec = autofs_gbl_sec; ++ int ret; ++ ++ if (!strcasecmp(res, NAME_LDAP_URI)) ++ ret = conf_add(sec, res, value, 0); ++ else if (!strcasecmp(res, NAME_SEARCH_BASE)) ++ ret = conf_add(sec, res, value, 0); ++ else ++ ret = conf_update(sec, res, value, 0); ++ ++ return ret; + } + + static int parse_line(char *line, char **res, char **value) +@@ -200,6 +521,119 @@ static int parse_line(char *line, char **res, char **value) + return 1; + } + ++/* ++ * Read config env variables and check they have been set. ++ * ++ * This simple minded routine assumes the config file ++ * is valid bourne shell script without spaces around "=" ++ * and that it has valid values. ++ */ ++unsigned int defaults_read_config(unsigned int to_syslog) ++{ ++ FILE *f; ++ char buf[MAX_LINE_LEN]; ++ struct stat stb; ++ char *res; ++ int ret; ++ ++ f = open_fopen_r(DEFAULT_CONFIG_FILE); ++ if (!f) ++ return 0; ++ ++ pthread_mutex_lock(&conf_mutex); ++ if (config) { ++ if (fstat(fileno(f), &stb) != -1) { ++ /* Config hasn't been updated */ ++ if (stb.st_mtime <= config->modified) ++ goto out; ++ } ++ } else { ++ if (conf_init()) { ++ pthread_mutex_unlock(&conf_mutex); ++ message(to_syslog, "failed to init config"); ++ return 0; ++ } ++ } ++ ++ /* Set configuration to defaults */ ++ ret = conf_load_autofs_defaults(); ++ if (!ret) { ++ pthread_mutex_unlock(&conf_mutex); ++ message(to_syslog, "failed to reset autofs default config"); ++ return 0; ++ } ++ ++ while ((res = fgets(buf, MAX_LINE_LEN, f))) { ++ char *key, *value; ++ if (!parse_line(res, &key, &value)) ++ continue; ++ check_set_config_value(key, value); ++ } ++ ++ if (fstat(fileno(f), &stb) != -1) ++ config->modified = stb.st_mtime; ++ else ++ message(to_syslog, "failed to update config modified time"); ++ ++ if (!feof(f) || ferror(f)) { ++ pthread_mutex_unlock(&conf_mutex); ++ message(to_syslog, ++ "fgets returned error %d while reading %s", ++ ferror(f), DEFAULT_CONFIG_FILE); ++ fclose(f); ++ return 0; ++ } ++out: ++ pthread_mutex_unlock(&conf_mutex); ++ fclose(f); ++ return 1; ++} ++ ++static char *conf_get_string(const char *section, const char *name) ++{ ++ struct conf_option *co; ++ char *val = NULL; ++ ++ pthread_mutex_lock(&conf_mutex); ++ co = conf_lookup(section, name); ++ if (co && co->value) ++ val = strdup(co->value); ++ pthread_mutex_unlock(&conf_mutex); ++ return val; ++} ++ ++static long conf_get_number(const char *section, const char *name) ++{ ++ struct conf_option *co; ++ long val = -1; ++ ++ pthread_mutex_lock(&conf_mutex); ++ co = conf_lookup(section, name); ++ if (co && co->value) ++ val = atol(co->value); ++ pthread_mutex_unlock(&conf_mutex); ++ return val; ++} ++ ++static int conf_get_yesno(const char *section, const char *name) ++{ ++ struct conf_option *co; ++ int val = -1; ++ ++ pthread_mutex_lock(&conf_mutex); ++ co = conf_lookup(section, name); ++ if (co && co->value) { ++ if (isdigit(*co->value)) ++ val = atoi(co->value); ++ else if (!strcasecmp(co->value, "yes")) ++ val = 1; ++ else if (!strcasecmp(co->value, "no")) ++ val = 0; ++ } ++ pthread_mutex_unlock(&conf_mutex); ++ return val; ++} ++ + #ifdef WITH_LDAP + void defaults_free_uris(struct list_head *list) + { +@@ -229,7 +663,7 @@ static unsigned int add_uris(char *value, struct list_head *list) + char *str, *tok, *ptr = NULL; + size_t len = strlen(value) + 1; + +- str = alloca(len); ++ str = malloc(len); + if (!str) + return 0; + strcpy(str, value); +@@ -253,44 +687,48 @@ static unsigned int add_uris(char *value, struct list_head *list) + + tok = strtok_r(NULL, " ", &ptr); + } ++ free(str); + + return 1; + } + + struct list_head *defaults_get_uris(void) + { +- FILE *f; +- char buf[MAX_LINE_LEN]; +- char *res; ++ struct conf_option *co; + struct list_head *list; + +- f = open_fopen_r(DEFAULTS_CONFIG_FILE); +- if (!f) +- return NULL; +- + list = malloc(sizeof(struct list_head)); + if (!list) { +- fclose(f); + return NULL; + } + INIT_LIST_HEAD(list); + +- while ((res = fgets(buf, MAX_LINE_LEN, f))) { +- char *key, *value; ++ if (defaults_read_config(0)) { ++ free(list); ++ return NULL; ++ } + +- if (!parse_line(res, &key, &value)) +- continue; ++ pthread_mutex_lock(&conf_mutex); ++ co = conf_lookup(autofs_gbl_sec, NAME_LDAP_URI); ++ if (!co || !co->value) { ++ pthread_mutex_unlock(&conf_mutex); ++ free(list); ++ return NULL; ++ } + +- if (!strcasecmp(res, LDAP_URI)) +- add_uris(value, list); ++ while (co) { ++ if (!strcasecmp(co->name, NAME_LDAP_URI)) ++ if (co->value) ++ add_uris(co->value, list); ++ co = co->next; + } ++ pthread_mutex_unlock(&conf_mutex); + + if (list_empty(list)) { + free(list); + list = NULL; + } + +- fclose(f); + return list; + } + +@@ -390,45 +828,50 @@ void defaults_free_searchdns(struct ldap_searchdn *sdn) + + struct ldap_searchdn *defaults_get_searchdns(void) + { +- FILE *f; +- char buf[MAX_LINE_LEN]; +- char *res; ++ struct conf_option *co; + struct ldap_searchdn *sdn, *last; + +- f = open_fopen_r(DEFAULTS_CONFIG_FILE); +- if (!f) ++ if (defaults_read_config(0)) + return NULL; + ++ pthread_mutex_lock(&conf_mutex); ++ co = conf_lookup(autofs_gbl_sec, NAME_SEARCH_BASE); ++ if (!co || !co->value) { ++ pthread_mutex_unlock(&conf_mutex); ++ return NULL; ++ } ++ + sdn = last = NULL; + +- while ((res = fgets(buf, MAX_LINE_LEN, f))) { +- char *key, *value; ++ while (co) { ++ struct ldap_searchdn *new; + +- if (!parse_line(res, &key, &value)) ++ if (!co->value || strcasecmp(co->name, NAME_SEARCH_BASE) ) { ++ co = co->next; + continue; ++ } + +- if (!strcasecmp(key, SEARCH_BASE)) { +- struct ldap_searchdn *new = alloc_searchdn(value); ++ new = alloc_searchdn(co->value); ++ if (!new) { ++ pthread_mutex_unlock(&conf_mutex); ++ defaults_free_searchdns(sdn); ++ return NULL; ++ } + +- if (!new) { +- defaults_free_searchdns(sdn); +- fclose(f); +- return NULL; +- } ++ if (!last) ++ last = new; ++ else { ++ last->next = new; ++ last = new; ++ } + +- if (!last) +- last = new; +- else { +- last->next = new; +- last = new; +- } ++ if (!sdn) ++ sdn = new; + +- if (!sdn) +- sdn = new; +- } ++ co = co->next; + } ++ pthread_mutex_unlock(&conf_mutex); + +- fclose(f); + return sdn; + } + +@@ -436,25 +879,26 @@ struct ldap_schema *defaults_get_schema(void) + { + struct ldap_schema *schema; + char *mc, *ma, *ec, *ea, *va; ++ const char *sec = autofs_gbl_sec; + +- mc = get_env_string(ENV_NAME_MAP_OBJ_CLASS); ++ mc = conf_get_string(sec, NAME_MAP_OBJ_CLASS); + if (!mc) + return NULL; + +- ma = get_env_string(ENV_NAME_MAP_ATTR); ++ ma = conf_get_string(sec, NAME_MAP_ATTR); + if (!ma) { + free(mc); + return NULL; + } + +- ec = get_env_string(ENV_NAME_ENTRY_OBJ_CLASS); ++ ec = conf_get_string(sec, NAME_ENTRY_OBJ_CLASS); + if (!ec) { + free(mc); + free(ma); + return NULL; + } + +- ea = get_env_string(ENV_NAME_ENTRY_ATTR); ++ ea = conf_get_string(sec, NAME_ENTRY_ATTR); + if (!ea) { + free(mc); + free(ma); +@@ -462,7 +906,7 @@ struct ldap_schema *defaults_get_schema(void) + return NULL; + } + +- va = get_env_string(ENV_NAME_VALUE_ATTR); ++ va = conf_get_string(sec, NAME_VALUE_ATTR); + if (!va) { + free(mc); + free(ma); +@@ -491,72 +935,9 @@ struct ldap_schema *defaults_get_schema(void) + } + #endif + +-/* +- * Read config env variables and check they have been set. +- * +- * This simple minded routine assumes the config file +- * is valid bourne shell script without spaces around "=" +- * and that it has valid values. +- */ +-unsigned int defaults_read_config(unsigned int to_syslog) +-{ +- FILE *f; +- char buf[MAX_LINE_LEN]; +- char *res; +- +- f = open_fopen_r(DEFAULTS_CONFIG_FILE); +- if (!f) +- return 0; +- +- while ((res = fgets(buf, MAX_LINE_LEN, f))) { +- char *key, *value; +- +- if (!parse_line(res, &key, &value)) +- continue; +- +- if (check_set_config_value(key, ENV_NAME_MASTER_MAP, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_TIMEOUT, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_NEGATIVE_TIMEOUT, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_BROWSE_MODE, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_LOGGING, value, to_syslog) || +- check_set_config_value(key, ENV_LDAP_TIMEOUT, value, to_syslog) || +- check_set_config_value(key, ENV_LDAP_NETWORK_TIMEOUT, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_MAP_OBJ_CLASS, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_ENTRY_OBJ_CLASS, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_MAP_ATTR, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_ENTRY_ATTR, value, to_syslog) || +- check_set_config_value(key, ENV_NAME_VALUE_ATTR, value, to_syslog) || +- check_set_config_value(key, ENV_APPEND_OPTIONS, value, to_syslog) || +- check_set_config_value(key, ENV_MOUNT_WAIT, value, to_syslog) || +- check_set_config_value(key, ENV_UMOUNT_WAIT, value, to_syslog) || +- check_set_config_value(key, ENV_AUTH_CONF_FILE, value, to_syslog) || +- check_set_config_value(key, ENV_MAP_HASH_TABLE_SIZE, value, to_syslog) || +- check_set_config_value(key, ENV_MOUNT_NFS_DEFAULT_PROTOCOL, value, to_syslog)) +- ; +- } +- +- if (!feof(f) || ferror(f)) { +- if (!to_syslog) { +- fprintf(stderr, +- "fgets returned error %d while reading %s\n", +- ferror(f), DEFAULTS_CONFIG_FILE); +- } else { +- logmsg("fgets returned error %d while reading %s", +- ferror(f), DEFAULTS_CONFIG_FILE); +- } +- fclose(f); +- return 0; +- } +- +- fclose(f); +- return 1; +-} +- + const char *defaults_get_master_map(void) + { +- char *master; +- +- master = get_env_string(ENV_NAME_MASTER_MAP); ++ char *master = conf_get_string(autofs_gbl_sec, NAME_MASTER_MAP); + if (!master) + return strdup(default_master_map_name); + +@@ -565,20 +946,23 @@ const char *defaults_get_master_map(void) + + int defaults_master_set(void) + { +- char *val = getenv(ENV_NAME_MASTER_MAP); +- if (!val) +- return 0; ++ struct conf_option *co; + +- return 1; ++ pthread_mutex_lock(&conf_mutex); ++ co = conf_lookup(autofs_gbl_sec, NAME_MASTER_MAP); ++ pthread_mutex_unlock(&conf_mutex); ++ if (co) ++ return 1; ++ return 0; + } + + unsigned int defaults_get_timeout(void) + { + long timeout; + +- timeout = get_env_number(ENV_NAME_TIMEOUT); ++ timeout = conf_get_number(autofs_gbl_sec, NAME_TIMEOUT); + if (timeout < 0) +- timeout = DEFAULT_TIMEOUT; ++ timeout = atol(DEFAULT_TIMEOUT); + + return (unsigned int) timeout; + } +@@ -587,9 +971,9 @@ unsigned int defaults_get_negative_timeout(void) + { + long n_timeout; + +- n_timeout = get_env_number(ENV_NAME_NEGATIVE_TIMEOUT); ++ n_timeout = conf_get_number(autofs_gbl_sec, NAME_NEGATIVE_TIMEOUT); + if (n_timeout <= 0) +- n_timeout = DEFAULT_NEGATIVE_TIMEOUT; ++ n_timeout = atol(DEFAULT_NEGATIVE_TIMEOUT); + + return (unsigned int) n_timeout; + } +@@ -598,9 +982,9 @@ unsigned int defaults_get_browse_mode(void) + { + int res; + +- res = get_env_yesno(ENV_NAME_BROWSE_MODE); ++ res = conf_get_yesno(autofs_gbl_sec, NAME_BROWSE_MODE); + if (res < 0) +- res = DEFAULT_BROWSE_MODE; ++ res = atoi(DEFAULT_BROWSE_MODE); + + return res; + } +@@ -608,14 +992,14 @@ unsigned int defaults_get_browse_mode(void) + unsigned int defaults_get_logging(void) + { + char *res; +- unsigned int logging = DEFAULT_LOGGING; ++ unsigned int logging = LOGOPT_NONE; + +- res = get_env_string(ENV_NAME_LOGGING); ++ res = conf_get_string(autofs_gbl_sec, NAME_LOGGING); + if (!res) + return logging; + + if (!strcasecmp(res, "none")) +- logging = DEFAULT_LOGGING; ++ logging = LOGOPT_NONE; + else { + if (!strcasecmp(res, "verbose")) + logging |= LOGOPT_VERBOSE; +@@ -633,9 +1017,9 @@ unsigned int defaults_get_ldap_timeout(void) + { + int res; + +- res = get_env_number(ENV_LDAP_TIMEOUT); ++ res = conf_get_number(autofs_gbl_sec, NAME_LDAP_TIMEOUT); + if (res < 0) +- res = DEFAULT_LDAP_TIMEOUT; ++ res = atoi(DEFAULT_LDAP_TIMEOUT); + + return res; + } +@@ -644,20 +1028,20 @@ unsigned int defaults_get_ldap_network_timeout(void) + { + int res; + +- res = get_env_number(ENV_LDAP_NETWORK_TIMEOUT); ++ res = conf_get_number(autofs_gbl_sec, NAME_LDAP_NETWORK_TIMEOUT); + if (res < 0) +- res = DEFAULT_LDAP_NETWORK_TIMEOUT; ++ res = atoi(DEFAULT_LDAP_NETWORK_TIMEOUT); + + return res; + } + + unsigned int defaults_get_mount_nfs_default_proto(void) + { +- long proto; ++ int proto; + +- proto = get_env_number(ENV_MOUNT_NFS_DEFAULT_PROTOCOL); ++ proto = conf_get_number(autofs_gbl_sec, NAME_MOUNT_NFS_DEFAULT_PROTOCOL); + if (proto < 2 || proto > 4) +- proto = DEFAULT_NFS_MOUNT_PROTOCOL; ++ proto = atoi(DEFAULT_MOUNT_NFS_DEFAULT_PROTOCOL); + + return (unsigned int) proto; + } +@@ -666,9 +1050,9 @@ unsigned int defaults_get_append_options(void) + { + int res; + +- res = get_env_yesno(ENV_APPEND_OPTIONS); ++ res = conf_get_yesno(autofs_gbl_sec, NAME_APPEND_OPTIONS); + if (res < 0) +- res = DEFAULT_APPEND_OPTIONS; ++ res = atoi(DEFAULT_APPEND_OPTIONS); + + return res; + } +@@ -677,9 +1061,9 @@ unsigned int defaults_get_mount_wait(void) + { + long wait; + +- wait = get_env_number(ENV_MOUNT_WAIT); ++ wait = conf_get_number(autofs_gbl_sec, NAME_MOUNT_WAIT); + if (wait < 0) +- wait = DEFAULT_MOUNT_WAIT; ++ wait = atoi(DEFAULT_MOUNT_WAIT); + + return (unsigned int) wait; + } +@@ -688,9 +1072,9 @@ unsigned int defaults_get_umount_wait(void) + { + long wait; + +- wait = get_env_number(ENV_UMOUNT_WAIT); ++ wait = conf_get_number(autofs_gbl_sec, NAME_UMOUNT_WAIT); + if (wait < 0) +- wait = DEFAULT_UMOUNT_WAIT; ++ wait = atoi(DEFAULT_UMOUNT_WAIT); + + return (unsigned int) wait; + } +@@ -699,7 +1083,7 @@ const char *defaults_get_auth_conf_file(void) + { + char *cf; + +- cf = get_env_string(ENV_AUTH_CONF_FILE); ++ cf = conf_get_string(autofs_gbl_sec, NAME_AUTH_CONF_FILE); + if (!cf) + return strdup(default_auth_conf_file); + +@@ -710,9 +1094,9 @@ unsigned int defaults_get_map_hash_table_size(void) + { + long size; + +- size = get_env_number(ENV_MAP_HASH_TABLE_SIZE); ++ size = conf_get_number(autofs_gbl_sec, NAME_MAP_HASH_TABLE_SIZE); + if (size < 0) +- size = DEFAULT_MAP_HASH_TABLE_SIZE; ++ size = atoi(DEFAULT_MAP_HASH_TABLE_SIZE); + + return (unsigned int) size; + } diff --git a/SOURCES/autofs-5.0.9-amd-lookup-skip-sss-source-for-amd-lookups.patch b/SOURCES/autofs-5.0.9-amd-lookup-skip-sss-source-for-amd-lookups.patch new file mode 100644 index 0000000..041d465 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-skip-sss-source-for-amd-lookups.patch @@ -0,0 +1,41 @@ +autofs-5.0.9 - amd-lookup skip sss source for amd lookups + +From: Ian Kent + +Looks like we won't be able to provide sss as a map source for +amd maps. There's no way to tell sss to use a different schema +for different map formats. +--- + daemon/lookup.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -636,6 +636,13 @@ int lookup_nss_read_map(struct autofs_po + list_for_each(p, head) { + this = list_entry(p, struct nss_source, list); + ++ if (map->flags & MAP_FLAG_FORMAT_AMD && ++ !strcmp(this->source, "sss")) { ++ warn(ap->logopt, ++ "source sss is not available for amd maps."); ++ continue; ++ } ++ + debug(ap->logopt, + "reading map %s %s", this->source, map->argv[0]); + +@@ -1164,6 +1171,13 @@ int lookup_nss_mount(struct autofs_point + list_for_each(p, head) { + this = list_entry(p, struct nss_source, list); + ++ if (map->flags & MAP_FLAG_FORMAT_AMD && ++ !strcmp(this->source, "sss")) { ++ warn(ap->logopt, ++ "source sss is not available for amd maps."); ++ continue; ++ } ++ + result = lookup_map_name(this, ap, map, name, name_len); + + if (result == NSS_STATUS_UNKNOWN) diff --git a/SOURCES/autofs-5.0.9-amd-lookup-split-config-into-init-and-config-settings.patch b/SOURCES/autofs-5.0.9-amd-lookup-split-config-into-init-and-config-settings.patch new file mode 100644 index 0000000..bb5293f --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-split-config-into-init-and-config-settings.patch @@ -0,0 +1,809 @@ +autofs-5.0.9 - amd lookup split config into init and config settings + +From: Ian Kent + +Split the configuration into program and init time configuration files. +The bulk of the configuration is now in the daemon configuration file +in /etc/autofs.conf by default. + +The daemon configuration names are now lower case but in reality are +(and have always been) case insensitive. + +Also, read the old configuration from the old configuration location +after reading the new configuration to ensure that people updating +don't get a surprize if they don't update the existing setup they +have. Note that this means that if the old configuration isn't updated +changes made in the new configuration will be overridden by the old. +--- + autofs.spec | 2 + lib/defaults.c | 22 ++++++ + man/auto.master.5.in | 39 ++++++----- + redhat/Makefile | 6 - + redhat/autofs.conf.default.in | 131 ++++++++++++++++++++++++++++++++++++++ + redhat/autofs.sysconfig | 14 ++++ + redhat/autofs.sysconfig.in | 138 ----------------------------------------- + samples/Makefile | 44 ++++++++++--- + samples/autofs.conf.default.in | 109 +++++++++++++++----------------- + samples/autofs.init.conf | 14 ++++ + 10 files changed, 293 insertions(+), 226 deletions(-) + create mode 100644 redhat/autofs.conf.default.in + create mode 100644 redhat/autofs.sysconfig + delete mode 100644 redhat/autofs.sysconfig.in + create mode 100644 samples/autofs.init.conf + +--- autofs-5.0.7.orig/autofs.spec ++++ autofs-5.0.7/autofs.spec +@@ -117,6 +117,7 @@ install -m 644 redhat/autofs.service $RP + install -m 755 redhat/autofs.init $RPM_BUILD_ROOT/etc/rc.d/init.d/autofs + %define init_file_name /etc/rc.d/init.d/autofs + %endif ++install -m 644 redhat/autofs.conf $RPM_BUILD_ROOT/etc/autofs.conf + install -m 644 redhat/autofs.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/autofs + + %clean +@@ -176,6 +177,7 @@ fi + %doc CREDITS CHANGELOG INSTALL COPY* README* samples/ldap* samples/autofs.schema samples/autofs_ldap_auth.conf + %config %{init_file_name} + %config(noreplace) /etc/auto.master ++%config(noreplace) /etc/autofs.conf + %config(noreplace,missingok) /etc/auto.misc + %config(noreplace,missingok) /etc/auto.net + %config(noreplace,missingok) /etc/auto.smb +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -33,7 +33,14 @@ + #define AUTOFS_GLOBAL_SECTION "autofs" + #define AMD_GLOBAL_SECTION "amd" + +-#define DEFAULT_CONFIG_FILE AUTOFS_CONF_DIR "/autofs" ++/* ++ * The configuration location has changed. ++ * The name of the configuration is now autofs.conf and it is ++ * located in the same directory as the maps. AUTOFS_CONF_DIR ++ * remains pointed at the init system configuration. ++ */ ++#define DEFAULT_CONFIG_FILE AUTOFS_MAP_DIR "/autofs.conf" ++#define OLD_CONFIG_FILE AUTOFS_CONF_DIR "/autofs" + #define MAX_LINE_LEN 256 + #define MAX_SECTION_NAME MAX_LINE_LEN + +@@ -965,6 +972,19 @@ unsigned int defaults_read_config(unsign + + fclose(f); + ++ /* ++ * Try to read the old config file and override the installed ++ * defaults in case user has a stale config following updating ++ * to the new config file location. ++ */ ++ ++ f = open_fopen_r(OLD_CONFIG_FILE); ++ if (!f) ++ goto out; ++ ++ read_config(to_syslog, f, OLD_CONFIG_FILE); ++ ++ fclose(f); + out: + pthread_mutex_unlock(&conf_mutex); + return 1; +--- autofs-5.0.7.orig/man/auto.master.5.in ++++ autofs-5.0.7/man/auto.master.5.in +@@ -214,44 +214,44 @@ configuration file + .hy + They are: + .TP +-.B TIMEOUT ++.B timeout + Sets the default mount timeout in seconds. The internal program + default is 10 minutes, but the default installed configuration + overrides this and sets the timeout to 5 minutes to be consistent + with earlier autofs releases. + .TP +-.B NEGATIVE_TIMEOUT ++.B negative_timeout + Set the default timeout for caching failed key lookups (program default + 60). If the equivalent command line option is given it will override this + setting. + .TP +-.B MOUNT_WAIT ++.B mount_wait + Set the default time to wait for a response from a spawned mount(8) + before sending it a SIGTERM. Note that we still need to wait for the + RPC layer to timeout before the sub-process exits so this isn't ideal + but it is the best we can do. The default is to wait until mount(8) + returns without intervention. + .TP +-.B UMOUNT_WAIT ++.B umount_wait + Set the default time to wait for a response from a spawned umount(8) + before sending it a SIGTERM. Note that we still need to wait for the + RPC layer to timeout before the sub-process exits so this isn't ideal + but it is the best we can do. + .TP +-.B BROWSE_MODE ++.B browse_mode + Maps are browsable by default (program default "yes"). + .TP +-.B MOUNT_NFS_DEFAULT_PROTOCOL ++.B mount_nfs_default_protocol + Specify the default protocol used by mount.nfs(8) (program default 3). Since + we can't identify this default automatically we need to set it in the autofs + configuration. + .TP +-.B APPEND_OPTIONS ++.B append_options + Determine whether global options, given on the command line or per mount + in the master map, are appended to map entry options or if the map entry + options replace the global options (program default "yes", append options). + .TP +-.B LOGGING ++.B logging + set default log level "none", "verbose" or "debug" (program default "none"). + .SH BUILTIN MAP -hosts + If "-hosts" is given as the map then accessing a key under the mount point +@@ -317,15 +317,15 @@ values must be set, any partial schema s + .P + The configuration settings available are: + .TP +-.B LDAP_TIMEOUT ++.B ldap_timeout + Set the network response timeout (default 8). + Set timeout value for the synchronous API calls. The default is the LDAP + library default of an infinite timeout. + .TP +-.B LDAP_NETWORK_TIMEOUT ++.B ldap_network_timeout + Set the network response timeout (default 8). + .TP +-.B LDAP_URI ++.B ldap_uri + A space seperated list of server uris of the form ://[/] + where can be ldap or ldaps. The option can be given multiple times. + Map entries that include a server name override this option and it is then +@@ -341,34 +341,34 @@ SRV RR lookup. The server list returned + according to the minimum ttl found in the SRV RR records or after one hour, + whichever is less. + .TP +-.B SEARCH_BASE ++.B search_base + The base dn to use when searching for amap base dn. This entry may be + given multiple times and each will be checked for a map base dn in + the order they occur in the configuration. The search base list is read + at startup and whenever the daemon recieves a HUP signal. + .TP +-.B MAP_OBJECT_CLASS ++.B map_object_class + The map object class. In the \fBnisMap\fP schema this corresponds to the class + \fBnisMap\fP and in the \fBautomountMap\fP schema it corresponds to the class + \fBautomountMap\fP. + .TP +-.B ENTRY_OBJECT_CLASS ++.B entry_object_class + The map entry object class. In the \fBnisMap\fP schema this corresponds + to the class \fBnisObject\fP and in the \fBautomountMap\fP schema it + corresponds to the class \fBautomount\fP. + .TP +-.B MAP_ATTRIBUTE ++.B map_attribute + The attribute used to identify the name of the map to which this + entry belongs. In the \fBnisMap\fP schema this corresponds to the attribute + \fBnisMapName\fP and in the \fBautomountMap\fP schema it corresponds to the + attribute \fBou\fP or \fBautomountMapName\fP. + .TP +-.B ENTRY_ATTRIBUTE ++.B entry_attribute + The attribute used to identify a map key. In the \fBnisMap\fP schema this + corresponds to the attribute \fBcn\fP and in the \fBautomountMap\fP schema + it corresponds to the attribute \fBautomountKey\fP. + .TP +-.B VALUE_ATTRIBUTE ++.B value_attribute + The attribute used to identify the value of the map entry. In the \fBnisMap\fP + schema this corresponds to the attribute \fBnisMapEntry\fP and in the \fBautomountMap\fP + schema it corresponds to the attribute \fBautomountInformation\fP. +@@ -386,6 +386,11 @@ settings. The default location of this + .nh + .BR @@autofsmapdir@@/autofs_ldap_auth.conf . + .hy ++.TP ++.B auth_conf_file ++This configuration option may be used to specify an alternate location ++for the ldap authentication file ++.P + If this file exists it will be used to establish whether TLS or authentication + should be used. + .P +--- autofs-5.0.7.orig/redhat/Makefile ++++ autofs-5.0.7/redhat/Makefile +@@ -2,7 +2,7 @@ + -include ../Makefile.conf + include ../Makefile.rules + +-all: autofs.init autofs.sysconfig autofs.service ++all: autofs.init autofs.conf autofs.service + + autofs.init: autofs.init.in + sed -e "s|@@sbindir@@|$(sbindir)|g" \ +@@ -11,9 +11,9 @@ autofs.init: autofs.init.in + -e "s|@@autofspiddir@@|$(autofspiddir)|g" \ + -e "s|@@initdir@@|$(initdir)|g" < autofs.init.in > autofs.init + +-autofs.sysconfig: autofs.sysconfig.in ++autofs.conf: autofs.conf.default.in + sed -e "s|@@autofsmapdir@@|$(autofsmapdir)|g" \ +- < autofs.sysconfig.in > autofs.sysconfig ++ < autofs.conf.default.in > autofs.conf + + autofs.service: ../samples/autofs.service.in + sed -e "s|@@sbindir@@|$(sbindir)|g" \ +--- /dev/null ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -0,0 +1,131 @@ ++# ++# Define default options for autofs. ++# ++[ autofs ] ++# ++# master_map_name - default map name for the master map. ++# ++#master_map_name = auto.master ++# ++# timeout - set the default mount timeout in secons. The internal ++# program default is 10 minutes, but the default installed ++# configuration overrides this and sets the timeout to 5 ++# minutes to be consistent with earlier autofs releases. ++# ++timeout = 300 ++# ++# negative_timeout - set the default negative timeout for ++# failed mount attempts (default 60). ++# ++#negative_timeout = 60 ++# ++# mount_wait - time to wait for a response from mount(8). ++# Setting this timeout can cause problems when ++# mount would otherwise wait for a server that ++# is temporarily unavailable, such as when it's ++# restarting. The default setting (-1) of waiting ++# for mount(8) usually results in a wait of around ++# 3 minutes. ++# ++#mount_wait = -1 ++# ++# umount_wait - time to wait for a response from umount(8). ++# ++#umount_wait = 12 ++# ++# browse_mode - maps are browsable by default. ++# ++browse_mode = no ++# ++# mount_nfs_default_protocol - specify the default protocol used by ++# mount.nfs(8). Since we can't identify ++# the default automatically we need to ++# set it in our configuration. ++# ++#mount_nfs_default_protocol = 3 ++mount_nfs_default_protocol = 4 ++# ++# append_options - append to global options instead of replace. ++# ++#append_options = yes ++# ++# logging - set default log level "none", "verbose" or "debug" ++# ++#logging = none ++# ++# Define base dn for map dn lookup. ++# ++# Define server URIs ++# ++# ldap_uri - space seperated list of server uris of the form ++# ://[/] where can be ldap ++# or ldaps. The option can be given multiple times. ++# Map entries that include a server name override ++# this option. ++# ++# This configuration option can also be used to ++# request autofs lookup SRV RRs for a domain of ++# the form :///[]. Note that a ++# trailing "/" is not allowed when using this form. ++# If the domain dn is not specified the dns domain ++# name (if any) is used to construct the domain dn ++# for the SRV RR lookup. The server list returned ++# from an SRV RR lookup is refreshed according to ++# the minimum ttl found in the SRV RR records or ++# after one hour, whichever is less. ++# ++#ldap_uri = "" ++# ++# ldap_timeout - timeout value for the synchronous API calls ++# (default is LDAP library default). ++# ++#ldap_timeout = -1 ++# ++# ldap_network_timeout - set the network response timeout (default 8). ++# ++#ldap_network_timeout = 8 ++# ++# search_base - base dn to use for searching for map search dn. ++# Multiple entries can be given and they are checked ++# in the order they occur here. ++# ++#search_base = "" ++# ++# Define the LDAP schema to used for lookups ++# ++# If no schema is set autofs will check each of the schemas ++# below in the order given to try and locate an appropriate ++# basdn for lookups. If you want to minimize the number of ++# queries to the server set the values here. ++# ++#map_object_class = nisMap ++#entry_object_class = nisObject ++#map_attribute = nisMapName ++#entry_attribute = cn ++#value_attribute= nisMapEntry ++# ++# Other common LDAP nameing ++# ++#map_object_class = automountMap ++#entry_object_class = automount ++#map_attribute = ou ++#entry_attribute = cn ++#value_attribute= automountInformation ++# ++#map_object_class = automountMap ++#entry_object_class = automount ++#map_attribute = automountMapName ++#entry_attribute = automountKey ++#value_attribute= automountInformation ++# ++# auth_conf_file - set the default location for the SASL ++# authentication configuration file. ++# ++#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. ++# ++#map_hash_table_size = 1024 ++# +--- /dev/null ++++ autofs-5.0.7/redhat/autofs.sysconfig +@@ -0,0 +1,14 @@ ++# ++# Init syatem options ++# ++# If the kernel supports using the autofs miscellanous device ++# and you wish to use it you must set this configuration option ++# to "yes" otherwise it will not be used. ++# ++USE_MISC_DEVICE="yes" ++# ++# Use OPTIONS to add automount(8) command line options that ++# will be used when the daemon is started. ++# ++#OPTIONS="" ++# +--- autofs-5.0.7.orig/redhat/autofs.sysconfig.in ++++ /dev/null +@@ -1,138 +0,0 @@ +-# +-# Define default options for autofs. +-# +-# MASTER_MAP_NAME - default map name for the master map. +-# +-#MASTER_MAP_NAME="auto.master" +-# +-# TIMEOUT - set the default mount timeout in secons. The internal +-# program default is 10 minutes, but the default installed +-# configuration overrides this and sets the timeout to 5 +-# minutes to be consistent with earlier autofs releases. +-# +-TIMEOUT=300 +-# +-# NEGATIVE_TIMEOUT - set the default negative timeout for +-# failed mount attempts (default 60). +-# +-#NEGATIVE_TIMEOUT=60 +-# +-# MOUNT_WAIT - time to wait for a response from mount(8). +-# Setting this timeout can cause problems when +-# mount would otherwise wait for a server that +-# is temporarily unavailable, such as when it's +-# restarting. The default setting (-1) of waiting +-# for mount(8) usually results in a wait of around +-# 3 minutes. +-# +-#MOUNT_WAIT=-1 +-# +-# UMOUNT_WAIT - time to wait for a response from umount(8). +-# +-#UMOUNT_WAIT=12 +-# +-# BROWSE_MODE - maps are browsable by default. +-# +-BROWSE_MODE="no" +-# +-# MOUNT_NFS_DEFAULT_PROTOCOL - specify the default protocol used by +-# mount.nfs(8). Since we can't identify +-# the default automatically we need to +-# set it in our configuration. +-# +-#MOUNT_NFS_DEFAULT_PROTOCOL=3 +-MOUNT_NFS_DEFAULT_PROTOCOL=4 +-# +-# APPEND_OPTIONS - append to global options instead of replace. +-# +-#APPEND_OPTIONS="yes" +-# +-# LOGGING - set default log level "none", "verbose" or "debug" +-# +-#LOGGING="none" +-# +-# Define base dn for map dn lookup. +-# +-# Define server URIs +-# +-# LDAP_URI - space seperated list of server uris of the form +-# ://[/] where can be ldap +-# or ldaps. The option can be given multiple times. +-# Map entries that include a server name override +-# this option. +-# +-# This configuration option can also be used to +-# request autofs lookup SRV RRs for a domain of +-# the form :///[]. Note that a +-# trailing "/" is not allowed when using this form. +-# If the domain dn is not specified the dns domain +-# name (if any) is used to construct the domain dn +-# for the SRV RR lookup. The server list returned +-# from an SRV RR lookup is refreshed according to +-# the minimum ttl found in the SRV RR records or +-# after one hour, whichever is less. +-# +-#LDAP_URI="" +-# +-# LDAP__TIMEOUT - timeout value for the synchronous API calls +-# (default is LDAP library default). +-# +-#LDAP_TIMEOUT=-1 +-# +-# LDAP_NETWORK_TIMEOUT - set the network response timeout (default 8). +-# +-#LDAP_NETWORK_TIMEOUT=8 +-# +-# SEARCH_BASE - base dn to use for searching for map search dn. +-# Multiple entries can be given and they are checked +-# in the order they occur here. +-# +-#SEARCH_BASE="" +-# +-# Define the LDAP schema to used for lookups +-# +-# If no schema is set autofs will check each of the schemas +-# below in the order given to try and locate an appropriate +-# basdn for lookups. If you want to minimize the number of +-# queries to the server set the values here. +-# +-#MAP_OBJECT_CLASS="nisMap" +-#ENTRY_OBJECT_CLASS="nisObject" +-#MAP_ATTRIBUTE="nisMapName" +-#ENTRY_ATTRIBUTE="cn" +-#VALUE_ATTRIBUTE="nisMapEntry" +-# +-# Other common LDAP nameing +-# +-#MAP_OBJECT_CLASS="automountMap" +-#ENTRY_OBJECT_CLASS="automount" +-#MAP_ATTRIBUTE="ou" +-#ENTRY_ATTRIBUTE="cn" +-#VALUE_ATTRIBUTE="automountInformation" +-# +-#MAP_OBJECT_CLASS="automountMap" +-#ENTRY_OBJECT_CLASS="automount" +-#MAP_ATTRIBUTE="automountMapName" +-#ENTRY_ATTRIBUTE="automountKey" +-#VALUE_ATTRIBUTE="automountInformation" +-# +-# AUTH_CONF_FILE - set the default location for the SASL +-# authentication configuration file. +-# +-#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. +-# +-#MAP_HASH_TABLE_SIZE=1024 +-# +-# General global options +-# +-# If the kernel supports using the autofs miscellanous device +-# and you wish to use it you must set this configuration option +-# to "yes" otherwise it will not be used. +-USE_MISC_DEVICE="yes" +-# +-#OPTIONS="" +-# +--- autofs-5.0.7.orig/samples/Makefile ++++ autofs-5.0.7/samples/Makefile +@@ -4,7 +4,7 @@ include ../Makefile.rules + + SAMPLES = auto.master auto.misc auto.net auto.smb + +-all: rc.autofs autofs.conf.default autofs.service ++all: rc.autofs autofs.conf.default autofs.init.conf autofs.service + + rc.autofs: rc.autofs.in + sed -e "s|@@sbindir@@|$(sbindir)|g" \ +@@ -46,26 +46,52 @@ else + endif + endif + +-CONFIG = $(shell test -e $(INSTALLROOT)$(autofsconfdir)/autofs.orig || echo "-b --suffix=.orig") +-CEXISTS = $(shell test -e $(INSTALLROOT)$(autofsconfdir)/autofs || echo "no") ++# ++# The map directory contains the main autofs configuration ... ++# ++CONFIG = $(shell test -e $(INSTALLROOT)$(autofsmapdir)/autofs.conf.orig || echo "-b --suffix=.orig") ++CEXISTS = $(shell test -e $(INSTALLROOT)$(autofsmapdir)/autofs || echo "no") + + .PHONY: autofs.conf + autofs.conf: autofs.conf.default + @echo +- @echo "Installing autofs default configuation in $(autofsconfdir)" ++ @echo "Installing autofs default configuation in $(autofsmapdir)" + @if test -z "$(CONFIG)" ; \ + then \ + install -v autofs.conf.default -m 644 \ +- $(INSTALLROOT)$(autofsconfdir)/autofs.conf.new ; \ ++ $(INSTALLROOT)$(autofsmapdir)/autofs.conf.new ; \ + echo "Found existing backup of configuration file." ; \ + echo "Installed package default configuration file as \"autofs.conf.new\"." ; \ + else \ + install -v autofs.conf.default -m 644 $(CONFIG) \ +- $(INSTALLROOT)$(autofsconfdir)/autofs ; \ +- echo "Installed package configuration configuration as \"autofs\"." ; \ ++ $(INSTALLROOT)$(autofsmapdir)/autofs.conf ; \ ++ echo "Installed package default configuration as \"autofs.conf\"." ; \ + if test -z "$(CEXISTS)" ; \ + then \ +- echo "Backup of existing configuration made to \"autofs.orig\"." ; \ ++ echo "Backup of existing configuration made to \"autofs.conf.orig\"." ; \ ++ fi ; \ ++ fi ++ ++CINIT = $(shell test -e $(INSTALLROOT)$(autofsconfdir)/autofs.orig || echo "-b --suffix=.orig") ++CIEXISTS = $(shell test -e $(INSTALLROOT)$(autofsconfdir)/autofs || echo "no") ++ ++.PHONY: autofs.sysinit ++autofs.sysinit: autofs.init.conf ++ @echo ++ @echo "Installing autofs init configuation in $(autofsconfdir)" ++ @if test -z "$(CINIT)" ; \ ++ then \ ++ install -v autofs.init.conf -m 644 \ ++ $(INSTALLROOT)$(autofsconfdir)/autofs.new ; \ ++ echo "Found existing backup of init configuration file." ; \ ++ echo "Installed package init configuration file as \"autofs.new\"." ; \ ++ else \ ++ install -v autofs.init.conf -m 644 $(CINIT) \ ++ $(INSTALLROOT)$(autofsconfdir)/autofs ; \ ++ echo "Installed package init configuration as \"autofs\"." ; \ ++ if test -z "$(CIEXISTS)" ; \ ++ then \ ++ echo "Backup of existing init configuration made to \"autofs.orig\"." ; \ + fi ; \ + fi + +@@ -185,7 +211,7 @@ auto.smb: + fi + + install: rc.autofs autofs.conf.default dirs autofs.init autofs.service \ +- autofs.conf autofs_ldap_auth.conf $(SAMPLES) ++ autofs.conf autofs.sysinit autofs_ldap_auth.conf $(SAMPLES) + @echo + + clean: +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -1,23 +1,25 @@ + # + # Define default options for autofs. + # +-# MASTER_MAP_NAME - default map name for the master map. ++[ autofs ] + # +-#MASTER_MAP_NAME="auto.master" ++# master_map_name - default map name for the master map. + # +-# TIMEOUT - set the default mount timeout in secons. The internal ++#master_map_name = auto.master ++# ++# timeout - set the default mount timeout in secons. The internal + # program default is 10 minutes, but the default installed + # configuration overrides this and sets the timeout to 5 + # minutes to be consistent with earlier autofs releases. + # +-TIMEOUT=300 ++timeout = 300 + # +-# NEGATIVE_TIMEOUT - set the default negative timeout for ++# negative_timeout - set the default negative timeout for + # failed mount attempts (default 60). + # +-#NEGATIVE_TIMEOUT=60 ++#negative_timeout = 60 + # +-# MOUNT_WAIT - time to wait for a response from mount(8). ++# mount_wait - time to wait for a response from mount(8). + # Setting this timeout can cause problems when + # mount would otherwise wait for a server that + # is temporarily unavailable, such as when it's +@@ -25,34 +27,36 @@ TIMEOUT=300 + # for mount(8) usually results in a wait of around + # 3 minutes. + # +-#MOUNT_WAIT=-1 ++#mount_wait = -1 + # +-# UMOUNT_WAIT - time to wait for a response from umount(8). ++# umount_wait - time to wait for a response from umount(8). + # +-#UMOUNT_WAIT=12 ++#umount_wait = 12 + # +-# BROWSE_MODE - maps are browsable by default. ++# browse_mode - maps are browsable by default. + # +-BROWSE_MODE="no" ++browse_mode = no + # +-# MOUNT_NFS_DEFAULT_PROTOCOL - specify the default protocol used by ++# mount_nfs_default_protocol - specify the default protocol used by + # mount.nfs(8). Since we can't identify + # the default automatically we need to + # set it in our configuration. + # +-#MOUNT_NFS_DEFAULT_PROTOCOL=3 ++#mount_nfs_default_protocol = 3 ++# ++# append_options - append to global options instead of replace. + # +-# APPEND_OPTIONS - append to global options instead of replace. ++#append_options = yes + # +-#APPEND_OPTIONS="yes" ++# logging - set default log level "none", "verbose" or "debug" + # +-# LOGGING - set default log level "none", "verbose" or "debug" ++#logging = none + # +-#LOGGING="none" ++# Define base dn for map dn lookup. + # + # Define server URIs + # +-# LDAP_URI - space seperated list of server uris of the form ++# ldap_uri - space seperated list of server uris of the form + # ://[/] where can be ldap + # or ldaps. The option can be given multiple times. + # Map entries that include a server name override +@@ -69,24 +73,22 @@ BROWSE_MODE="no" + # the minimum ttl found in the SRV RR records or + # after one hour, whichever is less. + # +-#LDAP_URI="" ++#ldap_uri = "" + # +-# LDAP__TIMEOUT - timeout value for the synchronous API calls ++# ldap_timeout - timeout value for the synchronous API calls + # (default is LDAP library default). + # +-#LDAP_TIMEOUT=-1 +-# +-# LDAP_NETWORK_TIMEOUT - set the network response timeout (default 8). ++#ldap_timeout = -1 + # +-#LDAP_NETWORK_TIMEOUT=8 ++# ldap_network_timeout - set the network response timeout (default 8). + # +-# Define base dn for map dn lookup. ++#ldap_network_timeout = 8 + # +-# SEARCH_BASE - base dn to use for searching for map search dn. ++# search_base - base dn to use for searching for map search dn. + # Multiple entries can be given and they are checked + # in the order they occur here. + # +-#SEARCH_BASE="" ++#search_base = "" + # + # Define the LDAP schema to used for lookups + # +@@ -95,43 +97,34 @@ BROWSE_MODE="no" + # basdn for lookups. If you want to minimize the number of + # queries to the server set the values here. + # +-#MAP_OBJECT_CLASS="nisMap" +-#ENTRY_OBJECT_CLASS="nisObject" +-#MAP_ATTRIBUTE="nisMapName" +-#ENTRY_ATTRIBUTE="cn" +-#VALUE_ATTRIBUTE="nisMapEntry" ++#map_object_class = nisMap ++#entry_object_class = nisObject ++#map_attribute = nisMapName ++#entry_attribute = cn ++#value_attribute= nisMapEntry + # + # Other common LDAP nameing + # +-#MAP_OBJECT_CLASS="automountMap" +-#ENTRY_OBJECT_CLASS="automount" +-#MAP_ATTRIBUTE="ou" +-#ENTRY_ATTRIBUTE="cn" +-#VALUE_ATTRIBUTE="automountInformation" +-# +-#MAP_OBJECT_CLASS="automountMap" +-#ENTRY_OBJECT_CLASS="automount" +-#MAP_ATTRIBUTE="automountMapName" +-#ENTRY_ATTRIBUTE="automountKey" +-#VALUE_ATTRIBUTE="automountInformation" ++#map_object_class = automountMap ++#entry_object_class = automount ++#map_attribute = ou ++#entry_attribute = cn ++#value_attribute= automountInformation ++# ++#map_object_class = automountMap ++#entry_object_class = automount ++#map_attribute = automountMapName ++#entry_attribute = automountKey ++#value_attribute= automountInformation + # +-# AUTH_CONF_FILE - set the default location for the SASL +-# authentication configuration file. ++# auth_conf_file - set the default location for the SASL ++# authentication configuration file. + # +-#AUTH_CONF_FILE="@@autofsmapdir@@/autofs_ldap_auth.conf" ++#auth_conf_file = @@autofsmapdir@@/autofs_ldap_auth.conf + # +-# MAP_HASH_TABLE_SIZE - set the map cache hash table size. ++# 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. + # +-#MAP_HASH_TABLE_SIZE=1024 +-# +-# General global options +-# +-# If the kernel supports using the autofs miscellanous device +-# and you wish to use it you must set this configuration option +-# to "yes" otherwise it will not be used. +-USE_MISC_DEVICE="yes" +-# +-#OPTIONS="" ++#map_hash_table_size = 1024 + # +--- /dev/null ++++ autofs-5.0.7/samples/autofs.init.conf +@@ -0,0 +1,14 @@ ++# ++# Init syatem options ++# ++# If the kernel supports using the autofs miscellanous device ++# and you wish to use it you must set this configuration option ++# to "yes" otherwise it will not be used. ++# ++USE_MISC_DEVICE="yes" ++# ++# Use OPTIONS to add automount(8) command line options that ++# will be used when the daemon is started. ++# ++#OPTIONS="" ++# diff --git a/SOURCES/autofs-5.0.9-amd-lookup-try-to-use-external-mounts-for-nfs-mounts.patch b/SOURCES/autofs-5.0.9-amd-lookup-try-to-use-external-mounts-for-nfs-mounts.patch new file mode 100644 index 0000000..dc52861 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-try-to-use-external-mounts-for-nfs-mounts.patch @@ -0,0 +1,38 @@ +autofs-5.0.9 - amd lookup try to use external mounts for nfs mounts + +From: Ian Kent + +When using nfs type mounts they may be mounted externally to avoid +multiple instances of the mount. + +The current usage doesn't always use external mounts when it can so, +if option fs is defined, use an external. +--- + modules/parse_amd.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 0c708e6..becc519 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1011,7 +1011,7 @@ static int do_nfs_mount(struct autofs_point *ap, const char *name, + if (proximity == PROXIMITY_OTHER && entry->remopts) + opts = entry->remopts; + +- if (!entry->sublink) { ++ if (!entry->fs) { + ret = mount_nfs->mount_mount(ap, ap->path, name, strlen(name), + target, entry->type, opts, + mount_nfs->context); +@@ -1214,6 +1214,11 @@ static unsigned int validate_nfs_options(unsigned int logopt, + return 0; + } + } ++ if (entry->sublink && !entry->fs) { ++ error(logopt, MODPREFIX ++ "%s: sublink option requires option fs"); ++ return 0; ++ } + return 1; + } + diff --git a/SOURCES/autofs-5.0.9-amd-lookup-try-to-use-external-mounts-for-real-mounts.patch b/SOURCES/autofs-5.0.9-amd-lookup-try-to-use-external-mounts-for-real-mounts.patch new file mode 100644 index 0000000..5904ba9 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-try-to-use-external-mounts-for-real-mounts.patch @@ -0,0 +1,47 @@ +autofs-5.0.9 - amd lookup try to use external mounts for real mounts + +From: Ian Kent + +When using generic type mounts they may point to user mounted +external mounts which doesn't need to be mounted or umounted. + +The current usage doesn't always use external mounts which isn't +quite right so, if option fs is defined use, an external. +--- + modules/parse_amd.c | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 410f6ff..790f25e 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -970,7 +970,7 @@ static int do_generic_mount(struct autofs_point *ap, const char *name, + unsigned int umount = 0; + int ret = 0; + +- if (!entry->sublink) { ++ if (!entry->fs) { + ret = do_mount(ap, ap->path, name, strlen(name), + target, entry->type, entry->opts); + } else { +@@ -986,7 +986,7 @@ static int do_generic_mount(struct autofs_point *ap, const char *name, + goto out; + umount = 1; + } +- /* We might be using an external mount */ ++ /* We have an external mount */ + ext_mount_add(&entry->ext_mount, entry->fs, umount); + ret = do_link_mount(ap, name, entry, flags); + } +@@ -1237,6 +1237,11 @@ static unsigned int validate_generic_options(unsigned int logopt, + return 0; + } + } ++ if (entry->sublink && !entry->fs) { ++ error(logopt, MODPREFIX ++ "%s: sublink option requires option fs"); ++ return 0; ++ } + return 1; + } + diff --git a/SOURCES/autofs-5.0.9-amd-lookup-update-changelog.patch b/SOURCES/autofs-5.0.9-amd-lookup-update-changelog.patch new file mode 100644 index 0000000..c6e42aa --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-update-changelog.patch @@ -0,0 +1,19 @@ +autofs-5.0.9 - amd lookup update changelog + +From: Ian Kent + + +--- + CHANGELOG | 1 + + 1 file changed, 1 insertion(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -108,6 +108,7 @@ + - fix crash due to thread unsafe use of libldap. + - fix deadlock in init_ldap_connection. + - extend fix for crash due to thread unsafe use of libldap. ++- add amd map format parser. + + 25/07/2012 autofs-5.0.7 + ======================= diff --git a/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-file-to-handle-amd-keys.patch b/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-file-to-handle-amd-keys.patch new file mode 100644 index 0000000..07ca05b --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-file-to-handle-amd-keys.patch @@ -0,0 +1,410 @@ +autofs-5.0.9 - amd lookup update lookup file to handle amd keys + +From: Ian Kent + +Update file map lookup to handle map key matching for amd format +maps. +--- + modules/lookup_file.c | 287 +++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 206 insertions(+), 81 deletions(-) + +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 512e3ef..7c982c6 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -702,9 +702,22 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + } else { + char *s_key; + +- s_key = sanitize_path(key, k_len, ap->type, ap->logopt); +- if (!s_key) +- continue; ++ if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ if (!strcmp(key, "/defaults")) { ++ cache_writelock(mc); ++ cache_update(mc, source, key, mapent, age); ++ cache_unlock(mc); ++ continue; ++ } ++ /* Don't fail on "/" in key => type == 0 */ ++ s_key = sanitize_path(key, k_len, 0, ap->logopt); ++ if (!s_key) ++ continue; ++ } else { ++ s_key = sanitize_path(key, k_len, ap->type, ap->logopt); ++ if (!s_key) ++ continue; ++ } + + cache_writelock(mc); + cache_update(mc, source, s_key, mapent, age); +@@ -724,12 +737,75 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return NSS_STATUS_SUCCESS; + } + ++static int match_key(struct autofs_point *ap, ++ struct map_source *source, char *map_key, ++ const char *key, size_t key_len, const char *mapent) ++{ ++ char buf[MAX_ERR_BUF]; ++ struct mapent_cache *mc; ++ time_t age = time(NULL); ++ char *lkp_key; ++ char *prefix; ++ size_t map_key_len; ++ int ret, eq; ++ ++ mc = source->mc; ++ ++ /* exact match is a match for both autofs and amd */ ++ eq = strcmp(map_key, key); ++ if (eq == 0) { ++ cache_writelock(mc); ++ ret = cache_update(mc, source, key, mapent, age); ++ cache_unlock(mc); ++ return ret; ++ } ++ ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) ++ return CHE_FAIL; ++ ++ map_key_len = strlen(map_key); ++ ++ lkp_key = strdup(key); ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "strdup: %s", estr); ++ return CHE_FAIL; ++ } ++ ++ ret = CHE_FAIL; ++ ++ if (map_key_len > (strlen(lkp_key) + 2)) ++ goto done; ++ ++ /* ++ * Now strip successive directory components and try a ++ * match against map entries ending with a wildcard and ++ * finally try the wilcard entry itself. If we get a match ++ * then update the cache with the read key and its mapent. ++ */ ++ while ((prefix = strrchr(lkp_key, '/'))) { ++ size_t len; ++ *prefix = '\0'; ++ len = strlen(lkp_key); ++ eq = strncmp(map_key, lkp_key, len); ++ if (!eq && map_key[len + 1] == '*') { ++ cache_writelock(mc); ++ ret = cache_update(mc, source, map_key, mapent, age); ++ cache_unlock(mc); ++ goto done; ++ } ++ } ++done: ++ free(lkp_key); ++ return ret; ++} ++ + static int lookup_one(struct autofs_point *ap, + struct map_source *source, + const char *key, int key_len, + struct lookup_context *ctxt) + { +- struct mapent_cache *mc; ++ struct mapent_cache *mc = source->mc; + char mkey[KEY_MAX_LEN + 1]; + char mapent[MAPENT_MAX_LEN + 1]; + time_t age = time(NULL); +@@ -737,8 +813,6 @@ static int lookup_one(struct autofs_point *ap, + unsigned int k_len, m_len; + int entry, ret; + +- mc = source->mc; +- + f = open_fopen_r(ctxt->mapname); + if (!f) { + error(ap->logopt, +@@ -781,29 +855,38 @@ static int lookup_one(struct autofs_point *ap, + } + } else { + char *s_key; +- int eq; + +- s_key = sanitize_path(mkey, k_len, ap->type, ap->logopt); +- if (!s_key) +- continue; ++ if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ if (!strcmp(mkey, "/defaults")) { ++ cache_writelock(mc); ++ cache_update(mc, source, mkey, mapent, age); ++ cache_unlock(mc); ++ continue; ++ } ++ /* Don't fail on "/" in key => type == 0 */ ++ s_key = sanitize_path(mkey, k_len, 0, ap->logopt); ++ if (!s_key) ++ continue; ++ } else { ++ s_key = sanitize_path(mkey, k_len, ap->type, ap->logopt); ++ if (!s_key) ++ continue; + +- if (key_len != strlen(s_key)) { +- free(s_key); +- continue; ++ if (key_len != strlen(s_key)) { ++ free(s_key); ++ continue; ++ } + } + +- eq = strncmp(s_key, key, key_len); +- if (eq != 0) { ++ ret = match_key(ap, source, ++ s_key, key, key_len, mapent); ++ if (ret == CHE_FAIL) { + free(s_key); + continue; + } + + free(s_key); + +- cache_writelock(mc); +- ret = cache_update(mc, source, key, mapent, age); +- cache_unlock(mc); +- + fclose(f); + + return ret; +@@ -897,7 +980,10 @@ static int check_map_indirect(struct autofs_point *ap, + return NSS_STATUS_NOTFOUND; + + cache_writelock(mc); +- exists = cache_lookup_distinct(mc, key); ++ if (source->flags & MAP_FLAG_FORMAT_AMD) ++ exists = match_cached_key(ap, MODPREFIX, source, key); ++ else ++ exists = cache_lookup_distinct(mc, key); + /* Not found in the map but found in the cache */ + if (exists && exists->source == source && ret & CHE_MISSING) { + if (exists->mapent) { +@@ -936,6 +1022,53 @@ static int check_map_indirect(struct autofs_point *ap, + return NSS_STATUS_SUCCESS; + } + ++static int map_update_needed(struct autofs_point *ap, ++ struct map_source *source, ++ struct lookup_context * ctxt) ++{ ++ struct mapent_cache *mc; ++ struct mapent *me; ++ struct stat st; ++ int ret = 1; ++ ++ mc = source->mc; ++ ++ /* ++ * We can skip the map lookup and cache update altogether ++ * if we know the map hasn't been modified since it was ++ * last read. If it has then we can mark the map stale ++ * so a re-read is triggered following the lookup. ++ */ ++ if (stat(ctxt->mapname, &st)) { ++ error(ap->logopt, MODPREFIX ++ "file map %s, could not stat", ctxt->mapname); ++ return -1; ++ } ++ ++ cache_readlock(mc); ++ me = cache_lookup_first(mc); ++ if (me && st.st_mtime <= me->age) { ++ /* ++ * If any map instances are present for this source ++ * then either we have plus included entries or we ++ * are looking through the list of nsswitch sources. ++ * In either case, or if it's a "multi" source, we ++ * cannot avoid reading through the map because we ++ * must preserve the key order over multiple sources ++ * or maps. But also, we can't know, at this point, ++ * if a source instance has been changed since the ++ * last time we checked it. ++ */ ++ if (!source->instance && ++ source->type && strcmp(source->type, "multi")) ++ ret = 0; ++ } else ++ source->stale = 1; ++ cache_unlock(mc); ++ ++ return ret; ++} ++ + int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +@@ -944,8 +1077,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + struct mapent *me; + char key[KEY_MAX_LEN + 1]; + int key_len; ++ char *lkp_key; + char *mapent = NULL; + char mapent_buf[MAPENT_MAX_LEN + 1]; ++ char buf[MAX_ERR_BUF]; + int status = 0; + int ret = 1; + +@@ -967,9 +1102,18 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + debug(ap->logopt, MODPREFIX "looking up %s", name); + +- key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); +- if (key_len > KEY_MAX_LEN) +- return NSS_STATUS_NOTFOUND; ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { ++ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ } else { ++ key_len = expandamdent(name, NULL, NULL); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ memset(key, 0, KEY_MAX_LEN + 1); ++ expandamdent(name, key, NULL); ++ debug(ap->logopt, MODPREFIX "expanded key: \"%s\"", key); ++ } + + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, key, LKP_DISTINCT); +@@ -1003,50 +1147,35 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + * we never know about it. + */ + if (ap->type == LKP_INDIRECT && *key != '/') { +- struct stat st; +- char *lkp_key; ++ int ret; + +- /* +- * We can skip the map lookup and cache update altogether +- * if we know the map hasn't been modified since it was +- * last read. If it has then we can mark the map stale +- * so a re-read is triggered following the lookup. +- */ +- if (stat(ctxt->mapname, &st)) { +- error(ap->logopt, MODPREFIX +- "file map %s, could not stat", ctxt->mapname); +- return NSS_STATUS_UNAVAIL; +- } ++ ret = map_update_needed(ap, source, ctxt); ++ if (!ret) ++ goto do_cache_lookup; ++ /* Map isn't accessable, just try the cache */ ++ if (ret < 0) ++ goto do_cache_lookup; + + cache_readlock(mc); +- me = cache_lookup_first(mc); +- if (me && st.st_mtime <= me->age) { +- /* +- * If any map instances are present for this source +- * then either we have plus included entries or we +- * are looking through the list of nsswitch sources. +- * In either case, or if it's a "multi" source, we +- * cannot avoid reading through the map because we +- * must preserve the key order over multiple sources +- * or maps. But also, we can't know, at this point, +- * if a source instance has been changed since the +- * last time we checked it. +- */ +- if (!source->instance && +- source->type && strcmp(source->type, "multi")) +- goto do_cache_lookup; +- } else +- source->stale = 1; +- + me = cache_lookup_distinct(mc, key); + if (me && me->multi) + lkp_key = strdup(me->multi->key); +- else ++ else if (!ap->pref) + lkp_key = strdup(key); ++ else { ++ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1); ++ if (lkp_key) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, key); ++ } ++ } + cache_unlock(mc); + +- if (!lkp_key) ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); + return NSS_STATUS_UNKNOWN; ++ } + + status = check_map_indirect(ap, source, + lkp_key, strlen(lkp_key), ctxt); +@@ -1066,42 +1195,38 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + * when we're starting up so just take the readlock in that + * case. + */ ++do_cache_lookup: + if (ap->flags & MOUNT_FLAG_REMOUNT) + cache_readlock(mc); + else + cache_writelock(mc); +-do_cache_lookup: +- me = cache_lookup(mc, key); +- /* +- * Stale mapent => check for entry in alternate source or wildcard. +- * Note, plus included direct mount map entries are included as an +- * instance (same map entry cache), not in a distinct source. +- */ +- if (me && (!me->mapent || +- (me->source != source && *me->key != '/'))) { +- while ((me = cache_lookup_key_next(me))) +- if (me->source == source) +- break; +- if (!me) +- me = cache_lookup_distinct(mc, "*"); ++ ++ if (!ap->pref) ++ lkp_key = strdup(key); ++ else { ++ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1); ++ if (lkp_key) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, key); ++ } ++ } ++ ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ cache_unlock(mc); ++ return NSS_STATUS_UNKNOWN; + } ++ ++ me = match_cached_key(ap, MODPREFIX, source, lkp_key); + if (me && me->mapent) { +- /* +- * If this is a lookup add wildcard match for later validation +- * checks and negative cache lookups. +- */ +- if (!(ap->flags & MOUNT_FLAG_REMOUNT) && +- ap->type == LKP_INDIRECT && *me->key == '*') { +- ret = cache_update(mc, source, key, me->mapent, me->age); +- if (!(ret & (CHE_OK | CHE_UPDATED))) +- me = NULL; +- } + if (me && (me->source == source || *me->key == '/')) { + strcpy(mapent_buf, me->mapent); + mapent = mapent_buf; + } + } + cache_unlock(mc); ++ free(lkp_key); + + if (!me) + return NSS_STATUS_NOTFOUND; diff --git a/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-nisplus-to-handle-amd-keys.patch b/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-nisplus-to-handle-amd-keys.patch new file mode 100644 index 0000000..d88a8ea --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-nisplus-to-handle-amd-keys.patch @@ -0,0 +1,314 @@ +autofs-5.0.9 - amd lookup update lookup nisplus to handle amd keys + +From: Ian Kent + + +--- + modules/lookup_nisplus.c | 208 +++++++++++++++++++++++++++++++++++++++++++--- + 1 file changed, 196 insertions(+), 12 deletions(-) + +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 42c9ccc..e9444c9 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -243,7 +243,19 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + if (*key == '+') + continue; + +- s_key = sanitize_path(key, len, ap->type, ap->logopt); ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) ++ s_key = sanitize_path(key, len, ap->type, ap->logopt); ++ else { ++ if (!strcmp(key, "/defaults")) { ++ mapent = ENTRY_VAL(this, 1); ++ cache_writelock(mc); ++ cache_update(mc, source, key, mapent, age); ++ cache_unlock(mc); ++ continue; ++ } ++ /* Don't fail on "/" in key => type == 0 */ ++ s_key = sanitize_path(key, len, 0, ap->logopt); ++ } + if (!s_key) + continue; + +@@ -322,6 +334,66 @@ static int lookup_one(struct autofs_point *ap, + return ret; + } + ++static int match_key(struct autofs_point *ap, ++ struct map_source *source, ++ const char *key, int key_len, ++ struct lookup_context *ctxt) ++{ ++ char buf[MAX_ERR_BUF]; ++ char *lkp_key; ++ char *prefix; ++ int ret; ++ ++ ret = lookup_one(ap, source, key, key_len, ctxt); ++ if (ret < 0) ++ return ret; ++ if (ret == CHE_OK || ret == CHE_UPDATED) ++ return ret; ++ ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) ++ return CHE_FAIL; ++ ++ lkp_key = strdup(key); ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "strdup: %s", estr); ++ return CHE_FAIL; ++ } ++ ++ ret = CHE_MISSING; ++ ++ /* ++ * Now strip successive directory components and try a ++ * match against map entries ending with a wildcard and ++ * finally try the wilcard entry itself. ++ */ ++ while ((prefix = strrchr(lkp_key, '/'))) { ++ char *match; ++ size_t len; ++ *prefix = '\0'; ++ len = strlen(lkp_key) + 3; ++ match = malloc(len); ++ if (!match) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ ret = CHE_FAIL; ++ goto done; ++ } ++ len--; ++ strcpy(match, lkp_key); ++ strcat(match, "/*"); ++ ret = lookup_one(ap, source, match, len, ctxt); ++ free(match); ++ if (ret < 0) ++ goto done; ++ if (ret == CHE_OK || ret == CHE_UPDATED) ++ goto done; ++ } ++done: ++ free(lkp_key); ++ return ret; ++} ++ + static int lookup_wild(struct autofs_point *ap, + struct map_source *source, struct lookup_context *ctxt) + { +@@ -374,6 +446,59 @@ static int lookup_wild(struct autofs_point *ap, + return ret; + } + ++static int lookup_amd_defaults(struct autofs_point *ap, ++ struct map_source *source, ++ struct lookup_context *ctxt) ++{ ++ struct mapent_cache *mc = source->mc; ++ char *tablename; ++ nis_result *result; ++ nis_object *this; ++ char *mapent; ++ char buf[MAX_ERR_BUF]; ++ int cur_state; ++ int ret; ++ ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); ++ tablename = malloc(9 + strlen(ctxt->mapname) + ++ strlen(ctxt->domainname) + 20); ++ if (!tablename) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ pthread_setcancelstate(cur_state, NULL); ++ return CHE_FAIL; ++ } ++ sprintf(tablename, "[key=/defaults],%s.org_dir.%s", ++ ctxt->mapname, ctxt->domainname); ++ ++ result = nis_list(tablename, FOLLOW_PATH | FOLLOW_LINKS, NULL, NULL); ++ if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) { ++ nis_error rs = result->status; ++ nis_freeresult(result); ++ free(tablename); ++ pthread_setcancelstate(cur_state, NULL); ++ if (rs == NIS_NOTFOUND || ++ rs == NIS_S_NOTFOUND || ++ rs == NIS_PARTIAL) ++ return CHE_MISSING; ++ ++ return -rs; ++ } ++ ++ this = NIS_RES_OBJECT(result); ++ mapent = ENTRY_VAL(this, 1); ++ ++ cache_writelock(mc); ++ ret = cache_update(mc, source, "/defaults", mapent, time(NULL)); ++ cache_unlock(mc); ++ ++ nis_freeresult(result); ++ free(tablename); ++ pthread_setcancelstate(cur_state, NULL); ++ ++ return ret; ++} ++ + static int check_map_indirect(struct autofs_point *ap, + struct map_source *source, + char *key, int key_len, +@@ -387,8 +512,17 @@ static int check_map_indirect(struct autofs_point *ap, + + mc = source->mc; + ++ if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ /* Check for a /defaults entry to update the map source */ ++ if (lookup_amd_defaults(ap, source, ctxt) == CHE_FAIL) { ++ warn(ap->logopt, MODPREFIX ++ "error getting /defaults from map %s", ++ ctxt->mapname); ++ } ++ } ++ + /* check map and if change is detected re-read map */ +- ret = lookup_one(ap, source, key, key_len, ctxt); ++ ret = match_key(ap, source, key, key_len, ctxt); + if (ret == CHE_FAIL) + return NSS_STATUS_NOTFOUND; + +@@ -397,9 +531,16 @@ static int check_map_indirect(struct autofs_point *ap, + * If the server is down and the entry exists in the cache + * and belongs to this map return success and use the entry. + */ +- exists = cache_lookup(mc, key); +- if (exists && exists->source == source) ++ cache_readlock(mc); ++ if (source->flags & MAP_FLAG_FORMAT_AMD) ++ exists = match_cached_key(ap, MODPREFIX, source, key); ++ else ++ exists = cache_lookup(mc, key); ++ if (exists && exists->source == source) { ++ cache_unlock(mc); + return NSS_STATUS_SUCCESS; ++ } ++ cache_unlock(mc); + + warn(ap->logopt, + MODPREFIX "lookup for %s failed: %s", +@@ -418,6 +559,10 @@ static int check_map_indirect(struct autofs_point *ap, + } + me = cache_lookup_next(mc, me); + } ++ if (source->flags & MAP_FLAG_FORMAT_AMD) ++ exists = match_cached_key(ap, MODPREFIX, source, key); ++ else ++ exists = cache_lookup_distinct(mc, key); + exists = cache_lookup_distinct(mc, key); + /* Not found in the map but found in the cache */ + if (exists && exists->source == source && ret & CHE_MISSING) { +@@ -474,9 +619,11 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + struct mapent_cache *mc; + char key[KEY_MAX_LEN + 1]; + int key_len; ++ char *lkp_key; + char *mapent = NULL; + int mapent_len; + struct mapent *me; ++ char buf[MAX_ERR_BUF]; + int status; + int ret = 1; + +@@ -488,9 +635,18 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + debug(ap->logopt, MODPREFIX "looking up %s", name); + +- key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); +- if (key_len > KEY_MAX_LEN) +- return NSS_STATUS_NOTFOUND; ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { ++ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ } else { ++ key_len = expandamdent(name, NULL, NULL); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ memset(key, 0, KEY_MAX_LEN + 1); ++ expandamdent(name, key, NULL); ++ debug(ap->logopt, MODPREFIX "expanded key: \"%s\"", key); ++ } + + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, key, LKP_DISTINCT); +@@ -524,21 +680,30 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + * we never know about it. + */ + if (ap->type == LKP_INDIRECT && *key != '/') { +- char *lkp_key; +- + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); + if (me && me->multi) + lkp_key = strdup(me->multi->key); +- else ++ else if (!ap->pref) + lkp_key = strdup(key); ++ else { ++ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1); ++ if (lkp_key) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, key); ++ } ++ } + cache_unlock(mc); + +- if (!lkp_key) ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); + return NSS_STATUS_UNKNOWN; ++ } + + status = check_map_indirect(ap, source, + lkp_key, strlen(lkp_key), ctxt); ++ free(lkp_key); + if (status) + return status; + } +@@ -555,7 +720,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + cache_readlock(mc); + else + cache_writelock(mc); +- me = cache_lookup(mc, key); ++ ++ if (!ap->pref) ++ lkp_key = strdup(key); ++ else { ++ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1); ++ if (lkp_key) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, key); ++ } ++ } ++ ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ cache_unlock(mc); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ me = match_cached_key(ap, MODPREFIX, source, lkp_key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { + while ((me = cache_lookup_key_next(me))) +@@ -583,6 +766,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + } + } + cache_unlock(mc); ++ free(lkp_key); + + if (!mapent) + return NSS_STATUS_TRYAGAIN; diff --git a/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-program-to-handle-amd-keys.patch b/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-program-to-handle-amd-keys.patch new file mode 100644 index 0000000..9c21bf7 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-program-to-handle-amd-keys.patch @@ -0,0 +1,462 @@ +autofs-5.0.9 - amd lookup update lookup program to handle amd keys + +From: Ian Kent + + +--- + modules/lookup_program.c | 390 +++++++++++++++++++++++++++++++++------------- + 1 file changed, 282 insertions(+), 108 deletions(-) + +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index 6ce94e4..08d14ff 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -113,123 +113,30 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + return NSS_STATUS_UNKNOWN; + } + +-int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++static char *lookup_one(struct autofs_point *ap, ++ const char *name, int name_len, ++ struct lookup_context *ctxt) + { +- struct lookup_context *ctxt = (struct lookup_context *) context; +- struct map_source *source; +- struct mapent_cache *mc; + char *mapent = NULL, *mapp, *tmp; +- struct mapent *me; + char buf[MAX_ERR_BUF]; + char errbuf[1024], *errp; + char ch; + int pipefd[2], epipefd[2]; + struct pollfd pfd[2]; + pid_t f; +- int status; + enum state { st_space, st_map, st_done } state; + int quoted = 0; +- int ret = 1; + int distance; + int alloci = 1; +- +- source = ap->entry->current; +- ap->entry->current = NULL; +- master_source_current_signal(ap->entry); +- +- mc = source->mc; +- +- /* 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)) { +- cache_unlock(me->mc); +- return NSS_STATUS_NOTFOUND; +- } else { +- struct mapent_cache *smc = me->mc; +- struct mapent *sme; +- +- if (me->mapent) +- cache_unlock(smc); +- else { +- cache_unlock(smc); +- cache_writelock(smc); +- sme = cache_lookup_distinct(smc, name); +- /* Negative timeout expired for non-existent entry. */ +- if (sme && !sme->mapent) { +- if (cache_pop_mapent(sme) == CHE_FAIL) +- cache_delete(smc, name); +- } +- cache_unlock(smc); +- } +- } +- } +- +- /* Catch installed direct offset triggers */ +- cache_readlock(mc); +- me = cache_lookup_distinct(mc, name); +- if (!me) { +- cache_unlock(mc); +- /* +- * If there's a '/' in the name and the offset is not in +- * the cache then it's not a valid path in the mount tree. +- */ +- if (strchr(name, '/')) { +- debug(ap->logopt, +- MODPREFIX "offset %s not found", name); +- return NSS_STATUS_NOTFOUND; +- } +- } else { +- /* Otherwise we found a valid offset so try mount it */ +- debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent); +- +- /* +- * If this is a request for an offset mount (whose entry +- * must be present in the cache to be valid) or the entry +- * is newer than the negative timeout value then just +- * try and mount it. Otherwise try and remove it and +- * proceed with the program map lookup. +- */ +- if (strchr(name, '/') || +- me->age + ap->negative_timeout > time(NULL)) { +- char *ent = NULL; +- +- if (me->mapent) { +- ent = alloca(strlen(me->mapent) + 1); +- strcpy(ent, me->mapent); +- } +- cache_unlock(mc); +- master_source_current_wait(ap->entry); +- ap->entry->current = source; +- ret = ctxt->parse->parse_mount(ap, name, +- name_len, ent, ctxt->parse->context); +- goto out_free; +- } else { +- if (me->multi) { +- cache_unlock(mc); +- warn(ap->logopt, MODPREFIX +- "unexpected lookup for active multi-mount" +- " key %s, returning fail", name); +- return NSS_STATUS_UNAVAIL; +- } +- cache_unlock(mc); +- cache_writelock(mc); +- me = cache_lookup_distinct(mc, name); +- if (me) +- cache_delete(mc, name); +- cache_unlock(mc); +- } +- } ++ int status; + + mapent = (char *) malloc(MAPENT_MAX_LEN + 1); + if (!mapent) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "malloc: %s", estr); +- return NSS_STATUS_UNAVAIL; ++ return NULL; + } + +- debug(ap->logopt, MODPREFIX "looking up %s", name); +- + /* + * 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() +@@ -238,12 +145,12 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + if (open_pipe(pipefd)) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "pipe: %s", estr); +- goto out_free; ++ goto out_error; + } + if (open_pipe(epipefd)) { + close(pipefd[0]); + close(pipefd[1]); +- goto out_free; ++ goto out_error; + } + + f = fork(); +@@ -254,7 +161,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + close(pipefd[1]); + close(epipefd[0]); + close(epipefd[1]); +- goto out_free; ++ goto out_error; + } else if (f == 0) { + reset_signals(); + close(pipefd[0]); +@@ -420,21 +327,288 @@ next: + if (waitpid(f, &status, 0) != f) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "waitpid: %s", estr); +- goto out_free; ++ goto out_error; + } + + if (mapp == mapent || !WIFEXITED(status) || WEXITSTATUS(status) != 0) { + info(ap->logopt, MODPREFIX "lookup for %s failed", name); +- goto out_free; ++ goto out_error; + } + +- cache_writelock(mc); +- ret = cache_update(mc, source, name, mapent, time(NULL)); +- cache_unlock(mc); +- if (ret == CHE_FAIL) { ++ return mapent; ++ ++out_error: ++ if (mapent) + free(mapent); +- return NSS_STATUS_UNAVAIL; ++ ++ return NULL; ++} ++ ++static int lookup_amd_defaults(struct autofs_point *ap, ++ struct map_source *source, ++ struct lookup_context *ctxt) ++{ ++ struct mapent_cache *mc = source->mc; ++ char *ment = lookup_one(ap, "/defaults", 9, ctxt); ++ if (ment) { ++ char *start = ment + 9; ++ int ret; ++ ++ while (isblank(*start)) ++ start++; ++ cache_writelock(mc); ++ ret = cache_update(mc, source, "/defaults", start, time(NULL)); ++ cache_unlock(mc); ++ if (ret == CHE_FAIL) { ++ free(ment); ++ return NSS_STATUS_UNAVAIL; ++ } ++ free(ment); + } ++ return NSS_STATUS_SUCCESS; ++} ++ ++static int match_key(struct autofs_point *ap, ++ struct map_source *source, ++ const char *name, int name_len, ++ char **mapent, struct lookup_context *ctxt) ++{ ++ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD; ++ struct mapent_cache *mc = source->mc; ++ char buf[MAX_ERR_BUF]; ++ char *ment; ++ char *lkp_key; ++ size_t lkp_len; ++ char *prefix; ++ int ret; ++ ++ if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ ret = lookup_amd_defaults(ap, source, ctxt); ++ if (ret != NSS_STATUS_SUCCESS) { ++ warn(ap->logopt, ++ MODPREFIX "failed to save /defaults entry"); ++ } ++ } ++ ++ if (!is_amd_format) { ++ lkp_key = strdup(name); ++ lkp_len = name_len; ++ } else { ++ size_t len; ++ ++ if (ap->pref) ++ len = strlen(ap->pref) + strlen(name); ++ else ++ len = strlen(name); ++ ++ lkp_key = malloc(len + 1); ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ return NSS_STATUS_UNAVAIL; ++ } ++ ++ if (ap->pref) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, name); ++ } else ++ strcpy(lkp_key, name); ++ ++ lkp_len = len; ++ } ++ ++ ment = lookup_one(ap, lkp_key, lkp_len, ctxt); ++ if (ment) { ++ char *start = ment; ++ if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ start = ment + lkp_len; ++ while (isblank(*start)) ++ start++; ++ } ++ cache_writelock(mc); ++ ret = cache_update(mc, source, lkp_key, start, time(NULL)); ++ cache_unlock(mc); ++ if (ret == CHE_FAIL) { ++ free(ment); ++ free(lkp_key); ++ return NSS_STATUS_UNAVAIL; ++ } ++ *mapent = strdup(start); ++ if (!*mapent) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ free(lkp_key); ++ free(ment); ++ return NSS_STATUS_UNAVAIL; ++ } ++ free(lkp_key); ++ free(ment); ++ return NSS_STATUS_SUCCESS; ++ } ++ ++ if (!is_amd_format) { ++ free(lkp_key); ++ return NSS_STATUS_NOTFOUND; ++ } ++ ++ ret = NSS_STATUS_NOTFOUND; ++ ++ /* ++ * Now strip successive directory components and try a ++ * match against map entries ending with a wildcard and ++ * finally try the wilcard entry itself. ++ */ ++ while ((prefix = strrchr(lkp_key, '/'))) { ++ char *match; ++ size_t len; ++ *prefix = '\0'; ++ len = strlen(lkp_key) + 3; ++ match = malloc(len); ++ if (!match) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ free(lkp_key); ++ return NSS_STATUS_UNAVAIL; ++ } ++ len--; ++ strcpy(match, lkp_key); ++ strcat(match, "/*"); ++ ment = lookup_one(ap, match, len, ctxt); ++ if (ment) { ++ char *start = ment + len; ++ while (isblank(*start)) ++ start++; ++ cache_writelock(mc); ++ ret = cache_update(mc, source, match, start, time(NULL)); ++ cache_unlock(mc); ++ if (ret == CHE_FAIL) { ++ free(match); ++ free(ment); ++ free(lkp_key); ++ return NSS_STATUS_UNAVAIL; ++ } ++ free(match); ++ *mapent = strdup(start); ++ if (!*mapent) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ free(ment); ++ free(lkp_key); ++ return NSS_STATUS_UNAVAIL; ++ } ++ free(ment); ++ free(lkp_key); ++ return NSS_STATUS_SUCCESS; ++ } ++ free(match); ++ } ++ free(lkp_key); ++ ++ return ret; ++} ++ ++int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *context) ++{ ++ struct lookup_context *ctxt = (struct lookup_context *) context; ++ struct map_source *source; ++ struct mapent_cache *mc; ++ char *mapent = NULL; ++ struct mapent *me; ++ int ret = 1; ++ ++ source = ap->entry->current; ++ ap->entry->current = NULL; ++ master_source_current_signal(ap->entry); ++ ++ mc = source->mc; ++ ++ /* 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)) { ++ cache_unlock(me->mc); ++ return NSS_STATUS_NOTFOUND; ++ } else { ++ struct mapent_cache *smc = me->mc; ++ struct mapent *sme; ++ ++ if (me->mapent) ++ cache_unlock(smc); ++ else { ++ cache_unlock(smc); ++ cache_writelock(smc); ++ sme = cache_lookup_distinct(smc, name); ++ /* Negative timeout expired for non-existent entry. */ ++ if (sme && !sme->mapent) { ++ if (cache_pop_mapent(sme) == CHE_FAIL) ++ cache_delete(smc, name); ++ } ++ cache_unlock(smc); ++ } ++ } ++ } ++ ++ /* Catch installed direct offset triggers */ ++ cache_readlock(mc); ++ me = cache_lookup_distinct(mc, name); ++ if (!me) { ++ cache_unlock(mc); ++ /* ++ * If there's a '/' in the name and the offset is not in ++ * the cache then it's not a valid path in the mount tree. ++ */ ++ if (strchr(name, '/')) { ++ debug(ap->logopt, ++ MODPREFIX "offset %s not found", name); ++ return NSS_STATUS_NOTFOUND; ++ } ++ } else { ++ /* Otherwise we found a valid offset so try mount it */ ++ debug(ap->logopt, MODPREFIX "%s -> %s", name, me->mapent); ++ ++ /* ++ * If this is a request for an offset mount (whose entry ++ * must be present in the cache to be valid) or the entry ++ * is newer than the negative timeout value then just ++ * try and mount it. Otherwise try and remove it and ++ * proceed with the program map lookup. ++ */ ++ if (strchr(name, '/') || ++ me->age + ap->negative_timeout > time(NULL)) { ++ char *ent = NULL; ++ ++ if (me->mapent) { ++ ent = alloca(strlen(me->mapent) + 1); ++ strcpy(ent, me->mapent); ++ } ++ cache_unlock(mc); ++ master_source_current_wait(ap->entry); ++ ap->entry->current = source; ++ ret = ctxt->parse->parse_mount(ap, name, ++ name_len, ent, ctxt->parse->context); ++ goto out_free; ++ } else { ++ if (me->multi) { ++ cache_unlock(mc); ++ warn(ap->logopt, MODPREFIX ++ "unexpected lookup for active multi-mount" ++ " key %s, returning fail", name); ++ return NSS_STATUS_UNAVAIL; ++ } ++ cache_unlock(mc); ++ cache_writelock(mc); ++ me = cache_lookup_distinct(mc, name); ++ if (me) ++ cache_delete(mc, name); ++ cache_unlock(mc); ++ } ++ } ++ ++ debug(ap->logopt, MODPREFIX "looking up %s", name); ++ ++ ret = match_key(ap, source, name, name_len, &mapent, ctxt); ++ if (ret != NSS_STATUS_SUCCESS) ++ goto out_free; + + debug(ap->logopt, MODPREFIX "%s -> %s", name, mapent); + diff --git a/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-yp-to-handle-amd-keys.patch b/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-yp-to-handle-amd-keys.patch new file mode 100644 index 0000000..5c9fd3b --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-update-lookup-yp-to-handle-amd-keys.patch @@ -0,0 +1,388 @@ +autofs-5.0.9 - amd lookup update lookup yp to handle amd keys + +From: Ian Kent + + +--- + modules/lookup_yp.c | 248 ++++++++++++++++++++++++++++++++++++++++++++------- + 1 file changed, 216 insertions(+), 32 deletions(-) + +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index ba97ccc..146e39e 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -36,9 +36,10 @@ + #define MODPREFIX "lookup(yp): " + + struct lookup_context { +- const char *domainname; ++ char *domainname; + const char *mapname; + unsigned long order; ++ unsigned int check_defaults; + struct parse_mod *parse; + }; + +@@ -113,7 +114,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + ctxt = malloc(sizeof(struct lookup_context)); + if (!ctxt) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "%s", estr); ++ logerr(MODPREFIX "malloc: %s", estr); + return 1; + } + memset(ctxt, 0, sizeof(struct lookup_context)); +@@ -124,17 +125,28 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 1; + } + ctxt->mapname = argv[0]; +- +- /* This should, but doesn't, take a const char ** */ +- err = yp_get_default_domain((char **) &ctxt->domainname); +- if (err) { +- size_t len = strlen(ctxt->mapname); +- char *name = alloca(len + 1); +- memcpy(name, ctxt->mapname, len); +- name[len] = '\0'; +- free(ctxt); +- logerr(MODPREFIX "map %s: %s", name, yperr_string(err)); +- return 1; ++ ctxt->check_defaults = 1; ++ ++ if (mapfmt && !strcmp(mapfmt, "amd")) ++ ctxt->domainname = conf_amd_get_nis_domain(); ++ ++ if (!ctxt->domainname) { ++ char *domainname; ++ /* This should, but doesn't, take a const char ** */ ++ err = yp_get_default_domain(&domainname); ++ if (err) { ++ logerr(MODPREFIX ++ "map %s: %s", ctxt->mapname, yperr_string(err)); ++ free(ctxt); ++ return 1; ++ } ++ 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; ++ } + } + + ctxt->order = get_map_order(ctxt->domainname, ctxt->mapname); +@@ -286,7 +298,12 @@ int yp_all_callback(int status, char *ypkey, int ypkeylen, + if (*ypkey == '+') + return 0; + +- key = sanitize_path(ypkey, ypkeylen, ap->type, ap->logopt); ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) ++ key = sanitize_path(ypkey, ypkeylen, ap->type, ap->logopt); ++ else ++ /* Don't fail on "/" in key => type == 0 */ ++ key = sanitize_path(ypkey, ypkeylen, 0, ap->logopt); ++ + if (!key) { + error(logopt, MODPREFIX "invalid path %s", ypkey); + return 0; +@@ -372,6 +389,9 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context) + } + + source->age = age; ++ pthread_mutex_lock(&ap->entry->current_mutex); ++ ctxt->check_defaults = 0; ++ pthread_mutex_unlock(&ap->entry->current_mutex); + + return NSS_STATUS_SUCCESS; + } +@@ -432,6 +452,66 @@ static int lookup_one(struct autofs_point *ap, + return ret; + } + ++static int match_key(struct autofs_point *ap, ++ struct map_source *source, ++ const char *key, int key_len, ++ struct lookup_context *ctxt) ++{ ++ char buf[MAX_ERR_BUF]; ++ char *lkp_key; ++ char *prefix; ++ int ret; ++ ++ ret = lookup_one(ap, source, key, strlen(key), ctxt); ++ if (ret < 0) ++ return ret; ++ if (ret == CHE_OK || ret == CHE_UPDATED) ++ return ret; ++ ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) ++ return CHE_FAIL; ++ ++ lkp_key = strdup(key); ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "strdup: %s", estr); ++ return CHE_FAIL; ++ } ++ ++ ret = CHE_MISSING; ++ ++ /* ++ * Now strip successive directory components and try a ++ * match against map entries ending with a wildcard and ++ * finally try the wilcard entry itself. ++ */ ++ while ((prefix = strrchr(lkp_key, '/'))) { ++ char *match; ++ size_t len; ++ *prefix = '\0'; ++ len = strlen(lkp_key) + 3; ++ match = malloc(len); ++ if (!match) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ ret = CHE_FAIL; ++ goto done; ++ } ++ len--; ++ strcpy(match, lkp_key); ++ strcat(match, "/*"); ++ ret = lookup_one(ap, source, match, len, ctxt); ++ free(match); ++ if (ret < 0) ++ goto done; ++ if (ret == CHE_OK || ret == CHE_UPDATED) ++ goto done; ++ } ++done: ++ free(lkp_key); ++ return ret; ++} ++ + static int lookup_wild(struct autofs_point *ap, + struct map_source *source, struct lookup_context *ctxt) + { +@@ -480,6 +560,52 @@ static int lookup_wild(struct autofs_point *ap, + return ret; + } + ++static int lookup_amd_defaults(struct autofs_point *ap, ++ struct map_source *source, ++ struct lookup_context *ctxt) ++{ ++ struct mapent_cache *mc = source->mc; ++ char *mapname; ++ char *mapent; ++ int mapent_len; ++ int ret; ++ ++ mapname = malloc(strlen(ctxt->mapname) + 1); ++ if (!mapname) ++ return 0; ++ ++ strcpy(mapname, ctxt->mapname); ++ ++ ret = yp_match((char *) ctxt->domainname, mapname, ++ (char *) "/defaults", 9, &mapent, &mapent_len); ++ ++ if (ret != YPERR_SUCCESS) { ++ if (ret == YPERR_MAP) { ++ char *usc; ++ ++ while ((usc = strchr(mapname, '_'))) ++ *usc = '.'; ++ ++ ret = yp_match((char *) ctxt->domainname, mapname, ++ "/defaults", 9, &mapent, &mapent_len); ++ } ++ } ++ free(mapname); ++ ++ /* No /defaults entry */ ++ if (ret == YPERR_KEY) ++ return CHE_OK; ++ ++ if (ret != YPERR_SUCCESS) ++ return CHE_FAIL; ++ ++ cache_writelock(mc); ++ ret = cache_update(mc, source, "/defaults", mapent, time(NULL)); ++ cache_unlock(mc); ++ ++ return ret; ++} ++ + static int check_map_indirect(struct autofs_point *ap, + struct map_source *source, + char *key, int key_len, +@@ -492,8 +618,28 @@ static int check_map_indirect(struct autofs_point *ap, + + mc = source->mc; + ++ /* Only read map if it has been modified */ ++ pthread_mutex_lock(&ap->entry->current_mutex); ++ map_order = get_map_order(ctxt->domainname, ctxt->mapname); ++ if (map_order > ctxt->order) { ++ ctxt->order = map_order; ++ source->stale = 1; ++ ctxt->check_defaults = 1; ++ } ++ ++ if (source->flags & MAP_FLAG_FORMAT_AMD && ctxt->check_defaults) { ++ /* Check for a /defaults entry to update the map source */ ++ if (lookup_amd_defaults(ap, source, ctxt) == CHE_FAIL) { ++ warn(ap->logopt, MODPREFIX ++ "error getting /defaults from map %s", ++ ctxt->mapname); ++ } else ++ ctxt->check_defaults = 0; ++ } ++ pthread_mutex_unlock(&ap->entry->current_mutex); ++ + /* check map and if change is detected re-read map */ +- ret = lookup_one(ap, source, key, key_len, ctxt); ++ ret = match_key(ap, source, key, key_len, ctxt); + if (ret == CHE_FAIL) + return NSS_STATUS_NOTFOUND; + +@@ -503,7 +649,10 @@ static int check_map_indirect(struct autofs_point *ap, + * and belongs to this map return success and use the entry. + */ + cache_readlock(mc); +- exists = cache_lookup(mc, key); ++ if (source->flags & MAP_FLAG_FORMAT_AMD) ++ exists = match_cached_key(ap, MODPREFIX, source, key); ++ else ++ exists = cache_lookup(mc, key); + if (exists && exists->source == source) { + cache_unlock(mc); + return NSS_STATUS_SUCCESS; +@@ -517,15 +666,11 @@ static int check_map_indirect(struct autofs_point *ap, + return NSS_STATUS_UNAVAIL; + } + +- /* Only read map if it has been modified */ +- map_order = get_map_order(ctxt->domainname, ctxt->mapname); +- if (map_order > ctxt->order) { +- ctxt->order = map_order; +- source->stale = 1; +- } +- + cache_writelock(mc); +- exists = cache_lookup_distinct(mc, key); ++ if (source->flags & MAP_FLAG_FORMAT_AMD) ++ exists = match_cached_key(ap, MODPREFIX, source, key); ++ else ++ exists = cache_lookup_distinct(mc, key); + /* Not found in the map but found in the cache */ + if (exists && exists->source == source && ret & CHE_MISSING) { + if (exists->mapent) { +@@ -578,9 +723,11 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + struct mapent_cache *mc; + char key[KEY_MAX_LEN + 1]; + int key_len; ++ char *lkp_key; + char *mapent = NULL; + int mapent_len; + struct mapent *me; ++ char buf[MAX_ERR_BUF]; + int status = 0; + int ret = 1; + +@@ -592,9 +739,18 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + + debug(ap->logopt, MODPREFIX "looking up %s", name); + +- key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); +- if (key_len > KEY_MAX_LEN) +- return NSS_STATUS_NOTFOUND; ++ if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { ++ key_len = snprintf(key, KEY_MAX_LEN + 1, "%s", name); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ } else { ++ key_len = expandamdent(name, NULL, NULL); ++ if (key_len > KEY_MAX_LEN) ++ return NSS_STATUS_NOTFOUND; ++ memset(key, 0, KEY_MAX_LEN + 1); ++ expandamdent(name, key, NULL); ++ debug(ap->logopt, MODPREFIX "expanded key: \"%s\"", key); ++ } + + /* Check if we recorded a mount fail for this key anywhere */ + me = lookup_source_mapent(ap, key, LKP_DISTINCT); +@@ -628,18 +784,26 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + * we never know about it. + */ + if (ap->type == LKP_INDIRECT && *key != '/') { +- char *lkp_key; +- + cache_readlock(mc); + me = cache_lookup_distinct(mc, key); + if (me && me->multi) + lkp_key = strdup(me->multi->key); +- else ++ else if (!ap->pref) + lkp_key = strdup(key); ++ else { ++ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1); ++ if (lkp_key) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, key); ++ } ++ } + cache_unlock(mc); + +- if (!lkp_key) ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); + return NSS_STATUS_UNKNOWN; ++ } + + status = check_map_indirect(ap, source, + lkp_key, strlen(lkp_key), ctxt); +@@ -660,7 +824,25 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + cache_readlock(mc); + else + cache_writelock(mc); +- me = cache_lookup(mc, key); ++ ++ if (!ap->pref) ++ lkp_key = strdup(key); ++ else { ++ lkp_key = malloc(strlen(ap->pref) + strlen(key) + 1); ++ if (lkp_key) { ++ strcpy(lkp_key, ap->pref); ++ strcat(lkp_key, key); ++ } ++ } ++ ++ if (!lkp_key) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, MODPREFIX "malloc: %s", estr); ++ cache_unlock(mc); ++ return NSS_STATUS_UNKNOWN; ++ } ++ ++ me = match_cached_key(ap, MODPREFIX, source, lkp_key); + /* Stale mapent => check for entry in alternate source or wildcard */ + if (me && !me->mapent) { + while ((me = cache_lookup_key_next(me))) +@@ -687,6 +869,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + } + } + cache_unlock(mc); ++ free(lkp_key); + + if (mapent) { + master_source_current_wait(ap->entry); +@@ -716,6 +899,7 @@ int lookup_done(void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; + int rv = close_parse(ctxt->parse); ++ free(ctxt->domainname); + free(ctxt); + return rv; + } diff --git a/SOURCES/autofs-5.0.9-amd-lookup-update-man-page-autofs-config-description.patch b/SOURCES/autofs-5.0.9-amd-lookup-update-man-page-autofs-config-description.patch new file mode 100644 index 0000000..5ec7125 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-update-man-page-autofs-config-description.patch @@ -0,0 +1,74 @@ +autofs-5.0.9 - update man page autofs config description + +From: Ian Kent + + +--- + man/auto.master.5.in | 43 ++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 38 insertions(+), 5 deletions(-) + +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index eb31c93..59df04f 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -205,14 +205,47 @@ 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. +-.SH GENERAL SYSTEM DEFAULTS CONFIGURATION ++.SH AUTOFS CONFIGURATION + .P +-The default value of several general settings may be changed in the +-configuration file ++There are two files that amy contain configuration settings + .nh ++.BR @@autofsmapdir@@/autofs.conf . ++.hy ++and + .BR @@autofsconfdir@@/autofs . + .hy +-They are: ++The former contains the bulk of configuration options while the later ++contains entries to be set in the environment for use by the init ++sub-system. ++.TP ++The only entry currently present in the init system configuration ++is OPTIONS which may be used to specify options to be used when ++starting ++.BR automount (8) . ++.TP ++Previously all configuration entries were located in the init system ++configuration file and their values were set in the environment for ++later use by autofs. Configuration entries that were set in the ++environment continue to be set in the environment at program startup ++and any setting already present in the environment takes precedence. ++.SH SYSTEM DEFAULTS CONFIGURATION ++.P ++The value of most settings may be set in the configuration file ++.nh ++.BR @@autofsmapdir@@/autofs.conf . ++.hy ++Configuration entries are "name = value" pairs and the name is case ++insensitive. Older configuration names had a DEFAULTS_ prefix which ++is appended to the configuration name when a value isn't found and ++the search repeated. ++.TP ++An optional section name ++.nh ++.BR [ autofs ] ++.hy ++may also be given. ++.TP ++The available configuration entries are: + .TP + .B timeout + Sets the default mount timeout in seconds. The internal program +@@ -308,7 +341,7 @@ The object classes and attributes used for accessing automount maps in + LDAP can be changed by setting entries in the autofs configuration + located in + .nh +-.BR @@autofsconfdir@@/autofs . ++.BR @@autofsmapdir@@/autofs.conf . + .hy + .TP + .B NOTE: diff --git a/SOURCES/autofs-5.0.9-amd-lookup-update-man-pages.patch b/SOURCES/autofs-5.0.9-amd-lookup-update-man-pages.patch new file mode 100644 index 0000000..4b8072e --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-update-man-pages.patch @@ -0,0 +1,1085 @@ +autofs-5.0.9 - amd lookup update man pages + +From: Ian Kent + +Update man pages to reflect the addition of the amd map format +parser, move configuration to it's own man page and update with +amd options descriptions. +--- + man/auto.master.5.in | 183 ++---------------- + man/autofs.5 | 346 +++++++++++++++++++++++++++++++++- + man/autofs.8.in | 1 + man/autofs.conf.5.in | 412 ++++++++++++++++++++++++++++++++++++++++ + man/autofs_ldap_auth.conf.5.in | 1 + man/automount.8 | 1 + 6 files changed, 782 insertions(+), 162 deletions(-) + create mode 100644 man/autofs.conf.5.in + +diff --git a/man/auto.master.5.in b/man/auto.master.5.in +index 59df04f..2267550 100644 +--- a/man/auto.master.5.in ++++ b/man/auto.master.5.in +@@ -122,14 +122,18 @@ will be ignored if its name is not ended with the suffix. In addition a dot file + which name is started with "." is also ignored. + .RE + .TP +-\fBformat\fP +-Format of the map data; currently the only formats +-recognized are \fBsun\fP, which is a subset of the Sun automounter map +-format, and \fBhesiod\fP, for hesiod filesys entries. If the format is +-left unspecified, it defaults to \fBsun\fP for all map types except +-\fBhesiod\fP. +-.TP +-\fBmap\fP ++.B format ++.br ++Format of the map data; currently the formats recognized are \fBsun\fP, ++which is a subset of the Sun automounter map format, \fBhesiod\fP, for ++hesiod filesys entries and \fBamd\fP for amd formated map entries. ++If the format is left unspecified, it defaults to \fBsun\fP for all map ++types except \fBhesiod\fP unless it is a top level \fBamd\fP mount that ++has a configuration entry for the mount point path, in which case the ++format used is \fBamd\fP. ++.TP ++.B map ++.br + Name of the map to use. This is an absolute UNIX pathname + for maps of types \fBfile\fP, \fBdir\fP, or \fBprogram\fP, and the name of a database + in the case for maps of type \fByp\fP, \fBnisplus\fP, or \fBhesiod\fP or +@@ -205,87 +209,6 @@ 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. +-.SH AUTOFS CONFIGURATION +-.P +-There are two files that amy contain configuration settings +-.nh +-.BR @@autofsmapdir@@/autofs.conf . +-.hy +-and +-.BR @@autofsconfdir@@/autofs . +-.hy +-The former contains the bulk of configuration options while the later +-contains entries to be set in the environment for use by the init +-sub-system. +-.TP +-The only entry currently present in the init system configuration +-is OPTIONS which may be used to specify options to be used when +-starting +-.BR automount (8) . +-.TP +-Previously all configuration entries were located in the init system +-configuration file and their values were set in the environment for +-later use by autofs. Configuration entries that were set in the +-environment continue to be set in the environment at program startup +-and any setting already present in the environment takes precedence. +-.SH SYSTEM DEFAULTS CONFIGURATION +-.P +-The value of most settings may be set in the configuration file +-.nh +-.BR @@autofsmapdir@@/autofs.conf . +-.hy +-Configuration entries are "name = value" pairs and the name is case +-insensitive. Older configuration names had a DEFAULTS_ prefix which +-is appended to the configuration name when a value isn't found and +-the search repeated. +-.TP +-An optional section name +-.nh +-.BR [ autofs ] +-.hy +-may also be given. +-.TP +-The available configuration entries are: +-.TP +-.B timeout +-Sets the default mount timeout in seconds. The internal program +-default is 10 minutes, but the default installed configuration +-overrides this and sets the timeout to 5 minutes to be consistent +-with earlier autofs releases. +-.TP +-.B negative_timeout +-Set the default timeout for caching failed key lookups (program default +-60). If the equivalent command line option is given it will override this +-setting. +-.TP +-.B mount_wait +-Set the default time to wait for a response from a spawned mount(8) +-before sending it a SIGTERM. Note that we still need to wait for the +-RPC layer to timeout before the sub-process exits so this isn't ideal +-but it is the best we can do. The default is to wait until mount(8) +-returns without intervention. +-.TP +-.B umount_wait +-Set the default time to wait for a response from a spawned umount(8) +-before sending it a SIGTERM. Note that we still need to wait for the +-RPC layer to timeout before the sub-process exits so this isn't ideal +-but it is the best we can do. +-.TP +-.B browse_mode +-Maps are browsable by default (program default "yes"). +-.TP +-.B mount_nfs_default_protocol +-Specify the default protocol used by mount.nfs(8) (program default 3). Since +-we can't identify this default automatically we need to set it in the autofs +-configuration. +-.TP +-.B append_options +-Determine whether global options, given on the command line or per mount +-in the master map, are appended to map entry options or if the map entry +-options replace the global options (program default "yes", append options). +-.TP +-.B logging +-set default log level "none", "verbose" or "debug" (program default "none"). + .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 +@@ -341,76 +264,21 @@ The object classes and attributes used for accessing automount maps in + LDAP can be changed by setting entries in the autofs configuration + located in + .nh +-.BR @@autofsmapdir@@/autofs.conf . ++.BR @@autofsconfdir@@/autofs.conf . + .hy + .TP + .B NOTE: + If a schema is given in the configuration then all the schema configuration + values must be set, any partial schema specification will be ignored. +-.P +-The configuration settings available are: +-.TP +-.B ldap_timeout +-Set the network response timeout (default 8). +-Set timeout value for the synchronous API calls. The default is the LDAP +-library default of an infinite timeout. + .TP +-.B ldap_network_timeout +-Set the network response timeout (default 8). +-.TP +-.B ldap_uri +-A space seperated list of server uris of the form ://[/] +-where can be ldap or ldaps. The option can be given multiple times. +-Map entries that include a server name override this option and it is then +-not used. Default is an empty list in which case either the server given +-in a map entry or the LDAP configured default is used. This uri list is read at +-startup and whenever the daemon receives a HUP signal. +-.P +-This configuration option can also be used to request autofs lookup SRV RRs +-for a domain of the form :///[]. Note that a trailing +-"/" is not allowed when using this form. If the domain dn is not specified +-the dns domain name (if any) is used to construct the domain dn for the +-SRV RR lookup. The server list returned from an SRV RR lookup is refreshed +-according to the minimum ttl found in the SRV RR records or after one hour, +-whichever is less. ++For \fBamd\fP format maps a different schema is used: + .TP +-.B search_base +-The base dn to use when searching for amap base dn. This entry may be +-given multiple times and each will be checked for a map base dn in +-the order they occur in the configuration. The search base list is read +-at startup and whenever the daemon recieves a HUP signal. +-.TP +-.B map_object_class +-The map object class. In the \fBnisMap\fP schema this corresponds to the class +-\fBnisMap\fP and in the \fBautomountMap\fP schema it corresponds to the class +-\fBautomountMap\fP. +-.TP +-.B entry_object_class +-The map entry object class. In the \fBnisMap\fP schema this corresponds +-to the class \fBnisObject\fP and in the \fBautomountMap\fP schema it +-corresponds to the class \fBautomount\fP. +-.TP +-.B map_attribute +-The attribute used to identify the name of the map to which this +-entry belongs. In the \fBnisMap\fP schema this corresponds to the attribute +-\fBnisMapName\fP and in the \fBautomountMap\fP schema it corresponds to the +-attribute \fBou\fP or \fBautomountMapName\fP. +-.TP +-.B entry_attribute +-The attribute used to identify a map key. In the \fBnisMap\fP schema this +-corresponds to the attribute \fBcn\fP and in the \fBautomountMap\fP schema +-it corresponds to the attribute \fBautomountKey\fP. +-.TP +-.B value_attribute +-The attribute used to identify the value of the map entry. In the \fBnisMap\fP +-schema this corresponds to the attribute \fBnisMapEntry\fP and in the \fBautomountMap\fP +-schema it corresponds to the attribute \fBautomountInformation\fP. +-.TP +-.B NOTE: +-It is essential that entries use class and attribute in a consistent +-manner for correct operation of autofs. For example mixing \fBcn\fP and +-\fBautomountKey\fP attributes in \fBautomount\fP schema map entries won't +-work as expected. ++.I amdMap ++.br ++The \fBamdmap\fP schema contains attributes \fBamdmapName\fP, \fBamdmapKey\fP ++and \fBamdmapValue\fP where \fBamdmapName\fP contains the name of the containing ++map, \fBamdmapKey\fP contains the map key and \fBamdmapValue\fP contains the ++map entry. + .SH LDAP AUTHENTICATION, ENCRYPTED AND CERTIFIED CONNECTIONS + LDAP authenticated binds, TLS encrypted connections and certification + may be used by setting appropriate values in the autofs authentication +@@ -419,10 +287,6 @@ settings. The default location of this file is + .nh + .BR @@autofsmapdir@@/autofs_ldap_auth.conf . + .hy +-.TP +-.B auth_conf_file +-This configuration option may be used to specify an alternate location +-for the ldap authentication file + .P + If this file exists it will be used to establish whether TLS or authentication + should be used. +@@ -458,7 +322,9 @@ in the per-user configuration. The location of these files and the configuration + entry requirements is system dependent so the documentation for your + installation will need to be consulted to get further information. + .P +-See \fBautofs_ldap_auth.conf\fP(5) for more information. ++See ++.B autofs_ldap_auth.conf (5) ++for more information. + .SH EXAMPLE + .sp + .RS +.2i +@@ -492,7 +358,8 @@ configuration will be used to locate the source of the map + .SH "SEE ALSO" + .BR automount (8), + .BR autofs (5), +-.BR autofs (8). ++.BR autofs (8), ++.BR autofs.conf (5), + .BR autofs_ldap_auth.conf (5) + .SH AUTHOR + This manual page was written by Christoph Lameter , +diff --git a/man/autofs.5 b/man/autofs.5 +index c3a1611..81ae375 100644 +--- a/man/autofs.5 ++++ b/man/autofs.5 +@@ -1,6 +1,5 @@ + .\" t +-.TH AUTOFS 5 "6 Apr 1998" +-.TH AUTOFS 5 "14 Jan 2000" ++.TH AUTOFS 5 "9 Feb 2014" + .SH NAME + autofs \- Format of the automounter maps + .SH "DESCRIPTION" +@@ -10,14 +9,16 @@ the master map of the automounter (see + These maps describe how file systems below the mount point of the map + (given in the master map) are to be mounted. This page describes the + .B sun +-map format; if another map format is specified (e.g. \fBhesiod\fP), ++map format; if another map format, other than ++.B amd , ++is specified (e.g. \fBhesiod\fP), + this documentation does not apply. + + Indirect maps, except for the internal hosts map, can be changed on the fly + and the automouter will recognize those changes on the next operation it + performs on that map. Direct maps require a HUP signal be sent to the + daemon to refresh their contents as does the master map. +-.SH "FORMAT" ++.SH "SUN FORMAT" + This is a description of the text file format. Other methods of specifying + these files may exist. All empty lines or lines beginning with # are + ignored. The basic format of one line in such maps is: +@@ -245,10 +246,347 @@ Anything else is questionable and unsupported, but these variations will also wo + .SH UNSUPPORTED + This version of the automounter supports direct maps stored in FILE, NIS, NISPLUS + and LDAP only. ++.P ++.SH "AMD FORMAT" ++This is a description of the text file format. Other methods of specifying ++mount map entries may be required for different map sources. All empty ++lines or lines beginning with # are ignored. The basic format of one ++line in such maps is: ++.P ++.BR key\ location-list ++.TP ++.B key ++.br ++A \fBkey\fP is a path (or a single path component alone) that may end ++in the wildcard key, "*", or the wildcard key alone and must not begin ++with the "/" character. ++.TP ++.B location-list ++Following the \fBkey\fP is a mount \fBlocation-list\fP. ++.TP ++A \fBlocation-list\fP list has the following syntax: ++.TP ++.B location[\ location[\ ...\ ]]\ [||\ location[\ location[\ ...\ ]] ++.P ++A mount \fBlocation-list\fP can use the cut operator, \fB||\fP, to specify ++locations that should be tried if none of the locations to the left of it ++where selected for a mount attempt. ++ ++A mount \fBlocation\fP consists of an optional colon seperated list ++of \fBselectors\fP, followed by a colon seperated list of \fBoption:=value\fP ++pairs. ++ ++The \fBselectors\fP that may be used return a value or boolean result. ++Those that return a value may be to used with the comparison ++operators \fB==\fP and \fB!=\fP and those that return a boolean result ++may be negated with the \fB!\fP. ++ ++For a \fBlocation\fP to be selected for a mount attempt all of its \fBselectors\fP ++must evaluate to true. If a \fBlocation\fP is selected for a mount attempt ++and succeeds the lookup is completed and returns success. If the mount ++attempt fails the proceedure continues with the next \fBlocation\fP until ++they have all been tried. ++ ++In addition some \fBselectors\fP take no argumenets, some one argument ++and others optionally take two arguments. ++ ++The \fBselectors\fP that take no arguments are: ++.RS ++.TP ++.B arch ++.br ++The machine architecture which, if not set in the confugration, is ++obtained using uname(2). ++.TP ++.B karch ++.br ++The machine kernel architecture which, if not set in the confugration, ++is obtained using uname(2). ++.TP ++.B os ++.br ++The operating system name, if not set in the confugration, is obtained ++using uname(2). ++.TP ++.B osver ++.br ++The operating system version, if not set in the confugration, is obtained ++using uname(2). ++.TP ++.B full_os ++.br ++The full operating system name, if not set in the confugration this selector ++has no value. ++.TP ++.B vendor ++.br ++The operating system vendor name, if not set in the confugration this selector ++has the value "unknown". ++.TP ++.B byte ++.br ++The endianess of the hardware. ++.TP ++.B cluster ++.br ++The name of the local cluster. It has a value only if it is set in the ++configuration. ++.TP ++.B autodir ++.br ++The base path under which external mounts are done if they are needed. ++Most mounts are done in place but some can't be and this is the base ++path under which those mounts will be done. ++.TP ++.B domain ++.br ++The local domain name. It is set to the value of the configuration ++option \fBsub_domain\fP. If sub_domain is not given in the configuration ++it is set to the domain part of the local host name, as given by ++gethostname(2). ++.TP ++.B host ++.br ++The local host name, without the domain part, as given by gethostname(2). ++.TP ++.B hostd ++.br ++The full host name. If \fBsub_domain\fP is given in the configuration ++this is set to the contatenation of \fBhost\fP and \fBsub_domain\fP deperated ++by a \fB.\fP. If \fBsub_domain\fP is not set in the configuration the value ++of \fBdomain\fP is used instead of \fBsub_domain\fP. ++.TP ++.B uid ++.br ++The numeric value of the uid of the user that first requested the mount. Note ++this is usual the same as that used by amd but can be different within autofs. ++.TP ++.B gid ++.br ++The numeric value of the gid of the user that first requested the mount. Note ++this is usual the same as that used by amd but can be different within autofs. ++.TP ++.B key ++.br ++The string value of the key being looked up. ++.TP ++.B map ++.br ++The string value of the map name used to lookup \fBkey\fPs. ++.TP ++.B path ++.br ++The string value of the full path to the mount being requested. ++.TP ++.B dollar ++.br ++Evaluates to the string "$". ++.RE ++.TP ++The \fBselectors\fP that take one argument are: ++.RS ++.TP ++.B in_network(network) ", " network(network) ", " netnumber(network) ", " wire(network) ++.br ++These \fBselectors\fP are all the same. \fBin_network()\fP is the ++preferred usage. The \fBnetwork\fP argument is an address (which may include ++a subnet mask) or network name. The function compares \fBnetwork\fP ++against each interface and returns true if \fBnetwork\fP belongs to ++the network the interface is connected to. ++.TP ++.B xhost(hostname) ++.br ++The \fBxhost()\fP selector compares \fBhostname\fP to the \fB${host}\fP ++and if it doesn't match it attempts to lookup the cannonical name ++of \fBhostname\fP and compares it to \f${host}\fP as well. ++.TP ++.B exists(filename) ++.br ++Returns true if \fBfilename\fP exits as determined by lstat(2). ++.TP ++.B true() ++.br ++Evaluates to true, the argument is ignored and may be empty. ++.TP ++.B false() ++.br ++Evaluates to false, the argument is ignored and may be empty. ++.RE ++.TP ++The \fBselectors\fP that take up to two arguments are: ++.RS ++.TP ++.B netgrp(netgroup[,hostname]) ++.br ++The \fBnetgrp()\fP selector returns true if \fPhostname\fP is a member of ++the netgroup \fBnetgroup\fP. If \fBhostname\fP is not given \fB${host}\fP ++is used for the comparison. ++.TP ++.B netgrpd(netgroup[,hostname]) ++.br ++The \fBnetgrpd()i\fP selector behaves the same as \fBnetgrp()\fP except ++that if \fBhostname\fP is not given \fB${hostd}\fP, the fully qualified ++hostname, is used instead of \fB${host}\fP. ++.RE ++.TP ++The \fBoptions\fP that may be used are: ++.RS ++.TP ++.B type ++.br ++This is the mount filesystem \fBtype\fP. ++It can have a value of ++.BR auto ", " link ", " linkx ", " host ", " lofs ", " ext2-4 ", " ++.BR xfs ", " nfs ", " nfsl " or " cdfs "." ++Other types that are not yet implemented or are not available iin autofs are ++.BR nfsx ", " lustre ", " jfs ", " program ", " cachefs " and " direct "." ++.TP ++.B maptype ++.br ++The \fBmaptype\fP option specifies the type of the map source and can ++have a value of \fBfile\fP, \fBnis\fP, \fBnisplus\fP, \fBexec\fP, \fBldap\fP ++or \fBhesiod\fP. Map sources either not yet implemented or not available in ++autofs are \fBsss\fP, \fBndbm\fP, \fBpasswd\fP and \fBunion\fP. ++.TP ++.B fs ++.br ++The option \fBfs\fP is used to specify the local filesystem. The meaning of ++this option (and whether or not it is used) is dependent on the mount ++filesystem \fBtype\fP. ++.TP ++.B rhost ++.br ++The remote host name for network mount requests. ++.TP ++.B rfs ++.br ++The remote host filesystem path for network mount requests. ++.TP ++.B dev ++.br ++Must resolve to the device file for local device mount ++requests. ++.TP ++.B sublink ++.br ++The \fBsublink\fP option is used to specify a subdirectory ++within the mount location to which this entry will point. ++.TP ++.B pref ++.br ++The \fBpref\fP option is used to specify a prefix that is ++prepended to the lookup key before looking up the map entry ++key. ++.TP ++.B opts ++.br ++The \fBopts\fP option is used to specify mount options to be ++used for the mount. If a "\fB-\fP" is given it is ignored. ++Options that may be used are dependend on the mount filesystem. ++.TP ++.B addopts ++.br ++The \fBaddopts\fP option is used to specify additional mount ++options used in addition to the default mount options for the ++mount location. ++.TP ++.B remopts ++.br ++The \fBaddopts\fP option is used to specify mount options used ++instead the options given in \fBopts\fP when the mount location ++is on a remote retwork. ++.RE ++.TP ++A number of \fBoptions\fP aren't available or aren't yet implemented ++within autofs, these are: ++.RS ++.TP ++.B cache ++.br ++The \fBcache option\fP isn't used by autofs. The map entry cache is ++continually updated and stale entries cleaned on re-load when map ++changes are detected so these configuration entries are not used. ++The \fBregex\fP map key matching is not implemented and may not be ++due to the potential overhead of the full map scans needed on every ++key lookup. ++.TP ++.B cachedir ++.br ++The \fBcachefs\fP filesystem is not available on Linux, a different ++implementation is used for caching network mounted file systems. ++.TP ++.B mount ", " unmount ", " umount ++.br ++These \fBoptions\fP are used by the amd \fBprogram\fP mount type which ++is not yet implemented. ++.TP ++.B delay ++.br ++This \fBoption\fP is not used by the autofs implementation and is ignored. ++.RE ++.BR ++.SH FEATURES ++.SS Key Matching ++The amd parser key matching is unusual. ++ ++The key string to be looked up is constructed by prepending the prefix, if ++there is one. ++ ++The resulting relative path string is matched by first trying the sting ++itself. If no match is found the last component of the key string is ++replaced with the wilcard match cahracter ("*") and a wildcard match is ++attemted. This process continues until a match is found or until the ++last match, against the wilcard match key alone, fails to match a map ++entry and the key lookup fails. ++.SS Macro Usage ++Macros are used a lot in the autofs amd implementation. ++ ++Many of the option values are set as macro variables corresponding to the ++option name during the map entry parse. So they may be used in subsequent ++option values. Beware though, the order in which option values is not ++necessarily left to right so you may get unexpected results. ++.BR ++.SH EXAMPLE ++Example NFS mount map: ++.P ++Assuming we have the autofs master map entry: ++.sp ++.RS +.2i ++.ta 1.0i 3.0i ++.nf ++/test file,amd:/etc/amd.test ++.fi ++.RE ++.sp ++And the following map in /etc/amd.test: ++.sp ++.RS +.2i ++.ta 1.0i 3.0i ++.nf ++/defaults type:=nfs;rhost:=bilbo ++apps rfs:=/autofs ++util rhost:=zeus;rfs:=/work/util ++local rfs:=/shared;sublink:=local ++.fi ++.RE ++.sp ++In the first line we have an NFS remote mount of the exported directory ++/autofs from host bilbo which would be mounted on /test/apps. Next ++another nfs mount for the exported directory /work/util from host zeus. ++This would be mounted on /test/util. ++ ++Finally we have an example of the use of the \fBsublink\fP option. In ++this case the filesystem bilbo:/shared would be mounted on a path ++external the automount directory (under the direcory given by ++configuration option auto_dir) and the path /test/local either ++symlinked or bind mounted (depending on the setting autofs_use_lofs) ++to the "local" subdirectory of the external mount. ++.BR + .SH "SEE ALSO" + .BR automount (8), + .BR auto.master (5), + .BR autofs (8), ++.BR autofs.conf (5), + .BR mount (8). + .BR autofs_ldap_auth.conf (5) + .SH AUTHOR +diff --git a/man/autofs.8.in b/man/autofs.8.in +index fae0b00..7ab4242 100644 +--- a/man/autofs.8.in ++++ b/man/autofs.8.in +@@ -49,6 +49,7 @@ will display the status of, + .SH "SEE ALSO" + .BR automount (8), + .BR autofs (5), ++.BR autofs.conf (5), + .BR auto.master (5). + .BR autofs_ldap_auth.conf (5) + .SH AUTHOR +diff --git a/man/autofs.conf.5.in b/man/autofs.conf.5.in +new file mode 100644 +index 0000000..aad4143 +--- /dev/null ++++ b/man/autofs.conf.5.in +@@ -0,0 +1,412 @@ ++.\" t ++.TH AUTOFS.CONF "23 Jan 2014" ++.SH NAME ++autofs.conf \- autofs configuration ++.SH "DESCRIPTION" ++.P ++Configuration settings used by ++.BR automount (8) ++may be changed in the configuration file \fB@@autofsmapdir@@/autofs.conf\fP. ++.P ++This file contains two primary sections, \fBautofs\fP and \fBamd\fP. ++.P ++Configuration entries may be present at the beginning of the ++configuration file without a section header and are implicitly ++included as part of the \fBautofs\fP section. ++.P ++Each section name is enclosed in square brackets with ++spaces between the brackets and the section name. The \fBamd\fP ++section may be followed by further sections, named by the ++top level mount point path, that contain per mount ++configuration settings. ++.SH "SECTION autofs CONFIGURATION OPTIONS" ++.P ++Configuration settings available are: ++.TP ++.B timeout ++.br ++Sets the default mount timeout in seconds. The internal program ++default is 10 minutes, but the default installed configuration ++overrides this and sets the timeout to 5 minutes to be consistent ++with earlier autofs releases. ++.TP ++.B negative_timeout ++.br ++Set the default timeout for caching failed key lookups (program default ++60). If the equivalent command line option is given it will override this ++setting. ++.TP ++.B mount_wait ++.br ++Set the default time to wait for a response from a spawned mount(8) ++before sending it a SIGTERM. Note that we still need to wait for the ++RPC layer to timeout before the sub-process exits so this isn't ideal ++but it is the best we can do. The default is to wait until mount(8) ++returns without intervention. ++.TP ++.B umount_wait ++.br ++Set the default time to wait for a response from a spawned umount(8) ++before sending it a SIGTERM. Note that we still need to wait for the ++RPC layer to timeout before the sub-process exits so this isn't ideal ++but it is the best we can do. ++.TP ++.B browse_mode ++.br ++Maps are browsable by default (program default "yes"). ++.TP ++.B mount_nfs_default_protocol ++.br ++Specify the default protocol used by ++.BR mount.nfs (8) ++(program default 3). Since we can't identify this default automatically ++we need to set it in the autofs configuration. ++.TP ++.B append_options ++.br ++Determine whether global options, given on the command line or per mount ++in the master map, are appended to map entry options or if the map entry ++options replace the global options (program default "yes", append options). ++.TP ++.B logging ++.br ++set default log level "none", "verbose" or "debug" (program default "none"). ++.SS LDAP Configuration ++.P ++Configuration settings available are: ++.TP ++.B ldap_timeout ++.br ++Set the network response timeout (default 8). ++Set timeout value for the synchronous API calls. The default is the LDAP ++library default of an infinite timeout. ++.TP ++.B ldap_network_timeout ++.br ++Set the network response timeout (default 8). ++.TP ++.B ldap_uri ++.br ++A space seperated list of server uris of the form ://[/] ++where can be ldap or ldaps. The option can be given multiple times. ++Map entries that include a server name override this option and it is then ++not used. Default is an empty list in which case either the server given ++in a map entry or the LDAP configured default is used. This uri list is read at ++startup and whenever the daemon receives a HUP signal. ++ ++This configuration option can also be used to request autofs lookup SRV RRs ++for a domain of the form :///[]. Note that a trailing ++"/" is not allowed when using this form. If the domain dn is not specified ++the dns domain name (if any) is used to construct the domain dn for the ++SRV RR lookup. The server list returned from an SRV RR lookup is refreshed ++according to the minimum ttl found in the SRV RR records or after one hour, ++whichever is less. ++.TP ++.B search_base ++.br ++The base dn to use when searching for amap base dn. This entry may be ++given multiple times and each will be checked for a map base dn in ++the order they occur in the configuration. The search base list is read ++at startup and whenever the daemon recieves a HUP signal. ++.TP ++.B map_object_class ++.br ++The map object class. In the \fBnisMap\fP schema this corresponds to the class ++\fBnisMap\fP and in the \fBautomountMap\fP schema it corresponds to the class ++\fBautomountMap\fP. ++.TP ++.B entry_object_class ++.br ++The map entry object class. In the \fBnisMap\fP schema this corresponds ++to the class \fBnisObject\fP and in the \fBautomountMap\fP schema it ++corresponds to the class \fBautomount\fP. ++.TP ++.B map_attribute ++.br ++The attribute used to identify the name of the map to which this ++entry belongs. In the \fBnisMap\fP schema this corresponds to the attribute ++\fBnisMapName\fP and in the \fBautomountMap\fP schema it corresponds to the ++attribute \fBou\fP or \fBautomountMapName\fP. ++.TP ++.B entry_attribute ++.br ++The attribute used to identify a map key. In the \fBnisMap\fP schema this ++corresponds to the attribute \fBcn\fP and in the \fBautomountMap\fP schema ++it corresponds to the attribute \fBautomountKey\fP. ++.TP ++.B value_attribute ++.br ++The attribute used to identify the value of the map entry. In the \fBnisMap\fP ++schema this corresponds to the attribute \fBnisMapEntry\fP and in the \fBautomountMap\fP ++schema it corresponds to the attribute ++.BR automountInformation . ++.TP ++.B NOTE: ++It is essential that entries use class and attribute in a consistent ++manner for correct operation of autofs. For example mixing \fBcn\fP ++and \fBautomountKey\fP attributes in \fBautomount\fP schema will ++not work as expected. ++.TP ++.B auth_conf_file ++This configuration option may be used to specify an alternate location ++for the ldap authentication configuration file. See ++.BR autofs_ldap_auth.conf (5) ++for more information. ++.SH "SECTION amd CONFIGURATION OPTIONS" ++.P ++A number of the amd configuration options are not used by autofs, ++some because they are not relevant within autofs, some because ++they are done differently in autofs and others that are not yet ++implemented. ++ ++Since \fBmount_type\fP is always autofs (because there's no user space ++NFS server) the configuration entries relating to that aren't used. ++Also, server availability is done differently within autofs so the ++options that relate to the amd server monitoring sub-system are ++also not used. ++ ++These options are \fBmount_type\fP, \fBauto_attrcache\fP, \fBportmap_program\fP, ++\fBnfs_vers_ping\fP, \fBnfs_allow_any_interface\fP, \fBnfs_allow_insecure_port\fP, ++\fBnfs_proto\fP, \fBnfs_retransmit_counter\fP, \fBnfs_retransmit_counter_udp\fP, ++\fBnfs_retransmit_counter_tcp\fP, \fBnfs_retransmit_counter_toplvl\fP, ++\fBnfs_retry_interval\fP, \fBnfs_retry_interval_udp\fP, \fBnfs_retry_interval_tcp\fP, ++\fBnfs_retry_interval_toplvl\fP and \fBnfs_vers\fP. ++ ++Other options that are not used within the autofs implementation: ++.TP ++.BR log_file ", " truncate_log ++.br autofs used either stderr when running in the foreground or ++sends its output to syslog so an alternate log file (or truncating ++the log) can't be used. ++.TP ++.B print_pid ++.br ++There's no corresponding option for this within autofs. ++.TP ++.BR use_tcpwrappers ", " show_statfs_entries ++.br ++There's no user space NFS server to control access to so this ++option isn't relevant. The show_statfs_entries can't be ++implemented for the same reason. ++.TP ++.B debug_mtab_file ++.br ++There's no user space NFS server and autofs avoids using file ++based mtab whenever possible. ++.TP ++.B sun_map_syntax ++.br ++Sun map format is handled by autofs itself. ++.TP ++.BR plock ", " show_statfs_entries ", " preferred_amq_port ++.br ++Are not supported by autofs. ++.TP ++.BR ldap_cache_maxmem ", " ldap_cache_seconds ++.br ++External ldap caching is not used by autofs. ++.TP ++.B ldap_proto_version ++.br ++autofs always attempts to use the highest available ldap ++protocol version. ++.TP ++.BR cache_duration ", " map_reload_interval ", " map_options ++.br ++The map entry cache is continually updated and stale entries ++cleaned on re-load, which is done when map changes aredetected ++so these configuration entries are not used by autofs. ++.TP ++.B localhost_address ++This is not used within autofs. This configuration option was ++only used in the amd user space server code and is not relevant ++within autofs. ++.P ++Options that are handled differently within autofs: ++.TP ++.B pid_file ++.br ++To specify a pid file name a command line option must be used on startup. ++.TP ++.B print_version ++.br ++Program version and feature information is obtained by using the ++automount command line option "-V". ++.TP ++.B debug_options ", " log_options ++.br ++autofs has somewhat more limited logging and debug logging options. ++When the log_options options is encountered it is converted to the ++nearest matching autofs logging option. Since the configuration ++option debug_options would be handled the same way it is ignored. ++.TP ++.B restart_mounts ++.br ++This option has no sensible meaning within autofs because autofs ++always tries to re-connect to existing mounts. While this has its ++own set of problems not re-connecting to existing mounts always ++results in a non-functional automount tree if mounts were busy at ++the last shutdown (as is also the case with amd when using ++mount_type autofs). ++.TP ++.B forced_unmounts ++.br ++Detaching mounts often causes serious problems for users of ++existing mounts. It is used by autofs in some cases, either at ++the explicit request of the user (with a command line or init ++option) and in some special cases during program operation but ++is avoided whenever possible. ++.P ++A number of configuration options are not yet implemented: ++.TP ++.B search_path ++.br ++Always a little frustrating, the compiled in map location should ++be used to locate maps but isn't in some cases. This requires ++work within autofs itself and that will (obviously) include ++implementing this configuration option for the amd map parser ++as well. ++.TP ++.B fully_qualified_hosts ++Not yet implemented. ++.TP ++.B unmount_on_exit ++.br ++Since autofs always tries to re-connect to mounts left mounted ++from a previous shutdown this is a sensible option to implement ++and that will be done. ++.TP ++.B browsable_dirs ++.br ++Not yet implemented. ++.TP ++.B exec_map_timeout ++.br ++A timeout is not currently used for for program maps, might be ++implemented. ++.TP ++.B tag ++.br ++The tag option is not implemented within autofs. ++.P ++Supported options: ++.TP ++.BR arch ", " karch ", " os ", " osver ++.br ++These options default to what is returned from uname(2) and can ++be overridden if required. ++.TP ++.B full_os ++This option has no default and must be set in the configuration ++if used in maps. ++.TP ++.B cluster ++.br ++If not set defaults to the host domain name. This option corresponds ++to the HP_UX cluster name (according to the amd source) and is ++probably not used in Linux but is set anyway. ++.TP ++.B vendor ++This option has a default value of "unknown", it must be set in the ++configuration if used in maps. ++.TP ++.B auto_dir ++.br ++Is the base name of the mount tree used for external mounts that ++are sometimes needed by amd maps. Its default value is "/a". ++.TP ++.B map_type ++.br ++Specifies the autofs map source, such as file, nis, ldap etc. and ++has no default value set. ++.TP ++.B map_defaults ++.br ++This option is used to override /defaults entries within maps ++and can be used to provide different defaults on specific machines ++without having to modify centrally managed maps. It is empty by ++default. ++.TP ++.B dismount_interval ++.br ++Is equivalent to the autofs timeout option. It is only possible ++to use this with type "auto" mounts due to the way the autofs ++kernel module performs expiry. It takes its default value from ++the autofs internal defaulti of 600 seconds. ++.TP ++.B autofs_use_lofs ++.br ++If set to "yes" autofs will attempt to use bind mounts for type ++"auto" when possible. ++.TP ++.B nis_domain ++.br ++Allows setting of a domain name other than the system default. ++.TP ++.B local_domain ++.br ++Is used to override (or set) the host domain name. ++.TP ++.B normalize_hostnames ++.br ++If set to "yes" then the contents of ${rhost} is translated in ++its official host name. ++.TP ++.B domain_strip ++.br ++If set to "yes" the domain name part of the host is strippped ++when normalizing hostnames. This can be useful when using of ++the same maps in a multiple domain environment. ++.TP ++.B normalize_slashes ++.br ++This option is set to "yes" by default and will collapse ++multiple unescaped occurrences of "/" to a single "/". ++.TP ++.BR selectors_in_defaults ", " selectors_on_default ++.br ++This option has a default value of "no". If set to "yes" then ++any defaults entry will be checked for selectors to determine ++the values to be used. selectors_in_defaults is the preferred ++option to use. ++.TP ++.B ldap_base ++.br ++iThis option has no default value. It must be set to the base dn ++that is used for queries if ldap is to be used as a map source. ++.TP ++.B ldap_hostports ++.br ++This option has no default value set. It must be set to the URI ++of the LDAP server to be used for lookups wheni ldap is used a ++map source. It may contain a comma or space seperated list of ++LDAP URIs. ++.TP ++.B hesiod_base ++.br ++Sets the base name used for hesiod map sources. ++.SH EXAMPLE ++.sp ++.RS +.2i ++.ta 1.0i ++.nf ++[ autofs ] ++timeout = 300 ++browse_mode = no ++ ++[ amd ] ++dismount_interval = 300 ++map_type = nis ++autofs_use_lofs = no ++ ++[ /expamle/mount ] ++dismount_interval = 60 ++map_type = file ++.fi ++.RE ++.SH "SEE ALSO" ++.BR automount (8), ++.BR auto.master (5), ++.BR autofs_ldap_auth.conf (5) ++.SH AUTHOR ++This manual page was written by Ian Kent . +diff --git a/man/autofs_ldap_auth.conf.5.in b/man/autofs_ldap_auth.conf.5.in +index fa23ce5..fe5077d 100644 +--- a/man/autofs_ldap_auth.conf.5.in ++++ b/man/autofs_ldap_auth.conf.5.in +@@ -113,5 +113,6 @@ externally configured credential cache that is used during authentication. + By default, autofs will setup a memory based credential cache. + .SH "SEE ALSO" + .BR auto.master (5), ++.BR autofs.conf (5), + .SH AUTHOR + This manual page was written by Ian Kent . +diff --git a/man/automount.8 b/man/automount.8 +index 79e53f0..130b24c 100644 +--- a/man/automount.8 ++++ b/man/automount.8 +@@ -172,6 +172,7 @@ constructed has been detached from the mount tree. + .SH "SEE ALSO" + .BR autofs (5), + .BR autofs (8), ++.BR autofs.conf (5), + .BR auto.master (5), + .BR mount (8). + .BR autofs_ldap_auth.conf (5) diff --git a/SOURCES/autofs-5.0.9-amd-lookup-use-config-map_type-if-type-is-not-given.patch b/SOURCES/autofs-5.0.9-amd-lookup-use-config-map_type-if-type-is-not-given.patch new file mode 100644 index 0000000..dba91f1 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-use-config-map_type-if-type-is-not-given.patch @@ -0,0 +1,62 @@ +autofs-5.0.9 - amd lookup use config map_type if type is not given + +From: Ian Kent + +If the map type isn't given in the map defaults or the map location +the attempt to set it from the configuration. + +A NULL map type is valid and means use the nss source list to find +the source of the map. + +This approach may not always give the best result. For example, when +a map type specified in the master map submounts will not inherit +it and will instead use a configured global type instead. Second, +if we want to use nss to find a map source a global map type can't +be defined or it will override the nss source search. +--- + modules/parse_amd.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index e27a195..bf673b3 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -1339,12 +1339,21 @@ struct amd_entry *make_default_entry(struct autofs_point *ap, + char *defaults = "opts:=rw,defaults"; + struct amd_entry *defaults_entry; + struct list_head dflts; ++ char *map_type; + + INIT_LIST_HEAD(&dflts); + if (amd_parse_list(ap, defaults, &dflts, &sv)) + return NULL; + defaults_entry = list_entry(dflts.next, struct amd_entry, list); + list_del_init(&defaults_entry->list); ++ /* ++ * If map type isn't given try to inherit from ++ * parent. A NULL map type is valid and means ++ * use configured nss sources. ++ */ ++ map_type = conf_amd_get_map_type(ap->path); ++ if (map_type) ++ defaults_entry->map_type = strdup(map_type); + /* The list should now be empty .... */ + free_amd_entry_list(&dflts); + return defaults_entry; +@@ -1458,6 +1467,16 @@ static struct amd_entry *get_defaults_entry(struct autofs_point *ap, + if (amd_parse_list(ap, expand, &dflts, &sv)) + goto out; + entry = select_default_entry(ap, &dflts, sv); ++ if (!entry->map_type) { ++ /* ++ * If map type isn't given try to inherit from ++ * parent. A NULL map type is valid and means ++ * use configured nss sources. ++ */ ++ char *map_type = conf_amd_get_map_type(ap->path); ++ if (map_type) ++ entry->map_type = strdup(map_type); ++ } + free(expand); + } + diff --git a/SOURCES/autofs-5.0.9-amd-lookup-use-flags-in-map_source-for-format.patch b/SOURCES/autofs-5.0.9-amd-lookup-use-flags-in-map_source-for-format.patch new file mode 100644 index 0000000..9300486 --- /dev/null +++ b/SOURCES/autofs-5.0.9-amd-lookup-use-flags-in-map_source-for-format.patch @@ -0,0 +1,64 @@ +autofs-5.0.9 - amd lookup use flags in map_source for format + +From: Ian Kent + +We will need to check the map format several times so add a flags +field to the map_source struct so we don't need to use strcmp() +every time. +--- + daemon/lookup.c | 2 ++ + include/master.h | 3 +++ + lib/master.c | 4 ++++ + 3 files changed, 9 insertions(+) + +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -476,6 +476,7 @@ static enum nsswitch_status read_map_sou + } + + this->source[4] = '\0'; ++ tmap.flags = map->flags; + tmap.type = this->source; + tmap.format = map->format; + tmap.lookup = map->lookup; +@@ -879,6 +880,7 @@ static enum nsswitch_status lookup_map_n + } + + this->source[4] = '\0'; ++ tmap.flags = map->flags; + tmap.type = this->source; + tmap.format = map->format; + tmap.mc = map->mc; +--- autofs-5.0.7.orig/include/master.h ++++ autofs-5.0.7/include/master.h +@@ -20,7 +20,10 @@ + #ifndef MASTER_H + #define MASTER_H + ++#define MAP_FLAG_FORMAT_AMD 0x0001 ++ + struct map_source { ++ unsigned int flags; + char *type; + char *format; + time_t exp_timeout; /* Timeout for expiring mounts */ +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -178,6 +178,8 @@ master_add_map_source(struct master_mape + return NULL; + } + source->format = nformat; ++ if (!strcmp(nformat, "amd")) ++ source->flags |= MAP_FLAG_FORMAT_AMD; + } + + source->age = age; +@@ -430,6 +432,8 @@ master_add_source_instance(struct map_so + return NULL; + } + new->format = nformat; ++ if (!strcmp(nformat, "amd")) ++ new->flags |= MAP_FLAG_FORMAT_AMD; + } + + new->age = age; diff --git a/SOURCES/autofs-5.0.9-check-for-non-existent-negative-entries-in-lookup_ghost.patch b/SOURCES/autofs-5.0.9-check-for-non-existent-negative-entries-in-lookup_ghost.patch new file mode 100644 index 0000000..cd7c140 --- /dev/null +++ b/SOURCES/autofs-5.0.9-check-for-non-existent-negative-entries-in-lookup_ghost.patch @@ -0,0 +1,40 @@ +autofs-5.0.9 - check for non existent negative entries in lookup_ghost() + +From: Ian Kent + +Map entries that have been created in the cache due to a negative lookup +but don't exist in the map source shouldn't have directories created. +In fact map entries that are negative shouldn't have directories created +at all since they should have neen created befor the entry became negative. +--- + CHANGELOG | 1 + + daemon/lookup.c | 8 ++++++++ + 2 files changed, 9 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -72,6 +72,7 @@ + - fix protmap not trying proto v2. + - fix negative status being reset on map read. + - fix fix negative status being reset on map read. ++- check for non existent negative entries in lookup_ghost(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -604,6 +604,14 @@ int lookup_ghost(struct autofs_point *ap + cache_readlock(mc); + me = cache_enumerate(mc, NULL); + while (me) { ++ /* ++ * Map entries that have been created in the cache ++ * due to a negative lookup shouldn't have directories ++ * created if they haven't already been created. ++ */ ++ if (!me->mapent) ++ goto next; ++ + if (!strcmp(me->key, "*")) + goto next; + diff --git a/SOURCES/autofs-5.0.9-fix-fix-negative-status-being-reset-on-map-read.patch b/SOURCES/autofs-5.0.9-fix-fix-negative-status-being-reset-on-map-read.patch new file mode 100644 index 0000000..327c81d --- /dev/null +++ b/SOURCES/autofs-5.0.9-fix-fix-negative-status-being-reset-on-map-read.patch @@ -0,0 +1,42 @@ +autofs-5.0.9 - fix fix negative status being reset on map read + +From: Ian Kent + +The original patch to fix the negative status being reset on map +read caused a regression for the case where a negative entry was +created as a result of a lookup matching the wildcard entry. + +It isn't possible to eliminate the key not found in map messages +on map read for this case because there's no way of knowing if +a map change would have fixed the original problem so the negative +entry status must be reset and the mount retried on each map read. +--- + CHANGELOG | 1 + + daemon/lookup.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -71,6 +71,7 @@ + - fix rpc_portmap_getport() proto not set. + - fix protmap not trying proto v2. + - fix negative status being reset on map read. ++- fix fix negative status being reset on map read. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -1041,8 +1041,11 @@ void lookup_prune_one_cache(struct autof + /* + * Reset time of last fail for valid map entries to + * force entry update and subsequent mount retry. ++ * A map entry that's still invalid after a read ++ * may have been created by a failed wildcard lookup ++ * so reset the status on those too. + */ +- if (me->mapent) ++ if (me->mapent || cache_lookup(mc, "*")) + me->status = 0; + me = cache_enumerate(mc, me); + continue; diff --git a/SOURCES/autofs-5.0.9-fix-mistake-in-assignment.patch b/SOURCES/autofs-5.0.9-fix-mistake-in-assignment.patch new file mode 100644 index 0000000..bd3ff22 --- /dev/null +++ b/SOURCES/autofs-5.0.9-fix-mistake-in-assignment.patch @@ -0,0 +1,40 @@ +autofs-5.0.9 - fix mistake in assignment + +From: Ian Kent + +Fix an obvious mistake in an accumulation assignment. +--- + CHANGELOG | 1 + + lib/mounts.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -103,6 +103,7 @@ + - fixes for samples/auto.master. + - fix variable substitution description. + - fix incorrect append options description in README.v5-release. ++- fix mistake in assignment. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -1932,7 +1932,7 @@ int clean_stale_multi_triggers(struct au + /* Check for and umount stale subtree offsets */ + oe_base = oe->key + strlen(root); + ret = clean_stale_multi_triggers(ap, oe, root, oe_base); +- left =+ ret; ++ left += ret; + if (ret) + continue; + +@@ -1977,7 +1977,7 @@ int clean_stale_multi_triggers(struct au + key = strdup(oe->key); + if (!key) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- error(ap->logopt, "malloc: %s", estr); ++ error(ap->logopt, "malloc: %s", estr); + left++; + continue; + } diff --git a/SOURCES/autofs-5.0.9-fix-race-accessing-qdn-in-get_query_dn.patch b/SOURCES/autofs-5.0.9-fix-race-accessing-qdn-in-get_query_dn.patch new file mode 100644 index 0000000..85d651a --- /dev/null +++ b/SOURCES/autofs-5.0.9-fix-race-accessing-qdn-in-get_query_dn.patch @@ -0,0 +1,48 @@ +autofs-5.0.9 - fix race accessing qdn in get_query_dn() + +From: Ian Kent + +Fix a couple of obvious problems in get_query_dn(). + +First, check dn is not NULL before attempting to duplicate it. +And also protect the update of qdn in the context by a mutex. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 9 ++++++--- + 2 files changed, 7 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -129,6 +129,7 @@ + - add serialization to sasl init. + - dont allocate dev_ctl_ops too early. + - fix incorrect round robin host detection. ++- fix race accessing qdn in get_query_dn(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -461,16 +461,19 @@ static int get_query_dn(unsigned logopt, + } + + free(query); +- qdn = strdup(dn); +- ldap_memfree(dn); ++ if (dn) { ++ qdn = strdup(dn); ++ ldap_memfree(dn); ++ } + ldap_msgfree(result); + if (!qdn) + return 0; + ++ uris_mutex_lock(ctxt); + if (ctxt->qdn) + free(ctxt->qdn); +- + ctxt->qdn = qdn; ++ uris_mutex_unlock(ctxt); + + return 1; + } diff --git a/SOURCES/autofs-5.0.9-revert-special-case-cifs-escapes.patch b/SOURCES/autofs-5.0.9-revert-special-case-cifs-escapes.patch new file mode 100644 index 0000000..30f6413 --- /dev/null +++ b/SOURCES/autofs-5.0.9-revert-special-case-cifs-escapes.patch @@ -0,0 +1,91 @@ +autofs-5.0.9 - revert special case cifs escapes + +From: Ian Kent + +The patch this reverts added an additional dquote on the mount location +to revolve "\"s but this causes inconsistent quoting between the lookup +key and the mount location when it is substituted using the &. + +As described in the original patch: +"Since "\" is a valid seperator for cifs shares it can't be used to escape +characters in the share name passed to mount.cifs. So we have no choice +but to require that the seperator we use is "/" and de-quote the string +before sending it to mount.cifs." + +We do need to require that the seperator "/" is used which alone should +eliminate the need for an additional dequote and expect that invalid +share name mounts will fail. +--- + modules/mount_generic.c | 36 ++++++------------------------------ + 1 file changed, 6 insertions(+), 30 deletions(-) + +--- autofs-5.0.7.orig/modules/mount_generic.c ++++ autofs-5.0.7/modules/mount_generic.c +@@ -39,7 +39,6 @@ int mount_mount(struct autofs_point *ap, + { + char fullpath[PATH_MAX]; + char buf[MAX_ERR_BUF]; +- char *loc; + int err; + int len, status, existed = 1; + +@@ -75,44 +74,22 @@ int mount_mount(struct autofs_point *ap, + if (!status) + existed = 0; + +- /* +- * Special case quoting for cifs share names. +- * +- * Since "\" is a valid seperator for cifs shares it can't be +- * used to escape characters in the share name passed to +- * mount.cifs. So we have no choice but to require that the +- * seperator we use is "/" and de-quote the string before +- * sending it to mount.cifs. +- */ +- loc = NULL; +- if (strcmp(fstype, "cifs")) +- loc = strdup(what); +- else +- loc = dequote(what, strlen(what), ap->logopt); +- if (!loc) { +- error(ap->logopt, +- MODPREFIX "failed to alloc buffer for mount location"); +- return 1; +- } +- + if (options && options[0]) { + debug(ap->logopt, + MODPREFIX "calling mount -t %s " SLOPPY "-o %s %s %s", +- fstype, options, loc, fullpath); ++ fstype, options, what, fullpath); + + err = spawn_mount(ap->logopt, "-t", fstype, +- SLOPPYOPT "-o", options, loc, fullpath, NULL); ++ SLOPPYOPT "-o", options, what, fullpath, NULL); + } else { + debug(ap->logopt, MODPREFIX "calling mount -t %s %s %s", +- fstype, loc, fullpath); +- err = spawn_mount(ap->logopt, "-t", fstype, loc, fullpath, NULL); ++ fstype, what, fullpath); ++ err = spawn_mount(ap->logopt, "-t", fstype, what, fullpath, NULL); + } + + if (err) { + info(ap->logopt, MODPREFIX "failed to mount %s (type %s) on %s", +- loc, fstype, fullpath); +- +- free(loc); ++ what, fstype, fullpath); + + if (ap->type != LKP_INDIRECT) + return 1; +@@ -123,8 +100,7 @@ int mount_mount(struct autofs_point *ap, + return 1; + } else { + debug(ap->logopt, MODPREFIX "mounted %s type %s on %s", +- loc, fstype, fullpath); +- free(loc); ++ what, fstype, fullpath); + return 0; + } + } diff --git a/SOURCES/autofs-5.1.0-add-a-prefix-to-program-map-stdvars.patch b/SOURCES/autofs-5.1.0-add-a-prefix-to-program-map-stdvars.patch new file mode 100644 index 0000000..cdccc46 --- /dev/null +++ b/SOURCES/autofs-5.1.0-add-a-prefix-to-program-map-stdvars.patch @@ -0,0 +1,216 @@ +autofs-5.1.0 - add a prefix to program map stdvars + +From: Ian Kent + +When a program map uses an interpreted languages like python it's +possible to load and execute arbitray code from a user home directory. +This is because the standard environment variables are used to locate +and load modules when using these languages. + +To avoid that we need to add a prefix to these environment names so +they aren't used for this purpose. The prefix used is "AUTOFS_" and +is not configurable. +--- + CHANGELOG | 1 + include/mounts.h | 4 +- + lib/mounts.c | 84 +++++++++++++++++++++++++++++++++++++++-------- + modules/lookup_program.c | 2 - + modules/parse_sun.c | 8 ++-- + 5 files changed, 78 insertions(+), 21 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -162,6 +162,7 @@ + - make negative cache update consistent for all lookup modules. + - ensure negative cache isn't updated on remount. + - dont add wildcard to negative cache. ++- add a prefix to program map stdvars. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/mounts.h ++++ autofs-5.0.7/include/mounts.h +@@ -87,8 +87,8 @@ extern unsigned int nfs_mount_uses_strin + + struct amd_entry; + +-struct substvar *addstdenv(struct substvar *sv); +-struct substvar *removestdenv(struct substvar *sv); ++struct substvar *addstdenv(struct substvar *sv, const char *prefix); ++struct substvar *removestdenv(struct substvar *sv, const char *prefix); + void add_std_amd_vars(struct substvar *sv); + void remove_std_amd_vars(void); + struct amd_entry *new_amd_entry(const struct substvar *sv); +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -32,6 +32,7 @@ + + #define MAX_OPTIONS_LEN 80 + #define MAX_MNT_NAME_LEN 30 ++#define MAX_ENV_NAME 15 + + #define EBUFSIZ 1024 + +@@ -328,7 +329,61 @@ int check_nfs_mount_version(struct nfs_m + } + #endif + +-struct substvar *addstdenv(struct substvar *sv) ++static char *set_env_name(const char *prefix, const char *name, char *buf) ++{ ++ size_t len; ++ ++ len = strlen(name); ++ if (prefix) ++ len += strlen(prefix); ++ len++; ++ ++ if (len > MAX_ENV_NAME) ++ return NULL; ++ ++ if (!prefix) ++ strcpy(buf, name); ++ else { ++ strcpy(buf, prefix); ++ strcat(buf, name); ++ } ++ return buf; ++} ++ ++static struct substvar *do_macro_addvar(struct substvar *list, ++ const char *prefix, ++ const char *name, ++ const char *val) ++{ ++ char buf[MAX_ENV_NAME + 1]; ++ char *new; ++ size_t len; ++ ++ new = set_env_name(prefix, name, buf); ++ if (new) { ++ len = strlen(new); ++ list = macro_addvar(list, new, len, val); ++ } ++ return list; ++} ++ ++static struct substvar *do_macro_removevar(struct substvar *list, ++ const char *prefix, ++ const char *name) ++{ ++ char buf[MAX_ENV_NAME + 1]; ++ char *new; ++ size_t len; ++ ++ new = set_env_name(prefix, name, buf); ++ if (new) { ++ len = strlen(new); ++ list = macro_removevar(list, new, len); ++ } ++ return list; ++} ++ ++struct substvar *addstdenv(struct substvar *sv, const char *prefix) + { + struct substvar *list = sv; + struct thread_stdenv_vars *tsv; +@@ -343,14 +398,14 @@ struct substvar *addstdenv(struct substv + num = (long) tsv->uid; + ret = sprintf(numbuf, "%ld", num); + if (ret > 0) +- list = macro_addvar(list, "UID", 3, numbuf); ++ list = do_macro_addvar(list, prefix, "UID", numbuf); + num = (long) tsv->gid; + ret = sprintf(numbuf, "%ld", num); + if (ret > 0) +- list = macro_addvar(list, "GID", 3, numbuf); +- list = macro_addvar(list, "USER", 4, tsv->user); +- list = macro_addvar(list, "GROUP", 5, tsv->group); +- list = macro_addvar(list, "HOME", 4, tsv->home); ++ list = do_macro_addvar(list, prefix, "GID", numbuf); ++ list = do_macro_addvar(list, prefix, "USER", tsv->user); ++ list = do_macro_addvar(list, prefix, "GROUP", tsv->group); ++ list = do_macro_addvar(list, prefix, "HOME", tsv->home); + mv = macro_findvar(list, "HOST", 4); + if (mv) { + char *shost = strdup(mv->val); +@@ -358,7 +413,8 @@ struct substvar *addstdenv(struct substv + char *dot = strchr(shost, '.'); + if (dot) + *dot = '\0'; +- list = macro_addvar(list, "SHOST", 5, shost); ++ list = do_macro_addvar(list, ++ prefix, "SHOST", shost); + free(shost); + } + } +@@ -366,16 +422,16 @@ struct substvar *addstdenv(struct substv + return list; + } + +-struct substvar *removestdenv(struct substvar *sv) ++struct substvar *removestdenv(struct substvar *sv, const char *prefix) + { + struct substvar *list = sv; + +- list = macro_removevar(list, "UID", 3); +- list = macro_removevar(list, "USER", 4); +- list = macro_removevar(list, "HOME", 4); +- list = macro_removevar(list, "GID", 3); +- list = macro_removevar(list, "GROUP", 5); +- list = macro_removevar(list, "SHOST", 5); ++ list = do_macro_removevar(list, prefix, "UID"); ++ list = do_macro_removevar(list, prefix, "USER"); ++ list = do_macro_removevar(list, prefix, "HOME"); ++ list = do_macro_removevar(list, prefix, "GID"); ++ list = do_macro_removevar(list, prefix, "GROUP"); ++ list = do_macro_removevar(list, prefix, "SHOST"); + return list; + } + +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -181,7 +181,7 @@ static char *lookup_one(struct autofs_po + if (ctxt->mapfmt && strcmp(ctxt->mapfmt, "MAPFMT_DEFAULT")) { + struct parse_context *pctxt = (struct parse_context *) ctxt->parse->context; + /* Add standard environment as seen by sun map parser */ +- pctxt->subst = addstdenv(pctxt->subst); ++ pctxt->subst = addstdenv(pctxt->subst, "AUTOFS_"); + macro_setenv(pctxt->subst); + } + execl(ctxt->mapname, ctxt->mapname, name, NULL); +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -1214,12 +1214,12 @@ int parse_mount(struct autofs_point *ap, + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + macro_lock(); + +- ctxt->subst = addstdenv(ctxt->subst); ++ ctxt->subst = addstdenv(ctxt->subst, NULL); + + mapent_len = expandsunent(mapent, NULL, name, ctxt->subst, slashify); + if (mapent_len == 0) { + error(ap->logopt, MODPREFIX "failed to expand map entry"); +- ctxt->subst = removestdenv(ctxt->subst); ++ ctxt->subst = removestdenv(ctxt->subst, NULL); + macro_unlock(); + pthread_setcancelstate(cur_state, NULL); + return 1; +@@ -1229,7 +1229,7 @@ int parse_mount(struct autofs_point *ap, + if (!pmapent) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "alloca: %s", estr); +- ctxt->subst = removestdenv(ctxt->subst); ++ ctxt->subst = removestdenv(ctxt->subst, NULL); + macro_unlock(); + pthread_setcancelstate(cur_state, NULL); + return 1; +@@ -1237,7 +1237,7 @@ int parse_mount(struct autofs_point *ap, + pmapent[mapent_len] = '\0'; + + expandsunent(mapent, pmapent, name, ctxt->subst, slashify); +- ctxt->subst = removestdenv(ctxt->subst); ++ ctxt->subst = removestdenv(ctxt->subst, NULL); + + macro_unlock(); + pthread_setcancelstate(cur_state, NULL); diff --git a/SOURCES/autofs-5.1.0-add-config-option-to-force-use-of-program-map-stdvars.patch b/SOURCES/autofs-5.1.0-add-config-option-to-force-use-of-program-map-stdvars.patch new file mode 100644 index 0000000..d1be23d --- /dev/null +++ b/SOURCES/autofs-5.1.0-add-config-option-to-force-use-of-program-map-stdvars.patch @@ -0,0 +1,186 @@ +autofs-5.1.0 - add config option to force use of program map stdvars + +From: Ian Kent + +Enabling the extended environment (including $HOME, for example) for +program maps opens automount(8) to a privilege escalation. + +Rather than just removing the entended environment a configuration +option is added to disable it by default so that those who wish to +use it can do so if they wish. +--- + CHANGELOG | 1 + + include/defaults.h | 2 ++ + lib/defaults.c | 12 ++++++++++++ + man/autofs.5 | 5 +++++ + man/autofs.conf.5.in | 9 +++++++++ + modules/lookup_program.c | 14 +++++++++++++- + redhat/autofs.conf.default.in | 11 +++++++++++ + samples/autofs.conf.default.in | 11 +++++++++++ + 8 files changed, 64 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -163,6 +163,7 @@ + - ensure negative cache isn't updated on remount. + - dont add wildcard to negative cache. + - add a prefix to program map stdvars. ++- add config option to force use of program map stdvars. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -30,6 +30,7 @@ + #define DEFAULT_UMOUNT_WAIT "12" + #define DEFAULT_BROWSE_MODE "1" + #define DEFAULT_LOGGING "none" ++#define DEFAULT_FORCE_STD_PROG_MAP_ENV "0" + + #define DEFAULT_LDAP_TIMEOUT "-1" + #define DEFAULT_LDAP_NETWORK_TIMEOUT "8" +@@ -151,6 +152,7 @@ unsigned int defaults_get_timeout(void); + unsigned int defaults_get_negative_timeout(void); + unsigned int defaults_get_browse_mode(void); + unsigned int defaults_get_logging(void); ++unsigned int defaults_force_std_prog_map_env(void); + const char *defaults_get_ldap_server(void); + unsigned int defaults_get_ldap_timeout(void); + unsigned int defaults_get_ldap_network_timeout(void); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -50,6 +50,7 @@ + #define NAME_NEGATIVE_TIMEOUT "negative_timeout" + #define NAME_BROWSE_MODE "browse_mode" + #define NAME_LOGGING "logging" ++#define NAME_FORCE_STD_PROG_MAP_ENV "force_standard_program_map_env" + + #define NAME_LDAP_URI "ldap_uri" + #define NAME_LDAP_TIMEOUT "ldap_timeout" +@@ -1589,6 +1590,17 @@ unsigned int defaults_get_logging(void) + return logging; + } + ++unsigned int defaults_force_std_prog_map_env(void) ++{ ++ int res; ++ ++ res = conf_get_yesno(autofs_gbl_sec, NAME_FORCE_STD_PROG_MAP_ENV); ++ if (res < 0) ++ res = atoi(DEFAULT_FORCE_STD_PROG_MAP_ENV); ++ ++ return res; ++} ++ + unsigned int defaults_get_ldap_timeout(void) + { + int res; +--- autofs-5.0.7.orig/man/autofs.5 ++++ autofs-5.0.7/man/autofs.5 +@@ -190,6 +190,11 @@ SHOST Short hostname (domain part remove + .fi + .RE + .sp ++If a program map is used these standard environment variables will have ++a prefix of "AUTOFS_" to prevent interpreted languages like python from ++being able to load and execute arbitray code from a user home directory. ++.RE ++.sp + Additional entries can be defined with the -Dvariable=Value map-option to + .BR automount (8). + .SS Executable Maps +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -71,6 +71,15 @@ options replace the global options (prog + .B logging + .br + set default log level "none", "verbose" or "debug" (program default "none"). ++.TP ++.B force_standard_program_map_env ++.br ++override the use of a prefix with standard environment variables when a ++program map is executed. Since program maps are run as the privileded ++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"). + .SS LDAP Configuration + .P + Configuration settings available are: +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -129,6 +129,7 @@ static char *lookup_one(struct autofs_po + int distance; + int alloci = 1; + int status; ++ char *prefix; + + mapent = (char *) malloc(MAPENT_MAX_LEN + 1); + if (!mapent) { +@@ -174,6 +175,17 @@ static char *lookup_one(struct autofs_po + warn(ap->logopt, + MODPREFIX "failed to set PWD to %s for map %s", + 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. +@@ -181,7 +193,7 @@ static char *lookup_one(struct autofs_po + if (ctxt->mapfmt && strcmp(ctxt->mapfmt, "MAPFMT_DEFAULT")) { + struct parse_context *pctxt = (struct parse_context *) ctxt->parse->context; + /* Add standard environment as seen by sun map parser */ +- pctxt->subst = addstdenv(pctxt->subst, "AUTOFS_"); ++ pctxt->subst = addstdenv(pctxt->subst, prefix); + macro_setenv(pctxt->subst); + } + execl(ctxt->mapname, ctxt->mapname, name, NULL); +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -53,6 +53,17 @@ mount_nfs_default_protocol = 4 + # + #logging = none + # ++# force_standard_program_map_env - disable the use of the "AUTOFS_" ++# prefix for standard environemt variables when ++# executing a program map. Since program maps ++# are run as the privileded user this 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. ++# ++# force_standard_program_map_env = no ++# + # Define base dn for map dn lookup. + # + # Define server URIs +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -52,6 +52,17 @@ browse_mode = no + # + #logging = none + # ++# force_standard_program_map_env - disable the use of the "AUTOFS_" ++# prefix for standard environemt variables when ++# executing a program map. Since program maps ++# are run as the privileded user this 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. ++# ++# force_standard_program_map_env = no ++# + # Define base dn for map dn lookup. + # + # Define server URIs diff --git a/SOURCES/autofs-5.1.0-add-mutex-call-return-check-in-defaults_c.patch b/SOURCES/autofs-5.1.0-add-mutex-call-return-check-in-defaults_c.patch new file mode 100644 index 0000000..bd2b056 --- /dev/null +++ b/SOURCES/autofs-5.1.0-add-mutex-call-return-check-in-defaults_c.patch @@ -0,0 +1,199 @@ +autofs-5.1.0 - add mutex call return check in defaults.c + +From: Ian Kent + +Even though pthread_mutex_lock() and pthread_mutex_unlock() should +never fail checking their return has very occassionally been useful +and isn't consistent with the usage elsewhere. +--- + CHANGELOG | 1 + + lib/defaults.c | 55 ++++++++++++++++++++++++++++++++++--------------------- + 2 files changed, 35 insertions(+), 21 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -145,6 +145,7 @@ + - fix some out of order evaluations in parse_amd.c. + - fix copy and paste error in dup_defaults_entry(). + - fix leak in parse_mount(). ++- add mutex call return check in defaults.c. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -171,6 +171,19 @@ static int conf_update(const char *, con + static void conf_delete(const char *, const char *); + static struct conf_option *conf_lookup(const char *, const char *); + ++static void defaults_mutex_lock(void) ++{ ++ int status = pthread_mutex_lock(&conf_mutex); ++ if (status) ++ fatal(status); ++} ++ ++static void defaults_mutex_unlock(void) ++{ ++ int status = pthread_mutex_unlock(&conf_mutex); ++ if (status) ++ fatal(status); ++} + + static void message(unsigned int to_syslog, const char *msg, ...) + { +@@ -253,9 +266,9 @@ static void __conf_release(void) + + void defaults_conf_release(void) + { +- pthread_mutex_lock(&conf_mutex); ++ defaults_mutex_lock(); + __conf_release(); +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + return; + } + +@@ -727,11 +740,11 @@ static unsigned int conf_section_exists( + return 0; + + ret = 0; +- pthread_mutex_lock(&conf_mutex); ++ defaults_mutex_lock(); + co = conf_lookup(section, section); + if (co) + ret = 1; +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + + return ret; + } +@@ -1057,7 +1070,7 @@ unsigned int defaults_read_config(unsign + + conf = oldconf = NULL; + +- pthread_mutex_lock(&conf_mutex); ++ defaults_mutex_lock(); + if (!config) { + if (conf_init()) { + message(to_syslog, "failed to init config"); +@@ -1149,7 +1162,7 @@ out: + fclose(conf); + if (oldconf) + fclose(oldconf); +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + return ret; + } + +@@ -1158,11 +1171,11 @@ static char *conf_get_string(const char + struct conf_option *co; + char *val = NULL; + +- pthread_mutex_lock(&conf_mutex); ++ defaults_mutex_lock(); + co = conf_lookup(section, name); + if (co && co->value) + val = strdup(co->value); +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + return val; + } + +@@ -1171,11 +1184,11 @@ static long conf_get_number(const char * + struct conf_option *co; + long val = -1; + +- pthread_mutex_lock(&conf_mutex); ++ defaults_mutex_lock(); + co = conf_lookup(section, name); + if (co && co->value) + val = atol(co->value); +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + return val; + } + +@@ -1184,7 +1197,7 @@ static int conf_get_yesno(const char *se + struct conf_option *co; + int val = -1; + +- pthread_mutex_lock(&conf_mutex); ++ defaults_mutex_lock(); + co = conf_lookup(section, name); + if (co && co->value) { + if (isdigit(*co->value)) +@@ -1194,7 +1207,7 @@ static int conf_get_yesno(const char *se + else if (!strcasecmp(co->value, "no")) + val = 0; + } +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + return val; + } + +@@ -1271,10 +1284,10 @@ struct list_head *defaults_get_uris(void + return NULL; + } + +- pthread_mutex_lock(&conf_mutex); ++ defaults_mutex_lock(); + co = conf_lookup(autofs_gbl_sec, NAME_LDAP_URI); + if (!co) { +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + free(list); + return NULL; + } +@@ -1285,7 +1298,7 @@ struct list_head *defaults_get_uris(void + add_uris(co->value, list); + co = co->next; + } +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + + if (list_empty(list)) { + free(list); +@@ -1397,10 +1410,10 @@ struct ldap_searchdn *defaults_get_searc + if (!defaults_read_config(0)) + return NULL; + +- pthread_mutex_lock(&conf_mutex); ++ defaults_mutex_lock(); + co = conf_lookup(autofs_gbl_sec, NAME_SEARCH_BASE); + if (!co) { +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + return NULL; + } + +@@ -1416,7 +1429,7 @@ struct ldap_searchdn *defaults_get_searc + + new = alloc_searchdn(co->value); + if (!new) { +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + defaults_free_searchdns(sdn); + return NULL; + } +@@ -1433,7 +1446,7 @@ struct ldap_searchdn *defaults_get_searc + + co = co->next; + } +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + + return sdn; + } +@@ -1511,9 +1524,9 @@ int defaults_master_set(void) + { + struct conf_option *co; + +- pthread_mutex_lock(&conf_mutex); ++ defaults_mutex_lock(); + co = conf_lookup(autofs_gbl_sec, NAME_MASTER_MAP); +- pthread_mutex_unlock(&conf_mutex); ++ defaults_mutex_unlock(); + if (co) + return 1; + return 0; diff --git a/SOURCES/autofs-5.1.0-add-return-check-in-ldap-check_map_indirect.patch b/SOURCES/autofs-5.1.0-add-return-check-in-ldap-check_map_indirect.patch new file mode 100644 index 0000000..4609bf8 --- /dev/null +++ b/SOURCES/autofs-5.1.0-add-return-check-in-ldap-check_map_indirect.patch @@ -0,0 +1,68 @@ +autofs-5.1.0 - add return check in ldap check_map_indirect() + +From: Ian Kent + +Fix not checking return from pthread_mutex_lock/pthread_mutex_unlock in +modules/lookup_ldap.c:check_map_indirect(). +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 17 +++++++++++++---- + 2 files changed, 14 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -139,6 +139,7 @@ + - fix leak in get_network_proximity(). + - fix buffer size checks in merge_options(). + - check amd lex buffer len before copy. ++- add return check in ldap check_map_indirect(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -3420,12 +3420,15 @@ static int check_map_indirect(struct aut + time_t now = time(NULL); + time_t t_last_read; + int ret, cur_state; ++ int status; + + mc = source->mc; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + +- pthread_mutex_lock(&ap->entry->current_mutex); ++ status = pthread_mutex_lock(&ap->entry->current_mutex); ++ if (status) ++ fatal(status); + if (is_amd_format) { + unsigned long timestamp = get_amd_timestamp(ctxt); + if (timestamp > ctxt->timestamp) { +@@ -3445,7 +3448,9 @@ static int check_map_indirect(struct aut + ctxt->check_defaults = 0; + } + } +- pthread_mutex_unlock(&ap->entry->current_mutex); ++ status = pthread_mutex_unlock(&ap->entry->current_mutex); ++ if (status) ++ fatal(status); + + ret = match_key(ap, source, key, key_len, ctxt); + if (ret == CHE_FAIL) { +@@ -3490,10 +3495,14 @@ static int check_map_indirect(struct aut + } + cache_unlock(mc); + +- pthread_mutex_lock(&ap->entry->current_mutex); ++ status = pthread_mutex_lock(&ap->entry->current_mutex); ++ if (status) ++ fatal(status); + if (t_last_read > ap->exp_runfreq && ret & CHE_UPDATED) + source->stale = 1; +- pthread_mutex_unlock(&ap->entry->current_mutex); ++ status = pthread_mutex_unlock(&ap->entry->current_mutex); ++ if (status) ++ fatal(status); + } + + cache_readlock(mc); diff --git a/SOURCES/autofs-5.1.0-add-serialization-to-sasl-init.patch b/SOURCES/autofs-5.1.0-add-serialization-to-sasl-init.patch new file mode 100644 index 0000000..8ed0796 --- /dev/null +++ b/SOURCES/autofs-5.1.0-add-serialization-to-sasl-init.patch @@ -0,0 +1,92 @@ +autofs-5.1.0 - add serialization to sasl init + +From: Ian Kent + +Attempt to resolve crash in sasl initialization. We know that the +initial connection calls to connect to an LDAP server are not +thread safe and it looks like the sasl code doesn't take that into +consideration so adding serialization with a mutex is probably a +sensible thing to do. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 13 +++++++++++++ + 2 files changed, 14 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -126,6 +126,7 @@ + - cleanup options in amd_parse.c + - allow empty value for some map options. + - allow empty value in macro selectors. ++- add serialization to sasl init. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -578,7 +578,9 @@ static int do_bind(unsigned logopt, LDAP + 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); +@@ -922,7 +924,9 @@ static LDAP *do_reconnect(unsigned logop + #ifdef WITH_SASL + /* Dispose of the sasl authentication connection and try again. */ + if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) { ++ ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); ++ ldapinit_mutex_unlock(); + ldap = connect_to_server(logopt, ctxt->server, ctxt); + } + #endif +@@ -958,7 +962,9 @@ static LDAP *do_reconnect(unsigned logop + * current server again before trying other servers in the list. + */ + if (!ldap && ctxt->auth_required & LDAP_NEED_AUTH) { ++ ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); ++ ldapinit_mutex_unlock(); + ldap = connect_to_server(logopt, ctxt->uri->uri, ctxt); + } + #endif +@@ -969,7 +975,9 @@ static LDAP *do_reconnect(unsigned logop + + find_server: + #ifdef WITH_SASL ++ ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); ++ ldapinit_mutex_unlock(); + #endif + + /* Current server failed, try the rest or dc connection */ +@@ -1742,11 +1750,14 @@ int lookup_init(const char *mapfmt, int + + #ifdef WITH_SASL + /* Init the sasl callbacks */ ++ ldapinit_mutex_lock(); + 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(); + #endif + + if (is_amd_format) +@@ -3678,8 +3689,10 @@ int lookup_done(void *context) + struct lookup_context *ctxt = (struct lookup_context *) context; + int rv = close_parse(ctxt->parse); + #ifdef WITH_SASL ++ ldapinit_mutex_lock(); + autofs_sasl_dispose(ctxt); + autofs_sasl_done(); ++ ldapinit_mutex_unlock(); + #endif + free_context(ctxt); + return rv; diff --git a/SOURCES/autofs-5.1.0-beta1-add-plus-to-path-match-pattern.patch b/SOURCES/autofs-5.1.0-beta1-add-plus-to-path-match-pattern.patch new file mode 100644 index 0000000..224f399 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-add-plus-to-path-match-pattern.patch @@ -0,0 +1,39 @@ +autofs-5.1.0-beta1 - add plus to path match pattern + +From: Ian Kent + +The pattern matching in the tokenizer is very strict and quite +limited. That's been done (initially) to ensure that the parsing +of other parts of map entries is accurate and to ensure that +error cases are handled cleanly since the strict matching will +cause errors. + +I don't want to open up patterns that probably need it to accept +a wide range of characters just yet but adding "+" to the match +is obviously needed. +--- + CHANGELOG | 1 + + modules/amd_tok.l | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -121,6 +121,7 @@ + - fix ldap_uri config update. + - fix typo in conf_load_autofs_defaults(). + - fix hash on confg option add and delete. ++- add plus to path match pattern. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/amd_tok.l ++++ autofs-5.0.7/modules/amd_tok.l +@@ -81,7 +81,7 @@ V4NUM ([01]?[0-9][0-9]?|2[0-4][0-9]|25[ + MACRO (\$\{([[:alpha:]_/]([[:alnum:]_\-])([[:alnum:]_\-/])*)\}) + QSTR (\"([^"\\]|\\.)*\") + OSTR ([[:alpha:]]([[:alnum:]_\-])+) +-FSTR ([[:alnum:]_/\.]([[:alnum:]_\-/\.]|(\\.))*) ++FSTR ([[:alnum:]_/\.]([[:alnum:]_\-/\+\.]|(\\.))*) + VSTR (([[:alnum:]_\-\:/\.])+) + SSTR ([[:alpha:]]([[:alnum:]\-\.])+) + IP4ADDR ({V4NUM}\.((({V4NUM}\.){0,2}){V4NUM}?)) diff --git a/SOURCES/autofs-5.1.0-beta1-allow-empty-value-for-some-map-options.patch b/SOURCES/autofs-5.1.0-beta1-allow-empty-value-for-some-map-options.patch new file mode 100644 index 0000000..a55c6f5 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-allow-empty-value-for-some-map-options.patch @@ -0,0 +1,570 @@ +autofs-5.1.0-beta1 - allow empty value for some map options + +From: Ian Kent + +Some map options may be given but left blank, possibly with the intent +the mount location mount attempt will not be done or fail, such as when +the delay option is also given. + +autofs doesn't implement the delay option but it shouldn't fail to parse +these locations so that a valid locations in the list can be tried. +--- + CHANGELOG | 1 + lib/parse_subs.c | 12 +++- + modules/amd_parse.y | 36 ++++++++++++++ + modules/amd_tok.l | 35 ++++++++++++-- + modules/parse_amd.c | 125 ++++++++++++++++++++++++++++++++-------------------- + 5 files changed, 155 insertions(+), 54 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -124,6 +124,7 @@ + - add plus to path match pattern. + - fix multi entry ldap option handling. + - cleanup options in amd_parse.c ++- allow empty value for some map options. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/parse_subs.c ++++ autofs-5.0.7/lib/parse_subs.c +@@ -889,14 +889,20 @@ char *merge_options(const char *opt1, co + char *tok, *ptr = NULL; + size_t len; + +- if (!opt1 && !opt2) ++ if ((!opt1 || !*opt1) && (!opt2 || !*opt2)) + return NULL; + +- if (!opt2) ++ if (!opt2 || !*opt2) { ++ if (!*opt1) ++ return NULL; + return strdup(opt1); ++ } + +- if (!opt1) ++ if (!opt1 || !*opt1) { ++ if (!*opt2) ++ return NULL; + return strdup(opt2); ++ } + + if (!strcmp(opt1, opt2)) + return strdup(opt1); +--- autofs-5.0.7.orig/modules/amd_parse.y ++++ autofs-5.0.7/modules/amd_parse.y +@@ -335,6 +335,15 @@ option_assignment: MAP_OPTION OPTION_ASS + YYABORT; + } + } ++ | MAP_OPTION OPTION_ASSIGN ++ { ++ if (!strcmp($1, "fs")) ++ entry.fs = amd_strdup(""); ++ else { ++ amd_notify($1); ++ YYABORT; ++ } ++ } + | FS_OPTION OPTION_ASSIGN FS_OPT_VALUE + { + if (!strcmp($1, "rhost")) +@@ -358,6 +367,19 @@ option_assignment: MAP_OPTION OPTION_ASS + YYABORT; + } + } ++ | FS_OPTION OPTION_ASSIGN ++ { ++ if (!strcmp($1, "rhost")) ++ entry.rhost = amd_strdup(""); ++ else if (!strcmp($1, "rfs")) ++ entry.rfs = amd_strdup(""); ++ else if (!strcmp($1, "dev")) ++ entry.dev = amd_strdup(""); ++ else { ++ amd_notify($1); ++ YYABORT; ++ } ++ } + | MNT_OPTION OPTION_ASSIGN options + { + memset(opts, 0, sizeof(opts)); +@@ -370,6 +392,20 @@ option_assignment: MAP_OPTION OPTION_ASS + else { + amd_notify($1); + YYABORT; ++ } ++ } ++ | MNT_OPTION OPTION_ASSIGN ++ { ++ memset(opts, 0, sizeof(opts)); ++ if (!strcmp($1, "opts")) ++ entry.opts = amd_strdup(""); ++ else if (!strcmp($1, "addopts")) ++ entry.addopts = amd_strdup(""); ++ else if (!strcmp($1, "remopts")) ++ entry.remopts = amd_strdup(""); ++ else { ++ amd_notify($1); ++ YYABORT; + } + } + | MAP_OPTION OPTION_ASSIGN CACHE_OPTION +--- autofs-5.0.7.orig/modules/amd_tok.l ++++ autofs-5.0.7/modules/amd_tok.l +@@ -177,9 +177,14 @@ CUTSEP (\|\||\/) + } + + { +- {NL} | ++ {NL} { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ + \x00 { + BEGIN(INITIAL); ++ return SEPERATOR; + yyless(1); + } + +@@ -217,9 +222,14 @@ CUTSEP (\|\||\/) + } + + { +- {NL} | ++ {NL} { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ + \x00 { + BEGIN(INITIAL); ++ return SEPERATOR; + yyless(1); + } + +@@ -242,9 +252,14 @@ CUTSEP (\|\||\/) + } + + { +- {NL} | ++ {NL} { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ + \x00 { + BEGIN(INITIAL); ++ return SEPERATOR; + yyless(1); + } + +@@ -269,9 +284,14 @@ CUTSEP (\|\||\/) + } + + { +- {NL} | ++ {NL} { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ + \x00 { + BEGIN(INITIAL); ++ return SEPERATOR; + yyless(1); + } + +@@ -296,9 +316,14 @@ CUTSEP (\|\||\/) + } + + { +- {NL} | ++ {NL} { ++ BEGIN(INITIAL); ++ yyless(1); ++ } ++ + \x00 { + BEGIN(INITIAL); ++ return SEPERATOR; + yyless(1); + } + +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -683,7 +683,7 @@ static struct substvar *expand_entry(str + unsigned int logopt = ap->logopt; + char *expand; + +- if (entry->rhost) { ++ if (entry->rhost && *entry->rhost) { + char *host = strdup(entry->rhost); + char *nn; + if (!host) { +@@ -720,7 +720,7 @@ next: + sv = macro_addvar(sv, "sublink", 7, entry->sublink); + } + +- if (entry->rfs) { ++ if (entry->rfs && *entry->rfs) { + if (expand_selectors(ap, entry->rfs, &expand, sv)) { + debug(logopt, MODPREFIX + "rfs expand(\"%s\") -> %s", entry->rfs, expand); +@@ -730,7 +730,7 @@ next: + sv = macro_addvar(sv, "rfs", 3, entry->rfs); + } + +- if (entry->fs) { ++ if (entry->fs && *entry->fs) { + if (expand_selectors(ap, entry->fs, &expand, sv)) { + debug(logopt, MODPREFIX + "fs expand(\"%s\") -> %s", entry->fs, expand); +@@ -740,7 +740,7 @@ next: + sv = macro_addvar(sv, "fs", 2, entry->fs); + } + +- if (entry->opts) { ++ if (entry->opts && *entry->opts) { + if (expand_selectors(ap, entry->opts, &expand, sv)) { + debug(logopt, MODPREFIX + "ops expand(\"%s\") -> %s", entry->opts, expand); +@@ -750,7 +750,7 @@ next: + sv = macro_addvar(sv, "opts", 4, entry->opts); + } + +- if (entry->addopts) { ++ if (entry->addopts && *entry->addopts) { + if (expand_selectors(ap, entry->addopts, &expand, sv)) { + debug(logopt, MODPREFIX + "addopts expand(\"%s\") -> %s", +@@ -761,7 +761,7 @@ next: + sv = macro_addvar(sv, "addopts", 7, entry->addopts); + } + +- if (entry->remopts) { ++ if (entry->remopts && *entry->remopts) { + if (expand_selectors(ap, entry->remopts, &expand, sv)) { + debug(logopt, MODPREFIX + "remopts expand(\"%s\") -> %s", +@@ -781,7 +781,7 @@ static void expand_merge_options(struct + { + char *tmp; + +- if (entry->opts) { ++ if (entry->opts && *entry->opts) { + if (!expand_selectors(ap, entry->opts, &tmp, sv)) + error(ap->logopt, MODPREFIX "failed to expand opts"); + else { +@@ -790,7 +790,7 @@ static void expand_merge_options(struct + } + } + +- if (entry->addopts) { ++ if (entry->addopts && *entry->addopts) { + if (!expand_selectors(ap, entry->addopts, &tmp, sv)) + error(ap->logopt, MODPREFIX "failed to expand addopts"); + else { +@@ -799,7 +799,7 @@ static void expand_merge_options(struct + } + } + +- if (entry->remopts) { ++ if (entry->remopts && *entry->remopts) { + if (!expand_selectors(ap, entry->remopts, &tmp, sv)) + error(ap->logopt, MODPREFIX "failed to expand remopts"); + else { +@@ -832,11 +832,13 @@ static struct substvar *merge_entry_opti + entry->opts = tmp; + sv = macro_addvar(sv, "opts", 4, entry->opts); + } +- tmp = strdup(entry->opts); +- if (tmp) { +- free(entry->remopts); +- entry->remopts = tmp; +- sv = macro_addvar(sv, "remopts", 7, entry->remopts); ++ if (*entry->opts) { ++ tmp = strdup(entry->opts); ++ if (tmp) { ++ free(entry->remopts); ++ entry->remopts = tmp; ++ sv = macro_addvar(sv, "remopts", 7, entry->remopts); ++ } + } + return sv; + } +@@ -853,7 +855,7 @@ static struct substvar *merge_entry_opti + entry->opts = tmp; + sv = macro_addvar(sv, "opts", 4, entry->opts); + } +- } else if (entry->addopts) { ++ } else if (entry->addopts && *entry->addopts) { + tmp = strdup(entry->addopts); + if (tmp) { + info(ap->logopt, MODPREFIX +@@ -875,7 +877,7 @@ static struct substvar *merge_entry_opti + entry->remopts = tmp; + sv = macro_addvar(sv, "remopts", 7, entry->remopts); + } +- } else if (entry->addopts) { ++ } else if (entry->addopts && *entry->addopts) { + tmp = strdup(entry->addopts); + if (tmp) { + info(ap->logopt, MODPREFIX +@@ -910,6 +912,7 @@ static int do_link_mount(struct autofs_p + struct amd_entry *entry, unsigned int flags) + { + char target[PATH_MAX + 1]; ++ const char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL; + int ret; + + if (entry->sublink) +@@ -922,7 +925,7 @@ static int do_link_mount(struct autofs_p + + /* For a sublink this might cause an external mount */ + ret = do_mount(ap, ap->path, +- name, strlen(name), target, "bind", entry->opts); ++ name, strlen(name), target, "bind", opts); + if (!ret) + goto out; + +@@ -967,12 +970,13 @@ static int do_generic_mount(struct autof + struct amd_entry *entry, const char *target, + unsigned int flags) + { ++ const char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL; + unsigned int umount = 0; + int ret = 0; + + if (!entry->fs) { +- ret = do_mount(ap, ap->path, name, strlen(name), +- target, entry->type, entry->opts); ++ ret = do_mount(ap, ap->path, name, ++ strlen(name), target, entry->type, opts); + } else { + /* + * Careful, external mounts may get mounted +@@ -981,7 +985,7 @@ static int do_generic_mount(struct autof + */ + if (!is_mounted(_PATH_MOUNTED, entry->fs, MNTS_REAL)) { + ret = do_mount(ap, entry->fs, "/", 1, +- target, entry->type, entry->opts); ++ target, entry->type, opts); + if (ret) + goto out; + umount = 1; +@@ -999,7 +1003,7 @@ static int do_nfs_mount(struct autofs_po + { + char target[PATH_MAX + 1]; + unsigned int proximity; +- char *opts = entry->opts; ++ char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL; + unsigned int umount = 0; + int ret = 0; + +@@ -1008,7 +1012,7 @@ static int do_nfs_mount(struct autofs_po + strcat(target, entry->rfs); + + proximity = get_network_proximity(entry->rhost); +- if (proximity == PROXIMITY_OTHER && entry->remopts) ++ if (proximity == PROXIMITY_OTHER && entry->remopts && *entry->remopts) + opts = entry->remopts; + + if (!entry->fs) { +@@ -1120,7 +1124,7 @@ static int do_host_mount(struct autofs_p + goto out; + } + +- if (entry->opts) { ++ if (entry->opts && *entry->opts) { + argv[0] = entry->opts; + argv[1] = NULL; + pargv = argv; +@@ -1180,9 +1184,13 @@ static unsigned int validate_auto_option + /* + * The amd manual implies all the mount type auto options + * are optional but I don't think there's much point if +- * no map is given. ++ * no map is given. If the option has been intentionally ++ * left blank the mount must be expected to fail so don't ++ * report the error. + */ +- if (!entry->fs) { ++ if (!*entry->fs) ++ return 0; ++ else if (!entry->fs) { + error(logopt, MODPREFIX + "%s: file system not given", entry->type); + return 0; +@@ -1201,11 +1209,19 @@ static unsigned int validate_nfs_options + struct amd_entry *entry) + { + /* +- * Required option rhost will always have a value. +- * It is set from ${host} if it is found to be NULL +- * earlier in the parsing process. ++ * Required option rhost will always have a value unless ++ * it has been intentionally left blank. It is set from ++ * ${host} if it is found to be NULL earlier in the parsing ++ * process. Don't report the error if it has been left blank ++ * or if the fs option has been left blank since the mount is ++ * expected to fail. + */ +- if (!entry->rfs) { ++ if (!entry->rfs || !*entry->rfs) { ++ if (!*entry->rfs) ++ return 0; ++ /* Map option fs has been intentionally left blank */ ++ if (entry->fs && !*entry->fs) ++ return 0; + if (entry->fs) + entry->rfs = strdup(entry->fs); + if (!entry->rfs) { +@@ -1226,14 +1242,22 @@ static unsigned int validate_generic_opt + unsigned long fstype, + struct amd_entry *entry) + { ++ /* ++ * If dev or rfs are empty in the map entry the mount is ++ * expected to fail so don't report the error. ++ */ + if (fstype != AMD_MOUNT_TYPE_LOFS) { +- if (!entry->dev) { ++ if (!*entry->dev) ++ return 0; ++ else if (!entry->dev) { + error(logopt, MODPREFIX + "%s: mount device not given", entry->type); + return 0; + } + } else { +- if (!entry->rfs) { ++ if (!*entry->rfs) ++ return 0; ++ else if (!entry->rfs) { + /* + * Can't use entry->type as the mount type to reprot + * the error since entry->type == "bind" not "lofs". +@@ -1270,11 +1294,14 @@ static unsigned int validate_host_option + struct amd_entry *entry) + { + /* +- * Not really that useful since rhost is always non-null +- * because it will have the the value of the host name if +- * it isn't set in the map entry. ++ * rhost is always non-null, unless it is intentionally left ++ * empty, because it will have the the value of the host name ++ * if it isn't given in the map entry. Don't report an error ++ * if it has been left empty since it's expected to fail. + */ +- if (!entry->rhost) { ++ if (!*entry->rhost) ++ return 0; ++ else if (!entry->rhost) { + error(logopt, MODPREFIX + "%s: remote host name not given", entry->type); + return 0; +@@ -1382,7 +1409,7 @@ void dequote_entry(struct autofs_point * + } + } + +- if (entry->fs) { ++ if (entry->fs && *entry->fs) { + res = dequote(entry->fs, strlen(entry->fs), ap->logopt); + if (res) { + debug(ap->logopt, +@@ -1393,7 +1420,7 @@ void dequote_entry(struct autofs_point * + } + } + +- if (entry->rfs) { ++ if (entry->rfs && *entry->rfs) { + res = dequote(entry->rfs, strlen(entry->rfs), ap->logopt); + if (res) { + debug(ap->logopt, +@@ -1404,7 +1431,7 @@ void dequote_entry(struct autofs_point * + } + } + +- if (entry->opts) { ++ if (entry->opts && *entry->opts) { + res = dequote(entry->opts, strlen(entry->opts), ap->logopt); + if (res) { + debug(ap->logopt, +@@ -1415,7 +1442,7 @@ void dequote_entry(struct autofs_point * + } + } + +- if (entry->remopts) { ++ if (entry->remopts && *entry->remopts) { + res = dequote(entry->remopts, strlen(entry->remopts), ap->logopt); + if (res) { + debug(ap->logopt, +@@ -1426,7 +1453,7 @@ void dequote_entry(struct autofs_point * + } + } + +- if (entry->addopts) { ++ if (entry->addopts && *entry->addopts) { + res = dequote(entry->addopts, strlen(entry->addopts), ap->logopt); + if (res) { + debug(ap->logopt, +@@ -1446,6 +1473,10 @@ static void normalize_sublink(unsigned i + char *new; + size_t len; + ++ /* Normalizing sublink requires a non-blank fs option */ ++ if (!*entry->fs) ++ return; ++ + if (entry->sublink && *entry->sublink != '/') { + len = strlen(entry->fs) + strlen(entry->sublink) + 2; + new = malloc(len); +@@ -1559,37 +1590,39 @@ static struct amd_entry *dup_defaults_en + entry->fs = tmp; + } + +- if (defaults->rfs) { ++ /* These shouldn't be blank in a defaults entry but ... */ ++ ++ if (defaults->rfs && *defaults->rfs) { + tmp = strdup(defaults->rfs); + if (tmp) + entry->rfs = tmp; + } + +- if (defaults->rhost) { ++ if (defaults->rhost && *defaults->rfs) { + tmp = strdup(defaults->rhost); + if (tmp) + entry->rhost = tmp; + } + +- if (defaults->dev) { ++ if (defaults->dev && *defaults->dev) { + tmp = strdup(defaults->dev); + if (tmp) + entry->dev = tmp; + } + +- if (defaults->opts) { ++ if (defaults->opts && *defaults->opts) { + tmp = strdup(defaults->opts); + if (tmp) + entry->opts = tmp; + } + +- if (defaults->addopts) { ++ if (defaults->addopts && *defaults->addopts) { + tmp = strdup(defaults->addopts); + if (tmp) + entry->addopts = tmp; + } + +- if (defaults->remopts) { ++ if (defaults->remopts && *defaults->remopts) { + tmp = strdup(defaults->remopts); + if (tmp) + entry->remopts = tmp; diff --git a/SOURCES/autofs-5.1.0-beta1-allow-empty-value-in-macro-selectors.patch b/SOURCES/autofs-5.1.0-beta1-allow-empty-value-in-macro-selectors.patch new file mode 100644 index 0000000..7e92c4f --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-allow-empty-value-in-macro-selectors.patch @@ -0,0 +1,74 @@ +autofs-5.1.0-beta1 - allow empty value in macro selectors + +From: Ian Kent + +Some map selectors (this case is olny considering macro selectors) may +be given the comparison value left blank, possibly with the intent the +selector will not match so a mount will not be attempted, such as when +the delay option is also given. + +autofs doesn't implement the delay option but it shouldn't fail to parse +these locations so that a valid locations in the list can be tried. +--- + CHANGELOG | 1 + + modules/amd_parse.y | 14 ++++++++++++++ + modules/parse_amd.c | 9 +++++++-- + 3 files changed, 22 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -125,6 +125,7 @@ + - fix multi entry ldap option handling. + - cleanup options in amd_parse.c + - allow empty value for some map options. ++- allow empty value in macro selectors. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/amd_parse.y ++++ autofs-5.0.7/modules/amd_parse.y +@@ -200,12 +200,26 @@ selection: SELECTOR IS_EQUAL SELECTOR_VA + YYABORT; + } + } ++ | SELECTOR IS_EQUAL ++ { ++ if (!make_selector($1, "", NULL, SEL_COMP_EQUAL)) { ++ amd_notify($1); ++ YYABORT; ++ } ++ } + | SELECTOR NOT_EQUAL SELECTOR_VALUE + { + if (!make_selector($1, $3, NULL, SEL_COMP_NOTEQUAL)) { + amd_notify($1); + YYABORT; + } ++ } ++ | SELECTOR NOT_EQUAL ++ { ++ if (!make_selector($1, "", NULL, SEL_COMP_EQUAL)) { ++ amd_notify($1); ++ YYABORT; ++ } + } + | SELECTOR LBRACKET SEL_ARG_VALUE RBRACKET + { +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -350,8 +350,13 @@ static int eval_selector(unsigned int lo + break; + + case SEL_FLAG_NUM: +- res = atoi(v->val); +- val = atoi(s->comp.value); ++ if (!*s->comp.value) { ++ res = 1; ++ val = 0; ++ } else { ++ res = atoi(v->val); ++ val = atoi(s->comp.value); ++ } + if (s->compare & SEL_COMP_EQUAL && res == val) { + debug(logopt, MODPREFIX + "matched selector %s(%s) equal to %s", diff --git a/SOURCES/autofs-5.1.0-beta1-cleanup-options-in-amd_parse-c.patch b/SOURCES/autofs-5.1.0-beta1-cleanup-options-in-amd_parse-c.patch new file mode 100644 index 0000000..3620ce0 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-cleanup-options-in-amd_parse-c.patch @@ -0,0 +1,46 @@ +autofs-5.1.0-beta1 - cleanup options in amd_parse.c + +From: Ian Kent + +Remove useless duplicated memset() calls from mount options handling +in the amd parser. +--- + CHANGELOG | 1 + + modules/amd_parse.y | 13 +++++-------- + 2 files changed, 6 insertions(+), 8 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -123,6 +123,7 @@ + - fix hash on confg option add and delete. + - add plus to path match pattern. + - fix multi entry ldap option handling. ++- cleanup options in amd_parse.c + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/amd_parse.y ++++ autofs-5.0.7/modules/amd_parse.y +@@ -360,17 +360,14 @@ option_assignment: MAP_OPTION OPTION_ASS + } + | MNT_OPTION OPTION_ASSIGN options + { +- if (!strcmp($1, "opts")) { ++ memset(opts, 0, sizeof(opts)); ++ if (!strcmp($1, "opts")) + entry.opts = amd_strdup(opts); +- memset(opts, 0, sizeof(opts)); +- } else if (!strcmp($1, "addopts")) { ++ else if (!strcmp($1, "addopts")) + entry.addopts = amd_strdup(opts); +- memset(opts, 0, sizeof(opts)); +- } else if (!strcmp($1, "remopts")) { ++ else if (!strcmp($1, "remopts")) + entry.remopts = amd_strdup(opts); +- memset(opts, 0, sizeof(opts)); +- } else { +- memset(opts, 0, sizeof(opts)); ++ else { + amd_notify($1); + YYABORT; + } diff --git a/SOURCES/autofs-5.1.0-beta1-fix-expire-when-server-not-responding.patch b/SOURCES/autofs-5.1.0-beta1-fix-expire-when-server-not-responding.patch new file mode 100644 index 0000000..be62b2a --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-expire-when-server-not-responding.patch @@ -0,0 +1,50 @@ +autofs-5.1.0-beta1 - fix expire when server not responding + +From: Ian Kent + +The change to handle expire of symlinks relies on doing a stat(2) +call to check if the path to be expired is a symlink. + +But system calls that invoke a path walk on real mounts need to be +avoided during expire because if the server isn't responding they +will hang. +--- + CHANGELOG | 1 + + daemon/automount.c | 7 ++++++- + 2 files changed, 7 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -117,6 +117,7 @@ + - fix incorrect max key length in defaults get_hash(). + - fix xfn sets incorrect lexer state. + - fix old style key lookup. ++- fix expire when server not responding. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -573,9 +573,13 @@ int umount_multi(struct autofs_point *ap + + debug(ap->logopt, "path %s incl %d", path, incl); + ++ /* If path is a mount it can't be a symlink */ ++ if (is_mounted(_PATH_MOUNTED, path, MNTS_ALL)) ++ goto real_mount; ++ + if (lstat(path, &st)) { + warn(ap->logopt, +- "failed to stat mount point directory %s", path); ++ "failed to stat directory or symlink %s", path); + return 1; + } + +@@ -617,6 +621,7 @@ int umount_multi(struct autofs_point *ap + return 0; + } + ++real_mount: + is_autofs_fs = 0; + if (master_find_submount(ap, path)) + is_autofs_fs = 1; diff --git a/SOURCES/autofs-5.1.0-beta1-fix-hash-on-config-option-add-and-delete.patch b/SOURCES/autofs-5.1.0-beta1-fix-hash-on-config-option-add-and-delete.patch new file mode 100644 index 0000000..789cb93 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-hash-on-config-option-add-and-delete.patch @@ -0,0 +1,107 @@ +autofs-5.1.0-beta1 - fix hash on confg option add and delete + +From: Ian Kent + +The hash calculation needs to be the same for upper and lower case config +options. The config entry add and delete functions weren't doing that. +--- + CHANGELOG | 1 + + lib/defaults.c | 40 ++++++++++++++++++++++------------------ + 2 files changed, 23 insertions(+), 18 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -120,6 +120,7 @@ + - fix expire when server not responding. + - fix ldap_uri config update. + - fix typo in conf_load_autofs_defaults(). ++- fix hash on confg option add and delete. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -524,12 +524,24 @@ error: + return 0; + } + ++static u_int32_t get_hash(const char *key, unsigned int size) ++{ ++ const char *pkey = key; ++ char lkey[PATH_MAX + 1]; ++ char *plkey = &lkey[0]; ++ ++ while (*pkey) ++ *plkey++ = tolower(*pkey++); ++ *plkey = '\0'; ++ return hash(lkey, size); ++} ++ + static int conf_add(const char *section, const char *key, const char *value, unsigned long flags) + { + struct conf_option *co; + char *sec, *name, *val, *tmp; + unsigned int size = CFG_TABLE_SIZE; +- u_int32_t index; ++ u_int32_t key_hash; + int ret = CFG_FAIL; + + sec = name = val = tmp = NULL; +@@ -568,12 +580,12 @@ static int conf_add(const char *section, + if (flags & CONF_ENV && value) + setenv(name, value, 0); + +- index = hash(key, size); +- if (!config->hash[index]) +- config->hash[index] = co; ++ key_hash = get_hash(key, size); ++ if (!config->hash[key_hash]) ++ config->hash[key_hash] = co; + else { + struct conf_option *last = NULL, *next; +- next = config->hash[index]; ++ next = config->hash[key_hash]; + while (next) { + last = next; + next = last->next; +@@ -598,9 +610,11 @@ static void conf_delete(const char *sect + { + struct conf_option *co, *last; + unsigned int size = CFG_TABLE_SIZE; ++ u_int32_t key_hash; + + last = NULL; +- for (co = config->hash[hash(key, size)]; co != NULL; co = co->next) { ++ key_hash = get_hash(key, size); ++ for (co = config->hash[key_hash]; co != NULL; co = co->next) { + if (strcasecmp(section, co->section)) + continue; + if (!strcasecmp(key, co->name)) +@@ -613,6 +627,8 @@ static void conf_delete(const char *sect + + if (last) + last->next = co->next; ++ else ++ config->hash[key_hash] = co->next; + + free(co->section); + free(co->name); +@@ -661,18 +677,6 @@ error: + return ret; + } + +-static u_int32_t get_hash(const char *key, unsigned int size) +-{ +- const char *pkey = key; +- char lkey[PATH_MAX + 1]; +- char *plkey = &lkey[0]; +- +- while (*pkey) +- *plkey++ = tolower(*pkey++); +- *plkey = '\0'; +- return hash(lkey, size); +-} +- + static struct conf_option *conf_lookup_key(const char *section, const char *key) + { + struct conf_option *co; diff --git a/SOURCES/autofs-5.1.0-beta1-fix-incorrect-max-key-length-in-defaults-get_hash.patch b/SOURCES/autofs-5.1.0-beta1-fix-incorrect-max-key-length-in-defaults-get_hash.patch new file mode 100644 index 0000000..4ef58d2 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-incorrect-max-key-length-in-defaults-get_hash.patch @@ -0,0 +1,49 @@ +autofs-5.1.0-beta1 - fix incorrect max key length in defaults get_hash() + +From: Ian Kent + +amd section names can correspond to mount point path names. +--- + CHANGELOG | 1 + + lib/defaults.c | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -114,6 +114,7 @@ + - fix ldap default schema config. + - fix ldap default master map name config. + - fix map format init in lookup_init(). ++- fix incorrect max key length in defaults get_hash(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -43,7 +43,6 @@ + #define OLD_CONFIG_FILE AUTOFS_CONF_DIR "/autofs" + #define MAX_LINE_LEN 256 + #define MAX_SECTION_NAME MAX_LINE_LEN +-#define MAX_CFG_NAME_LEN 31 + + #define NAME_MASTER_MAP "master_map_name" + +@@ -665,7 +664,7 @@ error: + static u_int32_t get_hash(const char *key, unsigned int size) + { + const char *pkey = key; +- char lkey[MAX_CFG_NAME_LEN]; ++ char lkey[PATH_MAX + 1]; + char *plkey = &lkey[0]; + + while (*pkey) +@@ -683,6 +682,9 @@ static struct conf_option *conf_lookup(c + if (!key || !section) + return NULL; + ++ if (strlen(key) > PATH_MAX) ++ return NULL; ++ + key_hash = get_hash(key, size); + for (co = config->hash[key_hash]; co != NULL; co = co->next) { + if (strcasecmp(section, co->section)) diff --git a/SOURCES/autofs-5.1.0-beta1-fix-ldap-default-master-map-name-config.patch b/SOURCES/autofs-5.1.0-beta1-fix-ldap-default-master-map-name-config.patch new file mode 100644 index 0000000..206e2b7 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-ldap-default-master-map-name-config.patch @@ -0,0 +1,38 @@ +autofs-5.1.0-beta1 - fix ldap default master map name config + +From: Ian Kent + +If there is no master map name defined in the autofs configuration the +lookup will try to find a map with the default name and if the map isn't +found will substute dots with underscores and repeat the lookup. + +So don't set the default master map name at defaults initialization time. +--- + CHANGELOG | 1 + + lib/defaults.c | 5 ----- + 2 files changed, 1 insertion(+), 5 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -112,6 +112,7 @@ + - fix wildcard key lookup. + - fix out of order amd timestamp lookup. + - fix ldap default schema config. ++- fix ldap default master map name config. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -266,11 +266,6 @@ static int conf_load_autofs_defaults(voi + const char *sec = autofs_gbl_sec; + int ret; + +- ret = conf_update(sec, NAME_MASTER_MAP, +- DEFAULT_MASTER_MAP_NAME, CONF_ENV); +- if (ret == CFG_FAIL) +- goto error; +- + ret = conf_update(sec, NAME_TIMEOUT, + DEFAULT_TIMEOUT, CONF_ENV); + if (ret == CFG_FAIL) diff --git a/SOURCES/autofs-5.1.0-beta1-fix-ldap-default-schema-config.patch b/SOURCES/autofs-5.1.0-beta1-fix-ldap-default-schema-config.patch new file mode 100644 index 0000000..41b1589 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-ldap-default-schema-config.patch @@ -0,0 +1,58 @@ +autofs-5.1.0-beta1 - fix ldap default schema config + +From: Ian Kent + +If there is no schema set in the autofs configuration then the ldap +lookup module assumes it will get a NULL return when it asks for the +default schema. + +So don't set the default schema at defaults initialization time. +--- + CHANGELOG | 1 + + lib/defaults.c | 25 ------------------------- + 2 files changed, 1 insertion(+), 25 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -111,6 +111,7 @@ + - add amd map format parser. + - fix wildcard key lookup. + - fix out of order amd timestamp lookup. ++- fix ldap default schema config. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -301,31 +301,6 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + +- ret = conf_update(sec, NAME_MAP_OBJ_CLASS, +- DEFAULT_MAP_OBJ_CLASS, CONF_ENV); +- if (ret == CFG_FAIL) +- goto error; +- +- ret = conf_update(sec, NAME_ENTRY_OBJ_CLASS, +- DEFAULT_ENTRY_OBJ_CLASS, CONF_ENV); +- if (ret == CFG_FAIL) +- goto error; +- +- ret = conf_update(sec, NAME_MAP_ATTR, +- DEFAULT_MAP_ATTR, CONF_ENV); +- if (ret == CFG_FAIL) +- goto error; +- +- ret = conf_update(sec, NAME_ENTRY_ATTR, +- DEFAULT_ENTRY_ATTR, CONF_ENV); +- if (ret == CFG_FAIL) +- goto error; +- +- ret = conf_update(sec, NAME_VALUE_ATTR, +- DEFAULT_VALUE_ATTR, CONF_ENV); +- if (ret == CFG_FAIL) +- goto error; +- + ret = conf_update(sec, NAME_APPEND_OPTIONS, + DEFAULT_APPEND_OPTIONS, CONF_ENV); + if (ret == CFG_FAIL) diff --git a/SOURCES/autofs-5.1.0-beta1-fix-ldap_uri-config-update.patch b/SOURCES/autofs-5.1.0-beta1-fix-ldap_uri-config-update.patch new file mode 100644 index 0000000..6809a17 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-ldap_uri-config-update.patch @@ -0,0 +1,60 @@ +autofs-5.1.0-beta1 - fix ldap_uri config update + +From: Ian Kent + +Fix some errors in ldap get uris and get search dns. +--- + CHANGELOG | 1 + + lib/defaults.c | 11 +++++------ + 2 files changed, 6 insertions(+), 6 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -118,6 +118,7 @@ + - fix xfn sets incorrect lexer state. + - fix old style key lookup. + - fix expire when server not responding. ++- fix ldap_uri config update. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -1100,19 +1100,18 @@ struct list_head *defaults_get_uris(void + struct list_head *list; + + list = malloc(sizeof(struct list_head)); +- if (!list) { ++ if (!list) + return NULL; +- } + INIT_LIST_HEAD(list); + +- if (defaults_read_config(0)) { ++ if (!defaults_read_config(0)) { + free(list); + return NULL; + } + + pthread_mutex_lock(&conf_mutex); + co = conf_lookup(autofs_gbl_sec, NAME_LDAP_URI); +- if (!co || !co->value) { ++ if (!co) { + pthread_mutex_unlock(&conf_mutex); + free(list); + return NULL; +@@ -1233,12 +1232,12 @@ struct ldap_searchdn *defaults_get_searc + struct conf_option *co; + struct ldap_searchdn *sdn, *last; + +- if (defaults_read_config(0)) ++ if (!defaults_read_config(0)) + return NULL; + + pthread_mutex_lock(&conf_mutex); + co = conf_lookup(autofs_gbl_sec, NAME_SEARCH_BASE); +- if (!co || !co->value) { ++ if (!co) { + pthread_mutex_unlock(&conf_mutex); + return NULL; + } diff --git a/SOURCES/autofs-5.1.0-beta1-fix-map-format-init-in-lookup_init.patch b/SOURCES/autofs-5.1.0-beta1-fix-map-format-init-in-lookup_init.patch new file mode 100644 index 0000000..001dbc4 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-map-format-init-in-lookup_init.patch @@ -0,0 +1,32 @@ +autofs-5.1.0-beta1 - fix map format init in lookup_init() + +From: Ian Kent + +is_format_amd is not initialized in modules/lookup_ldap.c:lookup_init() +which can cause it to be incorrect leading to a failure to locate a +base dn. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 1 + + 2 files changed, 2 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -113,6 +113,7 @@ + - fix out of order amd timestamp lookup. + - fix ldap default schema config. + - fix ldap default master map name config. ++- fix map format init in lookup_init(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -1647,6 +1647,7 @@ int lookup_init(const char *mapfmt, int + /* 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; + ctxt->format = MAP_FLAG_FORMAT_AMD; diff --git a/SOURCES/autofs-5.1.0-beta1-fix-multi-entry-ldap-option-handling.patch b/SOURCES/autofs-5.1.0-beta1-fix-multi-entry-ldap-option-handling.patch new file mode 100644 index 0000000..f38999c --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-multi-entry-ldap-option-handling.patch @@ -0,0 +1,310 @@ +autofs-5.1.0-beta1 - fix multi entry ldap option handling + +From: Ian Kent + +Handling new and old configurations presents special problems for +configuration entries that may have repeated values, such as ldap_uris +and ldap_search_base, which can be overridden when the old configuration +is read. + +If entries exist in the new configuration they need to be saved and +restored if there's no entries in the old configuration or, if entries +exist in the old configuration, they need to be discarded. +--- + CHANGELOG | 1 + lib/defaults.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++----------- + 2 files changed, 198 insertions(+), 44 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -122,6 +122,7 @@ + - fix typo in conf_load_autofs_defaults(). + - fix hash on confg option add and delete. + - add plus to path match pattern. ++- fix multi entry ldap option handling. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -916,83 +916,236 @@ static int read_config(unsigned int to_s + return 0; + } + +-/* +- * Read config env variables and check they have been set. +- * +- * This simple minded routine assumes the config file +- * is valid bourne shell script without spaces around "=" +- * and that it has valid values. +- */ +-unsigned int defaults_read_config(unsigned int to_syslog) ++struct conf_option *save_ldap_option_list(const char *key) + { +- FILE *f; +- struct stat stb; +- int ret; ++ struct conf_option *co, *head, *this, *last; ++ unsigned int size = CFG_TABLE_SIZE; ++ u_int32_t key_hash; ++ ++ key_hash = get_hash(key, size); ++ co = config->hash[key_hash]; ++ if (!co) ++ return NULL; ++ last = co; ++ ++ head = this = NULL; ++ while (co) { ++ if (strcasecmp(autofs_gbl_sec, co->section)) { ++ last = co; ++ goto next; ++ } + +- pthread_mutex_lock(&conf_mutex); +- if (!config) { +- if (conf_init()) { +- pthread_mutex_unlock(&conf_mutex); +- message(to_syslog, "failed to init config"); +- return 0; ++ if (!strcasecmp(co->name, key)) { ++ /* Unlink from old */ ++ if (co == config->hash[key_hash]) ++ config->hash[key_hash] = co->next; ++ else ++ last->next = co->next; ++ last = co->next; ++ co->next = NULL; ++ /* Add to new */ ++ if (this) ++ this->next = co; ++ this = co; ++ /* If none have been found yet */ ++ if (!head) ++ head = co; ++ co = last; ++ continue; + } ++next: ++ co = co->next; ++ } ++ ++ return head; ++} ++ ++void restore_ldap_option_list(struct conf_option *list) ++{ ++ struct conf_option *co, *this, *last; ++ unsigned int size = CFG_TABLE_SIZE; ++ u_int32_t key_hash; ++ ++ if (!list) ++ return; ++ ++ this = list; ++ while (this) { ++ last = this; ++ this = this->next; ++ } ++ ++ key_hash = get_hash(list->name, size); ++ co = config->hash[key_hash]; ++ config->hash[key_hash] = list; ++ if (co) ++ last->next = co; ++ ++ return; ++} ++ ++void free_ldap_option_list(struct conf_option *list) ++{ ++ struct conf_option *next, *this; ++ ++ if (!list) ++ return; ++ ++ this = list; ++ while (this) { ++ next = this->next; ++ free(this->section); ++ free(this->name); ++ free(this->value); ++ free(this); ++ this = next; + } + +- /* Set configuration to defaults */ ++ return; ++} ++ ++static void clean_ldap_multi_option(const char *key) ++{ ++ const char *sec = autofs_gbl_sec; ++ struct conf_option *co; ++ ++ while ((co = conf_lookup(sec, key))) ++ conf_delete(co->section, co->name); ++ ++ return; ++} ++ ++static int reset_defaults(unsigned int to_syslog) ++{ ++ int ret; ++ + ret = conf_load_autofs_defaults(); + if (!ret) { +- pthread_mutex_unlock(&conf_mutex); + message(to_syslog, "failed to reset autofs default config"); + return 0; + } + + ret = conf_load_amd_defaults(); + if (!ret) { +- pthread_mutex_unlock(&conf_mutex); + message(to_syslog, "failed to reset amd default config"); + return 0; + } + +- f = open_fopen_r(DEFAULT_CONFIG_FILE); +- if (!f) { ++ return 1; ++} ++ ++/* ++ * Read config env variables and check they have been set. ++ * ++ * This simple minded routine assumes the config file ++ * is valid bourne shell script without spaces around "=" ++ * and that it has valid values. ++ */ ++unsigned int defaults_read_config(unsigned int to_syslog) ++{ ++ FILE *conf, *oldconf; ++ struct stat stb, oldstb; ++ int ret, stat, oldstat; ++ ++ ret = 1; ++ ++ pthread_mutex_lock(&conf_mutex); ++ if (!config) { ++ if (conf_init()) { ++ message(to_syslog, "failed to init config"); ++ ret = 0; ++ goto out; ++ } ++ } ++ ++ conf = open_fopen_r(DEFAULT_CONFIG_FILE); ++ if (!conf) + message(to_syslog, "failed to to open config %s", + DEFAULT_CONFIG_FILE); ++ ++ oldconf = open_fopen_r(OLD_CONFIG_FILE); ++ if (!oldconf) ++ message(to_syslog, "failed to to open old config %s", ++ OLD_CONFIG_FILE); ++ ++ /* Neither config has been updated */ ++ stat = oldstat = -1; ++ if (conf && oldconf && ++ (stat = fstat(fileno(conf), &stb) != -1) && ++ stb.st_mtime <= config->modified && ++ (oldstat = fstat(fileno(oldconf), &oldstb) == -1) && ++ oldstb.st_mtime <= config->modified) { ++ fclose(conf); ++ fclose(oldconf); + goto out; + } + +- if (fstat(fileno(f), &stb) != -1) { +- /* Config hasn't been updated */ +- if (stb.st_mtime <= config->modified) { +- fclose(f); ++ if (conf || oldconf) { ++ if (!reset_defaults(to_syslog)) { ++ fclose(conf); ++ fclose(oldconf); ++ ret = 0; + goto out; + } + } + +- ret = read_config(to_syslog, f, DEFAULT_CONFIG_FILE); +- +- if (fstat(fileno(f), &stb) != -1) +- config->modified = stb.st_mtime; +- else +- message(to_syslog, "failed to update config modified time"); ++ /* Update last modified */ ++ if (stat != -1) { ++ if (oldstat == -1) ++ config->modified = stb.st_mtime; ++ else { ++ if (oldstb.st_mtime < stb.st_mtime) ++ config->modified = oldstb.st_mtime; ++ else ++ config->modified = stb.st_mtime; ++ } ++ } + +- fclose(f); ++ if (conf) { ++ read_config(to_syslog, conf, DEFAULT_CONFIG_FILE); ++ fclose(conf); ++ } + + /* +- * Try to read the old config file and override the installed +- * defaults in case user has a stale config following updating +- * to the new config file location. ++ * Read the old config file and override the installed ++ * defaults in case user has a stale config following ++ * updating to the new config file location. + */ ++ if (oldconf) { ++ struct conf_option *ldap_search_base, *ldap_uris; ++ const char *sec = amd_gbl_sec; ++ struct conf_option *co; ++ ++ ldap_search_base = save_ldap_option_list(NAME_SEARCH_BASE); ++ if (ldap_search_base) ++ clean_ldap_multi_option(NAME_SEARCH_BASE); ++ ++ ldap_uris = save_ldap_option_list(NAME_LDAP_URI); ++ if (ldap_uris) ++ clean_ldap_multi_option(NAME_LDAP_URI); ++ ++ read_config(to_syslog, oldconf, OLD_CONFIG_FILE); ++ fclose(oldconf); ++ ++ if (ldap_search_base) { ++ co = conf_lookup(sec, NAME_SEARCH_BASE); ++ if (co) ++ free_ldap_option_list(ldap_search_base); ++ else ++ restore_ldap_option_list(ldap_search_base); ++ } + +- f = open_fopen_r(OLD_CONFIG_FILE); +- if (!f) +- goto out; +- +- read_config(to_syslog, f, OLD_CONFIG_FILE); +- +- fclose(f); ++ if (ldap_uris) { ++ co = conf_lookup(sec, NAME_LDAP_URI); ++ if (co) ++ free_ldap_option_list(ldap_uris); ++ else ++ restore_ldap_option_list(ldap_uris); ++ } ++ } + out: + pthread_mutex_unlock(&conf_mutex); +- return 1; ++ return ret; + } + + static char *conf_get_string(const char *section, const char *name) diff --git a/SOURCES/autofs-5.1.0-beta1-fix-old-style-key-lookup.patch b/SOURCES/autofs-5.1.0-beta1-fix-old-style-key-lookup.patch new file mode 100644 index 0000000..96b1306 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-old-style-key-lookup.patch @@ -0,0 +1,83 @@ +autofs-5.1.0-beta1 - fix old style key lookup + +From: Ian Kent + +Old (old) style configuration keys all started with DEFAULT_ but +the configuration entry lookup requires the has of the lower case +name. So trying to these old style names failes because thet don't +has to the same value. + +So change the key lookup to strip the DEFAULT_ string and retry +the lookup so valid entries hash properly. +--- + CHANGELOG | 1 + + lib/defaults.c | 33 +++++++++++++++++++++------------ + 2 files changed, 22 insertions(+), 12 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -116,6 +116,7 @@ + - fix map format init in lookup_init(). + - fix incorrect max key length in defaults get_hash(). + - fix xfn sets incorrect lexer state. ++- fix old style key lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -673,33 +673,42 @@ static u_int32_t get_hash(const char *ke + return hash(lkey, size); + } + +-static struct conf_option *conf_lookup(const char *section, const char *key) ++static struct conf_option *conf_lookup_key(const char *section, const char *key) + { + struct conf_option *co; + u_int32_t key_hash; + unsigned int size = CFG_TABLE_SIZE; + +- if (!key || !section) +- return NULL; +- +- if (strlen(key) > PATH_MAX) +- return NULL; +- + key_hash = get_hash(key, size); + for (co = config->hash[key_hash]; co != NULL; co = co->next) { + if (strcasecmp(section, co->section)) + continue; + if (!strcasecmp(key, co->name)) + break; ++ } ++ ++ return co; ++} ++ ++static struct conf_option *conf_lookup(const char *section, const char *key) ++{ ++ struct conf_option *co; ++ ++ if (!key || !section) ++ return NULL; ++ ++ if (strlen(key) > PATH_MAX) ++ return NULL; ++ ++ co = conf_lookup_key(section, key); ++ if (!co) { + /* + * Strip "DEFAULT_" and look for config entry for + * backward compatibility with old style config names. ++ * Perhaps this should be a case sensitive compare? + */ +- if (strlen(key) <= 8) +- continue; +- if (!strncasecmp("DEFAULT_", key, 8) && +- !strcasecmp(key + 8, co->name)) +- break; ++ if (strlen(key) > 8 && !strncasecmp("DEFAULT_", key, 8)) ++ co = conf_lookup_key(section, key + 8); + } + + return co; diff --git a/SOURCES/autofs-5.1.0-beta1-fix-out-of-order-amd-timestamp-lookup.patch b/SOURCES/autofs-5.1.0-beta1-fix-out-of-order-amd-timestamp-lookup.patch new file mode 100644 index 0000000..6670659 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-out-of-order-amd-timestamp-lookup.patch @@ -0,0 +1,58 @@ +autofs-5.1.0-beta1 - fix out of order amd timestamp lookup + +From: Ian Kent + +The call in ->lookup_init() for an ldap source tries to get the amd +ldap entry timestamp whether or not the map is amd format. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 7 +++++-- + 2 files changed, 6 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -110,6 +110,7 @@ + - extend fix for crash due to thread unsafe use of libldap. + - add amd map format parser. + - fix wildcard key lookup. ++- fix out of order amd timestamp lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -1621,6 +1621,7 @@ static void validate_uris(struct list_he + */ + int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) + { ++ unsigned int is_amd_format; + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; + int ret; +@@ -1647,6 +1648,7 @@ int lookup_init(const char *mapfmt, int + if (mapfmt == NULL) + mapfmt = MAPFMT_DEFAULT; + if (!strcmp(mapfmt, "amd")) { ++ is_amd_format = 1; + ctxt->format = MAP_FLAG_FORMAT_AMD; + ctxt->check_defaults = 1; + } +@@ -1654,7 +1656,7 @@ int lookup_init(const char *mapfmt, int + ctxt->timeout = defaults_get_ldap_timeout(); + ctxt->network_timeout = defaults_get_ldap_network_timeout(); + +- if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) { ++ if (!is_amd_format) { + /* + * Parse out the server name and base dn, and fill them + * into the proper places in the lookup context structure. +@@ -1746,7 +1748,8 @@ int lookup_init(const char *mapfmt, int + } + #endif + +- ctxt->timestamp = get_amd_timestamp(ctxt); ++ 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); diff --git a/SOURCES/autofs-5.1.0-beta1-fix-typo-in-conf_load_autofs_defaults.patch b/SOURCES/autofs-5.1.0-beta1-fix-typo-in-conf_load_autofs_defaults.patch new file mode 100644 index 0000000..4e58ac2 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-typo-in-conf_load_autofs_defaults.patch @@ -0,0 +1,31 @@ +autofs-5.1.0-beta1 - fix typo in conf_load_autofs_defaults() + +From: Ian Kent + + +--- + CHANGELOG | 1 + + lib/defaults.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -119,6 +119,7 @@ + - fix old style key lookup. + - fix expire when server not responding. + - fix ldap_uri config update. ++- fix typo in conf_load_autofs_defaults(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -320,7 +320,7 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + +- /* LDAP_URI nad SEARCH_BASE can occur multiple times */ ++ /* LDAP_URI and SEARCH_BASE can occur multiple times */ + while ((co = conf_lookup(sec, NAME_LDAP_URI))) + conf_delete(co->section, co->name); + diff --git a/SOURCES/autofs-5.1.0-beta1-fix-wildcard-key-lookup.patch b/SOURCES/autofs-5.1.0-beta1-fix-wildcard-key-lookup.patch new file mode 100644 index 0000000..085dfab --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-wildcard-key-lookup.patch @@ -0,0 +1,160 @@ +autofs-5.1.0-beta1 - fix wildcard key lookup + +From: Ian Kent + +The changes to key matching caused wildcard key lookups for autofs +format maps to fail. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 10 ++++------ + modules/lookup_nisplus.c | 11 +++++------ + modules/lookup_program.c | 4 ++-- + modules/lookup_yp.c | 6 ++---- + 5 files changed, 14 insertions(+), 18 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -109,6 +109,7 @@ + - fix deadlock in init_ldap_connection. + - extend fix for crash due to thread unsafe use of libldap. + - add amd map format parser. ++- fix wildcard key lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -3349,12 +3349,9 @@ static int match_key(struct autofs_point + else + ret = lookup_one(ap, source, key, key_len, ctxt); + +- if (ret == CHE_OK || ret == CHE_UPDATED) ++ if (ret == CHE_OK || ret == CHE_UPDATED || !is_amd_format) + return ret; + +- if (!is_amd_format) +- return CHE_FAIL; +- + lkp_key = strdup(key); + if (!lkp_key) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -3399,6 +3396,7 @@ static int check_map_indirect(struct aut + char *key, int key_len, + struct lookup_context *ctxt) + { ++ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD; + struct mapent_cache *mc; + struct mapent *me; + time_t now = time(NULL); +@@ -3410,7 +3408,7 @@ static int check_map_indirect(struct aut + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); + + pthread_mutex_lock(&ap->entry->current_mutex); +- if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ if (is_amd_format) { + unsigned long timestamp = get_amd_timestamp(ctxt); + if (timestamp > ctxt->timestamp) { + ctxt->timestamp = timestamp; +@@ -3457,7 +3455,7 @@ static int check_map_indirect(struct aut + } + pthread_setcancelstate(cur_state, NULL); + +- if (!(source->flags & MAP_FLAG_FORMAT_AMD)) { ++ if (!is_amd_format) { + /* + * Check for map change and update as needed for + * following cache lookup. +--- autofs-5.0.7.orig/modules/lookup_nisplus.c ++++ autofs-5.0.7/modules/lookup_nisplus.c +@@ -339,6 +339,7 @@ static int match_key(struct autofs_point + const char *key, int key_len, + struct lookup_context *ctxt) + { ++ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD; + char buf[MAX_ERR_BUF]; + char *lkp_key; + char *prefix; +@@ -347,12 +348,9 @@ static int match_key(struct autofs_point + ret = lookup_one(ap, source, key, key_len, ctxt); + if (ret < 0) + return ret; +- if (ret == CHE_OK || ret == CHE_UPDATED) ++ if (ret == CHE_OK || ret == CHE_UPDATED || is_amd_format) + return ret; + +- if (!(source->flags & MAP_FLAG_FORMAT_AMD)) +- return CHE_FAIL; +- + lkp_key = strdup(key); + if (!lkp_key) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -504,6 +502,7 @@ static int check_map_indirect(struct aut + char *key, int key_len, + struct lookup_context *ctxt) + { ++ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD; + struct mapent_cache *mc; + struct mapent *me, *exists; + time_t now = time(NULL); +@@ -512,7 +511,7 @@ static int check_map_indirect(struct aut + + mc = source->mc; + +- if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ if (is_amd_format) { + /* Check for a /defaults entry to update the map source */ + if (lookup_amd_defaults(ap, source, ctxt) == CHE_FAIL) { + warn(ap->logopt, MODPREFIX +@@ -559,7 +558,7 @@ static int check_map_indirect(struct aut + } + me = cache_lookup_next(mc, me); + } +- if (source->flags & MAP_FLAG_FORMAT_AMD) ++ if (is_amd_format) + exists = match_cached_key(ap, MODPREFIX, source, key); + else + exists = cache_lookup_distinct(mc, key); +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -382,7 +382,7 @@ static int match_key(struct autofs_point + char *prefix; + int ret; + +- if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ if (is_amd_format) { + ret = lookup_amd_defaults(ap, source, ctxt); + if (ret != NSS_STATUS_SUCCESS) { + warn(ap->logopt, +@@ -420,7 +420,7 @@ static int match_key(struct autofs_point + ment = lookup_one(ap, lkp_key, lkp_len, ctxt); + if (ment) { + char *start = ment; +- if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ if (is_amd_format) { + start = ment + lkp_len; + while (isblank(*start)) + start++; +--- autofs-5.0.7.orig/modules/lookup_yp.c ++++ autofs-5.0.7/modules/lookup_yp.c +@@ -457,6 +457,7 @@ static int match_key(struct autofs_point + const char *key, int key_len, + struct lookup_context *ctxt) + { ++ unsigned int is_amd_format = source->flags & MAP_FLAG_FORMAT_AMD; + char buf[MAX_ERR_BUF]; + char *lkp_key; + char *prefix; +@@ -465,12 +466,9 @@ static int match_key(struct autofs_point + ret = lookup_one(ap, source, key, strlen(key), ctxt); + if (ret < 0) + return ret; +- if (ret == CHE_OK || ret == CHE_UPDATED) ++ if (ret == CHE_OK || ret == CHE_UPDATED || !is_amd_format) + return ret; + +- if (!(source->flags & MAP_FLAG_FORMAT_AMD)) +- return CHE_FAIL; +- + lkp_key = strdup(key); + if (!lkp_key) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); diff --git a/SOURCES/autofs-5.1.0-beta1-fix-xfn-sets-incorrect-lexer-state.patch b/SOURCES/autofs-5.1.0-beta1-fix-xfn-sets-incorrect-lexer-state.patch new file mode 100644 index 0000000..7d4b440 --- /dev/null +++ b/SOURCES/autofs-5.1.0-beta1-fix-xfn-sets-incorrect-lexer-state.patch @@ -0,0 +1,39 @@ +autofs-5.1.0-beta1 - fix xfn sets incorrect lexer state + +From: Ian Kent + +The X/Open Federated Naming service isn't supported and the parser will +call YYABORT() when it sees the MAPXFN token so we must set the start +state to the INITIAL state here for the next yylex() call. +--- + CHANGELOG | 1 + + lib/master_tok.l | 8 +++++++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -115,6 +115,7 @@ + - fix ldap default master map name config. + - fix map format init in lookup_init(). + - fix incorrect max key length in defaults get_hash(). ++- fix xfn sets incorrect lexer state. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/master_tok.l ++++ autofs-5.0.7/lib/master_tok.l +@@ -258,7 +258,13 @@ OPTNTOUT (-n{OPTWS}|-n{OPTWS}={OPTWS}|-- + } + + "-xfn" { +- BEGIN(OPTSTR); ++ /* ++ * The X/Open Federated Naming service isn't supported ++ * and the parser will call YYABORT() when it sees the ++ * MAPXFN token so we must set the start state to the ++ * INITIAL state here for the next yylex() call. ++ */ ++ BEGIN(INITIAL); + strcpy(master_lval.strtype, master_text); + return MAPXFN; + } diff --git a/SOURCES/autofs-5.1.0-check-amd-lex-buffer-len-before-copy.patch b/SOURCES/autofs-5.1.0-check-amd-lex-buffer-len-before-copy.patch new file mode 100644 index 0000000..8f439bf --- /dev/null +++ b/SOURCES/autofs-5.1.0-check-amd-lex-buffer-len-before-copy.patch @@ -0,0 +1,188 @@ +autofs-5.1.0 - check amd lex buffer len before copy + +From: Ian Kent + +Guard against lex to yacc communication buffer overflow. +--- + CHANGELOG | 1 + + modules/amd_tok.l | 49 +++++++++++++++++++++++++++++++------------------ + 2 files changed, 32 insertions(+), 18 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -138,6 +138,7 @@ + - fix buffer size checks in get_network_proximity(). + - fix leak in get_network_proximity(). + - fix buffer size checks in merge_options(). ++- check amd lex buffer len before copy. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/amd_tok.l ++++ autofs-5.0.7/modules/amd_tok.l +@@ -22,6 +22,7 @@ + # undef ECHO + #endif + static void amd_echo(void); /* forward definition */ ++static void amd_copy_buffer(void); + #define ECHO amd_echo() + int amd_wrap(void); + +@@ -125,26 +126,26 @@ CUTSEP (\|\||\/) + + {MAPOPT} { + BEGIN(MAPOPTVAL); +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return MAP_OPTION; + + } + + {FSOPTS} { + BEGIN(FSOPTVAL); +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return FS_OPTION; + } + + {MNTOPT} { + BEGIN(MNTOPTVAL); +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return MNT_OPTION; + } + + {SELOPT} { + BEGIN(SELOPTVAL); +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return SELECTOR; + } + +@@ -152,13 +153,13 @@ CUTSEP (\|\||\/) + + {SEL1ARG} { + BEGIN(SELARGVAL); +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return SELECTOR; + } + + {SEL2ARG} { + BEGIN(SELARGVAL); +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return SELECTOR; + } + +@@ -171,7 +172,7 @@ CUTSEP (\|\||\/) + #.* { return COMMENT; } + + {OTHR} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return OTHER; + } + } +@@ -201,22 +202,22 @@ CUTSEP (\|\||\/) + ":=" { return OPTION_ASSIGN; } + + {FSTYPE} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return FS_TYPE; + } + + {MAPTYPE} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return MAP_TYPE; + } + + {CHEOPT} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return CACHE_OPTION; + } + + {FOPT} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return FS_OPT_VALUE; + } + } +@@ -246,7 +247,7 @@ CUTSEP (\|\||\/) + ":=" { return OPTION_ASSIGN; } + + {FOPT} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return FS_OPT_VALUE; + } + } +@@ -278,7 +279,7 @@ CUTSEP (\|\||\/) + "," { return COMMA; } + + {OPTS} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return OPTION; + } + } +@@ -310,7 +311,7 @@ CUTSEP (\|\||\/) + "!=" { return NOT_EQUAL; } + + {SOPT} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return SELECTOR_VALUE; + } + } +@@ -335,24 +336,24 @@ CUTSEP (\|\||\/) + "(" { return LBRACKET; } + + {NOPT} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return SEL_ARG_VALUE; + } + + {SOPT}/"," { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return SEL_ARG_VALUE; + } + + "," { return COMMA; } + + {SOPT} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return SEL_ARG_VALUE; + } + + {FOPT} { +- strcpy(amd_lval.strtype, amd_text); ++ amd_copy_buffer(); + return SEL_ARG_VALUE; + } + +@@ -368,6 +369,18 @@ int amd_wrap(void) + return 1; + } + ++static void amd_copy_buffer(void) ++{ ++ if (amd_leng < 2048) ++ strcpy(amd_lval.strtype, amd_text); ++ else { ++ strncpy(amd_lval.strtype, amd_text, 2047); ++ amd_lval.strtype[2047] = '\0'; ++ logmsg("warning: truncated option near %s\n", ++ &amd_lval.strtype[2030]); ++ } ++} ++ + static void amd_echo(void) + { + logmsg("%s\n", amd_text); diff --git a/SOURCES/autofs-5.1.0-check-host-macro-is-set-before-use.patch b/SOURCES/autofs-5.1.0-check-host-macro-is-set-before-use.patch new file mode 100644 index 0000000..8e816cf --- /dev/null +++ b/SOURCES/autofs-5.1.0-check-host-macro-is-set-before-use.patch @@ -0,0 +1,34 @@ +autofs-5.1.0 - check host macro is set before use + +From: Ian Kent + +Check marco lookup return for ${host} in match_my_name() before using it. +--- + CHANGELOG | 1 + + modules/parse_amd.c | 5 +++++ + 2 files changed, 6 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -140,6 +140,7 @@ + - fix buffer size checks in merge_options(). + - check amd lex buffer len before copy. + - add return check in ldap check_map_indirect(). ++- check host macro is set before use. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -238,6 +238,11 @@ static int match_my_name(unsigned int lo + return 1; + } + ++ if (!v || !v->val) { ++ error(logopt, "error: ${host} not set"); ++ goto out; ++ } ++ + /* Check if comparison value is an alias */ + + memset(&hints, 0, sizeof(hints)); diff --git a/SOURCES/autofs-5.1.0-check-options-length-before-use-in-parse_amd_c.patch b/SOURCES/autofs-5.1.0-check-options-length-before-use-in-parse_amd_c.patch new file mode 100644 index 0000000..3c3240a --- /dev/null +++ b/SOURCES/autofs-5.1.0-check-options-length-before-use-in-parse_amd_c.patch @@ -0,0 +1,83 @@ +autofs-5.1.0 - check options length before use in parse_amd.c + +From: Ian Kent + +Check for temporary buffer overflow before copy at several places in +modules/parse_amd.c. +--- + CHANGELOG | 1 + + modules/parse_amd.c | 36 ++++++++++++++++++++++++++++++++---- + 2 files changed, 33 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -141,6 +141,7 @@ + - check amd lex buffer len before copy. + - add return check in ldap check_map_indirect(). + - check host macro is set before use. ++- check options length before use in parse_amd.c. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -906,9 +906,20 @@ static int do_auto_mount(struct autofs_p + { + char target[PATH_MAX + 1]; + +- if (!entry->map_type) ++ if (!entry->map_type) { ++ if (strlen(entry->fs) > PATH_MAX) { ++ error(ap->logopt, MODPREFIX ++ "error: fs option length is too long"); ++ return 0; ++ } + strcpy(target, entry->fs); +- else { ++ } else { ++ if (strlen(entry->fs) + ++ strlen(entry->map_type) + 5 > PATH_MAX) { ++ error(ap->logopt, MODPREFIX ++ "error: fs + maptype options length is too long"); ++ return 0; ++ } + strcpy(target, entry->map_type); + strcat(target, ",amd:"); + strcat(target, entry->fs); +@@ -925,10 +936,21 @@ static int do_link_mount(struct autofs_p + const char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL; + int ret; + +- if (entry->sublink) ++ if (entry->sublink) { ++ if (strlen(entry->sublink) > PATH_MAX) { ++ error(ap->logopt, MODPREFIX ++ "error: sublink option length is too long"); ++ return 0; ++ } + strcpy(target, entry->sublink); +- else ++ } else { ++ if (strlen(entry->fs) > PATH_MAX) { ++ error(ap->logopt, MODPREFIX ++ "error: fs option length is too long"); ++ return 0; ++ } + strcpy(target, entry->fs); ++ } + + if (!(flags & CONF_AUTOFS_USE_LOFS)) + goto symlink; +@@ -1017,6 +1039,12 @@ static int do_nfs_mount(struct autofs_po + unsigned int umount = 0; + int ret = 0; + ++ if (strlen(entry->rhost) + strlen(entry->rfs) + 1 > PATH_MAX) { ++ error(ap->logopt, MODPREFIX ++ "error: rhost + rfs options length is too long"); ++ return 0; ++ } ++ + strcpy(target, entry->rhost); + strcat(target, ":"); + strcat(target, entry->rfs); diff --git a/SOURCES/autofs-5.1.0-clarify-multiple-mounts-description.patch b/SOURCES/autofs-5.1.0-clarify-multiple-mounts-description.patch new file mode 100644 index 0000000..e34c1b9 --- /dev/null +++ b/SOURCES/autofs-5.1.0-clarify-multiple-mounts-description.patch @@ -0,0 +1,45 @@ +autofs-5.1.0 - clarify multiple mounts description + +From: Ian Kent + +Try and clarify the "Multiple Mounts" and "Replicated Server" sections +in the autofs(5) man page. +--- + CHANGELOG | 1 + + man/autofs.5 | 8 ++++++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -154,6 +154,7 @@ + - fix out of order clearing of options buffer. + - fix reset amd lexer scan buffer. + - ignore multiple commas in options strings. ++- clarify multiple mounts description. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/autofs.5 ++++ autofs-5.0.7/man/autofs.5 +@@ -211,15 +211,19 @@ can be used to name multiple filesystems + .RS +.2i + .ta 1.0i + .nf +-.BI "key [" -options "] [mount-point [" -options "] location...]..." ++.BI "key [ -options ] [[/] location [/relative-mount-point [ -options ] location...]..." + .fi + .RE + .sp + .P + This may extend over multiple lines, quoting the line-breaks with \`\\\'. + If present, the per-mountpoint mount-options are appended to the +-default mount-options. ++default mount-options. This behaviour may be overridden by the append_options ++configuration setting. + .SS Replicated Server ++A mount location can specify multiple hosts for a location, portentially ++with a different export path for the same file system. Historically these ++different locations are read-only and provide the same replicated file system. + .sp + .RS +.2i + .ta 1.5i diff --git a/SOURCES/autofs-5.1.0-dont-add-wildcard-to-negative-cache.patch b/SOURCES/autofs-5.1.0-dont-add-wildcard-to-negative-cache.patch new file mode 100644 index 0000000..5e9392f --- /dev/null +++ b/SOURCES/autofs-5.1.0-dont-add-wildcard-to-negative-cache.patch @@ -0,0 +1,48 @@ +autofs-5.1.0 - dont add wildcard to negative cache + +From: Ian Kent + +If the wilcard is added to the negative cache it prevents any +further matching of the wildcard for the given map. +--- + CHANGELOG | 1 + + daemon/lookup.c | 4 ++++ + lib/cache.c | 4 ++++ + 3 files changed, 9 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -161,6 +161,7 @@ + - fix hosts map update on reload. + - make negative cache update consistent for all lookup modules. + - ensure negative cache isn't updated on remount. ++- dont add wildcard to negative cache. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -1057,6 +1057,10 @@ static void update_negative_cache(struct + if (source && source->depth) + return; + ++ /* Don't update the wildcard */ ++ if (strlen(name) == 1 && *name == '*') ++ return; ++ + /* Have we recorded the lookup fail for negative caching? */ + me = lookup_source_mapent(ap, name, LKP_DISTINCT); + if (me) +--- autofs-5.0.7.orig/lib/cache.c ++++ autofs-5.0.7/lib/cache.c +@@ -762,6 +762,10 @@ void cache_update_negative(struct mapent + struct mapent *me; + int rv = CHE_OK; + ++ /* Don't update the wildcard */ ++ if (strlen(key) == 1 && *key == '*') ++ return; ++ + me = cache_lookup_distinct(mc, key); + if (me) + rv = cache_push_mapent(me, NULL); diff --git a/SOURCES/autofs-5.1.0-dont-allocate-dev_ctl_ops-too-early.patch b/SOURCES/autofs-5.1.0-dont-allocate-dev_ctl_ops-too-early.patch new file mode 100644 index 0000000..ba5b231 --- /dev/null +++ b/SOURCES/autofs-5.1.0-dont-allocate-dev_ctl_ops-too-early.patch @@ -0,0 +1,83 @@ +autofs-5.1.0 - dont allocate dev_ctl_ops too early + +From: Ian Kent + +If the standard io file descriptors have been closed by the cloning +process the file handle for autofs device control can correspond to +a descriptor number of one of the standard io descriptors which will +be closed when the process is daemonized. + +Avoid this by closing the device control descriptor opened when +performing sanity checks at startup so that it can be opened +on a higher numbered file descriptor after the process has switched +to daemon mode. +--- + CHANGELOG | 1 + + lib/mounts.c | 14 +++++++++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -127,6 +127,7 @@ + - allow empty value for some map options. + - allow empty value in macro selectors. + - add serialization to sasl init. ++- dont allocate dev_ctl_ops too early. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -90,7 +90,7 @@ unsigned int linux_version_code(void) + + unsigned int query_kproto_ver(void) + { +- struct ioctl_ops *ops = get_ioctl_ops(); ++ struct ioctl_ops *ops; + char dir[] = "/tmp/autoXXXXXX", *t_dir; + char options[MAX_OPTIONS_LEN + 1]; + pid_t pgrp = getpgrp(); +@@ -131,10 +131,19 @@ unsigned int query_kproto_ver(void) + return 0; + } + ++ ops = get_ioctl_ops(); ++ if (!ops) { ++ umount(t_dir); ++ close(pipefd[0]); ++ rmdir(t_dir); ++ return 0; ++ } ++ + ops->open(LOGOPT_NONE, &ioctlfd, st.st_dev, t_dir); + if (ioctlfd == -1) { + umount(t_dir); + close(pipefd[0]); ++ close_ioctl_ctl(); + rmdir(t_dir); + return 0; + } +@@ -146,6 +155,7 @@ unsigned int query_kproto_ver(void) + ops->close(LOGOPT_NONE, ioctlfd); + umount(t_dir); + close(pipefd[0]); ++ close_ioctl_ctl(); + rmdir(t_dir); + return 0; + } +@@ -155,6 +165,7 @@ unsigned int query_kproto_ver(void) + ops->close(LOGOPT_NONE, ioctlfd); + umount(t_dir); + close(pipefd[0]); ++ close_ioctl_ctl(); + rmdir(t_dir); + return 0; + } +@@ -162,6 +173,7 @@ unsigned int query_kproto_ver(void) + ops->close(LOGOPT_NONE, ioctlfd); + umount(t_dir); + close(pipefd[0]); ++ close_ioctl_ctl(); + rmdir(t_dir); + + return 1; diff --git a/SOURCES/autofs-5.1.0-ensure-negative-cache-isnt-updated-on-remount.patch b/SOURCES/autofs-5.1.0-ensure-negative-cache-isnt-updated-on-remount.patch new file mode 100644 index 0000000..baa753a --- /dev/null +++ b/SOURCES/autofs-5.1.0-ensure-negative-cache-isnt-updated-on-remount.patch @@ -0,0 +1,47 @@ +autofs-5.1.0 - ensure negative cache isn't updated on remount + +From: Ian Kent + +The negative cache shouldn't be updated when re-connecting at +startup but a couple of lookup modules didn't check for this +case. +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 3 +++ + modules/lookup_program.c | 3 +++ + 3 files changed, 7 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -160,6 +160,7 @@ + - fix typo in update_hosts_mounts(). + - fix hosts map update on reload. + - make negative cache update consistent for all lookup modules. ++- ensure negative cache isn't updated on remount. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_hosts.c ++++ autofs-5.0.7/modules/lookup_hosts.c +@@ -151,6 +151,9 @@ static int do_parse_mount(struct autofs_ + if (ret) { + struct mapent_cache *mc = source->mc; + ++ /* Don't update negative cache when re-connecting */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ return NSS_STATUS_TRYAGAIN; + cache_writelock(mc); + cache_update_negative(mc, source, name, ap->negative_timeout); + cache_unlock(mc); +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -622,6 +622,9 @@ out_free: + free(mapent); + + if (ret) { ++ /* Don't update negative cache when re-connecting */ ++ if (ap->flags & MOUNT_FLAG_REMOUNT) ++ return NSS_STATUS_TRYAGAIN; + cache_writelock(mc); + cache_update_negative(mc, source, name, ap->negative_timeout); + cache_unlock(mc); diff --git a/SOURCES/autofs-5.1.0-fix-FILE-pointer-check-in-defaults_read_config.patch b/SOURCES/autofs-5.1.0-fix-FILE-pointer-check-in-defaults_read_config.patch new file mode 100644 index 0000000..80dc9fb --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-FILE-pointer-check-in-defaults_read_config.patch @@ -0,0 +1,78 @@ +autofs-5.1.0 - fix FILE pointer check in defaults_read_config() + +From: Ian Kent + +Fix possible use after free usage of FILE pointer in defaults_read_config(). +--- + CHANGELOG | 1 + + lib/defaults.c | 15 +++++++-------- + 2 files changed, 8 insertions(+), 8 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -132,6 +132,7 @@ + - fix race accessing qdn in get_query_dn(). + - fix leak in cache_push_mapent(). + - fix config entry read buffer not checked. ++- fix FILE pointer check in defaults_read_config(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -1055,6 +1055,8 @@ unsigned int defaults_read_config(unsign + + ret = 1; + ++ conf = oldconf = NULL; ++ + pthread_mutex_lock(&conf_mutex); + if (!config) { + if (conf_init()) { +@@ -1081,15 +1083,11 @@ unsigned int defaults_read_config(unsign + stb.st_mtime <= config->modified && + (oldstat = fstat(fileno(oldconf), &oldstb) == -1) && + oldstb.st_mtime <= config->modified) { +- fclose(conf); +- fclose(oldconf); + goto out; + } + + if (conf || oldconf) { + if (!reset_defaults(to_syslog)) { +- fclose(conf); +- fclose(oldconf); + ret = 0; + goto out; + } +@@ -1107,10 +1105,8 @@ unsigned int defaults_read_config(unsign + } + } + +- if (conf) { ++ if (conf) + read_config(to_syslog, conf, DEFAULT_CONFIG_FILE); +- fclose(conf); +- } + + /* + * Read the old config file and override the installed +@@ -1131,7 +1127,6 @@ unsigned int defaults_read_config(unsign + clean_ldap_multi_option(NAME_LDAP_URI); + + read_config(to_syslog, oldconf, OLD_CONFIG_FILE); +- fclose(oldconf); + + if (ldap_search_base) { + co = conf_lookup(sec, NAME_SEARCH_BASE); +@@ -1150,6 +1145,10 @@ unsigned int defaults_read_config(unsign + } + } + out: ++ if (conf) ++ fclose(conf); ++ if (oldconf) ++ fclose(oldconf); + pthread_mutex_unlock(&conf_mutex); + return ret; + } diff --git a/SOURCES/autofs-5.1.0-fix-buffer-size-checks-in-get_network_proximity.patch b/SOURCES/autofs-5.1.0-fix-buffer-size-checks-in-get_network_proximity.patch new file mode 100644 index 0000000..3969a1a --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-buffer-size-checks-in-get_network_proximity.patch @@ -0,0 +1,52 @@ +autofs-5.1.0 - fix buffer size checks in get_network_proximity() + +From: Ian Kent + +Add several buffer size checks in get_network_proximity(). +--- + CHANGELOG | 1 + + lib/parse_subs.c | 8 +++++--- + 2 files changed, 6 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -135,6 +135,7 @@ + - fix FILE pointer check in defaults_read_config(). + - fix memory leak in conf_amd_get_log_options(). + - fix signed comparison in inet_fill_net(). ++- fix buffer size checks in get_network_proximity(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/parse_subs.c ++++ autofs-5.0.7/lib/parse_subs.c +@@ -437,7 +437,7 @@ unsigned int get_network_proximity(const + { + struct addrinfo hints; + struct addrinfo *ni, *this; +- char name_or_num[NI_MAXHOST]; ++ char name_or_num[NI_MAXHOST + 1]; + unsigned int proximity; + char *net; + int ret; +@@ -449,16 +449,18 @@ unsigned int get_network_proximity(const + if (net) + strcpy(name_or_num, net); + else { +- char this[NI_MAXHOST]; ++ char this[NI_MAXHOST + 1]; + char *mask; + ++ if (strlen(name) > NI_MAXHOST) ++ return PROXIMITY_ERROR; + strcpy(this, name); + if ((mask = strchr(this, '/'))) + *mask++ = '\0'; + if (!strchr(this, '.')) + strcpy(name_or_num, this); + else { +- char buf[NI_MAXHOST], *new; ++ char buf[NI_MAXHOST + 1], *new; + new = inet_fill_net(this, buf); + if (!new) + return PROXIMITY_ERROR; diff --git a/SOURCES/autofs-5.1.0-fix-buffer-size-checks-in-merge_options.patch b/SOURCES/autofs-5.1.0-fix-buffer-size-checks-in-merge_options.patch new file mode 100644 index 0000000..d3b01d5 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-buffer-size-checks-in-merge_options.patch @@ -0,0 +1,105 @@ +autofs-5.1.0 - fix buffer size checks in merge_options() + +From: Ian Kent + +Fix some buffer size overflow checks in merge_options(). +--- + CHANGELOG | 1 + + lib/parse_subs.c | 25 +++++++++++++++++++++---- + 2 files changed, 22 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -137,6 +137,7 @@ + - fix signed comparison in inet_fill_net(). + - fix buffer size checks in get_network_proximity(). + - fix leak in get_network_proximity(). ++- fix buffer size checks in merge_options(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/parse_subs.c ++++ autofs-5.0.7/lib/parse_subs.c +@@ -886,11 +886,11 @@ static char *hasopt(const char *str, con + + char *merge_options(const char *opt1, const char *opt2) + { +- char str[MAX_OPTIONS_LEN]; +- char result[MAX_OPTIONS_LEN]; +- char neg[MAX_OPTION_LEN]; ++ char str[MAX_OPTIONS_LEN + 1]; ++ char result[MAX_OPTIONS_LEN + 1]; ++ char neg[MAX_OPTION_LEN + 1]; + char *tok, *ptr = NULL; +- size_t len; ++ size_t resultlen, len; + + if ((!opt1 || !*opt1) && (!opt2 || !*opt2)) + return NULL; +@@ -910,9 +910,12 @@ char *merge_options(const char *opt1, co + if (!strcmp(opt1, opt2)) + return strdup(opt1); + ++ if (strlen(str) > MAX_OPTIONS_LEN) ++ return NULL; + memset(result, 0, sizeof(result)); + strcpy(str, opt1); + ++ resultlen = 0; + tok = strtok_r(str, ",", &ptr); + while (tok) { + const char *this = (const char *) tok; +@@ -920,12 +923,15 @@ char *merge_options(const char *opt1, co + if (eq) { + *eq = '\0'; + if (!hasopt(opt2, this)) { ++ if (resultlen + strlen(this) > MAX_OPTIONS_LEN) ++ return NULL; + *eq = '='; + if (!*result) + strcpy(result, this); + else + strcat(result, this); + strcat(result, ","); ++ resultlen += strlen(this) + 1; + goto next; + } + } +@@ -946,10 +952,14 @@ char *merge_options(const char *opt1, co + goto next; + + if (!strncmp(this, "no", 2)) { ++ if (strlen(this + 2) > MAX_OPTION_LEN) ++ return NULL; + strcpy(neg, this + 2); + if (hasopt(opt2, neg)) + goto next; + } else { ++ if ((strlen(this) + 2) > MAX_OPTION_LEN) ++ return NULL; + strcpy(neg, "no"); + strcat(neg, this); + if (hasopt(opt2, neg)) +@@ -959,15 +969,22 @@ char *merge_options(const char *opt1, co + if (hasopt(opt2, tok)) + goto next; + ++ if (resultlen + strlen(this) + 1 > MAX_OPTIONS_LEN) ++ return NULL; ++ + if (!*result) + strcpy(result, this); + else + strcat(result, this); + strcat(result, ","); ++ resultlen =+ strlen(this) + 1; + next: + tok = strtok_r(NULL, ",", &ptr); + } + ++ if (resultlen + strlen(opt2) > MAX_OPTIONS_LEN) ++ return NULL; ++ + if (!*result) + strcpy(result, opt2); + else diff --git a/SOURCES/autofs-5.1.0-fix-config-entry-read-buffer-not-checked.patch b/SOURCES/autofs-5.1.0-fix-config-entry-read-buffer-not-checked.patch new file mode 100644 index 0000000..fecee6e --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-config-entry-read-buffer-not-checked.patch @@ -0,0 +1,45 @@ +autofs-5.1.0 - fix config entry read buffer not checked + +From: Ian Kent + +Check the length of config file line read in and report truncation +if it was too long. +--- + CHANGELOG | 1 + + lib/defaults.c | 8 +++++++- + 2 files changed, 8 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -131,6 +131,7 @@ + - fix incorrect round robin host detection. + - fix race accessing qdn in get_query_dn(). + - fix leak in cache_push_mapent(). ++- fix config entry read buffer not checked. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -834,7 +834,7 @@ static int parse_line(char *line, char * + + static int read_config(unsigned int to_syslog, FILE *f, const char *name) + { +- char buf[MAX_LINE_LEN]; ++ char buf[MAX_LINE_LEN + 2]; + char secbuf[MAX_SECTION_NAME]; + char *new_sec; + char *res; +@@ -842,6 +842,12 @@ static int read_config(unsigned int to_s + new_sec = NULL; + while ((res = fgets(buf, MAX_LINE_LEN, f))) { + char *sec, *key, *value; ++ ++ if (strlen(res) > MAX_LINE_LEN) { ++ message(to_syslog, "%s was truncated, ignored", res); ++ continue; ++ } ++ + sec = key = value = NULL; + if (!parse_line(res, &sec, &key, &value)) + continue; diff --git a/SOURCES/autofs-5.1.0-fix-copy-and-paste-error-in-dup_defaults_entry.patch b/SOURCES/autofs-5.1.0-fix-copy-and-paste-error-in-dup_defaults_entry.patch new file mode 100644 index 0000000..5f3f644 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-copy-and-paste-error-in-dup_defaults_entry.patch @@ -0,0 +1,31 @@ +autofs-5.1.0 - fix copy and paste error in dup_defaults_entry() + +From: Ian Kent + + +--- + CHANGELOG | 1 + + modules/parse_amd.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -143,6 +143,7 @@ + - check host macro is set before use. + - check options length before use in parse_amd.c. + - fix some out of order evaluations in parse_amd.c. ++- fix copy and paste error in dup_defaults_entry(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -1631,7 +1631,7 @@ static struct amd_entry *dup_defaults_en + entry->rfs = tmp; + } + +- if (defaults->rhost && *defaults->rfs) { ++ if (defaults->rhost && *defaults->rhost) { + tmp = strdup(defaults->rhost); + if (tmp) + entry->rhost = tmp; diff --git a/SOURCES/autofs-5.1.0-fix-fix-master-map-type-check.patch b/SOURCES/autofs-5.1.0-fix-fix-master-map-type-check.patch new file mode 100644 index 0000000..c7a38be --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-fix-master-map-type-check.patch @@ -0,0 +1,38 @@ +autofs-5.1.0 - fix fix master map type check + +From: Ian Kent + +The map type is of the form [,] but the master map type +check for the old style map syntax wasn't allowing for to be +given (see commit 7c104167). + +When fixing this an incorrect length was accidently used when checking +for the "yp" map type which causes it to never match. +--- + CHANGELOG | 1 + + daemon/lookup.c | 4 ++-- + 2 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -156,6 +156,7 @@ + - ignore multiple commas in options strings. + - clarify multiple mounts description. + - update man page autofs(8) for systemd. ++- fix fix master map type check. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -233,8 +233,8 @@ int lookup_nss_read_master(struct master + memset(source, 0, 10); + if ((!strncmp(name, "file", 4) && + (name[4] == ',' || name[4] == ':')) || +- (!strncmp(name, "yp", 3) && +- (name[3] == ',' || name[3] == ':')) || ++ (!strncmp(name, "yp", 2) && ++ (name[2] == ',' || name[2] == ':')) || + (!strncmp(name, "nis", 3) && + (name[3] == ',' || name[3] == ':')) || + (!strncmp(name, "nisplus", 7) && diff --git a/SOURCES/autofs-5.1.0-fix-gcc5-complaints.patch b/SOURCES/autofs-5.1.0-fix-gcc5-complaints.patch new file mode 100644 index 0000000..3f653cc --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-gcc5-complaints.patch @@ -0,0 +1,68 @@ +autofs-5.1.0 - fix gcc5 complaints + +From: Ian Kent + +gcc5 is not happy with the way dump_core() and master_get_logopt() +are declared inline, remove the inline and let the compiler decide. +--- + CHANGELOG | 1 + + daemon/spawn.c | 2 +- + include/automount.h | 2 +- + include/master.h | 2 +- + lib/master.c | 2 +- + 5 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -192,6 +192,7 @@ + - fix handle_mounts() termination condition check. + - fix config old name lookup. + - fix error handling on ldap bind fail. ++- fix gcc5 complaints. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/spawn.c ++++ autofs-5.0.7/daemon/spawn.c +@@ -36,7 +36,7 @@ static pthread_mutex_t spawn_mutex = PTH + + #define MTAB_LOCK_RETRIES 3 + +-inline void dump_core(void) ++void dump_core(void) + { + sigset_t segv; + +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -241,7 +241,7 @@ const char **copy_argv(int argc, const c + int compare_argv(int argc1, const char **argv1, int argc2, const char **argv2); + int free_argv(int argc, const char **argv); + +-inline void dump_core(void); ++void dump_core(void); + int aquire_lock(void); + void release_lock(void); + int spawnl(unsigned logopt, const char *prog, ...); +--- autofs-5.0.7.orig/include/master.h ++++ autofs-5.0.7/include/master.h +@@ -120,7 +120,7 @@ void master_notify_state_change(struct m + int master_mount_mounts(struct master *, time_t, int); + int dump_map(struct master *, const char *, const char *); + int master_show_mounts(struct master *); +-extern inline unsigned int master_get_logopt(void); ++unsigned int master_get_logopt(void); + int master_list_empty(struct master *); + int master_done(struct master *); + int master_kill(struct master *); +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -1712,7 +1712,7 @@ int master_done(struct master *master) + return res; + } + +-inline unsigned int master_get_logopt(void) ++unsigned int master_get_logopt(void) + { + return master_list ? master_list->logopt : LOGOPT_NONE; + } diff --git a/SOURCES/autofs-5.1.0-fix-hosts-map-options-check-in-lookup_amd_instance.patch b/SOURCES/autofs-5.1.0-fix-hosts-map-options-check-in-lookup_amd_instance.patch new file mode 100644 index 0000000..f7f79dc --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-hosts-map-options-check-in-lookup_amd_instance.patch @@ -0,0 +1,32 @@ +autofs-5.1.0 - fix hosts map options check in lookup_amd_instance() + +From: Ian Kent + +Ongoing bug fixes have caused a hosts map source check in lookup_amd_instance() +to be inconsistent and consequently not find the iexpected map source. +--- + CHANGELOG | 1 + + daemon/lookup.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -147,6 +147,7 @@ + - fix leak in parse_mount(). + - add mutex call return check in defaults.c. + - force disable browse mode for amd format maps. ++- fix hosts map options check in lookup_amd_instance(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -843,7 +843,7 @@ static int lookup_amd_instance(struct au + return NSS_STATUS_UNKNOWN; + } + +- if (entry->opts) { ++ if (entry->opts && *entry->opts) { + argv[0] = entry->opts; + argv[1] = NULL; + pargv = argv; diff --git a/SOURCES/autofs-5.1.0-fix-hosts-map-update-on-reload.patch b/SOURCES/autofs-5.1.0-fix-hosts-map-update-on-reload.patch new file mode 100644 index 0000000..d98b40d --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-hosts-map-update-on-reload.patch @@ -0,0 +1,80 @@ +autofs-5.1.0 - fix hosts map update on reload + +From: Ian Kent + +Commit aedfd5aa - "amd lookup fix host mount naming" introduced a +regression when updating sun format maps. + +The amd host mount type assumes the lookup name is the host name for +the host mount but amd uses ${rhost} for this. + +This introduces the possibility of multiple concurrent mount requests +since constructing a mount tree that isn't under the lookup name can't +take advantage of the kernel queuing of other concurrent lookups while +the mount tree is constructed. + +Consequently multi-mount updates (currently only done for the internal +hosts map which the amd parser also uses for its hosts map) can't be +allowed for amd mounts. +--- + CHANGELOG | 1 + + modules/parse_sun.c | 37 ++++++++++++++++++++++++++++--------- + 2 files changed, 29 insertions(+), 9 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -158,6 +158,7 @@ + - update man page autofs(8) for systemd. + - fix fix master map type check. + - fix typo in update_hosts_mounts(). ++- fix hosts map update on reload. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -1356,16 +1356,35 @@ int parse_mount(struct autofs_point *ap, + } + + cache_multi_writelock(me); +- /* Someone beat us to it, return success */ +- if (me->multi) { +- free(options); +- cache_multi_unlock(me); +- cache_unlock(mc); +- pthread_setcancelstate(cur_state, NULL); +- return 0; +- } + /* So we know we're the multi-mount root */ +- me->multi = me; ++ if (!me->multi) ++ me->multi = me; ++ else { ++ /* ++ * The amd host mount type assumes the lookup name ++ * is the host name for the host mount but amd uses ++ * ${rhost} for this. ++ * ++ * This introduces the possibility of multiple ++ * concurrent mount requests since constructing a ++ * mount tree that isn't under the lookup name can't ++ * take advantage of the kernel queuing of other ++ * concurrent lookups while the mount tree is ++ * constructed. ++ * ++ * Consequently multi-mount updates (currently only ++ * done for the internal hosts map which the amd ++ * parser also uses for its hosts map) can't be ++ * allowed for amd mounts. ++ */ ++ if (source->flags & MAP_FLAG_FORMAT_AMD) { ++ free(options); ++ cache_multi_unlock(me); ++ cache_unlock(mc); ++ pthread_setcancelstate(cur_state, NULL); ++ return 0; ++ } ++ } + + age = me->age; + diff --git a/SOURCES/autofs-5.1.0-fix-incorrect-check-in-parse_mount.patch b/SOURCES/autofs-5.1.0-fix-incorrect-check-in-parse_mount.patch new file mode 100644 index 0000000..d1e52a4 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-incorrect-check-in-parse_mount.patch @@ -0,0 +1,171 @@ +autofs-5.1.0 - fix incorrect check in parse_mount() + +From: Ian Kent + +The change to allow the use of the hosts map in map entries introduced +an invalid check into parse_mount(). The case attempts to check the +contents of an options string that is always invalid for the return +value case in which it is checked, not to mention the check itself is +incorrect. +--- + CHANGELOG | 1 + modules/parse_sun.c | 70 ++++++++++++++++++++++++++++++++-------------------- + 2 files changed, 45 insertions(+), 26 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -164,6 +164,7 @@ + - dont add wildcard to negative cache. + - add a prefix to program map stdvars. + - add config option to force use of program map stdvars. ++- fix incorrect check in parse_mount(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -756,6 +756,8 @@ update_offset_entry(struct autofs_point + + mc = source->mc; + ++ memset(m_mapent, 0, MAPENT_MAX_LEN + 1); ++ + /* Internal hosts map may have loc == NULL */ + if (!*path) { + error(ap->logopt, +@@ -782,7 +784,7 @@ update_offset_entry(struct autofs_point + if (*myoptions) + m_options_len = strlen(myoptions) + 2; + +- m_mapent_len = strlen(loc); ++ m_mapent_len = loc ? strlen(loc) : 0; + if (m_mapent_len + m_options_len > MAPENT_MAX_LEN) { + error(ap->logopt, MODPREFIX "multi mount mapent too long"); + return CHE_FAIL; +@@ -793,10 +795,13 @@ update_offset_entry(struct autofs_point + strcat(m_mapent, myoptions); + if (loc) { + strcat(m_mapent, " "); +- strcat(m_mapent, loc); ++ if (loc) ++ strcat(m_mapent, loc); + } +- } else +- strcpy(m_mapent, loc); ++ } else { ++ if (loc) ++ strcpy(m_mapent, loc); ++ } + + ret = cache_update_offset(mc, name, m_key, m_mapent, age); + if (ret == CHE_DUPLICATE) +@@ -923,9 +928,15 @@ static int parse_mapent(const char *ent, + l = chunklen(p, check_colon(p)); + loc = dequote(p, l, logopt); + if (!loc) { +- warn(logopt, MODPREFIX "possible missing location"); +- free(myoptions); +- return 0; ++ if (strstr(myoptions, "fstype=autofs") && ++ strstr(myoptions, "hosts")) { ++ warn(logopt, MODPREFIX "possible missing location"); ++ free(myoptions); ++ return 0; ++ } ++ *options = myoptions; ++ *location = NULL; ++ return (p - ent); + } + + /* Location can't begin with a '/' */ +@@ -953,10 +964,15 @@ static int parse_mapent(const char *ent, + l = chunklen(p, check_colon(p)); + ent_chunk = dequote(p, l, logopt); + if (!ent_chunk) { +- warn(logopt, MODPREFIX "null location or out of memory"); +- free(myoptions); +- free(loc); +- return 0; ++ if (strstr(myoptions, "fstype=autofs") && ++ strstr(myoptions, "hosts")) { ++ warn(logopt, MODPREFIX ++ "null location or out of memory"); ++ free(myoptions); ++ free(loc); ++ return 0; ++ } ++ goto next; + } + + /* Location can't begin with a '/' */ +@@ -992,7 +1008,7 @@ static int parse_mapent(const char *ent, + strcat(loc, ent_chunk); + + free(ent_chunk); +- ++next: + p += l; + p = skipspace(p); + } +@@ -1093,7 +1109,9 @@ static int mount_subtree(struct autofs_p + cache_delete_offset_list(me->mc, name); + return 1; + } +- ro_len = strlen(ro_loc); ++ ro_len = 0; ++ if (ro_loc) ++ ro_len = strlen(ro_loc); + + tmp = alloca(mnt_root_len + 2); + strcpy(tmp, mnt_root); +@@ -1104,7 +1122,8 @@ static int mount_subtree(struct autofs_p + rv = sun_mount(ap, root, name, namelen, ro_loc, ro_len, myoptions, ctxt); + + free(myoptions); +- free(ro_loc); ++ if (ro_loc) ++ free(ro_loc); + } + + if (ro && rv == 0) { +@@ -1420,16 +1439,13 @@ int parse_mount(struct autofs_point *ap, + + l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); + if (!l) { +- if (!(strstr(myoptions, "fstype=autofs") && +- strstr(myoptions, "hosts"))) { +- cache_delete_offset_list(mc, name); +- cache_multi_unlock(me); +- cache_unlock(mc); +- free(path); +- free(options); +- pthread_setcancelstate(cur_state, NULL); +- return 1; +- } ++ cache_delete_offset_list(mc, name); ++ cache_multi_unlock(me); ++ cache_unlock(mc); ++ free(path); ++ free(options); ++ pthread_setcancelstate(cur_state, NULL); ++ return 1; + } + + p += l; +@@ -1450,12 +1466,14 @@ int parse_mount(struct autofs_point *ap, + free(path); + free(options); + free(myoptions); +- free(loc); ++ if (loc) ++ free(loc); + pthread_setcancelstate(cur_state, NULL); + return 1; + } + +- free(loc); ++ if (loc) ++ free(loc); + free(path); + free(myoptions); + } while (*p == '/' || (*p == '"' && *(p + 1) == '/')); diff --git a/SOURCES/autofs-5.1.0-fix-incorrect-round-robin-host-detection.patch b/SOURCES/autofs-5.1.0-fix-incorrect-round-robin-host-detection.patch new file mode 100644 index 0000000..e4cdd34 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-incorrect-round-robin-host-detection.patch @@ -0,0 +1,31 @@ +autofs-5.1.0 - fix incorrect round robin host detection + +From: Ian Kent + + +--- + CHANGELOG | 1 + + modules/replicated.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -128,6 +128,7 @@ + - allow empty value in macro selectors. + - add serialization to sasl init. + - dont allocate dev_ctl_ops too early. ++- fix incorrect round robin host detection. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/replicated.c ++++ autofs-5.0.7/modules/replicated.c +@@ -946,7 +946,7 @@ try_name: + } + + this = ni; +- while (this->ai_next) { ++ while (this) { + if (this->ai_family == AF_INET) { + struct sockaddr_in *addr = (struct sockaddr_in *) this->ai_addr; + if (addr->sin_addr.s_addr != INADDR_LOOPBACK) diff --git a/SOURCES/autofs-5.1.0-fix-leak-in-cache_push_mapent.patch b/SOURCES/autofs-5.1.0-fix-leak-in-cache_push_mapent.patch new file mode 100644 index 0000000..c98a961 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-leak-in-cache_push_mapent.patch @@ -0,0 +1,32 @@ +autofs-5.1.0 - fix leak in cache_push_mapent() + +From: Ian Kent + +cache_push_mapent() incorectly sets the cache entry mapent to the old +value which causes a memory leak when the new map entry isn't NULL. +--- + CHANGELOG | 1 + + lib/cache.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -130,6 +130,7 @@ + - dont allocate dev_ctl_ops too early. + - fix incorrect round robin host detection. + - fix race accessing qdn in get_query_dn(). ++- fix leak in cache_push_mapent(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/cache.c ++++ autofs-5.0.7/lib/cache.c +@@ -203,7 +203,7 @@ int cache_push_mapent(struct mapent *me, + + s->mapent = me->mapent; + s->age = me->age; +- me->mapent = mapent; ++ me->mapent = new; + + if (me->stack) + s->next = me->stack; diff --git a/SOURCES/autofs-5.1.0-fix-leak-in-get_network_proximity.patch b/SOURCES/autofs-5.1.0-fix-leak-in-get_network_proximity.patch new file mode 100644 index 0000000..87df882 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-leak-in-get_network_proximity.patch @@ -0,0 +1,35 @@ +autofs-5.1.0 - fix leak in get_network_proximity() + +From: Ian Kent + +Fix variable net not freed after use in get_network_proximity(). +--- + CHANGELOG | 1 + + lib/parse_subs.c | 5 +++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -136,6 +136,7 @@ + - fix memory leak in conf_amd_get_log_options(). + - fix signed comparison in inet_fill_net(). + - fix buffer size checks in get_network_proximity(). ++- fix leak in get_network_proximity(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/parse_subs.c ++++ autofs-5.0.7/lib/parse_subs.c +@@ -446,9 +446,10 @@ unsigned int get_network_proximity(const + return PROXIMITY_ERROR; + + net = get_network_number(name); +- if (net) ++ if (net) { + strcpy(name_or_num, net); +- else { ++ free(net); ++ } else { + char this[NI_MAXHOST + 1]; + char *mask; + diff --git a/SOURCES/autofs-5.1.0-fix-leak-in-parse_mount.patch b/SOURCES/autofs-5.1.0-fix-leak-in-parse_mount.patch new file mode 100644 index 0000000..6959316 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-leak-in-parse_mount.patch @@ -0,0 +1,45 @@ +autofs-5.1.0 - fix leak in parse_mount() + +From: Ian Kent + +Fix a potential memory leak of the allocated mount location +in modules/parse_sun.c:parse_mount(). +--- + CHANGELOG | 1 + + modules/parse_sun.c | 8 ++++++-- + 2 files changed, 7 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -144,6 +144,7 @@ + - check options length before use in parse_amd.c. + - fix some out of order evaluations in parse_amd.c. + - fix copy and paste error in dup_defaults_entry(). ++- fix leak in parse_mount(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -1567,7 +1567,10 @@ int parse_mount(struct autofs_point *ap, + */ + if ((strstr(options, "fstype=autofs") && + strstr(options, "hosts"))) { +- loc = NULL; ++ if (loc) { ++ free(loc); ++ loc = NULL; ++ } + loclen = 0; + } else { + loclen = strlen(loc); +@@ -1591,7 +1594,8 @@ int parse_mount(struct autofs_point *ap, + rv = sun_mount(ap, ap->path, name, name_len, + loc, loclen, options, ctxt); + +- free(loc); ++ if (loc) ++ free(loc); + free(options); + pthread_setcancelstate(cur_state, NULL); + } diff --git a/SOURCES/autofs-5.1.0-fix-macro-usage-in-lookup_program_c.patch b/SOURCES/autofs-5.1.0-fix-macro-usage-in-lookup_program_c.patch new file mode 100644 index 0000000..7416db1 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-macro-usage-in-lookup_program_c.patch @@ -0,0 +1,34 @@ +autofs-5.1.0 - fix macro usage in lookup_program.c + +From: Ian Kent + +The macro MAPFMT_DEFAULT is used incorrectly in a comparison in +modules/lookup_program.c:lookup_one(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_program.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -166,6 +166,7 @@ + - add config option to force use of program map stdvars. + - fix incorrect check in parse_mount(). + - handle duplicates in multi mounts. ++- fix macro usage in lookup_program.c. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -190,7 +190,7 @@ static char *lookup_one(struct autofs_po + * MAPFMT_DEFAULT must be "sun" for ->parse_init() to have setup + * the macro table. + */ +- if (ctxt->mapfmt && strcmp(ctxt->mapfmt, "MAPFMT_DEFAULT")) { ++ if (ctxt->mapfmt && !strcmp(ctxt->mapfmt, MAPFMT_DEFAULT)) { + struct parse_context *pctxt = (struct parse_context *) ctxt->parse->context; + /* Add standard environment as seen by sun map parser */ + pctxt->subst = addstdenv(pctxt->subst, prefix); diff --git a/SOURCES/autofs-5.1.0-fix-mem-leak-in-create_client.patch b/SOURCES/autofs-5.1.0-fix-mem-leak-in-create_client.patch new file mode 100644 index 0000000..84cbf99 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-mem-leak-in-create_client.patch @@ -0,0 +1,35 @@ +autofs-5.1.0 - fix memory leak in create_client() + +From: Ian Kent + +In create_client(), if the target host is unreachable the function +exists without freeing the addrinfo data returned from getaddrinfo(3). +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -148,6 +148,7 @@ + - add mutex call return check in defaults.c. + - force disable browse mode for amd format maps. + - fix hosts map options check in lookup_amd_instance(). ++- fix memory leak in create_client(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/rpc_subs.c ++++ autofs-5.0.7/lib/rpc_subs.c +@@ -719,8 +719,10 @@ static int create_client(struct conn_inf + ret = rpc_do_create_client(haddr->ai_addr, info, &fd, client); + if (ret == 0) + break; +- if (ret == -EHOSTUNREACH) ++ if (ret == -EHOSTUNREACH) { ++ freeaddrinfo(ai); + goto out_close; ++ } + + if (!info->client && fd != RPC_ANYSOCK) { + close(fd); diff --git a/SOURCES/autofs-5.1.0-fix-memory-leak-in-conf_amd_get_log_options.patch b/SOURCES/autofs-5.1.0-fix-memory-leak-in-conf_amd_get_log_options.patch new file mode 100644 index 0000000..557f8a9 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-memory-leak-in-conf_amd_get_log_options.patch @@ -0,0 +1,30 @@ +autofs-5.1.0 - fix memory leak in conf_amd_get_log_options() + +From: Ian Kent + +Fix obvious memory leak in conf_amd_get_log_options(). +--- + CHANGELOG | 1 + + lib/defaults.c | 1 + + 2 files changed, 2 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -133,6 +133,7 @@ + - fix leak in cache_push_mapent(). + - fix config entry read buffer not checked. + - fix FILE pointer check in defaults_read_config(). ++- fix memory leak in conf_amd_get_log_options(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -1794,6 +1794,7 @@ unsigned int conf_amd_get_log_options(vo + if (log_level < LOG_CRIT) + log_level = LOG_CRIT; + } ++ free(tmp); + } + + if (log_level == -1) diff --git a/SOURCES/autofs-5.1.0-fix-memory-leak-in-get_defaults_entry.patch b/SOURCES/autofs-5.1.0-fix-memory-leak-in-get_defaults_entry.patch new file mode 100644 index 0000000..d4fe877 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-memory-leak-in-get_defaults_entry.patch @@ -0,0 +1,35 @@ +autofs-5.1.0 - fix memory leak in get_defaults_entry() + +From: Ian Kent + +In get_defaults_entry(), if parsing of the expanded defaults string fails +the expanded string used for the parse is not freed. +--- + CHANGELOG | 1 + + modules/parse_amd.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -150,6 +150,7 @@ + - fix hosts map options check in lookup_amd_instance(). + - fix memory leak in create_client(). + - fix memory leak in get_exports(). ++- fix memory leak in get_defaults_entry(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -1797,8 +1797,10 @@ static struct amd_entry *get_defaults_en + char *expand; + if (!expand_selectors(ap, defaults, &expand, sv)) + goto out; +- if (amd_parse_list(ap, expand, &dflts, &sv)) ++ if (amd_parse_list(ap, expand, &dflts, &sv)) { ++ free(expand); + goto out; ++ } + entry = select_default_entry(ap, &dflts, sv); + if (!entry->map_type) { + /* diff --git a/SOURCES/autofs-5.1.0-fix-memory-leak-in-get_exports.patch b/SOURCES/autofs-5.1.0-fix-memory-leak-in-get_exports.patch new file mode 100644 index 0000000..f1d0516 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-memory-leak-in-get_exports.patch @@ -0,0 +1,81 @@ +autofs-5.1.0 - fix memory leak in get_exports() + +From: Ian Kent + +In modules/lookup_hosts.c:get_exports() looping over the returned list of +exports uses the pointer that contains the list. The pointer is updated +in the process of creating the exports multi-mount so a pointer to the +returned list is no longer available to be freed when done. +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 17 +++++++++-------- + 2 files changed, 10 insertions(+), 8 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -149,6 +149,7 @@ + - force disable browse mode for amd format maps. + - fix hosts map options check in lookup_amd_instance(). + - fix memory leak in create_client(). ++- fix memory leak in get_exports(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_hosts.c ++++ autofs-5.0.7/modules/lookup_hosts.c +@@ -82,18 +82,19 @@ static char *get_exports(struct autofs_p + { + char buf[MAX_ERR_BUF]; + char *mapent; +- exports exp; ++ exports exp, this; + + debug(ap->logopt, MODPREFIX "fetchng export list for %s", host); + + exp = rpc_get_exports(host, 10, 0, RPC_CLOSE_NOLINGER); + + mapent = NULL; +- while (exp) { ++ this = exp; ++ while (this) { + if (mapent) { + int len = strlen(mapent) + 1; + +- len += strlen(host) + 2*(strlen(exp->ex_dir) + 2) + 3; ++ len += strlen(host) + 2*(strlen(this->ex_dir) + 2) + 3; + mapent = realloc(mapent, len); + if (!mapent) { + char *estr; +@@ -103,10 +104,10 @@ static char *get_exports(struct autofs_p + return NULL; + } + strcat(mapent, " \""); +- strcat(mapent, exp->ex_dir); ++ strcat(mapent, this->ex_dir); + strcat(mapent, "\""); + } else { +- int len = 2*(strlen(exp->ex_dir) + 2) + strlen(host) + 3; ++ int len = 2*(strlen(this->ex_dir) + 2) + strlen(host) + 3; + + mapent = malloc(len); + if (!mapent) { +@@ -117,16 +118,16 @@ static char *get_exports(struct autofs_p + return NULL; + } + strcpy(mapent, "\""); +- strcat(mapent, exp->ex_dir); ++ strcat(mapent, this->ex_dir); + strcat(mapent, "\""); + } + strcat(mapent, " \""); + strcat(mapent, host); + strcat(mapent, ":"); +- strcat(mapent, exp->ex_dir); ++ strcat(mapent, this->ex_dir); + strcat(mapent, "\""); + +- exp = exp->ex_next; ++ this = this->ex_next; + } + rpc_exports_free(exp); + diff --git a/SOURCES/autofs-5.1.0-fix-mount-as-you-go-offset-selection.patch b/SOURCES/autofs-5.1.0-fix-mount-as-you-go-offset-selection.patch new file mode 100644 index 0000000..42989cf --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-mount-as-you-go-offset-selection.patch @@ -0,0 +1,84 @@ +autofs-5.1.0 - fix mount as you go offset selection + +From: Ian Kent + +The function cache_get_offset() returns offsets to be mounted that +are within the current current subtree for the mount-as-you-go +functionality used for nested multi-mount map entries. + +However, the function was returning offsets from the subree below +nesting points which prevented the mount at the containing nesting +point from being mounted. This is because the kernel will see a +non-empty directory and conclude it isn't a mount point. +--- + CHANGELOG | 1 + + lib/cache.c | 27 ++++++++++++++++++++++++--- + 2 files changed, 25 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -168,6 +168,7 @@ + - handle duplicates in multi mounts. + - fix macro usage in lookup_program.c. + - remove unused offset handling code. ++- fix mount as you go offset selection. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/cache.c ++++ autofs-5.0.7/lib/cache.c +@@ -1183,7 +1183,6 @@ struct mapent *cache_enumerate(struct ma + * Get each offset from list head under prefix. + * Maintain traversal current position in pos for subsequent calls. + * Return each offset into offset. +- * TODO: length check on offset. + */ + /* cache must be read locked by caller */ + char *cache_get_offset(const char *prefix, char *offset, int start, +@@ -1212,6 +1211,9 @@ char *cache_get_offset(const char *prefi + continue; + + if (!strncmp(prefix, offset_start, plen)) { ++ struct mapent *np = NULL; ++ char pe[PATH_MAX + 1]; ++ + /* "/" doesn't count for root offset */ + if (plen == 1) + pstart = &offset_start[plen - 1]; +@@ -1224,7 +1226,24 @@ char *cache_get_offset(const char *prefi + + /* get next offset */ + pend = pstart; +- while (*pend++) ; ++ while (*pend++) { ++ size_t nest_pt_offset; ++ ++ if (*pend != '/') ++ continue; ++ ++ nest_pt_offset = start + pend - pstart; ++ if (plen > 1) ++ nest_pt_offset += plen; ++ strcpy(pe, this->key); ++ pe[nest_pt_offset] = '\0'; ++ ++ np = cache_lookup_distinct(this->mc, pe); ++ if (np) ++ break; ++ } ++ if (np) ++ continue; + len = pend - pstart - 1; + strncpy(offset, pstart, len); + offset[len] ='\0'; +@@ -1257,7 +1276,9 @@ char *cache_get_offset(const char *prefi + break; + + /* compare offset */ +- if (pstart[len] != '/' || strncmp(offset, pstart, len)) ++ if (pstart[len] != '/' || ++ strlen(pstart) != len || ++ strncmp(offset, pstart, len)) + break; + + *pos = next; diff --git a/SOURCES/autofs-5.1.0-fix-out-of-order-clearing-of-options-buffer.patch b/SOURCES/autofs-5.1.0-fix-out-of-order-clearing-of-options-buffer.patch new file mode 100644 index 0000000..85da1e7 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-out-of-order-clearing-of-options-buffer.patch @@ -0,0 +1,39 @@ +autofs-5.1.0 - fix out of order clearing of options buffer + +From: Ian Kent + +When setting the result of parsing an options string the options buffer +was being cleared before use. +--- + CHANGELOG | 1 + + modules/amd_parse.y | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -151,6 +151,7 @@ + - fix memory leak in create_client(). + - fix memory leak in get_exports(). + - fix memory leak in get_defaults_entry(). ++- fix out of order clearing of options buffer. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/amd_parse.y ++++ autofs-5.0.7/modules/amd_parse.y +@@ -396,7 +396,6 @@ option_assignment: MAP_OPTION OPTION_ASS + } + | MNT_OPTION OPTION_ASSIGN options + { +- memset(opts, 0, sizeof(opts)); + if (!strcmp($1, "opts")) + entry.opts = amd_strdup(opts); + else if (!strcmp($1, "addopts")) +@@ -407,6 +406,7 @@ option_assignment: MAP_OPTION OPTION_ASS + amd_notify($1); + YYABORT; + } ++ memset(opts, 0, sizeof(opts)); + } + | MNT_OPTION OPTION_ASSIGN + { diff --git a/SOURCES/autofs-5.1.0-fix-reset-amd-lexer-scan-buffer.patch b/SOURCES/autofs-5.1.0-fix-reset-amd-lexer-scan-buffer.patch new file mode 100644 index 0000000..1dcec58 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-reset-amd-lexer-scan-buffer.patch @@ -0,0 +1,225 @@ +autofs-5.1.0 - fix reset amd lexer scan buffer + +From: Ian Kent + +When the amd parser encounters an error often the lexer is left in +a state where a new parse can't be started. Fix this by explicitly +naming our start states and resetting to the proper start state at +buffer initialization on each scan. +--- + CHANGELOG | 1 + modules/amd_tok.l | 59 +++++++++++++++++++++++++++++++--------------------- + modules/parse_amd.c | 3 ++ + 3 files changed, 40 insertions(+), 23 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -152,6 +152,7 @@ + - fix memory leak in get_exports(). + - fix memory leak in get_defaults_entry(). + - fix out of order clearing of options buffer. ++- fix reset amd lexer scan buffer. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/amd_tok.l ++++ autofs-5.0.7/modules/amd_tok.l +@@ -1,4 +1,3 @@ +-%{ + /* ----------------------------------------------------------------------- * + * + * Copyright 2013 Ian Kent +@@ -18,6 +17,12 @@ + * + * ----------------------------------------------------------------------- */ + ++%s START MAPOPTVAL FSOPTVAL MNTOPTVAL SELOPTVAL SELARGVAL ++ ++%{ ++ ++static int reset_start_state = 0; ++ + #ifdef ECHO + # undef ECHO + #endif +@@ -71,8 +76,6 @@ int amd_yyinput(char *, int); + + %option nounput + +-%x MAPOPTVAL FSOPTVAL MNTOPTVAL SELOPTVAL SELARGVAL +- + NL \r?\n + OPTWS [[:blank:]]* + OTHR [^!;:=/|\- \t\r\n#]* +@@ -120,7 +123,14 @@ CUTSEP (\|\||\/) + + %% + +-{ ++%{ ++ if (reset_start_state) { ++ BEGIN START; ++ reset_start_state = 0; ++ } ++%} ++ ++{ + {NL} | + \x00 { } + +@@ -179,23 +189,23 @@ CUTSEP (\|\||\/) + + { + {NL} { +- BEGIN(INITIAL); ++ BEGIN(START); + yyless(1); + } + + \x00 { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + yyless(1); + } + + ";" { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + } + + {OPTWS} { +- BEGIN(INITIAL); ++ BEGIN(START); + return SPACE; + } + +@@ -224,23 +234,23 @@ CUTSEP (\|\||\/) + + { + {NL} { +- BEGIN(INITIAL); ++ BEGIN(START); + yyless(1); + } + + \x00 { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + yyless(1); + } + + ";" { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + } + + {OPTWS} { +- BEGIN(INITIAL); ++ BEGIN(START); + return SPACE; + } + +@@ -254,23 +264,23 @@ CUTSEP (\|\||\/) + + { + {NL} { +- BEGIN(INITIAL); ++ BEGIN(START); + yyless(1); + } + + \x00 { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + yyless(1); + } + + ";" { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + } + + {OPTWS} { +- BEGIN(INITIAL); ++ BEGIN(START); + return SPACE; + } + +@@ -286,23 +296,23 @@ CUTSEP (\|\||\/) + + { + {NL} { +- BEGIN(INITIAL); ++ BEGIN(START); + yyless(1); + } + + \x00 { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + yyless(1); + } + + ";" { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + } + + {OPTWS} { +- BEGIN(INITIAL); ++ BEGIN(START); + return SPACE; + } + +@@ -318,18 +328,18 @@ CUTSEP (\|\||\/) + + { + {NL} { +- BEGIN(INITIAL); ++ BEGIN(START); + yyless(1); + } + + \x00 { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + yyless(1); + } + + ";" { +- BEGIN(INITIAL); ++ BEGIN(START); + return SEPERATOR; + } + +@@ -391,6 +401,9 @@ static void amd_echo(void) + + void amd_set_scan_buffer(const char *buffer) + { ++ YY_FLUSH_BUFFER; ++ reset_start_state = 1; ++ + line = buffer; + line_pos = &line[0]; + /* +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -1798,6 +1798,9 @@ static struct amd_entry *get_defaults_en + if (!expand_selectors(ap, defaults, &expand, sv)) + goto out; + if (amd_parse_list(ap, expand, &dflts, &sv)) { ++ error(ap->logopt, MODPREFIX ++ "failed to parse defaults entry, " ++ "attempting to use internal default"); + free(expand); + goto out; + } diff --git a/SOURCES/autofs-5.1.0-fix-signed-comparison-in-inet_fill_net.patch b/SOURCES/autofs-5.1.0-fix-signed-comparison-in-inet_fill_net.patch new file mode 100644 index 0000000..14dc2b4 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-signed-comparison-in-inet_fill_net.patch @@ -0,0 +1,32 @@ +autofs-5.1.0 - fix signed comparison in inet_fill_net() + +From: Ian Kent + +Fix the less than 0 comparison of an incorrectly declared var in +inet_fill_net(). +--- + CHANGELOG | 1 + + lib/parse_subs.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -134,6 +134,7 @@ + - fix config entry read buffer not checked. + - fix FILE pointer check in defaults_read_config(). + - fix memory leak in conf_amd_get_log_options(). ++- fix signed comparison in inet_fill_net(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/parse_subs.c ++++ autofs-5.0.7/lib/parse_subs.c +@@ -378,7 +378,7 @@ unsigned int get_proximity(struct sockad + static char *inet_fill_net(const char *net_num, char *net) + { + char *np; +- unsigned int dots = 3; ++ int dots = 3; + + if (strlen(net_num) > INET_ADDRSTRLEN) + return NULL; diff --git a/SOURCES/autofs-5.1.0-fix-some-out-of-order-evaluations-in-parse_amd_c.patch b/SOURCES/autofs-5.1.0-fix-some-out-of-order-evaluations-in-parse_amd_c.patch new file mode 100644 index 0000000..ec8def8 --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-some-out-of-order-evaluations-in-parse_amd_c.patch @@ -0,0 +1,103 @@ +autofs-5.1.0 - fix some out of order evaluations in parse_amd.c + +From: Ian Kent + +Fix some check contents before NULL check ordering in modules/parse_amd.c. +--- + CHANGELOG | 1 + + modules/parse_amd.c | 33 ++++++++++++++------------------- + 2 files changed, 15 insertions(+), 19 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -142,6 +142,7 @@ + - add return check in ldap check_map_indirect(). + - check host macro is set before use. + - check options length before use in parse_amd.c. ++- fix some out of order evaluations in parse_amd.c. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -1226,13 +1226,12 @@ static unsigned int validate_auto_option + * left blank the mount must be expected to fail so don't + * report the error. + */ +- if (!*entry->fs) +- return 0; +- else if (!entry->fs) { ++ if (!entry->fs) { + error(logopt, MODPREFIX + "%s: file system not given", entry->type); + return 0; +- } ++ } else if (!*entry->fs) ++ return 0; + return 1; + } + +@@ -1255,13 +1254,12 @@ static unsigned int validate_nfs_options + * expected to fail. + */ + if (!entry->rfs || !*entry->rfs) { +- if (!*entry->rfs) ++ if (entry->rfs && !*entry->rfs) + return 0; + /* Map option fs has been intentionally left blank */ + if (entry->fs && !*entry->fs) + return 0; +- if (entry->fs) +- entry->rfs = strdup(entry->fs); ++ entry->rfs = strdup(entry->fs); + if (!entry->rfs) { + error(logopt, MODPREFIX + "%s: remote file system not given", entry->type); +@@ -1285,24 +1283,22 @@ static unsigned int validate_generic_opt + * expected to fail so don't report the error. + */ + if (fstype != AMD_MOUNT_TYPE_LOFS) { +- if (!*entry->dev) +- return 0; +- else if (!entry->dev) { ++ if (!entry->dev) { + error(logopt, MODPREFIX + "%s: mount device not given", entry->type); + return 0; +- } +- } else { +- if (!*entry->rfs) ++ } else if (!*entry->dev) + return 0; +- else if (!entry->rfs) { ++ } else { ++ if (!entry->rfs) { + /* + * Can't use entry->type as the mount type to reprot + * the error since entry->type == "bind" not "lofs". + */ + error(logopt, "lofs: mount device not given"); + return 0; +- } ++ } else if (!*entry->rfs) ++ return 0; + } + if (entry->sublink && !entry->fs) { + error(logopt, MODPREFIX +@@ -1337,13 +1333,12 @@ static unsigned int validate_host_option + * if it isn't given in the map entry. Don't report an error + * if it has been left empty since it's expected to fail. + */ +- if (!*entry->rhost) +- return 0; +- else if (!entry->rhost) { ++ if (!entry->rhost) { + error(logopt, MODPREFIX + "%s: remote host name not given", entry->type); + return 0; +- } ++ } else if (!*entry->rhost) ++ return 0; + return 1; + } + diff --git a/SOURCES/autofs-5.1.0-fix-typo-in-update_hosts_mounts.patch b/SOURCES/autofs-5.1.0-fix-typo-in-update_hosts_mounts.patch new file mode 100644 index 0000000..67566bf --- /dev/null +++ b/SOURCES/autofs-5.1.0-fix-typo-in-update_hosts_mounts.patch @@ -0,0 +1,31 @@ +autofs-5.1.0 - fix typo in update_hosts_mounts() + +From: Ian Kent + +Correct the stutter in the update exports message. +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -157,6 +157,7 @@ + - clarify multiple mounts description. + - update man page autofs(8) for systemd. + - fix fix master map type check. ++- fix typo in update_hosts_mounts(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_hosts.c ++++ autofs-5.0.7/modules/lookup_hosts.c +@@ -214,7 +214,7 @@ next: + goto cont; + + debug(ap->logopt, MODPREFIX +- "attempt to update exports for exports for %s", me->key); ++ "attempt to update exports for %s", me->key); + + master_source_current_wait(ap->entry); + ap->entry->current = source; diff --git a/SOURCES/autofs-5.1.0-force-disable-browse-mode-for-amd-format-maps.patch b/SOURCES/autofs-5.1.0-force-disable-browse-mode-for-amd-format-maps.patch new file mode 100644 index 0000000..cc83947 --- /dev/null +++ b/SOURCES/autofs-5.1.0-force-disable-browse-mode-for-amd-format-maps.patch @@ -0,0 +1,46 @@ +autofs-5.1.0 - force disable browse mode for amd format maps + +From: Ian Kent + +As in am-utils amd format maps using autofs file system don't support +the browse option and in autofs they don't work properly if it is used. + +This might be implemented later but for now forcefully disable it. +--- + CHANGELOG | 1 + + lib/master_parse.y | 2 ++ + modules/mount_autofs.c | 2 ++ + 3 files changed, 5 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -146,6 +146,7 @@ + - fix copy and paste error in dup_defaults_entry(). + - fix leak in parse_mount(). + - add mutex call return check in defaults.c. ++- force disable browse mode for amd format maps. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/master_parse.y ++++ autofs-5.0.7/lib/master_parse.y +@@ -810,6 +810,8 @@ int master_parse_entry(const char *buffe + logopt = LOGOPT_DEBUG; + else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) + logopt = LOGOPT_VERBOSE; ++ /* amd mounts don't support browse mode */ ++ ghost = 0; + } + + +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -261,6 +261,8 @@ int mount_mount(struct autofs_point *ap, + nap->pref = am_entry->pref; + am_entry->pref = NULL; + } ++ /* amd mounts don't support browse mode */ ++ nap->flags &= ~MOUNT_FLAG_GHOST; + } + + if (handle_mounts_startup_cond_init(&suc)) { diff --git a/SOURCES/autofs-5.1.0-guard-against-incorrect-umount-return.patch b/SOURCES/autofs-5.1.0-guard-against-incorrect-umount-return.patch new file mode 100644 index 0000000..e996fed --- /dev/null +++ b/SOURCES/autofs-5.1.0-guard-against-incorrect-umount-return.patch @@ -0,0 +1,57 @@ +autofs-5.1.0 - guard against incorrect umount return + +From: Ian Kent + +If umount(8) returns a fail but the mount is actually umounted autofs +can incorrectly try reconstruct mount triggers. This can lead to the +automount point becoming unresponsive. +--- + CHANGELOG | 1 + + daemon/automount.c | 3 ++- + lib/mounts.c | 6 ++++-- + 3 files changed, 7 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -184,6 +184,7 @@ + - fix out of order call in program map lookup. + - make service want network-online. + - add remote-fs.target systemd dependency. ++- gaurd against incorrect umount return. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -532,7 +532,8 @@ static int umount_subtree_mounts(struct + if (!is_mm_root && is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { + struct amd_entry *entry; + debug(ap->logopt, "unmounting dir = %s", path); +- if (umount_ent(ap, path)) { ++ if (umount_ent(ap, path) && ++ is_mounted(_PATH_MOUNTED, path, MNTS_REAL)) { + warn(ap->logopt, "could not umount dir %s", path); + left++; + goto done; +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -2126,7 +2126,8 @@ int umount_multi_triggers(struct autofs_ + */ + if (is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { + info(ap->logopt, "unmounting dir = %s", root); +- if (umount_ent(ap, root)) { ++ if (umount_ent(ap, root) && ++ is_mounted(_PATH_MOUNTED, root, MNTS_REAL)) { + if (mount_multi_triggers(ap, me, root, strlen(root), "/") < 0) + warn(ap->logopt, + "failed to remount offset triggers"); +@@ -2227,7 +2228,8 @@ int clean_stale_multi_triggers(struct au + */ + if (oe->ioctlfd != -1 || + is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) { +- if (umount_ent(ap, oe->key)) { ++ if (umount_ent(ap, oe->key) && ++ is_mounted(_PROC_MOUNTS, oe->key, MNTS_REAL)) { + debug(ap->logopt, + "offset %s has active mount, invalidate", + oe->key); diff --git a/SOURCES/autofs-5.1.0-handle-duplicates-in-multi-mounts.patch b/SOURCES/autofs-5.1.0-handle-duplicates-in-multi-mounts.patch new file mode 100644 index 0000000..48bbd5f --- /dev/null +++ b/SOURCES/autofs-5.1.0-handle-duplicates-in-multi-mounts.patch @@ -0,0 +1,76 @@ +autofs-5.1.0 - handle duplicates in multi mounts + +From: Ian Kent + +Duplicate entries in multi-mounts are a syntax error however some +other automount implementations allow them and attempt to continue +with the mount anyway. + +This patch turns a detected duplicate error into a success return +in order to continue. + +Since it can't be known if the first or the later entry is the +correct one to use the later replaces the old unless a memory +allocation error occures in which case the old entry is retained +and the change is noted in the log. +--- + CHANGELOG | 1 + + lib/cache.c | 19 ++++++++++++++++++- + modules/parse_sun.c | 5 +++-- + 3 files changed, 22 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -165,6 +165,7 @@ + - add a prefix to program map stdvars. + - add config option to force use of program map stdvars. + - fix incorrect check in parse_mount(). ++- handle duplicates in multi mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/cache.c ++++ autofs-5.0.7/lib/cache.c +@@ -733,8 +733,25 @@ int cache_update_offset(struct mapent_ca + + me = cache_lookup_distinct(mc, key); + if (me && me->age == age) { +- if (me == owner || strcmp(me->key, key) == 0) ++ if (me == owner || strcmp(me->key, key) == 0) { ++ char *pent; ++ ++ warn(logopt, ++ "duplcate offset detected for key %s", me->key); ++ ++ pent = malloc(strlen(mapent) + 1); ++ if (!pent) ++ warn(logopt, ++ "map entry not updated: %s", me->mapent); ++ else { ++ if (me->mapent) ++ free(me->mapent); ++ me->mapent = strcpy(pent, mapent); ++ warn(logopt, ++ "map entry updated with: %s", mapent); ++ } + return CHE_DUPLICATE; ++ } + } + + ret = cache_update(mc, owner->source, key, mapent, age); +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -804,10 +804,11 @@ update_offset_entry(struct autofs_point + } + + ret = cache_update_offset(mc, name, m_key, m_mapent, age); +- if (ret == CHE_DUPLICATE) ++ if (ret == CHE_DUPLICATE) { + warn(ap->logopt, MODPREFIX + "syntax error or duplicate offset %s -> %s", path, loc); +- else if (ret == CHE_FAIL) ++ ret = CHE_OK; ++ } else if (ret == CHE_FAIL) + debug(ap->logopt, MODPREFIX + "failed to update multi-mount offset %s -> %s", path, m_mapent); + else { diff --git a/SOURCES/autofs-5.1.0-ignore-multiple-commas-in-options-strings.patch b/SOURCES/autofs-5.1.0-ignore-multiple-commas-in-options-strings.patch new file mode 100644 index 0000000..85957ea --- /dev/null +++ b/SOURCES/autofs-5.1.0-ignore-multiple-commas-in-options-strings.patch @@ -0,0 +1,50 @@ +autofs-5.1.0 - ignore multiple commas in options strings + +From: Ian Kent + +When parsing options strings (such as opts, addopts or remopts) the parser +would object to multiple occurrances of the comma character. But this is +probably not a significant problem and the parser should just ignore them. +--- + CHANGELOG | 1 + + modules/amd_parse.y | 4 ++++ + modules/amd_tok.l | 4 ++-- + 3 files changed, 7 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -153,6 +153,7 @@ + - fix memory leak in get_defaults_entry(). + - fix out of order clearing of options buffer. + - fix reset amd lexer scan buffer. ++- ignore multiple commas in options strings. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/amd_parse.y ++++ autofs-5.0.7/modules/amd_parse.y +@@ -465,6 +465,10 @@ options: OPTION + { + prepend_opt(opts, $1); + } ++ | OPTION COMMA ++ { ++ prepend_opt(opts, $1); ++ } + ; + + %% +--- autofs-5.0.7.orig/modules/amd_tok.l ++++ autofs-5.0.7/modules/amd_tok.l +@@ -284,9 +284,9 @@ CUTSEP (\|\||\/) + return SPACE; + } + +- ":=" { return OPTION_ASSIGN; } ++ (:=)(,+)? { return OPTION_ASSIGN; } + +- "," { return COMMA; } ++ ,+ { return COMMA; } + + {OPTS} { + amd_copy_buffer(); diff --git a/SOURCES/autofs-5.1.0-init-qdn-before-use.patch b/SOURCES/autofs-5.1.0-init-qdn-before-use.patch new file mode 100644 index 0000000..ae83a4b --- /dev/null +++ b/SOURCES/autofs-5.1.0-init-qdn-before-use.patch @@ -0,0 +1,31 @@ +autofs-5.1.0 - init qdn before use in get_query_dn() + +From: Ian Kent + +Ensure qdn is initialized before use in case there's garbage in it. +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -169,6 +169,7 @@ + - fix macro usage in lookup_program.c. + - remove unused offset handling code. + - fix mount as you go offset selection. ++- init qdn before use in get_query_dn(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -335,7 +335,7 @@ LDAP *init_ldap_connection(unsigned logo + static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key) + { + char buf[MAX_ERR_BUF]; +- char *query, *dn, *qdn; ++ char *query, *dn, *qdn = NULL; + LDAPMessage *result = NULL, *e; + char *attrs[2]; + struct berval **value; diff --git a/SOURCES/autofs-5.1.0-make-negative-cache-update-consistent-for-all-lookup-modules.patch b/SOURCES/autofs-5.1.0-make-negative-cache-update-consistent-for-all-lookup-modules.patch new file mode 100644 index 0000000..928c1ce --- /dev/null +++ b/SOURCES/autofs-5.1.0-make-negative-cache-update-consistent-for-all-lookup-modules.patch @@ -0,0 +1,100 @@ +autofs-5.1.0 - make negative cache update consistent for all lookup modules + +From: Ian Kent + +Use common function for negative cache update everywhere to ensure consistency. +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 14 +------------- + modules/lookup_nisplus.c | 13 +------------ + modules/lookup_program.c | 14 +------------- + 4 files changed, 4 insertions(+), 38 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -159,6 +159,7 @@ + - fix fix master map type check. + - fix typo in update_hosts_mounts(). + - fix hosts map update on reload. ++- make negative cache update consistent for all lookup modules. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_hosts.c ++++ autofs-5.0.7/modules/lookup_hosts.c +@@ -149,22 +149,10 @@ static int do_parse_mount(struct autofs_ + ret = ctxt->parse->parse_mount(ap, name, name_len, + mapent, ctxt->parse->context); + if (ret) { +- time_t now = time(NULL); + struct mapent_cache *mc = source->mc; +- struct mapent *me; +- int rv = CHE_OK; + + cache_writelock(mc); +- me = cache_lookup_distinct(mc, name); +- if (me) +- rv = cache_push_mapent(me, NULL); +- else +- rv = cache_update(mc, source, name, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, name); +- if (me) +- me->status = now + ap->negative_timeout; +- } ++ cache_update_negative(mc, source, name, ap->negative_timeout); + cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; + } +--- autofs-5.0.7.orig/modules/lookup_nisplus.c ++++ autofs-5.0.7/modules/lookup_nisplus.c +@@ -777,24 +777,13 @@ int lookup_mount(struct autofs_point *ap + ret = ctxt->parse->parse_mount(ap, key, key_len, + mapent, ctxt->parse->context); + if (ret) { +- time_t now = time(NULL); +- int rv = CHE_OK; +- + free(mapent); + + /* Don't update negative cache when re-connecting */ + if (ap->flags & MOUNT_FLAG_REMOUNT) + return NSS_STATUS_TRYAGAIN; + cache_writelock(mc); +- me = cache_lookup_distinct(mc, key); +- if (me) +- rv = cache_push_mapent(me, NULL); +- else +- rv = cache_update(mc, source, key, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, key); +- me->status = time(NULL) + ap->negative_timeout; +- } ++ cache_update_negative(mc, source, key, ap->negative_timeout); + cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; + } +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -622,20 +622,8 @@ out_free: + free(mapent); + + if (ret) { +- time_t now = time(NULL); +- int rv = CHE_OK; +- + cache_writelock(mc); +- me = cache_lookup_distinct(mc, name); +- if (me) +- rv = cache_push_mapent(me, NULL); +- else +- rv = cache_update(mc, source, name, NULL, now); +- if (rv != CHE_FAIL) { +- me = cache_lookup_distinct(mc, name); +- if (me) +- me->status = now + ap->negative_timeout; +- } ++ cache_update_negative(mc, source, name, ap->negative_timeout); + cache_unlock(mc); + return NSS_STATUS_TRYAGAIN; + } diff --git a/SOURCES/autofs-5.1.0-make-service-want-network-online.patch b/SOURCES/autofs-5.1.0-make-service-want-network-online.patch new file mode 100644 index 0000000..75f43d6 --- /dev/null +++ b/SOURCES/autofs-5.1.0-make-service-want-network-online.patch @@ -0,0 +1,38 @@ +autofs-5.1.0 - make service want network-online + +From: Ian Kent + +autofs often fails to start properly in Fedora with recent systemd. + +Changing the systemd unit to Want the network-online target works +around this. + +I'm not sure if this will cause problems for people that use file +maps and expect autofs to start without the network up but I hope +that's a small minority, if there are any at all. +--- + CHANGELOG | 1 + + samples/autofs.service.in | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -182,6 +182,7 @@ + - fix direct map expire not set for initail empty map. + - update map_hash_table_size description. + - fix out of order call in program map lookup. ++- make service want network-online. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/samples/autofs.service.in ++++ autofs-5.0.7/samples/autofs.service.in +@@ -1,6 +1,7 @@ + [Unit] + Description=Automounts filesystems on demand +-After=network.target ypbind.service sssd.service ++After=network.target ypbind.service sssd.service network-online.target ++Wants=network-online.target + + [Service] + Type=forking diff --git a/SOURCES/autofs-5.1.0-remove-unused-offset-handling-code.patch b/SOURCES/autofs-5.1.0-remove-unused-offset-handling-code.patch new file mode 100644 index 0000000..0af84f7 --- /dev/null +++ b/SOURCES/autofs-5.1.0-remove-unused-offset-handling-code.patch @@ -0,0 +1,157 @@ +autofs-5.1.0 - remove unused offset handling code + +From: Ian Kent + +Some offset handling functions were moved into the cache module +a while ago and are now unused. +--- + CHANGELOG | 1 + include/mounts.h | 8 ---- + lib/mounts.c | 95 ------------------------------------------------------- + 3 files changed, 1 insertion(+), 103 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -167,6 +167,7 @@ + - fix incorrect check in parse_mount(). + - handle duplicates in multi mounts. + - fix macro usage in lookup_program.c. ++- remove unused offset handling code. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/mounts.h ++++ autofs-5.0.7/include/mounts.h +@@ -68,11 +68,6 @@ struct mnt_list { + struct list_head list; + struct list_head entries; + struct list_head sublist; +- /* +- * Offset mount handling ie. add_ordered_list +- * and get_offset. +- */ +- struct list_head ordered; + }; + + +@@ -109,9 +104,6 @@ void free_mnt_list(struct mnt_list *list + int contained_in_local_fs(const char *path); + int is_mounted(const char *table, const char *path, unsigned int type); + int has_fstab_option(const char *opt); +-char *get_offset(const char *prefix, char *offset, +- struct list_head *head, struct list_head **pos); +-void add_ordered_list(struct mnt_list *ent, struct list_head *head); + void tree_free_mnt_tree(struct mnt_list *tree); + struct mnt_list *tree_make_mnt_tree(const char *table, const char *path); + int tree_get_mnt_list(struct mnt_list *mnts, struct list_head *list, const char *path, int include); +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -1090,100 +1090,6 @@ int has_fstab_option(const char *opt) + return ret; + } + +-char *get_offset(const char *prefix, char *offset, +- struct list_head *head, struct list_head **pos) +-{ +- struct list_head *next; +- struct mnt_list *this; +- size_t plen = strlen(prefix); +- size_t len = 0; +- +- *offset = '\0'; +- next = *pos ? (*pos)->next : head->next; +- while (next != head) { +- char *pstart, *pend; +- +- this = list_entry(next, struct mnt_list, ordered); +- *pos = next; +- next = next->next; +- +- if (strlen(this->path) <= plen) +- continue; +- +- if (!strncmp(prefix, this->path, plen)) { +- pstart = &this->path[plen]; +- +- /* not part of this sub-tree */ +- if (*pstart != '/') +- continue; +- +- /* get next offset */ +- pend = pstart; +- while (*pend++) ; +- len = pend - pstart - 1; +- strncpy(offset, pstart, len); +- offset[len] ='\0'; +- break; +- } +- } +- +- while (next != head) { +- char *pstart; +- +- this = list_entry(next, struct mnt_list, ordered); +- +- if (strlen(this->path) <= plen + len) +- break; +- +- pstart = &this->path[plen]; +- +- /* not part of this sub-tree */ +- if (*pstart != '/') +- break; +- +- /* new offset */ +- if (!*(pstart + len + 1)) +- break; +- +- /* compare next offset */ +- if (pstart[len] != '/' || strncmp(offset, pstart, len)) +- break; +- +- *pos = next; +- next = next->next; +- } +- +- return *offset ? offset : NULL; +-} +- +-void add_ordered_list(struct mnt_list *ent, struct list_head *head) +-{ +- struct list_head *p; +- struct mnt_list *this; +- +- list_for_each(p, head) { +- size_t tlen; +- int eq; +- +- this = list_entry(p, struct mnt_list, ordered); +- tlen = strlen(this->path); +- +- eq = strncmp(this->path, ent->path, tlen); +- if (!eq && tlen == strlen(ent->path)) +- return; +- +- if (eq > 0) { +- INIT_LIST_HEAD(&ent->ordered); +- list_add_tail(&ent->ordered, p); +- return; +- } +- } +- INIT_LIST_HEAD(&ent->ordered); +- list_add_tail(&ent->ordered, p); +- +- return; +-} +- + /* + * Since we have to look at the entire mount tree for direct + * mounts (all mounts under "/") and we may have a large number +@@ -1283,7 +1189,6 @@ struct mnt_list *tree_make_mnt_tree(cons + INIT_LIST_HEAD(&ent->list); + INIT_LIST_HEAD(&ent->entries); + INIT_LIST_HEAD(&ent->sublist); +- INIT_LIST_HEAD(&ent->ordered); + + ent->path = malloc(len + 1); + if (!ent->path) { diff --git a/SOURCES/autofs-5.1.0-update-man-page-autofs-8-for-systemd.patch b/SOURCES/autofs-5.1.0-update-man-page-autofs-8-for-systemd.patch new file mode 100644 index 0000000..52c626a --- /dev/null +++ b/SOURCES/autofs-5.1.0-update-man-page-autofs-8-for-systemd.patch @@ -0,0 +1,112 @@ +autofs-5.1.0 - update man page autofs(8) for systemd + +From: Ian Kent + +Update the autofs(8) man page to account for systems using systemd. +--- + CHANGELOG | 1 + + man/autofs.8.in | 51 +++++++++++++++++++++++++++++++++++++-------------- + 2 files changed, 38 insertions(+), 14 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -155,6 +155,7 @@ + - fix reset amd lexer scan buffer. + - ignore multiple commas in options strings. + - clarify multiple mounts description. ++- update man page autofs(8) for systemd. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/autofs.8.in ++++ autofs-5.0.7/man/autofs.8.in +@@ -1,23 +1,30 @@ + .TH AUTOFS 8 "9 Sep 1997" + .SH NAME +-@@initdir@@/autofs \- Control Script for automounter ++Service control for the automounter + .SH SYNOPSIS ++If a SysV init script system is being used: ++.br + .B @@initdir@@/autofs + .I start|stop|restart|reload|status ++.P ++or if the systemd init system is being used: ++.br ++.B systemctl ++.I start|stop|restart|reload|status ++.B autofs.service + .SH "DESCRIPTION" + .B autofs + controls the operation of the + .BR automount (8) +-daemons running on the Linux system. Usually ++daemon(s) running on the Linux system. Usually + .B autofs + is invoked at system boot time with the + .I start + parameter and at shutdown time with the + .I stop +-parameter. The +-.B autofs +-script can also be manually invoked by the system administrator to shut +-down, restart or reload the automounters. ++parameter. Service control actions can also be manually invoked by ++the system administrator to shut down, restart, reload or obtain ++service status. + .P + .SH "OPERATION" + .B autofs +@@ -31,28 +38,44 @@ will mount and start a thread, with the + manage the mount point. + .P + .B @@initdir@@/autofs reload +-will check the current auto.master map against running daemons. It will kill +-those daemons whose entries have changed and then start daemons for new or +-changed entries. ++or ++.B systemctl autofs.service reload ++will check the current auto.master map against the current automount managed ++mounts. It will terminate those daemons or threads (depending on ++.B autofs ++version) whose entries have been removed, re-read the automount maps for ++entries that have changed and start new daemons or threads for entries ++that have been added. + .P +-If a map is modified then the change will become effective immediately. If +-the ++If an indirect map is modified then the change will become effective immediately. ++If an indirect map uses the ++.B browse ++option, the master map contains direct mount maps or the + .I auto.master + map is modified then the + .B autofs +-script must be rerun to activate the changes. ++service control reload action must be rerun to activate the changes. + .P + .B @@initdir@@/autofs status ++or ++.B systemctl autofs.service status + will display the status of, + .BR automount (8) +-,running or not. ++,running or not. When using the systemd init system the status output includes ++somewhat more information related to the service status. ++.P ++.B systemctl(1) ++has more functions than the actions mentioned here, see ++.B systemctl(1) ++for more information. + .SH "SEE ALSO" + .BR automount (8), + .BR autofs (5), + .BR autofs.conf (5), + .BR auto.master (5). + .BR autofs_ldap_auth.conf (5) ++.BR systemctl(1) + .SH AUTHOR + This manual page was written by Christoph Lameter , + for the Debi GNU/Linux system. Edited by H. Peter Anvin +-. ++ and Ian Kent . diff --git a/SOURCES/autofs-5.1.1-add-config-option-to-suppress-not-found-log-message.patch b/SOURCES/autofs-5.1.1-add-config-option-to-suppress-not-found-log-message.patch new file mode 100644 index 0000000..6211649 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-config-option-to-suppress-not-found-log-message.patch @@ -0,0 +1,171 @@ +autofs-5.1.1 - add config option to suppress not found log message + +From: Ian Kent + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 11 +++++++++-- + include/defaults.h | 4 +++- + lib/defaults.c | 17 +++++++++++++++++ + man/autofs.conf.5.in | 7 +++++++ + modules/lookup_hesiod.c | 6 ++++-- + redhat/autofs.conf.default.in | 8 ++++++++ + samples/autofs.conf.default.in | 8 ++++++++ + 8 files changed, 57 insertions(+), 5 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -205,6 +205,7 @@ + - fix typo in autofs_sasl_bind(). + - add configuration option to use fqdn in mounts. + - fix use-after-free in st_queue_handler(). ++- add config option to supress not found log message. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -1036,8 +1036,15 @@ static void update_negative_cache(struct + */ + cache_unlock(me->mc); + else { +- /* Notify only once after fail */ +- logmsg("key \"%s\" not found in map source(s).", name); ++ if (!defaults_disable_not_found_message()) { ++ /* This really should be a warning but the original ++ * request for this needed it to be unconditional. ++ * That produces, IMHO, unnecessary noise in the log ++ * so a configuration option has been added to provide ++ * the ability to turn it off. ++ */ ++ logmsg("key \"%s\" not found in map source(s).", name); ++ } + + /* Doesn't exist in any source, just add it somewhere */ + if (source) +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -47,7 +47,8 @@ + + #define DEFAULT_MAP_HASH_TABLE_SIZE "1024" + +-#define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0" ++#define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0" ++#define DEFAULT_DISABLE_NOT_FOUND_MESSAGE "0" + + /* Config entry flags */ + #define CONF_NONE 0x00000000 +@@ -165,6 +166,7 @@ unsigned int defaults_get_umount_wait(vo + const char *defaults_get_auth_conf_file(void); + unsigned int defaults_get_map_hash_table_size(void); + unsigned int defaults_use_hostname_for_mounts(void); ++unsigned int defaults_disable_not_found_message(void); + + unsigned int conf_amd_mount_section_exists(const char *); + char *conf_amd_get_arch(void); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -73,6 +73,7 @@ + #define NAME_MAP_HASH_TABLE_SIZE "map_hash_table_size" + + #define NAME_USE_HOSTNAME_FOR_MOUNTS "use_hostname_for_mounts" ++#define NAME_DISABLE_NOT_FOUND_MESSAGE "disable_not_found_message" + + #define NAME_AMD_ARCH "arch" + #define NAME_AMD_AUTO_ATTRCACHE "auto_attrcache" +@@ -341,6 +342,11 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_DISABLE_NOT_FOUND_MESSAGE, ++ DEFAULT_DISABLE_NOT_FOUND_MESSAGE, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ + /* LDAP_URI and SEARCH_BASE can occur multiple times */ + while ((co = conf_lookup(sec, NAME_LDAP_URI))) + conf_delete(co->section, co->name); +@@ -1717,6 +1723,17 @@ unsigned int defaults_use_hostname_for_m + + return res; + } ++ ++unsigned int defaults_disable_not_found_message(void) ++{ ++ int res; ++ ++ res = conf_get_yesno(autofs_gbl_sec, NAME_DISABLE_NOT_FOUND_MESSAGE); ++ if (res < 0) ++ res = atoi(DEFAULT_DISABLE_NOT_FOUND_MESSAGE); ++ ++ return res; ++} + + unsigned int conf_amd_mount_section_exists(const char *section) + { +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -129,6 +129,13 @@ name resolving to one that isn't respond + of attempts at a successful mount will correspond to the number of + addresses the host name resolves to the order will also not correspond + to fastest responding hosts. ++.TP ++.B disable_not_found_message ++.br ++The original request to add this log message needed it to be unconditional. ++That produces, IMHO, unnecessary noise in the log so a configuration option ++has been added to provide the ability to turn it off. The default is "no" ++to maintain the current behaviour. + .SS LDAP Configuration + .P + Configuration settings available are: +--- autofs-5.0.7.orig/modules/lookup_hesiod.c ++++ autofs-5.0.7/modules/lookup_hesiod.c +@@ -194,8 +194,10 @@ static int lookup_one(struct autofs_poin + hes_result = hesiod_resolve(ctxt->hesiod_context, key, "filsys"); + if (!hes_result || !hes_result[0]) { + int err = errno; +- error(ap->logopt, +- MODPREFIX "key \"%s\" not found in map", key); ++ if (!defaults_disable_not_found_message()) { ++ error(ap->logopt, ++ MODPREFIX "key \"%s\" not found in map", key); ++ } + status = pthread_mutex_unlock(&hesiod_mutex); + if (status) + fatal(status); +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -151,6 +151,14 @@ mount_nfs_default_protocol = 4 + # + #use_hostname_for_mounts = "no" + # ++# disable_not_found_message - The original request to add this log message ++# needed it to be unconditional. That produces, IMHO, ++# unnecessary noise in the log so a configuration option ++# has been added to provide the ability to turn it off. ++# The default is "no" to maintain the current behaviour. ++# ++#disable_not_found_message = "no" ++# + # Otions for the amd parser within autofs. + # + # amd configuration options that are aren't used, haven't been +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -150,6 +150,14 @@ browse_mode = no + # + #use_hostname_for_mounts = "no" + # ++# disable_not_found_message - The original request to add this log message ++# needed it to be unconditional. That produces, IMHO, ++# unnecessary noise in the log so a configuration option ++# has been added to provide the ability to turn it off. ++# The default is "no" to maintain the current behaviour. ++# ++#disable_not_found_message = "no" ++# + # Otions for the amd parser within autofs. + # + # amd configuration options that are aren't used, haven't been diff --git a/SOURCES/autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch b/SOURCES/autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch new file mode 100644 index 0000000..3f15df7 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch @@ -0,0 +1,182 @@ +autofs-5.1.1 - add configuration option to use fqdn in mounts + +From: Ian Kent + +When a server name returns multiple IP addresses autofs uses the IP +address when performing the mount to ensure that the the host proximity +order is respected, and that servers that aren't responding aren't +tried. + +But sometimes people need to use the server name for the mount so +add a configuration option to enable that. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/defaults.h | 3 +++ + lib/defaults.c | 18 ++++++++++++++++++ + man/autofs.conf.5.in | 18 ++++++++++++++++++ + modules/mount_nfs.c | 3 ++- + modules/replicated.c | 6 ++++++ + redhat/autofs.conf.default.in | 8 ++++++++ + samples/autofs.conf.default.in | 8 ++++++++ + 8 files changed, 64 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -203,6 +203,7 @@ + - fix use after free in sun parser parse_init(). + - fix use after free in open_lookup(). + - fix typo in autofs_sasl_bind(). ++- add configuration option to use fqdn in mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -47,6 +47,8 @@ + + #define DEFAULT_MAP_HASH_TABLE_SIZE "1024" + ++#define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0" ++ + /* Config entry flags */ + #define CONF_NONE 0x00000000 + #define CONF_ENV 0x00000001 +@@ -162,6 +164,7 @@ unsigned int defaults_get_mount_wait(voi + unsigned int defaults_get_umount_wait(void); + const char *defaults_get_auth_conf_file(void); + unsigned int defaults_get_map_hash_table_size(void); ++unsigned int defaults_use_hostname_for_mounts(void); + + unsigned int conf_amd_mount_section_exists(const char *); + char *conf_amd_get_arch(void); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -72,6 +72,8 @@ + + #define NAME_MAP_HASH_TABLE_SIZE "map_hash_table_size" + ++#define NAME_USE_HOSTNAME_FOR_MOUNTS "use_hostname_for_mounts" ++ + #define NAME_AMD_ARCH "arch" + #define NAME_AMD_AUTO_ATTRCACHE "auto_attrcache" + #define NAME_AMD_AUTO_DIR "auto_dir" +@@ -334,6 +336,11 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_USE_HOSTNAME_FOR_MOUNTS, ++ DEFAULT_USE_HOSTNAME_FOR_MOUNTS, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ + /* LDAP_URI and SEARCH_BASE can occur multiple times */ + while ((co = conf_lookup(sec, NAME_LDAP_URI))) + conf_delete(co->section, co->name); +@@ -1700,6 +1707,17 @@ unsigned int defaults_get_map_hash_table + return (unsigned int) size; + } + ++unsigned int defaults_use_hostname_for_mounts(void) ++{ ++ int res; ++ ++ res = conf_get_yesno(autofs_gbl_sec, NAME_USE_HOSTNAME_FOR_MOUNTS); ++ if (res < 0) ++ res = atoi(DEFAULT_USE_HOSTNAME_FOR_MOUNTS); ++ ++ return res; ++} ++ + unsigned int conf_amd_mount_section_exists(const char *section) + { + return conf_section_exists(section); +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -111,6 +111,24 @@ entries, in this case, is usually much l + in the map. In this last case it would be unusual for the map entry + cache to grow large enough to warrant increasing the default before + an event that cleans stale entries, a map re-read for example. ++.TP ++.B use_hostname_for_mounts ++.br ++NFS mounts where the host name resolves to more than one IP address ++are probed for availability and to establish the order in which mounts ++to them should be tried. To ensure that mount attempts are made only ++to hosts that are responding and are tried in the order of hosts with ++the quickest response the IP address of the host needs to be used for ++the mount. ++ ++If it is necessary to use the hostname given in the map entry for the ++mount regardless, then set this option to "yes". ++ ++Be aware that if this is done there is no defense against the host ++name resolving to one that isn't responding and while the number ++of attempts at a successful mount will correspond to the number of ++addresses the host name resolves to the order will also not correspond ++to fastest responding hosts. + .SS LDAP Configuration + .P + Configuration settings available are: +--- autofs-5.0.7.orig/modules/mount_nfs.c ++++ autofs-5.0.7/modules/mount_nfs.c +@@ -316,7 +316,8 @@ dont_probe: + + /* Not a local host - do an NFS mount */ + +- if (this->rr && this->addr) { ++ if (this->rr && this->addr && ++ !defaults_use_hostname_for_mounts()) { + socklen_t len = INET6_ADDRSTRLEN; + char n_buf[len + 1]; + const char *n_addr; +--- autofs-5.0.7.orig/modules/replicated.c ++++ autofs-5.0.7/modules/replicated.c +@@ -667,6 +667,12 @@ int prune_host_list(unsigned logopt, str + if (!*list) + return 0; + ++ /* If we're using the host name then there's no point probing ++ * avialability and respose time. ++ */ ++ if (defaults_use_hostname_for_mounts()) ++ return 1; ++ + /* Use closest hosts to choose NFS version */ + + first = *list; +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -142,6 +142,14 @@ mount_nfs_default_protocol = 4 + # + #map_hash_table_size = 1024 + # ++# use_hostname_for_mounts - nfs mounts where the host name resolves ++# to more than one IP address normally need ++# to use the IP address to esure a mount to ++# a host that isn't responding isn't done. ++# If that behaviour is not wanted then set ++# ths to "yes", default is "no". ++# ++#use_hostname_for_mounts = "no" + # + # Otions for the amd parser within autofs. + # +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -141,6 +141,14 @@ browse_mode = no + # + #map_hash_table_size = 1024 + # ++# use_hostname_for_mounts - nfs mounts where the host name resolves ++# to more than one IP address normally need ++# to use the IP address to esure a mount to ++# a host that isn't responding isn't done. ++# If that behaviour is not wanted then set ++# ths to "yes", default is "no". ++# ++#use_hostname_for_mounts = "no" + # + # Otions for the amd parser within autofs. + # diff --git a/SOURCES/autofs-5.1.1-add-reinit-entry-point-to-modules.patch b/SOURCES/autofs-5.1.1-add-reinit-entry-point-to-modules.patch new file mode 100644 index 0000000..0c801a9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-reinit-entry-point-to-modules.patch @@ -0,0 +1,666 @@ +autofs-5.1.1 - add reinit entry point to modules + +From: Ian Kent + +In order to avoid closing and then re-opening lookup modules +on HUP signal (since there init entry point needs to be called +for initialization) add a reinit entry point to lookup, parse +and mount modules. + +Signed-off-by: Ian Kent +--- + daemon/module.c | 39 +++++++++++++++++++++++++++++++++++++++ + include/automount.h | 15 +++++++++++++++ + modules/lookup_dir.c | 9 ++++++++- + modules/lookup_file.c | 9 ++++++++- + modules/lookup_hesiod.c | 9 ++++++++- + modules/lookup_hosts.c | 9 ++++++++- + modules/lookup_ldap.c | 9 ++++++++- + modules/lookup_multi.c | 9 ++++++++- + modules/lookup_nisplus.c | 9 ++++++++- + modules/lookup_program.c | 9 ++++++++- + modules/lookup_sss.c | 9 ++++++++- + modules/lookup_userhome.c | 9 ++++++++- + modules/lookup_yp.c | 9 ++++++++- + modules/mount_afs.c | 5 +++++ + modules/mount_autofs.c | 5 +++++ + modules/mount_bind.c | 5 +++++ + modules/mount_changer.c | 5 +++++ + modules/mount_ext2.c | 5 +++++ + modules/mount_generic.c | 5 +++++ + modules/mount_nfs.c | 5 +++++ + modules/parse_amd.c | 5 +++++ + modules/parse_hesiod.c | 5 +++++ + modules/parse_sun.c | 5 +++++ + 23 files changed, 192 insertions(+), 11 deletions(-) + +diff --git a/daemon/module.c b/daemon/module.c +index 9028aaa..3bd7a0c 100644 +--- a/daemon/module.c ++++ b/daemon/module.c +@@ -105,6 +105,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + } + + if (!(mod->lookup_init = (lookup_init_t) dlsym(dh, "lookup_init")) || ++ !(mod->lookup_reinit = (lookup_reinit_t) dlsym(dh, "lookup_reinit")) || + !(mod->lookup_read_master = (lookup_read_master_t) dlsym(dh, "lookup_read_master")) || + !(mod->lookup_read_map = (lookup_read_map_t) dlsym(dh, "lookup_read_map")) || + !(mod->lookup_mount = (lookup_mount_t) dlsym(dh, "lookup_mount")) || +@@ -127,6 +128,19 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + return NSS_STATUS_SUCCESS; + } + ++int reinit_lookup(struct lookup_mod *mod, const char *name, ++ const char *err_prefix, const char *mapfmt, ++ int argc, const char *const *argv) ++{ ++ if (mod->lookup_reinit(mapfmt, argc, argv, &mod->context)) { ++ if (err_prefix) ++ logerr("%scould not reinit lookup module %s", ++ err_prefix, name); ++ return 1; ++ } ++ return 0; ++} ++ + int close_lookup(struct lookup_mod *mod) + { + int rv = mod->lookup_done(mod->context); +@@ -185,6 +199,7 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix, + } + + if (!(mod->parse_init = (parse_init_t) dlsym(dh, "parse_init")) || ++ !(mod->parse_reinit = (parse_reinit_t) dlsym(dh, "parse_reinit")) || + !(mod->parse_mount = (parse_mount_t) dlsym(dh, "parse_mount")) || + !(mod->parse_done = (parse_done_t) dlsym(dh, "parse_done"))) { + if (err_prefix) +@@ -204,6 +219,18 @@ struct parse_mod *open_parse(const char *name, const char *err_prefix, + return mod; + } + ++int reinit_parse(struct parse_mod *mod, const char *name, ++ const char *err_prefix, int argc, const char *const *argv) ++{ ++ if (mod->parse_reinit(argc, argv, &mod->context)) { ++ if (err_prefix) ++ logerr("%scould not reinit parse module %s", ++ err_prefix, name); ++ return 1; ++ } ++ return 0; ++} ++ + int close_parse(struct parse_mod *mod) + { + int rv = mod->parse_done(mod->context); +@@ -261,6 +288,7 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix) + } + + if (!(mod->mount_init = (mount_init_t) dlsym(dh, "mount_init")) || ++ !(mod->mount_reinit = (mount_reinit_t) dlsym(dh, "mount_reinit")) || + !(mod->mount_mount = (mount_mount_t) dlsym(dh, "mount_mount")) || + !(mod->mount_done = (mount_done_t) dlsym(dh, "mount_done"))) { + if (err_prefix) +@@ -280,6 +308,17 @@ struct mount_mod *open_mount(const char *name, const char *err_prefix) + return mod; + } + ++int reinit_mount(struct mount_mod *mod, const char *name, const char *err_prefix) ++{ ++ if (mod->mount_reinit(&mod->context)) { ++ if (err_prefix) ++ logerr("%scould not reinit mount module %s", ++ err_prefix, name); ++ return 1; ++ } ++ return 0; ++} ++ + int close_mount(struct mount_mod *mod) + { + int rv = mod->mount_done(mod->context); +diff --git a/include/automount.h b/include/automount.h +index d614c10..ab3e360 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -281,12 +281,14 @@ int lookup_source_close_ioctlfd(struct autofs_point *ap, const char *key); + + #ifdef MODULE_LOOKUP + int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context); ++int lookup_reinit(const char *mapfmt, int argc, const char *const *argv, void **context); + int lookup_read_master(struct master *master, time_t age, void *context); + int lookup_read_map(struct autofs_point *, time_t, void *context); + int lookup_mount(struct autofs_point *, const char *, int, void *); + int lookup_done(void *); + #endif + typedef int (*lookup_init_t) (const char *, int, const char *const *, void **); ++typedef int (*lookup_reinit_t) (const char *, int, const char *const *, void **); + typedef int (*lookup_read_master_t) (struct master *master, time_t, void *); + typedef int (*lookup_read_map_t) (struct autofs_point *, time_t, void *); + typedef int (*lookup_mount_t) (struct autofs_point *, const char *, int, void *); +@@ -294,6 +296,7 @@ typedef int (*lookup_done_t) (void *); + + struct lookup_mod { + lookup_init_t lookup_init; ++ lookup_reinit_t lookup_reinit; + lookup_read_master_t lookup_read_master; + lookup_read_map_t lookup_read_map; + lookup_mount_t lookup_mount; +@@ -304,6 +307,9 @@ struct lookup_mod { + + int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + int argc, const char *const *argv, struct lookup_mod **lookup); ++int reinit_lookup(struct lookup_mod *mod, const char *name, ++ const char *err_prefix, const char *mapfmt, ++ int argc, const char *const *argv); + int close_lookup(struct lookup_mod *); + + /* parse module */ +@@ -312,16 +318,19 @@ int close_lookup(struct lookup_mod *); + + #ifdef MODULE_PARSE + int parse_init(int argc, const char *const *argv, void **context); ++int parse_reinit(int argc, const char *const *argv, void **context); + int parse_mount(struct autofs_point *ap, const char *name, + int name_len, const char *mapent, void *context); + int parse_done(void *); + #endif + typedef int (*parse_init_t) (int, const char *const *, void **); ++typedef int (*parse_reinit_t) (int, const char *const *, void **); + typedef int (*parse_mount_t) (struct autofs_point *, const char *, int, const char *, void *); + typedef int (*parse_done_t) (void *); + + struct parse_mod { + parse_init_t parse_init; ++ parse_reinit_t parse_reinit; + parse_mount_t parse_mount; + parse_done_t parse_done; + void *dlhandle; +@@ -330,6 +339,8 @@ struct parse_mod { + + struct parse_mod *open_parse(const char *name, const char *err_prefix, + int argc, const char *const *argv); ++int reinit_parse(struct parse_mod *, const char *name, ++ const char *err_prefix, int argc, const char *const *argv); + int close_parse(struct parse_mod *); + + /* mount module */ +@@ -338,17 +349,20 @@ int close_parse(struct parse_mod *); + + #ifdef MODULE_MOUNT + int mount_init(void **context); ++int mount_reinit(void **context); + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context); + int mount_done(void *context); + #endif + typedef int (*mount_init_t) (void **); ++typedef int (*mount_reinit_t) (void **); + typedef int (*mount_mount_t) (struct autofs_point *, const char *, const char *, int, + const char *, const char *, const char *, void *); + typedef int (*mount_done_t) (void *); + + struct mount_mod { + mount_init_t mount_init; ++ mount_reinit_t mount_reinit; + mount_mount_t mount_mount; + mount_done_t mount_done; + void *dlhandle; +@@ -356,6 +370,7 @@ struct mount_mod { + }; + + struct mount_mod *open_mount(const char *name, const char *err_prefix); ++int reinit_mount(struct mount_mod *mod, const char *name, const char *err_prefix); + int close_mount(struct mount_mod *); + + /* buffer management */ +diff --git a/modules/lookup_dir.c b/modules/lookup_dir.c +index cbeda1f..7a95e24 100644 +--- a/modules/lookup_dir.c ++++ b/modules/lookup_dir.c +@@ -51,7 +51,8 @@ struct lookup_context { + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -105,6 +106,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static int acceptable_dirent_p(const struct dirent *e) + { + size_t namesz; +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index 7c982c6..c32a4cd 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -50,7 +50,8 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -112,6 +113,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static int read_one(unsigned logopt, FILE *f, char *key, unsigned int *k_len, char *mapent, unsigned int *m_len) + { + char *kptr, *p; +diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c +index 526f294..de5ec08 100644 +--- a/modules/lookup_hesiod.c ++++ b/modules/lookup_hesiod.c +@@ -39,7 +39,8 @@ int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + + /* This initializes a context (persistent non-global data) for queries to + this module. */ +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt = NULL; + char buf[MAX_ERR_BUF]; +@@ -96,6 +97,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + return NSS_STATUS_UNKNOWN; +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 53aa9d6..8ba0a4a 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -46,7 +46,8 @@ int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + exports rpc_get_exports(const char *host, long seconds, long micros, unsigned int option); + void rpc_exports_free(exports list); + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -73,6 +74,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + return NSS_STATUS_UNKNOWN; +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index d846d8e..0f5bc48 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -1687,7 +1687,8 @@ static void validate_uris(struct list_head *list) + * This initializes a context (persistent non-global data) for queries to + * this module. Return zero if we succeed. + */ +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + unsigned int is_amd_format; + struct lookup_context *ctxt; +@@ -1835,6 +1836,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index ba8d4f0..0ee20f5 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -150,7 +150,8 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + return NULL; + } + +-int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *my_mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -244,6 +245,12 @@ error_out: + return 1; + } + ++int lookup_reinit(const char *my_mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + return NSS_STATUS_UNKNOWN; +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index d5eba47..0c66152 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -30,7 +30,8 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -76,6 +77,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index a3a7e98..fa4f54d 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -49,7 +49,8 @@ struct parse_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -100,6 +101,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int lookup_read_master(struct master *master, time_t age, void *context) + { + return NSS_STATUS_UNKNOWN; +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index 720b5e3..c58a272 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -56,7 +56,8 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -137,6 +138,12 @@ lib_names_fail: + return 1; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static int setautomntent(unsigned int logopt, + struct lookup_context *ctxt, const char *mapname, + void **sss_ctxt) +diff --git a/modules/lookup_userhome.c b/modules/lookup_userhome.c +index fb3caaa..c21dee9 100644 +--- a/modules/lookup_userhome.c ++++ b/modules/lookup_userhome.c +@@ -29,7 +29,14 @@ + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; /* Nothing to do */ ++} ++ ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + return 0; /* Nothing to do */ + } +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index fcf470a..1e5a7ed 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -103,7 +103,8 @@ static unsigned int get_map_order(const char *domain, const char *map) + return (unsigned int) last_changed; + } + +-int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **context) ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; +@@ -165,6 +166,12 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co + return 0; + } + ++int lookup_reinit(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int yp_all_master_callback(int status, char *ypkey, int ypkeylen, + char *val, int vallen, char *ypcb_data) + { +diff --git a/modules/mount_afs.c b/modules/mount_afs.c +index 50628ce..2a776bd 100644 +--- a/modules/mount_afs.c ++++ b/modules/mount_afs.c +@@ -25,6 +25,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c +index 4846e7f..39948e6 100644 +--- a/modules/mount_autofs.c ++++ b/modules/mount_autofs.c +@@ -39,6 +39,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, + int name_len, const char *what, const char *fstype, + const char *c_options, void *context) +diff --git a/modules/mount_bind.c b/modules/mount_bind.c +index ac954e3..4864ea5 100644 +--- a/modules/mount_bind.c ++++ b/modules/mount_bind.c +@@ -67,6 +67,11 @@ out: + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +diff --git a/modules/mount_changer.c b/modules/mount_changer.c +index 5e2b47c..798f23b 100644 +--- a/modules/mount_changer.c ++++ b/modules/mount_changer.c +@@ -41,6 +41,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c +index 3c87512..c00e3d5 100644 +--- a/modules/mount_ext2.c ++++ b/modules/mount_ext2.c +@@ -33,6 +33,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, void *context) + { +diff --git a/modules/mount_generic.c b/modules/mount_generic.c +index c4108e6..ae63787 100644 +--- a/modules/mount_generic.c ++++ b/modules/mount_generic.c +@@ -33,6 +33,11 @@ int mount_init(void **context) + return 0; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, + void *context) +diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c +index 315fc99..15e1043 100644 +--- a/modules/mount_nfs.c ++++ b/modules/mount_nfs.c +@@ -54,6 +54,11 @@ int mount_init(void **context) + return !mount_bind; + } + ++int mount_reinit(void **context) ++{ ++ return 0; ++} ++ + int mount_mount(struct autofs_point *ap, const char *root, const char *name, int name_len, + const char *what, const char *fstype, const char *options, + void *context) +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 2e3d21f..0626bf4 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -130,6 +130,11 @@ int parse_init(int argc, const char *const *argv, void **context) + return 0; + } + ++int parse_reinit(int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static struct substvar *add_lookup_vars(struct autofs_point *ap, + const char *key, int key_len, + struct map_source *source, +diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c +index 237fd50..0b2b57f 100644 +--- a/modules/parse_hesiod.c ++++ b/modules/parse_hesiod.c +@@ -261,6 +261,11 @@ int parse_init(int argc, const char *const *argv, void **context) + return 0; + } + ++int parse_reinit(int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + int parse_done(void *context) + { + return 0; +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 10dbd0c..35d6da5 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -413,6 +413,11 @@ options_done: + return 0; + } + ++int parse_reinit(int argc, const char *const *argv, void **context) ++{ ++ return 0; ++} ++ + static const char *parse_options(const char *str, char **ret, unsigned int logopt) + { + const char *cp = str; diff --git a/SOURCES/autofs-5.1.1-add-remote-fs-target-systemd-dependency.patch b/SOURCES/autofs-5.1.1-add-remote-fs-target-systemd-dependency.patch new file mode 100644 index 0000000..cb71d92 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-remote-fs-target-systemd-dependency.patch @@ -0,0 +1,35 @@ +autofs-5.1.1 - add remote-fs.target systemd dependency + +From: Ian Kent + +If maps are stored on a NFS mount autofs will fail to start if the +systemd unit doesn't depend on the remote-fs target. + +I'm not sure how this will affect systems that don't have anything +to depend on in the remote-fs target but I expect it will not stop +the startup from functioning. +--- + CHANGELOG | 1 + + samples/autofs.service.in | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -183,6 +183,7 @@ + - update map_hash_table_size description. + - fix out of order call in program map lookup. + - make service want network-online. ++- add remote-fs.target systemd dependency. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/samples/autofs.service.in ++++ autofs-5.0.7/samples/autofs.service.in +@@ -1,6 +1,6 @@ + [Unit] + Description=Automounts filesystems on demand +-After=network.target ypbind.service sssd.service network-online.target ++After=network.target ypbind.service sssd.service network-online.target remote-fs.target + Wants=network-online.target + + [Service] diff --git a/SOURCES/autofs-5.1.1-add-type-to-struct-lookup_mod.patch b/SOURCES/autofs-5.1.1-add-type-to-struct-lookup_mod.patch new file mode 100644 index 0000000..3b148e0 --- /dev/null +++ b/SOURCES/autofs-5.1.1-add-type-to-struct-lookup_mod.patch @@ -0,0 +1,101 @@ +autofs-5.1.1 - add type to struct lookup_mod + +From: Ian Kent + +Add opened map type field to struct lookup_mod for module comparison +during reinit. + +Signed-off-by: Ian Kent +--- + daemon/module.c | 18 ++++++++++++++++++ + include/automount.h | 1 + + 2 files changed, 19 insertions(+) + +diff --git a/daemon/module.c b/daemon/module.c +index 3bd7a0c..d9921f4 100644 +--- a/daemon/module.c ++++ b/daemon/module.c +@@ -61,6 +61,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + char buf[MAX_ERR_BUF]; + char fnbuf[PATH_MAX]; + size_t size; ++ char *type; + void *dh; + int *ver; + +@@ -75,10 +76,20 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + return NSS_STATUS_UNAVAIL; + } + ++ type = strdup(name); ++ if (!type) { ++ free(mod); ++ if (err_prefix) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr("%s%s", err_prefix, estr); ++ } ++ } ++ + size = snprintf(fnbuf, sizeof(fnbuf), + "%s/lookup_%s.so", AUTOFS_LIB_DIR, name); + if (size >= sizeof(fnbuf)) { + free(mod); ++ free(type); + if (err_prefix) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("%s%s", err_prefix, estr); +@@ -91,6 +102,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + logerr("%scannot open lookup module %s (%s)", + err_prefix, name, dlerror()); + free(mod); ++ free(type); + return NSS_STATUS_UNAVAIL; + } + +@@ -101,6 +113,7 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + err_prefix, name); + dlclose(dh); + free(mod); ++ free(type); + return NSS_STATUS_UNAVAIL; + } + +@@ -114,14 +127,18 @@ int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, + logerr("%slookup module %s corrupt", err_prefix, name); + dlclose(dh); + free(mod); ++ free(type); + return NSS_STATUS_UNAVAIL; + } + + if (mod->lookup_init(mapfmt, argc, argv, &mod->context)) { + dlclose(dh); + free(mod); ++ free(type); + return NSS_STATUS_NOTFOUND; + } ++ ++ mod->type = type; + mod->dlhandle = dh; + *lookup = mod; + +@@ -145,6 +162,7 @@ int close_lookup(struct lookup_mod *mod) + { + int rv = mod->lookup_done(mod->context); + dlclose(mod->dlhandle); ++ free(mod->type); + free(mod); + return rv; + } +diff --git a/include/automount.h b/include/automount.h +index ab3e360..3ea2381 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -301,6 +301,7 @@ struct lookup_mod { + lookup_read_map_t lookup_read_map; + lookup_mount_t lookup_mount; + lookup_done_t lookup_done; ++ char *type; + void *dlhandle; + void *context; + }; diff --git a/SOURCES/autofs-5.1.1-always-set-direct-mounts-catatonic-at-exit.patch b/SOURCES/autofs-5.1.1-always-set-direct-mounts-catatonic-at-exit.patch new file mode 100644 index 0000000..fa70990 --- /dev/null +++ b/SOURCES/autofs-5.1.1-always-set-direct-mounts-catatonic-at-exit.patch @@ -0,0 +1,187 @@ +autofs-5.1.1 - always set direct mounts catatonic at exit + +From: Ian Kent + +Direct mounts are all mounted at application start or when the map +is re-read and entries have been added. + +They are only ever umounted at application exit or when the map is +re-read and entries have been removed. + +If these mounts are in use (so that they are not umounted) and aren't +set catatonic at exit and an application attempts to access the path +it will lead to a hang as there is no daemon to answer the mount +request. + +It's questionable whether to set busy direct mounts catatonic when +attempting to umount them when re-reading the map as the mount may +then expire leaving an unresponsive direct mount trigger that hasn't +yet been cleaned from the map entry cache. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/direct.c | 99 +++++++++++++++++++++++++++++++++++++++++++++++++++----- + 2 files changed, 92 insertions(+), 8 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -186,6 +186,7 @@ + - add remote-fs.target systemd dependency. + - gaurd against incorrect umount return. + - fix typo in autofs.conf. ++- always set direct mounts catatonic at exit. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -82,6 +82,65 @@ static void mnts_cleanup(void *arg) + return; + } + ++/* When exiting direct mount triggers must be set catatonic, regardless ++ * of whether they are busy on not, to avoid a hang on access once the ++ * daemon has gone away. ++ */ ++static int set_direct_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd) ++{ ++ struct ioctl_ops *ops = get_ioctl_ops(); ++ unsigned int opened = 0; ++ char buf[MAX_ERR_BUF]; ++ int fd = -1; ++ int error; ++ ++ /* In case the miscellaneous device isn't being used try ++ * and use an existing ioctl control fd. In this case if ++ * we don't already have an ioctl fd the mount can't be ++ * set catatonic if it's covered. ++ */ ++ if (ioctlfd >= 0) ++ fd = ioctlfd; ++ else if (me->ioctlfd >= 0) ++ fd = me->ioctlfd; ++ else { ++ error = ops->open(ap->logopt, &fd, me->dev, me->key); ++ if (error == -1) { ++ int err = errno; ++ char *estr; ++ ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "failed to open ioctlfd for %s, error: %s", ++ me->key, estr); ++ return err; ++ } ++ opened = 1; ++ } ++ ++ if (fd >= 0) { ++ error = ops->catatonic(ap->logopt, fd); ++ if (error == -1) { ++ int err = errno; ++ char *estr; ++ ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "failed to set %s catatonic, error: %s", ++ me->key, estr); ++ if (opened) ++ ops->close(ap->logopt, fd); ++ return err; ++ } ++ if (opened) ++ ops->close(ap->logopt, fd); ++ } ++ ++ debug(ap->logopt, "set %s catatonic", me->key); ++ ++ return 0; ++} ++ + int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me) + { + struct ioctl_ops *ops = get_ioctl_ops(); +@@ -97,7 +156,8 @@ int do_umount_autofs_direct(struct autof + } + + if (me->ioctlfd != -1) { +- if (tree_is_mounted(mnts, me->key, MNTS_REAL)) { ++ if (ap->state == ST_READMAP && ++ tree_is_mounted(mnts, me->key, MNTS_REAL)) { + error(ap->logopt, + "attempt to umount busy direct mount %s", + me->key); +@@ -116,7 +176,12 @@ int do_umount_autofs_direct(struct autof + if (rv) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, "ioctl failed: %s", estr); +- if (opened && ioctlfd != -1) ++ /* The ioctl failed so this probably won't ++ * work either but since we opened it here ++ * try anyway. We should set these catatonic ++ * too but .... ++ */ ++ if (opened) + ops->close(ap->logopt, ioctlfd); + return 1; + } else if (!status) { +@@ -124,18 +189,20 @@ int do_umount_autofs_direct(struct autof + error(ap->logopt, + "ask umount returned busy for %s", + me->key); +- if (opened && ioctlfd != -1) ++ if (ap->state != ST_READMAP) ++ set_direct_mount_catatonic(ap, me, ioctlfd); ++ if (opened) + ops->close(ap->logopt, ioctlfd); + return 1; + } else { + me->ioctlfd = -1; +- ops->catatonic(ap->logopt, ioctlfd); ++ set_direct_mount_catatonic(ap, me, ioctlfd); + ops->close(ap->logopt, ioctlfd); + goto force_umount; + } + } + me->ioctlfd = -1; +- ops->catatonic(ap->logopt, ioctlfd); ++ set_direct_mount_catatonic(ap, me, ioctlfd); + ops->close(ap->logopt, ioctlfd); + } else { + error(ap->logopt, +@@ -212,15 +279,31 @@ int umount_autofs_direct(struct autofs_p + cache_readlock(mc); + me = cache_enumerate(mc, NULL); + while (me) { ++ int error; ++ + ne = cache_lookup_distinct(nc, me->key); + if (ne && map->master_line > ne->age) { + me = cache_enumerate(mc, me); + continue; + } + +- /* TODO: check return, locking me */ +- do_umount_autofs_direct(ap, mnts, me); +- ++ /* The daemon is exiting so ... ++ * If we get a fail here we must make our ++ * best effort to set the direct mount trigger ++ * catatonic regardless of the reason for the ++ * failed umount. ++ */ ++ error = do_umount_autofs_direct(ap, mnts, me); ++ if (!error) ++ goto done; ++ ++ error = set_direct_mount_catatonic(ap, me, me->ioctlfd); ++ if (!error) ++ goto done; ++ ++ /* We really need to set this, last ditch attempt */ ++ set_direct_mount_catatonic(ap, me, -1); ++done: + me = cache_enumerate(mc, me); + } + pthread_cleanup_pop(1); diff --git a/SOURCES/autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch b/SOURCES/autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch new file mode 100644 index 0000000..0879443 --- /dev/null +++ b/SOURCES/autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch @@ -0,0 +1,73 @@ +autofs-5.1.1 - change lookup to use reinit instead of reopen + +From: Ian Kent + +When a HUP signal is received lookup module are cloed and then re-opened. +This can occassionally cause a problem with library data segemets and +lead to a SEGV. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 32 +++++++++++++++++++++----------- + 2 files changed, 22 insertions(+), 11 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -195,6 +195,7 @@ + - fix gcc5 complaints. + - fix missing source sss in multi map lookup. + - fix update_hosts_mounts() return. ++- change lookup to use reinit instead of reopen. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -300,17 +300,27 @@ static int do_read_map(struct autofs_poi + struct lookup_mod *lookup; + int status; + +- status = open_lookup(map->type, "", map->format, +- map->argc, map->argv, &lookup); +- if (status != NSS_STATUS_SUCCESS) { +- debug(ap->logopt, "lookup module %s failed", map->type); +- return status; +- } +- ++ lookup = NULL; + master_source_writelock(ap->entry); +- if (map->lookup) +- close_lookup(map->lookup); +- map->lookup = lookup; ++ if (!map->lookup) { ++ status = open_lookup(map->type, "", map->format, ++ map->argc, map->argv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) { ++ master_source_unlock(ap->entry); ++ debug(ap->logopt, ++ "lookup module %s open failed", map->type); ++ return status; ++ } ++ map->lookup = lookup; ++ } else { ++ lookup = map->lookup; ++ status = lookup->lookup_reinit(map->format, ++ map->argc, map->argv, ++ &lookup->context); ++ if (status) ++ warn(ap->logopt, ++ "lookup module %s reinit failed", map->type); ++ } + master_source_unlock(ap->entry); + + if (!map->stale) +@@ -742,7 +752,7 @@ int do_lookup_mount(struct autofs_point + map->format, map->argc, map->argv, &lookup); + if (status != NSS_STATUS_SUCCESS) { + debug(ap->logopt, +- "lookup module %s failed", map->type); ++ "lookup module %s open failed", map->type); + return status; + } + map->lookup = lookup; diff --git a/SOURCES/autofs-5.1.1-factor-out-alloc-multi-map-context.patch b/SOURCES/autofs-5.1.1-factor-out-alloc-multi-map-context.patch new file mode 100644 index 0000000..f42e418 --- /dev/null +++ b/SOURCES/autofs-5.1.1-factor-out-alloc-multi-map-context.patch @@ -0,0 +1,203 @@ +autofs-5.1.1 - factor out alloc multi map context + +From: Ian Kent + +Seperate out the context allocation function for the multi map module. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 161 +++++++++++++++++++++++++----------------------- + 1 file changed, 85 insertions(+), 76 deletions(-) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 36ace11..433b424 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -40,6 +40,84 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + ++static int free_multi_context(struct lookup_context *); ++ ++static struct lookup_context *alloc_context(const char *format, ++ int argc, const char *const *argv) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ char **args; ++ int i, an; ++ char *estr; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) ++ goto nomem; ++ ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (argc < 1) { ++ logerr(MODPREFIX "No map list"); ++ goto error_out; ++ } ++ ++ ctxt->n = 1; /* Always at least one map */ ++ for (i = 0; i < argc; i++) { ++ if (!strcmp(argv[i], "--")) /* -- separates maps */ ++ ctxt->n++; ++ } ++ ++ if (!(ctxt->m = malloc(ctxt->n * sizeof(struct module_info))) || ++ !(ctxt->argl = malloc((argc + 1) * sizeof(const char *)))) ++ goto nomem; ++ ++ memset(ctxt->m, 0, ctxt->n * sizeof(struct module_info)); ++ ++ memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *)); ++ ++ args = NULL; ++ for (i = an = 0; ctxt->argl[an]; an++) { ++ if (ctxt->m[i].argc == 0) ++ args = (char **) &ctxt->argl[an]; ++ ++ if (strcmp(ctxt->argl[an], "--")) ++ ctxt->m[i].argc++; ++ else { ++ ctxt->argl[an] = NULL; ++ if (!args) { ++ logerr(MODPREFIX "error assigning map args"); ++ goto error_out; ++ } ++ ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, ++ (const char **) args); ++ if (!ctxt->m[i].argv) ++ goto nomem; ++ args = NULL; ++ i++; ++ } ++ } ++ ++ /* catch the last one */ ++ if (args) { ++ ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args); ++ if (!ctxt->m[i].argv) ++ goto nomem; ++ } ++ ++ return ctxt; ++ ++nomem: ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "error: %s", estr); ++ ++error_out: ++ free_multi_context(ctxt); ++ free(ctxt); ++ ++ return NULL; ++} ++ + static int free_multi_context(struct lookup_context *ctxt) + { + int rv; +@@ -180,95 +258,26 @@ int lookup_init(const char *my_mapfmt, + int argc, const char *const *argv, void **context) + { + struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; +- char **args; +- int i, an; +- char *estr; ++ int i; + +- ctxt = malloc(sizeof(struct lookup_context)); ++ ctxt = alloc_context(my_mapfmt, argc, argv); + if (!ctxt) +- goto nomem; +- +- memset(ctxt, 0, sizeof(struct lookup_context)); +- +- if (argc < 1) { +- logerr(MODPREFIX "No map list"); +- goto error_out; +- } +- +- ctxt->n = 1; /* Always at least one map */ +- for (i = 0; i < argc; i++) { +- if (!strcmp(argv[i], "--")) /* -- separates maps */ +- ctxt->n++; +- } +- +- if (!(ctxt->m = malloc(ctxt->n * sizeof(struct module_info))) || +- !(ctxt->argl = malloc((argc + 1) * sizeof(const char *)))) +- goto nomem; +- +- memset(ctxt->m, 0, ctxt->n * sizeof(struct module_info)); +- +- memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *)); +- +- args = NULL; +- for (i = an = 0; ctxt->argl[an]; an++) { +- if (ctxt->m[i].argc == 0) { +- args = (char **) &ctxt->argl[an]; +- } +- if (!strcmp(ctxt->argl[an], "--")) { +- ctxt->argl[an] = NULL; +- if (!args) { +- logerr(MODPREFIX "error assigning map args"); +- goto error_out; +- } +- ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args); +- if (!ctxt->m[i].argv) +- goto nomem; +- args = NULL; +- i++; +- } else { +- ctxt->m[i].argc++; +- } +- } +- +- /* catch the last one */ +- if (args) { +- ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args); +- if (!ctxt->m[i].argv) +- goto nomem; +- } ++ return 1; + + for (i = 0; i < ctxt->n; i++) { + ctxt->m[i].mod = nss_open_lookup(my_mapfmt, + ctxt->m[i].argc, ctxt->m[i].argv); + if (!ctxt->m[i].mod) { + logerr(MODPREFIX "error opening module"); +- goto error_out; ++ free_multi_context(ctxt); ++ free(ctxt); ++ return 1; + } + } + + *context = ctxt; +- return 0; + +-nomem: +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "error: %s", estr); +-error_out: +- if (ctxt) { +- if (ctxt->m) { +- for (i = 0; i < ctxt->n; i++) { +- if (ctxt->m[i].mod) +- close_lookup(ctxt->m[i].mod); +- if (ctxt->m[i].argv) +- free_argv(ctxt->m[i].argc, ctxt->m[i].argv); +- } +- free(ctxt->m); +- } +- if (ctxt->argl) +- free(ctxt->argl); +- free(ctxt); +- } +- return 1; ++ return 0; + } + + int lookup_reinit(const char *my_mapfmt, diff --git a/SOURCES/autofs-5.1.1-factor-out-free-multi-map-context.patch b/SOURCES/autofs-5.1.1-factor-out-free-multi-map-context.patch new file mode 100644 index 0000000..19670bd --- /dev/null +++ b/SOURCES/autofs-5.1.1-factor-out-free-multi-map-context.patch @@ -0,0 +1,68 @@ +autofs-5.1.1 - factor out free multi map context + +From: Ian Kent + +Seperate out the free context function for the multi map module. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 38 +++++++++++++++++++++++++++++--------- + 1 file changed, 29 insertions(+), 9 deletions(-) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 0ee20f5..36ace11 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -40,6 +40,32 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + ++static int free_multi_context(struct lookup_context *ctxt) ++{ ++ int rv; ++ ++ if (!ctxt) ++ return 0; ++ ++ rv = 0; ++ if (ctxt->m) { ++ int i; ++ ++ for (i = 0; i < ctxt->n; i++) { ++ if (ctxt->m[i].mod) ++ rv = rv || close_lookup(ctxt->m[i].mod); ++ if (ctxt->m[i].argv) ++ free_argv(ctxt->m[i].argc, ctxt->m[i].argv); ++ } ++ free(ctxt->m); ++ } ++ ++ if (ctxt->argl) ++ free(ctxt->argl); ++ ++ return rv; ++} ++ + static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv) + { + struct list_head nsslist; +@@ -306,16 +332,10 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void * + int lookup_done(void *context) + { + struct lookup_context *ctxt = (struct lookup_context *) context; +- int i, rv = 0; ++ int rv; + +- for (i = 0; i < ctxt->n; i++) { +- if (ctxt->m[i].mod) +- rv = rv || close_lookup(ctxt->m[i].mod); +- if (ctxt->m[i].argv) +- free_argv(ctxt->m[i].argc, ctxt->m[i].argv); +- } +- free(ctxt->argl); +- free(ctxt->m); ++ rv = free_multi_context(ctxt); + free(ctxt); ++ + return rv; + } diff --git a/SOURCES/autofs-5.1.1-fix-config-old-name-lookup.patch b/SOURCES/autofs-5.1.1-fix-config-old-name-lookup.patch new file mode 100644 index 0000000..ccf77c9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-config-old-name-lookup.patch @@ -0,0 +1,54 @@ +autofs-5.1.1 - fix config old name lookup + +From: Ian Kent + +There are three cases needed to handle configuration name lookup. + +First there's the configuration key name, the name match is case +insensitive so the recent case change isn't a seperate case. + +But the much older configuration key names that began with "DEFAULT_" +need special handling. + +There are two cases that need to be covered: +1) an old name is given but a new name needs to be located. +2) a new name is given but an old name needs to be located. + +Only 1) is currently covered, so fix that in conf_lookup(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/defaults.c | 11 +++++++++++ + 2 files changed, 12 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -190,6 +190,7 @@ + - log pipe read errors. + - fix rwlock unlock crash. + - fix handle_mounts() termination condition check. ++- fix config old name lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -727,6 +727,17 @@ static struct conf_option *conf_lookup(c + */ + if (strlen(key) > 8 && !strncasecmp("DEFAULT_", key, 8)) + co = conf_lookup_key(section, key + 8); ++ else { ++ /* A new key name has been given but the value ++ * we seek is stored under an old key name (which ++ * includes the "DEFAULT_" prefix or doesn't exist. ++ */ ++ char old_key[PATH_MAX + 1]; ++ ++ strcpy(old_key, "DEFAULT_"); ++ strcat(old_key, key); ++ co = conf_lookup_key(section, old_key); ++ } + } + + return co; diff --git a/SOURCES/autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch b/SOURCES/autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch new file mode 100644 index 0000000..392b238 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch @@ -0,0 +1,52 @@ +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(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -179,6 +179,7 @@ + - make find_server() return a status. + - fix return handling of do_reconnect() in ldap module. + - fix direct mount stale instance flag reset. ++- fix direct map expire not set for initail empty map. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/state.c ++++ autofs-5.0.7/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/SOURCES/autofs-5.1.1-fix-direct-mount-stale-instance-flag-reset.patch b/SOURCES/autofs-5.1.1-fix-direct-mount-stale-instance-flag-reset.patch new file mode 100644 index 0000000..3bcfb36 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-direct-mount-stale-instance-flag-reset.patch @@ -0,0 +1,34 @@ +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(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -178,6 +178,7 @@ + - make find_dc_server() return a status. + - make find_server() return a status. + - fix return handling of do_reconnect() in ldap module. ++- fix direct mount stale instance flag reset. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/state.c ++++ autofs-5.0.7/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/SOURCES/autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch b/SOURCES/autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch new file mode 100644 index 0000000..8c637d8 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch @@ -0,0 +1,87 @@ +autofs-5.1.1 - fix error handling on ldap bind fail + +From: Ian Kent + +When calling unbind_ldap_connection() if a sasl connection is +being used then autofs_sasl_unbind() should be called and not +ldap_unbind_ext(), otherwise the ldap connection release code +could be called twice. + +So, in unbind_ldap_connection() check if a sasl connection is in +use and unbind it if it is otherwise call ldap_unbind_ext() to +release the ldap connection. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 17 ++++++++++------- + 2 files changed, 11 insertions(+), 7 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -191,6 +191,7 @@ + - fix rwlock unlock crash. + - fix handle_mounts() termination condition check. + - fix config old name lookup. ++- fix error handling on ldap bind fail. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -216,15 +216,18 @@ int bind_ldap_simple(unsigned logopt, LD + + int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) + { +- int rv; ++ int rv = LDAP_SUCCESS; + + if (ctxt->use_tls == LDAP_TLS_RELEASE) + ctxt->use_tls = LDAP_TLS_INIT; + #ifdef WITH_SASL +- autofs_sasl_unbind(ctxt); +-#endif +- ++ if (ctxt->auth_required & LDAP_NEED_AUTH) ++ autofs_sasl_unbind(ctxt); ++ else ++ rv = ldap_unbind_ext(ldap, NULL, NULL); ++#else + rv = ldap_unbind_ext(ldap, NULL, NULL); ++#endif + if (rv != LDAP_SUCCESS) + error(logopt, "unbind failed: %s", ldap_err2string(rv)); + +@@ -302,7 +305,7 @@ LDAP *__init_ldap_connection(unsigned lo + + rv = ldap_start_tls_s(ldap, NULL, NULL); + if (rv != LDAP_SUCCESS) { +- __unbind_ldap_connection(logopt, ldap, ctxt); ++ ldap_unbind_ext(ldap, NULL, NULL); + if (ctxt->tls_required) { + error(logopt, MODPREFIX + "TLS required but START_TLS failed: %s", +@@ -576,14 +579,13 @@ static int do_bind(unsigned logopt, LDAP + char *host = NULL, *nhost; + int rv; + ++ ldapinit_mutex_lock(); + #ifdef WITH_SASL + debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s", + ctxt->auth_required, ctxt->sasl_mech); + + if (ctxt->auth_required & LDAP_NEED_AUTH) { +- ldapinit_mutex_lock(); + rv = autofs_sasl_bind(logopt, ldap, ctxt); +- ldapinit_mutex_unlock(); + debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv); + } else { + rv = bind_ldap_simple(logopt, ldap, uri, ctxt); +@@ -593,6 +595,7 @@ static int do_bind(unsigned logopt, LDAP + rv = bind_ldap_simple(logopt, ldap, uri, ctxt); + debug(logopt, MODPREFIX "ldap simple bind returned %d", rv); + #endif ++ ldapinit_mutex_unlock(); + + if (rv != 0) + return 0; diff --git a/SOURCES/autofs-5.1.1-fix-fix-gcc5-complaints.patch b/SOURCES/autofs-5.1.1-fix-fix-gcc5-complaints.patch new file mode 100644 index 0000000..6880f65 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-fix-gcc5-complaints.patch @@ -0,0 +1,23 @@ +autofs-5.1.1 - fix fix gcc5 complaints + +From: Ian Kent + +Remove a stray declare of dump_core(). + +Signed-off-by: Ian Kent +--- + lib/rpc_subs.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c +index 846c40e..84fae9e 100644 +--- a/lib/rpc_subs.c ++++ b/lib/rpc_subs.c +@@ -77,7 +77,6 @@ static const rpcvers_t mount_vers[] = { + }; + + static int connect_nb(int, struct sockaddr *, socklen_t, struct timeval *); +-inline void dump_core(void); + + /* + * Perform a non-blocking connect on the socket fd. diff --git a/SOURCES/autofs-5.1.1-fix-handle_mounts-termination-condition-check.patch b/SOURCES/autofs-5.1.1-fix-handle_mounts-termination-condition-check.patch new file mode 100644 index 0000000..1da74b8 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-handle_mounts-termination-condition-check.patch @@ -0,0 +1,239 @@ +autofs-5.1.1 - fix handle_mounts() termination condition check + +From: Ian Kent + +In get_pkt(), if a kernel request is present on the kernel pipe and +the autofs mount point state changes to ST_SHUTDOWN after the poll(2) +check but before the request has been processed the handle_mounts() +thread will exit without shutting down the autofs mount point. + +So change the handle_mounts() exit condition check to take account +of this case. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 191 ++++++++++++++++++++++++++++------------------------- + 2 files changed, 105 insertions(+), 87 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -189,6 +189,7 @@ + - always set direct mounts catatonic at exit. + - log pipe read errors. + - fix rwlock unlock crash. ++- fix handle_mounts() termination condition check. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -1659,6 +1659,99 @@ static void submount_source_unlock_neste + master_source_unlock(parent->entry); + } + ++int handle_mounts_exit(struct autofs_point *ap) ++{ ++ int ret, cur_state; ++ ++ /* ++ * If we're a submount we need to ensure our parent ++ * doesn't try to mount us again until our shutdown ++ * is complete and that any outstanding mounts are ++ * completed before we try to shutdown. ++ */ ++ pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); ++ ++ master_mutex_lock(); ++ ++ if (!ap->submount) ++ master_source_writelock(ap->entry); ++ else { ++ /* ++ * If a mount request arrives before the locks are ++ * aquired just return to ready state. ++ */ ++ ret = submount_source_writelock_nested(ap); ++ if (ret) { ++ warn(ap->logopt, ++ "can't shutdown submount: mount in progress"); ++ /* Return to ST_READY is done immediately */ ++ st_add_task(ap, ST_READY); ++ master_mutex_unlock(); ++ pthread_setcancelstate(cur_state, NULL); ++ return 0; ++ } ++ } ++ ++ if (ap->state != ST_SHUTDOWN) { ++ if (!ap->submount) ++ alarm_add(ap, ap->exp_runfreq); ++ /* Return to ST_READY is done immediately */ ++ st_add_task(ap, ST_READY); ++ if (ap->submount) ++ submount_source_unlock_nested(ap); ++ else ++ master_source_unlock(ap->entry); ++ master_mutex_unlock(); ++ ++ pthread_setcancelstate(cur_state, NULL); ++ return 0; ++ } ++ ++ alarm_delete(ap); ++ st_remove_tasks(ap); ++ st_wait_task(ap, ST_ANY, 0); ++ ++ /* ++ * For a direct mount map all mounts have already gone ++ * by the time we get here and since we only ever ++ * umount direct mounts at shutdown there is no need ++ * to check for possible recovery. ++ */ ++ if (ap->type == LKP_DIRECT) { ++ umount_autofs(ap, NULL, 1); ++ handle_mounts_cleanup(ap); ++ return 1; ++ } ++ ++ /* ++ * If umount_autofs returns non-zero it wasn't able ++ * to complete the umount and has left the mount intact ++ * so we can continue. This can happen if a lookup ++ * occurs while we're trying to umount. ++ */ ++ ret = umount_autofs(ap, NULL, 1); ++ if (!ret) { ++ handle_mounts_cleanup(ap); ++ return 1; ++ } ++ ++ /* Failed shutdown returns to ready */ ++ warn(ap->logopt, "can't shutdown: filesystem %s still busy", ap->path); ++ if (!ap->submount) ++ alarm_add(ap, ap->exp_runfreq); ++ /* Return to ST_READY is done immediately */ ++ st_add_task(ap, ST_READY); ++ if (ap->submount) ++ submount_source_unlock_nested(ap); ++ else ++ master_source_unlock(ap->entry); ++ master_mutex_unlock(); ++ ++ pthread_setcancelstate(cur_state, NULL); ++ ++ return 0; ++} ++ + void *handle_mounts(void *arg) + { + struct startup_cond *suc; +@@ -1714,97 +1807,21 @@ void *handle_mounts(void *arg) + + pthread_setcancelstate(cancel_state, NULL); + +- while (ap->state != ST_SHUTDOWN) { ++ while (1) { + if (handle_packet(ap)) { +- int ret, cur_state; +- +- /* +- * If we're a submount we need to ensure our parent +- * doesn't try to mount us again until our shutdown +- * is complete and that any outstanding mounts are +- * completed before we try to shutdown. +- */ +- pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cur_state); +- +- master_mutex_lock(); +- +- if (ap->submount) { +- /* +- * If a mount request arrives before the locks are +- * aquired just return to ready state. +- */ +- ret = submount_source_writelock_nested(ap); +- if (ret) { +- warn(ap->logopt, +- "can't shutdown submount: mount in progress"); +- /* Return to ST_READY is done immediately */ +- st_add_task(ap, ST_READY); +- master_mutex_unlock(); +- pthread_setcancelstate(cur_state, NULL); +- continue; +- } +- } else +- master_source_writelock(ap->entry); +- +- if (ap->state != ST_SHUTDOWN) { +- if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); +- /* Return to ST_READY is done immediately */ +- st_add_task(ap, ST_READY); +- if (ap->submount) +- submount_source_unlock_nested(ap); +- else +- master_source_unlock(ap->entry); +- master_mutex_unlock(); +- +- pthread_setcancelstate(cur_state, NULL); +- continue; +- } +- +- alarm_delete(ap); +- st_remove_tasks(ap); +- st_wait_task(ap, ST_ANY, 0); +- +- /* +- * For a direct mount map all mounts have already gone +- * by the time we get here and since we only ever +- * umount direct mounts at shutdown there is no need +- * to check for possible recovery. +- */ +- if (ap->type == LKP_DIRECT) { +- umount_autofs(ap, NULL, 1); +- handle_mounts_cleanup(ap); ++ if (handle_mounts_exit(ap)) + break; +- } ++ } + +- /* +- * If umount_autofs returns non-zero it wasn't able +- * to complete the umount and has left the mount intact +- * so we can continue. This can happen if a lookup +- * occurs while we're trying to umount. +- */ +- ret = umount_autofs(ap, NULL, 1); +- if (!ret) { +- handle_mounts_cleanup(ap); ++ /* If we get here a packet has been received and handled ++ * and the autofs mount point has not been shutdown. But ++ * if the autofs mount point has been set to ST_SHUTDOWN ++ * we should attempt to perform the shutdown cleanup and ++ * exit if successful. ++ */ ++ if (ap->state == ST_SHUTDOWN) { ++ if (handle_mounts_exit(ap)) + break; +- } +- +- /* Failed shutdown returns to ready */ +- warn(ap->logopt, +- "can't shutdown: filesystem %s still busy", +- ap->path); +- if (!ap->submount) +- alarm_add(ap, ap->exp_runfreq); +- /* Return to ST_READY is done immediately */ +- st_add_task(ap, ST_READY); +- if (ap->submount) +- submount_source_unlock_nested(ap); +- else +- master_source_unlock(ap->entry); +- master_mutex_unlock(); +- +- pthread_setcancelstate(cur_state, NULL); +- + } + } + diff --git a/SOURCES/autofs-5.1.1-fix-left-mount-count-return.patch b/SOURCES/autofs-5.1.1-fix-left-mount-count-return.patch new file mode 100644 index 0000000..0d0a01e --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-left-mount-count-return.patch @@ -0,0 +1,37 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -170,6 +170,7 @@ + - remove unused offset handling code. + - fix mount as you go offset selection. + - init qdn before use in get_query_dn(). ++- fix left mount count return from umount_multi_triggers(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -2130,7 +2130,7 @@ int umount_multi_triggers(struct autofs_ + 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/SOURCES/autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch b/SOURCES/autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch new file mode 100644 index 0000000..21ca47d --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch @@ -0,0 +1,47 @@ +autofs-5.1.1 - fix map format check in nss_open_lookup() multi map module + +From: Ian Kent + +The nss_open_lookup() function doesn't properly allow for map format when +it's given with the map type. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 433b424..f8ebf94 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -24,6 +24,8 @@ + #include "automount.h" + #include "nsswitch.h" + ++#define MAX_MAP_TYPE_STRING 20 ++ + #define MODPREFIX "lookup(multi): " + + struct module_info { +@@ -166,11 +168,17 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + !strncmp(argv[0], "ldaps", 5) || + !strncmp(argv[0], "ldap", 4) || + !strncmp(argv[0], "sss", 3)) { +- const char *fmt = strchr(argv[0], ','); +- if (fmt) ++ char type[MAX_MAP_TYPE_STRING]; ++ char *fmt; ++ ++ strcpy(type, argv[0]); ++ fmt = strchr(type, ','); ++ if (!fmt) ++ fmt = (char *) format; ++ else { ++ *fmt = '\0'; + fmt++; +- else +- fmt = format; ++ } + open_lookup(argv[0], MODPREFIX, fmt, argc - 1, argv + 1, &mod); + return mod; + } diff --git a/SOURCES/autofs-5.1.1-fix-memory-leak-in-ldap-do_init.patch b/SOURCES/autofs-5.1.1-fix-memory-leak-in-ldap-do_init.patch new file mode 100644 index 0000000..e043ce4 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-memory-leak-in-ldap-do_init.patch @@ -0,0 +1,33 @@ +autofs-5.1.1 - fix memory leak in ldap do_init() + +From: Ian Kent + +Fix error return without free of temporory allocated storage in +do_init(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 1 + + 2 files changed, 2 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -199,6 +199,7 @@ + - fix unbind sasl external mech. + - fix sasl connection concurrancy problem. + - fix memory leak in nisplus lookup_reinit(). ++- fix memory leak in ldap do_init(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -1752,6 +1752,7 @@ static int do_init(const char *mapfmt, + */ + if (!parse_server_string(LOGOPT_NONE, tmp, ctxt)) { + error(LOGOPT_ANY, MODPREFIX "cannot parse server string"); ++ free(tmp); + return 1; + } + free(tmp); diff --git a/SOURCES/autofs-5.1.1-fix-memory-leak-in-nisplus-lookup_reinit.patch b/SOURCES/autofs-5.1.1-fix-memory-leak-in-nisplus-lookup_reinit.patch new file mode 100644 index 0000000..23cc485 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-memory-leak-in-nisplus-lookup_reinit.patch @@ -0,0 +1,36 @@ +autofs-5.1.1 - fix memory leak in nisplus lookup_reinit() + +From: Ian Kent + +Don't forget to free context on reinit error. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_nisplus.c | 4 +++- + 2 files changed, 4 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -198,6 +198,7 @@ + - change lookup to use reinit instead of reopen. + - fix unbind sasl external mech. + - fix sasl connection concurrancy problem. ++- fix memory leak in nisplus lookup_reinit(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_nisplus.c ++++ autofs-5.0.7/modules/lookup_nisplus.c +@@ -116,8 +116,10 @@ int lookup_reinit(const char *mapfmt, + + new->parse = ctxt->parse; + ret = do_init(mapfmt, argc, argv, new, 1); +- if (ret) ++ if (ret) { ++ free(new); + return 1; ++ } + + *context = new; + diff --git a/SOURCES/autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch b/SOURCES/autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch new file mode 100644 index 0000000..f5a10c7 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch @@ -0,0 +1,34 @@ +autofs-5.1.1 - fix missing source sss in multi map lookup + +From: Ian Kent + +The sss source isn't accounted for in the multi map lookup module. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_multi.c | 3 ++- + 2 files changed, 3 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -193,6 +193,7 @@ + - fix config old name lookup. + - fix error handling on ldap bind fail. + - fix gcc5 complaints. ++- fix missing source sss in multi map lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_multi.c ++++ autofs-5.0.7/modules/lookup_multi.c +@@ -58,7 +58,8 @@ static struct lookup_mod *nss_open_looku + !strncmp(argv[0], "nisplus", 7) || + !strncmp(argv[0], "nis", 3) || + !strncmp(argv[0], "ldaps", 5) || +- !strncmp(argv[0], "ldap", 4)) { ++ !strncmp(argv[0], "ldap", 4) || ++ !strncmp(argv[0], "sss", 3)) { + const char *fmt = strchr(argv[0], ','); + if (fmt) + fmt++; diff --git a/SOURCES/autofs-5.1.1-fix-nameing-typo-in-autofs-conf.patch b/SOURCES/autofs-5.1.1-fix-nameing-typo-in-autofs-conf.patch new file mode 100644 index 0000000..906ea55 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-nameing-typo-in-autofs-conf.patch @@ -0,0 +1,46 @@ +autofs-5.1.1 - fix 'nameing' typo in autofs.conf + +From: Ian Kent + +Change nameing to naming at about line 118 in autofs package default +configurations. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + redhat/autofs.conf.default.in | 2 +- + samples/autofs.conf.default.in | 2 +- + 3 files changed, 3 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -185,6 +185,7 @@ + - make service want network-online. + - add remote-fs.target systemd dependency. + - gaurd against incorrect umount return. ++- fix typo in autofs.conf. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -115,7 +115,7 @@ mount_nfs_default_protocol = 4 + #entry_attribute = cn + #value_attribute= nisMapEntry + # +-# Other common LDAP nameing ++# Other common LDAP naming + # + #map_object_class = automountMap + #entry_object_class = automount +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -114,7 +114,7 @@ browse_mode = no + #entry_attribute = cn + #value_attribute= nisMapEntry + # +-# Other common LDAP nameing ++# Other common LDAP naming + # + #map_object_class = automountMap + #entry_object_class = automount diff --git a/SOURCES/autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch b/SOURCES/autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch new file mode 100644 index 0000000..720eaf2 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch @@ -0,0 +1,48 @@ +autofs-5.1.1 - fix nsswitch handling when opening multi map + +From: Ian Kent + +When initializing the lookup module for multi-map entries nsswitch +actions should be honoured to the extent they can be. In particular +the case of a map not found should use an nsswitch action (if present) +to work out whether to continue looking or return a failure. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index 55035e4..ba8d4f0 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -84,6 +84,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + list_for_each(p, head) { + struct nss_source *this; + int status; ++ int ret; + + this = list_entry(p, struct nss_source, list); + +@@ -127,6 +128,10 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + + argv[0] = save_argv0; + free(path); ++ ++ ret = check_nss_result(this, status); ++ if (ret >= 0) ++ break; + } + + status = open_lookup(this->source, MODPREFIX, +@@ -135,6 +140,10 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + free_sources(&nsslist); + return mod; + } ++ ++ ret = check_nss_result(this, status); ++ if (ret >= 0) ++ break; + } + free_sources(&nsslist); + diff --git a/SOURCES/autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch b/SOURCES/autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch new file mode 100644 index 0000000..b2b9a5b --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch @@ -0,0 +1,65 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -181,6 +181,7 @@ + - fix direct mount stale instance flag reset. + - fix direct map expire not set for initail empty map. + - update map_hash_table_size description. ++- fix out of order call in program map lookup. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_program.c ++++ autofs-5.0.7/modules/lookup_program.c +@@ -139,6 +139,16 @@ static char *lookup_one(struct autofs_po + } + + /* ++ * 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 +@@ -177,16 +187,6 @@ static char *lookup_one(struct autofs_po + 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/SOURCES/autofs-5.1.1-fix-return-handling-in-sss-lookup-module.patch b/SOURCES/autofs-5.1.1-fix-return-handling-in-sss-lookup-module.patch new file mode 100644 index 0000000..fefa268 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-return-handling-in-sss-lookup-module.patch @@ -0,0 +1,94 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -171,6 +171,7 @@ + - fix mount as you go offset selection. + - init qdn before use in get_query_dn(). + - fix left mount count return from umount_multi_triggers(). ++- fix return handling in sss lookup module. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_sss.c ++++ autofs-5.0.7/modules/lookup_sss.c +@@ -148,9 +148,8 @@ static int setautomntent(unsigned int lo + 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 lo + 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 *ma + 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 + 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_poin + + 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/SOURCES/autofs-5.1.1-fix-return-handling-of-do_reconnect-in-ldap-module.patch b/SOURCES/autofs-5.1.1-fix-return-handling-of-do_reconnect-in-ldap-module.patch new file mode 100644 index 0000000..6dd78d6 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-return-handling-of-do_reconnect-in-ldap-module.patch @@ -0,0 +1,204 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -177,6 +177,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. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/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 logop + 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 *ma + 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_po + 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_poin + 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_poin + } + + /* 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_ + 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_ + } + + /* 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/SOURCES/autofs-5.1.1-fix-rwlock-unlock-crash.patch b/SOURCES/autofs-5.1.1-fix-rwlock-unlock-crash.patch new file mode 100644 index 0000000..d52bcfe --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-rwlock-unlock-crash.patch @@ -0,0 +1,63 @@ +autofs-5.1.1 - fix rwlock unlock crash + +From: Ian Kent + +It should be the case that the only way that automount can exit +the kernel communication read loop is after reading a packet and +performing shutdown operations. + +However there are reports of pthread_rwlock_unlock() being called +from the exit cleanup function when the lock it is trying to unlock +is not held. + +But the call to the cleanup function is outside the communication +loop so call it from each of the loop break points instead so that +the expected locks must be held. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 7 ++++--- + 2 files changed, 5 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -188,6 +188,7 @@ + - fix typo in autofs.conf. + - always set direct mounts catatonic at exit. + - log pipe read errors. ++- fix rwlock unlock crash. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -1773,6 +1773,7 @@ void *handle_mounts(void *arg) + */ + if (ap->type == LKP_DIRECT) { + umount_autofs(ap, NULL, 1); ++ handle_mounts_cleanup(ap); + break; + } + +@@ -1783,8 +1784,10 @@ void *handle_mounts(void *arg) + * occurs while we're trying to umount. + */ + ret = umount_autofs(ap, NULL, 1); +- if (!ret) ++ if (!ret) { ++ handle_mounts_cleanup(ap); + break; ++ } + + /* Failed shutdown returns to ready */ + warn(ap->logopt, +@@ -1805,8 +1808,6 @@ void *handle_mounts(void *arg) + } + } + +- handle_mounts_cleanup(ap); +- + return NULL; + } + diff --git a/SOURCES/autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch b/SOURCES/autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch new file mode 100644 index 0000000..02671a9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch @@ -0,0 +1,828 @@ +autofs-5.1.1 - fix sasl connection concurrancy problem + +From: Ian Kent + +After using the contributed Cyrus SASL code in autofs for years I've +finally looked at the Cyrus SASL C API RFC only to find that the +library isn't thread safe unless a connection context per thread is +used, similar to the LDAP library. + +To be fair this code originated prior to the threaded version of +autofs so it's my bad I didn't check. + +But having seen this I have no choice but to make the sasl context +per thread not per autofs lookup context. + +Also extend the mutual exclusion even further. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/lookup_ldap.h | 16 ++-- + modules/cyrus-sasl.c | 46 ++++++----- + modules/lookup_ldap.c | 198 +++++++++++++++++++++++++------------------------- + 4 files changed, 136 insertions(+), 125 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -197,6 +197,7 @@ + - fix update_hosts_mounts() return. + - change lookup to use reinit instead of reopen. + - fix unbind sasl external mech. ++- fix sasl connection concurrancy problem. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/lookup_ldap.h ++++ autofs-5.0.7/include/lookup_ldap.h +@@ -34,6 +34,13 @@ struct ldap_searchdn { + struct ldap_searchdn *next; + }; + ++struct ldap_conn { ++ LDAP *ldap; ++#ifdef WITH_SASL ++ sasl_conn_t *sasl_conn; ++#endif ++}; ++ + struct lookup_context { + char *mapname; + unsigned int format; +@@ -86,7 +93,6 @@ struct lookup_context { + /* Kerberos */ + krb5_context krb5ctxt; + krb5_ccache krb5_ccache; +- sasl_conn_t *sasl_conn; + /* SASL external */ + char *extern_cert; + char *extern_key; +@@ -113,16 +119,16 @@ struct lookup_context { + + /* lookup_ldap.c */ + LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt); +-int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt); ++int unbind_ldap_connection(unsigned logopt, struct ldap_conn *conn, struct lookup_context *ctxt); + int authtype_requires_creds(const char *authtype); + + #ifdef WITH_SASL + /* cyrus-sasl.c */ + int autofs_sasl_client_init(unsigned logopt); + int autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt); +-int autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt); +-void autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt); +-void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt); ++int autofs_sasl_bind(unsigned logopt, struct ldap_conn *conn, struct lookup_context *ctxt); ++void autofs_sasl_unbind(struct ldap_conn *conn, struct lookup_context *ctxt); ++void autofs_sasl_dispose(struct ldap_conn *conn, struct lookup_context *ctxt); + void autofs_sasl_done(void); + /* cyrus-sasl-extern */ + int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt); +--- autofs-5.0.7.orig/modules/cyrus-sasl.c ++++ autofs-5.0.7/modules/cyrus-sasl.c +@@ -855,16 +855,19 @@ sasl_choose_mech(unsigned logopt, LDAP * + * Routine called when unbinding an ldap connection. + */ + void +-autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt) ++autofs_sasl_unbind(struct ldap_conn *conn, struct lookup_context *ctxt) + { + if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { +- ldap_unbind_s(ldap); ++ if (conn->ldap) { ++ ldap_unbind_s(conn->ldap); ++ conn->ldap = NULL; ++ } + return; + } + +- if (ctxt->sasl_conn) { +- sasl_dispose(&ctxt->sasl_conn); +- ctxt->sasl_conn = NULL; ++ if (conn->sasl_conn) { ++ sasl_dispose(&conn->sasl_conn); ++ conn->sasl_conn = NULL; + } + } + +@@ -878,13 +881,10 @@ autofs_sasl_unbind(LDAP *ldap, struct lo + * -1 - Failure + */ + int +-autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++autofs_sasl_bind(unsigned logopt, ++ struct ldap_conn *conn, struct lookup_context *ctxt) + { +- sasl_conn_t *conn = NULL; +- +- /* If we already have a connection use it */ +- if (ctxt->sasl_conn) +- return 0; ++ sasl_conn_t *sasl_conn = NULL; + + if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { + int result; +@@ -893,7 +893,7 @@ autofs_sasl_bind(unsigned logopt, LDAP * + "Attempting sasl bind with mechanism %s", + ctxt->sasl_mech); + +- result = do_sasl_extern(ldap, ctxt); ++ result = do_sasl_extern(conn->ldap, ctxt); + if (result) + debug(logopt, + "Failed to authenticate with mech %s", +@@ -923,14 +923,16 @@ autofs_sasl_bind(unsigned logopt, LDAP * + * auth mechanism. + */ + if (ctxt->sasl_mech) +- conn = sasl_bind_mech(logopt, ldap, ctxt, ctxt->sasl_mech); ++ sasl_conn = sasl_bind_mech(logopt, ++ conn->ldap, ctxt, ctxt->sasl_mech); + else +- conn = sasl_choose_mech(logopt, ldap, ctxt); ++ sasl_conn = sasl_choose_mech(logopt, conn->ldap, ctxt); + + if (!conn) + return -1; + +- ctxt->sasl_conn = conn; ++ conn->sasl_conn = sasl_conn; ++ + return 0; + } + +@@ -938,19 +940,21 @@ autofs_sasl_bind(unsigned logopt, LDAP * + * Destructor routine. This should be called when finished with an ldap + * session. + */ +-void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt) ++void autofs_sasl_dispose(struct ldap_conn *conn, struct lookup_context *ctxt) + { + int status, ret; + + if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { +- if (ldap) +- ldap_unbind_s(ldap); ++ if (conn && conn->ldap) { ++ ldap_unbind_s(conn->ldap); ++ conn->ldap = NULL; ++ } + return; + } + +- if (ctxt->sasl_conn) { +- sasl_dispose(&ctxt->sasl_conn); +- ctxt->sasl_conn = NULL; ++ if (conn && conn->sasl_conn) { ++ sasl_dispose(&conn->sasl_conn); ++ conn->sasl_conn = NULL; + } + + if (ctxt->kinit_successful) { +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -214,7 +214,9 @@ int bind_ldap_simple(unsigned logopt, LD + return 0; + } + +-int __unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++int __unbind_ldap_connection(unsigned logopt, ++ struct ldap_conn *conn, ++ struct lookup_context *ctxt) + { + int rv = LDAP_SUCCESS; + +@@ -222,30 +224,35 @@ int __unbind_ldap_connection(unsigned lo + ctxt->use_tls = LDAP_TLS_INIT; + #ifdef WITH_SASL + if (ctxt->auth_required & LDAP_NEED_AUTH) +- autofs_sasl_unbind(ldap, ctxt); +- else +- rv = ldap_unbind_ext(ldap, NULL, NULL); +-#else +- rv = ldap_unbind_ext(ldap, NULL, NULL); ++ autofs_sasl_unbind(conn, ctxt); ++ /* No, sasl_dispose does not release the ldap connection ++ * unless it's using sasl EXTERNAL ++ */ + #endif ++ if (conn->ldap) { ++ rv = ldap_unbind_ext(conn->ldap, NULL, NULL); ++ conn->ldap = NULL; ++ } + if (rv != LDAP_SUCCESS) + error(logopt, "unbind failed: %s", ldap_err2string(rv)); + + return rv; + } + +-int unbind_ldap_connection(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt) ++int unbind_ldap_connection(unsigned logopt, ++ struct ldap_conn *conn, ++ struct lookup_context *ctxt) + { + int rv; + + ldapinit_mutex_lock(); +- rv = __unbind_ldap_connection(logopt, ldap, ctxt); ++ rv = __unbind_ldap_connection(logopt, conn, ctxt); + ldapinit_mutex_unlock(); + + return rv; + } + +-LDAP *__init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt) ++LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt) + { + LDAP *ldap = NULL; + struct timeval timeout = { ctxt->timeout, 0 }; +@@ -313,7 +320,7 @@ LDAP *__init_ldap_connection(unsigned lo + return NULL; + } + ctxt->use_tls = LDAP_TLS_DONT_USE; +- ldap = __init_ldap_connection(logopt, uri, ctxt); ++ ldap = init_ldap_connection(logopt, uri, ctxt); + if (ldap) + ctxt->use_tls = LDAP_TLS_INIT; + return ldap; +@@ -324,17 +331,6 @@ LDAP *__init_ldap_connection(unsigned lo + return ldap; + } + +-LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_context *ctxt) +-{ +- LDAP *ldap; +- +- ldapinit_mutex_lock(); +- ldap = __init_ldap_connection(logopt, uri, ctxt); +- ldapinit_mutex_unlock(); +- +- return ldap; +-} +- + static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key) + { + char buf[MAX_ERR_BUF]; +@@ -574,33 +570,32 @@ static int find_query_dn(unsigned logopt + return 0; + } + +-static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt) ++static int do_bind(unsigned logopt, struct ldap_conn *conn, ++ const char *uri, struct lookup_context *ctxt) + { + char *host = NULL, *nhost; + int rv; + +- ldapinit_mutex_lock(); + #ifdef WITH_SASL + debug(logopt, MODPREFIX "auth_required: %d, sasl_mech %s", + ctxt->auth_required, ctxt->sasl_mech); + + if (ctxt->auth_required & LDAP_NEED_AUTH) { +- rv = autofs_sasl_bind(logopt, ldap, ctxt); ++ rv = autofs_sasl_bind(logopt, conn, ctxt); + debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv); + } else { +- rv = bind_ldap_simple(logopt, ldap, uri, ctxt); ++ rv = bind_ldap_simple(logopt, conn->ldap, uri, ctxt); + debug(logopt, MODPREFIX "ldap simple bind returned %d", rv); + } + #else +- rv = bind_ldap_simple(logopt, ldap, uri, ctxt); ++ rv = bind_ldap_simple(logopt, conn->ldap, uri, ctxt); + debug(logopt, MODPREFIX "ldap simple bind returned %d", rv); + #endif +- ldapinit_mutex_unlock(); + + if (rv != 0) + return 0; + +- rv = ldap_get_option(ldap, LDAP_OPT_HOST_NAME, &host); ++ rv = ldap_get_option(conn->ldap, LDAP_OPT_HOST_NAME, &host); + if (rv != LDAP_SUCCESS || !host) { + debug(logopt, "failed to get hostname for connection"); + return 0; +@@ -634,15 +629,12 @@ static int do_bind(unsigned logopt, LDAP + return 1; + } + +-static int do_connect(unsigned logopt, LDAP **ldap, ++static int do_connect(unsigned logopt, struct ldap_conn *conn, + const char *uri, struct lookup_context *ctxt) + { + char *cur_host = NULL; +- LDAP *handle; + int ret = NSS_STATUS_SUCCESS; + +- *ldap = NULL; +- + #ifdef WITH_SASL + if (ctxt->extern_cert && ctxt->extern_key) { + set_env(logopt, ENV_LDAPTLS_CERT, ctxt->extern_cert); +@@ -650,8 +642,8 @@ static int do_connect(unsigned logopt, L + } + #endif + +- handle = init_ldap_connection(logopt, uri, ctxt); +- if (!handle) { ++ conn->ldap = init_ldap_connection(logopt, uri, ctxt); ++ if (!conn->ldap) { + ret = NSS_STATUS_UNAVAIL; + goto out; + } +@@ -661,8 +653,8 @@ static int do_connect(unsigned logopt, L + cur_host = ctxt->cur_host; + uris_mutex_unlock(ctxt); + +- if (!do_bind(logopt, handle, uri, ctxt)) { +- unbind_ldap_connection(logopt, handle, ctxt); ++ if (!do_bind(logopt, conn, uri, ctxt)) { ++ __unbind_ldap_connection(logopt, conn, ctxt); + ret = NSS_STATUS_UNAVAIL; + goto out; + } +@@ -673,7 +665,6 @@ static int do_connect(unsigned logopt, L + uris_mutex_lock(ctxt); + if (ctxt->schema && ctxt->qdn && (cur_host == ctxt->cur_host)) { + uris_mutex_unlock(ctxt); +- *ldap = handle; + goto out; + } + uris_mutex_unlock(ctxt); +@@ -684,8 +675,8 @@ static int do_connect(unsigned logopt, L + * base dn for searches. + */ + if (!ctxt->schema) { +- if (!find_query_dn(logopt, handle, ctxt)) { +- unbind_ldap_connection(logopt, handle, ctxt); ++ if (!find_query_dn(logopt, conn->ldap, ctxt)) { ++ __unbind_ldap_connection(logopt, conn, ctxt); + ret = NSS_STATUS_NOTFOUND; + warn(logopt, + MODPREFIX "failed to find valid query dn"); +@@ -694,21 +685,21 @@ static int do_connect(unsigned logopt, L + } else if (!(ctxt->format & MAP_FLAG_FORMAT_AMD)) { + const char *class = ctxt->schema->map_class; + const char *key = ctxt->schema->map_attr; +- if (!get_query_dn(logopt, handle, ctxt, class, key)) { +- unbind_ldap_connection(logopt, handle, ctxt); ++ if (!get_query_dn(logopt, conn->ldap, ctxt, class, key)) { ++ __unbind_ldap_connection(logopt, conn, ctxt); + ret = NSS_STATUS_NOTFOUND; + error(logopt, MODPREFIX "failed to get query dn"); + goto out; + } + } + +- *ldap = handle; + out: + return ret; + } + + static unsigned long get_amd_timestamp(struct lookup_context *ctxt) + { ++ struct ldap_conn conn; + LDAP *ldap; + LDAPMessage *result = NULL, *e; + char *query; +@@ -719,9 +710,11 @@ static unsigned long get_amd_timestamp(s + unsigned long timestamp = 0; + int rv, l, ql; + +- rv = do_connect(LOGOPT_ANY, &ldap, ctxt->server, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_connect(LOGOPT_ANY, &conn, ctxt->server, ctxt); + if (rv != NSS_STATUS_SUCCESS) + return 0; ++ ldap = conn.ldap; + + map = amd_timestamp.map_attr; + class = amd_timestamp.entry_class; +@@ -758,7 +751,7 @@ static unsigned long get_amd_timestamp(s + rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result); + if ((rv != LDAP_SUCCESS) || !result) { + crit(LOGOPT_ANY, MODPREFIX "timestamp query failed %s", query); +- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt); ++ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt); + if (result) + ldap_msgfree(result); + free(query); +@@ -770,7 +763,7 @@ static unsigned long get_amd_timestamp(s + debug(LOGOPT_ANY, + MODPREFIX "got answer, but no entry for timestamp"); + ldap_msgfree(result); +- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt); ++ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt); + free(query); + return CHE_MISSING; + } +@@ -821,18 +814,18 @@ next: + } + + ldap_msgfree(result); +- unbind_ldap_connection(LOGOPT_ANY, ldap, ctxt); ++ unbind_ldap_connection(LOGOPT_ANY, &conn, ctxt); + free(query); + + return timestamp; + } + +-static int connect_to_server(unsigned logopt, LDAP **ldap, ++static int connect_to_server(unsigned logopt, struct ldap_conn *conn, + const char *uri, struct lookup_context *ctxt) + { + int ret; + +- ret = do_connect(logopt, ldap, uri, ctxt); ++ ret = do_connect(logopt, conn, uri, ctxt); + if (ret != NSS_STATUS_SUCCESS) { + warn(logopt, + MODPREFIX "couldn't connect to server %s", +@@ -842,7 +835,7 @@ static int connect_to_server(unsigned lo + return ret; + } + +-static int find_dc_server(unsigned logopt, LDAP **ldap, ++static int find_dc_server(unsigned logopt, struct ldap_conn *conn, + const char *uri, struct lookup_context *ctxt) + { + char *str, *tok, *ptr = NULL; +@@ -858,7 +851,7 @@ static int find_dc_server(unsigned logop + int rv; + + debug(logopt, "trying server uri %s", this); +- rv = connect_to_server(logopt, ldap, this, ctxt); ++ rv = connect_to_server(logopt, conn, this, ctxt); + if (rv == NSS_STATUS_SUCCESS) { + info(logopt, "connected to uri %s", this); + free(str); +@@ -875,7 +868,7 @@ static int find_dc_server(unsigned logop + } + + static int find_server(unsigned logopt, +- LDAP **ldap, struct lookup_context *ctxt) ++ struct ldap_conn *conn, struct lookup_context *ctxt) + { + struct ldap_uri *this = NULL; + struct list_head *p, *first; +@@ -906,7 +899,7 @@ static int find_server(unsigned logopt, + if (!strstr(this->uri, ":///")) { + uri = strdup(this->uri); + debug(logopt, "trying server uri %s", uri); +- rv = connect_to_server(logopt, ldap, uri, ctxt); ++ rv = connect_to_server(logopt, conn, uri, ctxt); + if (rv == NSS_STATUS_SUCCESS) { + ret = NSS_STATUS_SUCCESS; + info(logopt, "connected to uri %s", uri); +@@ -928,7 +921,7 @@ static int find_server(unsigned logopt, + dclist = tmp; + uri = strdup(dclist->uri); + } +- rv = find_dc_server(logopt, ldap, uri, ctxt); ++ rv = find_dc_server(logopt, conn, uri, ctxt); + if (rv == NSS_STATUS_SUCCESS) { + ret = NSS_STATUS_SUCCESS; + free(uri); +@@ -947,7 +940,7 @@ static int find_server(unsigned logopt, + } + + uris_mutex_lock(ctxt); +- if (ldap) ++ if (conn->ldap) + ctxt->uri = this; + if (dclist) { + if (!ctxt->dclist) +@@ -965,37 +958,39 @@ static int find_server(unsigned logopt, + } + + static int do_reconnect(unsigned logopt, +- LDAP **ldap, struct lookup_context *ctxt) ++ struct ldap_conn *conn, struct lookup_context *ctxt) + { + int ret = NSS_STATUS_UNAVAIL; + int dcrv = NSS_STATUS_SUCCESS; + int rv = NSS_STATUS_SUCCESS; + ++ ldapinit_mutex_lock(); + if (ctxt->server || !ctxt->uris) { +- ret = do_connect(logopt, ldap, ctxt->server, ctxt); ++ ret = do_connect(logopt, conn, ctxt->server, ctxt); + #ifdef WITH_SASL + /* Dispose of the sasl authentication connection and try again. */ + if (ctxt->auth_required & LDAP_NEED_AUTH && + ret != NSS_STATUS_SUCCESS && ret != NSS_STATUS_NOTFOUND) { +- ldapinit_mutex_lock(); +- autofs_sasl_dispose(*ldap, ctxt); +- ldapinit_mutex_unlock(); +- ret = connect_to_server(logopt, ldap, ++ autofs_sasl_dispose(conn, ctxt); ++ ret = connect_to_server(logopt, conn, + ctxt->server, ctxt); + } + #endif ++ ldapinit_mutex_unlock(); + return ret; + } + + if (ctxt->dclist) { +- dcrv = find_dc_server(logopt, ldap, ctxt->dclist->uri, ctxt); +- if (dcrv == NSS_STATUS_SUCCESS) ++ dcrv = find_dc_server(logopt, conn, ctxt->dclist->uri, ctxt); ++ if (dcrv == NSS_STATUS_SUCCESS) { ++ ldapinit_mutex_unlock(); + return dcrv; ++ } + } + + uris_mutex_lock(ctxt); + if (ctxt->dclist) { +- if (!ldap || ctxt->dclist->expire < time(NULL)) { ++ if (!conn->ldap || ctxt->dclist->expire < time(NULL)) { + free_dclist(ctxt->dclist); + ctxt->dclist = NULL; + } +@@ -1009,7 +1004,7 @@ static int do_reconnect(unsigned logopt, + if (!ctxt->uri) + goto find_server; + +- rv = do_connect(logopt, ldap, ctxt->uri->uri, ctxt); ++ rv = do_connect(logopt, conn, ctxt->uri->uri, ctxt); + #ifdef WITH_SASL + /* + * Dispose of the sasl authentication connection and try the +@@ -1017,26 +1012,24 @@ static int do_reconnect(unsigned logopt, + */ + if (ctxt->auth_required & LDAP_NEED_AUTH && + rv != NSS_STATUS_SUCCESS && rv != NSS_STATUS_NOTFOUND) { +- ldapinit_mutex_lock(); +- autofs_sasl_dispose(*ldap, ctxt); +- ldapinit_mutex_unlock(); +- rv = connect_to_server(logopt, ldap, ctxt->uri->uri, ctxt); ++ autofs_sasl_dispose(conn, ctxt); ++ rv = connect_to_server(logopt, conn, ctxt->uri->uri, ctxt); + } + #endif +- if (rv == NSS_STATUS_SUCCESS) ++ if (rv == NSS_STATUS_SUCCESS) { ++ ldapinit_mutex_unlock(); + return rv; ++ } + + /* Failed to connect, try to find a new server */ + + find_server: + #ifdef WITH_SASL +- ldapinit_mutex_lock(); +- autofs_sasl_dispose(*ldap, ctxt); +- ldapinit_mutex_unlock(); ++ autofs_sasl_dispose(conn, ctxt); + #endif + + /* Current server failed, try the rest or dc connection */ +- ret = find_server(logopt, ldap, ctxt); ++ ret = find_server(logopt, conn, ctxt); + if (ret != NSS_STATUS_SUCCESS) { + if (ret == NSS_STATUS_NOTFOUND || + dcrv == NSS_STATUS_NOTFOUND || +@@ -1044,6 +1037,7 @@ find_server: + ret = NSS_STATUS_NOTFOUND; + error(logopt, MODPREFIX "failed to find available server"); + } ++ ldapinit_mutex_unlock(); + + return ret; + } +@@ -1877,11 +1871,6 @@ int lookup_reinit(const char *mapfmt, + + *context = new; + +-#ifdef WITH_SASL +- ldapinit_mutex_lock(); +- autofs_sasl_dispose(NULL, ctxt); +- ldapinit_mutex_unlock(); +-#endif + free_context(ctxt); + + return 0; +@@ -1893,6 +1882,8 @@ int lookup_read_master(struct master *ma + unsigned int timeout = master->default_timeout; + unsigned int logging = master->default_logging; + unsigned int logopt = master->logopt; ++ struct ldap_conn conn; ++ LDAP *ldap; + int rv, l, count; + char buf[MAX_ERR_BUF]; + char parse_buf[PARSE_MAX_BUF]; +@@ -1903,12 +1894,13 @@ int lookup_read_master(struct master *ma + char **values = NULL; + char *attrs[3]; + int scope = LDAP_SCOPE_SUBTREE; +- LDAP *ldap = NULL; + + /* Initialize the LDAP context. */ +- rv = do_reconnect(logopt, &ldap, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_reconnect(logopt, &conn, ctxt); + if (rv) + return rv; ++ ldap = conn.ldap; + + class = ctxt->schema->entry_class; + entry = ctxt->schema->entry_attr; +@@ -1942,7 +1934,7 @@ int lookup_read_master(struct master *ma + if ((rv != LDAP_SUCCESS) || !result) { + error(logopt, MODPREFIX "query failed for %s: %s", + query, ldap_err2string(rv)); +- unbind_ldap_connection(logging, ldap, ctxt); ++ unbind_ldap_connection(logging, &conn, ctxt); + if (result) + ldap_msgfree(result); + free(query); +@@ -1955,7 +1947,7 @@ int lookup_read_master(struct master *ma + MODPREFIX "query succeeded, no matches for %s", + query); + ldap_msgfree(result); +- unbind_ldap_connection(logging, ldap, ctxt); ++ unbind_ldap_connection(logging, &conn, ctxt); + free(query); + return NSS_STATUS_NOTFOUND; + } else +@@ -2076,7 +2068,7 @@ next: + + /* Clean up. */ + ldap_msgfree(result); +- unbind_ldap_connection(logopt, ldap, ctxt); ++ unbind_ldap_connection(logopt, &conn, ctxt); + free(query); + + return NSS_STATUS_SUCCESS; +@@ -2796,6 +2788,7 @@ static int read_one_map(struct autofs_po + struct lookup_context *ctxt, + time_t age, int *result_ldap) + { ++ struct ldap_conn conn; + struct ldap_search_params sp; + char buf[MAX_ERR_BUF]; + char *class, *info, *entry; +@@ -2816,10 +2809,11 @@ static int read_one_map(struct autofs_po + sp.age = age; + + /* Initialize the LDAP context. */ +- sp.ldap = NULL; +- rv = do_reconnect(ap->logopt, &sp.ldap, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_reconnect(ap->logopt, &conn, ctxt); + if (rv) + return rv; ++ sp.ldap = conn.ldap; + + class = ctxt->schema->entry_class; + entry = ctxt->schema->entry_attr; +@@ -2878,7 +2872,7 @@ static int read_one_map(struct autofs_po + if (sp.pageSize < 5) { + debug(ap->logopt, MODPREFIX + "result size too small"); +- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + *result_ldap = rv; + free(sp.query); + return NSS_STATUS_UNAVAIL; +@@ -2887,7 +2881,7 @@ static int read_one_map(struct autofs_po + } + + if (rv != LDAP_SUCCESS || !sp.result) { +- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + *result_ldap = rv; + if (sp.result) + ldap_msgfree(sp.result); +@@ -2903,7 +2897,7 @@ static int read_one_map(struct autofs_po + rv = do_get_entries(&sp, source, ctxt); + if (rv != LDAP_SUCCESS) { + ldap_msgfree(sp.result); +- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + *result_ldap = rv; + if (sp.cookie) + ber_bvfree(sp.cookie); +@@ -2916,7 +2910,7 @@ static int read_one_map(struct autofs_po + + debug(ap->logopt, MODPREFIX "done updating map"); + +- unbind_ldap_connection(ap->logopt, sp.ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + + source->age = age; + if (sp.cookie) +@@ -2959,6 +2953,8 @@ static int lookup_one(struct autofs_poin + char *qKey, int qKey_len, struct lookup_context *ctxt) + { + struct mapent_cache *mc; ++ struct ldap_conn conn; ++ LDAP *ldap; + int rv, i, l, ql, count; + char buf[MAX_ERR_BUF]; + time_t age = time(NULL); +@@ -2971,7 +2967,6 @@ static int lookup_one(struct autofs_poin + struct berval **bvValues; + char *attrs[3]; + int scope = LDAP_SCOPE_SUBTREE; +- LDAP *ldap = NULL; + struct mapent *we; + unsigned int wild = 0; + int ret = CHE_MISSING; +@@ -2984,11 +2979,13 @@ static int lookup_one(struct autofs_poin + } + + /* Initialize the LDAP context. */ +- rv = do_reconnect(ap->logopt, &ldap, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_reconnect(ap->logopt, &conn, ctxt); + if (rv == NSS_STATUS_UNAVAIL) + return CHE_UNAVAIL; + if (rv == NSS_STATUS_NOTFOUND) + return ret; ++ ldap = conn.ldap; + + class = ctxt->schema->entry_class; + entry = ctxt->schema->entry_attr; +@@ -3076,7 +3073,7 @@ static int lookup_one(struct autofs_poin + + if ((rv != LDAP_SUCCESS) || !result) { + crit(ap->logopt, MODPREFIX "query failed for %s", query); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + if (result) + ldap_msgfree(result); + free(query); +@@ -3091,7 +3088,7 @@ static int lookup_one(struct autofs_poin + debug(ap->logopt, + MODPREFIX "got answer, but no entry for %s", query); + ldap_msgfree(result); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + free(query); + return CHE_MISSING; + } +@@ -3277,7 +3274,7 @@ next: + } + + ldap_msgfree(result); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + + /* Failed to find wild entry, update cache if needed */ + cache_writelock(mc); +@@ -3317,7 +3314,8 @@ static int lookup_one_amd(struct autofs_ + struct lookup_context *ctxt) + { + struct mapent_cache *mc = source->mc; +- LDAP *ldap = NULL; ++ struct ldap_conn conn; ++ LDAP *ldap; + LDAPMessage *result = NULL, *e; + char *query; + int scope = LDAP_SCOPE_SUBTREE; +@@ -3336,11 +3334,13 @@ static int lookup_one_amd(struct autofs_ + } + + /* Initialize the LDAP context. */ +- rv = do_reconnect(ap->logopt, &ldap, ctxt); ++ memset(&conn, 0, sizeof(struct ldap_conn)); ++ rv = do_reconnect(ap->logopt, &conn, ctxt); + if (rv == NSS_STATUS_UNAVAIL) + return CHE_UNAVAIL; + if (rv == NSS_STATUS_NOTFOUND) + return ret; ++ ldap = conn.ldap; + + map = ctxt->schema->map_attr; + class = ctxt->schema->entry_class; +@@ -3382,7 +3382,7 @@ static int lookup_one_amd(struct autofs_ + rv = ldap_search_s(ldap, ctxt->base, scope, query, attrs, 0, &result); + if ((rv != LDAP_SUCCESS) || !result) { + crit(ap->logopt, MODPREFIX "query failed for %s", query); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + if (result) + ldap_msgfree(result); + free(query); +@@ -3397,7 +3397,7 @@ static int lookup_one_amd(struct autofs_ + debug(ap->logopt, + MODPREFIX "got answer, but no entry for %s", query); + ldap_msgfree(result); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + free(query); + return CHE_MISSING; + } +@@ -3459,7 +3459,7 @@ next: + } + + ldap_msgfree(result); +- unbind_ldap_connection(ap->logopt, ldap, ctxt); ++ unbind_ldap_connection(ap->logopt, &conn, ctxt); + free(query); + + return ret; diff --git a/SOURCES/autofs-5.1.1-fix-typo-in-autofs_sasl_bind.patch b/SOURCES/autofs-5.1.1-fix-typo-in-autofs_sasl_bind.patch new file mode 100644 index 0000000..7e138c1 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-typo-in-autofs_sasl_bind.patch @@ -0,0 +1,33 @@ +autofs-5.1.1 - fix typo in autofs_sasl_bind() + +From: Ian Kent + +Changes to autofs_sasl_bind() introduced an incorrect variable reference. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/cyrus-sasl.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -202,6 +202,7 @@ + - fix memory leak in ldap do_init(). + - fix use after free in sun parser parse_init(). + - fix use after free in open_lookup(). ++- fix typo in autofs_sasl_bind(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/cyrus-sasl.c ++++ autofs-5.0.7/modules/cyrus-sasl.c +@@ -928,7 +928,7 @@ autofs_sasl_bind(unsigned logopt, + else + sasl_conn = sasl_choose_mech(logopt, conn->ldap, ctxt); + +- if (!conn) ++ if (!sasl_conn) + return -1; + + conn->sasl_conn = sasl_conn; diff --git a/SOURCES/autofs-5.1.1-fix-unbind-external-mech.patch b/SOURCES/autofs-5.1.1-fix-unbind-external-mech.patch new file mode 100644 index 0000000..a01cdaf --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-unbind-external-mech.patch @@ -0,0 +1,132 @@ +autofs-5.1.1 - fix unbind sasl external mech + +From: Ian Kent + +If the sasl EXTERNAL mechanism is being used autofs leaks ldap +connection resources. + +In this case the current ldap connection needs to be unbound +when calling autofs_sasl_unbind() or autofs_sasl_dispose(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/lookup_ldap.h | 4 ++-- + modules/cyrus-sasl.c | 15 +++++++++++++-- + modules/lookup_ldap.c | 12 ++++++------ + 4 files changed, 22 insertions(+), 10 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -196,6 +196,7 @@ + - fix missing source sss in multi map lookup. + - fix update_hosts_mounts() return. + - change lookup to use reinit instead of reopen. ++- fix unbind sasl external mech. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/lookup_ldap.h ++++ autofs-5.0.7/include/lookup_ldap.h +@@ -121,8 +121,8 @@ int authtype_requires_creds(const char * + int autofs_sasl_client_init(unsigned logopt); + int autofs_sasl_init(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt); + int autofs_sasl_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt); +-void autofs_sasl_unbind(struct lookup_context *ctxt); +-void autofs_sasl_dispose(struct lookup_context *ctxt); ++void autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt); ++void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt); + void autofs_sasl_done(void); + /* cyrus-sasl-extern */ + int do_sasl_extern(LDAP *ldap, struct lookup_context *ctxt); +--- autofs-5.0.7.orig/modules/cyrus-sasl.c ++++ autofs-5.0.7/modules/cyrus-sasl.c +@@ -855,8 +855,13 @@ sasl_choose_mech(unsigned logopt, LDAP * + * Routine called when unbinding an ldap connection. + */ + void +-autofs_sasl_unbind(struct lookup_context *ctxt) ++autofs_sasl_unbind(LDAP *ldap, struct lookup_context *ctxt) + { ++ if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { ++ ldap_unbind_s(ldap); ++ return; ++ } ++ + if (ctxt->sasl_conn) { + sasl_dispose(&ctxt->sasl_conn); + ctxt->sasl_conn = NULL; +@@ -933,10 +938,16 @@ autofs_sasl_bind(unsigned logopt, LDAP * + * Destructor routine. This should be called when finished with an ldap + * session. + */ +-void autofs_sasl_dispose(struct lookup_context *ctxt) ++void autofs_sasl_dispose(LDAP *ldap, struct lookup_context *ctxt) + { + int status, ret; + ++ if (ctxt->sasl_mech && !strncmp(ctxt->sasl_mech, "EXTERNAL", 8)) { ++ if (ldap) ++ ldap_unbind_s(ldap); ++ return; ++ } ++ + if (ctxt->sasl_conn) { + sasl_dispose(&ctxt->sasl_conn); + ctxt->sasl_conn = NULL; +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -222,7 +222,7 @@ int __unbind_ldap_connection(unsigned lo + ctxt->use_tls = LDAP_TLS_INIT; + #ifdef WITH_SASL + if (ctxt->auth_required & LDAP_NEED_AUTH) +- autofs_sasl_unbind(ctxt); ++ autofs_sasl_unbind(ldap, ctxt); + else + rv = ldap_unbind_ext(ldap, NULL, NULL); + #else +@@ -978,7 +978,7 @@ static int do_reconnect(unsigned logopt, + if (ctxt->auth_required & LDAP_NEED_AUTH && + ret != NSS_STATUS_SUCCESS && ret != NSS_STATUS_NOTFOUND) { + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(*ldap, ctxt); + ldapinit_mutex_unlock(); + ret = connect_to_server(logopt, ldap, + ctxt->server, ctxt); +@@ -1018,7 +1018,7 @@ static int do_reconnect(unsigned logopt, + if (ctxt->auth_required & LDAP_NEED_AUTH && + rv != NSS_STATUS_SUCCESS && rv != NSS_STATUS_NOTFOUND) { + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(*ldap, ctxt); + ldapinit_mutex_unlock(); + rv = connect_to_server(logopt, ldap, ctxt->uri->uri, ctxt); + } +@@ -1031,7 +1031,7 @@ static int do_reconnect(unsigned logopt, + find_server: + #ifdef WITH_SASL + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(*ldap, ctxt); + ldapinit_mutex_unlock(); + #endif + +@@ -1879,7 +1879,7 @@ int lookup_reinit(const char *mapfmt, + + #ifdef WITH_SASL + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(NULL, ctxt); + ldapinit_mutex_unlock(); + #endif + free_context(ctxt); +@@ -3816,7 +3816,7 @@ int lookup_done(void *context) + int rv = close_parse(ctxt->parse); + #ifdef WITH_SASL + ldapinit_mutex_lock(); +- autofs_sasl_dispose(ctxt); ++ autofs_sasl_dispose(NULL, ctxt); + autofs_sasl_done(); + ldapinit_mutex_unlock(); + #endif diff --git a/SOURCES/autofs-5.1.1-fix-update_hosts_mounts-return.patch b/SOURCES/autofs-5.1.1-fix-update_hosts_mounts-return.patch new file mode 100644 index 0000000..d2c9b34 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-update_hosts_mounts-return.patch @@ -0,0 +1,55 @@ +autofs-5.1.1 - fix update_hosts_mounts() return + +From: Ian Kent + +The return of update_hosts_mounts() isn't used so set it to void type +and log a warning if the map entry fails the parse. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_hosts.c | 11 ++++++----- + 2 files changed, 7 insertions(+), 5 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -194,6 +194,7 @@ + - fix error handling on ldap bind fail. + - fix gcc5 complaints. + - fix missing source sss in multi map lookup. ++- fix update_hosts_mounts() return. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_hosts.c ++++ autofs-5.0.7/modules/lookup_hosts.c +@@ -162,9 +162,9 @@ static int do_parse_mount(struct autofs_ + return NSS_STATUS_SUCCESS; + } + +-static int update_hosts_mounts(struct autofs_point *ap, +- struct map_source *source, time_t age, +- struct lookup_context *ctxt) ++static void update_hosts_mounts(struct autofs_point *ap, ++ struct map_source *source, time_t age, ++ struct lookup_context *ctxt) + { + struct mapent_cache *mc; + struct mapent *me; +@@ -212,13 +212,14 @@ next: + ap->flags |= MOUNT_FLAG_REMOUNT; + ret = ctxt->parse->parse_mount(ap, me->key, strlen(me->key), + me->mapent, ctxt->parse->context); ++ if (ret) ++ warn(ap->logopt, MODPREFIX ++ "failed to parse mount %s", me->mapent); + ap->flags &= ~MOUNT_FLAG_REMOUNT; + cont: + me = cache_lookup_next(mc, me); + } + pthread_cleanup_pop(1); +- +- return NSS_STATUS_SUCCESS; + } + + int lookup_read_map(struct autofs_point *ap, time_t age, void *context) diff --git a/SOURCES/autofs-5.1.1-fix-use-after-free-in-open_lookup.patch b/SOURCES/autofs-5.1.1-fix-use-after-free-in-open_lookup.patch new file mode 100644 index 0000000..20a2bfe --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-use-after-free-in-open_lookup.patch @@ -0,0 +1,32 @@ +autofs-5.1.1 - fix use after free in open_lookup() + +From: Ian Kent + +If storage can't be allocated for module type error exit. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/module.c | 1 + + 2 files changed, 2 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -201,6 +201,7 @@ + - fix memory leak in nisplus lookup_reinit(). + - fix memory leak in ldap do_init(). + - fix use after free in sun parser parse_init(). ++- fix use after free in open_lookup(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/module.c ++++ autofs-5.0.7/daemon/module.c +@@ -83,6 +83,7 @@ int open_lookup(const char *name, const + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("%s%s", err_prefix, estr); + } ++ return NSS_STATUS_UNAVAIL; + } + + size = snprintf(fnbuf, sizeof(fnbuf), diff --git a/SOURCES/autofs-5.1.1-fix-use-after-free-in-sun-parser-parse_init.patch b/SOURCES/autofs-5.1.1-fix-use-after-free-in-sun-parser-parse_init.patch new file mode 100644 index 0000000..32211d9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-use-after-free-in-sun-parser-parse_init.patch @@ -0,0 +1,33 @@ +autofs-5.1.1 - fix use after free in sun parser parse_init() + +From: Ian Kent + +Change to free context in function it was allocated (parse_init) on +error to avoid use after free. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/parse_sun.c | 1 - + 2 files changed, 1 insertion(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -200,6 +200,7 @@ + - fix sasl connection concurrancy problem. + - fix memory leak in nisplus lookup_reinit(). + - fix memory leak in ldap do_init(). ++- fix use after free in sun parser parse_init(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/parse_sun.c ++++ autofs-5.0.7/modules/parse_sun.c +@@ -345,7 +345,6 @@ static int do_init(int argc, const char + } + if (!noptstr) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- kill_context(ctxt); + logerr(MODPREFIX "%s", estr); + return 1; + } diff --git a/SOURCES/autofs-5.1.1-fix-use-after-free-st_queue_handler.patch b/SOURCES/autofs-5.1.1-fix-use-after-free-st_queue_handler.patch new file mode 100644 index 0000000..207c80c --- /dev/null +++ b/SOURCES/autofs-5.1.1-fix-use-after-free-st_queue_handler.patch @@ -0,0 +1,37 @@ +autofs-5.1.1 - fix use-after-free in st_queue_handler() + +From: Frank Sorenson + +The task may be referenced after being freed. Move the +free to after the list_del_init. + +Signed-off-by: Frank Sorenson +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/state.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -204,6 +204,7 @@ + - fix use after free in open_lookup(). + - fix typo in autofs_sasl_bind(). + - add configuration option to use fqdn in mounts. ++- fix use-after-free in st_queue_handler(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/state.c ++++ autofs-5.0.7/daemon/state.c +@@ -1179,9 +1179,9 @@ remove: + struct state_queue, pending); + + list_del(&task->list); ++ list_del_init(&next->pending); + free(task); + +- list_del_init(&next->pending); + list_add_tail(&next->list, head); + if (p == head) + p = head->next; diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-file-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-file-lookup-module.patch new file mode 100644 index 0000000..fae1f5f --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-file-lookup-module.patch @@ -0,0 +1,147 @@ +autofs-5.1.1 - implement reinit in file lookup module + +From: Ian Kent + +Refactor the file lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_file.c | 85 +++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 65 insertions(+), 20 deletions(-) + +diff --git a/modules/lookup_file.c b/modules/lookup_file.c +index c32a4cd..aed3cba 100644 +--- a/modules/lookup_file.c ++++ b/modules/lookup_file.c +@@ -50,23 +50,13 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; +- +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } ++ int ret = 0; + + if (argc < 1) { +- free(ctxt); + logerr(MODPREFIX "No map name"); + return 1; + } +@@ -74,14 +64,12 @@ int lookup_init(const char *mapfmt, + ctxt->mapname = argv[0]; + + if (ctxt->mapname[0] != '/') { +- free(ctxt); + logmsg(MODPREFIX + "file map %s is not an absolute pathname", argv[0]); + return 1; + } + + if (access(ctxt->mapname, R_OK)) { +- free(ctxt); + warn(LOGOPT_NONE, MODPREFIX + "file map %s missing or not readable", argv[0]); + return 1; +@@ -95,19 +83,51 @@ int lookup_init(const char *mapfmt, + + ctxt->opts_argv = copy_argv(argc, (const char **) argv); + if (ctxt->opts_argv == NULL) { +- free(ctxt); + warn(LOGOPT_NONE, MODPREFIX "failed to duplicate options"); + return 1; + } + ctxt->opts_argc = argc; + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv); +- if (!ctxt->parse) { ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc, argv); ++ if (!ctxt->parse) { ++ logmsg(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++ ++ if (ret) + free_argv(ctxt->opts_argc, ctxt->opts_argv); ++ ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { + free(ctxt); +- logmsg(MODPREFIX "failed to open parse context"); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -116,6 +136,31 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++ free_argv(ctxt->opts_argc, ctxt->opts_argv); ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch new file mode 100644 index 0000000..1f060b9 --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch @@ -0,0 +1,154 @@ +autofs-5.1.1 - implement reinit in hesiod lookup module + +From: Ian Kent + +Refactor the hesiod lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_hesiod.c | 96 ++++++++++++++++++++++++++++++++++++----------- + 1 file changed, 74 insertions(+), 22 deletions(-) + +diff --git a/modules/lookup_hesiod.c b/modules/lookup_hesiod.c +index de5ec08..c0f7f51 100644 +--- a/modules/lookup_hesiod.c ++++ b/modules/lookup_hesiod.c +@@ -37,24 +37,12 @@ static pthread_mutex_t hesiod_mutex = PTHREAD_MUTEX_INITIALIZER; + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-/* This initializes a context (persistent non-global data) for queries to +- this module. */ +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt = NULL; + char buf[MAX_ERR_BUF]; +- +- *context = NULL; +- +- /* If we can't build a context, bail. */ +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } +- memset(ctxt, 0, sizeof(struct lookup_context)); ++ int ret = 0; + + /* Initialize the resolver. */ + res_init(); +@@ -63,7 +51,6 @@ int lookup_init(const char *mapfmt, + if (hesiod_init(&(ctxt->hesiod_context)) != 0) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "hesiod_init(): %s", estr); +- free(ctxt); + return 1; + } + +@@ -75,9 +62,9 @@ int lookup_init(const char *mapfmt, + /* amd formated hesiod maps have a map name */ + const char *mapname = argv[0]; + if (strncmp(mapname, AMD_MAP_PREFIX, AMD_MAP_PREFIX_LEN)) { ++ hesiod_end(ctxt->hesiod_context); + logerr(MODPREFIX + "incorrect prefix for hesiod map %s", mapname); +- free(ctxt); + return 1; + } + ctxt->mapname = mapname; +@@ -85,13 +72,52 @@ int lookup_init(const char *mapfmt, + argv++; + } + +- /* Open the parser, if we can. */ +- ctxt->parser = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parser) { +- logerr(MODPREFIX "failed to open parse context"); ++ if (reinit) { ++ ret = reinit_parse(ctxt->parser, mapfmt, ++ MODPREFIX, argc - 1, argv - 1); ++ if (ret) ++ logerr(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parser = open_parse(mapfmt, ++ MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parser) { ++ logerr(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++ ++ if (ret) ++ hesiod_end(ctxt->hesiod_context); ++ ++ return ret; ++} ++ ++/* This initializes a context (persistent non-global data) for queries to ++ this module. */ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ *context = NULL; ++ ++ /* If we can't build a context, bail. */ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ ret = do_init(mapfmt, argc, argv, ctxt, 0); ++ if (ret) { + free(ctxt); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -100,6 +126,32 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ /* If we can't build a context, bail. */ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parser = ctxt->parser; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++ hesiod_end(ctxt->hesiod_context); ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch new file mode 100644 index 0000000..4180980 --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch @@ -0,0 +1,40 @@ +autofs-5.1.1 - implement reinit in hosts lookup module + +From: Ian Kent + +Refactor the hosts lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_hosts.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c +index 8ba0a4a..0a64655 100644 +--- a/modules/lookup_hosts.c ++++ b/modules/lookup_hosts.c +@@ -69,6 +69,7 @@ int lookup_init(const char *mapfmt, + free(ctxt); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -77,6 +78,15 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ int ret; ++ ++ mapfmt = MAPFMT_DEFAULT; ++ ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv); ++ if (ret) ++ return 1; ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch new file mode 100644 index 0000000..23214bd --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch @@ -0,0 +1,216 @@ +autofs-5.1.1 - implement reinit in ldap lookup module + +From: Ian Kent + +Refactor the ldap lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_ldap.c | 109 +++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 77 insertions(+), 32 deletions(-) + +diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c +index 0f5bc48..578d6c6 100644 +--- a/modules/lookup_ldap.c ++++ b/modules/lookup_ldap.c +@@ -1683,39 +1683,23 @@ static void validate_uris(struct list_head *list) + return; + } + +-/* +- * This initializes a context (persistent non-global data) for queries to +- * this module. Return zero if we succeed. +- */ +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { + unsigned int is_amd_format; +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; + int ret; + +- *context = NULL; +- +- /* If we can't build a context, bail. */ +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, sizeof(buf)); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } +- memset(ctxt, 0, sizeof(struct lookup_context)); +- + ret = pthread_mutex_init(&ctxt->uris_mutex, NULL); + if (ret) { + error(LOGOPT_ANY, MODPREFIX "failed to init uris mutex"); +- free(ctxt); + return 1; + } + + /* If a map type isn't explicitly given, parse it like sun entries. */ + if (mapfmt == NULL) + mapfmt = MAPFMT_DEFAULT; ++ + is_amd_format = 0; + if (!strcmp(mapfmt, "amd")) { + is_amd_format = 1; +@@ -1733,7 +1717,6 @@ int lookup_init(const char *mapfmt, + */ + if (!parse_server_string(LOGOPT_NONE, argv[0], ctxt)) { + error(LOGOPT_ANY, MODPREFIX "cannot parse server string"); +- free_context(ctxt); + return 1; + } + +@@ -1758,7 +1741,6 @@ int lookup_init(const char *mapfmt, + char *tmp = conf_amd_get_ldap_base(); + if (!tmp) { + error(LOGOPT_ANY, MODPREFIX "failed to get base dn"); +- free_context(ctxt); + return 1; + } + ctxt->base = tmp; +@@ -1767,7 +1749,6 @@ int lookup_init(const char *mapfmt, + if (!tmp) { + error(LOGOPT_ANY, + MODPREFIX "failed to get ldap_hostports"); +- free_context(ctxt); + return 1; + } + +@@ -1777,21 +1758,18 @@ int lookup_init(const char *mapfmt, + */ + if (!parse_server_string(LOGOPT_NONE, tmp, ctxt)) { + error(LOGOPT_ANY, MODPREFIX "cannot parse server string"); +- free_context(ctxt); + return 1; + } + free(tmp); + + if (!ctxt->server) { + error(LOGOPT_ANY, MODPREFIX "ldap_hostports not valid"); +- free_context(ctxt); + return 1; + } + + tmp = strdup(argv[0]); + if (!tmp) { + error(LOGOPT_ANY, MODPREFIX "failed to set mapname"); +- free_context(ctxt); + return 1; + } + ctxt->mapname = tmp; +@@ -1805,7 +1783,7 @@ int lookup_init(const char *mapfmt, + */ + ret = parse_ldap_config(LOGOPT_NONE, ctxt); + if (ret) { +- free_context(ctxt); ++ error(LOGOPT_ANY, MODPREFIX "failed to parse ldap config"); + return 1; + } + +@@ -1815,7 +1793,6 @@ int lookup_init(const char *mapfmt, + if (!autofs_sasl_client_init(LOGOPT_NONE)) { + error(LOGOPT_ANY, "failed to init sasl client"); + ldapinit_mutex_unlock(); +- free_context(ctxt); + return 1; + } + ldapinit_mutex_unlock(); +@@ -1824,13 +1801,51 @@ int lookup_init(const char *mapfmt, + if (is_amd_format) + ctxt->timestamp = get_amd_timestamp(ctxt); + +- /* Open the parser, if we can. */ +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, ++ mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ /* Open the parser, if we can. */ ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logerr(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++ ++ return ret; ++} ++ ++/* ++ * This initializes a context (persistent non-global data) for queries to ++ * this module. Return zero if we succeed. ++ */ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ *context = NULL; ++ ++ /* If we can't build a context, bail. */ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ ret = do_init(mapfmt, argc, argv, ctxt, 0); ++ if (ret) { + free_context(ctxt); +- logerr(MODPREFIX "failed to open parse context"); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -1839,6 +1854,36 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ /* If we can't build a context, bail. */ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, sizeof(buf)); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free_context(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++#ifdef WITH_SASL ++ ldapinit_mutex_lock(); ++ autofs_sasl_dispose(ctxt); ++ ldapinit_mutex_unlock(); ++#endif ++ free_context(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch new file mode 100644 index 0000000..bb669fa --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch @@ -0,0 +1,265 @@ +autofs-5.1.1 - implement reinit in multi lookup module + +From: Ian Kent + +Update the multi lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_multi.c | 228 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 227 insertions(+), 1 deletion(-) + +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index f8ebf94..fadd2ea 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -146,6 +146,31 @@ static int free_multi_context(struct lookup_context *ctxt) + return rv; + } + ++static struct lookup_context *update_multi_context(struct lookup_context *ctxt, ++ struct lookup_context *new) ++{ ++ int i; ++ ++ for (i = 0; i < new->n && i < ctxt->n; i++) { ++ if (new->m[i].mod) ++ continue; ++ ++ if (!ctxt->m[i].mod) ++ continue; ++ ++ /* reinit or open failed, use old one, questionable but ++ * we need to do something. ++ */ ++ new->m[i].mod = ctxt->m[i].mod; ++ ctxt->m[i].mod = NULL; ++ new->m[i].argc = ctxt->m[i].argc; ++ new->m[i].argv = ctxt->m[i].argv; ++ ctxt->m[i].argv = NULL; ++ } ++ ++ return new; ++} ++ + static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv) + { + struct list_head nsslist; +@@ -268,6 +293,8 @@ int lookup_init(const char *my_mapfmt, + struct lookup_context *ctxt; + int i; + ++ *context = NULL; ++ + ctxt = alloc_context(my_mapfmt, argc, argv); + if (!ctxt) + return 1; +@@ -291,7 +318,206 @@ int lookup_init(const char *my_mapfmt, + int lookup_reinit(const char *my_mapfmt, + int argc, const char *const *argv, void **context) + { +- return 0; ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct list_head nsslist; ++ struct list_head *head, *p; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF], *estr; ++ int i, ret = 0; ++ int status; ++ ++ new = alloc_context(my_mapfmt, argc, argv); ++ if (!new) ++ return 1; ++ ++ for (i = 0; i < new->n; i++) { ++ if (i >= ctxt->n) { ++ new->m[i].mod = nss_open_lookup(my_mapfmt, ++ new->m[i].argc, ++ new->m[i].argv); ++ if (!new->m[i].mod) { ++ logerr(MODPREFIX "error opening module"); ++ /* TODO: check */ ++ ret = 1; ++ goto out; ++ } ++ continue; ++ } ++ ++ if (*new->m[i].argv[0] == '/') { ++ if (strcmp(new->m[i].argv[0], ctxt->m[i].argv[0])) ++ open_lookup("file", MODPREFIX, ++ my_mapfmt, ++ new->m[i].argc, ++ new->m[i].argv, ++ &new->m[i].mod); ++ else { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, "file", ++ MODPREFIX, my_mapfmt, ++ new->m[i].argc, new->m[i].argv)) ++ new->m[i].mod = NULL; ++ else ++ ctxt->m[i].mod = NULL; ++ } ++ continue; ++ } ++ ++ if (!strncmp(new->m[i].argv[0], "file", 4) || ++ !strncmp(new->m[i].argv[0], "yp", 2) || ++ !strncmp(new->m[i].argv[0], "nisplus", 7) || ++ !strncmp(new->m[i].argv[0], "nis", 3) || ++ !strncmp(new->m[i].argv[0], "ldaps", 5) || ++ !strncmp(new->m[i].argv[0], "ldap", 4) || ++ !strncmp(new->m[i].argv[0], "sss", 3)) { ++ char type[MAX_MAP_TYPE_STRING]; ++ char *fmt; ++ ++ strcpy(type, new->m[i].argv[0]); ++ fmt = strchr(type, ','); ++ if (!fmt) ++ fmt = (char *) my_mapfmt; ++ else { ++ *fmt = '\0'; ++ fmt++; ++ } ++ ++ if (!strcmp(new->m[i].argv[0], ctxt->m[i].argv[0]) && ++ !strcmp(new->m[i].argv[1], ctxt->m[i].argv[1])) { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, new->m[i].argv[0], ++ MODPREFIX, fmt, ++ new->m[i].argc - 1, new->m[i].argv + 1)) ++ new->m[i].mod = NULL; ++ else ++ ctxt->m[i].mod = NULL; ++ } else { ++ open_lookup(type, MODPREFIX, fmt, ++ new->m[i].argc - 1, ++ new->m[i].argv + 1, ++ &new->m[i].mod); ++ } ++ continue; ++ } ++ ++ INIT_LIST_HEAD(&nsslist); ++ ++ if (nsswitch_parse(&nsslist)) { ++ if (!list_empty(&nsslist)) ++ free_sources(&nsslist); ++ logerr("can't to read name service switch config."); ++ /* TODO: check */ ++ ret = 1; ++ goto out; ++ } ++ ++ head = &nsslist; ++ list_for_each(p, head) { ++ struct nss_source *this; ++ ++ this = list_entry(p, struct nss_source, list); ++ ++ if (!strcmp(this->source, ctxt->m[i].mod->type)) { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, this->source, ++ MODPREFIX, my_mapfmt, ++ new->m[i].argc, new->m[i].argv)) ++ new->m[i].mod = NULL; ++ else ++ ctxt->m[i].mod = NULL; ++ continue; ++ } ++ ++ if (!strcmp(this->source, "files")) { ++ char src_file[] = "file"; ++ char src_prog[] = "program"; ++ struct stat st; ++ char *type, *path, *save_argv0; ++ ++ path = malloc(strlen(AUTOFS_MAP_DIR) + ++ strlen(new->m[i].argv[0]) + 2); ++ if (!path) { ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "error: %s", estr); ++ free_sources(&nsslist); ++ ret = 1; ++ goto out; ++ } ++ strcpy(path, AUTOFS_MAP_DIR); ++ strcat(path, "/"); ++ strcat(path, new->m[i].argv[0]); ++ ++ if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) { ++ free(path); ++ continue; ++ } ++ ++ if (st.st_mode & __S_IEXEC) ++ type = src_prog; ++ else ++ type = src_file; ++ ++ save_argv0 = (char *) new->m[i].argv[0]; ++ new->m[i].argv[0] = path; ++ ++ if (strcmp(type, ctxt->m[i].mod->type)) { ++ status = open_lookup(type, ++ MODPREFIX, ++ my_mapfmt, ++ new->m[i].argc, ++ new->m[i].argv, ++ &new->m[i].mod); ++ if (status == NSS_STATUS_SUCCESS) { ++ free(save_argv0); ++ break; ++ } ++ } else { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, type, ++ MODPREFIX, my_mapfmt, ++ new->m[i].argc, new->m[i].argv)) ++ new->m[i].mod = NULL; ++ else { ++ ctxt->m[i].mod = NULL; ++ free(save_argv0); ++ break; ++ } ++ } ++ ++ new->m[i].argv[0] = save_argv0; ++ free(path); ++ continue; ++ } ++ ++ if (strcmp(this->source, ctxt->m[i].mod->type)) { ++ status = open_lookup(this->source, MODPREFIX, ++ my_mapfmt, ++ new->m[i].argc, ++ new->m[i].argv, ++ &new->m[i].mod); ++ if (status == NSS_STATUS_SUCCESS) ++ break; ++ } else { ++ new->m[i].mod = ctxt->m[i].mod; ++ if (reinit_lookup(new->m[i].mod, this->source, ++ MODPREFIX, my_mapfmt, ++ new->m[i].argc, new->m[i].argv)) ++ new->m[i].mod = NULL; ++ else { ++ ctxt->m[i].mod = NULL; ++ break; ++ } ++ } ++ } ++ free_sources(&nsslist); ++ } ++out: ++ /* Update new context with any needed old context */ ++ *context = update_multi_context(ctxt, new); ++ free_multi_context(ctxt); ++ free(ctxt); ++ ++ return ret; + } + + int lookup_read_master(struct master *master, time_t age, void *context) diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch new file mode 100644 index 0000000..eb0eb5c --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch @@ -0,0 +1,133 @@ +autofs-5.1.1 - implement reinit in nisplus lookup module + +From: Ian Kent + +Refactor the nisplus lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_nisplus.c | 83 +++++++++++++++++++++++++++++++++++----------- + 1 file changed, 63 insertions(+), 20 deletions(-) + +diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c +index 0c66152..5fd1d89 100644 +--- a/modules/lookup_nisplus.c ++++ b/modules/lookup_nisplus.c +@@ -30,25 +30,16 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; +- +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "%s", estr); +- return 1; +- } ++ int ret = 0; + + if (argc < 1) { +- free(ctxt); + logmsg(MODPREFIX "No map name"); +- return 1; ++ ret = 1; ++ goto out; + } + ctxt->mapname = argv[0]; + +@@ -58,20 +49,50 @@ int lookup_init(const char *mapfmt, + */ + ctxt->domainname = nis_local_directory(); + if (!ctxt->domainname) { +- free(ctxt); + logmsg(MODPREFIX "NIS+ domain not set"); +- return 1; ++ ret = 1; ++ goto out; + } + + if (!mapfmt) + mapfmt = MAPFMT_DEFAULT; + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc, argv); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logerr(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++out: ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "%s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { + free(ctxt); +- logerr(MODPREFIX "failed to open parse context"); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -80,6 +101,28 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "%s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) ++ return 1; ++ ++ *context = new; ++ ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-parse-modules.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-parse-modules.patch new file mode 100644 index 0000000..b39731b --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-parse-modules.patch @@ -0,0 +1,146 @@ +autofs-5.1.1 - implement reinit in parse modules + +From: Ian Kent + +Refactor the parse modules to add an implementation for the newly added +reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/parse_hesiod.c | 1 + + modules/parse_sun.c | 70 ++++++++++++++++++++++++++++++++++++------------ + 2 files changed, 54 insertions(+), 17 deletions(-) + +diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c +index 0b2b57f..a02da82 100644 +--- a/modules/parse_hesiod.c ++++ b/modules/parse_hesiod.c +@@ -258,6 +258,7 @@ static int parse_generic(struct autofs_point *ap, + + int parse_init(int argc, const char *const *argv, void **context) + { ++ *context = NULL; + return 0; + } + +diff --git a/modules/parse_sun.c b/modules/parse_sun.c +index 35d6da5..a164fba 100644 +--- a/modules/parse_sun.c ++++ b/modules/parse_sun.c +@@ -232,27 +232,15 @@ int expandsunent(const char *src, char *dst, const char *key, + return len; + } + +-int parse_init(int argc, const char *const *argv, void **context) ++static int do_init(int argc, const char *const *argv, struct parse_context *ctxt) + { +- struct parse_context *ctxt; +- char buf[MAX_ERR_BUF]; + char *noptstr, *def, *val, *macros, *gbl_options; +- const char *xopt; ++ char buf[MAX_ERR_BUF]; + int optlen, len, offset; ++ const char *xopt; + int i, bval; + unsigned int append_options; + +- /* Set up context and escape chain */ +- +- if (!(ctxt = (struct parse_context *) malloc(sizeof(struct parse_context)))) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- *context = NULL; +- return 1; +- } +- *context = (void *) ctxt; +- +- *ctxt = default_context; + optlen = 0; + + /* Look for options and capture, and create new defines if we need to */ +@@ -359,7 +347,6 @@ int parse_init(int argc, const char *const *argv, void **context) + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + kill_context(ctxt); + logerr(MODPREFIX "%s", estr); +- *context = NULL; + return 1; + } + ctxt->optstr = noptstr; +@@ -391,9 +378,36 @@ int parse_init(int argc, const char *const *argv, void **context) + } + } + options_done: ++ + debug(LOGOPT_NONE, + MODPREFIX "init gathered global options: %s", ctxt->optstr); + ++ return 0; ++} ++ ++int parse_init(int argc, const char *const *argv, void **context) ++{ ++ struct parse_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ /* Set up context and escape chain */ ++ ++ ctxt = (struct parse_context *) malloc(sizeof(struct parse_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ ++ *ctxt = default_context; ++ ++ if (do_init(argc, argv, ctxt)) { ++ free(ctxt); ++ return 1; ++ } ++ + /* We only need this once. NFS mounts are so common that we cache + this module. */ + instance_mutex_lock(); +@@ -404,17 +418,39 @@ options_done: + init_ctr++; + } else { + kill_context(ctxt); +- *context = NULL; + instance_mutex_unlock(); + return 1; + } + } + instance_mutex_unlock(); ++ ++ *context = (void *) ctxt; ++ + return 0; + } + + int parse_reinit(int argc, const char *const *argv, void **context) + { ++ struct parse_context *ctxt = (struct parse_context *) *context; ++ struct parse_context *new; ++ char buf[MAX_ERR_BUF]; ++ ++ new = (struct parse_context *) malloc(sizeof(struct parse_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ ++ *new = default_context; ++ ++ if (do_init(argc, argv, new)) ++ return 1; ++ ++ kill_context(ctxt); ++ ++ *context = (void *) new; ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-program-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-program-lookup-module.patch new file mode 100644 index 0000000..4b43b98 --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-program-lookup-module.patch @@ -0,0 +1,153 @@ +autofs-5.1.1 - implement reinit in program lookup module + +From: Ian Kent + +Refactor the program lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_program.c | 98 ++++++++++++++++++++++++++++++++++++---------- + 1 file changed, 76 insertions(+), 22 deletions(-) + +diff --git a/modules/lookup_program.c b/modules/lookup_program.c +index fa4f54d..3e9c448 100644 +--- a/modules/lookup_program.c ++++ b/modules/lookup_program.c +@@ -49,53 +49,82 @@ struct parse_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; +- +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } ++ int ret = 0; + + if (argc < 1) { + logmsg(MODPREFIX "No map name"); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + ctxt->mapname = argv[0]; + + if (ctxt->mapname[0] != '/') { + logmsg(MODPREFIX "program map %s is not an absolute pathname", + ctxt->mapname); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + + if (access(ctxt->mapname, X_OK)) { + logmsg(MODPREFIX "program map %s missing or not executable", + ctxt->mapname); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + + if (!mapfmt) + mapfmt = MAPFMT_DEFAULT; + + ctxt->mapfmt = strdup(mapfmt); ++ if (!ctxt->mapfmt) { ++ logmsg(MODPREFIX "failed to allocate storage for map format"); ++ ret = 1; ++ goto out; ++ } + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { +- logmsg(MODPREFIX "failed to open parse context"); ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logmsg(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++out: ++ if (ret && ctxt->mapfmt) ++ free(ctxt->mapfmt); ++ ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { + free(ctxt); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -104,6 +133,31 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++ free(ctxt->mapfmt); ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch new file mode 100644 index 0000000..ab1104c --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch @@ -0,0 +1,189 @@ +autofs-5.1.1 - implement reinit in sss lookup module + +From: Ian Kent + +Refactor the sss lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_sss.c | 130 +++++++++++++++++++++++++++++++++++++------------- + 1 file changed, 95 insertions(+), 35 deletions(-) + +diff --git a/modules/lookup_sss.c b/modules/lookup_sss.c +index c58a272..2f32e94 100644 +--- a/modules/lookup_sss.c ++++ b/modules/lookup_sss.c +@@ -56,39 +56,16 @@ struct lookup_context { + + int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int open_sss_lib(struct lookup_context *ctxt) + { +- struct lookup_context *ctxt; +- char buf[MAX_ERR_BUF]; + char dlbuf[PATH_MAX]; + char *estr; + void *dh; + size_t size; + +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } +- +- if (argc < 1) { +- free(ctxt); +- logerr(MODPREFIX "No map name"); +- return 1; +- } +- ctxt->mapname = argv[0]; +- +- if (!mapfmt) +- mapfmt = MAPFMT_DEFAULT; +- + size = snprintf(dlbuf, sizeof(dlbuf), + "%s/%s.so", SSS_LIB_DIR, SSS_SO_NAME); + if (size >= sizeof(dlbuf)) { +- free(ctxt); + logmsg(MODPREFIX "sss library path too long"); + return 1; + } +@@ -96,7 +73,6 @@ int lookup_init(const char *mapfmt, + dh = dlopen(dlbuf, RTLD_LAZY); + if (!dh) { + logerr(MODPREFIX "failed to open %s: %s", dlbuf, dlerror()); +- free(ctxt); + return 1; + } + ctxt->dlhandle = dh; +@@ -117,15 +93,6 @@ int lookup_init(const char *mapfmt, + if (!ctxt->setautomntent) + goto lib_names_fail; + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { +- logmsg(MODPREFIX "failed to open parse context"); +- dlclose(dh); +- free(ctxt); +- return 1; +- } +- *context = ctxt; +- + return 0; + + lib_names_fail: +@@ -134,13 +101,106 @@ lib_names_fail: + else + logerr(MODPREFIX "dlsym: %s", estr); + dlclose(dh); +- free(ctxt); ++ + return 1; + } + ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) ++{ ++ int ret = 0; ++ ++ if (argc < 1) { ++ logerr(MODPREFIX "No map name"); ++ ret = 1; ++ goto out; ++ } ++ ctxt->mapname = argv[0]; ++ ++ if (!mapfmt) ++ mapfmt = MAPFMT_DEFAULT; ++ ++ if (!reinit) { ++ ret = open_sss_lib(ctxt); ++ if (ret) ++ goto out; ++ } ++ ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logmsg(MODPREFIX "failed to open parse context"); ++ dlclose(ctxt->dlhandle); ++ ret = 1; ++ } ++ } ++out: ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { ++ free(ctxt); ++ return 1; ++ } ++ ++ *context = ctxt; ++ ++ return 0; ++} ++ + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ new->dlhandle = ctxt->dlhandle; ++ new->setautomntent = ctxt->setautomntent; ++ new->getautomntent_r = ctxt->getautomntent_r; ++ new->getautomntbyname_r = ctxt->getautomntbyname_r; ++ new->endautomntent = ctxt->endautomntent; ++ ++ *context = new; ++ ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch b/SOURCES/autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch new file mode 100644 index 0000000..b0761cc --- /dev/null +++ b/SOURCES/autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch @@ -0,0 +1,151 @@ +autofs-5.1.1 - implement reinit in yp lookup module + +From: Ian Kent + +Refactor the yp lookup module to add an implementation for the newly +added reinit entry point. + +Signed-off-by: Ian Kent +--- + modules/lookup_yp.c | 93 +++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 71 insertions(+), 22 deletions(-) + +diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c +index 1e5a7ed..e31c2cf 100644 +--- a/modules/lookup_yp.c ++++ b/modules/lookup_yp.c +@@ -103,27 +103,18 @@ static unsigned int get_map_order(const char *domain, const char *map) + return (unsigned int) last_changed; + } + +-int lookup_init(const char *mapfmt, +- int argc, const char *const *argv, void **context) ++static int do_init(const char *mapfmt, ++ int argc, const char *const *argv, ++ struct lookup_context *ctxt, unsigned int reinit) + { +- struct lookup_context *ctxt; + char buf[MAX_ERR_BUF]; + int err; +- +- *context = NULL; +- +- ctxt = malloc(sizeof(struct lookup_context)); +- if (!ctxt) { +- char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +- logerr(MODPREFIX "malloc: %s", estr); +- return 1; +- } +- memset(ctxt, 0, sizeof(struct lookup_context)); ++ int ret = 0; + + if (argc < 1) { +- free(ctxt); + logerr(MODPREFIX "no map name"); +- return 1; ++ ret = 1; ++ goto out; + } + ctxt->mapname = argv[0]; + ctxt->check_defaults = 1; +@@ -138,15 +129,15 @@ int lookup_init(const char *mapfmt, + if (err) { + logerr(MODPREFIX + "map %s: %s", ctxt->mapname, yperr_string(err)); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + ctxt->domainname = strdup(domainname); + if (!ctxt->domainname) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "strdup: %s", estr); +- free(ctxt); +- return 1; ++ ret = 1; ++ goto out; + } + } + +@@ -155,12 +146,45 @@ int lookup_init(const char *mapfmt, + if (!mapfmt) + mapfmt = MAPFMT_DEFAULT; + +- ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); +- if (!ctxt->parse) { ++ if (reinit) { ++ ret = reinit_parse(ctxt->parse, mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (ret) ++ logmsg(MODPREFIX "failed to reinit parse context"); ++ } else { ++ ctxt->parse = open_parse(mapfmt, MODPREFIX, argc - 1, argv + 1); ++ if (!ctxt->parse) { ++ logmsg(MODPREFIX "failed to open parse context"); ++ ret = 1; ++ } ++ } ++out: ++ if (ret && ctxt->domainname) ++ free(ctxt->domainname); ++ ++ return ret; ++} ++ ++int lookup_init(const char *mapfmt, ++ int argc, const char *const *argv, void **context) ++{ ++ struct lookup_context *ctxt; ++ char buf[MAX_ERR_BUF]; ++ ++ *context = NULL; ++ ++ ctxt = malloc(sizeof(struct lookup_context)); ++ if (!ctxt) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(ctxt, 0, sizeof(struct lookup_context)); ++ ++ if (do_init(mapfmt, argc, argv, ctxt, 0)) { + free(ctxt); +- logmsg(MODPREFIX "failed to open parse context"); + return 1; + } ++ + *context = ctxt; + + return 0; +@@ -169,6 +193,31 @@ int lookup_init(const char *mapfmt, + int lookup_reinit(const char *mapfmt, + int argc, const char *const *argv, void **context) + { ++ struct lookup_context *ctxt = (struct lookup_context *) *context; ++ struct lookup_context *new; ++ char buf[MAX_ERR_BUF]; ++ int ret; ++ ++ new = malloc(sizeof(struct lookup_context)); ++ if (!new) { ++ char *estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ logerr(MODPREFIX "malloc: %s", estr); ++ return 1; ++ } ++ memset(new, 0, sizeof(struct lookup_context)); ++ ++ new->parse = ctxt->parse; ++ ret = do_init(mapfmt, argc, argv, new, 1); ++ if (ret) { ++ free(new); ++ return 1; ++ } ++ ++ *context = new; ++ ++ free(ctxt->domainname); ++ free(ctxt); ++ + return 0; + } + diff --git a/SOURCES/autofs-5.1.1-improve-scalability-of-direct-mount-path-component-creation.patch b/SOURCES/autofs-5.1.1-improve-scalability-of-direct-mount-path-component-creation.patch new file mode 100644 index 0000000..8ac71db --- /dev/null +++ b/SOURCES/autofs-5.1.1-improve-scalability-of-direct-mount-path-component-creation.patch @@ -0,0 +1,190 @@ +autofs-5.1.1 - improve scalability of direct mount path component + +From: Jeff Mahoney + +With direct mounts, we want to avoid creating path components on +remote file systems unless that file system is the root file system. + +The check boils down to allowing the mkdir if: +1/ If it's the root directory, or +2/ If it's not a remote file system, or +3/ If it's a remote file system that's the root file system + +We can do that without parsing the mount table and can +improve startup time for all cases. + +Signed-off-by: Jeff Mahoney +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 56 +++++++++++++++++++++++++++++++++++++++------------- + include/automount.h | 2 + + include/mounts.h | 1 + lib/mounts.c | 45 ----------------------------------------- + 5 files changed, 45 insertions(+), 60 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -245,6 +245,7 @@ + - use autofs_point to store expire timeout where possibe. + - fix possible NULL derefernce. + - fix work around sss startup delay. ++- improve scalability of direct mount path component. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -135,10 +135,25 @@ void set_thread_mount_request_log_id(str + } + } + ++static int is_remote_fstype(unsigned int fs_type) ++{ ++ int ret = 0; ++ switch (fs_type) { ++ case SMB_SUPER_MAGIC: ++ case CIFS_MAGIC_NUMBER: ++ case NCP_SUPER_MAGIC: ++ case NFS_SUPER_MAGIC: ++ ret = 1; ++ break; ++ }; ++ return ret; ++} ++ + static int do_mkdir(const char *parent, const char *path, mode_t mode) + { + int status; +- struct stat st; ++ mode_t mask; ++ struct stat st, root; + struct statfs fs; + + /* If path exists we're done */ +@@ -151,24 +166,37 @@ static int do_mkdir(const char *parent, + } + + /* +- * If we're trying to create a directory within an autofs fs +- * or the path is contained in a localy mounted fs go ahead. ++ * We don't want to create the path on a remote file system ++ * unless it's the root file system. ++ * An empty parent means it's the root directory and always ok. + */ +- status = -1; +- if (*parent) ++ if (*parent) { + status = statfs(parent, &fs); +- if ((status != -1 && fs.f_type == (__SWORD_TYPE) AUTOFS_SUPER_MAGIC) || +- contained_in_local_fs(path)) { +- mode_t mask = umask(0022); +- int ret = mkdir(path, mode); +- (void) umask(mask); +- if (ret == -1) { +- errno = EACCES; +- return 0; ++ if (status == -1) ++ goto fail; ++ ++ if (is_remote_fstype(fs.f_type)) { ++ status = stat(parent, &st); ++ if (status == -1) ++ goto fail; ++ ++ status = stat("/", &root); ++ if (status == -1) ++ goto fail; ++ ++ if (st.st_dev != root.st_dev) ++ goto fail; + } +- return 1; + } + ++ mask = umask(0022); ++ status = mkdir(path, mode); ++ (void) umask(mask); ++ if (status == -1) ++ goto fail; ++ ++ return 1; ++fail: + errno = EACCES; + return 0; + } +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -75,6 +75,8 @@ int load_autofs4_module(void); + #define AUTOFS_SUPER_MAGIC 0x00000187L + #define SMB_SUPER_MAGIC 0x0000517BL + #define CIFS_MAGIC_NUMBER 0xFF534D42L ++#define NCP_SUPER_MAGIC 0x0000564CL ++#define NFS_SUPER_MAGIC 0x00006969L + + #define ATTEMPT_ID_SIZE 24 + +--- autofs-5.0.7.orig/include/mounts.h ++++ autofs-5.0.7/include/mounts.h +@@ -101,7 +101,6 @@ int ext_mount_remove(struct list_head *, + struct mnt_list *get_mnt_list(const char *table, const char *path, int include); + struct mnt_list *reverse_mnt_list(struct mnt_list *list); + void free_mnt_list(struct mnt_list *list); +-int contained_in_local_fs(const char *path); + int is_mounted(const char *table, const char *path, unsigned int type); + int has_fstab_option(const char *opt); + void tree_free_mnt_tree(struct mnt_list *tree); +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -941,51 +941,6 @@ void free_mnt_list(struct mnt_list *list + } + } + +-int contained_in_local_fs(const char *path) +-{ +- struct mnt_list *mnts, *this; +- size_t pathlen = strlen(path); +- int ret; +- +- if (!path || !pathlen || pathlen > PATH_MAX) +- return 0; +- +- mnts = get_mnt_list(_PATH_MOUNTED, "/", 1); +- if (!mnts) +- return 0; +- +- ret = 0; +- +- for (this = mnts; this != NULL; this = this->next) { +- size_t len = strlen(this->path); +- +- if (!strncmp(path, this->path, len)) { +- if (len > 1 && pathlen > len && path[len] != '/') +- continue; +- else if (len == 1 && this->path[0] == '/') { +- /* +- * always return true on rootfs, we don't +- * want to break diskless clients. +- */ +- ret = 1; +- } else if (this->fs_name[0] == '/') { +- if (strlen(this->fs_name) > 1) { +- if (this->fs_name[1] != '/') +- ret = 1; +- } else +- ret = 1; +- } else if (!strncmp("LABEL=", this->fs_name, 6) || +- !strncmp("UUID=", this->fs_name, 5)) +- ret = 1; +- break; +- } +- } +- +- free_mnt_list(mnts); +- +- return ret; +-} +- + static int table_is_mounted(const char *table, const char *path, unsigned int type) + { + struct mntent *mnt; diff --git a/SOURCES/autofs-5.1.1-log-pipe-read-errors.patch b/SOURCES/autofs-5.1.1-log-pipe-read-errors.patch new file mode 100644 index 0000000..36d8279 --- /dev/null +++ b/SOURCES/autofs-5.1.1-log-pipe-read-errors.patch @@ -0,0 +1,76 @@ +autofs-5.1.1 - log pipe read errors + +From: Ian Kent + +Log any unexpected pipe read (possible error) returns. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 24 ++++++++++++++++++++---- + 2 files changed, 21 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -187,6 +187,7 @@ + - gaurd against incorrect umount return. + - fix typo in autofs.conf. + - always set direct mounts catatonic at exit. ++- log pipe read errors. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -968,6 +968,8 @@ static int get_pkt(struct autofs_point * + struct pollfd fds[3]; + int pollfds = 3; + char buf[MAX_ERR_BUF]; ++ size_t read; ++ char *estr; + + fds[0].fd = ap->pipefd; + fds[0].events = POLLIN; +@@ -980,7 +982,6 @@ static int get_pkt(struct autofs_point * + + for (;;) { + if (poll(fds, pollfds, -1) == -1) { +- char *estr; + if (errno == EINTR) + continue; + estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -999,7 +1000,13 @@ static int get_pkt(struct autofs_point * + + state_pipe = ap->state_pipe[0]; + +- if (fullread(state_pipe, &next_state, read_size)) { ++ read = fullread(state_pipe, &next_state, read_size); ++ if (read) { ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "read error on state pipe, " ++ "read %u, error %s", ++ read, estr); + st_mutex_unlock(); + continue; + } +@@ -1010,8 +1017,17 @@ static int get_pkt(struct autofs_point * + return -1; + } + +- if (fds[0].revents & POLLIN) +- return fullread(ap->pipefd, pkt, kpkt_len); ++ if (fds[0].revents & POLLIN) { ++ read = fullread(ap->pipefd, pkt, kpkt_len); ++ if (read) { ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "read error on request pipe, " ++ "read %u, expected %u error %s", ++ read, kpkt_len, estr); ++ } ++ return read; ++ } + + if (fds[2].fd != -1 && fds[2].revents & POLLIN) { + debug(ap->logopt, "message pending on control fifo."); diff --git a/SOURCES/autofs-5.1.1-make-connect_to_server-return-a-status.patch b/SOURCES/autofs-5.1.1-make-connect_to_server-return-a-status.patch new file mode 100644 index 0000000..786b5db --- /dev/null +++ b/SOURCES/autofs-5.1.1-make-connect_to_server-return-a-status.patch @@ -0,0 +1,111 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -174,6 +174,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. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/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 log + 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 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 + 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 logop + 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 logop + 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/SOURCES/autofs-5.1.1-make-do_connect-return-a-status.patch b/SOURCES/autofs-5.1.1-make-do_connect-return-a-status.patch new file mode 100644 index 0000000..4eb2792 --- /dev/null +++ b/SOURCES/autofs-5.1.1-make-do_connect-return-a-status.patch @@ -0,0 +1,180 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -173,6 +173,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. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -631,10 +631,14 @@ static int do_bind(unsigned logopt, LDAP + 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, + } + #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, + 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, + * 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, + } 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(s + 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 + 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 logop + 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/SOURCES/autofs-5.1.1-make-find_dc_server-return-a-status.patch b/SOURCES/autofs-5.1.1-make-find_dc_server-return-a-status.patch new file mode 100644 index 0000000..0dac8e4 --- /dev/null +++ b/SOURCES/autofs-5.1.1-make-find_dc_server-return-a-status.patch @@ -0,0 +1,101 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -175,6 +175,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. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -839,33 +839,36 @@ static int connect_to_server(unsigned lo + 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 + 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 logop + } + + 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/SOURCES/autofs-5.1.1-make-find_server-return-a-status.patch b/SOURCES/autofs-5.1.1-make-find_server-return-a-status.patch new file mode 100644 index 0000000..34afed1 --- /dev/null +++ b/SOURCES/autofs-5.1.1-make-find_server-return-a-status.patch @@ -0,0 +1,117 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -176,6 +176,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. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -871,14 +871,14 @@ static int find_dc_server(unsigned logop + 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 + /* 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 + 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 + 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 + } + 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/SOURCES/autofs-5.1.1-make-open_lookup-return-nss-status.patch b/SOURCES/autofs-5.1.1-make-open_lookup-return-nss-status.patch new file mode 100644 index 0000000..15367f0 --- /dev/null +++ b/SOURCES/autofs-5.1.1-make-open_lookup-return-nss-status.patch @@ -0,0 +1,260 @@ +autofs-5.1.1 - make open_lookup() return nss status + +From: Ian Kent + +In order to distinguish between source unavailable and map not found +when opening nsswitch sources that have non-default actions open_lookup() +needs to return distinct results for these two cases. + +Signed-off-by: Ian Kent +--- + daemon/lookup.c | 21 +++++++++++---------- + daemon/module.c | 22 +++++++++++++--------- + include/automount.h | 4 ++-- + modules/lookup_multi.c | 20 +++++++++++++------- + modules/parse_amd.c | 6 ++++-- + 5 files changed, 43 insertions(+), 30 deletions(-) + +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 53455a1..0579f98 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -44,9 +44,9 @@ static int do_read_master(struct master *master, char *type, time_t age) + argv[0] = master->name; + argv[1] = NULL; + +- lookup = open_lookup(type, "", NULL, argc, argv); +- if (!lookup) +- return NSS_STATUS_UNAVAIL; ++ status = open_lookup(type, "", NULL, argc, argv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) ++ return status; + + status = lookup->lookup_read_master(master, age, lookup->context); + +@@ -300,10 +300,11 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a + struct lookup_mod *lookup; + int status; + +- lookup = open_lookup(map->type, "", map->format, map->argc, map->argv); +- if (!lookup) { ++ status = open_lookup(map->type, "", map->format, ++ map->argc, map->argv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) { + debug(ap->logopt, "lookup module %s failed", map->type); +- return NSS_STATUS_UNAVAIL; ++ return status; + } + + master_source_writelock(ap->entry); +@@ -737,12 +738,12 @@ int do_lookup_mount(struct autofs_point *ap, struct map_source *map, const char + int status; + + if (!map->lookup) { +- lookup = open_lookup(map->type, "", +- map->format, map->argc, map->argv); +- if (!lookup) { ++ status = open_lookup(map->type, "", ++ map->format, map->argc, map->argv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) { + debug(ap->logopt, + "lookup module %s failed", map->type); +- return NSS_STATUS_UNAVAIL; ++ return status; + } + map->lookup = lookup; + } +diff --git a/daemon/module.c b/daemon/module.c +index 466d8d7..9028aaa 100644 +--- a/daemon/module.c ++++ b/daemon/module.c +@@ -17,6 +17,7 @@ + #include + #include + #include "automount.h" ++#include "nsswitch.h" + + int load_autofs4_module(void) + { +@@ -53,8 +54,8 @@ int load_autofs4_module(void) + return 1; + } + +-struct lookup_mod *open_lookup(const char *name, const char *err_prefix, +- const char *mapfmt, int argc, const char *const *argv) ++int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, ++ int argc, const char *const *argv, struct lookup_mod **lookup) + { + struct lookup_mod *mod; + char buf[MAX_ERR_BUF]; +@@ -63,6 +64,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + void *dh; + int *ver; + ++ *lookup = NULL; + + mod = malloc(sizeof(struct lookup_mod)); + if (!mod) { +@@ -70,7 +72,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("%s%s", err_prefix, estr); + } +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + size = snprintf(fnbuf, sizeof(fnbuf), +@@ -81,7 +83,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr("%s%s", err_prefix, estr); + } +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + if (!(dh = dlopen(fnbuf, RTLD_NOW))) { +@@ -89,7 +91,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + logerr("%scannot open lookup module %s (%s)", + err_prefix, name, dlerror()); + free(mod); +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + if (!(ver = (int *) dlsym(dh, "lookup_version")) +@@ -99,7 +101,7 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + err_prefix, name); + dlclose(dh); + free(mod); +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + if (!(mod->lookup_init = (lookup_init_t) dlsym(dh, "lookup_init")) || +@@ -111,16 +113,18 @@ struct lookup_mod *open_lookup(const char *name, const char *err_prefix, + logerr("%slookup module %s corrupt", err_prefix, name); + dlclose(dh); + free(mod); +- return NULL; ++ return NSS_STATUS_UNAVAIL; + } + + if (mod->lookup_init(mapfmt, argc, argv, &mod->context)) { + dlclose(dh); + free(mod); +- return NULL; ++ return NSS_STATUS_NOTFOUND; + } + mod->dlhandle = dh; +- return mod; ++ *lookup = mod; ++ ++ return NSS_STATUS_SUCCESS; + } + + int close_lookup(struct lookup_mod *mod) +diff --git a/include/automount.h b/include/automount.h +index 447aba1..d614c10 100644 +--- a/include/automount.h ++++ b/include/automount.h +@@ -302,8 +302,8 @@ struct lookup_mod { + void *context; + }; + +-struct lookup_mod *open_lookup(const char *name, const char *err_prefix, +- const char *mapfmt, int argc, const char *const *argv); ++int open_lookup(const char *name, const char *err_prefix, const char *mapfmt, ++ int argc, const char *const *argv, struct lookup_mod **lookup); + int close_lookup(struct lookup_mod *); + + /* parse module */ +diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c +index ffb236c..55035e4 100644 +--- a/modules/lookup_multi.c ++++ b/modules/lookup_multi.c +@@ -50,8 +50,10 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + if (!argv || !argv[0]) + return NULL; + +- if (*argv[0] == '/') +- return open_lookup("file", MODPREFIX, format, argc, argv); ++ if (*argv[0] == '/') { ++ open_lookup("file", MODPREFIX, format, argc, argv, &mod); ++ return mod; ++ } + + if (!strncmp(argv[0], "file", 4) || + !strncmp(argv[0], "yp", 2) || +@@ -65,7 +67,8 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + fmt++; + else + fmt = format; +- return open_lookup(argv[0], MODPREFIX, fmt, argc -1, argv + 1); ++ open_lookup(argv[0], MODPREFIX, fmt, argc - 1, argv + 1, &mod); ++ return mod; + } + + INIT_LIST_HEAD(&nsslist); +@@ -80,6 +83,7 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + head = &nsslist; + list_for_each(p, head) { + struct nss_source *this; ++ int status; + + this = list_entry(p, struct nss_source, list); + +@@ -113,8 +117,9 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + save_argv0 = (char *) argv[0]; + argv[0] = path; + +- mod = open_lookup(type, MODPREFIX, format, argc, argv); +- if (mod) { ++ status = open_lookup(type, MODPREFIX, ++ format, argc, argv, &mod); ++ if (status == NSS_STATUS_SUCCESS) { + free_sources(&nsslist); + free(save_argv0); + return mod; +@@ -124,8 +129,9 @@ static struct lookup_mod *nss_open_lookup(const char *format, int argc, const ch + free(path); + } + +- mod = open_lookup(this->source, MODPREFIX, format, argc, argv); +- if (mod) { ++ status = open_lookup(this->source, MODPREFIX, ++ format, argc, argv, &mod); ++ if (status == NSS_STATUS_SUCCESS) { + free_sources(&nsslist); + return mod; + } +diff --git a/modules/parse_amd.c b/modules/parse_amd.c +index 899be40..2e3d21f 100644 +--- a/modules/parse_amd.c ++++ b/modules/parse_amd.c +@@ -31,6 +31,7 @@ + + #define MODULE_PARSE + #include "automount.h" ++#include "nsswitch.h" + + #define MODPREFIX "parse(amd): " + +@@ -1129,6 +1130,7 @@ static int do_host_mount(struct autofs_point *ap, const char *name, + struct mapent *me; + const char *argv[2]; + const char **pargv = NULL; ++ int status; + int argc = 0; + int ret = 1; + +@@ -1170,8 +1172,8 @@ static int do_host_mount(struct autofs_point *ap, const char *name, + } + + instance_mutex_lock(); +- lookup = open_lookup("hosts", MODPREFIX, NULL, argc, pargv); +- if (!lookup) { ++ status = open_lookup("hosts", MODPREFIX, NULL, argc, pargv, &lookup); ++ if (status != NSS_STATUS_SUCCESS) { + debug(ap->logopt, "open lookup module hosts failed"); + instance_mutex_unlock(); + goto out; diff --git a/SOURCES/autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch b/SOURCES/autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch new file mode 100644 index 0000000..68aeed1 --- /dev/null +++ b/SOURCES/autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch @@ -0,0 +1,138 @@ +autofs-5.1.1 - move check_nss_result() to nsswitchr.c + +From: Ian Kent + +The check_nss_result() function will be needed by the multi-map lookup +module so move it to the nss library module. + +Signed-off-by: Ian Kent +--- + daemon/lookup.c | 45 --------------------------------------------- + include/nsswitch.h | 1 + + lib/nsswitch.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 46 insertions(+), 45 deletions(-) + +diff --git a/daemon/lookup.c b/daemon/lookup.c +index 62071df..53455a1 100644 +--- a/daemon/lookup.c ++++ b/daemon/lookup.c +@@ -25,51 +25,6 @@ + #include "automount.h" + #include "nsswitch.h" + +-static int check_nss_result(struct nss_source *this, enum nsswitch_status result) +-{ +- enum nsswitch_status status; +- struct nss_action a; +- +- /* Check if we have negated actions */ +- for (status = 0; status < NSS_STATUS_MAX; status++) { +- a = this->action[status]; +- if (a.action == NSS_ACTION_UNKNOWN) +- continue; +- +- if (a.negated && result != status) { +- if (a.action == NSS_ACTION_RETURN) { +- if (result == NSS_STATUS_SUCCESS) +- return 1; +- else +- return 0; +- } +- } +- } +- +- a = this->action[result]; +- +- /* Check if we have other actions for this status */ +- switch (result) { +- case NSS_STATUS_SUCCESS: +- if (a.action == NSS_ACTION_CONTINUE) +- break; +- return 1; +- +- case NSS_STATUS_NOTFOUND: +- case NSS_STATUS_UNAVAIL: +- case NSS_STATUS_TRYAGAIN: +- if (a.action == NSS_ACTION_RETURN) { +- return 0; +- } +- break; +- +- default: +- break; +- } +- +- return -1; +-} +- + static void nsslist_cleanup(void *arg) + { + struct list_head *nsslist = (struct list_head *) arg; +diff --git a/include/nsswitch.h b/include/nsswitch.h +index 2b445a9..d3e4027 100644 +--- a/include/nsswitch.h ++++ b/include/nsswitch.h +@@ -56,6 +56,7 @@ struct nss_source { + }; + + int set_action(struct nss_action *a, char *status, char *action, int negated); ++int check_nss_result(struct nss_source *this, enum nsswitch_status result); + struct nss_source *add_source(struct list_head *head, char *source); + int free_sources(struct list_head *list); + +diff --git a/lib/nsswitch.c b/lib/nsswitch.c +index c6163a7..74c7525 100644 +--- a/lib/nsswitch.c ++++ b/lib/nsswitch.c +@@ -55,6 +55,51 @@ int set_action(struct nss_action *act, char *status, char *action, int negated) + return 1; + } + ++int check_nss_result(struct nss_source *this, enum nsswitch_status result) ++{ ++ enum nsswitch_status status; ++ struct nss_action a; ++ ++ /* Check if we have negated actions */ ++ for (status = 0; status < NSS_STATUS_MAX; status++) { ++ a = this->action[status]; ++ if (a.action == NSS_ACTION_UNKNOWN) ++ continue; ++ ++ if (a.negated && result != status) { ++ if (a.action == NSS_ACTION_RETURN) { ++ if (result == NSS_STATUS_SUCCESS) ++ return 1; ++ else ++ return 0; ++ } ++ } ++ } ++ ++ a = this->action[result]; ++ ++ /* Check if we have other actions for this status */ ++ switch (result) { ++ case NSS_STATUS_SUCCESS: ++ if (a.action == NSS_ACTION_CONTINUE) ++ break; ++ return 1; ++ ++ case NSS_STATUS_NOTFOUND: ++ case NSS_STATUS_UNAVAIL: ++ case NSS_STATUS_TRYAGAIN: ++ if (a.action == NSS_ACTION_RETURN) { ++ return 0; ++ } ++ break; ++ ++ default: ++ break; ++ } ++ ++ return -1; ++} ++ + struct nss_source *add_source(struct list_head *head, char *source) + { + struct nss_source *s; diff --git a/SOURCES/autofs-5.1.1-move-query-dn-calculation-from-do_bind-to-do_connect.patch b/SOURCES/autofs-5.1.1-move-query-dn-calculation-from-do_bind-to-do_connect.patch new file mode 100644 index 0000000..51c5d0c --- /dev/null +++ b/SOURCES/autofs-5.1.1-move-query-dn-calculation-from-do_bind-to-do_connect.patch @@ -0,0 +1,156 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -172,6 +172,7 @@ + - init qdn before use in get_query_dn(). + - 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(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -574,7 +574,7 @@ static int find_query_dn(unsigned logopt + 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_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 + } + } 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, + #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/SOURCES/autofs-5.1.1-update-map_hash_table_size-description.patch b/SOURCES/autofs-5.1.1-update-map_hash_table_size-description.patch new file mode 100644 index 0000000..bdc206b --- /dev/null +++ b/SOURCES/autofs-5.1.1-update-map_hash_table_size-description.patch @@ -0,0 +1,100 @@ +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(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -180,6 +180,7 @@ + - fix return handling of do_reconnect() in ldap module. + - fix direct mount stale instance flag reset. + - fix direct map expire not set for initail empty map. ++- update map_hash_table_size description. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -80,6 +80,37 @@ user setting these standard environment + 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: +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/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 + # +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/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/SOURCES/autofs-5.1.2-add-config-option-to-use-mount-request-log-id.patch b/SOURCES/autofs-5.1.2-add-config-option-to-use-mount-request-log-id.patch new file mode 100644 index 0000000..37e3b82 --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-config-option-to-use-mount-request-log-id.patch @@ -0,0 +1,148 @@ +autofs-5.1.2 - add config option to use mount request log id + +From: Ian Kent + +Add a configuration option to control whether request ids are added to +mount request log entries. It's default value is to not include the +additional id. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 3 +++ + include/defaults.h | 3 +++ + lib/defaults.c | 18 ++++++++++++++++++ + man/autofs.conf.5.in | 6 ++++++ + redhat/autofs.conf.default.in | 7 +++++++ + samples/autofs.conf.default.in | 7 +++++++ + 7 files changed, 45 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -239,6 +239,7 @@ + - create thread-local ID for mount attempts. + - log functions to prefix messages with attempt_id if available. + - factor out set_thread_mount_request_log_id(). ++- add config option to use mount request log id. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -116,6 +116,9 @@ void set_thread_mount_request_log_id(str + unsigned long *attempt_id; + int status; + ++ if (!defaults_get_use_mount_request_log_id()) ++ return; ++ + attempt_id = pthread_getspecific(key_thread_attempt_id); + if (attempt_id == NULL) { + attempt_id = (unsigned long *) calloc(1, sizeof(unsigned long)); +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -51,6 +51,8 @@ + #define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0" + #define DEFAULT_DISABLE_NOT_FOUND_MESSAGE "0" + ++#define DEFAULT_USE_MOUNT_REQUEST_LOG_ID "0" ++ + /* Config entry flags */ + #define CONF_NONE 0x00000000 + #define CONF_ENV 0x00000001 +@@ -169,6 +171,7 @@ const char *defaults_get_auth_conf_file( + unsigned int defaults_get_map_hash_table_size(void); + unsigned int defaults_use_hostname_for_mounts(void); + unsigned int defaults_disable_not_found_message(void); ++unsigned int defaults_get_use_mount_request_log_id(void); + + unsigned int conf_amd_mount_section_exists(const char *); + char **conf_amd_get_mount_paths(void); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -76,6 +76,8 @@ + #define NAME_USE_HOSTNAME_FOR_MOUNTS "use_hostname_for_mounts" + #define NAME_DISABLE_NOT_FOUND_MESSAGE "disable_not_found_message" + ++#define NAME_USE_MOUNT_REQUEST_LOG_ID "use_mount_request_log_id" ++ + #define NAME_AMD_ARCH "arch" + #define NAME_AMD_AUTO_ATTRCACHE "auto_attrcache" + #define NAME_AMD_AUTO_DIR "auto_dir" +@@ -354,6 +356,11 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_USE_MOUNT_REQUEST_LOG_ID, ++ DEFAULT_USE_MOUNT_REQUEST_LOG_ID, 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); +@@ -1832,6 +1839,17 @@ unsigned int defaults_disable_not_found_ + + return res; + } ++ ++unsigned int defaults_get_use_mount_request_log_id(void) ++{ ++ int res; ++ ++ res = conf_get_yesno(autofs_gbl_sec, NAME_USE_MOUNT_REQUEST_LOG_ID); ++ if (res < 0) ++ res = atoi(DEFAULT_USE_MOUNT_REQUEST_LOG_ID); ++ ++ return res; ++} + + unsigned int conf_amd_mount_section_exists(const char *section) + { +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -141,6 +141,12 @@ The original request to add this log mes + That produces, IMHO, unnecessary noise in the log so a configuration option + has been added to provide the ability to turn it off. The default is "no" + to maintain the current behaviour. ++.TP ++.B use_mount_request_log_id ++.br ++Set whether to use a mount request log id so that log entries for specific ++mount requests can be easily identified in logs that have multiple conncurrent ++requests. Default is don't use mount request log ids. + .SS LDAP Configuration + .P + Configuration settings available are: +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -71,6 +71,13 @@ mount_nfs_default_protocol = 4 + # + # force_standard_program_map_env = no + # ++# use_mount_request_log_id - Set whether to use a mount request log ++# id so that log entries for specific mount ++# requests can be easily identified in logs ++# that have multiple conncurrent requests. ++# ++#use_mount_request_log_id = no ++# + # Define base dn for map dn lookup. + # + # Define server URIs +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -70,6 +70,13 @@ browse_mode = no + # + # force_standard_program_map_env = no + # ++# use_mount_request_log_id - Set whether to use a mount request log ++# id so that log entries for specific mount ++# requests can be easily identified in logs ++# that have multiple conncurrent requests. ++# ++#use_mount_request_log_id = no ++# + # Define base dn for map dn lookup. + # + # Define server URIs diff --git a/SOURCES/autofs-5.1.2-add-congigure-option-for-limiting-getgrgid_r-stack-usage.patch b/SOURCES/autofs-5.1.2-add-congigure-option-for-limiting-getgrgid_r-stack-usage.patch new file mode 100644 index 0000000..db4c240 --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-congigure-option-for-limiting-getgrgid_r-stack-usage.patch @@ -0,0 +1,195 @@ +autofs-5.1.2 - add congigure option for limiting getgrgid_r() stack usage + +From: Ian Kent + +Almost all the time it isn't a problem for glibc to use stack allocation +to store group information during calls to getgrgid_r(). + +But if it is a problem the --enable-limit-getgrgid-size configure option +can be used to limit the buffer size passed to getgrgid_r() (which is used +to decide whether to alloca() local storage for the call). + +The check allows the call to go ahead if the increased buffer size is less +than 0.9 of the thread stack size. + +This isn't ideal because the current stack usage isn't known but should +be ok much of the time. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + configure | 32 +++++++++++++++++++++++++------- + configure.in | 24 +++++++++++++++++------- + include/config.h.in | 3 +++ + lib/mounts.c | 6 ++++-- + 5 files changed, 50 insertions(+), 16 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -249,6 +249,7 @@ + - fix invalid reference in remount_active_mount(). + - increase worker thread per-thread stack size. + - limit getgrgid_r() buffer size. ++- add congigure option for limiting getgrgid_r() stack usage. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/configure ++++ autofs-5.0.7/configure +@@ -743,6 +743,7 @@ enable_ext_env + enable_mount_locking + enable_forced_shutdown + enable_ignore_busy ++enable_limit_getgrgid_size + ' + ac_precious_vars='build_alias + host_alias +@@ -1360,13 +1361,14 @@ Optional Features: + --disable-option-checking ignore unrecognized --enable/--with options + --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) + --enable-FEATURE[=ARG] include FEATURE [ARG=yes] +- --enable-sloppy-mount enable the use of the -s option to mount +- --disable-ext-env disable search in environment for substitution variable +- --disable-mount-locking disable use of locking when spawning mount command +- --enable-force-shutdown enable USR1 signal to force unlink umount of any +- busy mounts during shutdown +- --enable-ignore-busy enable exit without umounting busy mounts during +- shutdown ++ --enable-sloppy-mount enable the use of the -s option to mount ++ --disable-ext-env disable search in environment for substitution variable ++ --disable-mount-locking disable use of locking when spawning mount command ++ --enable-force-shutdown enable USR1 signal to force unlink umount of any ++ busy mounts during shutdown ++ --enable-ignore-busy enable exit without umounting busy mounts during ++ shutdown ++ --enable-limit-getgrgid-size enable limit stack use of getgrgid_r() + + Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] +@@ -5662,6 +5664,22 @@ $as_echo "#define ENABLE_IGNORE_BUSY_MOU + + fi + ++# ++# Enable exit, ignoring busy mounts. ++# ++# Check whether --enable-limit-getgrgid-size was given. ++if test "${enable_limit_getgrgid_size+set}" = set; then : ++ enableval=$enable_limit_getgrgid_size; ++else ++ enableval=no ++fi ++ ++if test x$enable_limit_getgrgid_size = xyes -o x$enableval = xyes; then ++ ++$as_echo "#define ENABLE_LIMIT_GETGRGID_SIZE 1" >>confdefs.h ++ ++fi ++ + # + # Write Makefile.conf and include/config.h + # +--- autofs-5.0.7.orig/configure.in ++++ autofs-5.0.7/configure.in +@@ -158,7 +158,7 @@ AC_SUBST(sssldir) + # good for portability + # + AC_ARG_ENABLE(sloppy-mount, +-[ --enable-sloppy-mount enable the use of the -s option to mount],, ++[ --enable-sloppy-mount enable the use of the -s option to mount],, + enable_sloppy_mount=auto) + if test x$enable_sloppy_mount = xauto; then + AF_SLOPPY_MOUNT() +@@ -344,7 +344,7 @@ AC_SUBST(DAEMON_LDFLAGS) + # Enable ability to access value in external env variable + # + AC_ARG_ENABLE(ext-env, +-[ --disable-ext-env disable search in environment for substitution variable],, ++[ --disable-ext-env disable search in environment for substitution variable],, + enableval=yes) + if test x$enable_ext_env = xyes -o x$enableval = xyes; then + AC_DEFINE(ENABLE_EXT_ENV, 1, [leave this alone]) +@@ -354,7 +354,7 @@ fi + # Disable use of locking when spawning mount command + # + AC_ARG_ENABLE(mount-locking, +-[ --disable-mount-locking disable use of locking when spawning mount command],, ++[ --disable-mount-locking disable use of locking when spawning mount command],, + enableval=yes) + if test x$enable_mount_locking = xyes -o x$enableval = xyes; then + AC_DEFINE(ENABLE_MOUNT_LOCKING, 1, [Disable use of locking when spawning mount command]) +@@ -364,8 +364,8 @@ fi + # Enable forced shutdown on USR1 signal (unlink umounts all mounts). + # + AC_ARG_ENABLE(forced-shutdown, +-[ --enable-force-shutdown enable USR1 signal to force unlink umount of any +- busy mounts during shutdown],, ++[ --enable-force-shutdown enable USR1 signal to force unlink umount of any ++ busy mounts during shutdown],, + enableval=no) + if test x$enable_forced_shutdown = xyes -o x$enableval = xyes; then + AC_DEFINE(ENABLE_FORCED_SHUTDOWN, 1, [Enable forced shutdown on USR1 signal]) +@@ -375,14 +375,24 @@ fi + # Enable exit, ignoring busy mounts. + # + AC_ARG_ENABLE(ignore-busy, +-[ --enable-ignore-busy enable exit without umounting busy mounts during +- shutdown],, ++[ --enable-ignore-busy enable exit without umounting busy mounts during ++ shutdown],, + enableval=no) + if test x$enable_ignore_busy_mounts = xyes -o x$enableval = xyes; then + AC_DEFINE(ENABLE_IGNORE_BUSY_MOUNTS, 1, [Enable exit, ignoring busy mounts]) + fi + + # ++# Enable exit, ignoring busy mounts. ++# ++AC_ARG_ENABLE(limit-getgrgid-size, ++[ --enable-limit-getgrgid-size enable limit stack use of getgrgid_r()],, ++ enableval=no) ++if test x$enable_limit_getgrgid_size = xyes -o x$enableval = xyes; then ++ AC_DEFINE(ENABLE_LIMIT_GETGRGID_SIZE, 1, [Enable limit stack use of getgrgid_r()]) ++fi ++ ++# + # Write Makefile.conf and include/config.h + # + AC_CONFIG_HEADER(include/config.h) +--- autofs-5.0.7.orig/include/config.h.in ++++ autofs-5.0.7/include/config.h.in +@@ -9,6 +9,9 @@ + /* Enable exit, ignoring busy mounts */ + #undef ENABLE_IGNORE_BUSY_MOUNTS + ++/* Enable limit stack use of getgrgid_r() */ ++#undef ENABLE_LIMIT_GETGRGID_SIZE ++ + /* Disable use of locking when spawning mount command */ + #undef ENABLE_MOUNT_LOCKING + +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -1507,8 +1507,10 @@ void set_tsd_user_vars(unsigned int logo + + gr_tmp = NULL; + status = ERANGE; ++#ifdef ENABLE_LIMIT_GETGRGID_SIZE + if (!maxgrpbuf) + maxgrpbuf = detached_thread_stack_size * 0.9; ++#endif + + /* If getting the group name fails go on without it. It's + * used to set an environment variable for program maps +@@ -1532,9 +1534,9 @@ void set_tsd_user_vars(unsigned int logo + tmplen += grplen; + + /* Don't tempt glibc to alloca() larger than is (likely) +- * available on the stack. ++ * available on the stack if limit-getgrgid-size is enabled. + */ +- if (tmplen < maxgrpbuf) ++ if (!maxgrpbuf || (tmplen < maxgrpbuf)) + continue; + + /* Add a message so we know this happened */ diff --git a/SOURCES/autofs-5.1.2-add-function-conf_amd_get_map_name.patch b/SOURCES/autofs-5.1.2-add-function-conf_amd_get_map_name.patch new file mode 100644 index 0000000..2cf4bf0 --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-function-conf_amd_get_map_name.patch @@ -0,0 +1,60 @@ +autofs-5.1.2 - add function conf_amd_get_map_name() + +From: Ian Kent + +Add configuration function to get the map_name option from +an amd mount configuration section. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/defaults.h | 1 + + lib/defaults.c | 10 ++++++++++ + 3 files changed, 12 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -225,6 +225,7 @@ + - fix typos in README.amd-maps. + - add ref counting to struct map_source. + - add support for amd browsable option. ++- add function conf_amd_get_map_name(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -191,6 +191,7 @@ char *conf_amd_get_nfs_proto(void); + char *conf_amd_get_nis_domain(void); + unsigned int conf_amd_set_nis_domain(const char *); + char *conf_amd_get_map_defaults(const char *); ++char *conf_amd_get_map_name(const char *); + char *conf_amd_get_map_type(const char *); + char *conf_amd_get_search_path(const char *); + unsigned int conf_amd_get_dismount_interval(const char *); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -105,6 +105,7 @@ + #define NAME_AMD_MAP_DEFAULTS "map_defaults" + #define NAME_AMD_MAP_OPTIONS "map_options" + #define NAME_AMD_MAP_RELOAD_INTERVAL "map_reload_interval" ++#define NAME_AMD_MAP_NAME "map_name" + #define NAME_AMD_MAP_TYPE "map_type" + #define NAME_AMD_MOUNT_TYPE "mount_type" + #define NAME_AMD_PID_FILE "pid_file" +@@ -1914,6 +1915,15 @@ char *conf_amd_get_map_defaults(const ch + + return tmp; + } ++ ++char *conf_amd_get_map_name(const char *section) ++{ ++ char *tmp = NULL; ++ if (section) ++ tmp = conf_get_string(section, NAME_AMD_MAP_NAME); ++ ++ return tmp; ++} + + char *conf_amd_get_map_type(const char *section) + { diff --git a/SOURCES/autofs-5.1.2-add-function-conf_amd_get_map_options.patch b/SOURCES/autofs-5.1.2-add-function-conf_amd_get_map_options.patch new file mode 100644 index 0000000..fd374d3 --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-function-conf_amd_get_map_options.patch @@ -0,0 +1,64 @@ +autofs-5.1.2 - add function conf_amd_get_map_options() + +From: Ian Kent + +Add configuration function to get the map_options option from +an amd mount configuration section. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/defaults.h | 1 + + lib/defaults.c | 14 ++++++++++++++ + 3 files changed, 16 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -229,6 +229,7 @@ + - add function conf_amd_get_mount_paths(). + - include amd mount sections mounts in master mounts list. + - check for conflicting amd section mounts. ++- add function conf_get_map_options(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -193,6 +193,7 @@ char *conf_amd_get_nis_domain(void); + unsigned int conf_amd_set_nis_domain(const char *); + char *conf_amd_get_map_defaults(const char *); + char *conf_amd_get_map_name(const char *); ++char *conf_amd_get_map_options(const char *); + char *conf_amd_get_map_type(const char *); + char *conf_amd_get_search_path(const char *); + unsigned int conf_amd_get_dismount_interval(const char *); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -493,6 +493,11 @@ static int conf_load_amd_defaults(void) + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_AMD_MAP_OPTIONS, ++ DEFAULT_AMD_MAP_OPTIONS, CONF_NONE); ++ if (ret == CFG_FAIL) ++ goto error; ++ + ret = conf_update(sec, NAME_AMD_MAP_TYPE, + DEFAULT_AMD_MAP_TYPE, CONF_NONE); + if (ret == CFG_FAIL) +@@ -2004,6 +2009,15 @@ char *conf_amd_get_map_name(const char * + + return tmp; + } ++ ++char *conf_amd_get_map_options(const char *section) ++{ ++ char *tmp = NULL; ++ if (section) ++ tmp = conf_get_string(section, NAME_AMD_MAP_OPTIONS); ++ ++ return tmp; ++} + + char *conf_amd_get_map_type(const char *section) + { diff --git a/SOURCES/autofs-5.1.2-add-function-conf_amd_get_mount_paths.patch b/SOURCES/autofs-5.1.2-add-function-conf_amd_get_mount_paths.patch new file mode 100644 index 0000000..94ebfcd --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-function-conf_amd_get_mount_paths.patch @@ -0,0 +1,130 @@ +autofs-5.1.2 - add function conf_amd_get_mount_paths() + +From: Ian Kent + +Add configuration function to get an array of amd mount section +paths. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/defaults.h | 1 + lib/defaults.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 82 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -226,6 +226,7 @@ + - add ref counting to struct map_source. + - add support for amd browsable option. + - add function conf_amd_get_map_name(). ++- add function conf_amd_get_mount_paths(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -171,6 +171,7 @@ unsigned int defaults_use_hostname_for_m + unsigned int defaults_disable_not_found_message(void); + + unsigned int conf_amd_mount_section_exists(const char *); ++char **conf_amd_get_mount_paths(void); + char *conf_amd_get_arch(void); + char *conf_amd_get_karch(void); + char *conf_amd_get_os(void); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -763,6 +763,81 @@ static struct conf_option *conf_lookup(c + return co; + } + ++static char **conf_enumerate_amd_mount_sections(void) ++{ ++ struct conf_option *this; ++ unsigned int count; ++ char **paths; ++ char *last; ++ int i, j; ++ ++ last = NULL; ++ count = 0; ++ for (i = 0; i < CFG_TABLE_SIZE; i++) { ++ if (!config->hash[i]) ++ continue; ++ ++ this = config->hash[i]; ++ while (this) { ++ /* Only amd mount section names begin with '/' */ ++ if (*this->section != '/') { ++ this = this->next; ++ continue; ++ } ++ ++ if (!last || ++ strcmp(this->section, last)) ++ count ++; ++ last = this->section; ++ this = this->next; ++ } ++ } ++ ++ if (!count) ++ return NULL; ++ ++ paths = (char **) malloc(((count + 1) * sizeof(char *))); ++ if (!paths) ++ return NULL; ++ memset(paths, 0, ((count + 1) * sizeof(char *))); ++ ++ last = NULL; ++ j = 0; ++ ++ for (i = 0; i < CFG_TABLE_SIZE; i++) { ++ if (!config->hash[i]) ++ continue; ++ ++ this = config->hash[i]; ++ while (this) { ++ /* Only amd mount section names begin with '/' */ ++ if (*this->section != '/') { ++ this = this->next; ++ continue; ++ } ++ ++ if (!last || ++ strcmp(this->section, last)) { ++ char *path = strdup(this->section); ++ if (!path) ++ goto fail; ++ paths[j++] = path; ++ } ++ last = this->section; ++ this = this->next; ++ } ++ } ++ ++ return paths; ++ ++fail: ++ i = 0; ++ while (paths[i]) ++ free(paths[i++]); ++ free(paths); ++ return NULL; ++} ++ + static unsigned int conf_section_exists(const char *section) + { + struct conf_option *co; +@@ -1758,6 +1833,11 @@ unsigned int conf_amd_mount_section_exis + return conf_section_exists(section); + } + ++char **conf_amd_get_mount_paths(void) ++{ ++ return conf_enumerate_amd_mount_sections(); ++} ++ + char *conf_amd_get_arch(void) + { + return conf_get_string(amd_gbl_sec, NAME_AMD_ARCH); diff --git a/SOURCES/autofs-5.1.2-add-master-read-wait-option.patch b/SOURCES/autofs-5.1.2-add-master-read-wait-option.patch new file mode 100644 index 0000000..78dcc22 --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-master-read-wait-option.patch @@ -0,0 +1,197 @@ +autofs-5.1.2 - add master read wait option + +From: Ian Kent + +Add command line and configuration options to set the amount of time to +wait for the master map to become available at program start. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 11 +++++++++-- + include/defaults.h | 2 ++ + lib/defaults.c | 17 +++++++++++++++++ + man/autofs.conf.5.in | 5 +++++ + man/automount.8 | 4 ++++ + redhat/autofs.conf.default.in | 7 +++++++ + samples/autofs.conf.default.in | 7 +++++++ + 8 files changed, 52 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -207,6 +207,7 @@ + - fix use-after-free in st_queue_handler(). + - add config option to supress not found log message. + - wait for master map available at start. ++- add master read wait option. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -2082,10 +2082,11 @@ int main(int argc, char *argv[]) + unsigned ghost, logging, daemon_check; + unsigned dumpmaps, foreground, have_global_options; + unsigned master_read; ++ int master_wait; + time_t timeout; + time_t age = time(NULL); + struct rlimit rlim; +- const char *options = "+hp:t:vmdD:fVrO:l:n:CF"; ++ const char *options = "+hp:t:vmdD:fVrO:l:n:CFM"; + static const struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"pid-file", 1, 0, 'p'}, +@@ -2102,6 +2103,7 @@ int main(int argc, char *argv[]) + {"set-log-priority", 1, 0, 'l'}, + {"dont-check-daemon", 0, 0, 'C'}, + {"force", 0, 0, 'F'}, ++ {"master-wait", 1, 0, 'M'}, + {0, 0, 0, 0} + }; + +@@ -2122,6 +2124,7 @@ int main(int argc, char *argv[]) + nfs_mount_uses_string_options = check_nfs_mount_version(&vers, &check); + + kpkt_len = get_kpkt_len(); ++ master_wait = defaults_get_master_wait(); + timeout = defaults_get_timeout(); + ghost = defaults_get_browse_mode(); + logging = defaults_get_logging(); +@@ -2181,6 +2184,10 @@ int main(int argc, char *argv[]) + dumpmaps = 1; + break; + ++ case 'M': ++ master_wait = getnumopt(optarg, opt); ++ break; ++ + case 'O': + if (!have_global_options) { + global_options = strdup(optarg); +@@ -2502,7 +2509,7 @@ int main(int argc, char *argv[]) + * a signal is received, in which case exit returning an + * error. + */ +- if (!do_master_read_master(master_list, -1)) { ++ if (!do_master_read_master(master_list, master_wait)) { + logerr("%s: failed to read master map!", program); + master_kill(master_list); + release_flag_file(); +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -25,6 +25,7 @@ + #define DEFAULT_MASTER_MAP_NAME "auto.master" + + #define DEFAULT_TIMEOUT "600" ++#define DEFAULT_MASTER_WAIT "-1" + #define DEFAULT_NEGATIVE_TIMEOUT "60" + #define DEFAULT_MOUNT_WAIT "-1" + #define DEFAULT_UMOUNT_WAIT "12" +@@ -152,6 +153,7 @@ void defaults_conf_release(void); + const char *defaults_get_master_map(void); + int defaults_master_set(void); + unsigned int defaults_get_timeout(void); ++int defaults_get_master_wait(void); + unsigned int defaults_get_negative_timeout(void); + unsigned int defaults_get_browse_mode(void); + unsigned int defaults_get_logging(void); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -47,6 +47,7 @@ + #define NAME_MASTER_MAP "master_map_name" + + #define NAME_TIMEOUT "timeout" ++#define NAME_MASTER_WAIT "master_wait" + #define NAME_NEGATIVE_TIMEOUT "negative_timeout" + #define NAME_BROWSE_MODE "browse_mode" + #define NAME_LOGGING "logging" +@@ -287,6 +288,11 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_MASTER_WAIT, ++ DEFAULT_MASTER_WAIT, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ + ret = conf_update(sec, NAME_NEGATIVE_TIMEOUT, + DEFAULT_NEGATIVE_TIMEOUT, CONF_ENV); + if (ret == CFG_FAIL) +@@ -1568,6 +1574,17 @@ unsigned int defaults_get_timeout(void) + return (unsigned int) timeout; + } + ++int defaults_get_master_wait(void) ++{ ++ long wait; ++ ++ wait = conf_get_number(autofs_gbl_sec, NAME_MASTER_WAIT); ++ if (wait < 0) ++ wait = atol(DEFAULT_MASTER_WAIT); ++ ++ return (int) wait; ++} ++ + unsigned int defaults_get_negative_timeout(void) + { + long n_timeout; +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -30,6 +30,11 @@ default is 10 minutes, but the default i + overrides this and sets the timeout to 5 minutes to be consistent + with earlier autofs releases. + .TP ++.B master_wait ++sets the default maximum time to wait for the master map to become ++available if it cannot be read at program start (program default -1, ++wait forever). ++.TP + .B negative_timeout + .br + Set the default timeout for caching failed key lookups (program default +--- autofs-5.0.7.orig/man/automount.8 ++++ autofs-5.0.7/man/automount.8 +@@ -37,6 +37,10 @@ The internal program default is 10 minut + installed configuration overrides this and sets the timeout + to 5 minutes to be consistent with earlier autofs releases. + .TP ++.I "\-M , \-\-master-wait " ++Set the maximum time to wait for the master map to become available ++if it cannot be read at program start. ++.TP + .I "\-n , \-\-negative\-timeout " + Set the default timeout for caching failed key lookups. The default is 60 seconds. + .TP +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -14,6 +14,13 @@ + # + timeout = 300 + # ++# master_wait - set the default maximum time to wait for the ++# master map to become available if it cannot ++# be read at program start (default -1, wait ++# forever). ++# ++#master_wait = -1 ++# + # negative_timeout - set the default negative timeout for + # failed mount attempts (default 60). + # +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -14,6 +14,13 @@ + # + timeout = 300 + # ++# master_wait - set the default maximum time to wait for the ++# master map to become available if it cannot ++# be read at program start (default -1, wait ++# forever). ++# ++# master_wait = -1 ++# + # negative_timeout - set the default negative timeout for + # failed mount attempts (default 60). + # diff --git a/SOURCES/autofs-5.1.2-add-ref-counting-to-struct-map_source.patch b/SOURCES/autofs-5.1.2-add-ref-counting-to-struct-map_source.patch new file mode 100644 index 0000000..3968130 --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-ref-counting-to-struct-map_source.patch @@ -0,0 +1,216 @@ +autofs-5.1.2 - add ref counting to struct map_source + +From: Ian Kent + +amd map format maps that are type "auto" frequently refer to the +current map in their map entries. + +While this isn't a problem for relatively small maps it can be very +wasteful for large maps and even more so for maps that have multi- +component keys that trigger type "auto" mounts as they progress down +the directory tree. + +So add a reference count in order for amd type "auto" mounts to use +the parent map if it matches. + +sun format maps are much less likley to use the same map and if they +do they are usually trivial, one line maps, so it isn't a problem. + +But, more importantly, sun format maps need to track recursive inclusion +and inclusion depth for a given map source when plus map inclusion is +used which prevents the map soucre from being shared. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/indirect.c | 7 ++++- + include/master.h | 3 ++ + lib/master.c | 22 +++++++++++++++++ + modules/mount_autofs.c | 60 ++++++++++++++++++++++++++++++++----------------- + 5 files changed, 72 insertions(+), 21 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -223,6 +223,7 @@ + - fix argc off by one in mount_autofs.c. + - fix _strncmp() usage. + - fix typos in README.amd-maps. ++- add ref counting to struct map_source. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/indirect.c ++++ autofs-5.0.7/daemon/indirect.c +@@ -96,7 +96,12 @@ static int do_mount_autofs_indirect(stru + struct mnt_list *mnts; + int ret; + +- ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; ++ /* If the map is being shared the exp_timeout can't be inherited ++ * from the map source since it may be different so the autofs ++ * point exp_runfreq must have already been set. ++ */ ++ if (ap->entry->maps->ref <= 1) ++ ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + + if (ops->version && !do_force_unlink) { + ap->flags |= MOUNT_FLAG_REMOUNT; +--- autofs-5.0.7.orig/include/master.h ++++ autofs-5.0.7/include/master.h +@@ -23,6 +23,7 @@ + #define MAP_FLAG_FORMAT_AMD 0x0001 + + struct map_source { ++ unsigned int ref; + unsigned int flags; + char *type; + char *format; +@@ -89,6 +90,8 @@ struct map_source * + master_add_map_source(struct master_mapent *, char *, char *, time_t, int, const char **); + struct map_source * + master_find_map_source(struct master_mapent *, const char *, const char *, int, const char **); ++struct map_source * ++master_get_map_source(struct master_mapent *, const char *, const char *, int, const char **); + void master_free_map_source(struct map_source *, unsigned int); + struct map_source * + master_find_source_instance(struct map_source *, const char *, const char *, int, const char **); +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -180,6 +180,7 @@ master_add_map_source(struct master_mape + if (!source) + return NULL; + memset(source, 0, sizeof(struct map_source)); ++ source->ref = 1; + + if (type) { + ntype = strdup(type); +@@ -231,6 +232,8 @@ master_add_map_source(struct master_mape + + this = __master_find_map_source(entry, type, format, argc, tmpargv); + if (this) { ++ error(entry->ap->logopt, ++ "map source used without taking reference"); + this->age = age; + master_free_map_source(source, 0); + master_source_unlock(entry); +@@ -329,8 +332,27 @@ struct map_source *master_find_map_sourc + return source; + } + ++struct map_source * ++master_get_map_source(struct master_mapent *entry, ++ const char *type, const char *format, ++ int argc, const char **argv) ++{ ++ struct map_source *source = NULL; ++ ++ master_source_readlock(entry); ++ source = __master_find_map_source(entry, type, format, argc, argv); ++ if (source) ++ source->ref++; ++ master_source_unlock(entry); ++ ++ return source; ++} ++ + static void __master_free_map_source(struct map_source *source, unsigned int free_cache) + { ++ /* instance map sources are not ref counted */ ++ if (source->ref && --source->ref) ++ return; + if (source->type) + free(source->type); + if (source->format) +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -208,18 +208,37 @@ int mount_mount(struct autofs_point *ap, + } + if (info->map) + argv[0] = info->map; ++ ++ if (options) { ++ p = options; ++ while ((p = strchr(p, ',')) != NULL) { ++ if (*p == ',') { ++ *p = '\0'; ++ p++; ++ } ++ argv[argc++] = p; ++ } ++ } ++ argv[argc] = NULL; ++ + /* +- * If the parent map format is amd and the format isn't +- * specified in the map entry set it from the parent map +- * source. ++ * For amd type "auto" the map is often re-used so check ++ * if the the parent map can be used and use it if it ++ * matches. ++ * ++ * Also if the parent map format is amd and the format ++ * isn't specified in the map entry set it from the parent ++ * map source. + */ +- if (!info->format && ap->entry->maps) { ++ source = NULL; ++ if (ap->entry->maps && ap->entry->maps->flags & MAP_FLAG_FORMAT_AMD) { + struct map_source *s = ap->entry->maps; ++ + /* + * For amd maps, if the format and source type aren't + * specified try and set them from the parent. + */ +- if (s->flags & MAP_FLAG_FORMAT_AMD) { ++ if (!info->format) { + info->format = strdup("amd"); + if (!info->format) + warn(ap->logopt, MODPREFIX +@@ -231,23 +250,18 @@ int mount_mount(struct autofs_point *ap, + "failed to set amd map type"); + } + } +- } + +- if (options) { +- p = options; +- while ((p = strchr(p, ',')) != NULL) { +- if (*p == ',') { +- *p = '\0'; +- p++; +- } +- argv[argc++] = p; +- } ++ source = master_get_map_source(ap->entry, ++ info->type, info->format, ++ argc, argv); ++ if (source) ++ entry->maps = source; + } +- argv[argc] = NULL; + +- source = master_add_map_source(entry, +- info->type, info->format, +- time(NULL), argc, argv); ++ if (!source) ++ source = master_add_map_source(entry, ++ info->type, info->format, ++ time(NULL), argc, argv); + if (!source) { + error(ap->logopt, + MODPREFIX "failed to add map source to entry"); +@@ -256,7 +270,13 @@ int mount_mount(struct autofs_point *ap, + return 1; + } + free_map_type_info(info); +- source->exp_timeout = timeout; ++ /* The exp_timeout can't be inherited if the map is shared, so ++ * the autofs point exp_runfreq must be set here. ++ */ ++ if (source->ref <= 1) ++ source->exp_timeout = timeout; ++ else ++ nap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + + mounts_mutex_lock(ap); + diff --git a/SOURCES/autofs-5.1.2-add-sss-master-map-wait-config-option.patch b/SOURCES/autofs-5.1.2-add-sss-master-map-wait-config-option.patch new file mode 100644 index 0000000..a4f6d3d --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-sss-master-map-wait-config-option.patch @@ -0,0 +1,172 @@ +autofs-5.1.2 - add sss master map wait config option + +From: Ian Kent + +When sssd is starting up it can sometimes return "no such entry" for a +short time until it has read in the LDAP map information. This affects +reading the master map at autofs startup and results in no automount +mounts if sssd is the primary map source. + +This problem should be resolved in sssd but it's a problem for the +moment so a configuration option, sss_master_map_wait, has been added +to work around it. + +The internal program default is 0, don't wait. If the work around is +needed try setting this to 10 seconds to work around it. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/defaults.h | 2 ++ + lib/defaults.c | 17 +++++++++++++++++ + man/autofs.conf.5.in | 7 +++++++ + modules/lookup_sss.c | 7 ++++--- + redhat/autofs.conf.default.in | 10 ++++++++++ + samples/autofs.conf.default.in | 10 ++++++++++ + 7 files changed, 51 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -241,6 +241,7 @@ + - factor out set_thread_mount_request_log_id(). + - add config option to use mount request log id. + - work around sss startup delay. ++- add sss master map wait config option. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -51,6 +51,7 @@ + #define DEFAULT_USE_HOSTNAME_FOR_MOUNTS "0" + #define DEFAULT_DISABLE_NOT_FOUND_MESSAGE "0" + ++#define DEFAULT_SSS_MASTER_MAP_WAIT "0" + #define DEFAULT_USE_MOUNT_REQUEST_LOG_ID "0" + + /* Config entry flags */ +@@ -171,6 +172,7 @@ const char *defaults_get_auth_conf_file( + unsigned int defaults_get_map_hash_table_size(void); + unsigned int defaults_use_hostname_for_mounts(void); + unsigned int defaults_disable_not_found_message(void); ++unsigned int defaults_get_sss_master_map_wait(void); + unsigned int defaults_get_use_mount_request_log_id(void); + + unsigned int conf_amd_mount_section_exists(const char *); +--- autofs-5.0.7.orig/lib/defaults.c ++++ autofs-5.0.7/lib/defaults.c +@@ -76,6 +76,7 @@ + #define NAME_USE_HOSTNAME_FOR_MOUNTS "use_hostname_for_mounts" + #define NAME_DISABLE_NOT_FOUND_MESSAGE "disable_not_found_message" + ++#define NAME_SSS_MASTER_MAP_WAIT "sss_master_map_wait" + #define NAME_USE_MOUNT_REQUEST_LOG_ID "use_mount_request_log_id" + + #define NAME_AMD_ARCH "arch" +@@ -356,6 +357,11 @@ static int conf_load_autofs_defaults(voi + if (ret == CFG_FAIL) + goto error; + ++ ret = conf_update(sec, NAME_SSS_MASTER_MAP_WAIT, ++ DEFAULT_SSS_MASTER_MAP_WAIT, CONF_ENV); ++ if (ret == CFG_FAIL) ++ goto error; ++ + ret = conf_update(sec, NAME_USE_MOUNT_REQUEST_LOG_ID, + DEFAULT_USE_MOUNT_REQUEST_LOG_ID, CONF_ENV); + if (ret == CFG_FAIL) +@@ -1850,6 +1856,17 @@ unsigned int defaults_get_use_mount_requ + + return res; + } ++ ++unsigned int defaults_get_sss_master_map_wait(void) ++{ ++ int res; ++ ++ res = conf_get_yesno(autofs_gbl_sec, NAME_SSS_MASTER_MAP_WAIT); ++ if (res < 0) ++ res = atoi(DEFAULT_SSS_MASTER_MAP_WAIT); ++ ++ return res; ++} + + unsigned int conf_amd_mount_section_exists(const char *section) + { +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -142,6 +142,13 @@ That produces, IMHO, unnecessary noise i + has been added to provide the ability to turn it off. The default is "no" + to maintain the current behaviour. + .TP ++.B sss_master_map_wait ++.br ++Set the time to wait and retry if sssd returns "no such entry" when starting ++up. When sssd is starting up it can sometimes return "no such entry" for a ++short time until it has read in the LDAP map information. Default is 0 seconds, ++don't wait. ++.TP + .B use_mount_request_log_id + .br + Set whether to use a mount request log id so that log entries for specific +--- autofs-5.0.7.orig/modules/lookup_sss.c ++++ autofs-5.0.7/modules/lookup_sss.c +@@ -32,8 +32,6 @@ + + /* Half a second between retries */ + #define SETAUTOMOUNTENT_MASTER_INTERVAL 500000000 +-/* Try for 10 seconds */ +-#define SETAUTOMOUNTENT_MASTER_RETRIES 10 * 2 + + #define MODPREFIX "lookup(sss): " + +@@ -304,7 +302,10 @@ int lookup_read_master(struct master *ma + if (ret != ENOENT) + return NSS_STATUS_UNAVAIL; + +- retries = SETAUTOMOUNTENT_MASTER_RETRIES; ++ retries = defaults_get_sss_master_map_wait() * 2; ++ if (retries <= 0) ++ return NSS_STATUS_NOTFOUND; ++ + ret = setautomntent_wait(logopt, + ctxt, ctxt->mapname, &sss_ctxt, + retries); +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -173,6 +173,16 @@ mount_nfs_default_protocol = 4 + # + #disable_not_found_message = "no" + # ++# sss_master_map_wait - When sssd is starting up it can sometimes return ++# "no such entry" for a short time until it has read ++# in the LDAP map information. Internal default is 0 ++# seconds, don't wait but if there is a problem with ++# autofs not finding the master map at startup (when ++# it should) then try setting this to 10 to work ++# around it. ++# ++#sss_master_map_wait = 0 ++# + # Otions for the amd parser within autofs. + # + # amd configuration options that are aren't used, haven't been +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -172,6 +172,16 @@ browse_mode = no + # + #disable_not_found_message = "no" + # ++# sss_master_map_wait - When sssd is starting up it can sometimes return ++# "no such entry" for a short time until it has read ++# in the LDAP map information. Internal default is 0 ++# seconds, don't wait but if there is a problem with ++# autofs not finding the master map at startup (when ++# it should) then try setting this to 10 to work ++# around it. ++# ++#sss_master_map_wait = 0 ++# + # Otions for the amd parser within autofs. + # + # amd configuration options that are aren't used, haven't been diff --git a/SOURCES/autofs-5.1.2-add-support-for-amd-browsable-option.patch b/SOURCES/autofs-5.1.2-add-support-for-amd-browsable-option.patch new file mode 100644 index 0000000..2570d29 --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-support-for-amd-browsable-option.patch @@ -0,0 +1,355 @@ +autofs-5.1.2 - add support for amd browsable option + +From: Ian Kent + +Add support for the "browsable_dirs" configuration option and the +pseudo mount option "browsable" of amd format maps. + +Note that support for the configuration option "browsable_dirs = full" +and the pseudo mount option "fullybrowsable" of type auto map entries +cannot be implemented using the existing kernel to user space autofs +implementation. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + README.amd-maps | 2 + daemon/lookup.c | 106 ++++++++++++++++++++++++++++++++--------- + lib/master_parse.y | 14 ++++- + man/autofs.conf.5.in | 7 ++ + modules/amd_parse.y | 3 - + modules/mount_autofs.c | 8 +-- + modules/parse_amd.c | 2 + redhat/autofs.conf.default.in | 7 +- + samples/autofs.conf.default.in | 7 +- + 10 files changed, 120 insertions(+), 37 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -224,6 +224,7 @@ + - fix _strncmp() usage. + - fix typos in README.amd-maps. + - add ref counting to struct map_source. ++- add support for amd browsable option. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/README.amd-maps ++++ autofs-5.0.7/README.amd-maps +@@ -101,7 +101,7 @@ What hasn't been implemented + ---------------------------- + + The configuration options fully_qualified_hosts, unmount_on_exit and +-browsable_dirs (and a couple of others) aren't implemented. ++browsable_dirs = full (and a couple of others) aren't implemented. + + Map types (sources) ndbm, passwd are not implemented. + The map source "sss" can't be used for amd format maps. +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -663,6 +663,56 @@ int lookup_nss_read_map(struct autofs_po + return 0; + } + ++static char *make_browse_path(unsigned int logopt, ++ const char *root, const char *key, ++ const char *prefix) ++{ ++ unsigned int l_prefix; ++ unsigned int k_len, r_len; ++ char *k_start; ++ char *path; ++ ++ k_start = (char *) key; ++ k_len = strlen(key); ++ l_prefix = 0; ++ ++ if (prefix) { ++ l_prefix = strlen(prefix); ++ ++ if (l_prefix > k_len) ++ return NULL; ++ ++ /* If the prefix doesn't match the beginning ++ * of the key this entry isn't a sub directory ++ * at this level. ++ */ ++ if (strncmp(key, prefix, l_prefix)) ++ return NULL; ++ ++ /* Directory entry starts following the prefix */ ++ k_start += l_prefix; ++ } ++ ++ /* No remaining "/" allowed here */ ++ if (strchr(k_start, '/')) ++ return NULL; ++ ++ r_len = strlen(root); ++ ++ if ((r_len + strlen(k_start)) > KEY_MAX_LEN) ++ return NULL; ++ ++ path = malloc(r_len + k_len + 2); ++ if (!path) { ++ warn(logopt, "failed to allocate full path"); ++ return NULL; ++ } ++ ++ sprintf(path, "%s/%s", root, k_start); ++ ++ return path; ++} ++ + int lookup_ghost(struct autofs_point *ap, const char *root) + { + struct master_mapent *entry = ap->entry; +@@ -706,10 +756,19 @@ int lookup_ghost(struct autofs_point *ap + if (!me->mapent) + goto next; + +- if (!strcmp(me->key, "*")) ++ /* Wildcard cannot be a browse directory and amd map ++ * keys may end with the wildcard. ++ */ ++ if (strchr(me->key, '*')) + goto next; + ++ /* This will also take care of amd "/defaults" entry as ++ * amd map keys are not allowd to start with "/" ++ */ + if (*me->key == '/') { ++ if (map->flags & MAP_FLAG_FORMAT_AMD) ++ goto next; ++ + /* It's a busy multi-mount - leave till next time */ + if (list_empty(&me->multi_list)) + error(ap->logopt, +@@ -717,12 +776,10 @@ int lookup_ghost(struct autofs_point *ap + goto next; + } + +- fullpath = malloc(strlen(me->key) + strlen(root) + 3); +- if (!fullpath) { +- warn(ap->logopt, "failed to allocate full path"); ++ fullpath = make_browse_path(ap->logopt, ++ root, me->key, ap->pref); ++ if (!fullpath) + goto next; +- } +- sprintf(fullpath, "%s/%s", root, me->key); + + ret = stat(fullpath, &st); + if (ret == -1 && errno != ENOENT) { +@@ -732,6 +789,17 @@ int lookup_ghost(struct autofs_point *ap + goto next; + } + ++ /* Directory already exists? */ ++ if (!ret) { ++ /* Shouldn't need this ++ me->dev = st.st_dev; ++ me->ino = st.st_ino; ++ */ ++ debug(ap->logopt, "me->dev %d me->ino %d", me->dev, me->ino); ++ free(fullpath); ++ goto next; ++ } ++ + ret = mkdir_path(fullpath, 0555); + if (ret < 0 && errno != EEXIST) { + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); +@@ -1238,28 +1306,23 @@ void lookup_close_lookup(struct autofs_p + return; + } + +-static char *make_fullpath(const char *root, const char *key) ++static char *make_fullpath(struct autofs_point *ap, const char *key) + { ++ char *path = NULL; + int l; +- char *path; + +- if (*key == '/') { ++ if (*key != '/') ++ path = make_browse_path(ap->logopt, ap->path, key, ap->pref); ++ else { + l = strlen(key) + 1; + if (l > KEY_MAX_LEN) +- return NULL; ++ goto out; + path = malloc(l); + if (!path) +- return NULL; ++ goto out; + strcpy(path, key); +- } else { +- l = strlen(key) + 1 + strlen(root) + 1; +- if (l > KEY_MAX_LEN) +- return NULL; +- path = malloc(l); +- if (!path) +- return NULL; +- sprintf(path, "%s/%s", root, key); + } ++out: + return path; + } + +@@ -1290,13 +1353,14 @@ void lookup_prune_one_cache(struct autof + + key = strdup(me->key); + me = cache_enumerate(mc, me); +- if (!key || !strcmp(key, "*")) { ++ /* Don't consider any entries with a wildcard */ ++ if (!key || strchr(key, '*')) { + if (key) + free(key); + continue; + } + +- path = make_fullpath(ap->path, key); ++ path = make_fullpath(ap, key); + if (!path) { + warn(ap->logopt, "can't malloc storage for path"); + free(key); +--- autofs-5.0.7.orig/lib/master_parse.y ++++ autofs-5.0.7/lib/master_parse.y +@@ -806,14 +806,22 @@ int master_parse_entry(const char *buffe + + if (format && !strcmp(format, "amd")) { + unsigned int loglevel = conf_amd_get_log_options(); ++ unsigned int flags = conf_amd_get_flags(path); ++ + if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) + logopt = LOGOPT_DEBUG; + else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) + logopt = LOGOPT_VERBOSE; +- /* amd mounts don't support browse mode */ +- ghost = 0; +- } + ++ /* It isn't possible to provide the fullybrowsable amd ++ * browsing functionality within the autofs framework. ++ * This flag will not be set if browsable_dirs = full ++ * in the configuration or fullybrowsable is present as ++ * an option. ++ */ ++ if (flags & CONF_BROWSABLE_DIRS) ++ ghost = 1; ++ } + + if (timeout < 0) { + /* +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -348,7 +348,12 @@ and that will be done. + .TP + .B browsable_dirs + .br +-Not yet implemented. ++Allow map keys to be shown in directory listings. This option ++can have values of "yes" or "no". The default is "no". A variation ++of this option, "browsable", can be used as a pseudo mount option ++in type "auto" map entries to provide provide browsing funtionality ++in sub-mounts. The amd "browsable_dirs = full" option cannot be ++implemented within the current autofs framework and is not supported. + .TP + .B exec_map_timeout + .br +--- autofs-5.0.7.orig/modules/amd_parse.y ++++ autofs-5.0.7/modules/amd_parse.y +@@ -432,8 +432,7 @@ option_assignment: MAP_OPTION OPTION_ASS + + options: OPTION + { +- if (!strcmp($1, "browsable") || +- !strcmp($1, "fullybrowsable") || ++ if (!strcmp($1, "fullybrowsable") || + !strcmp($1, "nounmount") || + !strcmp($1, "unmount")) { + sprintf(msg_buf, "option %s is not currently " +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -121,11 +121,13 @@ int mount_mount(struct autofs_point *ap, + while (*comma != '\0' && *comma != ',') + comma++; + +- if (_strncmp("nobrowse", cp, 8) == 0) ++ if (_strncmp("nobrowse", cp, 8) == 0 || ++ _strncmp("nobrowsable", cp, 11) == 0) + ghost = 0; + else if (_strncmp("nobind", cp, 6) == 0) + nobind = 1; +- else if (_strncmp("browse", cp, 6) == 0) ++ else if (_strncmp("browse", cp, 6) == 0 || ++ _strncmp("browsable", cp, 9) == 0) + ghost = 1; + else if (_strncmp("symlink", cp, 7) == 0) + symlnk = 1; +@@ -286,8 +288,6 @@ int mount_mount(struct autofs_point *ap, + nap->pref = am_entry->pref; + am_entry->pref = NULL; + } +- /* amd mounts don't support browse mode */ +- nap->flags &= ~MOUNT_FLAG_GHOST; + } + + if (handle_mounts_startup_cond_init(&suc)) { +--- autofs-5.0.7.orig/modules/parse_amd.c ++++ autofs-5.0.7/modules/parse_amd.c +@@ -932,7 +932,7 @@ static int do_auto_mount(struct autofs_p + } + + return do_mount(ap, ap->path, +- name, strlen(name), target, "autofs", NULL); ++ name, strlen(name), target, "autofs", entry->opts); + } + + static int do_link_mount(struct autofs_point *ap, const char *name, +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -264,8 +264,6 @@ mount_nfs_default_protocol = 4 + # is a sensible option to implement and that will be + # done. + # +-# browsable_dirs - not yet implemented. +-# + # exec_map_timeout - a timeout is not currently used for + # for program maps, might be implemented. + # +@@ -308,6 +306,11 @@ mount_nfs_default_protocol = 4 + # takes its default value from the autofs internal default + # of 600 seconds. + # ++# browsable_dirs - make map keys visible in directory listings. ++# Note that support for the "fullybrowsable" option cannot ++# be added using the existing kernel to user space autofs ++# implementation. ++# + # autofs_use_lofs - if set to "yes" autofs will attempt to use bind + # mounts for type "auto" when possible. + # +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -263,8 +263,6 @@ browse_mode = no + # is a sensible option to implement and that will be + # done. + # +-# browsable_dirs - not yet implemented. +-# + # exec_map_timeout - a timeout is not currently used for + # for program maps, might be implemented. + # +@@ -307,6 +305,11 @@ browse_mode = no + # takes its default value from the autofs internal default + # of 600 seconds. + # ++# browsable_dirs - make map keys visible in directory listings. ++# Note that support for the "fullybrowsable" option cannot ++# be added using the existing kernel to user space autofs ++# implementation. ++# + # autofs_use_lofs - if set to "yes" autofs will attempt to use bind + # mounts for type "auto" when possible. + # diff --git a/SOURCES/autofs-5.1.2-add-the-mount-requestor-s-pid-to-pending_args.patch b/SOURCES/autofs-5.1.2-add-the-mount-requestor-s-pid-to-pending_args.patch new file mode 100644 index 0000000..0d7d077 --- /dev/null +++ b/SOURCES/autofs-5.1.2-add-the-mount-requestor-s-pid-to-pending_args.patch @@ -0,0 +1,56 @@ +autofs-5.1.2 - add the mount requestor's pid to pending_args + +From: Lars R. Damerow + +This will make it easier to log more information about the requesting +process as the mount request proceeds. + +Signed-off-by: Lars R. Damerow +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 1 + + daemon/indirect.c | 1 + + include/automount.h | 1 + + 4 files changed, 4 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -235,6 +235,7 @@ + - handle amd cache option all in amd type auto mounts. + - fix bogus check in expire_cleanup(). + - delay submount exit for amd submounts. ++- add the mount requestor's pid to pending_args. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -1465,6 +1465,7 @@ int handle_packet_missing_direct(struct + mt->type = NFY_MOUNT; + mt->uid = pkt->uid; + mt->gid = pkt->gid; ++ mt->pid = pkt->pid; + mt->wait_queue_token = pkt->wait_queue_token; + + status = pthread_create(&thid, &th_attr_detached, do_mount_direct, mt); +--- autofs-5.0.7.orig/daemon/indirect.c ++++ autofs-5.0.7/daemon/indirect.c +@@ -860,6 +860,7 @@ int handle_packet_missing_indirect(struc + mt->dev = pkt->dev; + mt->uid = pkt->uid; + mt->gid = pkt->gid; ++ mt->pid = pkt->pid; + mt->wait_queue_token = pkt->wait_queue_token; + + status = pthread_create(&thid, &th_attr_detached, do_mount_indirect, mt); +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -425,6 +425,7 @@ struct pending_args { + unsigned int len; /* Name field len */ + uid_t uid; /* uid of requestor */ + gid_t gid; /* gid of requestor */ ++ pid_t pid; /* pid of requestor */ + unsigned long wait_queue_token; /* Associated kernel wait token */ + }; + diff --git a/SOURCES/autofs-5.1.2-capture-cache-option-and-its-settings-during-parsing.patch b/SOURCES/autofs-5.1.2-capture-cache-option-and-its-settings-during-parsing.patch new file mode 100644 index 0000000..239c133 --- /dev/null +++ b/SOURCES/autofs-5.1.2-capture-cache-option-and-its-settings-during-parsing.patch @@ -0,0 +1,86 @@ +autofs-5.1.2 - capture cache option and its settings during parsing + +From: Ian Kent + +The amd map format parser was not aware of the optional sync +parameter of the cache option. + +Make the parser aware of the sync option and capture the cache +option and its settings during map parsing. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/parse_amd.h | 7 +++++++ + modules/amd_parse.y | 12 +++++++++--- + modules/amd_tok.l | 2 +- + 4 files changed, 18 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -230,6 +230,7 @@ + - include amd mount sections mounts in master mounts list. + - check for conflicting amd section mounts. + - add function conf_get_map_options(). ++- capture cache option and its settings during parsing. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/parse_amd.h ++++ autofs-5.0.7/include/parse_amd.h +@@ -39,9 +39,16 @@ + #define AMD_DEFAULTS_RESET 0x02000000 + #define AMD_DEFAULTS_MASK 0xff000000 + ++#define AMD_CACHE_OPTION_NONE 0x0000 ++#define AMD_CACHE_OPTION_INC 0x0001 ++#define AMD_CACHE_OPTION_ALL 0x0002 ++#define AMD_CACHE_OPTION_REGEXP 0x0004 ++#define AMD_CACHE_OPTION_SYNC 0x8000 ++ + struct amd_entry { + char *path; + unsigned long flags; ++ unsigned int cache_opts; + char *type; + char *map_type; + char *pref; +--- autofs-5.0.7.orig/modules/amd_parse.y ++++ autofs-5.0.7/modules/amd_parse.y +@@ -424,9 +424,14 @@ option_assignment: MAP_OPTION OPTION_ASS + } + | MAP_OPTION OPTION_ASSIGN CACHE_OPTION + { +- sprintf(msg_buf, "option %s is not used, autofs " +- "default caching is always used", $1); +- amd_info(msg_buf); ++ if (strncmp($3, "inc", 3)) ++ entry.cache_opts = AMD_CACHE_OPTION_INC; ++ else if (strncmp($3, "all", 3)) ++ entry.cache_opts = AMD_CACHE_OPTION_ALL; ++ else if (strncmp($3, "re", 2)) ++ entry.cache_opts = AMD_CACHE_OPTION_REGEXP; ++ if (strstr($3, "sync")) ++ entry.cache_opts |= AMD_CACHE_OPTION_SYNC; + } + ; + +@@ -534,6 +539,7 @@ static int amd_msg(const char *s) + static void local_init_vars(void) + { + memset(&entry, 0, sizeof(entry)); ++ entry.cache_opts = AMD_CACHE_OPTION_NONE; + memset(opts, 0, sizeof(opts)); + } + +--- autofs-5.0.7.orig/modules/amd_tok.l ++++ autofs-5.0.7/modules/amd_tok.l +@@ -101,7 +101,7 @@ NOPT ({SSTR}|(({IP4ADDR}(\/{V4MASK})?)| + MAPOPT (fs|type|maptype|pref|sublink|cache) + MNTOPT (opts|addopts|remopts) + FSOPTS (rhost|rfs|dev|cachedir|mount|unmount|umount|delay) +-CHEOPT (mapdefault|none|inc|re|regexp|all) ++CHEOPT ((mapdefault|none|inc|re|regexp|all)(,sync)?) + MAPTYPE (file|nis|nisplus|ldap|hesiod|exec|ndbm|passwd|union) + FSTYPE_LOCAL (link|linkx|lofs|ufs|ext2|ext3|ext4|xfs|jfs|cdfs|cachefs) + FSTYPE_NET (nfs|nfsx|nfsl|host) diff --git a/SOURCES/autofs-5.1.2-check-NFS-server-availability-on-local-mount-fallback.patch b/SOURCES/autofs-5.1.2-check-NFS-server-availability-on-local-mount-fallback.patch new file mode 100644 index 0000000..1a12258 --- /dev/null +++ b/SOURCES/autofs-5.1.2-check-NFS-server-availability-on-local-mount-fallback.patch @@ -0,0 +1,96 @@ +autofs-5.1.2 - check NFS server availability on local mount fallback + +From: Ian Kent + +The availability probe isn't done for anything autofs thinks is a +local mount because it's the local machine. + +It first tries a bind mount and if that fails it falls back to trying +a local NFS mount. If the local NFS server is not running mount.nfs(8) +can suffer a lengthy timeout. + +So check for the bind mount fallback case and check if an NFS server +is responding before trying the mount. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/rpc_subs.c | 11 +++++++++++ + modules/mount_nfs.c | 15 ++++++++++++++- + 3 files changed, 26 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -215,6 +215,7 @@ + - make lookup_nss_read_master() return nss status. + - make set_direct_mount_catatonic() more general. + - set autofs mounts catatonic at exit. ++- check NFS server availability on local mount fallback. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/rpc_subs.c ++++ autofs-5.0.7/lib/rpc_subs.c +@@ -1053,6 +1053,7 @@ static int __rpc_ping(const char *host, + + int rpc_ping(const char *host, long seconds, long micros, unsigned int option) + { ++ unsigned long vers4 = NFS4_VERSION; + unsigned long vers3 = NFS3_VERSION; + unsigned long vers2 = NFS2_VERSION; + int status; +@@ -1065,6 +1066,12 @@ int rpc_ping(const char *host, long seco + if (status > 0) + return RPC_PING_V3 | RPC_PING_UDP; + ++ /* UDP isn't recommended for NFSv4, don't bother checking it. ++ status = __rpc_ping(host, vers4, IPPROTO_UDP, seconds, micros, option); ++ if (status > 0) ++ return RPC_PING_V4 | RPC_PING_UDP; ++ */ ++ + status = __rpc_ping(host, vers2, IPPROTO_TCP, seconds, micros, option); + if (status > 0) + return RPC_PING_V2 | RPC_PING_TCP; +@@ -1073,6 +1080,10 @@ int rpc_ping(const char *host, long seco + if (status > 0) + return RPC_PING_V3 | RPC_PING_TCP; + ++ status = __rpc_ping(host, vers4, IPPROTO_TCP, seconds, micros, option); ++ if (status > 0) ++ return RPC_PING_V4 | RPC_PING_TCP; ++ + return status; + } + +--- autofs-5.0.7.orig/modules/mount_nfs.c ++++ autofs-5.0.7/modules/mount_nfs.c +@@ -347,6 +347,19 @@ dont_probe: + strcat(loc, ":"); + strcat(loc, this->path); + ++ /* If this is a fallback from a bind mount failure ++ * check if the local NFS server is available to try ++ * and prevent lengthy mount failure waits. ++ */ ++ if (this->proximity == PROXIMITY_LOCAL) { ++ char *host = this->name ? this->name : "localhost"; ++ int ret; ++ ++ ret = rpc_ping(host, 2, 0, RPC_CLOSE_DEFAULT); ++ if (ret <= 0) ++ goto next; ++ } ++ + if (nfsoptions && *nfsoptions) { + debug(ap->logopt, + MODPREFIX "calling mount -t %s " SLOPPY +@@ -369,7 +382,7 @@ dont_probe: + free_host_list(&hosts); + return 0; + } +- ++next: + free(loc); + this = this->next; + } diff --git a/SOURCES/autofs-5.1.2-check-for-conflicting-amd-section-mounts.patch b/SOURCES/autofs-5.1.2-check-for-conflicting-amd-section-mounts.patch new file mode 100644 index 0000000..6a7ea94 --- /dev/null +++ b/SOURCES/autofs-5.1.2-check-for-conflicting-amd-section-mounts.patch @@ -0,0 +1,113 @@ +autofs-5.1.2 - check for conflicting amd section mounts + +From: Ian Kent + +Allowing the addition of amd section mounts to the master mounts list +can lead to conflicting mount point paths. + +Check for conflicts and skip the amd mount section mounts if a conflict +with the master map mounts is found. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + include/master.h | 1 + lib/master.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- + 3 files changed, 58 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -228,6 +228,7 @@ + - add function conf_amd_get_map_name(). + - add function conf_amd_get_mount_paths(). + - include amd mount sections mounts in master mounts list. ++- check for conflicting amd section mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/master.h ++++ autofs-5.0.7/include/master.h +@@ -106,6 +106,7 @@ void master_source_lock_cleanup(void *); + void master_source_current_wait(struct master_mapent *); + void master_source_current_signal(struct master_mapent *); + struct master_mapent *master_find_mapent(struct master *, const char *); ++unsigned int master_partial_match_mapent(struct master *, const char *); + struct autofs_point *__master_find_submount(struct autofs_point *, const char *); + struct autofs_point *master_find_submount(struct autofs_point *, const char *); + struct amd_entry *__master_find_amdmount(struct autofs_point *, const char *); +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -710,6 +710,53 @@ struct master_mapent *master_find_mapent + return NULL; + } + ++unsigned int master_partial_match_mapent(struct master *master, const char *path) ++{ ++ struct list_head *head, *p; ++ size_t path_len = strlen(path); ++ int ret = 0; ++ ++ head = &master->mounts; ++ list_for_each(p, head) { ++ struct master_mapent *entry; ++ size_t entry_len; ++ size_t cmp_len; ++ ++ entry = list_entry(p, struct master_mapent, list); ++ ++ entry_len = strlen(entry->path); ++ cmp_len = min(entry_len, path_len); ++ ++ if (!strncmp(entry->path, path, cmp_len)) { ++ /* paths are equal, matching master map entry ? */ ++ if (entry_len == path_len) { ++ if (entry->maps && ++ entry->maps->flags & MAP_FLAG_FORMAT_AMD) ++ ret = 1; ++ else ++ ret = -1; ++ break; ++ } ++ ++ /* amd mount conflicts with entry mount */ ++ if (entry_len > path_len && ++ *(entry->path + path_len) == '/') { ++ ret = -1; ++ break; ++ } ++ ++ /* entry mount conflicts with amd mount */ ++ if (entry_len < path_len && ++ *(path + entry_len) == '/') { ++ ret = -1; ++ break; ++ } ++ } ++ } ++ ++ return ret; ++} ++ + struct autofs_point *__master_find_submount(struct autofs_point *ap, const char *path) + { + struct list_head *head, *p; +@@ -936,10 +983,16 @@ static void master_add_amd_mount_section + char *type = NULL; + char *map = NULL; + +- entry = master_find_mapent(master, path); +- if (entry) { ++ ret = master_partial_match_mapent(master, path); ++ if (ret) { ++ /* If this amd entry is already present in the ++ * master map it's not a duplicate, don't issue ++ * an error message. ++ */ ++ if (ret == 1) ++ goto next; + info(m_logopt, +- "ignoring duplicate amd section mount %s", ++ "amd section mount path conflict, %s ignored", + path); + goto next; + } diff --git a/SOURCES/autofs-5.1.2-create-thread-local-ID-for-mount-attempts.patch b/SOURCES/autofs-5.1.2-create-thread-local-ID-for-mount-attempts.patch new file mode 100644 index 0000000..84a130c --- /dev/null +++ b/SOURCES/autofs-5.1.2-create-thread-local-ID-for-mount-attempts.patch @@ -0,0 +1,177 @@ +autofs-5.1.2 - create thread-local ID for mount attempts + +From: Lars R. Damerow + +This patch creates key_thread_attempt_id as a pthread key and populates it +in each new thread serving a mount attempt. This ID can be used in output logs +as an easy string to grep for, allowing admins to quickly see a mount attempt's +log entries without the messages from other attempts interleaved. + +The contents of the ID are intended to be opaque, but to get a chance at +a unique value for each mount attempt, this patch does a very simple hash +computation of the thread's wait_queue_token, the pid of the requesting +process, and the key for the mount. The hash is based on the public domain +sdbm library. + +Signed-off-by: Lars R. Damerow +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 24 ++++++++++++++++++++++++ + daemon/direct.c | 17 +++++++++++++++++ + daemon/indirect.c | 17 +++++++++++++++++ + include/automount.h | 6 ++++++ + 5 files changed, 65 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -236,6 +236,7 @@ + - fix bogus check in expire_cleanup(). + - delay submount exit for amd submounts. + - add the mount requestor's pid to pending_args. ++- create thread-local ID for mount attempts. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -89,6 +89,7 @@ struct startup_cond suc = { + PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0}; + + pthread_key_t key_thread_stdenv_vars; ++pthread_key_t key_thread_attempt_id = (pthread_key_t) 0L; + + #define MAX_OPEN_FILES 10240 + +@@ -98,6 +99,17 @@ static int umount_all(struct autofs_poin + + extern struct master *master_list; + ++/* simple string hash based on public domain sdbm library */ ++unsigned long sdbm_hash(const char *str, unsigned long seed) ++{ ++ unsigned long hash = seed; ++ char c; ++ ++ while ((c = *str++)) ++ hash = c + (hash << 6) + (hash << 16) - hash; ++ return hash; ++} ++ + static int do_mkdir(const char *parent, const char *path, mode_t mode) + { + int status; +@@ -2441,6 +2453,18 @@ int main(int argc, char *argv[]) + program); + master_kill(master_list); + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ release_flag_file(); ++ macro_free_global_table(); ++ exit(1); ++ } ++ ++ status = pthread_key_create(&key_thread_attempt_id, free); ++ if (status) { ++ logerr("%s: failed to create thread data key for attempt ID!", ++ program); ++ master_kill(master_list); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + release_flag_file(); + macro_free_global_table(); +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -1210,6 +1210,8 @@ static void *do_mount_direct(void *arg) + struct autofs_point *ap; + struct stat st; + int status, state; ++ char attempt_id_comp[20]; ++ unsigned long *attempt_id; + + args = (struct pending_args *) arg; + +@@ -1219,6 +1221,21 @@ static void *do_mount_direct(void *arg) + + ap = mt.ap; + ++ attempt_id = pthread_getspecific(key_thread_attempt_id); ++ if (attempt_id == NULL) { ++ attempt_id = (unsigned long *) calloc(1, sizeof(unsigned long)); ++ if (attempt_id == NULL) ++ fatal(ENOMEM); ++ snprintf(attempt_id_comp, 20, "%ld", mt.wait_queue_token); ++ *attempt_id = sdbm_hash(attempt_id_comp, 0); ++ snprintf(attempt_id_comp, 20, "%u", mt.pid); ++ *attempt_id = sdbm_hash(attempt_id_comp, *attempt_id); ++ *attempt_id = sdbm_hash(mt.name, *attempt_id); ++ status = pthread_setspecific(key_thread_attempt_id, attempt_id); ++ if (status != 0) ++ fatal(status); ++ } ++ + args->signaled = 1; + status = pthread_cond_signal(&args->cond); + if (status) +--- autofs-5.0.7.orig/daemon/indirect.c ++++ autofs-5.0.7/daemon/indirect.c +@@ -726,6 +726,8 @@ static void *do_mount_indirect(void *arg + char buf[PATH_MAX + 1]; + struct stat st; + int len, status, state; ++ char attempt_id_comp[20]; ++ unsigned long *attempt_id; + + args = (struct pending_args *) arg; + +@@ -735,6 +737,21 @@ static void *do_mount_indirect(void *arg + + ap = mt.ap; + ++ attempt_id = pthread_getspecific(key_thread_attempt_id); ++ if (attempt_id == NULL) { ++ attempt_id = (unsigned long *) calloc(1, sizeof(unsigned long)); ++ if (attempt_id == NULL) ++ fatal(ENOMEM); ++ snprintf(attempt_id_comp, 20, "%ld", mt.wait_queue_token); ++ *attempt_id = sdbm_hash(attempt_id_comp, 0); ++ snprintf(attempt_id_comp, 20, "%u", mt.pid); ++ *attempt_id = sdbm_hash(attempt_id_comp, *attempt_id); ++ *attempt_id = sdbm_hash(mt.name, *attempt_id); ++ status = pthread_setspecific(key_thread_attempt_id, attempt_id); ++ if (status != 0) ++ fatal(status); ++ } ++ + args->signaled = 1; + status = pthread_cond_signal(&args->cond); + if (status) +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -76,6 +76,8 @@ int load_autofs4_module(void); + #define SMB_SUPER_MAGIC 0x0000517BL + #define CIFS_MAGIC_NUMBER 0xFF534D42L + ++#define ATTEMPT_ID_SIZE 24 ++ + /* This sould be enough for at least 20 host aliases */ + #define HOST_ENT_BUF_SIZE 2048 + +@@ -241,6 +243,8 @@ const char **copy_argv(int argc, const c + int compare_argv(int argc1, const char **argv1, int argc2, const char **argv2); + int free_argv(int argc, const char **argv); + ++unsigned long sdbm_hash(const char *str, unsigned long seed); ++ + void dump_core(void); + int aquire_lock(void); + void release_lock(void); +@@ -480,6 +484,8 @@ struct thread_stdenv_vars { + + extern pthread_key_t key_thread_stdenv_vars; + ++extern pthread_key_t key_thread_attempt_id; ++ + struct kernel_mod_version { + unsigned int major; + unsigned int minor; diff --git a/SOURCES/autofs-5.1.2-delay-submount-exit-for-amd-submounts.patch b/SOURCES/autofs-5.1.2-delay-submount-exit-for-amd-submounts.patch new file mode 100644 index 0000000..557fae9 --- /dev/null +++ b/SOURCES/autofs-5.1.2-delay-submount-exit-for-amd-submounts.patch @@ -0,0 +1,59 @@ +autofs-5.1.2 - delay submount exit for amd submounts + +From: Ian Kent + +For amd format maps it's better to not expire away submounts (amd +type "auto" mounts) straight way. + +This is because of the common heavy reuse of maps in amd maps and +we want to try and avoid constantly re-reading large maps. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/state.c | 18 +++++++++++++++--- + 2 files changed, 16 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -234,6 +234,7 @@ + - handle map_option cache for top level mounts. + - handle amd cache option all in amd type auto mounts. + - fix bogus check in expire_cleanup(). ++- delay submount exit for amd submounts. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/state.c ++++ autofs-5.0.7/daemon/state.c +@@ -132,15 +132,27 @@ void expire_cleanup(void *arg) + * mount expires in a reasonable time. Just skip + * one expire check after it's no longer busy before + * allowing it to shutdown. ++ * ++ * But if this mount point is an amd format map it ++ * is better to keep the mount around longer. This ++ * is because of the common heavy reuse of maps in ++ * amd maps and we want to try and avoid constantly ++ * re-reading large maps. + */ + if (ap->submount && !success) { + rv = ops->askumount(ap->logopt, ap->ioctlfd, &idle); + if (!rv && idle && ap->submount > 1) { +- next = ST_SHUTDOWN_PENDING; +- break; ++ struct map_source *map = ap->entry->maps; ++ ++ if (ap->submount > 4 || ++ !(map->flags & MAP_FLAG_FORMAT_AMD)) { ++ next = ST_SHUTDOWN_PENDING; ++ break; ++ } + } + ap->submount++; +- } ++ } else if (ap->submount > 1) ++ ap->submount = 1; + + if (ap->state == ST_EXPIRE && !ap->submount) + alarm_add(ap, ap->exp_runfreq); diff --git a/SOURCES/autofs-5.1.2-dont-fail-on-master-map-read-fail-timeout.patch b/SOURCES/autofs-5.1.2-dont-fail-on-master-map-read-fail-timeout.patch new file mode 100644 index 0000000..e4ed574 --- /dev/null +++ b/SOURCES/autofs-5.1.2-dont-fail-on-master-map-read-fail-timeout.patch @@ -0,0 +1,45 @@ +autofs-5.1.2 - dont exit on master map read fail timeout + +From: Ian Kent + +If there is a persistent master map read failure autofs should +continue on after the configured retry wait, as it would have +done previously. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 12 ++++++++---- + 2 files changed, 9 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -209,6 +209,7 @@ + - wait for master map available at start. + - add master read wait option. + - fix included master map not found return. ++- dont exit on master map read fail timeout. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -2510,10 +2510,14 @@ int main(int argc, char *argv[]) + * error. + */ + if (!do_master_read_master(master_list, master_wait)) { +- logerr("%s: failed to read master map!", program); +- master_kill(master_list); +- release_flag_file(); +- exit(3); ++ logmsg("%s: warning: could not read at least one " ++ "map source after waiting, continuing ...", ++ program); ++ /* ++ * Failed to read master map, continue with what ++ * we have anyway. ++ */ ++ master_read_master(master_list, age, 1); + } + } + diff --git a/SOURCES/autofs-5.1.2-dont-return-until-after-master-map-retry-read.patch b/SOURCES/autofs-5.1.2-dont-return-until-after-master-map-retry-read.patch new file mode 100644 index 0000000..9412bc3 --- /dev/null +++ b/SOURCES/autofs-5.1.2-dont-return-until-after-master-map-retry-read.patch @@ -0,0 +1,71 @@ +autofs-5.1.2 - don't return until after master map retry read + +From: Ian Kent + +The master map read retry needs to be done before returning success +at startup or there can be problems trying to access automount mounts +before they are mounted. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 31 ++++++++++--------------------- + 2 files changed, 11 insertions(+), 21 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -211,6 +211,7 @@ + - fix included master map not found return. + - dont exit on master map read fail timeout. + - set sane default master read wait timeout. ++- don't return until after master map retry read. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -2483,27 +2483,6 @@ int main(int argc, char *argv[]) + + master_read = master_read_master(master_list, age, 0); + if (!master_read) { +- if (foreground) +- logerr("%s: failed to read master map, " +- "will retry!", +- program); +- else +- logerr("%s: failed to read master map, " +- "will retry in background!", +- program); +- } +- +- /* +- * Mmm ... reset force unlink umount so we don't also do this +- * in future when we receive a HUP signal. +- */ +- do_force_unlink = 0; +- +- st_stat = 0; +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); +- +- if (!master_read) { + /* + * Read master map, waiting until it is available, unless + * a signal is received, in which case exit returning an +@@ -2521,6 +2500,16 @@ int main(int argc, char *argv[]) + } + } + ++ /* ++ * Mmm ... reset force unlink umount so we don't also do this ++ * in future when we receive a HUP signal. ++ */ ++ do_force_unlink = 0; ++ ++ st_stat = 0; ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ + state_mach_thid = pthread_self(); + statemachine(NULL); + diff --git a/SOURCES/autofs-5.1.2-factor-out-set-thread-mount-request-log-id.patch b/SOURCES/autofs-5.1.2-factor-out-set-thread-mount-request-log-id.patch new file mode 100644 index 0000000..f715c43 --- /dev/null +++ b/SOURCES/autofs-5.1.2-factor-out-set-thread-mount-request-log-id.patch @@ -0,0 +1,143 @@ +autofs-5.1.2 - factor out set_thread_mount_request_log_id() + +From: Ian Kent + +Factor out setting the thread mount request log id. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 24 +++++++++++++++++++++++- + daemon/direct.c | 17 +---------------- + daemon/indirect.c | 17 +---------------- + include/automount.h | 3 ++- + 5 files changed, 28 insertions(+), 34 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -238,6 +238,7 @@ + - add the mount requestor's pid to pending_args. + - create thread-local ID for mount attempts. + - log functions to prefix messages with attempt_id if available. ++- factor out set_thread_mount_request_log_id(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -100,7 +100,7 @@ static int umount_all(struct autofs_poin + extern struct master *master_list; + + /* simple string hash based on public domain sdbm library */ +-unsigned long sdbm_hash(const char *str, unsigned long seed) ++static unsigned long sdbm_hash(const char *str, unsigned long seed) + { + unsigned long hash = seed; + char c; +@@ -110,6 +110,28 @@ unsigned long sdbm_hash(const char *str, + return hash; + } + ++void set_thread_mount_request_log_id(struct pending_args *mt) ++{ ++ char attempt_id_comp[20]; ++ unsigned long *attempt_id; ++ int status; ++ ++ attempt_id = pthread_getspecific(key_thread_attempt_id); ++ if (attempt_id == NULL) { ++ attempt_id = (unsigned long *) calloc(1, sizeof(unsigned long)); ++ if (attempt_id == NULL) ++ fatal(ENOMEM); ++ snprintf(attempt_id_comp, 20, "%ld", mt->wait_queue_token); ++ *attempt_id = sdbm_hash(attempt_id_comp, 0); ++ snprintf(attempt_id_comp, 20, "%u", mt->pid); ++ *attempt_id = sdbm_hash(attempt_id_comp, *attempt_id); ++ *attempt_id = sdbm_hash(mt->name, *attempt_id); ++ status = pthread_setspecific(key_thread_attempt_id, attempt_id); ++ if (status != 0) ++ fatal(status); ++ } ++} ++ + static int do_mkdir(const char *parent, const char *path, mode_t mode) + { + int status; +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -1210,8 +1210,6 @@ static void *do_mount_direct(void *arg) + struct autofs_point *ap; + struct stat st; + int status, state; +- char attempt_id_comp[20]; +- unsigned long *attempt_id; + + args = (struct pending_args *) arg; + +@@ -1221,20 +1219,7 @@ static void *do_mount_direct(void *arg) + + ap = mt.ap; + +- attempt_id = pthread_getspecific(key_thread_attempt_id); +- if (attempt_id == NULL) { +- attempt_id = (unsigned long *) calloc(1, sizeof(unsigned long)); +- if (attempt_id == NULL) +- fatal(ENOMEM); +- snprintf(attempt_id_comp, 20, "%ld", mt.wait_queue_token); +- *attempt_id = sdbm_hash(attempt_id_comp, 0); +- snprintf(attempt_id_comp, 20, "%u", mt.pid); +- *attempt_id = sdbm_hash(attempt_id_comp, *attempt_id); +- *attempt_id = sdbm_hash(mt.name, *attempt_id); +- status = pthread_setspecific(key_thread_attempt_id, attempt_id); +- if (status != 0) +- fatal(status); +- } ++ set_thread_mount_request_log_id(&mt); + + args->signaled = 1; + status = pthread_cond_signal(&args->cond); +--- autofs-5.0.7.orig/daemon/indirect.c ++++ autofs-5.0.7/daemon/indirect.c +@@ -726,8 +726,6 @@ static void *do_mount_indirect(void *arg + char buf[PATH_MAX + 1]; + struct stat st; + int len, status, state; +- char attempt_id_comp[20]; +- unsigned long *attempt_id; + + args = (struct pending_args *) arg; + +@@ -737,20 +735,7 @@ static void *do_mount_indirect(void *arg + + ap = mt.ap; + +- attempt_id = pthread_getspecific(key_thread_attempt_id); +- if (attempt_id == NULL) { +- attempt_id = (unsigned long *) calloc(1, sizeof(unsigned long)); +- if (attempt_id == NULL) +- fatal(ENOMEM); +- snprintf(attempt_id_comp, 20, "%ld", mt.wait_queue_token); +- *attempt_id = sdbm_hash(attempt_id_comp, 0); +- snprintf(attempt_id_comp, 20, "%u", mt.pid); +- *attempt_id = sdbm_hash(attempt_id_comp, *attempt_id); +- *attempt_id = sdbm_hash(mt.name, *attempt_id); +- status = pthread_setspecific(key_thread_attempt_id, attempt_id); +- if (status != 0) +- fatal(status); +- } ++ set_thread_mount_request_log_id(&mt); + + args->signaled = 1; + status = pthread_cond_signal(&args->cond); +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -243,7 +243,8 @@ const char **copy_argv(int argc, const c + int compare_argv(int argc1, const char **argv1, int argc2, const char **argv2); + int free_argv(int argc, const char **argv); + +-unsigned long sdbm_hash(const char *str, unsigned long seed); ++struct pending_args; ++void set_thread_mount_request_log_id(struct pending_args *mt); + + void dump_core(void); + int aquire_lock(void); diff --git a/SOURCES/autofs-5.1.2-fix-_strncmp-usage.patch b/SOURCES/autofs-5.1.2-fix-_strncmp-usage.patch new file mode 100644 index 0000000..f8e2455 --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-_strncmp-usage.patch @@ -0,0 +1,64 @@ +autofs-5.1.2 - fix _strncmp() usage + +From: Ian Kent + +A change to fix nfs mount options changed to using a custom strncmp() +function. + +While the usage of the function is correct in the nfs and bind mount +modules it isn't correct in the autofs and ext2 mount modules. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_autofs.c | 12 ++++++------ + modules/mount_ext2.c | 2 +- + 3 files changed, 8 insertions(+), 7 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -221,6 +221,7 @@ + - fix short memory allocation in lookup_amd_instance(). + - fix count_mounts() function. + - fix argc off by one in mount_autofs.c. ++- fix _strncmp() usage. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -121,17 +121,17 @@ int mount_mount(struct autofs_point *ap, + while (*comma != '\0' && *comma != ',') + comma++; + +- if (_strncmp(cp, "nobrowse", 8) == 0) ++ if (_strncmp("nobrowse", cp, 8) == 0) + ghost = 0; +- else if (_strncmp(cp, "nobind", 6) == 0) ++ else if (_strncmp("nobind", cp, 6) == 0) + nobind = 1; +- else if (_strncmp(cp, "browse", 6) == 0) ++ else if (_strncmp("browse", cp, 6) == 0) + ghost = 1; +- else if (_strncmp(cp, "symlink", 7) == 0) ++ else if (_strncmp("symlink", cp, 7) == 0) + symlnk = 1; +- else if (_strncmp(cp, "hosts", 5) == 0) ++ else if (_strncmp("hosts", cp, 5) == 0) + hosts = 1; +- else if (_strncmp(cp, "timeout=", 8) == 0) { ++ else if (_strncmp("timeout=", cp, 8) == 0) { + char *val = strchr(cp, '='); + unsigned tout; + if (val) { +--- autofs-5.0.7.orig/modules/mount_ext2.c ++++ autofs-5.0.7/modules/mount_ext2.c +@@ -82,7 +82,7 @@ int mount_mount(struct autofs_point *ap, + + if (options && options[0]) { + for (p = options; (p1 = strchr(p, ',')); p = p1) +- if (!_strncmp(p, "ro", p1 - p) && ++p1 - p == sizeof("ro")) ++ if (!_strncmp("ro", p, p1 - p) && ++p1 - p == sizeof("ro")) + ro = 1; + if (!strcmp(p, "ro")) + ro = 1; diff --git a/SOURCES/autofs-5.1.2-fix-argc-off-by-one-in-mount_autofs_c.patch b/SOURCES/autofs-5.1.2-fix-argc-off-by-one-in-mount_autofs_c.patch new file mode 100644 index 0000000..6f56dec --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-argc-off-by-one-in-mount_autofs_c.patch @@ -0,0 +1,55 @@ +autofs-5.1.2 - fix argc off by one in mount_autofs.c + +From: Ian Kent + +The mount_autofs.c module incorrectly calculates the number of +arguments to its map. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_autofs.c | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -220,6 +220,7 @@ + - update and add README for old autofs schema. + - fix short memory allocation in lookup_amd_instance(). + - fix count_mounts() function. ++- fix argc off by one in mount_autofs.c. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -179,11 +179,11 @@ int mount_mount(struct autofs_point *ap, + + if (options) { + char *t = options; +- do { ++ while ((t = strchr(t, ',')) != NULL) { + argc++; + if (*t == ',') + t++; +- } while ((t = strchr(t, ',')) != NULL); ++ } + } + argv = (const char **) alloca((argc + 1) * sizeof(char *)); + +@@ -235,13 +235,13 @@ int mount_mount(struct autofs_point *ap, + + if (options) { + p = options; +- do { ++ while ((p = strchr(p, ',')) != NULL) { + if (*p == ',') { + *p = '\0'; + p++; + } + argv[argc++] = p; +- } while ((p = strchr(p, ',')) != NULL); ++ } + } + argv[argc] = NULL; + diff --git a/SOURCES/autofs-5.1.2-fix-bogus-check-in-expire_cleanup.patch b/SOURCES/autofs-5.1.2-fix-bogus-check-in-expire_cleanup.patch new file mode 100644 index 0000000..f227f35 --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-bogus-check-in-expire_cleanup.patch @@ -0,0 +1,35 @@ +autofs-5.1.2 - fix bogus check in expire_cleanup() + +From: Ian Kent + +ap->submount can never be 0 here. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/state.c | 4 +--- + 2 files changed, 2 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -233,6 +233,7 @@ + - capture cache option and its settings during parsing. + - handle map_option cache for top level mounts. + - handle amd cache option all in amd type auto mounts. ++- fix bogus check in expire_cleanup(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/state.c ++++ autofs-5.0.7/daemon/state.c +@@ -139,9 +139,7 @@ void expire_cleanup(void *arg) + next = ST_SHUTDOWN_PENDING; + break; + } +- +- if (ap->submount++ == 0) +- ap->submount = 2; ++ ap->submount++; + } + + if (ap->state == ST_EXPIRE && !ap->submount) diff --git a/SOURCES/autofs-5.1.2-fix-count_mounts-function.patch b/SOURCES/autofs-5.1.2-fix-count_mounts-function.patch new file mode 100644 index 0000000..4c42995 --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-count_mounts-function.patch @@ -0,0 +1,34 @@ +autofs-5.1.2 - fix count_mounts() function + +From: Ian Kent + +count_mounts() gets the number of mounts wrong, make it include the +base directory also. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -219,6 +219,7 @@ + - honor last rw in mount options when doing a bind mount. + - update and add README for old autofs schema. + - fix short memory allocation in lookup_amd_instance(). ++- fix count_mounts() function. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -392,7 +392,7 @@ int count_mounts(struct autofs_point *ap + counter.count = 0; + counter.dev = dev; + +- if (walk_tree(path, counter_fn, 0, ap, &counter) == -1) ++ if (walk_tree(path, counter_fn, 1, ap, &counter) == -1) + return -1; + + return counter.count; diff --git a/SOURCES/autofs-5.1.2-fix-included-master-map-not-found-return.patch b/SOURCES/autofs-5.1.2-fix-included-master-map-not-found-return.patch new file mode 100644 index 0000000..1660ed1 --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-included-master-map-not-found-return.patch @@ -0,0 +1,89 @@ +autofs-5.1.2 - fix included master map not found return + +From: Ian Kent + +When retrying the master map read at startup a not found return is needed +when there is no map rather than an unknown or unavailable for the retry +logic to work. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 6 ++++-- + modules/lookup_file.c | 18 ++++++++++++------ + 3 files changed, 17 insertions(+), 8 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -208,6 +208,7 @@ + - add config option to supress not found log message. + - wait for master map available at start. + - add master read wait option. ++- fix included master map not found return. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -241,7 +241,7 @@ int lookup_nss_read_master(struct master + } + + /* First one gets it */ +- result = NSS_STATUS_UNKNOWN; ++ result = NSS_STATUS_SUCCESS; + head = &nsslist; + list_for_each(p, head) { + struct nss_source *this; +@@ -282,8 +282,10 @@ int lookup_nss_read_master(struct master + } + } + +- if (result == NSS_STATUS_UNKNOWN) { ++ if (result == NSS_STATUS_UNKNOWN || ++ result == NSS_STATUS_NOTFOUND) { + debug(logopt, "no map - continuing to next source"); ++ result = NSS_STATUS_SUCCESS; + continue; + } + +--- autofs-5.0.7.orig/modules/lookup_file.c ++++ autofs-5.0.7/modules/lookup_file.c +@@ -463,6 +463,8 @@ int lookup_read_master(struct master *ma + + f = open_fopen_r(ctxt->mapname); + if (!f) { ++ if (errno == ENOENT) ++ return NSS_STATUS_NOTFOUND; + error(logopt, + MODPREFIX "could not open master map file %s", + ctxt->mapname); +@@ -506,12 +508,14 @@ int lookup_read_master(struct master *ma + MODPREFIX + "failed to read included master map %s", + master->name); +- /* +- * If we're starting up wee need the whole +- * master map initially, so tell the upper +- * layer to retry. +- */ +- master->read_fail = 1; ++ if (status != NSS_STATUS_NOTFOUND) { ++ /* ++ * If we're starting up wee need the whole ++ * master map initially, so tell the upper ++ * layer to retry. ++ */ ++ master->read_fail = 1; ++ } + } + master->depth--; + master->recurse = 0; +@@ -712,6 +716,8 @@ int lookup_read_map(struct autofs_point + + f = open_fopen_r(ctxt->mapname); + if (!f) { ++ if (errno == ENOENT) ++ return NSS_STATUS_NOTFOUND; + error(ap->logopt, + MODPREFIX "could not open map file %s", ctxt->mapname); + return NSS_STATUS_UNAVAIL; diff --git a/SOURCES/autofs-5.1.2-fix-invalid-reference-in-remount_active_mount.patch b/SOURCES/autofs-5.1.2-fix-invalid-reference-in-remount_active_mount.patch new file mode 100644 index 0000000..17dcabf --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-invalid-reference-in-remount_active_mount.patch @@ -0,0 +1,38 @@ +autofs-5.1.2 - fix invalid reference in remount_active_mount() + +From: Ian Kent + +remount_active_mount() can be called with the map entry pointer NULL +so it must be checked before use when getting the automount timeout. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 6 ++++-- + 2 files changed, 5 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -1721,8 +1721,10 @@ static int remount_active_mount(struct a + if (fd == -1) + return REMOUNT_OPEN_FAIL; + +- error(ap->logopt, "ap->type %d type %u", ap->type, type); +- timeout = get_exp_timeout(ap, me->source); ++ if (!me) ++ timeout = get_exp_timeout(ap, NULL); ++ else ++ timeout = get_exp_timeout(ap, me->source); + + /* Re-reading the map, set timeout and return */ + if (ap->state == ST_READMAP) { +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -246,6 +246,7 @@ + - fix possible NULL derefernce. + - fix work around sss startup delay. + - improve scalability of direct mount path component. ++- fix invalid reference in remount_active_mount(). + + 25/07/2012 autofs-5.0.7 + ======================= diff --git a/SOURCES/autofs-5.1.2-fix-possible-NULL-derefernce.patch b/SOURCES/autofs-5.1.2-fix-possible-NULL-derefernce.patch new file mode 100644 index 0000000..0e41a56 --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-possible-NULL-derefernce.patch @@ -0,0 +1,48 @@ +autofs-5.1.2 - fix possible NULL derefernce + +From: Ian Kent + +In modules/mount_autofs.c:mount_mount() a NULL pointer dereference is +(unlikley but) possible. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_autofs.c | 15 +++++++++------ + 2 files changed, 10 insertions(+), 6 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -243,6 +243,7 @@ + - work around sss startup delay. + - add sss master map wait config option. + - use autofs_point to store expire timeout where possibe. ++- fix possible NULL derefernce. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -280,13 +280,16 @@ int mount_mount(struct autofs_point *ap, + + if (source->flags & MAP_FLAG_FORMAT_AMD) { + struct amd_entry *am_entry = __master_find_amdmount(ap, entry->path); +- if (am_entry && am_entry->pref) { +- nap->pref = am_entry->pref; +- am_entry->pref = NULL; +- } + +- if (am_entry->cache_opts & AMD_CACHE_OPTION_ALL) +- nap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ if (am_entry) { ++ if (am_entry->pref) { ++ nap->pref = am_entry->pref; ++ am_entry->pref = NULL; ++ } ++ ++ if (am_entry->cache_opts & AMD_CACHE_OPTION_ALL) ++ nap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ } + } + + if (handle_mounts_startup_cond_init(&suc)) { diff --git a/SOURCES/autofs-5.1.2-fix-short-memory-allocation-in-lookup_amd_instance.patch b/SOURCES/autofs-5.1.2-fix-short-memory-allocation-in-lookup_amd_instance.patch new file mode 100644 index 0000000..c1d5878 --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-short-memory-allocation-in-lookup_amd_instance.patch @@ -0,0 +1,33 @@ +autofs-5.1.2 - fix short memory allocation in lookup_amd_instance() + +From: Ian Kent + +Fix off by one memory allocation size in lookup_amd_instance(). + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -218,6 +218,7 @@ + - check NFS server availability on local mount fallback. + - honor last rw in mount options when doing a bind mount. + - update and add README for old autofs schema. ++- fix short memory allocation in lookup_amd_instance(). + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -802,7 +802,7 @@ static int lookup_amd_instance(struct au + return NSS_STATUS_UNKNOWN; + } + +- m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 1); ++ m_key = malloc(strlen(ap->path) + strlen(me->multi->key) + 2); + if (!m_key) { + error(ap->logopt, + "failed to allocate storage for search key"); diff --git a/SOURCES/autofs-5.1.2-fix-typos-in-README.amd-maps.patch b/SOURCES/autofs-5.1.2-fix-typos-in-README.amd-maps.patch new file mode 100644 index 0000000..d8d52db --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-typos-in-README.amd-maps.patch @@ -0,0 +1,75 @@ +autofs-5.1.2 - fix typos in README.amd-maps + +From: Ian Kent + +Fix a few typos and try and clearify some statements in the README. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + README.amd-maps | 15 ++++++++------- + 2 files changed, 9 insertions(+), 7 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -222,6 +222,7 @@ + - fix count_mounts() function. + - fix argc off by one in mount_autofs.c. + - fix _strncmp() usage. ++- fix typos in README.amd-maps. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/README.amd-maps ++++ autofs-5.0.7/README.amd-maps +@@ -7,7 +7,8 @@ The ability to parse amd format maps has + How to use amd maps in autofs + ----------------------------- + +-To add amd map parsing to autofs new "format" module has been added. ++To add amd map parsing to autofs a new "format" module has been added. ++ + To use this new map format module the existing master map syntax is + used as described below. + +@@ -20,7 +21,7 @@ For amd format maps this becomes: + /amd/mp   file,amd:amd.mp + + which will use file as the map source and the amd format parser for +-the map. But see the section below on configuration below for how to ++the map. But see the section below on configuration for how to + eliminate the need to specify "map-type,format" in the master map. + + Configuration sub-system changes +@@ -42,18 +43,18 @@ All that's needed to add an existing amd + add it below the autofs configuration. Apart from changing the amd + "[ global ]" section name to "[ amd ]" nothing else should need to be + changed. However, quite a few amd configuration options don't have +-meaning within autofs. When these options are seen it should be logged. ++meaning within autofs. When these options are seen they are logged. + + Be aware that, if the an old configuration exists and the configuration + hasn't been updated after the installation, changes to the the old + configuration will override changes to the new configuration because + backward compatibility takes priority over the new implementation. + +-The amd per-map sections have two functions, to allow per-mount ++The amd per-mount sections have two functions, to allow per-mount + configuration, as it does in amd, and to allow master map entries to + avoid the need to specify the "type,format" part of the master map +-entry so they can use the nsswitch map source functionality in the +-same way autofs master map entries do. ++entry. This allows them to use the nsswitch map source functionality ++in the same way autofs master map entries do. + + If a section for an amd mount is added below the global amd section + using the mount point path (as is done in amd.conf) then autofs will +@@ -63,7 +64,7 @@ be given in the master map entry the map + as it is in amd and will no be used. + + If a mount point is present in the master map and the source of the +-map is nis then it should be sufficient to use (for example): ++map is nis then it is sufficient to use (for example): + + /amd/mp           amd.mp + diff --git a/SOURCES/autofs-5.1.2-fix-work-around-sss-startup-delay.patch b/SOURCES/autofs-5.1.2-fix-work-around-sss-startup-delay.patch new file mode 100644 index 0000000..3497b5d --- /dev/null +++ b/SOURCES/autofs-5.1.2-fix-work-around-sss-startup-delay.patch @@ -0,0 +1,41 @@ +autofs-5.1.2 - fix work around sss startup delay + +From: Ian Kent + +If a sss startup delay has been configured to non-zero autofs will +wait up to the configured time and return NSS_STATUS_UNAVAIL or +NSS_STATUS_NOTFOUND even if setautomntent_wait() returns success. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_sss.c | 8 +++++--- + 2 files changed, 6 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -244,6 +244,7 @@ + - add sss master map wait config option. + - use autofs_point to store expire timeout where possibe. + - fix possible NULL derefernce. ++- fix work around sss startup delay. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_sss.c ++++ autofs-5.0.7/modules/lookup_sss.c +@@ -309,9 +309,11 @@ int lookup_read_master(struct master *ma + ret = setautomntent_wait(logopt, + ctxt, ctxt->mapname, &sss_ctxt, + retries); +- if (ret == ENOENT) +- return NSS_STATUS_NOTFOUND; +- return NSS_STATUS_UNAVAIL; ++ if (ret) { ++ if (ret == ENOENT) ++ return NSS_STATUS_NOTFOUND; ++ return NSS_STATUS_UNAVAIL; ++ } + } + + count = 0; diff --git a/SOURCES/autofs-5.1.2-handle-amd-cache-option-all-in-amd-type-auto-mounts.patch b/SOURCES/autofs-5.1.2-handle-amd-cache-option-all-in-amd-type-auto-mounts.patch new file mode 100644 index 0000000..2673388 --- /dev/null +++ b/SOURCES/autofs-5.1.2-handle-amd-cache-option-all-in-amd-type-auto-mounts.patch @@ -0,0 +1,121 @@ +autofs-5.1.2 - handle amd cache option all in amd type auto mounts + +From: Ian Kent + +In order to read in the map at mount time autofs submounts must be +set as browasble but amd type auto mounts that have the cache:=all +option set need to read in the map without the browse option being +set. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/lookup_ldap.c | 10 ++++++---- + modules/lookup_nisplus.c | 10 ++++++---- + modules/lookup_sss.c | 10 ++++++---- + modules/lookup_yp.c | 10 ++++++---- + modules/mount_autofs.c | 3 +++ + 6 files changed, 28 insertions(+), 16 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -232,6 +232,7 @@ + - add function conf_get_map_options(). + - capture cache option and its settings during parsing. + - handle map_option cache for top level mounts. ++- handle amd cache option all in amd type auto mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_ldap.c ++++ autofs-5.0.7/modules/lookup_ldap.c +@@ -2797,11 +2797,13 @@ static int read_one_map(struct autofs_po + int rv, l; + + /* +- * If we don't need to create directories then there's no use +- * reading the map. We always need to read the whole map for +- * direct mounts in order to mount the triggers. ++ * If we don't need to create directories (or don't need ++ * to read an amd cache:=all map) then there's no use ++ * reading the map. We always need to read the whole map ++ * for direct mounts in order to mount the triggers. + */ +- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) { ++ if (ap->type != LKP_DIRECT && ++ !(ap->flags & (MOUNT_FLAG_GHOST|MOUNT_FLAG_AMD_CACHE_ALL))) { + debug(ap->logopt, "map read not needed, so not done"); + return NSS_STATUS_SUCCESS; + } +--- autofs-5.0.7.orig/modules/lookup_nisplus.c ++++ autofs-5.0.7/modules/lookup_nisplus.c +@@ -239,11 +239,13 @@ int lookup_read_map(struct autofs_point + master_source_current_signal(ap->entry); + + /* +- * If we don't need to create directories then there's no use +- * reading the map. We always need to read the whole map for +- * direct mounts in order to mount the triggers. ++ * If we don't need to create directories (or don't need ++ * to read an amd cache:=all map) then there's no use ++ * reading the map. We always need to read the whole map ++ * for direct mounts in order to mount the triggers. + */ +- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) { ++ if (ap->type != LKP_DIRECT && ++ !(ap->flags & (MOUNT_FLAG_GHOST|MOUNT_FLAG_AMD_CACHE_ALL))) { + debug(ap->logopt, "map read not needed, so not done"); + return NSS_STATUS_SUCCESS; + } +--- autofs-5.0.7.orig/modules/lookup_sss.c ++++ autofs-5.0.7/modules/lookup_sss.c +@@ -340,11 +340,13 @@ int lookup_read_map(struct autofs_point + mc = source->mc; + + /* +- * If we don't need to create directories then there's no use +- * reading the map. We always need to read the whole map for +- * direct mounts in order to mount the triggers. ++ * If we don't need to create directories (or don't need ++ * to read an amd cache:=all map) then there's no use ++ * reading the map. We always need to read the whole map ++ * for direct mounts in order to mount the triggers. + */ +- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) { ++ if (ap->type != LKP_DIRECT && ++ !(ap->flags & (MOUNT_FLAG_GHOST|MOUNT_FLAG_AMD_CACHE_ALL))) { + debug(ap->logopt, "map read not needed, so not done"); + return NSS_STATUS_SUCCESS; + } +--- autofs-5.0.7.orig/modules/lookup_yp.c ++++ autofs-5.0.7/modules/lookup_yp.c +@@ -401,11 +401,13 @@ int lookup_read_map(struct autofs_point + master_source_current_signal(ap->entry); + + /* +- * If we don't need to create directories then there's no use +- * reading the map. We always need to read the whole map for +- * direct mounts in order to mount the triggers. ++ * If we don't need to create directories (or don't need ++ * to read an amd cache:=all map) then there's no use ++ * reading the map. We always need to read the whole map ++ * for direct mounts in order to mount the triggers. + */ +- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT) { ++ if (ap->type != LKP_DIRECT && ++ !(ap->flags & (MOUNT_FLAG_GHOST|MOUNT_FLAG_AMD_CACHE_ALL))) { + debug(ap->logopt, "map read not needed, so not done"); + return NSS_STATUS_SUCCESS; + } +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -288,6 +288,9 @@ int mount_mount(struct autofs_point *ap, + nap->pref = am_entry->pref; + am_entry->pref = NULL; + } ++ ++ if (am_entry->cache_opts & AMD_CACHE_OPTION_ALL) ++ nap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; + } + + if (handle_mounts_startup_cond_init(&suc)) { diff --git a/SOURCES/autofs-5.1.2-handle-map_option-cache-for-top-level-mounts.patch b/SOURCES/autofs-5.1.2-handle-map_option-cache-for-top-level-mounts.patch new file mode 100644 index 0000000..1535822 --- /dev/null +++ b/SOURCES/autofs-5.1.2-handle-map_option-cache-for-top-level-mounts.patch @@ -0,0 +1,113 @@ +autofs-5.1.2 - handle map_option cache for top level mounts + +From: Ian Kent + +In order to read in the map at mount time autofs top level mounts +must be set as browsasble but amd top level mounts that have the +map_option cache:=all set need to read in the map without the browse +option being set. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/automount.h | 3 +++ + lib/master.c | 15 +++++++++++++++ + lib/master_parse.y | 16 ++++++++++++++++ + man/autofs.conf.5.in | 8 ++++++-- + 5 files changed, 41 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -231,6 +231,7 @@ + - check for conflicting amd section mounts. + - add function conf_get_map_options(). + - capture cache option and its settings during parsing. ++- handle map_option cache for top level mounts. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -505,6 +505,9 @@ struct kernel_mod_version { + /* Use symlinks instead of bind mounting local mounts */ + #define MOUNT_FLAG_SYMLINK 0x0040 + ++/* Read amd map even if it's not to be ghosted (browsable) */ ++#define MOUNT_FLAG_AMD_CACHE_ALL 0x0080 ++ + struct autofs_point { + pthread_t thid; + char *path; /* Mount point name */ +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -982,6 +982,7 @@ static void master_add_amd_mount_section + unsigned int ghost = 0; + char *type = NULL; + char *map = NULL; ++ char *opts; + + ret = master_partial_match_mapent(master, path); + if (ret) { +@@ -1036,6 +1037,20 @@ static void master_add_amd_mount_section + goto next; + } + ++ opts = conf_amd_get_map_options(path); ++ if (opts) { ++ /* autofs uses the equivalent of cache:=inc,sync ++ * (except for file maps which use cache:=all,sync) ++ * but if the map is large then it may be necessary ++ * to read the whole map at startup even if browsing ++ * is is not enabled, so look for cache:=all in the ++ * map_options configuration entry. ++ */ ++ if (strstr(opts, "cache:=all")) ++ entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ free(opts); ++ } ++ + type = conf_amd_get_map_type(path); + argv[0] = map; + argv[1] = NULL; +--- autofs-5.0.7.orig/lib/master_parse.y ++++ autofs-5.0.7/lib/master_parse.y +@@ -856,6 +856,22 @@ int master_parse_entry(const char *buffe + if (negative_timeout) + entry->ap->negative_timeout = negative_timeout; + ++ if (format && !strcmp(format, "amd")) { ++ char *opts = conf_amd_get_map_options(path); ++ if (opts) { ++ /* autofs uses the equivalent of cache:=inc,sync ++ * (except for file maps which use cache:=all,sync) ++ * but if the map is large then it may be necessary ++ * to read the whole map at startup even if browsing ++ * is is not enabled, so look for cache:=all in the ++ * map_options configuration entry. ++ */ ++ if (strstr(opts, "cache:=all")) ++ entry->ap->flags |= MOUNT_FLAG_AMD_CACHE_ALL; ++ free(opts); ++ } ++ } ++ + /* + source = master_find_map_source(entry, type, format, + local_argc, (const char **) local_argv); +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -284,8 +284,12 @@ protocol version. + .BR cache_duration ", " map_reload_interval ", " map_options + .br + The map entry cache is continually updated and stale entries +-cleaned on re-load, which is done when map changes aredetected +-so these configuration entries are not used by autofs. ++cleaned on re-load, which is done when map changes are detected ++so these configuration entries are not used by autofs. An ++exception to this is the case where the map is large. In this ++case it may be necessary to read the whole map at startup even if ++browsing is is not enabled. Adding the cache:=all option to ++map_options can be used to for this. + .TP + .B localhost_address + This is not used within autofs. This configuration option was diff --git a/SOURCES/autofs-5.1.2-honor-last-rw-in-mount-options-when-doing-a-bind-mount.patch b/SOURCES/autofs-5.1.2-honor-last-rw-in-mount-options-when-doing-a-bind-mount.patch new file mode 100644 index 0000000..9e3b68d --- /dev/null +++ b/SOURCES/autofs-5.1.2-honor-last-rw-in-mount-options-when-doing-a-bind-mount.patch @@ -0,0 +1,43 @@ +autofs-5.1.2 - honor last rw in mount options when doing a bind mount + +From: David Jeffery + +mount(8) will use the last ro/rw option in its options list. +e.g. "mount -o ro,rw" will make a read-write mount while +"mount -o rw,ro" will make a read-only mount. + +The patch changes the option parsing for mount_mount() in +modules/mount_nfs.c to clear the ro variable when a "rw" +option is seen. This will handle occurrences of both "ro" +and "rw" options, resulting in a read-only option being +passed to a bind mount only if the option order would also +have resulted in an nfs mount being read-only. + +Signed-off-by: David Jeffery +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_nfs.c | 2 ++ + 2 files changed, 3 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -216,6 +216,7 @@ + - make set_direct_mount_catatonic() more general. + - set autofs mounts catatonic at exit. + - check NFS server availability on local mount fallback. ++- honor last rw in mount options when doing a bind mount. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/mount_nfs.c ++++ autofs-5.0.7/modules/mount_nfs.c +@@ -180,6 +180,8 @@ int mount_mount(struct autofs_point *ap, + with bind mounts */ + else if (_strncmp("ro", cp, o_len) == 0) + ro = 1; ++ else if (_strncmp("rw", cp, o_len) == 0) ++ ro = 0; + /* and jump over trailing white space */ + memcpy(nfsp, cp, comma - cp + 1); + nfsp += comma - cp + 1; diff --git a/SOURCES/autofs-5.1.2-include-amd-mount-section-mounts-in-master-mounts-list.patch b/SOURCES/autofs-5.1.2-include-amd-mount-section-mounts-in-master-mounts-list.patch new file mode 100644 index 0000000..89de602 --- /dev/null +++ b/SOURCES/autofs-5.1.2-include-amd-mount-section-mounts-in-master-mounts-list.patch @@ -0,0 +1,236 @@ +autofs-5.1.2 - include amd mount section mounts in master mounts list + +From: Ian Kent + +Currently a master map entry is required for amd format maps and +top level amd mount path configuration sections can only used to +provide additional per-mount configuration. + +But being able to use the top level amd format mount path +configuration sections alone allows potentially incompatible +master map entries to not be included in the master map. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + README.amd-maps | 49 +++++++++++++++++++++---- + lib/master.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 152 insertions(+), 7 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -227,6 +227,7 @@ + - add support for amd browsable option. + - add function conf_amd_get_map_name(). + - add function conf_amd_get_mount_paths(). ++- include amd mount sections mounts in master mounts list. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/README.amd-maps ++++ autofs-5.0.7/README.amd-maps +@@ -9,8 +9,10 @@ How to use amd maps in autofs + + To add amd map parsing to autofs a new "format" module has been added. + +-To use this new map format module the existing master map syntax is +-used as described below. ++There are two ways to use this new map format module. First, the existing ++master map syntax can be used as described below, and second, sections that ++use the top level mount path may be added to the autofs configuration below ++the "amd" section in much the same way as is done with amd. + + The master map entry syntax is: + +@@ -21,8 +23,22 @@ For amd format maps this becomes: + /amd/mp   file,amd:amd.mp + + which will use file as the map source and the amd format parser for +-the map. But see the section below on configuration for how to +-eliminate the need to specify "map-type,format" in the master map. ++the map. ++ ++In order to use nsswitch to specify the map source an amd per-mount ++section needs to be added to the autofs configuration so autofs ++knows the master map entry is an amd format mount. ++ ++If an amd-per-mount section is added to the autofs configuration a ++corresponding master map entry is optional. If both are present the ++map name given in the master map entry will override a "map_name" ++option in the amd per-mount section. ++ ++If an amd per-mount section is used alone then not giving the "map_type" ++option will alow the use of nsswicth for map selection. ++ ++See below for an example of an amd per-mount configuration entry. ++ + + Configuration sub-system changes + -------------------------------- +@@ -56,12 +72,19 @@ avoid the need to specify the "type,form + entry. This allows them to use the nsswitch map source functionality + in the same way autofs master map entries do. + ++If amd per-mount sections are present in the autofs configuration ++their corresponding master map entries are optional. This allows ++amd maps to be used without adding incompatible entries to the autofs ++master map in shared infrastructure environments. ++ + If a section for an amd mount is added below the global amd section + using the mount point path (as is done in amd.conf) then autofs will + know the map format is amd (it doesn't matter if there are no other +-configuration options in the mount point section). Since the map must +-be given in the master map entry the map_name option is not mandatory +-as it is in amd and will no be used. ++configuration options in the mount point section). ++ ++If there is a corresponding master map entry the map given in the ++master map entry will be used over the map_name option if it is ++present in an amd per-mount section. + + If a mount point is present in the master map and the source of the + map is nis then it is sufficient to use (for example): +@@ -86,6 +109,18 @@ or + [ /amd/mp ] + map_type = nis + ++An example of an amd per-mount configuration entry is: ++ ++[ amd ] ++... ++ ++[ /test ] ++map_name = /etc/amd.test ++#map_type = file ++#search_path = /etc ++#browsable_dirs = yes | no ++browsable_dirs = yes ++ + + amd map options that can be used + -------------------------------- +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -910,6 +910,114 @@ struct master *master_new(const char *na + return master; + } + ++static void master_add_amd_mount_section_mounts(struct master *master, time_t age) ++{ ++ unsigned int m_logopt = master->logopt; ++ struct master_mapent *entry; ++ struct map_source *source; ++ unsigned int loglevel; ++ unsigned int logopt; ++ unsigned int flags; ++ char *argv[2]; ++ char **paths; ++ int ret; ++ int i; ++ ++ loglevel = conf_amd_get_log_options(); ++ ++ paths = conf_amd_get_mount_paths(); ++ if (!paths) ++ return; ++ ++ i = 0; ++ while (paths[i]) { ++ const char *path = paths[i]; ++ unsigned int ghost = 0; ++ char *type = NULL; ++ char *map = NULL; ++ ++ entry = master_find_mapent(master, path); ++ if (entry) { ++ info(m_logopt, ++ "ignoring duplicate amd section mount %s", ++ path); ++ goto next; ++ } ++ ++ map = conf_amd_get_map_name(path); ++ if (!map) { ++ error(m_logopt, ++ "failed to get map name for amd section mount %s", ++ path); ++ goto next; ++ } ++ ++ entry = master_new_mapent(master, path, age); ++ if (!entry) { ++ error(m_logopt, ++ "failed to allocate new amd section mount %s", ++ path); ++ goto next; ++ } ++ ++ logopt = m_logopt; ++ if (loglevel <= LOG_DEBUG && loglevel > LOG_INFO) ++ logopt = LOGOPT_DEBUG; ++ else if (loglevel <= LOG_INFO && loglevel > LOG_ERR) ++ logopt = LOGOPT_VERBOSE; ++ ++ /* It isn't possible to provide the fullybrowsable amd ++ * browsing functionality within the autofs framework. ++ * This flag will not be set if browsable_dirs = full ++ * in the configuration or fullybrowsable is present as ++ * an option. ++ */ ++ flags = conf_amd_get_flags(path); ++ if (flags & CONF_BROWSABLE_DIRS) ++ ghost = 1; ++ ++ ret = master_add_autofs_point(entry, logopt, 0, ghost, 0); ++ if (!ret) { ++ error(m_logopt, "failed to add autofs_point"); ++ master_free_mapent(entry); ++ goto next; ++ } ++ ++ type = conf_amd_get_map_type(path); ++ argv[0] = map; ++ argv[1] = NULL; ++ ++ source = master_add_map_source(entry, type, "amd", ++ age, 1, (const char **) argv); ++ if (!source) { ++ error(m_logopt, ++ "failed to add source for amd section mount %s", ++ path); ++ master_free_mapent(entry); ++ goto next; ++ } ++ ++ source->exp_timeout = conf_amd_get_dismount_interval(path); ++ source->master_line = 0; ++ ++ entry->age = age; ++ entry->current = NULL; ++ ++ master_add_mapent(master, entry); ++next: ++ if (type) ++ free(type); ++ if (map) ++ free(map); ++ i++; ++ } ++ ++ i = 0; ++ while (paths[i]) ++ free(paths[i++]); ++ free(paths); ++} ++ + int master_read_master(struct master *master, time_t age, int readall) + { + unsigned int logopt = master->logopt; +@@ -938,6 +1046,7 @@ int master_read_master(struct master *ma + master_init_scan(); + lookup_nss_read_master(master, age); + cache_unlock(nc); ++ master_add_amd_mount_section_mounts(master, age); + master_mutex_unlock(); + + if (!master->read_fail) diff --git a/SOURCES/autofs-5.1.2-increase-worker-thread-per-thread-stack-size.patch b/SOURCES/autofs-5.1.2-increase-worker-thread-per-thread-stack-size.patch new file mode 100644 index 0000000..b429a7d --- /dev/null +++ b/SOURCES/autofs-5.1.2-increase-worker-thread-per-thread-stack-size.patch @@ -0,0 +1,68 @@ +autofs-5.1.2 - increase worker thread per-thread stack size + +From: Ian Kent + +automount(8) uses a worker thread per-thread stack size of 1M which is +sufficient for its needs. + +But some glibc functions (such as nscd_getgr_r()) use alloca() to allocate +working storage that can have an arbitary size. Since alloca() never fails +there is no way to check for stack overflow. This has been fixed in more +recent versions of glibc. + +But for older version of glibc all that can be done by automount to avoid +this is to increase the stack size. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 14 +++++++++++++- + 2 files changed, 14 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -247,6 +247,7 @@ + - fix work around sss startup delay. + - improve scalability of direct mount path component. + - fix invalid reference in remount_active_mount(). ++- increase worker thread per-thread stack size. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -81,6 +81,7 @@ static int cloexec_works = 0; + /* Attributes for creating detached and joinable threads */ + pthread_attr_t th_attr; + pthread_attr_t th_attr_detached; ++size_t detached_thread_stack_size = PTHREAD_STACK_MIN * 144; + + struct master_readmap_cond mrc = { + PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0}; +@@ -2483,7 +2484,7 @@ int main(int argc, char *argv[]) + + #ifdef _POSIX_THREAD_ATTR_STACKSIZE + if (pthread_attr_setstacksize( +- &th_attr_detached, PTHREAD_STACK_MIN*64)) { ++ &th_attr_detached, detached_thread_stack_size)) { + logerr("%s: failed to set stack size thread attribute!", + program); + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +@@ -2494,6 +2495,17 @@ int main(int argc, char *argv[]) + } + #endif + ++ if (pthread_attr_getstacksize( ++ &th_attr_detached, &detached_thread_stack_size)) { ++ logerr("%s: failed to get detached thread stack size!", ++ program); ++ res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); ++ close(start_pipefd[1]); ++ release_flag_file(); ++ macro_free_global_table(); ++ exit(1); ++ } ++ + info(logging, "Starting automounter version %s, master map %s", + version, master_list->name); + info(logging, "using kernel protocol version %d.%02d", diff --git a/SOURCES/autofs-5.1.2-limit-getgrgid_r-buffer-size.patch b/SOURCES/autofs-5.1.2-limit-getgrgid_r-buffer-size.patch new file mode 100644 index 0000000..0ab3f0b --- /dev/null +++ b/SOURCES/autofs-5.1.2-limit-getgrgid_r-buffer-size.patch @@ -0,0 +1,118 @@ +autofs-5.1.2 - limit getgrgid_r() buffer size + +From: Ian Kent + +Some older versions of glibc use stack allocation to store group +information during calls to getgrgid_r(). But before doing this +it checks if the size of the response info. can fit in the user +supplied buffer and returns ERANGE if it can't. + +Now automount(8) doesn't check if the size of the buffer it is +passing is larger than it's stack size. That's not vey accurrate +since current stack usage isn't known but better than not checking +at all. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/mounts.c | 47 +++++++++++++++++++++++++++++++++-------------- + 2 files changed, 34 insertions(+), 14 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -248,6 +248,7 @@ + - improve scalability of direct mount path component. + - fix invalid reference in remount_active_mount(). + - increase worker thread per-thread stack size. ++- limit getgrgid_r() buffer size. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -48,6 +48,9 @@ static const char mnt_name_template[] + static struct kernel_mod_version kver = {0, 0}; + static const char kver_options_template[] = "fd=%d,pgrp=%u,minproto=3,maxproto=5"; + ++extern size_t detached_thread_stack_size; ++static size_t maxgrpbuf = 0; ++ + #define EXT_MOUNTS_HASH_SIZE 50 + + struct ext_mount { +@@ -1503,14 +1506,22 @@ void set_tsd_user_vars(unsigned int logo + } + + gr_tmp = NULL; ++ status = ERANGE; ++ if (!maxgrpbuf) ++ maxgrpbuf = detached_thread_stack_size * 0.9; ++ ++ /* If getting the group name fails go on without it. It's ++ * used to set an environment variable for program maps ++ * which may or may not use it so it isn't critical to ++ * operation. ++ */ ++ + tmplen = grplen; + while (1) { + char *tmp = realloc(gr_tmp, tmplen + 1); + if (!tmp) { + error(logopt, "failed to malloc buffer for getgrgid_r"); +- if (gr_tmp) +- free(gr_tmp); +- goto free_tsv_home; ++ goto no_group; + } + gr_tmp = tmp; + pgr = &gr; +@@ -1519,22 +1530,29 @@ void set_tsd_user_vars(unsigned int logo + if (status != ERANGE) + break; + tmplen += grplen; ++ ++ /* Don't tempt glibc to alloca() larger than is (likely) ++ * available on the stack. ++ */ ++ if (tmplen < maxgrpbuf) ++ continue; ++ ++ /* Add a message so we know this happened */ ++ debug(logopt, "group buffer allocation would be too large"); ++ break; + } + +- if (status || !pgr) { ++no_group: ++ if (status || !pgr) + error(logopt, "failed to get group info from getgrgid_r"); +- free(gr_tmp); +- goto free_tsv_home; ++ else { ++ tsv->group = strdup(gr.gr_name); ++ if (!tsv->group) ++ error(logopt, "failed to malloc buffer for group"); + } + +- tsv->group = strdup(gr.gr_name); +- if (!tsv->group) { +- error(logopt, "failed to malloc buffer for group"); ++ if (gr_tmp) + free(gr_tmp); +- goto free_tsv_home; +- } +- +- free(gr_tmp); + + status = pthread_setspecific(key_thread_stdenv_vars, tsv); + if (status) { +@@ -1545,7 +1563,8 @@ void set_tsd_user_vars(unsigned int logo + return; + + free_tsv_group: +- free(tsv->group); ++ if (tsv->group) ++ free(tsv->group); + free_tsv_home: + free(tsv->home); + free_tsv_user: diff --git a/SOURCES/autofs-5.1.2-log-functions-to-prefix-messages-with-attempt_id-if-available.patch b/SOURCES/autofs-5.1.2-log-functions-to-prefix-messages-with-attempt_id-if-available.patch new file mode 100644 index 0000000..089f96c --- /dev/null +++ b/SOURCES/autofs-5.1.2-log-functions-to-prefix-messages-with-attempt_id-if-available.patch @@ -0,0 +1,293 @@ +autofs-5.1.2 - log functions to prefix messages with attempt_id if available + +From: Lars R. Damerow + +Now that there should be a mount attempt id try and include it in log entries. + +Signed-off-by: Lars R. Damerow +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + lib/log.c | 164 +++++++++++++++++++++++++++++++++++++++++++++++++++----------- + 2 files changed, 137 insertions(+), 28 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -237,6 +237,7 @@ + - delay submount exit for amd submounts. + - add the mount requestor's pid to pending_args. + - create thread-local ID for mount attempts. ++- log functions to prefix messages with attempt_id if available. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/log.c ++++ autofs-5.0.7/lib/log.c +@@ -32,6 +32,26 @@ static unsigned int logging_to_syslog = + static unsigned int do_verbose = 0; /* Verbose feedback option */ + static unsigned int do_debug = 0; /* Full debug output */ + ++static char *prepare_attempt_prefix(const char *msg) ++{ ++ unsigned long *attempt_id; ++ char buffer[ATTEMPT_ID_SIZE + 1]; ++ char *prefixed_msg = NULL; ++ ++ attempt_id = pthread_getspecific(key_thread_attempt_id); ++ if (attempt_id) { ++ int len = sizeof(buffer) + 1 + strlen(msg) + 1; ++ ++ snprintf(buffer, ATTEMPT_ID_SIZE, "%02lx", *attempt_id); ++ prefixed_msg = (char *) calloc(len, sizeof(char)); ++ strcpy(prefixed_msg, buffer); ++ strcat(prefixed_msg, "|"); ++ strcat(prefixed_msg, msg); ++ } ++ ++ return prefixed_msg; ++} ++ + void set_log_norm(void) + { + do_verbose = 0; +@@ -72,124 +92,212 @@ void set_log_debug_ap(struct autofs_poin + void log_info(unsigned int logopt, const char *msg, ...) + { + unsigned int opt_log = logopt & (LOGOPT_DEBUG | LOGOPT_VERBOSE); ++ char *prefixed_msg; + va_list ap; + + if (!do_debug && !do_verbose && !opt_log) + return; + ++ prefixed_msg = prepare_attempt_prefix(msg); ++ + va_start(ap, msg); +- if (logging_to_syslog) +- vsyslog(LOG_INFO, msg, ap); +- else { +- vfprintf(stderr, msg, ap); ++ if (logging_to_syslog) { ++ if (prefixed_msg) ++ vsyslog(LOG_INFO, prefixed_msg, ap); ++ else ++ vsyslog(LOG_INFO, msg, ap); ++ } else { ++ if (prefixed_msg) ++ vfprintf(stderr, prefixed_msg, ap); ++ else ++ vfprintf(stderr, msg, ap); + fputc('\n', stderr); + } + va_end(ap); + ++ if (prefixed_msg) ++ free(prefixed_msg); ++ + return; + } + + void log_notice(unsigned int logopt, const char *msg, ...) + { + unsigned int opt_log = logopt & (LOGOPT_DEBUG | LOGOPT_VERBOSE); ++ char *prefixed_msg; + va_list ap; + + if (!do_debug && !do_verbose && !opt_log) + return; + ++ prefixed_msg = prepare_attempt_prefix(msg); ++ + va_start(ap, msg); +- if (logging_to_syslog) +- vsyslog(LOG_NOTICE, msg, ap); +- else { +- vfprintf(stderr, msg, ap); ++ if (logging_to_syslog) { ++ if (prefixed_msg) ++ vsyslog(LOG_NOTICE, prefixed_msg, ap); ++ else ++ vsyslog(LOG_INFO, msg, ap); ++ } else { ++ if (prefixed_msg) ++ vfprintf(stderr, prefixed_msg, ap); ++ else ++ vfprintf(stderr, msg, ap); + fputc('\n', stderr); + } + va_end(ap); + ++ if (prefixed_msg) ++ free(prefixed_msg); ++ + return; + } + + void log_warn(unsigned int logopt, const char *msg, ...) + { + unsigned int opt_log = logopt & (LOGOPT_DEBUG | LOGOPT_VERBOSE); ++ char *prefixed_msg; + va_list ap; + + if (!do_debug && !do_verbose && !opt_log) + return; + ++ prefixed_msg = prepare_attempt_prefix(msg); ++ + va_start(ap, msg); +- if (logging_to_syslog) +- vsyslog(LOG_WARNING, msg, ap); +- else { +- vfprintf(stderr, msg, ap); ++ if (logging_to_syslog) { ++ if (prefixed_msg) ++ vsyslog(LOG_WARNING, prefixed_msg, ap); ++ else ++ vsyslog(LOG_INFO, msg, ap); ++ } else { ++ if (prefixed_msg) ++ vfprintf(stderr, prefixed_msg, ap); ++ else ++ vfprintf(stderr, msg, ap); + fputc('\n', stderr); + } + va_end(ap); + ++ if (prefixed_msg) ++ free(prefixed_msg); ++ + return; + } + + void log_error(unsigned logopt, const char *msg, ...) + { ++ char *prefixed_msg; + va_list ap; + ++ prefixed_msg = prepare_attempt_prefix(msg); ++ + va_start(ap, msg); +- if (logging_to_syslog) +- vsyslog(LOG_ERR, msg, ap); +- else { +- vfprintf(stderr, msg, ap); ++ if (logging_to_syslog) { ++ if (prefixed_msg) ++ vsyslog(LOG_ERR, prefixed_msg, ap); ++ else ++ vsyslog(LOG_INFO, msg, ap); ++ } else { ++ if (prefixed_msg) ++ vfprintf(stderr, prefixed_msg, ap); ++ else ++ vfprintf(stderr, msg, ap); + fputc('\n', stderr); + } + va_end(ap); ++ ++ if (prefixed_msg) ++ free(prefixed_msg); ++ + return; + } + + void log_crit(unsigned logopt, const char *msg, ...) + { ++ char *prefixed_msg; + va_list ap; + ++ prefixed_msg = prepare_attempt_prefix(msg); ++ + va_start(ap, msg); +- if (logging_to_syslog) +- vsyslog(LOG_CRIT, msg, ap); +- else { +- vfprintf(stderr, msg, ap); ++ if (logging_to_syslog) { ++ if (prefixed_msg) ++ vsyslog(LOG_CRIT, prefixed_msg, ap); ++ else ++ vsyslog(LOG_INFO, msg, ap); ++ } else { ++ if (prefixed_msg) ++ vfprintf(stderr, prefixed_msg, ap); ++ else ++ vfprintf(stderr, msg, ap); + fputc('\n', stderr); + } + va_end(ap); ++ ++ if (prefixed_msg) ++ free(prefixed_msg); ++ + return; + } + + void log_debug(unsigned int logopt, const char *msg, ...) + { + unsigned int opt_log = logopt & LOGOPT_DEBUG; ++ char *prefixed_msg; + va_list ap; + + if (!do_debug && !opt_log) + return; + ++ prefixed_msg = prepare_attempt_prefix(msg); ++ + va_start(ap, msg); +- if (logging_to_syslog) +- vsyslog(LOG_WARNING, msg, ap); +- else { +- vfprintf(stderr, msg, ap); ++ if (logging_to_syslog) { ++ if (prefixed_msg) ++ vsyslog(LOG_WARNING, prefixed_msg, ap); ++ else ++ vsyslog(LOG_INFO, msg, ap); ++ } else { ++ if (prefixed_msg) ++ vfprintf(stderr, prefixed_msg, ap); ++ else ++ vfprintf(stderr, msg, ap); + fputc('\n', stderr); + } + va_end(ap); + ++ if (prefixed_msg) ++ free(prefixed_msg); ++ + return; + } + + void logmsg(const char *msg, ...) + { ++ char *prefixed_msg; + va_list ap; ++ ++ prefixed_msg = prepare_attempt_prefix(msg); ++ + va_start(ap, msg); +- if (logging_to_syslog) +- vsyslog(LOG_CRIT, msg, ap); +- else { +- vfprintf(stderr, msg, ap); ++ if (logging_to_syslog) { ++ if (prefixed_msg) ++ vsyslog(LOG_CRIT, prefixed_msg, ap); ++ else ++ vsyslog(LOG_INFO, msg, ap); ++ } else { ++ if (prefixed_msg) ++ vfprintf(stderr, prefixed_msg, ap); ++ else ++ vfprintf(stderr, msg, ap); + fputc('\n', stderr); + } + va_end(ap); ++ ++ if (prefixed_msg) ++ free(prefixed_msg); ++ + return; + } + diff --git a/SOURCES/autofs-5.1.2-make-lookup_nss_read_master-return-nss-status.patch b/SOURCES/autofs-5.1.2-make-lookup_nss_read_master-return-nss-status.patch new file mode 100644 index 0000000..d9d09e6 --- /dev/null +++ b/SOURCES/autofs-5.1.2-make-lookup_nss_read_master-return-nss-status.patch @@ -0,0 +1,99 @@ +autofs-5.1.2 - make lookup_nss_read_master() return nss status + +From: Ian Kent + +Currently lookup_nss_read_master() uses a boolean return but in order +for the master map retry read to function properly when trying to read +plus included maps it needs to return an NSS status instead. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/lookup.c | 14 ++++++++++---- + modules/lookup_dir.c | 2 +- + modules/lookup_file.c | 2 +- + 4 files changed, 13 insertions(+), 6 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -212,6 +212,7 @@ + - dont exit on master map read fail timeout. + - set sane default master read wait timeout. + - don't return until after master map retry read. ++- make lookup_nss_read_master() return nss status. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -175,7 +175,7 @@ int lookup_nss_read_master(struct master + if (result == NSS_STATUS_UNAVAIL) + master->read_fail = 1; + +- return !result; ++ return result; + } else { + char *name = master->name; + char *tmp; +@@ -225,7 +225,7 @@ int lookup_nss_read_master(struct master + if (result == NSS_STATUS_UNAVAIL) + master->read_fail = 1; + +- return !result; ++ return result; + } + } + } +@@ -237,7 +237,7 @@ int lookup_nss_read_master(struct master + if (!list_empty(&nsslist)) + free_sources(&nsslist); + error(logopt, "can't to read name service switch config."); +- return 0; ++ return NSS_STATUS_UNAVAIL; + } + + /* First one gets it */ +@@ -282,6 +282,12 @@ int lookup_nss_read_master(struct master + } + } + ++ /* We've been instructed to move onto the next source */ ++ if (result == NSS_STATUS_TRYAGAIN) { ++ result = NSS_STATUS_SUCCESS; ++ continue; ++ } ++ + if (result == NSS_STATUS_UNKNOWN || + result == NSS_STATUS_NOTFOUND) { + debug(logopt, "no map - continuing to next source"); +@@ -302,7 +308,7 @@ int lookup_nss_read_master(struct master + if (!list_empty(&nsslist)) + free_sources(&nsslist); + +- return !result; ++ return result; + } + + static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t age) +--- autofs-5.0.7.orig/modules/lookup_dir.c ++++ autofs-5.0.7/modules/lookup_dir.c +@@ -154,7 +154,7 @@ static int include_file(struct master *m + master->depth++; + debug(logopt, MODPREFIX "include: %s", master->name); + status = lookup_nss_read_master(master, age); +- if (!status) { ++ if (status != NSS_STATUS_SUCCESS) { + warn(logopt, + MODPREFIX + "failed to read included master map %s", +--- autofs-5.0.7.orig/modules/lookup_file.c ++++ autofs-5.0.7/modules/lookup_file.c +@@ -503,7 +503,7 @@ int lookup_read_master(struct master *ma + master->recurse = 1; + master->depth++; + status = lookup_nss_read_master(master, age); +- if (!status) { ++ if (status != NSS_STATUS_SUCCESS) { + warn(logopt, + MODPREFIX + "failed to read included master map %s", diff --git a/SOURCES/autofs-5.1.2-make-set_direct_mount_catatonic-more-general.patch b/SOURCES/autofs-5.1.2-make-set_direct_mount_catatonic-more-general.patch new file mode 100644 index 0000000..14e6cf0 --- /dev/null +++ b/SOURCES/autofs-5.1.2-make-set_direct_mount_catatonic-more-general.patch @@ -0,0 +1,219 @@ +autofs-5.1.2 - make set_direct_mount_catatonic() more general + +From: Ian Kent + +Setting direct mounts catatonic at exit doesn't go far enough. + +To avoid possible hang on access of automount managed paths when +the daemon has exited all mounted autofs file systems must be set +catatonic when the daemon exits. + +Start by making set_direct_mount_catatonic() able to handle the +different types of autofs mounts and move it to the mounts function +library. +--- + CHANGELOG | 1 + daemon/direct.c | 69 +++---------------------------------------------------- + include/mounts.h | 1 + lib/mounts.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 71 insertions(+), 64 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -213,6 +213,7 @@ + - set sane default master read wait timeout. + - don't return until after master map retry read. + - make lookup_nss_read_master() return nss status. ++- make set_direct_mount_catatonic() more general. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -82,65 +82,6 @@ static void mnts_cleanup(void *arg) + return; + } + +-/* When exiting direct mount triggers must be set catatonic, regardless +- * of whether they are busy on not, to avoid a hang on access once the +- * daemon has gone away. +- */ +-static int set_direct_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd) +-{ +- struct ioctl_ops *ops = get_ioctl_ops(); +- unsigned int opened = 0; +- char buf[MAX_ERR_BUF]; +- int fd = -1; +- int error; +- +- /* In case the miscellaneous device isn't being used try +- * and use an existing ioctl control fd. In this case if +- * we don't already have an ioctl fd the mount can't be +- * set catatonic if it's covered. +- */ +- if (ioctlfd >= 0) +- fd = ioctlfd; +- else if (me->ioctlfd >= 0) +- fd = me->ioctlfd; +- else { +- error = ops->open(ap->logopt, &fd, me->dev, me->key); +- if (error == -1) { +- int err = errno; +- char *estr; +- +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- error(ap->logopt, +- "failed to open ioctlfd for %s, error: %s", +- me->key, estr); +- return err; +- } +- opened = 1; +- } +- +- if (fd >= 0) { +- error = ops->catatonic(ap->logopt, fd); +- if (error == -1) { +- int err = errno; +- char *estr; +- +- estr = strerror_r(errno, buf, MAX_ERR_BUF); +- error(ap->logopt, +- "failed to set %s catatonic, error: %s", +- me->key, estr); +- if (opened) +- ops->close(ap->logopt, fd); +- return err; +- } +- if (opened) +- ops->close(ap->logopt, fd); +- } +- +- debug(ap->logopt, "set %s catatonic", me->key); +- +- return 0; +-} +- + int do_umount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struct mapent *me) + { + struct ioctl_ops *ops = get_ioctl_ops(); +@@ -190,19 +131,19 @@ int do_umount_autofs_direct(struct autof + "ask umount returned busy for %s", + me->key); + if (ap->state != ST_READMAP) +- set_direct_mount_catatonic(ap, me, ioctlfd); ++ set_mount_catatonic(ap, me, ioctlfd); + if (opened) + ops->close(ap->logopt, ioctlfd); + return 1; + } else { + me->ioctlfd = -1; +- set_direct_mount_catatonic(ap, me, ioctlfd); ++ set_mount_catatonic(ap, me, ioctlfd); + ops->close(ap->logopt, ioctlfd); + goto force_umount; + } + } + me->ioctlfd = -1; +- set_direct_mount_catatonic(ap, me, ioctlfd); ++ set_mount_catatonic(ap, me, ioctlfd); + ops->close(ap->logopt, ioctlfd); + } else { + error(ap->logopt, +@@ -297,12 +238,12 @@ int umount_autofs_direct(struct autofs_p + if (!error) + goto done; + +- error = set_direct_mount_catatonic(ap, me, me->ioctlfd); ++ error = set_mount_catatonic(ap, me, me->ioctlfd); + if (!error) + goto done; + + /* We really need to set this, last ditch attempt */ +- set_direct_mount_catatonic(ap, me, -1); ++ set_mount_catatonic(ap, me, -1); + done: + me = cache_enumerate(mc, me); + } +--- autofs-5.0.7.orig/include/mounts.h ++++ autofs-5.0.7/include/mounts.h +@@ -114,6 +114,7 @@ void set_tsd_user_vars(unsigned int, uid + const char *mount_type_str(unsigned int); + void notify_mount_result(struct autofs_point *, const char *, time_t, const char *); + int try_remount(struct autofs_point *, struct mapent *, unsigned int); ++int set_mount_catatonic(struct autofs_point *, struct mapent *, int); + int umount_ent(struct autofs_point *, const char *); + int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *); + int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *); +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -1894,6 +1894,70 @@ int try_remount(struct autofs_point *ap, + return 0; + } + ++/* ++ * When exiting mounts need be set catatonic, regardless of whether they ++ * are busy on not, to avoid a hang on access once the daemon has gone ++ * away. ++ */ ++int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd) ++{ ++ struct ioctl_ops *ops = get_ioctl_ops(); ++ unsigned int opened = 0; ++ char buf[MAX_ERR_BUF]; ++ char *path; ++ int fd = -1; ++ int error; ++ dev_t dev; ++ ++ path = ap->path; ++ dev = ap->dev; ++ if (me && (ap->type == LKP_DIRECT || *me->key == '/')) { ++ path = me->key; ++ dev = me->dev; ++ } ++ ++ if (ioctlfd >= 0) ++ fd = ioctlfd; ++ else if (me && me->ioctlfd >= 0) ++ fd = me->ioctlfd; ++ else { ++ error = ops->open(ap->logopt, &fd, dev, path); ++ if (error == -1) { ++ int err = errno; ++ char *estr; ++ ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "failed to open ioctlfd for %s, error: %s", ++ path, estr); ++ return err; ++ } ++ opened = 1; ++ } ++ ++ if (fd >= 0) { ++ error = ops->catatonic(ap->logopt, fd); ++ if (error == -1) { ++ int err = errno; ++ char *estr; ++ ++ estr = strerror_r(errno, buf, MAX_ERR_BUF); ++ error(ap->logopt, ++ "failed to set %s catatonic, error: %s", ++ path, estr); ++ if (opened) ++ ops->close(ap->logopt, fd); ++ return err; ++ } ++ if (opened) ++ ops->close(ap->logopt, fd); ++ } ++ ++ debug(ap->logopt, "set %s catatonic", path); ++ ++ return 0; ++} ++ + int umount_ent(struct autofs_point *ap, const char *path) + { + int rv; diff --git a/SOURCES/autofs-5.1.2-set-autofs-mounts-catatonic-at-exit.patch b/SOURCES/autofs-5.1.2-set-autofs-mounts-catatonic-at-exit.patch new file mode 100644 index 0000000..bac2be6 --- /dev/null +++ b/SOURCES/autofs-5.1.2-set-autofs-mounts-catatonic-at-exit.patch @@ -0,0 +1,207 @@ +autofs-5.1.2 - set autofs mounts catatonic at exit + +From: Ian Kent + +Setting direct mounts catatonic at exit doesn't go far enough. + +To avoid possible hang on access of automount managed paths when +the daemon has exited all mounted autofs file systems must be set +catatonic when the daemon exits. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 1 + daemon/direct.c | 17 ++++--------- + daemon/indirect.c | 3 -- + include/mounts.h | 3 +- + lib/mounts.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++++++- + 6 files changed, 78 insertions(+), 16 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -214,6 +214,7 @@ + - don't return until after master map retry read. + - make lookup_nss_read_master() return nss status. + - make set_direct_mount_catatonic() more general. ++- set autofs mounts catatonic at exit. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -1732,6 +1732,7 @@ int handle_mounts_exit(struct autofs_poi + */ + ret = umount_autofs(ap, NULL, 1); + if (!ret) { ++ set_indirect_mount_tree_catatonic(ap); + handle_mounts_cleanup(ap); + return 1; + } +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -130,20 +130,16 @@ int do_umount_autofs_direct(struct autof + error(ap->logopt, + "ask umount returned busy for %s", + me->key); +- if (ap->state != ST_READMAP) +- set_mount_catatonic(ap, me, ioctlfd); + if (opened) + ops->close(ap->logopt, ioctlfd); + return 1; + } else { + me->ioctlfd = -1; +- set_mount_catatonic(ap, me, ioctlfd); + ops->close(ap->logopt, ioctlfd); + goto force_umount; + } + } + me->ioctlfd = -1; +- set_mount_catatonic(ap, me, ioctlfd); + ops->close(ap->logopt, ioctlfd); + } else { + error(ap->logopt, +@@ -173,8 +169,11 @@ int do_umount_autofs_direct(struct autof + warn(ap->logopt, "mount point %s is in use", me->key); + if (ap->state == ST_SHUTDOWN_FORCE) + goto force_umount; +- else ++ else { ++ if (ap->state != ST_READMAP) ++ set_direct_mount_tree_catatonic(ap, me); + return 0; ++ } + break; + case ENOTDIR: + error(ap->logopt, "mount point is not a directory"); +@@ -238,12 +237,8 @@ int umount_autofs_direct(struct autofs_p + if (!error) + goto done; + +- error = set_mount_catatonic(ap, me, me->ioctlfd); +- if (!error) +- goto done; +- +- /* We really need to set this, last ditch attempt */ +- set_mount_catatonic(ap, me, -1); ++ if (ap->state != ST_READMAP) ++ set_direct_mount_tree_catatonic(ap, me); + done: + me = cache_enumerate(mc, me); + } +--- autofs-5.0.7.orig/daemon/indirect.c ++++ autofs-5.0.7/daemon/indirect.c +@@ -286,9 +286,6 @@ int umount_autofs_indirect(struct autofs + #endif + } + +- if (ap->shutdown) +- ops->catatonic(ap->logopt, ap->ioctlfd); +- + ops->close(ap->logopt, ap->ioctlfd); + ap->ioctlfd = -1; + sched_yield(); +--- autofs-5.0.7.orig/include/mounts.h ++++ autofs-5.0.7/include/mounts.h +@@ -114,7 +114,8 @@ void set_tsd_user_vars(unsigned int, uid + const char *mount_type_str(unsigned int); + void notify_mount_result(struct autofs_point *, const char *, time_t, const char *); + int try_remount(struct autofs_point *, struct mapent *, unsigned int); +-int set_mount_catatonic(struct autofs_point *, struct mapent *, int); ++void set_indirect_mount_tree_catatonic(struct autofs_point *); ++void set_direct_mount_tree_catatonic(struct autofs_point *, struct mapent *); + int umount_ent(struct autofs_point *, const char *); + int mount_multi_triggers(struct autofs_point *, struct mapent *, const char *, unsigned int, const char *); + int umount_multi_triggers(struct autofs_point *, struct mapent *, char *, const char *); +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -1899,7 +1899,7 @@ int try_remount(struct autofs_point *ap, + * are busy on not, to avoid a hang on access once the daemon has gone + * away. + */ +-int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd) ++static int set_mount_catatonic(struct autofs_point *ap, struct mapent *me, int ioctlfd) + { + struct ioctl_ops *ops = get_ioctl_ops(); + unsigned int opened = 0; +@@ -1926,6 +1926,9 @@ int set_mount_catatonic(struct autofs_po + int err = errno; + char *estr; + ++ if (errno == ENOENT) ++ return 0; ++ + estr = strerror_r(errno, buf, MAX_ERR_BUF); + error(ap->logopt, + "failed to open ioctlfd for %s, error: %s", +@@ -1958,6 +1961,70 @@ int set_mount_catatonic(struct autofs_po + return 0; + } + ++static void set_multi_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) ++{ ++ if (!list_empty(&me->multi_list)) { ++ struct list_head *head = &me->multi_list; ++ struct list_head *p; ++ ++ list_for_each(p, head) { ++ struct mapent *this; ++ ++ this = list_entry(p, struct mapent, multi_list); ++ set_mount_catatonic(ap, this, this->ioctlfd); ++ } ++ } ++} ++ ++void set_indirect_mount_tree_catatonic(struct autofs_point *ap) ++{ ++ struct master_mapent *entry = ap->entry; ++ struct map_source *map; ++ struct mapent_cache *mc; ++ struct mapent *me; ++ ++ if (!is_mounted(_PROC_MOUNTS, ap->path, MNTS_AUTOFS)) ++ return; ++ ++ map = entry->maps; ++ while (map) { ++ mc = map->mc; ++ cache_readlock(mc); ++ me = cache_enumerate(mc, NULL); ++ while (me) { ++ /* Skip negative map entries and wildcard entries */ ++ if (!me->mapent) ++ goto next; ++ ++ if (!strcmp(me->key, "*")) ++ goto next; ++ ++ /* Only need to set offset mounts catatonic */ ++ if (me->multi && me->multi == me) ++ set_multi_mount_tree_catatonic(ap, me); ++next: ++ me = cache_enumerate(mc, me); ++ } ++ cache_unlock(mc); ++ map = map->next; ++ } ++ ++ /* By the time this function is called ap->ioctlfd will have ++ * been closed so don't try and use it. ++ */ ++ set_mount_catatonic(ap, NULL, -1); ++ ++ return; ++} ++ ++void set_direct_mount_tree_catatonic(struct autofs_point *ap, struct mapent *me) ++{ ++ /* Set offset mounts catatonic for this mapent */ ++ if (me->multi && me->multi == me) ++ set_multi_mount_tree_catatonic(ap, me); ++ set_mount_catatonic(ap, me, me->ioctlfd); ++} ++ + int umount_ent(struct autofs_point *ap, const char *path) + { + int rv; diff --git a/SOURCES/autofs-5.1.2-set-sane-default-master-read-wait-timeout.patch b/SOURCES/autofs-5.1.2-set-sane-default-master-read-wait-timeout.patch new file mode 100644 index 0000000..d1954ad --- /dev/null +++ b/SOURCES/autofs-5.1.2-set-sane-default-master-read-wait-timeout.patch @@ -0,0 +1,85 @@ +autofs-5.1.2 - set sane default master read wait timeout + +From: Ian Kent + +If an unused map source is configured in nss, with the default +of waiting indefinitely, autofs will not start. + +To restore the previous behaviour of this case set a sensible +default timeout for the configuration option master_wait. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + include/defaults.h | 2 +- + man/autofs.conf.5.in | 4 ++-- + redhat/autofs.conf.default.in | 6 +++--- + samples/autofs.conf.default.in | 6 +++--- + 5 files changed, 10 insertions(+), 9 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -210,6 +210,7 @@ + - add master read wait option. + - fix included master map not found return. + - dont exit on master map read fail timeout. ++- set sane default master read wait timeout. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/include/defaults.h ++++ autofs-5.0.7/include/defaults.h +@@ -25,7 +25,7 @@ + #define DEFAULT_MASTER_MAP_NAME "auto.master" + + #define DEFAULT_TIMEOUT "600" +-#define DEFAULT_MASTER_WAIT "-1" ++#define DEFAULT_MASTER_WAIT "10" + #define DEFAULT_NEGATIVE_TIMEOUT "60" + #define DEFAULT_MOUNT_WAIT "-1" + #define DEFAULT_UMOUNT_WAIT "12" +--- autofs-5.0.7.orig/man/autofs.conf.5.in ++++ autofs-5.0.7/man/autofs.conf.5.in +@@ -32,8 +32,8 @@ with earlier autofs releases. + .TP + .B master_wait + sets the default maximum time to wait for the master map to become +-available if it cannot be read at program start (program default -1, +-wait forever). ++available if it cannot be read at program start (program default 10, ++wait for 10 seconds then continue). + .TP + .B negative_timeout + .br +--- autofs-5.0.7.orig/redhat/autofs.conf.default.in ++++ autofs-5.0.7/redhat/autofs.conf.default.in +@@ -16,10 +16,10 @@ timeout = 300 + # + # master_wait - set the default maximum time to wait for the + # master map to become available if it cannot +-# be read at program start (default -1, wait +-# forever). ++# be read at program start (default 10, wait ++# for 10 seconds then continue). + # +-#master_wait = -1 ++#master_wait = 10 + # + # negative_timeout - set the default negative timeout for + # failed mount attempts (default 60). +--- autofs-5.0.7.orig/samples/autofs.conf.default.in ++++ autofs-5.0.7/samples/autofs.conf.default.in +@@ -16,10 +16,10 @@ timeout = 300 + # + # master_wait - set the default maximum time to wait for the + # master map to become available if it cannot +-# be read at program start (default -1, wait +-# forever). ++# be read at program start (default 10, wait ++# for 10 seconds then continue). + # +-# master_wait = -1 ++# master_wait = 10 + # + # negative_timeout - set the default negative timeout for + # failed mount attempts (default 60). diff --git a/SOURCES/autofs-5.1.2-update-and-add-README-for-old-autofs-schema.patch b/SOURCES/autofs-5.1.2-update-and-add-README-for-old-autofs-schema.patch new file mode 100644 index 0000000..b5e2d55 --- /dev/null +++ b/SOURCES/autofs-5.1.2-update-and-add-README-for-old-autofs-schema.patch @@ -0,0 +1,87 @@ +autofs-5.1.2 - update and add README for old autofs schema + +From: Ian Kent + +The distribution file samples/autofs.schema is very old and is +incorrect. + +This schema was added to the discribution long ago when it was +not clear what schema to use for Linux autofs information. + +The schema was updated (at least to have consistent OIDs) somewhere +along the line but the autofs distribution copy was never updated. +The schema has now been updated in autofs but it is not recommended +for use as the schema for autofs map information. + +The rfc2307 or, preferably the, rfc2307bis schema is the recommened +schema to use. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + README.autofs-schema | 22 ++++++++++++++++++++++ + samples/autofs.schema.new | 23 +++++++++++++++++++++++ + 3 files changed, 46 insertions(+) + create mode 100644 README.autofs-schema + +--- /dev/null ++++ autofs-5.0.7/README.autofs-schema +@@ -0,0 +1,22 @@ ++autofs schema ++============= ++ ++The distribution file samples/autofs.schema is very old and is ++incorrect. ++ ++This schema was added to the discribution long ago when it was ++not clear what schema to use for Linux autofs information. ++ ++The schema was corrected somewhere along the line but the autofs ++distribution copy was never updated. The schema has now been ++updated but it is not recommended for use as the schema for autofs ++map information. ++ ++The rfc2307 or, preferably the, rfc2307bis schema is the recommened ++schema to use. ++ ++Note: Upstream the schema file was updated but in RHEL-6 the old ++schema file has been left in place and the updated schema file ++add as autofs.schema.new. ++ ++Ian +--- /dev/null ++++ autofs-5.0.7/samples/autofs.schema.new +@@ -0,0 +1,23 @@ ++# Depends upon core.schema and cosine.schema ++ ++# OID Base is 1.3.6.1.4.1.2312.4 ++# ++# Attribute types are under 1.3.6.1.4.1.2312.4.1 ++# Object classes are under 1.3.6.1.4.1.2312.4.2 ++# Syntaxes are under 1.3.6.1.4.1.2312.4.3 ++ ++# Attribute Type Definitions ++ ++attributetype ( 1.3.6.1.4.1.2312.4.1.2 NAME 'automountInformation' ++ DESC 'Information used by the autofs automounter' ++ EQUALITY caseExactMatch ++ SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE ) ++ ++objectclass ( 1.3.6.1.4.1.2312.4.2.3 NAME 'automount' SUP top STRUCTURAL ++ DESC 'An entry in an automounter map' ++ MUST ( cn $ automountInformation $ objectclass ) ++ MAY ( description ) ) ++ ++objectclass ( 1.3.6.1.4.1.2312.4.2.2 NAME 'automountMap' SUP top STRUCTURAL ++ DESC 'An group of related automount objects' ++ MUST ( ou ) ) +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -217,6 +217,7 @@ + - set autofs mounts catatonic at exit. + - check NFS server availability on local mount fallback. + - honor last rw in mount options when doing a bind mount. ++- update and add README for old autofs schema. + + 25/07/2012 autofs-5.0.7 + ======================= diff --git a/SOURCES/autofs-5.1.2-use-autofs_point-to-store-expire-timeout-where-possibe.patch b/SOURCES/autofs-5.1.2-use-autofs_point-to-store-expire-timeout-where-possibe.patch new file mode 100644 index 0000000..179a812 --- /dev/null +++ b/SOURCES/autofs-5.1.2-use-autofs_point-to-store-expire-timeout-where-possibe.patch @@ -0,0 +1,290 @@ +autofs-5.1.2 - use autofs_point to store expire timeout where possibe + +From: Ian Kent + +For technical reasons the expire timeout is stored in the map entry source +rather than the struct autofs_point and must be stored in the map source for +direct (and offset) mounts. + +But with the map source re-use needed by amd format type "auto" mounts the +timeout can't be stored in the map source since the it may be different for +mounts that share the map source. + +So use the struct autofs_point where possible. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/direct.c | 6 +++--- + daemon/indirect.c | 2 +- + daemon/state.c | 12 +++++++----- + include/automount.h | 1 + + include/mounts.h | 2 ++ + lib/master.c | 5 ++++- + lib/master_parse.y | 27 +++++++++++++-------------- + lib/mounts.c | 27 +++++++++++++++++++++------ + modules/mount_autofs.c | 12 ++++-------- + 10 files changed, 57 insertions(+), 38 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -242,6 +242,7 @@ + - add config option to use mount request log id. + - work around sss startup delay. + - add sss master map wait config option. ++- use autofs_point to store expire timeout where possibe. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/direct.c ++++ autofs-5.0.7/daemon/direct.c +@@ -312,7 +312,7 @@ static int unlink_active_mounts(struct a + + if (tree_get_mnt_list(mnts, &list, me->key, 1)) { + if (ap->state == ST_READMAP) { +- time_t tout = me->source->exp_timeout; ++ time_t tout = get_exp_timeout(ap, me->source); + int save_ioctlfd, ioctlfd; + + save_ioctlfd = ioctlfd = me->ioctlfd; +@@ -518,7 +518,7 @@ int mount_autofs_direct(struct autofs_po + } + + mc = map->mc; +- timeout = map->exp_timeout; ++ timeout = get_exp_timeout(ap, map); + cache_readlock(mc); + pthread_cleanup_push(cache_lock_cleanup, mc); + me = cache_enumerate(mc, NULL); +@@ -674,7 +674,7 @@ int mount_autofs_offset(struct autofs_po + struct ioctl_ops *ops = get_ioctl_ops(); + char buf[MAX_ERR_BUF]; + struct mnt_params *mp; +- time_t timeout = me->source->exp_timeout; ++ time_t timeout = get_exp_timeout(ap, me->source); + struct stat st; + int ioctlfd, status, ret; + const char *hosts_map_name = "-hosts"; +--- autofs-5.0.7.orig/daemon/indirect.c ++++ autofs-5.0.7/daemon/indirect.c +@@ -87,7 +87,7 @@ static int do_mount_autofs_indirect(stru + { + const char *str_indirect = mount_type_str(t_indirect); + struct ioctl_ops *ops = get_ioctl_ops(); +- time_t timeout = ap->entry->maps->exp_timeout; ++ time_t timeout = get_exp_timeout(ap, ap->entry->maps); + char *options = NULL; + const char *hosts_map_name = "-hosts"; + const char *map_name = hosts_map_name; +--- autofs-5.0.7.orig/daemon/state.c ++++ autofs-5.0.7/daemon/state.c +@@ -407,6 +407,7 @@ static void do_readmap_mount(struct auto + if (valid) { + struct mapent_cache *vmc = valid->mc; + struct ioctl_ops *ops = get_ioctl_ops(); ++ time_t timeout; + time_t runfreq; + + cache_unlock(vmc); +@@ -428,9 +429,10 @@ static void do_readmap_mount(struct auto + cache_set_ino_index(vmc, me->key, me->dev, me->ino); + cache_unlock(vmc); + /* Set timeout and calculate the expire run frequency */ +- ops->timeout(ap->logopt, valid->ioctlfd, map->exp_timeout); +- if (map->exp_timeout) { +- runfreq = (map->exp_timeout + CHECK_RATIO - 1) / CHECK_RATIO; ++ timeout = get_exp_timeout(ap, map); ++ ops->timeout(ap->logopt, valid->ioctlfd, timeout); ++ if (timeout) { ++ runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + if (ap->exp_runfreq) + ap->exp_runfreq = min(ap->exp_runfreq, runfreq); + else +@@ -442,7 +444,7 @@ static void do_readmap_mount(struct auto + debug(ap->logopt, + "%s is mounted", me->key); + } else +- do_mount_autofs_direct(ap, mnts, me, map->exp_timeout); ++ do_mount_autofs_direct(ap, mnts, me, get_exp_timeout(ap, map)); + + return; + } +@@ -491,7 +493,7 @@ static void *do_readmap(void *arg) + + if (ap->type == LKP_INDIRECT) { + struct ioctl_ops *ops = get_ioctl_ops(); +- time_t timeout = ap->entry->maps->exp_timeout; ++ time_t timeout = get_exp_timeout(ap, ap->entry->maps); + ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + ops->timeout(ap->logopt, ap->ioctlfd, timeout); + lookup_prune_cache(ap, now); +--- autofs-5.0.7.orig/include/automount.h ++++ autofs-5.0.7/include/automount.h +@@ -527,6 +527,7 @@ struct autofs_point { + dev_t dev; /* "Device" number assigned by kernel */ + struct master_mapent *entry; /* Master map entry for this mount */ + unsigned int type; /* Type of map direct or indirect */ ++ time_t exp_timeout; /* Indirect mount expire timeout */ + time_t exp_runfreq; /* Frequency for polling for timeouts */ + time_t negative_timeout; /* timeout in secs for failed mounts */ + unsigned int flags; /* autofs mount flags */ +--- autofs-5.0.7.orig/include/mounts.h ++++ autofs-5.0.7/include/mounts.h +@@ -112,6 +112,8 @@ int tree_find_mnt_ents(struct mnt_list * + int tree_is_mounted(struct mnt_list *mnts, const char *path, unsigned int type); + void set_tsd_user_vars(unsigned int, uid_t, gid_t); + const char *mount_type_str(unsigned int); ++void set_exp_timeout(struct autofs_point *ap, struct map_source *source, time_t timeout); ++time_t get_exp_timeout(struct autofs_point *ap, struct map_source *source); + void notify_mount_result(struct autofs_point *, const char *, time_t, const char *); + int try_remount(struct autofs_point *, struct mapent *, unsigned int); + void set_indirect_mount_tree_catatonic(struct autofs_point *); +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -99,6 +99,7 @@ int master_add_autofs_point(struct maste + ap->negative_timeout = defaults_get_negative_timeout(); + else + ap->negative_timeout = global_negative_timeout; ++ ap->exp_timeout = defaults_get_timeout(); + ap->exp_runfreq = 0; + ap->flags = 0; + if (ghost) +@@ -980,6 +981,7 @@ static void master_add_amd_mount_section + while (paths[i]) { + const char *path = paths[i]; + unsigned int ghost = 0; ++ time_t timeout; + char *type = NULL; + char *map = NULL; + char *opts; +@@ -1065,7 +1067,8 @@ static void master_add_amd_mount_section + goto next; + } + +- source->exp_timeout = conf_amd_get_dismount_interval(path); ++ timeout = conf_amd_get_dismount_interval(path); ++ set_exp_timeout(entry->ap, source, timeout); + source->master_line = 0; + + entry->age = age; +--- autofs-5.0.7.orig/lib/master_parse.y ++++ autofs-5.0.7/lib/master_parse.y +@@ -823,19 +823,6 @@ int master_parse_entry(const char *buffe + ghost = 1; + } + +- if (timeout < 0) { +- /* +- * If no timeout is given get the timout from the +- * first map (if it exists) or the config for amd +- * maps. +- */ +- if (format && !strcmp(format, "amd")) +- timeout = conf_amd_get_dismount_interval(path); +- else if (entry->maps) +- timeout = entry->maps->exp_timeout; +- else +- timeout = default_timeout; +- } + + if (!entry->ap) { + ret = master_add_autofs_point(entry, logopt, nobind, ghost, 0); +@@ -856,6 +843,18 @@ int master_parse_entry(const char *buffe + if (negative_timeout) + entry->ap->negative_timeout = negative_timeout; + ++ if (timeout < 0) { ++ /* ++ * If no timeout is given get the timout from the ++ * autofs point, or the first map, or the config ++ * for amd maps. ++ */ ++ if (format && !strcmp(format, "amd")) ++ timeout = conf_amd_get_dismount_interval(path); ++ else ++ timeout = get_exp_timeout(entry->ap, entry->maps); ++ } ++ + if (format && !strcmp(format, "amd")) { + char *opts = conf_amd_get_map_options(path); + if (opts) { +@@ -890,7 +889,7 @@ int master_parse_entry(const char *buffe + local_free_vars(); + return 0; + } +- source->exp_timeout = timeout; ++ set_exp_timeout(entry->ap, source, timeout); + source->master_line = lineno; + + entry->age = age; +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -1616,6 +1616,24 @@ const char *mount_type_str(const unsigne + return (pos == type_count ? NULL : str_type[pos]); + } + ++void set_exp_timeout(struct autofs_point *ap, ++ struct map_source *source, time_t timeout) ++{ ++ ap->exp_timeout = timeout; ++ if (source) ++ source->exp_timeout = timeout; ++} ++ ++time_t get_exp_timeout(struct autofs_point *ap, struct map_source *source) ++{ ++ time_t timeout = ap->exp_timeout; ++ ++ if (source && ap->type == LKP_DIRECT) ++ timeout = source->exp_timeout; ++ ++ return timeout; ++} ++ + void notify_mount_result(struct autofs_point *ap, + const char *path, time_t timeout, const char *type) + { +@@ -1747,12 +1765,9 @@ static int remount_active_mount(struct a + ops->open(ap->logopt, &fd, devid, path); + if (fd == -1) + return REMOUNT_OPEN_FAIL; +- else { +- if (type == t_indirect || type == t_offset) +- timeout = ap->entry->maps->exp_timeout; +- else +- timeout = me->source->exp_timeout; +- } ++ ++ error(ap->logopt, "ap->type %d type %u", ap->type, type); ++ timeout = get_exp_timeout(ap, me->source); + + /* Re-reading the map, set timeout and return */ + if (ap->state == ST_READMAP) { +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -57,7 +57,7 @@ int mount_mount(struct autofs_point *ap, + int nobind = ap->flags & MOUNT_FLAG_NOBIND; + int ghost = ap->flags & MOUNT_FLAG_GHOST; + int symlnk = ap->flags & MOUNT_FLAG_SYMLINK; +- time_t timeout = ap->entry->maps->exp_timeout; ++ time_t timeout = get_exp_timeout(ap, ap->entry->maps); + unsigned logopt = ap->logopt; + struct map_type_info *info; + struct master *master; +@@ -272,13 +272,9 @@ int mount_mount(struct autofs_point *ap, + return 1; + } + free_map_type_info(info); +- /* The exp_timeout can't be inherited if the map is shared, so +- * the autofs point exp_runfreq must be set here. +- */ +- if (source->ref <= 1) +- source->exp_timeout = timeout; +- else +- nap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; ++ ++ set_exp_timeout(nap, NULL, timeout); ++ nap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO; + + mounts_mutex_lock(ap); + diff --git a/SOURCES/autofs-5.1.2-wait-for-master-map-available-at-start.patch b/SOURCES/autofs-5.1.2-wait-for-master-map-available-at-start.patch new file mode 100644 index 0000000..22d275f --- /dev/null +++ b/SOURCES/autofs-5.1.2-wait-for-master-map-available-at-start.patch @@ -0,0 +1,280 @@ +autofs-5.1.2 - wait for master map available at start + +From: Ian Kent + +If the network map source isn't available at start the master map +can't be read. In this case we should wait until it is available +so we can get a startup map. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + daemon/automount.c | 81 +++++++++++++++++++++++++++++++++++++++++------ + daemon/lookup.c | 8 ++++ + lib/master.c | 3 + + modules/lookup_file.c | 6 +++ + modules/lookup_nisplus.c | 14 +++++--- + modules/lookup_yp.c | 13 +++++-- + 7 files changed, 108 insertions(+), 18 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -206,6 +206,7 @@ + - add configuration option to use fqdn in mounts. + - fix use-after-free in st_queue_handler(). + - add config option to supress not found log message. ++- wait for master map available at start. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -1379,9 +1379,10 @@ static void *do_read_master(void *arg) + return NULL; + } + +-static int do_hup_signal(struct master *master, time_t age) ++static int do_hup_signal(struct master *master) + { + unsigned int logopt = master->logopt; ++ time_t age = time(NULL); + pthread_t thid; + int status; + +@@ -1470,7 +1471,7 @@ static void *statemachine(void *arg) + break; + + case SIGHUP: +- do_hup_signal(master_list, time(NULL)); ++ do_hup_signal(master_list); + break; + + default: +@@ -2031,12 +2032,56 @@ static void remove_empty_args(char **arg + *argc = j; + } + ++static int do_master_read_master(struct master *master, int wait) ++{ ++ sigset_t signalset; ++ /* Wait must be at least 1 second */ ++ unsigned int retry_wait = 2; ++ unsigned int elapsed = 0; ++ int max_wait = wait; ++ int ret = 0; ++ time_t age; ++ ++ sigemptyset(&signalset); ++ sigaddset(&signalset, SIGTERM); ++ sigaddset(&signalset, SIGINT); ++ sigaddset(&signalset, SIGHUP); ++ sigprocmask(SIG_UNBLOCK, &signalset, NULL); ++ ++ while (1) { ++ struct timespec t = { retry_wait, 0 }; ++ ++ age = time(NULL); ++ if (master_read_master(master, age, 0)) { ++ ret = 1; ++ break; ++ } ++ ++ if (nanosleep(&t, NULL) == -1) ++ break; ++ ++ if (max_wait > 0) { ++ elapsed += retry_wait; ++ if (elapsed >= max_wait) { ++ logmsg("problem reading master map, " ++ "maximum wait exceeded"); ++ break; ++ } ++ } ++ } ++ ++ sigprocmask(SIG_BLOCK, &signalset, NULL); ++ ++ return ret; ++} ++ + int main(int argc, char *argv[]) + { + int res, opt, status; + int logpri = -1; + unsigned ghost, logging, daemon_check; + unsigned dumpmaps, foreground, have_global_options; ++ unsigned master_read; + time_t timeout; + time_t age = time(NULL); + struct rlimit rlim; +@@ -2429,14 +2474,16 @@ int main(int argc, char *argv[]) + dh_tirpc = dlopen("libtirpc.so.1", RTLD_NOW); + #endif + +- if (!master_read_master(master_list, age, 0)) { +- master_kill(master_list); +- *pst_stat = 3; +- res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); +- close(start_pipefd[1]); +- release_flag_file(); +- macro_free_global_table(); +- exit(3); ++ master_read = master_read_master(master_list, age, 0); ++ if (!master_read) { ++ if (foreground) ++ logerr("%s: failed to read master map, " ++ "will retry!", ++ program); ++ else ++ logerr("%s: failed to read master map, " ++ "will retry in background!", ++ program); + } + + /* +@@ -2449,6 +2496,20 @@ int main(int argc, char *argv[]) + res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat)); + close(start_pipefd[1]); + ++ if (!master_read) { ++ /* ++ * Read master map, waiting until it is available, unless ++ * a signal is received, in which case exit returning an ++ * error. ++ */ ++ if (!do_master_read_master(master_list, -1)) { ++ logerr("%s: failed to read master map!", program); ++ master_kill(master_list); ++ release_flag_file(); ++ exit(3); ++ } ++ } ++ + state_mach_thid = pthread_self(); + statemachine(NULL); + +--- autofs-5.0.7.orig/daemon/lookup.c ++++ autofs-5.0.7/daemon/lookup.c +@@ -241,6 +241,7 @@ int lookup_nss_read_master(struct master + } + + /* First one gets it */ ++ result = NSS_STATUS_UNKNOWN; + head = &nsslist; + list_for_each(p, head) { + struct nss_source *this; +@@ -248,6 +249,13 @@ int lookup_nss_read_master(struct master + + this = list_entry(p, struct nss_source, list); + ++ if (strncmp(this->source, "files", 5) && ++ strncmp(this->source, "nis", 3) && ++ strncmp(this->source, "nisplus", 7) && ++ strncmp(this->source, "ldap", 4) && ++ strncmp(this->source, "sss", 3)) ++ continue; ++ + debug(logopt, + "reading master %s %s", this->source, master->name); + +--- autofs-5.0.7.orig/lib/master.c ++++ autofs-5.0.7/lib/master.c +@@ -922,7 +922,10 @@ int master_read_master(struct master *ma + master_mount_mounts(master, age, readall); + else { + master->read_fail = 0; ++ /* HUP signal sets readall == 1 only */ + if (!readall) ++ return 0; ++ else + master_mount_mounts(master, age, readall); + } + +--- autofs-5.0.7.orig/modules/lookup_file.c ++++ autofs-5.0.7/modules/lookup_file.c +@@ -506,6 +506,12 @@ int lookup_read_master(struct master *ma + MODPREFIX + "failed to read included master map %s", + master->name); ++ /* ++ * If we're starting up wee need the whole ++ * master map initially, so tell the upper ++ * layer to retry. ++ */ ++ master->read_fail = 1; + } + master->depth--; + master->recurse = 0; +--- autofs-5.0.7.orig/modules/lookup_nisplus.c ++++ autofs-5.0.7/modules/lookup_nisplus.c +@@ -149,19 +149,25 @@ int lookup_read_master(struct master *ma + char *estr = strerror_r(errno, buf, MAX_ERR_BUF); + logerr(MODPREFIX "malloc: %s", estr); + pthread_setcancelstate(cur_state, NULL); +- return NSS_STATUS_UNAVAIL; ++ return NSS_STATUS_UNKNOWN; + } + sprintf(tablename, "%s.org_dir.%s", ctxt->mapname, ctxt->domainname); + + /* check that the table exists */ + result = nis_lookup(tablename, FOLLOW_PATH | FOLLOW_LINKS); + if (result->status != NIS_SUCCESS && result->status != NIS_S_SUCCESS) { ++ int status = result->status; + nis_freeresult(result); +- crit(logopt, +- MODPREFIX "couldn't locate nis+ table %s", ctxt->mapname); + free(tablename); + pthread_setcancelstate(cur_state, NULL); +- return NSS_STATUS_NOTFOUND; ++ if (status == NIS_UNAVAIL || status == NIS_FAIL) ++ return NSS_STATUS_UNAVAIL; ++ else { ++ crit(logopt, ++ MODPREFIX "couldn't locate nis+ table %s", ++ ctxt->mapname); ++ return NSS_STATUS_NOTFOUND; ++ } + } + + sprintf(tablename, "[],%s.org_dir.%s", ctxt->mapname, ctxt->domainname); +--- autofs-5.0.7.orig/modules/lookup_yp.c ++++ autofs-5.0.7/modules/lookup_yp.c +@@ -282,9 +282,9 @@ int lookup_read_master(struct master *ma + char *mapname; + int err; + +- mapname = alloca(strlen(ctxt->mapname) + 1); ++ mapname = malloc(strlen(ctxt->mapname) + 1); + if (!mapname) +- return 0; ++ return NSS_STATUS_UNKNOWN; + + strcpy(mapname, ctxt->mapname); + +@@ -308,19 +308,24 @@ int lookup_read_master(struct master *ma + err = yp_all((char *) ctxt->domainname, mapname, &ypcb); + } + +- if (err == YPERR_SUCCESS) ++ if (err == YPERR_SUCCESS) { ++ free(mapname); + return NSS_STATUS_SUCCESS; ++ } + + info(logopt, + MODPREFIX "read of master map %s failed: %s", + mapname, yperr_string(err)); + +- if (err == YPERR_PMAP || err == YPERR_YPSERV) ++ free(mapname); ++ ++ if (err == YPERR_YPSERV || err == YPERR_DOMAIN) + return NSS_STATUS_UNAVAIL; + + return NSS_STATUS_NOTFOUND; + } + ++ free(mapname); + return NSS_STATUS_SUCCESS; + } + diff --git a/SOURCES/autofs-5.1.2-work-around-sss-startup-delay.patch b/SOURCES/autofs-5.1.2-work-around-sss-startup-delay.patch new file mode 100644 index 0000000..cae6a0b --- /dev/null +++ b/SOURCES/autofs-5.1.2-work-around-sss-startup-delay.patch @@ -0,0 +1,113 @@ +autofs-5.1.2 - work around sss startup delay + +From: Ian Kent + +When sssd is starting up there can be a delay before the map +information is read. During that time an ENOENT can be returned +when there actually is a map and autofs must respect the ENOENT +return and continue because no map present is a valid response. + +To work around that make the master map read wait and retry for +for a time to give sssd a chance to read the map before returning +either an ENOENT or, if the retry limit is exceeded, ETIMEDOUT. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + modules/lookup_sss.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 62 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -240,6 +240,7 @@ + - log functions to prefix messages with attempt_id if available. + - factor out set_thread_mount_request_log_id(). + - add config option to use mount request log id. ++- work around sss startup delay. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/lookup_sss.c ++++ autofs-5.0.7/modules/lookup_sss.c +@@ -30,6 +30,11 @@ + + #define MAPFMT_DEFAULT "sun" + ++/* Half a second between retries */ ++#define SETAUTOMOUNTENT_MASTER_INTERVAL 500000000 ++/* Try for 10 seconds */ ++#define SETAUTOMOUNTENT_MASTER_RETRIES 10 * 2 ++ + #define MODPREFIX "lookup(sss): " + + #define SSS_SO_NAME "libsss_autofs" +@@ -219,6 +224,53 @@ static int setautomntent(unsigned int lo + return ret; + } + ++static int setautomntent_wait(unsigned int logopt, ++ struct lookup_context *ctxt, ++ const char *mapname, ++ void **sss_ctxt, unsigned int retries) ++{ ++ unsigned int retry = 0; ++ int ret = 0; ++ ++ *sss_ctxt = NULL; ++ ++ while (++retry < retries) { ++ struct timespec t = { 0, SETAUTOMOUNTENT_MASTER_INTERVAL }; ++ struct timespec r; ++ ++ ret = ctxt->setautomntent(mapname, sss_ctxt); ++ if (ret != ENOENT) ++ break; ++ ++ if (*sss_ctxt) { ++ free(*sss_ctxt); ++ *sss_ctxt = NULL; ++ } ++ ++ while (nanosleep(&t, &r) == -1 && errno == EINTR) ++ memcpy(&t, &r, sizeof(struct timespec)); ++ } ++ ++ ++ if (ret) { ++ char buf[MAX_ERR_BUF]; ++ char *estr; ++ ++ if (*sss_ctxt) { ++ free(*sss_ctxt); ++ *sss_ctxt = NULL; ++ } ++ ++ if (retry == retries) ++ ret = ETIMEDOUT; ++ ++ estr = strerror_r(ret, buf, MAX_ERR_BUF); ++ error(logopt, MODPREFIX "setautomntent: %s", estr); ++ } ++ ++ return ret; ++} ++ + static int endautomntent(unsigned int logopt, + struct lookup_context *ctxt, void **sss_ctxt) + { +@@ -247,6 +299,15 @@ int lookup_read_master(struct master *ma + + ret = setautomntent(logopt, ctxt, ctxt->mapname, &sss_ctxt); + if (ret) { ++ unsigned int retries; ++ ++ if (ret != ENOENT) ++ return NSS_STATUS_UNAVAIL; ++ ++ retries = SETAUTOMOUNTENT_MASTER_RETRIES; ++ ret = setautomntent_wait(logopt, ++ ctxt, ctxt->mapname, &sss_ctxt, ++ retries); + if (ret == ENOENT) + return NSS_STATUS_NOTFOUND; + return NSS_STATUS_UNAVAIL; diff --git a/SOURCES/autofs-5.1.3-allow-dot-in-OPTIONSTR-value-lexer-pattern.patch b/SOURCES/autofs-5.1.3-allow-dot-in-OPTIONSTR-value-lexer-pattern.patch new file mode 100644 index 0000000..e4ae4e7 --- /dev/null +++ b/SOURCES/autofs-5.1.3-allow-dot-in-OPTIONSTR-value-lexer-pattern.patch @@ -0,0 +1,38 @@ +autofs-5.1.3 - allow dot in OPTIONSTR value lexer pattern + +From: Ian Kent + +The options string in master map entries doesn't allow dot in the +string value side of an option assignment. This prevents using an +option like vers=4.1 to apply to all entries of the map. + +Add . to the options value portion of the regular expression used +for this field. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + lib/master_tok.l | 2 +- + 2 files changed, 2 insertions(+), 1 deletion(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -252,6 +252,7 @@ + - add congigure option for limiting getgrgid_r() stack usage. + - fix unset tsd group name handling. + - revert fix argc off by one in mount_autofs.c. ++- allow dot in OPTIONSTR value lexer pattern. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/master_tok.l ++++ autofs-5.0.7/lib/master_tok.l +@@ -91,7 +91,7 @@ OPTWS [[:blank:]]* + NL \r?\n + CONT \\\n{OPTWS} + +-OPTIONSTR ([\-]?([[:alpha:]_]([[:alnum:]_\-])*(=(\"?([[:alnum:]_\-\:])+\"?))?)+) ++OPTIONSTR ([\-]?([[:alpha:]_]([[:alnum:]_\-])*(=(\"?([[:alnum:]_\-\:\.])+\"?))?)+) + MACROSTR (-D{OPTWS}([[:alpha:]_]([[:alnum:]_\-\.])*)=([[:alnum:]_\-\.])+) + SLASHIFYSTR (--(no-)?slashify-colons) + NUMBER [0-9]+ diff --git a/SOURCES/autofs-5.1.3-fix-unset-tsd-group-name-handling.patch b/SOURCES/autofs-5.1.3-fix-unset-tsd-group-name-handling.patch new file mode 100644 index 0000000..d1656e4 --- /dev/null +++ b/SOURCES/autofs-5.1.3-fix-unset-tsd-group-name-handling.patch @@ -0,0 +1,75 @@ +autofs-5.1.3 - fix unset tsd group name handling + +From: Ian Kent + +Commit 1a64a6bbc5 changed set_tsd_user_vars() to the thread specific +values even if the group name could not be obtained. + +But the structure holding the values was not initialized on allocation +so the group field might not be NULL when no group name is available. + +Also the macro addition and removal functions didn't properly handle a +macro value of NULL. + +Signed-off-by: Ian Kent +Reported-by: Donald Buczek +--- + CHANGELOG | 1 + + lib/macros.c | 8 +++++--- + lib/mounts.c | 1 + + 3 files changed, 7 insertions(+), 3 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -250,6 +250,7 @@ + - increase worker thread per-thread stack size. + - limit getgrgid_r() buffer size. + - add congigure option for limiting getgrgid_r() stack usage. ++- fix unset tsd group name handling. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/lib/macros.c ++++ autofs-5.0.7/lib/macros.c +@@ -281,18 +281,20 @@ macro_addvar(struct substvar *table, con + } + + if (lv) { +- char *this = malloc(strlen(value) + 1); ++ const char *val = value ? value : ""; ++ char *this = malloc(strlen(val) + 1); + if (!this) { + lv = table; + goto done; + } +- strcpy(this, value); ++ strcpy(this, val); + free(lv->val); + lv->val = this; + if (lv != table) + lv = table; + } else { + struct substvar *new; ++ const char *this = value ? value : ""; + char *def, *val; + + def = strdup(str); +@@ -302,7 +304,7 @@ macro_addvar(struct substvar *table, con + } + def[len] = '\0'; + +- val = strdup(value); ++ val = strdup(this); + if (!val) { + lv = table; + free(def); +--- autofs-5.0.7.orig/lib/mounts.c ++++ autofs-5.0.7/lib/mounts.c +@@ -1456,6 +1456,7 @@ void set_tsd_user_vars(unsigned int logo + error(logopt, "failed alloc tsv storage"); + return; + } ++ memset(tsv, 0, sizeof(struct thread_stdenv_vars)); + + tsv->uid = uid; + tsv->gid = gid; diff --git a/SOURCES/autofs-5.1.3-handle-additional-nfs-versions-in-mount_nfs_c.patch b/SOURCES/autofs-5.1.3-handle-additional-nfs-versions-in-mount_nfs_c.patch new file mode 100644 index 0000000..37508a7 --- /dev/null +++ b/SOURCES/autofs-5.1.3-handle-additional-nfs-versions-in-mount_nfs_c.patch @@ -0,0 +1,40 @@ +autofs-5.1.3 - handle additional nfs versions in mount_nfs.c + +From: Ian Kent + +Since NFSv4 can now have a subversion it needs to be allowed for. + +It's enough to check for an options string starting with "vers=4" or +"nfsvers=4" because it's used only to set a flag used for special +casing the availibility probe for any NFS version 4 version. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_nfs.c | 5 +++-- + 2 files changed, 4 insertions(+), 2 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -253,6 +253,7 @@ + - fix unset tsd group name handling. + - revert fix argc off by one in mount_autofs.c. + - allow dot in OPTIONSTR value lexer pattern. ++- handle additional nfs versions in mount_nfs.c. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/mount_nfs.c ++++ autofs-5.0.7/modules/mount_nfs.c +@@ -148,8 +148,9 @@ int mount_mount(struct autofs_point *ap, + } else if (_strncmp("use-weight-only", cp, o_len) == 0) { + flags |= MOUNT_FLAG_USE_WEIGHT_ONLY; + } else { +- if (_strncmp("vers=4", cp, o_len) == 0 || +- _strncmp("nfsvers=4", cp, o_len) == 0) ++ /* Is any version of NFSv4 in the options */ ++ if (_strncmp("vers=4", cp, 6) == 0 || ++ _strncmp("nfsvers=4", cp, 9) == 0) + vers = NFS4_VERS_MASK | TCP_SUPPORTED; + else if (_strncmp("vers=3", cp, o_len) == 0 || + _strncmp("nfsvers=3", cp, o_len) == 0) { diff --git a/SOURCES/autofs-5.1.3-reset-master-map-list-on-startup-retry.patch b/SOURCES/autofs-5.1.3-reset-master-map-list-on-startup-retry.patch new file mode 100644 index 0000000..d2c17f5 --- /dev/null +++ b/SOURCES/autofs-5.1.3-reset-master-map-list-on-startup-retry.patch @@ -0,0 +1,76 @@ +autofs-5.1.3 - reset master map list on startup retry + +From: Ian Kent + +On autofs startup if automount thinks the master map read failed +for some reason it retries the read after waiting for a fairly +short delay. + +It should be ok to retry with the entries seen so far but there +may be cases where that causes problems so release any existing +master map entries before retrying. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + daemon/automount.c | 25 +++++++++++++++++++++++++ + 2 files changed, 26 insertions(+) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -254,6 +254,7 @@ + - revert fix argc off by one in mount_autofs.c. + - allow dot in OPTIONSTR value lexer pattern. + - handle additional nfs versions in mount_nfs.c. ++- reset master map list on startup retry. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/daemon/automount.c ++++ autofs-5.0.7/daemon/automount.c +@@ -2099,6 +2099,27 @@ static void remove_empty_args(char **arg + *argc = j; + } + ++static void do_master_list_reset(struct master *master) ++{ ++ struct list_head *head, *p; ++ ++ master_mutex_lock(); ++ ++ head = &master->mounts; ++ list_for_each(p, head) { ++ struct master_mapent *entry; ++ ++ entry = list_entry(p, struct master_mapent, list); ++ ++ if (!list_empty(&entry->list)) ++ list_del(&entry->list); ++ master_free_mapent_sources(entry, 1); ++ master_free_mapent(entry); ++ } ++ ++ master_mutex_unlock(); ++} ++ + static int do_master_read_master(struct master *master, int wait) + { + sigset_t signalset; +@@ -2118,6 +2139,8 @@ static int do_master_read_master(struct + while (1) { + struct timespec t = { retry_wait, 0 }; + ++ do_master_list_reset(master); ++ + age = time(NULL); + if (master_read_master(master, age, 0)) { + ret = 1; +@@ -2586,6 +2609,8 @@ int main(int argc, char *argv[]) + * Failed to read master map, continue with what + * we have anyway. + */ ++ do_master_list_reset(master_list); ++ age = time(NULL); + master_read_master(master_list, age, 1); + } + } diff --git a/SOURCES/autofs-5.1.3-revert-fix-argc-off-by-one-in-mount_autofs_c.patch b/SOURCES/autofs-5.1.3-revert-fix-argc-off-by-one-in-mount_autofs_c.patch new file mode 100644 index 0000000..b5049a4 --- /dev/null +++ b/SOURCES/autofs-5.1.3-revert-fix-argc-off-by-one-in-mount_autofs_c.patch @@ -0,0 +1,58 @@ +autofs-5.1.3 - revert fix argc off by one in mount_autofs.c + +From: Ian Kent + +Commit 6a44f715cf to fix an off by one error in the arguments calculation +when mounting an autofs submount actually introduced an off by one error +instead of fixing one. + +Revert the change. + +Signed-off-by: Ian Kent +--- + CHANGELOG | 1 + + modules/mount_autofs.c | 8 ++++---- + 2 files changed, 5 insertions(+), 4 deletions(-) + +--- autofs-5.0.7.orig/CHANGELOG ++++ autofs-5.0.7/CHANGELOG +@@ -251,6 +251,7 @@ + - limit getgrgid_r() buffer size. + - add congigure option for limiting getgrgid_r() stack usage. + - fix unset tsd group name handling. ++- revert fix argc off by one in mount_autofs.c. + + 25/07/2012 autofs-5.0.7 + ======================= +--- autofs-5.0.7.orig/modules/mount_autofs.c ++++ autofs-5.0.7/modules/mount_autofs.c +@@ -181,11 +181,11 @@ int mount_mount(struct autofs_point *ap, + + if (options) { + char *t = options; +- while ((t = strchr(t, ',')) != NULL) { ++ do { + argc++; + if (*t == ',') + t++; +- } ++ } while ((t = strchr(t, ',')) != NULL); + } + argv = (const char **) alloca((argc + 1) * sizeof(char *)); + +@@ -213,13 +213,13 @@ int mount_mount(struct autofs_point *ap, + + if (options) { + p = options; +- while ((p = strchr(p, ',')) != NULL) { ++ do { + if (*p == ',') { + *p = '\0'; + p++; + } + argv[argc++] = p; +- } ++ } while ((p = strchr(p, ',')) != NULL); + } + argv[argc] = NULL; + diff --git a/SPECS/autofs.spec b/SPECS/autofs.spec new file mode 100644 index 0000000..776262f --- /dev/null +++ b/SPECS/autofs.spec @@ -0,0 +1,2958 @@ +# +# $Id: autofs.spec,v 1.11 2003/12/04 15:41:32 raven Exp $ +# +# Use --without systemd in your rpmbuild command or force values to 0 to +# disable them. +%define with_systemd %{?_without_systemd: 0} %{?!_without_systemd: 1} + +Summary: A tool for automatically mounting and unmounting filesystems +Name: autofs +Version: 5.0.7 +Release: 70%{?dist}.1 +Epoch: 1 +License: GPLv2+ +Group: System Environment/Daemons +Source: ftp://ftp.kernel.org/pub/linux/daemons/autofs/v5/autofs-%{version}.tar.bz2 +Patch1: autofs-5.0.7-fix-nobind-sun-escaped-map-entries.patch +Patch2: autofs-5.0.7-fix-use-cache-entry-after-free-mistake.patch +Patch3: autofs-5.0.7-fix-ipv6-proximity-calculation.patch +Patch4: autofs-5.0.7-fix-parse-buffer-initialization.patch +Patch5: autofs-5.0.7-fix-typo-in-automount-8.patch +Patch6: autofs-5.0.7-include-usage-in-usage-message.patch +Patch7: autofs-5.0.7-dont-wait-forever-to-restart.patch +Patch8: autofs-5.0.7-add-timeout-option-description-to-man-page.patch +Patch9: autofs-5.0.7-fix-null-map-entry-order-handling.patch +Patch10: autofs-5.0.7-make-description-of-default-MOUNT_WAIT-setting-clear.patch +Patch11: autofs-5.0.7-configure-in-allow-cross-compilation.patch +Patch12: autofs-5.0.7-README-update-mailing-list-subscription-info.patch +Patch13: autofs-5.0.7-allow-non-root-user-to-check-status.patch +Patch14: autofs-5.0.7-configure-allow-cross-compilation-update.patch +Patch15: autofs-5.0.6-fix-recursive-mount-deadlock.patch +Patch16: autofs-5.0.6-increase-file-map-read-buffer-size.patch +Patch17: autofs-5.0.7-handle-new-location-of-systemd.patch +Patch18: autofs-5.0.7-fix-map-entry-duplicate-offset-detection.patch +Patch19: autofs-5.0.7-allow-nsswitch_conf-to-not-contain-automount-lines.patch +Patch20: autofs-5.0.7-fix-nobind-man-page-description.patch +Patch21: autofs-5.0.7-fix-submount-offset-delete.patch +Patch22: autofs-5.0.7-fix-init-script-status-return.patch +Patch23: autofs-5.0.7-fix-use-get_proximity-without-libtirpc.patch +Patch24: autofs-5.0.7-dont-use-dirent-d_type-to-filter-out-files-in-scandir.patch +Patch25: autofs-5.0.7-dont-schedule-new-alarms-after-readmap.patch +Patch26: autofs-5.0.7-use-numeric-protocol-ids-instead-of-protoent-structs.patch +Patch27: autofs-5.0.7-lib-defaults-use-WITH_LDAP-conditional-around-LDAP-types.patch +Patch28: autofs-5.0.7-make-yellow-pages-support-optional.patch +Patch29: autofs-5.0.7-modules-replicated-use-sin6.addr-s6_addr32.patch +Patch30: autofs-5.0.7-workaround-missing-GNU-versionsort-extension.patch +Patch31: autofs-5.0.7-dont-fail-on-master-map-self-include.patch +Patch32: autofs-5.0.7-fix-wildcard-multi-map-regression.patch +Patch33: autofs-5.0.7-fix-file-descriptor-leak-when-reloading-the-daemon.patch +Patch34: autofs-5.0.7-depricate-nosymlink-pseudo-option.patch +Patch35: autofs-5.0.7-add-symlink-pseudo-option.patch +Patch36: autofs-5.0.7-update-kernel-include-files.patch +Patch37: autofs-5.0.7-fix-requires-in-spec-file.patch +Patch38: autofs-5.0.7-fix-libtirpc-build-option.patch +Patch39: autofs-5.0.7-fix-systemd-unidir-in-spec-file.patch +Patch40: autofs-5.0.7-document-browse-option-in-man-page.patch +Patch41: autofs-5.0.7-fix-automounter-support-on-parisc.patch +Patch42: autofs-5.0.7-fix-some-automount_8-typos.patch +Patch43: autofs-5.0.7-syncronize-handle_mounts-shutdown.patch +Patch44: autofs-5.0.7-fix-submount-tree-not-all-expiring.patch +Patch45: autofs-5.0.7-make-dump-maps-check-for-duplicate-indirect-mounts.patch +Patch46: autofs-5.0.7-document-allowed-map-sources-in-auto_master.patch +Patch47: autofs-5.0.7-add-enable-sloppy-mount-option-to-configure.patch +Patch48: autofs-5.0.7-fix-interface-address-null-check.patch +Patch49: autofs-5.0.7-dont-probe-rdma-mounts.patch +Patch50: autofs-5.0.7-fix-master-map-mount-options-matching.patch +Patch51: autofs-5.0.7-fix-master-map-bogus-keywork-match.patch +Patch52: autofs-5.0.7-fix-fix-map-entry-duplicate-offset-detection.patch +Patch53: autofs-5.0.7-probe-each-nfs-version-in-turn-for-singleton-mounts.patch +Patch54: autofs-5.0.7-fix-fcntl-return-check.patch +Patch55: autofs-5.0.7-fix-spawn_umount-return-check-in-mount_bind-lookup_init.patch +Patch56: autofs-5.0.7-fix-check-mkdir_path-in-mount_bind-mount_mount.patch +Patch57: autofs-5.0.7-fix-incorrect-name-in-test.patch +Patch58: autofs-5.0.7-remove-debug-only-code-in-alarm-c.patch +Patch59: autofs-5.0.7-fix-inconsistent-use-of-cache-lock-in-handle_packet_missing_direct.patch +Patch60: autofs-5.0.7-fix-several-off-by-one-errors.patch +Patch61: autofs-5.0.7-fix-memory-leak-in-get_dc_list.patch +Patch62: autofs-5.0.7-fix-host_addr-null-reference-in-add_new_host.patch +Patch63: autofs-5.0.7-add-null-check-in-read_one.patch +Patch64: autofs-5.0.7-add-pgrp-check-in-do_spawn.patch +Patch65: autofs-5.0.7-fix-inconsistent-signed-usage-for-__rpc_ping.patch +Patch66: autofs-5.0.7-add-null-check-in-extract_version.patch +Patch67: autofs-5.0.7-recheck-valid-map-entry-lookup-return-in-do_readmap_mount.patch +Patch68: autofs-5.0.7-add-null-check-in-parse_server_string.patch +Patch69: autofs-5.0.7-add-map-entry-null-check-in-do_expire_direct.patch +Patch70: autofs-5.0.7-add-mapent-null-check-in-lookup-nisplus-lookup_mount.patch +Patch71: autofs-5.0.7-fix-potential-null-dereference-in-lookup_mount.patch +Patch72: autofs-5.0.7-fix-leaked-ldap-percent-hack-allocation-in-lookup_one.patch +Patch73: autofs-5.0.7-fix-incorrect-value-reference-in-parse_line.patch +Patch74: autofs-5.0.7-add-debug-alert-for-waitpid-in-check_nfs_mount_version.patch +Patch75: autofs-5.0.7-add-initialization-of-bind_result-in.patch-do_sasl_bind.patch +Patch76: autofs-5.0.7-fix-incorrect-check-in-flag_is_owned.patch +Patch77: autofs-5.0.7-fix-possible-use-after-free-in-lookup_dir-lookup_init.patch +Patch78: autofs-5.0.7-add-changlog-entry-for-coverity-fixes.patch +Patch79: autofs-5.0.7-fix-probe-each-nfs-version-in-turn-for-singleton-mounts.patch +Patch80: autofs-5.0.7-misc-man-page-fixes.patch +Patch81: autofs-5.0.7-fix-add-null-check-in-parse_server_string.patch +Patch82: autofs-5.0.7-check-for-protocol-option.patch +Patch83: autofs-5.0.7-use-ulimit-max-open-files-if-greater-than-internal-maximum.patch +Patch84: autofs-5.0.7-dont-override-LDFLAGS-in-make-rules.patch +Patch85: autofs-5.0.7-fix-a-couple-of-compiler-warnings.patch +Patch86: autofs-5.0.7-add-after-sssd-dependency-to-unit-file.patch +Patch87: autofs-5.0.7-fix-syncronize-handle_mounts-shutdown.patch +Patch88: autofs-5.0.7-fix-fix-wildcard-multi-map-regression.patch +Patch89: autofs-5.0.7-fix-dumpmaps-multi-output.patch +Patch90: autofs-5.0.7-try-and-cleanup-after-dumpmaps.patch +Patch91: autofs-5.0.7-teach-dumpmaps-to-output-simple-key-value-pairs.patch +Patch92: autofs-5.0.7-fix-get_nfs_info-probe.patch +Patch93: autofs-5.0.7-fix-portmap-lookup.patch +Patch94: autofs-5.0.7-only-probe-specific-nfs-version-when-requested.patch +Patch95: autofs-5.0.8-fix-ipv6-libtirpc-getport.patch +Patch96: autofs-5.0.7-improve-timeout-option-description.patch +Patch97: autofs-5.0.8-fix-ipv6-link-local-address-handling.patch +Patch98: autofs-5.0.8-fix-fix-ipv6-libtirpc-getport.patch +Patch99: autofs-5.0.8-get_nfs_info-should-query-portmapper-if-port-is-not-given.patch +Patch100: autofs-5.0.8-fix-ipv6-libtirpc-getport-proto-not-set.patch +Patch101: autofs-5.0.8-fix-portmap-not-trying-proto-v2.patch +Patch102: autofs-5.0.8-fix-negative-status-being-reset-on-map-read.patch +Patch103: autofs-5.0.9-fix-fix-negative-status-being-reset-on-map-read.patch +Patch104: autofs-5.0.9-check-for-non-existent-negative-entries-in-lookup_ghost.patch +Patch105: autofs-5.0.7-allow-use-of-hosts-map-in-maps.patch +Patch106: autofs-5.0.8-fix-options-compare.patch +Patch107: autofs-5.0.8-fix-fix-options-compare.patch + +# pre-patches for amd parser series. +Patch400: autofs-5.0.8-fix-max-declaration.patch +Patch401: autofs-5.0.7-setup-program-map-env-from-macro-table.patch +Patch402: autofs-5.0.7-add-short-host-name-standard-marco-variable.patch +Patch403: autofs-5.0.8-fix-symlink-fail-message-in-mount_bind-c.patch +Patch404: autofs-5.0.7-add-std-vars-to-program-map-invocation.patch +Patch405: autofs-5.0.8-check-for-existing-offset-mount-before-mounting.patch +Patch406: autofs-5.0.8-remove-macro-debug-prints.patch +Patch407: autofs-5.0.8-fix-cache-readlock-not-taken-on-lookup.patch +Patch408: autofs-5.0.7-fix-compilation-of-lookup_ldap_c-without-sasl.patch +Patch409: autofs-5.0.8-fix-undefined-authtype_requires_creds-err-if-ldap-en.patch +Patch410: autofs-5.0.8-pass-map_source-as-function-paramter-where-possible.patch +Patch411: autofs-5.0.8-check-for-bind-onto-self-in-mount_bind-c.patch +Patch412: autofs-5.0.8-fix-symlink-expire.patch +Patch413: autofs-5.0.8-fix-master-map-type-check.patch +Patch414: autofs-5.0.8-dont-clobber-mapent-for-negative-cache.patch +Patch415: autofs-5.0.7-fix-bad-mkdir-permission-on-create.patch +Patch416: autofs-5.0.8-fix-macro_addvar-and-move-init-to-main-thread.patch +Patch417: autofs-5.0.8-change-walk_tree-to-take-ap.patch +Patch418: autofs-5.0.8-add-negative-cache-lookup-to-hesiod-lookup.patch +Patch419: autofs-5.0.8-fix-external-env-configure.patch +Patch420: autofs-5.0.8-make-autofs-5-consistent-with-auto-master-5.patch +Patch421: autofs-5.0.8-fix-map-source-with-type-lookup.patch +Patch422: autofs-5.0.8-fix-fix-map-source-with-type-lookup.patch +Patch423: autofs-5.0.8-fix-lookup_nss_mount-map-lookup.patch +Patch424: autofs-5.0.8-dont-ignore-null-cache-entries-on-multi-mount-umount.patch +Patch425: autofs-5.0.8-fix-inconsistent-error-returns-in-handle_packet_missing_direct.patch +Patch426: autofs-5.0.8-simple-coverity-fixes.patch +Patch427: autofs-5.0.8-remove-stale-debug-message.patch +Patch428: autofs-5.0.8-fixes-for-samples-auto_master.patch +Patch429: autofs-5.0.8-fix-variable-substitution-description.patch +Patch430: autofs-5.0.8-fix-append-options-description-in-README_v5-release.patch +Patch431: autofs-5.0.9-fix-mistake-in-assignment.patch +Patch432: autofs-5.0.8-use-open-instead-of-access.patch +Patch433: autofs-5.0.7-fix-crash-due-to-thread-unsafe-use-of-libldap.patch +Patch434: autofs-5.0.8-fix-deadlock-in-init-ldap-connection.patch +Patch435: autofs-5.0.8-extend-libldap-serialization.patch + +# amd parser series (set1) +Patch500: autofs-5.0.9-amd-lookup-move-get_proximity-to-parse_subs-c.patch +Patch501: autofs-5.0.9-amd-lookup-use-flags-in-map_source-for-format.patch +Patch502: autofs-5.0.9-amd-lookup-rework-config-handling.patch +Patch503: autofs-5.0.9-amd-lookup-add-conf-handling-for-amd-maps.patch +Patch504: autofs-5.0.9-amd-lookup-split-config-into-init-and-config-settings.patch +Patch505: autofs-5.0.9-amd-lookup-update-man-page-autofs-config-description.patch +Patch506: autofs-5.0.9-amd-lookup-add-amd-config-descriptions-to-config.patch +Patch507: autofs-5.0.9-amd-lookup-fix-lofs-mounting.patch +Patch508: autofs-5.0.9-amd-lookup-add-merge_options-function.patch +Patch509: autofs-5.0.9-amd-lookup-add-expandamdent-function.patch +Patch510: autofs-5.0.9-amd-lookup-add-external-mounts-tracking-functions.patch +Patch511: autofs-5.0.9-amd-lookup-add-amd-global-macro-vars.patch +Patch512: autofs-5.0.9-amd-lookup-add-selector-handling-functions.patch +Patch513: autofs-5.0.9-amd-lookup-add-parse_amd-c.patch +Patch514: autofs-5.0.9-amd-lookup-add-parent-prefix-handling.patch +Patch515: autofs-5.0.9-amd-lookup-add-lookup-vars.patch +Patch516: autofs-5.0.9-amd-lookup-add-selector-handling.patch +Patch517: autofs-5.0.9-amd-lookup-add-cut-handling.patch +Patch518: autofs-5.0.9-amd-lookup-add-handling-of-amd-maps-in-the-master-map.patch +Patch519: autofs-5.0.9-amd-lookup-add-cache-partial-match-functions.patch +Patch520: autofs-5.0.9-amd-lookup-fix-expire-of-amd-nfs-mounts.patch +Patch521: autofs-5.0.9-amd-lookup-add-lofs-ext-and-xfs-fs-types.patch +Patch522: autofs-5.0.9-amd-lookup-add-key-matching-helper-function.patch +Patch523: autofs-5.0.9-amd-lookup-update-lookup-file-to-handle-amd-keys.patch +Patch524: autofs-5.0.9-amd-lookup-update-lookup-yp-to-handle-amd-keys.patch +Patch525: autofs-5.0.9-amd-lookup-update-lookup-program-to-handle-amd-keys.patch +Patch526: autofs-5.0.9-amd-lookup-update-lookup-nisplus-to-handle-amd-keys.patch +Patch527: autofs-5.0.8-amd-lookup-update-lookup-ldap-to-handle-amd-keys.patch +Patch528: autofs-5.0.8-amd-lookup-update-lookup-hesiod-to-handle-amd-keys.patch +Patch529: autofs-5.0.9-amd-lookup-add-handling-of-unhandled-options.patch +Patch530: autofs-5.0.9-amd-lookup-use-config-map_type-if-type-is-not-given.patch +Patch531: autofs-5.0.9-amd-lookup-update-man-pages.patch +Patch532: autofs-5.0.9-amd-lookup-add-remopts-handling.patch +Patch533: autofs-5.0.9-amd-lookup-add-nfsl-and-linkx-fs-types.patch +Patch534: autofs-5.0.9-amd-lookup-add-search_path-handling.patch +Patch535: autofs-5.0.9-amd-lookup-fix-host-mount-lookup.patch +Patch536: autofs-5.0.9-amd-lookup-fix-host-mount-naming.patch +Patch537: autofs-5.0.9-amd-lookup-check-for-required-options-for-mounts.patch +Patch538: autofs-5.0.9-amd-lookup-add-cdfs-fs-type.patch +Patch539: autofs-5.0.9-amd-lookup-dont-umount-admin-mounted-external-mounts.patch +Patch540: autofs-5.0.9-amd-lookup-skip-sss-source-for-amd-lookups.patch +Patch541: autofs-5.0.9-amd-lookup-allow-exec-to-be-used-by-amd-maps-in-master-map.patch +Patch542: autofs-5.0.9-amd-lookup-fix-amd-entry-not-found-at-expire.patch +Patch543: autofs-5.0.9-amd-lookup-fix-prefix-not-set-on-mount-reconnect.patch +Patch544: autofs-5.0.9-amd-lookup-add-REDAME-amd-maps.patch +Patch545: autofs-5.0.9-amd-lookup-fix-autofs_use_lofs-value-in-config.patch +Patch546: autofs-5.0.9-amd-lookup-fix-expire-of-external-mounts.patch +Patch547: autofs-5.0.9-amd-lookup-try-to-use-external-mounts-for-real-mounts.patch +Patch548: autofs-5.0.9-amd-lookup-add-ufs-fs-type.patch +Patch549: autofs-5.0.9-amd-lookup-fix-old-conf-handling.patch +Patch550: autofs-5.0.9-amd-lookup-try-to-use-external-mounts-for-nfs-mounts.patch +Patch551: autofs-5.0.9-amd-lookup-update-changelog.patch + +# amd parser series (set2) +Patch552: autofs-5.1.0-beta1-fix-wildcard-key-lookup.patch +Patch553: autofs-5.1.0-beta1-fix-out-of-order-amd-timestamp-lookup.patch +Patch554: autofs-5.1.0-beta1-fix-ldap-default-schema-config.patch +Patch555: autofs-5.1.0-beta1-fix-ldap-default-master-map-name-config.patch +Patch556: autofs-5.1.0-beta1-fix-map-format-init-in-lookup_init.patch +Patch557: autofs-5.1.0-beta1-fix-incorrect-max-key-length-in-defaults-get_hash.patch +Patch558: autofs-5.1.0-beta1-fix-xfn-sets-incorrect-lexer-state.patch +Patch559: autofs-5.1.0-beta1-fix-old-style-key-lookup.patch +Patch560: autofs-5.1.0-beta1-fix-expire-when-server-not-responding.patch +Patch561: autofs-5.1.0-beta1-fix-ldap_uri-config-update.patch +Patch562: autofs-5.1.0-beta1-fix-typo-in-conf_load_autofs_defaults.patch +Patch563: autofs-5.1.0-beta1-fix-hash-on-config-option-add-and-delete.patch +Patch564: autofs-5.1.0-beta1-add-plus-to-path-match-pattern.patch +Patch565: autofs-5.1.0-beta1-fix-multi-entry-ldap-option-handling.patch +Patch566: autofs-5.1.0-beta1-cleanup-options-in-amd_parse-c.patch +Patch567: autofs-5.1.0-beta1-allow-empty-value-for-some-map-options.patch +Patch568: autofs-5.1.0-beta1-allow-empty-value-in-macro-selectors.patch + +Patch600: autofs-5.1.0-add-serialization-to-sasl-init.patch +Patch601: autofs-5.1.0-dont-allocate-dev_ctl_ops-too-early.patch +Patch602: autofs-5.1.0-fix-incorrect-round-robin-host-detection.patch +Patch603: autofs-5.0.9-fix-race-accessing-qdn-in-get_query_dn.patch + +# Coverity motivated fixes, mainly for the new amd parser code +Patch604: autofs-5.1.0-fix-leak-in-cache_push_mapent.patch +Patch605: autofs-5.1.0-fix-config-entry-read-buffer-not-checked.patch +Patch606: autofs-5.1.0-fix-FILE-pointer-check-in-defaults_read_config.patch +Patch607: autofs-5.1.0-fix-memory-leak-in-conf_amd_get_log_options.patch +Patch608: autofs-5.1.0-fix-signed-comparison-in-inet_fill_net.patch +Patch609: autofs-5.1.0-fix-buffer-size-checks-in-get_network_proximity.patch +Patch610: autofs-5.1.0-fix-leak-in-get_network_proximity.patch +Patch611: autofs-5.1.0-fix-buffer-size-checks-in-merge_options.patch +Patch612: autofs-5.1.0-check-amd-lex-buffer-len-before-copy.patch +Patch613: autofs-5.1.0-add-return-check-in-ldap-check_map_indirect.patch +Patch614: autofs-5.1.0-check-host-macro-is-set-before-use.patch +Patch615: autofs-5.1.0-check-options-length-before-use-in-parse_amd_c.patch +Patch616: autofs-5.1.0-fix-some-out-of-order-evaluations-in-parse_amd_c.patch +Patch617: autofs-5.1.0-fix-copy-and-paste-error-in-dup_defaults_entry.patch +Patch618: autofs-5.1.0-fix-leak-in-parse_mount.patch +Patch619: autofs-5.1.0-add-mutex-call-return-check-in-defaults_c.patch + +# more amd format map fixes +Patch620: autofs-5.1.0-force-disable-browse-mode-for-amd-format-maps.patch +Patch621: autofs-5.1.0-fix-hosts-map-options-check-in-lookup_amd_instance.patch + +Patch622: autofs-5.1.0-fix-mem-leak-in-create_client.patch +Patch623: autofs-5.1.0-fix-memory-leak-in-get_exports.patch + +Patch624: autofs-5.1.0-fix-memory-leak-in-get_defaults_entry.patch +Patch625: autofs-5.1.0-fix-out-of-order-clearing-of-options-buffer.patch +Patch626: autofs-5.1.0-fix-reset-amd-lexer-scan-buffer.patch +Patch627: autofs-5.1.0-ignore-multiple-commas-in-options-strings.patch + +Patch628: autofs-5.1.0-clarify-multiple-mounts-description.patch +Patch629: autofs-5.1.0-update-man-page-autofs-8-for-systemd.patch +Patch630: autofs-5.1.0-fix-fix-master-map-type-check.patch +Patch631: autofs-5.1.0-fix-typo-in-update_hosts_mounts.patch +Patch632: autofs-5.1.0-fix-hosts-map-update-on-reload.patch +Patch633: autofs-5.1.0-make-negative-cache-update-consistent-for-all-lookup-modules.patch +Patch634: autofs-5.1.0-ensure-negative-cache-isnt-updated-on-remount.patch +Patch635: autofs-5.1.0-dont-add-wildcard-to-negative-cache.patch +Patch636: autofs-5.1.0-add-a-prefix-to-program-map-stdvars.patch +Patch637: autofs-5.1.0-add-config-option-to-force-use-of-program-map-stdvars.patch +Patch638: autofs-5.1.0-fix-incorrect-check-in-parse_mount.patch +Patch639: autofs-5.1.0-handle-duplicates-in-multi-mounts.patch +Patch640: autofs-5.1.0-fix-macro-usage-in-lookup_program_c.patch +Patch641: autofs-5.1.0-remove-unused-offset-handling-code.patch +Patch642: autofs-5.1.0-fix-mount-as-you-go-offset-selection.patch + +Patch643: autofs-5.1.0-init-qdn-before-use.patch +Patch644: autofs-5.1.1-fix-left-mount-count-return.patch +Patch645: autofs-5.1.1-fix-return-handling-in-sss-lookup-module.patch +Patch646: autofs-5.1.1-move-query-dn-calculation-from-do_bind-to-do_connect.patch +Patch647: autofs-5.1.1-make-do_connect-return-a-status.patch +Patch648: autofs-5.1.1-make-connect_to_server-return-a-status.patch +Patch649: autofs-5.1.1-make-find_dc_server-return-a-status.patch +Patch650: autofs-5.1.1-make-find_server-return-a-status.patch +Patch651: autofs-5.1.1-fix-return-handling-of-do_reconnect-in-ldap-module.patch +Patch652: autofs-5.1.1-fix-direct-mount-stale-instance-flag-reset.patch +Patch653: autofs-5.1.1-fix-direct-map-expire-not-set-for-initial-empty-map.patch +Patch654: autofs-5.1.1-update-map_hash_table_size-description.patch +Patch655: autofs-5.1.1-fix-out-of-order-call-in-program-map-lookup.patch + +Patch700: autofs-5.1.0-make-service-want-network-online.patch +Patch701: autofs-5.1.1-add-remote-fs-target-systemd-dependency.patch +Patch702: autofs-5.0.9-revert-special-case-cifs-escapes.patch +Patch703: autofs-5.1.0-guard-against-incorrect-umount-return.patch +Patch704: autofs-5.1.1-fix-nameing-typo-in-autofs-conf.patch + +Patch705: autofs-5.1.1-always-set-direct-mounts-catatonic-at-exit.patch +Patch706: autofs-5.1.1-log-pipe-read-errors.patch +Patch707: autofs-5.1.1-fix-rwlock-unlock-crash.patch +Patch708: autofs-5.1.1-fix-handle_mounts-termination-condition-check.patch + +# Series 1 - additional bug fixes (bug 1300500) +Patch709: autofs-5.1.1-fix-config-old-name-lookup.patch +Patch710: autofs-5.1.1-fix-error-handling-on-ldap-bind-fail.patch +Patch711: autofs-5.1.0-fix-gcc5-complaints.patch +Patch712: autofs-5.1.1-fix-fix-gcc5-complaints.patch + +# Series2 - add reinit method and change lookup to use reinit +# instead of reopen (bug 1300500) +Patch713: autofs-5.1.1-fix-missing-source-sss-in-multi-map-lookup.patch +Patch714: autofs-5.1.1-fix-update_hosts_mounts-return.patch +Patch715: autofs-5.1.1-move-check_nss_result-to-nsswitch_c.patch +Patch716: autofs-5.1.1-make-open_lookup-return-nss-status.patch +Patch717: autofs-5.1.1-fix-nsswitch-handling-when-opening-multi-map.patch +Patch718: autofs-5.1.1-add-reinit-entry-point-to-modules.patch +Patch719: autofs-5.1.1-implement-reinit-in-parse-modules.patch +Patch720: autofs-5.1.1-implement-reinit-in-file-lookup-module.patch +Patch721: autofs-5.1.1-implement-reinit-in-hesiod-lookup-module.patch +Patch722: autofs-5.1.1-implement-reinit-in-hosts-lookup-module.patch +Patch723: autofs-5.1.1-implement-reinit-in-ldap-lookup-module.patch +Patch724: autofs-5.1.1-implement-reinit-in-nisplus-lookup-module.patch +Patch725: autofs-5.1.1-implement-reinit-in-program-lookup-module.patch +Patch726: autofs-5.1.1-implement-reinit-in-sss-lookup-module.patch +Patch727: autofs-5.1.1-implement-reinit-in-yp-lookup-module.patch +Patch728: autofs-5.1.1-add-type-to-struct-lookup_mod.patch +Patch729: autofs-5.1.1-factor-out-free-multi-map-context.patch +Patch730: autofs-5.1.1-factor-out-alloc-multi-map-context.patch +Patch731: autofs-5.1.1-fix-map-format-check-in-nss_open_lookup-multi-map-module.patch +Patch732: autofs-5.1.1-implement-reinit-in-multi-lookup-module.patch +Patch733: autofs-5.1.1-change-lookup-to-use-reinit-instead-of-reopen.patch + +# Aditional bug fixes (bug 1300500) +Patch734: autofs-5.1.1-fix-unbind-external-mech.patch +Patch735: autofs-5.1.1-fix-sasl-connection-concurrancy-problem.patch + +# Some Coverity fixes identified for recent changes (bug 1300500) +Patch736: autofs-5.1.1-fix-memory-leak-in-nisplus-lookup_reinit.patch +Patch737: autofs-5.1.1-fix-memory-leak-in-ldap-do_init.patch +Patch738: autofs-5.1.1-fix-use-after-free-in-sun-parser-parse_init.patch +Patch739: autofs-5.1.1-fix-use-after-free-in-open_lookup.patch +Patch740: autofs-5.1.1-fix-typo-in-autofs_sasl_bind.patch + +Patch741: autofs-5.1.1-add-configuration-option-to-use-hostname-in-mounts.patch +Patch742: autofs-5.1.1-fix-use-after-free-st_queue_handler.patch +Patch743: autofs-5.1.1-add-config-option-to-suppress-not-found-log-message.patch + +Patch744: autofs-5.1.2-wait-for-master-map-available-at-start.patch +Patch745: autofs-5.1.2-add-master-read-wait-option.patch +Patch746: autofs-5.1.2-fix-included-master-map-not-found-return.patch +Patch747: autofs-5.1.2-dont-fail-on-master-map-read-fail-timeout.patch +Patch748: autofs-5.1.2-set-sane-default-master-read-wait-timeout.patch +Patch749: autofs-5.1.2-dont-return-until-after-master-map-retry-read.patch +Patch750: autofs-5.1.2-make-lookup_nss_read_master-return-nss-status.patch + +Patch751: autofs-5.1.2-make-set_direct_mount_catatonic-more-general.patch +Patch752: autofs-5.1.2-set-autofs-mounts-catatonic-at-exit.patch +Patch753: autofs-5.1.2-check-NFS-server-availability-on-local-mount-fallback.patch +Patch754: autofs-5.1.2-honor-last-rw-in-mount-options-when-doing-a-bind-mount.patch +Patch755: autofs-5.1.2-update-and-add-README-for-old-autofs-schema.patch + +# Bug 1367576 - amd mounts browse mode +Patch760: autofs-5.1.2-fix-short-memory-allocation-in-lookup_amd_instance.patch +Patch761: autofs-5.1.2-fix-count_mounts-function.patch +Patch762: autofs-5.1.2-fix-argc-off-by-one-in-mount_autofs_c.patch +Patch763: autofs-5.1.2-fix-_strncmp-usage.patch +Patch764: autofs-5.1.2-fix-typos-in-README.amd-maps.patch +Patch765: autofs-5.1.2-add-ref-counting-to-struct-map_source.patch +Patch766: autofs-5.1.2-add-support-for-amd-browsable-option.patch +Patch767: autofs-5.1.2-add-function-conf_amd_get_map_name.patch +Patch768: autofs-5.1.2-add-function-conf_amd_get_mount_paths.patch +Patch769: autofs-5.1.2-include-amd-mount-section-mounts-in-master-mounts-list.patch +Patch770: autofs-5.1.2-check-for-conflicting-amd-section-mounts.patch +Patch771: autofs-5.1.2-add-function-conf_amd_get_map_options.patch +Patch772: autofs-5.1.2-capture-cache-option-and-its-settings-during-parsing.patch +Patch773: autofs-5.1.2-handle-map_option-cache-for-top-level-mounts.patch +Patch774: autofs-5.1.2-handle-amd-cache-option-all-in-amd-type-auto-mounts.patch +Patch775: autofs-5.1.2-fix-bogus-check-in-expire_cleanup.patch +Patch776: autofs-5.1.2-delay-submount-exit-for-amd-submounts.patch + +Patch777: autofs-5.1.2-add-the-mount-requestor-s-pid-to-pending_args.patch +Patch778: autofs-5.1.2-create-thread-local-ID-for-mount-attempts.patch +Patch779: autofs-5.1.2-log-functions-to-prefix-messages-with-attempt_id-if-available.patch +Patch780: autofs-5.1.2-factor-out-set-thread-mount-request-log-id.patch +Patch781: autofs-5.1.2-add-config-option-to-use-mount-request-log-id.patch + +Patch782: autofs-5.1.2-work-around-sss-startup-delay.patch +Patch783: autofs-5.1.2-add-sss-master-map-wait-config-option.patch + +Patch784: autofs-5.1.2-use-autofs_point-to-store-expire-timeout-where-possibe.patch +Patch785: autofs-5.1.2-fix-possible-NULL-derefernce.patch +Patch786: autofs-5.1.2-fix-work-around-sss-startup-delay.patch + +Patch787: autofs-5.1.1-improve-scalability-of-direct-mount-path-component-creation.patch +Patch788: autofs-5.1.2-fix-invalid-reference-in-remount_active_mount.patch +Patch789: autofs-5.1.2-increase-worker-thread-per-thread-stack-size.patch +Patch790: autofs-5.1.2-limit-getgrgid_r-buffer-size.patch +Patch791: autofs-5.1.2-add-congigure-option-for-limiting-getgrgid_r-stack-usage.patch +Patch792: autofs-5.1.3-fix-unset-tsd-group-name-handling.patch + +Patch793: autofs-5.1.3-revert-fix-argc-off-by-one-in-mount_autofs_c.patch +Patch794: autofs-5.1.3-allow-dot-in-OPTIONSTR-value-lexer-pattern.patch +Patch795: autofs-5.1.3-handle-additional-nfs-versions-in-mount_nfs_c.patch + +Patch800: autofs-5.1.3-reset-master-map-list-on-startup-retry.patch + +Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +%if %{with_systemd} +BuildRequires: systemd-units +%endif +BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs libtirpc-devel +BuildRequires: libsss_autofs +Conflicts: cyrus-sasl-lib < 2.1.23-9 +Requires: bash coreutils sed gawk textutils sh-utils grep module-init-tools /bin/ps +%if %{with_systemd} +Requires(post): systemd-sysv +Requires(post): systemd-units +Requires(preun): systemd-units +Requires(postun): systemd-units +%else +Requires(post): /sbin/chkconfig +Requires(preun): /sbin/service +Requires(postun): /sbin/service +Requires(postun): /sbin/chkconfig +%endif +Summary(de): autofs daemon +Summary(fr): démon autofs +Summary(tr): autofs sunucu süreci +Summary(sv): autofs-daemon + +%description +autofs is a daemon which automatically mounts filesystems when you use +them, and unmounts them later when you are not using them. This can +include network filesystems, CD-ROMs, floppies, and so forth. + +%description -l de +autofs ist ein Dämon, der Dateisysteme automatisch montiert, wenn sie +benutzt werden, und sie später bei Nichtbenutzung wieder demontiert. +Dies kann Netz-Dateisysteme, CD-ROMs, Disketten und ähnliches einschließen. + +%description -l fr +autofs est un démon qui monte automatiquement les systèmes de fichiers +lorsqu'on les utilise et les démonte lorsqu'on ne les utilise plus. Cela +inclus les systèmes de fichiers réseau, les CD-ROMs, les disquettes, etc. + +%description -l tr +autofs, kullanýlan dosya sistemlerini gerek olunca kendiliðinden baðlar +ve kullanýmlarý sona erince yine kendiliðinden çözer. Bu iþlem, að dosya +sistemleri, CD-ROM'lar ve disketler üzerinde yapýlabilir. + +%description -l sv +autofs är en daemon som mountar filsystem när de använda, och senare +unmountar dem när de har varit oanvända en bestämd tid. Detta kan +inkludera nätfilsystem, CD-ROM, floppydiskar, och så vidare. + +%prep +%setup -q +echo %{version}-%{release} > .version +%if %{with_systemd} + %define unitdir %{?_unitdir:/usr/lib/systemd/system} + %define systemd_configure_arg --with-systemd +%endif +%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 +%patch54 -p1 +%patch55 -p1 +%patch56 -p1 +%patch57 -p1 +%patch58 -p1 +%patch59 -p1 +%patch60 -p1 +%patch61 -p1 +%patch62 -p1 +%patch63 -p1 +%patch64 -p1 +%patch65 -p1 +%patch66 -p1 +%patch67 -p1 +%patch68 -p1 +%patch69 -p1 +%patch70 -p1 +%patch71 -p1 +%patch72 -p1 +%patch73 -p1 +%patch74 -p1 +%patch75 -p1 +%patch76 -p1 +%patch77 -p1 +%patch78 -p1 +%patch79 -p1 +%patch80 -p1 +%patch81 -p1 +%patch82 -p1 +%patch83 -p1 +%patch84 -p1 +%patch85 -p1 +%patch86 -p1 +%patch87 -p1 +%patch88 -p1 +%patch89 -p1 +%patch90 -p1 +%patch91 -p1 +%patch92 -p1 +%patch93 -p1 +%patch94 -p1 +%patch95 -p1 +%patch96 -p1 +%patch97 -p1 +%patch98 -p1 +%patch99 -p1 +%patch100 -p1 +%patch101 -p1 +%patch102 -p1 +%patch103 -p1 +%patch104 -p1 +%patch105 -p1 +%patch106 -p1 +%patch107 -p1 + +# pre-patches for amd parser series. +%patch400 -p1 +%patch401 -p1 +%patch402 -p1 +%patch403 -p1 +%patch404 -p1 +%patch405 -p1 +%patch406 -p1 +%patch407 -p1 +%patch408 -p1 +%patch409 -p1 +%patch410 -p1 +%patch411 -p1 +%patch412 -p1 +%patch413 -p1 +%patch414 -p1 +%patch415 -p1 +%patch416 -p1 +%patch417 -p1 +%patch418 -p1 +%patch419 -p1 +%patch420 -p1 +%patch421 -p1 +%patch422 -p1 +%patch423 -p1 +%patch424 -p1 +%patch425 -p1 +%patch426 -p1 +%patch427 -p1 +%patch428 -p1 +%patch429 -p1 +%patch430 -p1 +%patch431 -p1 +%patch432 -p1 +%patch433 -p1 +%patch434 -p1 +%patch435 -p1 + +# amd parser series (set1) +%patch500 -p1 +%patch501 -p1 +%patch502 -p1 +%patch503 -p1 +%patch504 -p1 +%patch505 -p1 +%patch506 -p1 +%patch507 -p1 +%patch508 -p1 +%patch509 -p1 +%patch510 -p1 +%patch511 -p1 +%patch512 -p1 +%patch513 -p1 +%patch514 -p1 +%patch515 -p1 +%patch516 -p1 +%patch517 -p1 +%patch518 -p1 +%patch519 -p1 +%patch520 -p1 +%patch521 -p1 +%patch522 -p1 +%patch523 -p1 +%patch524 -p1 +%patch525 -p1 +%patch526 -p1 +%patch527 -p1 +%patch528 -p1 +%patch529 -p1 +%patch530 -p1 +%patch531 -p1 +%patch532 -p1 +%patch533 -p1 +%patch534 -p1 +%patch535 -p1 +%patch536 -p1 +%patch537 -p1 +%patch538 -p1 +%patch539 -p1 +%patch540 -p1 +%patch541 -p1 +%patch542 -p1 +%patch543 -p1 +%patch544 -p1 +%patch545 -p1 +%patch546 -p1 +%patch547 -p1 +%patch548 -p1 +%patch549 -p1 +%patch550 -p1 +%patch551 -p1 + +# amd parser series (set2) +%patch552 -p1 +%patch553 -p1 +%patch554 -p1 +%patch555 -p1 +%patch556 -p1 +%patch557 -p1 +%patch558 -p1 +%patch559 -p1 +%patch560 -p1 +%patch561 -p1 +%patch562 -p1 +%patch563 -p1 +%patch564 -p1 +%patch565 -p1 +%patch566 -p1 +%patch567 -p1 +%patch568 -p1 + +%patch600 -p1 +%patch601 -p1 +%patch602 -p1 +%patch603 -p1 +%patch604 -p1 +%patch605 -p1 +%patch606 -p1 +%patch607 -p1 +%patch608 -p1 +%patch609 -p1 +%patch610 -p1 +%patch611 -p1 +%patch612 -p1 +%patch613 -p1 +%patch614 -p1 +%patch615 -p1 +%patch616 -p1 +%patch617 -p1 +%patch618 -p1 +%patch619 -p1 +%patch620 -p1 +%patch621 -p1 +%patch622 -p1 +%patch623 -p1 +%patch624 -p1 +%patch625 -p1 +%patch626 -p1 +%patch627 -p1 + +%patch628 -p1 +%patch629 -p1 +%patch630 -p1 +%patch631 -p1 +%patch632 -p1 +%patch633 -p1 +%patch634 -p1 +%patch635 -p1 +%patch636 -p1 +%patch637 -p1 +%patch638 -p1 +%patch639 -p1 +%patch640 -p1 +%patch641 -p1 +%patch642 -p1 + +%patch643 -p1 +%patch644 -p1 +%patch645 -p1 +%patch646 -p1 +%patch647 -p1 +%patch648 -p1 +%patch649 -p1 +%patch650 -p1 +%patch651 -p1 +%patch652 -p1 +%patch653 -p1 +%patch654 -p1 +%patch655 -p1 + +%patch700 -p1 +%patch701 -p1 +%patch702 -p1 +%patch703 -p1 +%patch704 -p1 + +%patch705 -p1 +%patch706 -p1 +%patch707 -p1 +%patch708 -p1 + +# Series 1 - additional bug fixes (bug 1300500) +%patch709 -p1 +%patch710 -p1 +%patch711 -p1 +%patch712 -p1 + +# Series2 - add reinit method and change lookup to use reinit +# instead of reopen (bug 1300500) +%patch713 -p1 +%patch714 -p1 +%patch715 -p1 +%patch716 -p1 +%patch717 -p1 +%patch718 -p1 +%patch719 -p1 +%patch720 -p1 +%patch721 -p1 +%patch722 -p1 +%patch723 -p1 +%patch724 -p1 +%patch725 -p1 +%patch726 -p1 +%patch727 -p1 +%patch728 -p1 +%patch729 -p1 +%patch730 -p1 +%patch731 -p1 +%patch732 -p1 +%patch733 -p1 + +# Aditional bug fixes (bug 1300500) +%patch734 -p1 +%patch735 -p1 + +# Some Coverity fixes identified for recent changes (bug 1300500) +%patch736 -p1 +%patch737 -p1 +%patch738 -p1 +%patch739 -p1 +%patch740 -p1 + +%patch741 -p1 +%patch742 -p1 +%patch743 -p1 + +%patch744 -p1 +%patch745 -p1 +%patch746 -p1 +%patch747 -p1 +%patch748 -p1 +%patch749 -p1 +%patch750 -p1 + +%patch751 -p1 +%patch752 -p1 +%patch753 -p1 +%patch754 -p1 +%patch755 -p1 + +# Bug 1367576 +%patch760 -p1 +%patch761 -p1 +%patch762 -p1 +%patch763 -p1 +%patch764 -p1 +%patch765 -p1 +%patch766 -p1 +%patch767 -p1 +%patch768 -p1 +%patch769 -p1 +%patch770 -p1 +%patch771 -p1 +%patch772 -p1 +%patch773 -p1 +%patch774 -p1 +%patch775 -p1 +%patch776 -p1 + +%patch777 -p1 +%patch778 -p1 +%patch779 -p1 +%patch780 -p1 +%patch781 -p1 + +%patch782 -p1 +%patch783 -p1 + +%patch784 -p1 +%patch785 -p1 +%patch786 -p1 + +%patch787 -p1 +%patch788 -p1 +%patch789 -p1 +%patch790 -p1 +%patch791 -p1 +%patch792 -p1 + +%patch793 -p1 +%patch794 -p1 +%patch795 -p1 + +%patch800 -p1 + +%build +LDFLAGS=-Wl,-z,now +%configure --disable-mount-locking \ + --enable-ignore-busy \ + --with-libtirpc \ + --enable-limit-getgrgid-size \ + %{?systemd_configure_arg:} +make initdir=%{_initrddir} DONTSTRIP=1 + +%install +rm -rf $RPM_BUILD_ROOT +%if %{with_systemd} +install -d -m 755 $RPM_BUILD_ROOT%{unitdir} +%else +mkdir -p -m755 $RPM_BUILD_ROOT%{_initrddir} +%endif +mkdir -p -m755 $RPM_BUILD_ROOT%{_sbindir} +mkdir -p -m755 $RPM_BUILD_ROOT%{_libdir}/autofs +mkdir -p -m755 $RPM_BUILD_ROOT%{_mandir}/{man5,man8} +mkdir -p -m755 $RPM_BUILD_ROOT/etc/sysconfig +mkdir -p -m755 $RPM_BUILD_ROOT/etc/auto.master.d + +make install mandir=%{_mandir} initdir=%{_initrddir} systemddir=%{unitdir} INSTALLROOT=$RPM_BUILD_ROOT +echo make -C redhat +make -C redhat +install -m 755 -d $RPM_BUILD_ROOT/misc +%if %{with_systemd} +# Configure can get this wrong when the unit files appear under /lib and /usr/lib +find $RPM_BUILD_ROOT -type f -name autofs.service -exec rm -f {} \; +install -m 644 redhat/autofs.service $RPM_BUILD_ROOT%{unitdir}/autofs.service +%define init_file_name %{unitdir}/autofs.service +%else +install -m 755 redhat/autofs.init $RPM_BUILD_ROOT%{_initrddir}/autofs +%define init_file_name /etc/rc.d/init.d/autofs +%endif +install -m 644 redhat/autofs.conf $RPM_BUILD_ROOT/etc/autofs.conf +install -m 644 redhat/autofs.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/autofs + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +%if %{with_systemd} +%systemd_post %{name}.service +%else +if [ $1 -eq 1 ]; then + %{_sbindir}/sbin/chkconfig --add autofs +fi +%endif + +%preun +%if %{with_systemd} +%systemd_preun %{name}.service +%else +if [ $1 -eq 0 ] ; then + %{_sbindir}/service autofs stop > /dev/null 2>&1 || : + %{_sbindir}/chkconfig --del autofs +fi +%endif + +%postun +%if %{with_systemd} +%systemd_postun_with_restart %{name}.service +%else +if [ $1 -ge 1 ] ; then + %{_sbindir}/sbin/service autofs condrestart > /dev/null 2>&1 || : +fi +%endif + +%triggerun -- %{name} < 5.0.6-5 +# Save the current service runlevel info +# User must manually run systemd-sysv-convert --apply %{name} +# to migrate them to systemd targets +%{_bindir}/systemd-sysv-convert --save %{name} >/dev/null 2>&1 ||: + +# Run these because the SysV package being removed won't do them +%{_sbindir}/chkconfig --del %{name} >/dev/null 2>&1 || : +%{_bindir}/systemctl try-restart %{name}.service >/dev/null 2>&1 || : + +%files +%defattr(-,root,root,-) +%doc CREDITS INSTALL COPY* README* patches/* samples/ldap* samples/autofs.schema samples/autofs.schema.new +%config %{init_file_name} +%config(noreplace,missingok) /etc/auto.master +%config(noreplace,missingok) /etc/auto.misc +%config(noreplace,missingok) /etc/auto.net +%config(noreplace,missingok) /etc/auto.smb +%config(noreplace) /etc/autofs.conf +%config(noreplace) /etc/sysconfig/autofs +%config(noreplace) /etc/autofs_ldap_auth.conf +%{_sbindir}/automount +%{_mandir}/*/* +%{_libdir}/autofs/ +%dir /etc/auto.master.d + +%changelog +* Thu Oct 19 2017 Ian Kent - 5.0.7-70.el7_4.1 +- bz1515311 - Automount cannot access host shares after a reboot [rhel-7.4.z] + - reset master map list on startup retry. +- Resolves: rhbz#1515311 + +* Thu Oct 19 2017 Ian Kent - 5.0.7-70.el7_4 +- bz1503945 - autofs option parsing for maps with fstype=autofs no longer + works [rhel-7.4.z] + - revert fix argc off by one in mount_autofs.c. +- bz1503946 - autofs map entry options field does not accept dot character + [rhel-7.4.z] + - allow dot in OPTIONSTR value lexer pattern. + - handle additional nfs versions in mount_nfs.c. +- Resolves: rhbz#1503945 rhbz#1503946 + +* Fri Jun 2 2017 Ian Kent - 5.0.7-69 +- bz1435736 - autofs fails with kernel: automount[3386]: + segfault at 7f3fb7595ca8 ip 00007f3fb61e353a sp 00007f3fb7595cb0 + error 6 in libc-2.17.so[7f3fb60b7000+1b6000] + - fix a couple of covarity warning resulting in group name handling change. +- Related: rhbz#1435736 + +* Fri Jun 2 2017 Ian Kent - 5.0.7-68 +- bz1435736 - autofs fails with kernel: automount[3386]: + segfault at 7f3fb7595ca8 ip 00007f3fb61e353a sp 00007f3fb7595cb0 + error 6 in libc-2.17.so[7f3fb60b7000+1b6000] + - fix unset tsd group name handling. +- Related: rhbz#1435736 + +* Fri May 05 2017 Ian Kent - 5.0.7-66 +- bz1435736 - autofs fails with kernel: automount[3386]: + segfault at 7f3fb7595ca8 ip 00007f3fb61e353a sp 00007f3fb7595cb0 + error 6 in libc-2.17.so[7f3fb60b7000+1b6000] + - increase worker thread per-thread stack size. + - limit getgrgid_r() buffer size. + - add congigure option for limiting getgrgid_r() stack usage. + - use above option to limit getgrgid_r() stack usage with configure. +- Resolves: rhbz#1435736 + +* Mon Apr 24 2017 Ian Kent - 5.0.7-65 +- bz1367576 - [RFE] Add browsing support into autofs for AMD format maps + - fix invalid reference in remount_active_mount(). +- Related: rhbz#1367576 + +* Mon Apr 17 2017 Ian Kent - 5.0.7-64 +- bz1440769 - autofs is facing scalability issues + - improve scalability of direct mount path component creation. +- Resolves: rhbz#1440769 + +* Thu Mar 30 2017 Ian Kent - 5.0.7-63 +- bz1101782 - autofs configured with sssd is not finding any maps + - fix work around sss startup delay. +- bz1367576 - [RFE] Add browsing support into autofs for AMD format maps + - fix possible NULL derefernce. +- Related: rhbz#1101782 rhbz#1367576 + +* Mon Mar 27 2017 Ian Kent - 5.0.7-62 +- bz1367576 - [RFE] Add browsing support into autofs for AMD format maps + - use autofs_point to store expire timeout where possibe. +- Related: rhbz#1367576 + +* Mon Mar 20 2017 Ian Kent - 5.0.7-61 +- bz1101782 - autofs configured with sssd is not finding any maps + - work around sss startup delay. + - add sss master map wait config option (wait initially 0, disabled). +- Resolves: rhbz#1101782 + +* Mon Mar 20 2017 Ian Kent - 5.0.7-60 + - bz1382093 - Improve logging in autofs + - add the mount requestor's pid to pending_args. + - create thread-local ID for mount attempts. + - log functions to prefix messages with attempt_id if available. + - factor out set_thread_mount_request_log_id(). + - add config option to use mount request log id. +- Resolves: rhbz#1382093 + +* Wed Mar 15 2017 Ian Kent - 5.0.7-59 +- bz1383910 - Incorrect autofs.schema + - update and add README for old autofs schema +- bz1367576 - [RFE] Add browsing support into autofs for AMD format maps + - fix short memory allocation in lookup_amd_instance(). + - fix count_mounts() function. + - fix argc off by one in mount_autofs.c. + - fix _strncmp() usage. + - fix typos in README.amd-maps. + - add ref counting to struct map_source. + - add support for amd browsable option. + - add function conf_amd_get_map_name(). + - add function conf_amd_get_mount_paths(). + - include amd mount section mounts in master mounts list. + - check for conflicting amd section mounts. + - add function conf_amd_get_map_options(). + - capture cache option and its settings during parsing. + - handle map_option cache for top level mounts. + - handle amd cache option all in amd type auto mounts. + - fix bogus check in expire_cleanup(). + - delay submount exit for amd submounts. +- Resolves: rhbz#1383910 rhbz#1367576 + +* Wed Mar 01 2017 Ian Kent - 5.0.7-58 +- bz1420584 - RHEL7.3: shutdown / reboot hangs with findmnt in a readlink + system call, doing path_walk and stuck in autofs4_wait + - make set_direct_mount_catatonic() more general. + - set autofs mounts catatonic at exit. +- bz1396403 - Trying to access a non-existent directory using automount + results in 4 minute hang as not checking the local mount availability + - check NFS server availability on local mount fallback. +- bz1399796 - local nfs share being bind-mounted by autofs is mounted + read-only even when marked rw in its map + - honor last rw in mount options when doing a bind mount. +- Resolves: rhbz#1420584 rhbz#1396403 rhbz#1399796 + +* Sat Feb 04 2017 Ian Kent - 5.0.7-57 +- bz1383194 - On every system boot automount needs a restart to access + NIS map + - wait for master map available at start. + - add master read wait option. + - fix included master map not found return. + - dont exit on master map read fail timeout. + - set sane default master read wait timeout. + - don't return until after master map retry read. + - make lookup_nss_read_master() return nss status. +- Resolves: rhbz#1383194 + +* Wed May 25 2016 Ian Kent - 1:5.0.7-56 +- bz1327388 - Fix use-after-free in st_queue_handler + - fix use-after-free in st_queue_handler(). +- bz1252071 - [RFE] Disable alerting on non-existent automounts + - add config option to suppress not found log message. +- Resolves: rhbz#1327388 rhbz#1252071 + +* Tue May 17 2016 Ian Kent - 1:5.0.7-55 +- bz1298115 - The autofs service fails to load maps on boot if the maps + are stored on a NFS mount + - make service want network-online. + - add remote-fs.target systemd dependency. +- bz1300496 - Duplicate mounts created or leftovers in mtab + - revert special case cifs escapes. +- bz1300498 - Parent directory in nested mount gets unmounted while the + child remains mounted + - guard against incorrect umount return. +- bz1305721 - autofs.conf: Fix 'nameing' typo + - fix 'nameing' typo in autofs.conf. +- bz1329869 - RHEL6.7: shutdown / reboot hangs with findmnt in a readlink + system call, doing path_walk and stuck in autofs4_wait + - always set direct mounts catatonic at exit. + - log pipe read errors. + - fix rwlock unlock crash. + - fix handle_mounts() termination condition check. +- bz1300500 - double free or corruption (fasttop) causes abort in + ldap_int_tls_destroy + - fix config old name lookup. + - fix error handling on ldap bind fail. + - fix gcc5 complaints. + - fix fix gcc5 complaints. + - fix missing source sss in multi map lookup. + - fix update_hosts_mounts() return. + - change lookup to use reinit instead of reopen. + - fix unbind sasl external mech. + - fix sasl connection concurrancy problem. + - add some Coverity fixes identified for recent changes. +- bz1300501 - Request to add a configuration option to force use of the map + entry hostname for mounts + - add configuration option to use fqdn in mounts +- Resolves: rhbz#1298115 rhbz#1300496 rhbz#1300498 rhbz#1305721 +- Resolves: rhbz#1329869 rhbz#1300500 rhbz#1300501 + +* Thu Sep 17 2015 Ian Kent - 1:5.0.7-54 +- bz1263508 - Heavy program map usage can lead to a hang + - fix out of order call in program map lookup. +- Resolves: rhbz#1263508 + +* Tue Jul 7 2015 Ian Kent - 1:5.0.7-53 +- bz1238573 - RFE: autofs MAP_HASH_TABLE_SIZE description + - update map_hash_table_size description. +- Resolves: rhbz#1238573 + +* Thu Jul 2 2015 Ian Kent - 1:5.0.7-52 +- bz1233069 - Direct map does not expire if map is initially empty + - update patch to fix expiry problem. +- Related: rhbz#1233069 + +* Tue Jun 23 2015 Ian Kent - 1:5.0.7-51 +- bz1233065 - 'service autofs reload' does not reloads new mounts only + when 'sss' or 'ldap' is used in '/etc/nsswitch.conf' file + - init qdn before use in get_query_dn(). + - 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. + - 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. +- bz1233067 - autofs is performing excessive direct mount map re-reads + - fix direct mount stale instance flag reset. +- bz1233069 - Direct map does not expire if map is initially empty + - fix direct map expire not set for initial empty map. +- Resolves: rhbz#1233065 rhbz#1233067 rhbz#1233069 + +* Tue May 26 2015 Ian Kent - 1:5.0.7-50 +- bz1218045 - Similar but unrelated NFS exports block proper mounting of + "parent" mount point + - remove unused offset handling code. + - fix mount as you go offset selection. +- Resolves: rhbz#1218045 + +* Mon May 25 2015 Ian Kent - 1:5.0.7-49 +- bz1166457 - Autofs unable to mount indirect after attempt to mount wildcard + - make negative cache update consistent for all lookup modules. + - ensure negative cache isn't updated on remount. + - dont add wildcard to negative cache. +- bz1162041 - priv escalation via interpreter load path for program based + automount maps + - add a prefix to program map stdvars. + - add config option to force use of program map stdvars. +- bz1161474 - automount segment fault in parse_sun.so for negative parser tests + - fix incorrect check in parse_mount(). +- bz1205600 - Autofs stopped mounting /net/hostname/mounts after seeing duplicate + exports in the NFS server + - handle duplicates in multi mounts. +- bz1201582 - autofs: MAPFMT_DEFAULT is not macro in lookup_program.c + - fix macro usage in lookup_program.c. +- Resolves: rhbz#1166457 rhbz#1162041 rhbz#1161474 rhbz#1205600 rhbz#1201582 + +* Fri Dec 19 2014 Ian Kent - 1:5.0.7-48 +- bz1164957 - The default installed autofs.conf doesn't have default nfs + protocol set to 4 + - add missing line to copy RedHat customized config to spec file. +- Resolves: rhbz#1164957 + +* Tue Oct 28 2014 Ian Kent - 1:5.0.7-47 +- bz1156662 - autofs /net maps do not refresh list of shares exported on + the NFS server + - fix typo in update_hosts_mounts(). + - fix hosts map update on reload. +- Resolves: rhbz#1156662 + +* Fri Oct 17 2014 Ian Kent - 1:5.0.7-46 +- bz1153414 - autofs-5.0.5-109 with upgrade to RHEL 6.6 no longer recognizes + +yp: in auto.master + - fix fix master map type check. +- Resolves: rhbz#1153414 + +* Wed Oct 15 2014 Ian Kent - 1:5.0.7-45 +- bz1152862 - autofs shouldn't have kernel as a dependency + - remove an ancient kernel Requires. +- Resolves: rhbz#1152862 + +* Tue Oct 7 2014 Ian Kent - 1:5.0.7-44 +- bz1099800 - man page of /etc/init.d/autofs: /usr/share/man/man8/autofs.8.gz + is not needed in RHEL-7 + - update man page autofs(8) for systemd +- Resolves: rhbz#1099800 + +* Thu Sep 25 2014 Ian Kent - 1:5.0.7-43 +- bz1066772 - Clarify autofs(5) man page sections "Multiple Mounts" and + "Replicated Server" + - clarify multiple mounts description. +- Resolves: rhbz#1066772 + +* Mon Sep 22 2014 Ian Kent - 1:5.0.7-42 +- bz1116184 - RFE: RHEL7: Add am-utils RPM or equivalent am-utils functionality + to other packages + - add amd map format parser. +- bz1132236 - Memory leak in get_exports + - fix memory leak in create_client(). + - fix memory leak in get_exports(). +- bz1135158 - double free or corruption (fasttop) causes abort in ldap_int_tls_destroy + - fix deadlock in init_ldap_connection(). + - extend libldap serialization. +- Resolves: rhbz#1116184 rhbz#1132236 rhbz#1135158 + +* Mon Aug 25 2014 Ian Kent - 1:5.0.7-41 +- bz1094661 - autofs can ghost non-existent map entries given the right timing + - fix negative status being reset on map read. + - fix fix negative status being reset on map read. + - check for non existent negative entries in lookup_ghost(). +- bz1124389 - autofs-5.0.5-88.el6 breaks maps that have a -v in the options + - allow use of hosts map in maps (dependent patch). + - fix options compare. + - fix fix options compare. +- Resolves: rhbz#1094661 rhbz#1124389 + +* Wed Feb 19 2014 Ian Kent - 1:5.0.7-40 +- bz1063139 - autofs regression test failure. + - fix fix ipv6 libtirpc getport. + - get_nfs_info() should query portmapper if port is not given. + - fix rpc_portmap_getport() proto not set. + - fix portmap not trying proto v2. +- Resolves: rhbz#1063139 + +* Fri Jan 24 2014 Daniel Mach - 1:5.0.7-39 +- Mass rebuild 2014-01-24 + +* Fri Dec 27 2013 Daniel Mach - 1:5.0.7-38 +- Mass rebuild 2013-12-27 + +* Sat Nov 30 2013 Ian Kent - 1:5.0.7-37 +- bz1035977 - with IPv6 address automount fail with "hostname lookup failed" + - fix ipv6 link local address handling. +- Resolves: rhbz#1035977 + +* Tue Nov 19 2013 Ian Kent - 1:5.0.7-35 +- bz1030705 - Default unmount is in 10 seconds, man page says 10 minutes + - improve timeout option description. +- Related: rhbz#1030705 + +* Tue Nov 19 2013 Ian Kent - 1:5.0.7-35 +- bz1029611 - Fresh rhel7 install can't automount nfs exports + - fix ipv6 libtirpc getport function. +- Related: rhbz#1029611 + +* Thu Nov 14 2013 Ian Kent - 1:5.0.7-34 +- bz1029611 - Fresh rhel7 install can't automount nfs exports + - fix revision in spec file. +- Resolves: rhbz#1029611 + +* Thu Nov 14 2013 Ian Kent - 1:5.0.7-33 +- bz1029611 - Fresh rhel7 install can't automount nfs exports + - regenerate configure due to missing function. +- Resolves: rhbz#1029611 + +* Thu Nov 7 2013 Ian Kent - 1:5.0.7-32 +- bz1011909 - NFSv4 UDP packet sent during automounting + - only probe specific nfs version if requested. +- Related: rhbz#1011909 + +* Tue Oct 22 2013 Ian Kent - 1:5.0.7-31 +- bz1011909 - NFSv4 UDP packet sent during automounting + - fix get_nfs_info() probe. + - fix portmap lookup. +- bz995979 - RFE: feature to dump automount maps in native file format + - update dumpmaps patch with latest changes from QE testing. +- Resolves: rhbz#1011909 rhbz#995979 + +* Thu Aug 22 2013 Ian Kent - 1:5.0.7-30 +- bz852327 - RFE: feature to dump automount maps in native file format + - fix dumpmaps multi output. + - try and cleanup after dumpmaps. + - teach dumpmaps to output simple key value pairs. +- Resolves: rhbz#852327 + +* Tue Aug 13 2013 Ian Kent - 1:5.0.7-29 +- bz994352 - "autofs reload" causes automount to stop running when multiple + maps are removed from auto.master + - fix syncronize handle_mounts() shutdown. +- bz994359 - Wildcard in nested mounts regression + - fix fix wildcard multi map regression. +- Resolves: rhbz#994352 rhbz#994359 + +* Sat Jul 13 2013 Ian Kent - 1:5.0.7-28 +- bz983160 Package autofs-5.0.7-22.el7 failed RHEL7 RPMdiff testing + - fix add null check in parse_server_string() (bz979155). + - check for protocol option. + - use ulimit max open files if greater than internal maximum. + - fix default path used for unitdir. + - fix changelog inconsistent dates. + - fix default path used for unitdir. + - fix changelog inconsistent dates. + - link with full reloc options. + - fix a couple of compiler warnings. + - add after sssd dependency to unit file (bz984089). +- Resolves: rhbz#983160 ++ +* Wed Jun 19 2013 Ian Kent - 1:5.0.7-22 +- misc man page fixes (bz948517). + +* Wed Jun 12 2013 Ian Kent - 1:5.0.7-21 +- fix probe each nfs version in turn for singleton mounts (bz973537). + +* Tue Jun 11 2013 Ian Kent - 1:5.0.7-20 +- fix master map mount options matching. +- fix master map bogus keywork match. +- fix fix map entry duplicate offset detection. +- add a number of fixes based on a Covarity report. + +* Mon May 27 2013 Ian Kent - 1:5.0.7-19 +- dont probe rdma mounts. + +* Fri May 24 2013 Ian Kent - 1:5.0.7-17 +- fix interface address null check. + +* Mon May 13 2013 Ian Kent - 1:5.0.7-16 +- make dump maps check for duplicate indirect mounts (bz961312). +- document allowed map sources in auto.master(5) (bz961312). +- add enable sloppy mount option to configure. + +* Sun Apr 28 2013 Ian Kent - 1:5.0.7-14 +- fix some automount(8) typos (bz664178). +- fix syncronize of handle_mounts() shutdown. +- fix submount tree not all expiring. + +* Tue Mar 12 2013 Ian Kent - 1:5.0.7-12 +- dont fail on master map self include. +- fix wildcard multi map regression. +- fix file descriptor leak when reloading the daemon. +- depricate nosymlink pseudo option. +- add symlink pseudo option. +- update kernel include files. +- fix requires in spec file. +- fix libtirpc build option. +- fix systemd unidir in spec file. +- document browse option in man page. +- fix automounter support on parisc. + +* Wed Feb 13 2013 Fedora Release Engineering - 1:5.0.7-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + +* Mon Jan 21 2013 Ian Kent - 1:5.0.7-10 +- fix submount offset delete. +- fix init script status return. +- fix use get_proximity() without libtirpc. +- don't use dirent d_type to filter out files in scandir(). +- don't schedule new alarms after readmap. +- use numeric protocol ids instead of protoent structs. +- lib/defaults.c: use WITH_LDAP conditional around LDAP types. +- make yellow pages support optional. +- modules/replicated.c: use sin6_addr.s6_addr32. +- workaround missing GNU versionsort extension. + +* Tue Nov 20 2012 Ian Kent - 1:5.0.7-9 +- fix nobind man page description. + +* Tue Nov 20 2012 Ian Kent - 1:5.0.7-8 +- fix map entry duplicate offset detection. +- Allow nsswitch.conf to not contain "automount:" lines. + +* Thu Oct 18 2012 Ian Kent - 1:5.0.7-7 +- use spec file systemd unit file location. + +* Thu Oct 18 2012 Ian Kent - 1:5.0.7-6 +- fix recursive mount deadlock. +- increase file map read buffer size. +- handle new location of systemd. + +* Tue Oct 16 2012 Ian Kent - 1:5.0.7-5 +- configure: allow cross compilation update. +- fix date in changelog entry. + +* Mon Oct 15 2012 Ian Kent - 1:5.0.7-4 +- include usage in usage message. +- dont wait forever to restart. +- add option description to man page. +- fix null map entry order handling. +- make description of default MOUNT_WAIT setting clear. +- configure.in: allow cross compilation. +- README: update mailing list subscription info. +- allow non root user to check status. + +* Mon Sep 10 2012 Ian Kent - 1:5.0.7-3 +- fix nobind sun escaped map entries. +- fix use cache entry after free mistake. +- fix ipv6 proximity calculation. +- fix parse buffer initialization. +- fix typo in automount(8). + +* Mon Aug 27 2012 Ian Kent - 1:5.0.7-2 +- update systemd scriplet macros (bz850040). + +* Wed Jul 25 2012 Ian Kent - 1:5.0.7-1 +- Update to upstream version 5.0.7. + +* Wed Jul 25 2012 Ian Kent - 1:5.0.6-24 +- fix changelog message commit dates. + +* Wed Jul 18 2012 Fedora Release Engineering - 1:5.0.6-23 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + +* Mon Jul 16 2012 Ian Kent - 1:5.0.6-21 +- fix systemd argument passing. +- fix get_nfs_info() can incorrectly fail. +- fix offset directory removal. + +* Tue Jul 3 2012 Ian Kent - 1:5.0.6-21 +- fix fix LDAP result leaks on error paths. +- report map not read when debug logging. +- duplicate parent options for included maps. +- update ->timeout() function to not return timeout. +- move timeout to map_source. +- fix kernel verion check of version components. +- dont retry ldap connect if not required. +- check if /etc/mtab is a link to /proc/self/mounts. +- fix nfs4 contacts portmap. +- make autofs wait longer for shutdown. +- fix sss map age not updated. +- fix remount deadlock. +- fix umount recovery of busy direct mount. +- fix offset mount point directory removal. +- remove move mount code and configure option. +- fix remount of multi mount. +- fix devce ioctl alloc path check. +- refactor hosts lookup module. +- remove cache update from parse_mount(). +- add function to delete offset cache entry. +- allow update of multi mount offset entries. +- add hup signal handling to hosts map. + +* Tue May 22 2012 Ian Kent - 1:5.0.6-19 +- fix libtirpc name clash (bz821847). + +* Tue May 22 2012 Ian Kent - 1:5.0.6-18 +- update patch fix initialization in rpc create_client() (bz821847). + +* Wed May 16 2012 Ian Kent - 1:5.0.6-17 +- fix initialization in rpc create_client() (bz821847). + +* Tue May 1 2012 Ian Kent - 1:5.0.6-16 +- add libsss_autofs as a build dependency. + +* Tue May 1 2012 Ian Kent - 1:5.0.6-15 +- fix typo in libtirpc file name. +- fix rework error return handling in rpc code. +- allow MOUNT_WAIT to override probe. +- improve UDP RPC timeout handling. +- fix segfault in get_query_dn(). +- use strtok_r() in linux_version_code(). +- fix sss wildcard match. +- fix dlopen() error handling in sss module. +- fix configure string length tests for sss library. + +* Wed Feb 29 2012 Ian Kent - 1:5.0.6-14 +- fix function to check mount.nfs version. + +* Sun Feb 26 2012 Ian Kent - 1:5.0.6-13 +- fix error in %post scriplet. + +* Fri Feb 24 2012 Ian Kent - 1:5.0.6-12 +- ignore duplicate exports in auto.net. +- add kernel verion check function. +- add function to check mount.nfs version. +- reinstate singleton mount probe. +- rework error return handling in rpc code. +- catch EHOSTUNREACH and bail out early. +- systemd support fixes. +- fix segmentation fault in do_remount_indirect(). + +* Thu Feb 9 2012 Ian Kent - 1:5.0.6-11 +- fix fuzz in CHANGELOG hunk when applying patch26. + +* Tue Feb 7 2012 Ian Kent - 1:5.0.6-10 +- fix rpc build error. +- add sss lookup module. +- teach automount about sss source. + +* Mon Jan 23 2012 Ian Kent - 1:5.0.6-9 +- add correct patch for "fix improve mount location error reporting". +- add correct patch for "fix fix wait for master source mutex". + +* Mon Jan 23 2012 Ian Kent - 1:5.0.6-8 +- fix fix wait for master source mutex. +- fix improve mount location error reporting (bz783496). + +* Thu Jan 12 2012 Fedora Release Engineering - 1:5.0.6-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + +* Fri Dec 9 2011 Ian Kent - 1:5.0.6-6 +- remove empty command line arguments (passed by systemd). + +* Mon Dec 5 2011 Ian Kent - 1:5.0.6-5 +- fix ipv6 name lookup check. +- fix ipv6 rpc calls. +- fix ipv6 configure check. +- add piddir to configure. +- add systemd unit support. +- fix MNT_DETACH define. + +* Mon Dec 5 2011 Ian Kent - 1:5.0.6-4 +- fix lsb service name in init script 2 (bz712504). + +* Tue Nov 8 2011 Ian Kent - 1:5.0.6-3 +- improve mount location error reporting. +- fix paged query more results check. +- fix dumpmaps not reading maps. +- fix result null check in read_one_map(). +- Fix LDAP result leaks on error paths. +- code analysis fixes 1. +- fix not bind mounting local filesystem. +- update dir map-type patch for changed patch order. +- fix wait for master source mutex. +- fix submount shutdown race +- fix fix map source check in file lookup. +- add disable move mount configure option. + +* Wed Jul 6 2011 Ian Kent - 1:5.0.6-2 +- add missing spec file entries for dir-type change (bz719208). + +* Mon Jul 4 2011 Ian Kent - 1:5.0.6-1 +- update source to 5.0.6. +- fix ipv6 name for lookup fix. +- add dir map-type patch. + +* Tue Jun 14 2011 Ian Kent - 1:5.0.5-38 +- fix lsb service name in init script (bz692963). + +* Fri Mar 18 2011 Ian Kent - 1:5.0.5-37 +- replace GPLv3 code with GPLv2 equivalent. + +* Thu Mar 03 2011 Ian Kent - 1:5.0.5-36 +- use weight only for server selection. +- fix isspace() wild card substition. +- auto adjust ldap page size. +- fix prune cache valid check. +- fix mountd vers retry. +- fix expire race. +- add lsb force-reload and try-restart. + +* Mon Feb 07 2011 Fedora Release Engineering - 1:5.0.5-35 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + +* Tue Nov 23 2010 Ian Kent - 1:5.0.5-34.fc15 +- revert wait for master map to be available at start. + +* Mon Nov 22 2010 Ian Kent - 1:5.0.5-33.fc15 +- fix wait for master map to be available at start. + +* Mon Nov 8 2010 Ian Kent - 1:5.0.5-32.fc15 +- always read file maps mount lookup map read fix. +- fix direct map not updating on reread. +- add external bind method. +- fix add simple bind auth. +- add option to dump configured automount maps. +- wait for master map to be available at start. + +* Fri Aug 27 2010 Ian Kent - 1:5.0.5-31.fc15 +- fix status privilege error (bz627605). + +* Wed Aug 18 2010 Ian Kent - 1:5.0.5-30.fc15 +- fix restart not working (bz624694). + +* Wed Aug 11 2010 Ian Kent - 1:5.0.5-29 +- remove ERR_remove_state() openssl call. + +* Tue Aug 10 2010 Ian Kent - 1:5.0.5-28 +- remove extra read master map call. +- remove extra cache create call in master_add_map_source(). +- fix error handing in do_mount_indirect(). +- expire thread use pending mutex. +- explicity link against the Kerberos library. +- remove some log message duplication for verbose logging. + +* Mon May 24 2010 Ian Kent - 1:5.0.5-27.fc14 +- fix master map source server unavailable handling. +- add autofs_ldap_auth.conf man page. +- fix random selection for host on different network. +- make redhat init script more lsb compliant. +- don't hold lock for simple mounts. +- fix remount locking. +- fix wildcard map entry match. +- fix parse_sun() module init. +- dont check null cache on expire. +- fix null cache race. +- fix cache_init() on source re-read. +- fix mapent becomes negative during lookup. +- check each dc server individually. +- fix negative cache included map lookup. +- remove state machine timed wait. + +* Fri Apr 30 2010 Ian Kent - 1:5.0.5-26.fc14 +- remove URL tag as there is not official autofs wiki (bz529804). + +* Wed Apr 7 2010 Ian Kent - 1:5.0.5-25.fc14 +- make nfs4 default for replicated selection configuration (bz579949). +- add simple bind authentication option (bz579951). + +* Fri Mar 26 2010 Ian Kent - 1:5.0.5-24.fc14 +- fix add locality as valid ldap master map attribute (bz575863). + +* Wed Mar 17 2010 Ian Kent - 1:5.0.5-22 +- fix get query dn failure. +- fix ampersand escape in auto.smb. +- add locality as valid ldap master map attribute. + +* Wed Mar 17 2010 Ian Kent - 1:5.0.5-22 +- add Conflicts to ensure we get fixed cyrus-sasl-lib for rev 21 change. + +* Tue Feb 23 2010 Ian Kent - 1:5.0.5-21 +- add missing sasl mutex callbacks. + +* Thu Feb 11 2010 Ian Kent - 1:5.0.5-19 +- fix segfault upon reconnect cannot find valid base dn. + +* Mon Feb 1 2010 Ian Kent - 1:5.0.5-17 +- dont connect at ldap lookup module init. +- fix random selection option. +- fix disable timeout. +- fix strdup() return value check. + +* Tue Dec 8 2009 Ian Kent - 1:5.0.5-16 +- fix memory leak on reload (bz545137). + +* Fri Dec 4 2009 Ian Kent - 1:5.0.5-14 +- fix rpc fail on large export list (bz543023). + +* Mon Nov 30 2009 Ian Kent - 1:5.0.5-12 +- check for path mount location in generic module. +- dont fail mount on access fail. + +* Tue Nov 24 2009 Ian Kent - 1:5.0.5-10 +- fix pidof init script usage. + +* Mon Nov 23 2009 Ian Kent - 1:5.0.5-8 +- fix timeout in connect_nb(). + +* Mon Nov 16 2009 Ian Kent - 1:5.0.5-6 +- don't use master_lex_destroy() to clear parse buffer. +- make documentation for set-log-priority clearer. + +* Tue Nov 10 2009 Ian Kent - 1:5.0.5-5 +- fix ext4 "preen" fsck at mount. + +* Mon Nov 9 2009 Ian Kent - 1:5.0.5-4 +- fix stale initialization for file map instance patch was not applied. + +* Tue Nov 3 2009 Ian Kent - 1:5.0.5-3 +- fix stale initialization for file map instance. + +* Tue Oct 6 2009 Ian Kent - 1:5.0.5-2 +- fix included map read fail handling. +- refactor ldap sasl authentication bind to eliminate extra connect + causing some servers to reject the request. +- add mount wait parameter to allow timeout of mount requests to + unresponsive servers. +- special case cifs escape handling. +- fix libxml2 workaround configure. +- more code analysis corrections (and fix a typo in an init script). +- fix backwards #ifndef INET6. + +* Fri Sep 4 2009 Ian Kent - 1:5.0.5-1 +- update source to latest upstream version. + - this is essentially a consolidation of the patches already in this rpm. +- add dist tag to match latest RHEL-5 package tag format. + +* Thu Sep 3 2009 Ian Kent - 1:5.0.4-39 +- fix libxml2 non-thread-safe calls. +- fix direct map cache locking. +- fix patch "dont umount existing direct mount on reread" deadlock. + +* Fri Jul 24 2009 Fedora Release Engineering - 1:5.0.4-37 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + +* Fri Jul 17 2009 Ian Kent - 1:5.0.4-34 +- fix typo in patch to allow dumping core. + +* Wed Jul 15 2009 Ian Kent - 1:5.0.4-32 +- fix an RPC fd leak. +- don't block signals we expect to dump core. +- fix pthread push order in expire_proc_direct(). + +* Fri Jun 12 2009 Ian Kent - 1:5.0.4-30 +- fix incorrect dclist free. +- srv lookup handle endianness. +- fix bug introduced by library reload changes which causes autofs to + not release mount thread resources when using submounts. +- fix notify mount message path. +- try harder to work out if we created mount point at remount. +- fix double free in do_sasl_bind(). +- manual umount recovery fixes. +- fix map type info parse error. + +* Mon May 18 2009 Ian Kent - 1:5.0.4-28 +- use intr option as hosts mount default. +- sync kernel includes with upstream kernel. +- dont umount existing direct mount on master re-read. +- fix incorrect shutdown introduced by library relaod fixes. +- improve manual umount recovery. +- dont fail on ipv6 address when adding host. +- always read file maps multi map fix. +- always read file maps key lookup fixes. +- add support for LDAP_URI="ldap:///" SRV RR lookup. + +* Thu Apr 16 2009 Ian Kent - 1:5.0.4-26 +- fix lsb init script header. +- fix memory leak reading ldap master map. +- fix st_remove_tasks() locking. +- reset flex scanner when setting buffer. +- zero s_magic is valid. + +* Mon Mar 30 2009 Ian Kent - 1:5.0.4-24 +- clear rpc client on lookup fail. + +* Fri Mar 20 2009 Ian Kent - 1:5.0.4-23 +- fix call restorecon when misc device file doesn't exist. + +* Wed Mar 18 2009 Ian Kent - 1:5.0.4-22 +- use misc device ioctl interface by default, if available. + +* Tue Mar 17 2009 Ian Kent - 1:5.0.4-21 +- fix file map lookup when reading included or nsswitch sources. + - a regression introduced by file map lookup optimisation in rev 9. + +* Fri Mar 13 2009 Ian Kent - 1:5.0.4-20 +- add LSB init script parameter block. + +* Fri Mar 13 2009 Ian Kent - 1:5.0.4-19 +- another easy alloca replacements fix. + +* Thu Mar 12 2009 Ian Kent - 1:5.0.4-18 +- fix return start status on fail. +- fix double free in expire_proc(). + +* Wed Feb 25 2009 Ian Kent - 1:5.0.4-17 +- fix bad token declaration in master map parser. + +* Wed Feb 25 2009 Ian Kent - 1:5.0.4-16 +- correct mkdir command in %%install section, bz481132. + +* Tue Feb 24 2009 Ian Kent - 1:5.0.4-15 +- fix array out of bounds accesses and cleanup couple of other alloca() calls. +- Undo mistake in copy order for submount path introduced by rev 11 patch. +- add check for alternate libxml2 library for libxml2 tsd workaround. +- add check for alternate libtirpc library for libtirpc tsd workaround. +- cleanup configure defines for libtirpc. +- add WITH_LIBTIRPC to -V status report. +- add libtirpc-devel to BuildRequires. +- add nfs mount protocol default configuration option. + +* Mon Feb 23 2009 Fedora Release Engineering - 1:5.0.4-11 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + +* Thu Feb 19 2009 Ian Kent - 5.0.4-10 +- fix mntent.h not included before use of setmntent_r(). + +* Mon Feb 16 2009 Ian Kent - 5.0.4-9 +- fix hosts map use after free. +- fix uri list locking (again). +- check for stale SASL credentials upon connect fail. +- add "forcestart" and "forcerestart" init script options to allow + use of 5.0.3 strartup behavior if required. +- always read entire file map into cache to speed lookups. +- make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit. +- make some easy alloca replacements. +- update to configure libtirpc if present. +- update to provide ipv6 name and address support. +- update to provide ipv6 address parsing. + +* Thu Feb 5 2009 Ian Kent - 5.0.4-8 +- rename program map parsing bug fix patch. +- use CLOEXEC flag functionality for setmntent also, if present. + +* Wed Jan 21 2009 Jeff Moyer - 5.0.4-6 +- fix a bug in the program map parsing routine + +* Thu Jan 15 2009 Ian Kent - 5.0.4-5 +- fix negative caching of non-existent keys. +- fix ldap library detection in configure. +- use CLOEXEC flag functionality if present. +- fix select(2) fd limit. +- make hash table scale to thousands of entries. + +* Wed Dec 3 2008 Ian Kent - 5.0.4-4 +- fix nested submount expire deadlock. + +* Wed Nov 19 2008 Ian Kent - 5.0.4-3 +- fix libxml2 version check for deciding whether to use workaround. + +* Tue Nov 11 2008 Ian Kent - 5.0.4-2 +- Fix tag confusion. + +* Tue Nov 11 2008 Ian Kent - 5.0.4-1 +- Upstream source version 5.0.4. + +* Tue Nov 11 2008 Ian Kent - 5.0.3-32 +- correct buffer length setting in autofs-5.0.3-fix-ifc-buff-size-fix.patch. + +* Sun Nov 2 2008 Ian Kent - 5.0.3-30 +- fix segv during library re-open. +- fix incorrect pthreads condition handling for expire requests. +- fix master map lexer eval order. +- fix bad alloca usage. + +* Thu Oct 23 2008 Ian Kent - 5.0.3-28 +- don't close file handle for rootless direct mounti-mount at mount. +- wait submount expire thread completion when expire successful. +- add inadvertantly ommitted server list locking in LDAP module. + +* Fri Oct 10 2008 Ian Kent - 5.0.3-26 +- add map-type-in-map-name fix patch to sync with upstream and RHEL. +- don't readmap on HUP for new mount. +- add NIS_PARTIAL to map entry not found check and fix use after free bug. + +* Fri Sep 26 2008 Ian Kent - 5.0.3-25 +- fix fd leak at multi-mount non-fatal mount fail. +- fix incorrect multi-mount mountpoint calcualtion. + +* Fri Sep 19 2008 Ian Kent - 5.0.3-23 +- add upstream bug fixes + - bug fix for mtab check. + - bug fix for zero length nis key. + - update for ifc buffer handling. + - bug fix for kernel automount handling. +- warning: I found a bunch of patches that were present but not + being applied. + +* Mon Aug 25 2008 Ian Kent - 5.0.3-21 +- add upstream bug fix patches + - add command line option to override is running check. + - don't use proc fs for is running check. + - fix fail on included browse map not found. + - fix incorrect multi source messages. + - clear stale flag on map read. + - fix proximity other rpc ping timeout. + - refactor mount request vars code. + - make handle_mounts startup condition distinct. + - fix submount shutdown handling. + - try not to block on expire. + - add configuration paramter UMOUNT_WAIT. + - fix multi mount race. + - fix nfs4 colon escape handling. + - check replicated list after probe. + - add replicated server selection debug logging. + - update replicated server selection documentation. + - use /dev/urandom instead of /dev/random. + - check for mtab pointing to /proc/mounts. + - fix interface config buffer size. + - fix percent hack heap corruption. + +* Mon Jul 14 2008 Tom "spot" Callaway - 5.0.3-19 +- change conflicts to requires +- fix license tag + +* Mon Jun 30 2008 Ian Kent - 5.0.3-18 +- don't abuse the ap->ghost field on NFS mount. +- multi-map doesn't pickup NIS updates automatically. +- eliminate redundant DNS name lookups. +- mount thread create condition handling fix. +- allow directory create on NFS root. +- check direct mount path length. +- fix incorrect in check in get user info. +- fix a couple of memory leaks. + +* Wed May 14 2008 Ian Kent - 5.0.3-16 +- update patches, documentation and comments only change. +- rename patch and add to CVS. + +* Mon May 12 2008 Ian Kent - 5.0.3-14 +- check for nohide mounts (bz 442618). +- ignore nsswitch sources that aren't supported (bz 445880). + +* Thu Apr 17 2008 Ian Kent - 5.0.3-13 +- fix typo in patch for incorrect pthreads condition handling patch. + +* Mon Apr 14 2008 Ian Kent - 5.0.3-12 +- fix incorrect pthreads condition handling for mount requests. + +* Tue Apr 1 2008 Ian Kent - 5.0.3-11 +- and another try at fixing lexer matching map type in map name. + +* Sun Mar 30 2008 Ian Kent - 5.0.3-10 +- another try a fixing lexer matching map type in map name. + +* Wed Mar 26 2008 Ian Kent - 5.0.3-9 +- fix lexer ambiguity in match when map type name is included in map name. + +* Mon Mar 24 2008 Ian Kent - 5.0.3-8 +- revert miscellaneous device node related patches. +- add missing check for zero length NIS key. +- fix incorrect match of map type name when included in map name. +- update rev 7 sasl callbacks patch. + +* Thu Mar 20 2008 Ian Kent - 5.0.3-7 +- add patch to initialize sasl callbacks unconditionally on autofs + LDAP lookup library load. + +* Mon Feb 25 2008 Ian Kent - 5.0.3-6 +- fix expire calling kernel more often than needed. +- fix unlink of mount tree incorrectly causing autofs mount fail. +- add miscellaneous device node interface library. +- use miscellaneous device node, if available, for active restart. +- device node and active restart fixes. +- update is_mounted to use device node ioctl, if available. + +* Fri Feb 1 2008 Ian Kent - 5.0.3-5 +- another fix for don't fail on empty master map. + +* Fri Jan 25 2008 Ian Kent - 5.0.3-4 +- correction to the correction for handling of LDAP base dns with spaces. +- avoid using UDP for probing NFSv4 mount requests. +- use libldap instead of libldap_r. + +* Mon Jan 21 2008 Ian Kent - 5.0.3-3 +- catch "-xfn" map type and issue "no supported" message. +- another correction for handling of LDAP base dns with spaces. + +* Mon Jan 14 2008 Ian Kent - 5.0.3-2 +- correct configure test for ldap page control functions. + +* Mon Jan 14 2008 Ian Kent - 5.0.3-1 +- update source to version 5.0.3. + +* Fri Dec 21 2007 Ian Kent - 5.0.2-25 +- Bug 426401: CVE-2007-6285 autofs default doesn't set nodev in /net [rawhide] + - use mount option "nodev" for "-hosts" map unless "dev" is explicily specified. + +* Tue Dec 18 2007 Ian Kent - 5.0.2-23 +- Bug 397591 SELinux is preventing /sbin/rpc.statd (rpcd_t) "search" to (sysctl_fs_t). + - prevent fork between fd open and setting of FD_CLOEXEC. + +* Thu Dec 13 2007 Ian Kent - 5.0.2-21 +- Bug 421371: CVE-2007-5964 autofs defaults don't restrict suid in /net [rawhide] + - use mount option "nosuid" for "-hosts" map unless "suid" is explicily specified. + +* Thu Dec 6 2007 Jeremy Katz - 1:5.0.2-19 +- rebuild for new ldap + +* Tue Nov 20 2007 Ian Kent - 5.0.2-18 +- fix schema selection in LDAP schema discovery. +- check for "*" when looking up wildcard in LDAP. +- fix couple of edge case parse fails of timeout option. +- add SEARCH_BASE configuration option. +- add random selection as a master map entry option. +- re-read config on HUP signal. +- add LDAP_URI, LDAP_TIMEOUT and LDAP_NETWORK_TIMEOUT configuration options. +- fix deadlock in submount mount module. +- fix lack of ferror() checking when reading files. +- fix typo in autofs(5) man page. +- fix map entry expansion when undefined macro is present. +- remove unused export validation code. +- add dynamic logging (adapted from v4 patch from Jeff Moyer). +- fix recursive loopback mounts (Matthias Koenig). +- add map re-load to verbose logging. +- fix handling of LDAP base dns with spaces. +- handle MTAB_NOTUPDATED status return from mount. +- when default master map, auto.master, is used also check for auto_master. +- update negative mount timeout handling. +- fix large group handling (Ryan Thomas). +- fix for dynamic logging breaking non-sasl build (Guillaume Rousse). +- eliminate NULL proc ping for singleton host or local mounts. + +* Mon Sep 24 2007 Ian Kent - 5.0.2-16 +- add descriptive comments to config about LDAP schema discovery. +- work around segfault at exit caused by libxml2. +- fix foreground logging (also fixes shutdown needing extra signal bug). + +* Wed Sep 5 2007 Ian Kent - 5.0.2-15 +- fix LDAP schema discovery. + +* Tue Aug 28 2007 Ian Kent - 5.0.2-14 +- update patch to prevent failure on empty master map. +- if there's no "automount" entry in nsswitch.conf use "files" source. +- add LDAP schema discovery if no schema is configured. + +* Wed Aug 22 2007 Ian Kent - 5.0.2-13 +- fix "nosymlink" option handling and add desription to man page. + +* Tue Aug 21 2007 Ian Kent - 5.0.2-12 +- change random multiple server selection option name to be consistent + with upstream naming. + +* Tue Aug 21 2007 Ian Kent - 5.0.2-11 +- don't fail on empty master map. +- add support for the "%" hack for case insensitive attribute schemas. + +* Mon Jul 30 2007 Ian Kent - 5.0.2-10 +- mark map instances stale so they aren't "cleaned" during updates. +- fix large file compile time option. + +* Fri Jul 27 2007 Ian Kent - 5.0.2-9 +- fix version passed to get_supported_ver_and_cost (bz 249574). + +* Tue Jul 24 2007 Ian Kent - 5.0.2-8 +- fix parse confusion between attribute and attribute value. + +* Fri Jul 20 2007 Ian Kent - 5.0.2-7 +- fix handling of quoted slash alone (bz 248943). + +* Wed Jul 18 2007 Ian Kent - 5.0.2-6 +- fix wait time resolution in alarm and state queue handlers (bz 247711). + +* Mon Jul 16 2007 Ian Kent - 5.0.2-5 +- fix mount point directory creation for bind mounts. +- add quoting for exports gathered by hosts map. + +* Mon Jun 25 2007 Ian Kent - 5.0.2-4 +- update multi map nsswitch patch. + +* Mon Jun 25 2007 Ian Kent - 5.0.2-3 +- add missing "multi" map support. +- add multi map nsswitch lookup. + +* Wed Jun 20 2007 Ian Kent - 5.0.2-2 +- include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it). +- correct initialization of local var in parse_server_string. + +* Mon Jun 18 2007 Ian Kent - 5.0.2-1 +- Update to upstream release 5.0.2. + +* Tue Jun 12 2007 Ian Kent - 5.0.1-16 +- add ldaps support. + - note: it's no longer possible to have multiple hosts in an ldap map spec. + - note: to do this you need to rely on the ldap client config. + +* Thu Jun 7 2007 Ian Kent - 5.0.1-14 +- fix deadlock in alarm manager module. + +* Sun Jun 3 2007 Ian Kent - 5.0.1-12 +- correct mistake in logic test in wildcard lookup. + +* Mon May 7 2007 Ian Kent - 5.0.1-10 +- fix master map lexer to admit "." in macro values. + +* Tue Apr 17 2007 Ian Kent - 5.0.1-9 +- upstream fix for filesystem is local check. +- disable exports access control check (bz 203277). +- fix patch to add command option for set a global mount options (bz 214684). + +* Mon Apr 16 2007 Ian Kent - 5.0.1-8 +- add configuration variable to control appending of global options (bz 214684). +- add command option to set a global mount options string (bz 214684). + +* Tue Apr 3 2007 Ian Kent - 5.0.1-7 +- fix "null" domain netgroup match for "-hosts" map. + +* Thu Mar 29 2007 Ian Kent - 5.0.1-6 +- fix directory creation for browse mounts. +- fix wildcard map handling and improve nsswitch source map update. + +* Fri Mar 16 2007 Ian Kent - 5.0.1-5 +- drop "DEFAULT_" prefix from configuration names. +- add option to select replicated server at random (instead of + ping response time) (bz 227604). +- fix incorrect cast in directory cleanup routines (bz 231864). + +* Thu Mar 8 2007 Ian Kent - 5.0.1-4 +- fixed numeric export match (bz 231188). + +* Thu Mar 1 2007 Ian Kent - 5.0.1-3 +- change file map lexer to allow white-space only blank lines (bz 229434). + +* Fri Feb 23 2007 Ian Kent - 5.0.1-2 +- update "@network" matching patch. + +* Thu Feb 22 2007 Ian Kent - 5.0.1-1 +- update to release tar. +- fix return check for getpwuid_r and getgrgid_r. +- patch to give up trying to update exports list while host is mounted. +- fix to "@network" matching. +- patch to check for fstab update and retry if not updated. + +* Tue Feb 20 2007 Ian Kent - 5.0.1-0.rc3.24 +- add "condrestart" to init script (bz 228860). +- add "@network" and .domain.name export check. +- fix display map name in mount entry for "-hosts" map. + +* Fri Feb 16 2007 Ian Kent - 5.0.1-0.rc3.22 +- fix localhost replicated mounts not working (bz 208757). + +* Wed Feb 14 2007 Ian Kent - 5.0.1-0.rc3.20 +- correct return status from do_mkdir (bz 223480). + +* Sat Feb 10 2007 Ian Kent - 5.0.1-0.rc3.18 +- update the "task done race" patch to fix a deadlock. +- added URL tag. +- removed obsoletes autofs-ldap. +- replaced init directory paths with %%{_initrddir} macro. + +* Fri Feb 9 2007 Ian Kent - 5.0.1-0.rc3.17 +- make use of spaces and tabs in spec file consistent. +- escape embedded macro text in %%changelog. +- eliminate redundant %%version and %%release. +- remove redundant conditional check from %%clean. +- remove redundant exit from %%preun. +- correct %%defattr spec. +- remove empty %%doc and redundant %%dir misc lines. +- combine program module spec lines into simpler one line form. + +* Tue Feb 6 2007 Ian Kent - 5.0.1-0.rc3.15 +- fix race when setting task done (bz 227268). + +* Mon Jan 29 2007 Ian Kent - 5.0.1-0.rc3.13 +- make double quote handing consistent (at least as much as we can). +- fix handling of trailing white space in wildcard lookup (forward port bz 199720). +- check fqdn of each interface when matching export access list (bz 213700). + +* Thu Jan 18 2007 Ian Kent - 5.0.1-0.rc3.11 +- correct check for busy offset mounts before offset umount (bz 222872). + +* Wed Jan 17 2007 Ian Kent - 5.0.1-0.rc3.9 +- fix another expire regression introduced in the "mitigate manual umount" + patch (bz 222872). + +* Mon Jan 15 2007 Ian Kent - 5.0.1-0.rc3.7 +- ignore "winbind" if it appears in "automount" nsswitch.conf (bz 214632). + +* Wed Jan 10 2007 Ian Kent - 5.0.1-0.rc3.5 +- remove fullstop from Summary tag. +- change Buildroot to recommended form. +- replace Prereq with Requires. + +* Tue Jan 9 2007 Ian Kent - 5.0.1-0.rc3.3 +- remove redundant rpath link option (prep for move to Extras). + +* Tue Jan 9 2007 Ian Kent - 5.0.1-0.rc3.1 +- consolidate to rc3. +- fix typo in Fix typo in var when removing temp directory (bz 221847). + +* Wed Dec 27 2006 Ian Kent - 5.0.1-0.rc2.41 +- fix nonstrict multi-mount handling (bz 219383). +- correct detection of duplicate indirect mount entries (bz 220799). + +* Thu Dec 14 2006 Ian Kent - 5.0.1-0.rc2.38 +- update master map tokenizer to admit "slasify-colons" option. +- update location validation to accept "_" (bz 219445). +- set close-on-exec flag on open sockets (bz 215757). + +* Mon Dec 11 2006 Ian Kent - 5.0.1-0.rc2.35 +- update "replace-tempnam" patch to create temp files in sane location. + +* Mon Dec 11 2006 Ian Kent - 5.0.1-0.rc2.34 +- change mount "device" from "automount" to the map name. +- check for buffer overflow in mount_afs.c. +- replace tempnam with mkdtemp. + +* Sun Dec 10 2006 Ian Kent - 5.0.1-0.rc2.33 +- expand export access checks to include missing syntax options. +- make "-hosts" module try to be sensitive to exports list changes. + +* Thu Dec 7 2006 Ian Kent - 5.0.1-0.rc2.32 +- remove ability to use multiple indirect mount entries in master + map (bz 218616). + +* Wed Dec 6 2006 Ian Kent - 5.0.1-0.rc2.29 +- alter nfs4 host probing to not use portmap lookup and add options + check for "port=" parameter (bz 208757). +- correct semantics of "-null" map handling (bzs 214800, 208091). + +* Sat Nov 25 2006 Ian Kent - 5.0.1-0.rc2.26 +- fix parsing of bad mount mount point in master map (bz 215620). +- fix use after free memory access in cache.c and lookup_yp.c (bz 208091). +- eliminate use of pthread_kill to detect task completion (bz 208091). + +* Sun Nov 12 2006 Ian Kent - 5.0.1-0.rc2.23 +- fix tokenizer to distinguish between global option and dn string (bz 214684). +- fix incorrect return from spawn. + +* Wed Nov 8 2006 Ian Kent - 5.0.1-0.rc2.21 +- mitigate manual umount of automounts where possible. +- fix multiply recursive bind mounts. +- check kernel module version and require 5.00 or above. +- fix expire regression introduced in the "mitigate manual umount" patch. +- still more on multiply recursive bind mounts. + +* Mon Oct 30 2006 Ian Kent - 5.0.1-0.rc2.20 +- Update patch for changed semantics of mkdir in recent kernels. +- fix macro table locking (bz 208091). +- fix nsswitch parser locking (bz 208091). +- allow only one master map read task at a time. +- fix misc memory leaks. + +* Wed Oct 25 2006 Ian Kent - 5.0.1-0.rc2.19 +- deal with changed semantics of mkdir in recent kernels. + +* Fri Oct 20 2006 Ian Kent - 5.0.1-0.rc2.16 +- fix get_query_dn not looking in subtree for LDAP search (missed + econd occurance). +- allow additional common LDAP attributes in map dn. +- Resolves: rhbz#205997 + +* Mon Oct 16 2006 Ian Kent - 5.0.1-0.rc2.13 +- fix parsing of numeric host names in LDAP map specs (bz 205997). + +* Mon Oct 16 2006 Ian Kent - 5.0.1-0.rc2.12 +- fix "-fstype=nfs4" server probing (part 2 of bz 208757). +- set close-on-exec flag on open files where possible (bz 207678). + +* Fri Oct 13 2006 Ian Kent - 5.0.1-0.rc2.11 +- fix file handle leak in nsswitch parser (bz 207678). +- fix memory leak in mount and expire request processing (bz 207678). +- add additional check to prevent running of cancelled tasks. +- fix potential file handle leakage in rpc_subs.c for some failure + cases (bz 207678). +- fix file handle leak in included map lookup (bz 207678). + +* Sat Oct 7 2006 Ian Kent - 5.0.1-0.rc2.10 +- fix get_query_dn not looking in subtree for LDAP search. +- allow syntax "--timeout " for backward compatibility + (bz 193948). +- make masked_match independent of hostname for exports comparison + (bz 209638). + +* Thu Oct 5 2006 Ian Kent - 5.0.1-0.rc2.9 +- fix "-fstype=nfs4" handling (bz 208757). + +* Wed Sep 27 2006 Ian Kent - 5.0.1-0.rc2.8 +- review and fix master map options update for map reload. + +* Wed Sep 27 2006 Ian Kent - 5.0.1-0.rc2.7 +- make default installed master map for /net use "-hosts" instead + of auto.net. +- fix included map recursive map key lookup. + +* Mon Sep 25 2006 Ian Kent - 5.0.1-0.rc2.6 +- remove unused option UNDERSCORETODOT from default config files. + +* Mon Sep 25 2006 Ian Kent - 5.0.1-0.rc2.5 +- fix LDAP lookup delete cache entry only if entry doesn't exist. +- add missing socket close in replicated host check (Jeff Moyer). + +* Wed Sep 20 2006 Ian Kent - 5.0.1-0.rc2.4 +- fix cache entrys not being cleaned up on submount expire. + +* Sun Sep 17 2006 Ian Kent - 5.0.1-0.rc2.3 +- fix include check full patch for file map of same name. + +* Wed Sep 13 2006 Ian Kent - 5.0.1-0.rc2.2 +- fix handling of autofs specific mount options (bz 199777). + +* Fri Sep 1 2006 Ian Kent - 5.0.1-0.rc2.1 +- consolidate to rc2. +- fix colon escape handling. +- fix recusively referenced bind automounts. +- update kernel patches. + +* Fri Aug 25 2006 Ian Kent - 5.0.1-0.rc1.17 +- fix task cancelation at shutdown (more) +- fix concurrent mount and expire race with nested submounts. + +* Sun Aug 20 2006 Ian Kent - 5.0.1-0.rc1.16 +- fix included map lookup. +- fix directory cleanup on expire. +- fix task cancelation at shutdown. +- fix included map wild card key lookup. + +* Wed Aug 16 2006 Ian Kent - 5.0.1-0.rc1.15 +- expire individual submounts. +- add ino_index locking. +- fix nested submount expiring away when pwd is base of submount. +- more expire re-work to cope better with shutdown following cthon tests. +- allow hostname to start with numeric when validating. + +* Mon Aug 7 2006 Ian Kent - 5.0.1-0.rc1.14 +- remove SIGCHLD handler because it is no longer needed and was + causing expire problems. +- alter expire locking of multi-mounts to lock sub-tree instead of + entire tree. +- review verbose message feedback and update. +- correction for expire of multi-mounts. +- spelling corrections to release notes (Jeff Moyer). +- add back sloppy mount option, removed for Connectathon testing. +- disable mtab locking again. + +* Fri Aug 4 2006 Ian Kent - 5.0.1-0.rc1.13 +- tidy up directory cleanup and add validation check to rmdir_path. + +* Fri Aug 4 2006 Ian Kent - 5.0.1-0.rc1.12 +- enable mtab locking until I can resolve the race with it. + +* Fri Aug 4 2006 Ian Kent - 5.0.1-0.rc1.11 +- cthon fix expire of wildcard and program mounts broken by recent + patches. + +* Thu Aug 3 2006 Ian Kent - 5.0.1-0.rc1.10 +- cthon corrections for shutdown patch below and fix shutdown expire. + +* Wed Aug 2 2006 Ian Kent - 5.0.1-0.rc1.9 +- cthon fix some shutdown races. + +* Thu Jul 27 2006 Ian Kent - 5.0.1-0.rc1.8 +- Fix compile error. + +* Thu Jul 27 2006 Ian Kent - 5.0.1-0.rc1.7 +- cthon fix expire of various forms of nested mounts. + +* Mon Jul 24 2006 Ian Kent - 5.0.1-0.rc1.6 +- cthon more parser corrections and attempt to fix multi-mounts + with various combinations of submounts (still not right). + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.5 +- Add conflicts kernel < 2.6.17. +- Fix submount operation broken by connectathon updates. + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.4 +- Correction to host name validation test for connectathon tests. + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.3 +- More code cleanup and corrections for connectathon tests. + +* Wed Jul 19 2006 Ian Kent - 5.0.1-0.rc1.2 +- Code cleanup and fixes for connectathon tests. + +* Thu Jul 13 2006 Ian Kent - 5.0.1-0.rc1.1 +- Update version label to avoid package update problems. + +* Thu Jul 13 2006 Ian Kent - 5.0.0_beta6-8 +- add cacheing of negative lookups to reduce unneeded map + lookups (bz 197746 part 2). + +* Wed Jul 12 2006 Jesse Keating - 1:5.0.0_beta6-7.1 +- rebuild + +* Tue Jul 11 2006 Ian Kent - 5.0.0_beta6-7 +- correct directory cleanup in mount modules. +- merge key and wildcard LDAP query for lookups (bz 197746). + +* Sat Jul 8 2006 Ian Kent - 5.0.0_beta6-6 +- correct test for libhesiod. + +* Fri Jul 7 2006 Ian Kent - 5.0.0_beta6-5 +- correct auto.net installed as auto.smb. +- update LDAP auth - add autodectect option. + +* Wed Jul 5 2006 Ian Kent - 5.0.0_beta6-4 +- correct shutdown log message print. +- correct auth init test when no credentials required. + +* Tue Jul 4 2006 Ian Kent - 5.0.0_beta6-3 +- correct test for existence of auth config file. + +* Mon Jul 3 2006 Ian Kent - 5.0.0_beta6-2 +- merge LDAP authentication update for GSSAPI (Jeff Moyer). +- update default auth config to add options documenetation (Jeff Moyer). +- workaround segfaults at exit after using GSSAPI library. +- fix not checking return in init_ldap_connection (jeff Moyer). + +* Thu Jun 29 2006 Ian Kent - 5.0.0_beta6-1 +- consolidate to beta6, including: + - mode change update for config file. + - correction to get_query_dn fix from beta5-4. + +* Wed Jun 28 2006 Ian Kent - 5.0.0_beta5-6 +- cleanup defaults_read_config (Jeff Moyer). + +* Tue Jun 27 2006 Ian Kent - 5.0.0_beta5-5 +- allow global macro defines to override system macros. +- correct spelling error in default config files missed by + previous update. +- misc correctness and a memory leak fix. + +* Mon Jun 26 2006 Ian Kent - 5.0.0_beta5-4 +- correct spelling error in default config. +- fix default auth config not being installed. +- change LDAP query method as my test db was incorrect. +- change ldap defaults code to handle missing auth config. +- fix mistake in parsing old style LDAP specs. +- update LDAP so that new query method also works for old syntax. + +* Fri Jun 23 2006 Ian Kent - 5.0.0_beta5-3 +- lookup_init cleanup and fix missed memory leak. +- use nis map order to check if update is needed. +- fix couple of memory leaks in lookup_yp.c. +- fix pasre error in replicated server module. + +* Wed Jun 21 2006 Ian Kent - 5.0.0_beta5-2 +- Add openssl-devel to the BuildRequires, as it is needed for the LDAP + authentication bitsi also. + +* Tue Jun 20 2006 Ian Kent - 5.0.0_beta5-1 +- promote to beta5. + +* Tue Jun 20 2006 Ian Kent - 5.0.0_beta4-14 +- fix directory cleanup at exit. + +* Mon Jun 19 2006 Ian Kent - 5.0.0_beta4-13 +- Change LDAP message severity from crit to degug (bz# 183893). +- Corrections to INSTALL and README.v5.release. +- Add patch to fix segv on overlength map keys in file maps (Jeff Moter). +- Add patch to restrict scanning of /proc to pid directories only (Jeff Moyer). + +* Thu Jun 15 2006 Jeff Moyer - 5.0.0_beta4-12 +- Change BuildPrereq to BuildRequires as per the package guidelines. +- Add libxml2-devel to the BuildRequires, as it is needed for the LDAP + authentication bits. + +* Wed Jun 14 2006 Ian Kent - 5.0.0_beta4-11 +- add export access list matching to "hosts" lookup module (bz # 193585). + +* Tue Jun 13 2006 Jeff Moyer - 5.0.0_beta4-10 +- Add a BuildPrereq for cyrus-sasl-devel + +* Tue Jun 13 2006 Ian Kent - 5.0.0_beta4-9 +- move autofs4 module loading back to init script (part bz # 194061). + +* Mon Jun 12 2006 Ian Kent - 5.0.0_beta4-8 +- fix handling of master map entry update (bz # 193718). +- fix program map handling of invalid multi-mount offsets. + +* Sat Jun 10 2006 Ian Kent - 5.0.0_beta4-7 +- fix context init error (introduced by memory leak patch). + +* Fri Jun 9 2006 Ian Kent - 5.0.0_beta4-6 +- add free for working var in get_default_logging. +- add inialisation for kver in autofs_point struct. +- fix sources list corruption in check_update_map_sources. +- fix memory leak in walk_tree. +- fix memory leak in rpc_portmap_getport and rpc_ping_proto. +- fix memory leak in initialisation of lookup modules. + +* Thu Jun 8 2006 Ian Kent - 5.0.0_beta4-5 +- misc fixes for things found while investigating map re-read problem. + +* Wed Jun 7 2006 Ian Kent - 5.0.0_beta4-4 +- check base of offset mount tree is not a mount before umounting + its offsets. +- fix replicated mount parse for case where last name in list + fails lookup. +- correct indirect mount expire broken by the wildcard lookup fix. +- fix up multi-mount handling when wildcard map entry present. + +* Mon Jun 5 2006 Ian Kent - 5.0.0_beta4-3 +- correct config names in default.c (jpro@bas.ac.uk). + +* Mon Jun 5 2006 Ian Kent - 5.0.0_beta4-2 +- re-instate v4 directory cleanup (bz# 193832 again). +- backout master map lookup changes made to beta3. +- change default master map from /etc/auto.master to auto.master + so that we always use nsswitch to locate master map. +- change default installed master map to include "+auto.master" + to pickup NIS master map (all bz# 193831 again). + +* Fri Jun 2 2006 Ian Kent - 5.0.0_beta4-1 +- update to beta4. +- should address at least bzs 193798, 193770, 193831 and + possibly 193832. + +* Mon May 29 2006 Ian Kent - 5.0.0_beta3-6 +- add back test for nested mount in program map lookup. + - I must have commented this out for a reason. I guess we'll + find out soon enough. + +* Mon May 29 2006 Ian Kent - 5.0.0_beta3-5 +- fix handling of autofs filesystem mount fail on init. + +* Sat May 27 2006 Ian Kent - 5.0.0_beta3-4 +- updated hesiod patch. + +* Sat May 27 2006 Ian Kent - 5.0.0_beta3-3 +- update hesiod module (Jeff Moyer). + - add mutex to protect against overlapping mount requests. + - update return from mount request to give more sensible NSS_* + values. + +* Fri May 26 2006 Jeff Moyer - 1:5.0.0_beta3-2 +- Fix the install permissions for auto.master and auto.misc. + +* Thu May 25 2006 Ian Kent - 5.0.0_beta3-1 +- update source to version 5.0.0_beta3. +- add patch to remove extra debug print. +- add patch to + - fix memory alloc error in nis lookup module. + - add "_" to "." mapname translation to nis lookup module. +- add patch to add owner pid to mount list struct. +- add patch to disable NFSv4 when probing hosts (at least foe now). +- add patch to fix white space handling in replicated server selection code. +- add patch to prevent striping of debug info macro patch (Jeff Moyer). +- add patch to add sanity checks on rmdir_path and unlink (Jeff Moyer). +- add patch to fix e2fsck error code check (Jeff Moyer). + +* Tue May 16 2006 Ian Kent - 1:4.1.4-23 +- add patch to ignore the "bg" and "fg" mount options as they + aren't relevant for autofs mounts (bz #184386). + +* Tue May 2 2006 Ian Kent - 1:4.1.4-20 +- add patch to use "cifs" instead of smbfs and escape speces + in share names (bz #163999, #187732). + +* Tue Apr 11 2006 Ian Kent - 1:4.1.4-18 +- Add patch to allow customization of arguments to the + autofs-ldap-auto-master program (bz #187525). +- Add patch to escap "#" characters in exports from auto.net + program mount (bz#178304). + +* Fri Feb 10 2006 Jesse Keating - 1:4.1.4-16.2.2 +- bump again for double-long bug on ppc(64) + +* Tue Feb 07 2006 Jesse Keating - 1:4.1.4-16.2.1 +- rebuilt for new gcc4.1 snapshot and glibc changes + +* Wed Feb 1 2006 Ian Kent - 1:4.1.4-16.2 +- Add more general patch to translate "_" to "." in map names. (bz #147765) + +* Wed Jan 25 2006 Ian Kent - 1:4.1.4-16.1 +- Add patch to use LDAP_DEPRICATED compile option. (bz #173833) + +* Tue Jan 17 2006 Ian Kent - 1:4.1.4-16 +- Replace check-is-multi with more general multi-parse-fix. +- Add fix for premature return when waiting for lock file. +- Update copyright declaration for reentrant-syslog source. +- Add patch for configure option to disable locking during mount. + But don't disable locking by default. +- Add ability to handle automount schema used in Sun directory server. +- Quell compiler warning about getsockopt parameter. +- Quell compiler warning about yp_order parameter. + +* Fri Dec 09 2005 Jesse Keating +- rebuilt + +* Thu Nov 17 2005 Jeff Moyer - 1:4.1.4-14 +- Removed the /misc entry from the default auto.master. auto.misc has + an entry for the cdrom device, and the preferred method of mounting the + cd is via udev/hal. + +* Mon Nov 7 2005 Jeff Moyer - 1:4.1.4-13 +- Changed to sort -k 1, since that should be the same as +0. + +* Thu Nov 3 2005 Jeff Moyer - 1:4.1.4-12 +- The sort command no longer accepts options of the form "+0". This broke + auto.net, so the option was removed. Fixes bz #172111. + +* Wed Oct 26 2005 - 1:4.1.4-11 +- Check the return code of is_local_addr in get_best_mount. (bz #169523) + +* Wed Oct 26 2005 - 1:4.1.4-10 +- Fix some bugs in the parser +- allow -net instead of /etc/auto.net +- Fix a buffer overflow with large key lengths +- Don't allow autofs to unlink files, only to remove directories +- change to the upstream reentrant syslog patch from the band-aid deferred + syslog patch. +- Get rid of the init script patch that hard-coded the release to redhat. + This should be handled properly by all red hat distros. + +* Wed May 4 2005 Jeff Moyer - 1:4.1.4-8 +- Add in the deferred syslog patch. This fixes a hung automounter issue + related to unsafe calls to syslog in signal handler context. + +* Tue May 3 2005 Jeff Moyer - 1:4.1.4-7 +- I reversed the checking for multimount entries, breaking those configs! + This update puts the code back the way it was before I broke it. + +* Tue Apr 26 2005 Jeff Moyer - 1:4.1.4-6 +- Fix a race between mounting a share and updating the cache in the parent + process. If the mount completed first, the parent would not expire the + stale entry, leaving it first on the list. This causes map updates to not + be recognized (well, worse, they are recognized after the first expire, but + not subsequent ones). Fixes a regression, bug #137026 (rhel3 bug). + +* Fri Apr 15 2005 Chris Feist - 1:4.1.4-5 +- Fixed regression with -browse not taking effect. + +* Wed Apr 13 2005 Jeff Moyer - 1:4.1.4-4 +- Finish up with the merge breakage. +- Temporary fix for the multimount detection code. It seems half-baked. + +* Wed Apr 13 2005 Jeff Moyer - 1:4.1.4-3 +- Fix up the one-auto-master patch. My "improvements" had side-effects. + +* Wed Apr 13 2005 Jeff Moyer - 1:4.1.4-2 +- Import 4.1.4 and merge. + +* Mon Apr 4 2005 Jeff Moyer - 1:4.1.3-123 +- Add in an error case that was omitted in the multi-over patch. +- Update our auto.net to reflect the changes that went into 4.1.4_beta2. + This fixes a problem seen by at least one customer where a malformed entry + appeared first in the multimount list, thus causing the entire multimount + to be ignored. This new auto.net places that entry at the end, purely by + luck, but it fixes the problem in this one case. + +* Thu Mar 31 2005 Jeff Moyer - 1:4.1.3-119 +- Merge in the multi-over patch. This resolves an issue whereby multimounts + (such as those used for /net) could be processed in the wrong order, + resulting in directories not showing up in a multimount tree. The fix + is to process these directories in order, shortest to longer path. + +* Wed Mar 23 2005 Chris Feist - 1:4.1.3-115 +- Fixed regression causing any entries after a wildcard in an + indirect map to be ignored. (bz #151668). +- Fixed regression which caused local hosts to be mount instead + of --bind local directories. (bz #146887) + +* Thu Mar 17 2005 Chris Feist - 1:4.1.3-111 +- Fixed one off bug in the submount-variable-propagation patch. + (bz #143074) +- Fixed a bug in the init script which wouldn't find the -browse + option if it was preceded by another option. (fz #113494) + +* Mon Feb 28 2005 Chris Feist - 1:4.1.3-100 +- When using ldap if auto.master doesn't exist we now check for auto_master. + Addresses bz #130079 +- When using an auto.smb map we now remove the leading ':' from the path which + caused mount to fail in the past. Addresses bz #147492 +- Autofs now checks /etc/nsswitch.conf to determine in what order files & nis + are checked when looking up autofs submount maps which don't specify a + maptype. Addresses IT #57612. + +* Mon Feb 14 2005 Jeff Moyer - 1:4.1.3-99 +- Change Copyright to License in the spec file so it will build. + +* Fri Feb 11 2005 Jeff Moyer - 1:4.1.3-98 +- Program maps can repeat the last character of output. Fix this. + Addresses bz #138606 +- Return first entry when there are duplicate keys in a map. Addresses + bz #140108. +- Propagate custom map variables to submounts. Fixes bz #143074. +- Create a sysconfig variable to control whether we source only one master + map (the way sun does), or source all maps found (which is the default for + backwards compatibility). Addresses bz #143126. +- Revised version of the get_best_mount patch. (#146887) cfeist@redhat.com + The previous patch introduced a regression. Non-replicated mounts would + not have the white space stripped from the entry and the mount would fail. +- Handle comment characters in the middle of the automount line in + /etc/nsswitch.conf. Addresses bz #127457. + +* Wed Feb 2 2005 Chris Feist - 1:4.1.3-94 +- Stop automount from pinging hosts if there is only one host (#146887) + +* Wed Feb 2 2005 Jeff Moyer - 1:4.1.3-90 +- Fix potential double free in cache_release. This bug showed up in a + multi-map setup. Two calls to cache_release would result in a SIGSEGV, + and the automount process would never exit. + +* Mon Jan 24 2005 Chris Feist - 1:4.3-82 +- Fixed documentation so users know that any local mounts override + any other weighted mount. + +* Mon Jan 24 2005 Chris Feist - 1:4.3-80 +- Added a variable to determine if we created the directory or not + so we don't accidently remove a directory that we didn't create when + we stop autofs. (bz #134399) + +* Tue Jan 11 2005 Jeff Moyer - 1:4.1.3-76 +- Fix the large program map patch. + +* Tue Jan 11 2005 Jeff Moyer - 1:4.1.3-75 +- Fix some merging breakages that caused the package not to build. + +* Thu Jan 6 2005 - 1:4.1.3-74 +- Add in the map expiry patch +- Bring in other patches that have been committed to other branches. This + version should now contain all fixes we have to date +- Merge conflicts due to map expiry changes + +* Fri Nov 19 2004 Jeff Moyer - 1:4.1.3-57 +- Pass a socket into clntudp_bufcreate so that we don't use up additional + reserved ports. This patch, along with the socket leak fix, addresses + bz #128966. + +* Wed Nov 17 2004 - 1:4.1.3-56 +- Somehow the -browse patch either didn't get committed or got reverted. + Fixed. + +* Tue Nov 16 2004 Jeff Moyer - 1:4.1.3-55 +- Fix program maps so that they can have gt 4k characters. (Neil Horman) + Addresses bz #138994. +- Add a space after the colon here "Starting automounter:" in init script. + Fixes bz #138513. + +* Mon Nov 15 2004 Jeff Moyer - 1:4.1.3-53 +- Make autofs understand -[no]browse. Addresses fz #113494. + +* Thu Nov 11 2004 Jeff Moyer - 1:4.1.3-48 +- Fix the umount loop device function in the init script. + +* Wed Oct 27 2004 Chris Feist - 1:4.1.3-34 +- Added a patch to fix the automounter failing on ldap maps + when it couldn't get the whole map. (ie. when the search + limit was lower than the number of results) + +* Thu Oct 21 2004 Chris Feist - 1:4.1.3-32 +- Fixed the use of +ypmapname so the maps included with +ypmapname + are used in the correct order. (In the past the '+' entries + were always processed after local entries.) + +* Thu Oct 21 2004 Chris Feist - 1:4.1.3-31 +- Fixed the duplicate map detection code to detect if maps try + to mount on top of existing maps. + +* Wed Oct 20 2004 Chris Feist - 1:4.1.3-29 +- Fixed a problem with backwards compatability. Specifying local + maps without '/etc/' prepended to them now works. (bz #136038) + +* Fri Oct 15 2004 Chris Feist - 1:4.1.3-28 +- Fixed a bug which caused directories to never be unmounted. (bz #134403) + +* Thu Oct 14 2004 Chris Feist - 1:4.1.3-27 +- Fixed an error in the init script which caused duplicate entries to be + displayed when asking for autofs status. + +* Fri Oct 1 2004 Jeff Moyer - 1:4.1.3-22 +- Comment out map expiry (and related) patch for an FC3 build. + +* Thu Sep 23 2004 Jeff Moyer - 1:4.1.3-21 +- Make local options apply to all maps in a multi-map entry. + +* Tue Sep 21 2004 Jeff Moyer - 1:4.1.3-20 +- Merged my and Ian's socket leak fixes into one, smaller patch. Only + partially addresses bz #128966. +- Fix some more echo lines for internationalization. bz #77820 +- Revert the only one auto.master patch until we implement the +auto_master + syntax. Temporarily addresses bz #133055. + +* Thu Sep 2 2004 Jeff Moyer - 1:4.1.3-18 +- Umount loopback filesystems under automount points when stopping the + automounter. +- Uncomment the map expiry patch. +- change a close to an fclose in lookup_file.c + +* Tue Aug 31 2004 Jeff Moyer - 1:4.1.3-17 +- Add patch to support parsing nsswitch.conf to determine map sources. +- Disable this patch, and Ian's map expiry patch for a FC build. + +* Tue Aug 24 2004 Jeff Moyer - 1:4.1.3-16 +- Version 3 of Ian's map expiry changes. + +* Wed Aug 18 2004 Jeff Moyer - 1:4.1.3-15 +- Fix a socket leak in the rpc_subs, causing mounts to fail since we are + running out of port space fairly quickly. + +* Wed Aug 18 2004 Jeff Moyer - 1:4.1.3-14 +- New map expiry patch from Ian. +- Fix a couple signal races. No known problem reports of these, but they + are holes, none-the-less. + +* Tue Aug 10 2004 Jeff Moyer - 1:4.1.3-13 +- Only read one auto.master map (instead of concatenating all found sources). +- Uncomment Ian's experimental mount expiry patch. + +* Fri Aug 6 2004 Jeff Moyer - 1:4.1.3-12 +- Add a sysconfig entry to disable direct map support, and set this to + 1 by default. +- Disable the beta map expiry logic so I can build into a stable distro. +- Add defaults for all of the sysconfig variables to the init script so + we don't trip over user errors (i.e. deleting /etc/sysconfig/autofs). + +* Wed Aug 4 2004 Jeff Moyer - 1:4.1.3-11 +- Add beta map expiry code for wider testing. (Ian Kent) +- Fix check for ghosting option. I forgot to check for it in DAEMONOPTIONS. +- Remove STRIPDASH from /etc/sysconfig/autofs + +* Mon Jul 12 2004 Jeff Moyer - 1:4.1.3-10 +- Add bad chdir patch from Ian Kent. +- Add a typo fix for the mtab lock file. +- Nuke the stripdash patch. It didn't solve a problem. + +* Tue Jun 22 2004 Jeff Moyer - 1:4.1.3-9 +- Bump revison for inclusion in RHEL 3. + +* Mon Jun 21 2004 Jeff Moyer - 1:4.1.3-8 +- Change icmp ping to an rpc ping. (Ian Kent) +- Fix i18n patch + o Remove the extra \" from one echo line. + o Use echo -e if we are going to do a \n in the echo string. + +* Mon Jun 21 2004 Alan Cox +- Fixed i18n bug #107463 + +* Mon Jun 21 2004 Alan Cox +- Fixed i18n bug #107461 + +* Tue Jun 15 2004 Elliot Lee +- rebuilt + +* Sat Jun 5 2004 Jeff Moyer - 1:4.1.3-4 +- Perform an icmp ping request before rpc_pings, since the rpc clnt_create + function has a builtin default timeout of 60 seconds. This could result + in a long delay when a server in a replicated mount setup is down. +- For non-replicated server entries, ping a host before attempting to mount. + (Ian Kent) +- Change to %%configure. +- Put version-release into .version to allow for automount --version to + print exact info. +- Nuke my get-best-mount patch which always uses the long timeout. This + should no longer be needed. +- Put name into changelog entries to make them consistent. Add e:n-v-r + into Florian's entry. +- Stop autofs before uninstalling + +* Sat Jun 05 2004 Florian La Roche - 1:4.1.3-3 +- add a preun script to remove autofs + +* Tue Jun 1 2004 Jeff Moyer - 1:4.1.3-2 +- Incorporate patch from Ian which fixes an infinite loop seen by those + running older versions of the kernel patches (triggered by non-strict mounts + being the default). + +* Tue Jun 1 2004 Jeff Moyer - 1:4.1.3-1 +- Update to upstream 4.1.3. + +* Thu May 6 2004 Jeff Moyer - 1:4.1.2-6 +- The lookup_yp module only dealt with YPERR_KEY, all other errors were + treated as success. As a result, if the ypdomain was not bound, the + subprocess that starts mounts would SIGSEGV. This is now fixed. +- Option parsing in the init script was not precise enough, sometimes matching + filesystem options to one of --ghost, --timeout, --verbose, or --debug. + The option-parsing patch addresses this issue by making the regexp's much + more precise. +- Ian has rolled a third version of the replicated mount fixes. + +* Tue May 4 2004 Jeff Moyer - 1:4.1.2-5 +- Ian has a new fix for replicated server and multi-mounts. Updated the + patch for testing. Still beta. (Ian Kent) + +* Mon May 3 2004 Jeff Moyer - 1:4.1.2-4 +- Fix broken multi-mounts. test patch. (Ian Kent) + +* Tue Apr 20 2004 Jeff Moyer - 1:4.1.2-3 +- Fix a call to spawnl which forgot to specify a lock file. (nphilipp) + +* Wed Apr 14 2004 - 1:4.1.2-2 +- Pass --libdir= to ./configure so we get this right on 64 bit platforms that + support backwards compat. + +* Wed Apr 14 2004 Jeff Moyer - 1:4.1.2-1 +- Change hard-coded paths in the spec file to the %%{_xxx} variety. +- Update to upstream 4.1.2. +- Add a STRIPDASH option to /etc/sysconfig/autofs which allows for + compatibility with the Sun automounter options specification syntax in + auto.master. See /etc/sysconfig/autofs for more information. Addresses + bug 113950. + +* Tue Apr 6 2004 Jeff Moyer - 1:4.1.1-6 +- Add the /etc/sysconfig/autofs file, and supporting infrastructure in + the init script. +- Add support for UNDERSCORE_TO_DOT for those who want it. +- We no longer own /net. Move it to the filesystem package. + +* Tue Mar 30 2004 Jeff Moyer - 1:4.1.1-5 +- Clarify documentation on direct maps. +- Send automount daemons a HUP signal during reload. This tells them to + re-read maps (otherwise they use a cached version. Patch from the autofs + maintainer. + +* Mon Mar 22 2004 Jeff Moyer - 1:4.1.1-4 +- Fix init script to print out failures where appropriate. +- Build the automount daemon as a PIE. + +* Thu Mar 18 2004 Jeff Moyer - 1:4.1.1-3 +- Fix bug in get_best_mount, whereby if there is only one option, we + choose nothing. This is primarily due to the fact that we pass 0 in to + the get_best_mount function for the long timeout parameter. So, we + timeout trying to contact our first and only server, and never retry. + +* Thu Mar 18 2004 Jeff Moyer - 1:4.1.1-2 +- Prevent startup if a mountpoint is already mounted. + +* Thu Mar 18 2004 Jeff Moyer - 1:4.1.1-1 +- Update to 4.1.1, as it fixes problems with wildcards that people are + seeing quite a bit. + +* Wed Mar 17 2004 Jeff Moyer - 1:4.1.0-8 +- Fix ldap init code to parse server name and options correctly. + +* Tue Mar 16 2004 Jeff Moyer - 1:4.1.0-7 +- Moved the freeing of ap.path to cleanup_exit, as we would otherwise + reference an already-freed variable. + +* Mon Mar 15 2004 Jeff Moyer - 1:4.1.0-6 +- add %%config(noreplace) for auto.* config files. + +* Wed Mar 10 2004 Jeff Moyer 1:4.1.0-5 +- make the init script only recognize redhat systems. Nalin seems to remember + some arcane build system error that can be caused if we don't do this. + +* Wed Mar 10 2004 Jeff Moyer 1:4.1.0-4 +- comment out /net and /misc from the default auto.master. /net is important + since in a default shipping install, we can neatly co-exist with amd. + +* Wed Mar 10 2004 Jeff Moyer 1:4.1.0-3 +- Ported forward Red Hat's patches from 3.1.7 that were not already present + in 4.1.0. +- Moving autofs from version 3.1.7 to 4.1.0 + +* Mon Sep 29 2003 Ian Kent +- Added work around for O(1) patch oddity. + +* Sat Aug 16 2003 Ian Kent +- Fixed tree mounts. +- Corrected transciption error in autofs4-2.4.18 kernel module + +* Sun Aug 10 2003 Ian Kent +- Checked and merged most of the RedHat v3 patches +- Fixed kernel module handling wu-ftpd login problem (again) + +* Thu Aug 7 2003 Ian Kent +- Removed ineffective lock stuff +- Added -n to bind mount to prevent mtab update error +- Added retry to autofs umount to clean matb after fail +- Redirected messages from above to debug log and added info message +- Fixed autofs4 module reentrancy, pwd and chroot handling + +* Wed Jul 30 2003 Ian Kent +- Fixed autofs4 ghosting patch for 2.4.19 and above (again) +- Fixed autofs directory removal on failure of autofs mount +- Fixed lock file wait function overlapping calls to (u)mount + +* Sun Jul 27 2003 Ian Kent +- Implemented LDAP direct map handling for nisMap and automountMap schema +- Fixed autofs4 ghosting patch for 2.4.19 and above (again) +- Added locking to fix overlapping internal calls to (u)mount +- Added wait for mtab~ to improve tolerance of overlapping external calls to (u)mount +- Fixed ghosted directory removal after failed mount attempt + +* Wed May 28 2003 Ian Kent +- Cleaned up an restructured my added code +- Corrected ghosting problem with 2.4.19 and above +- Added autofs4 ghosting patch for 2.4.19 and above +- Implemented HUP signal to force update of ghosted maps + +* Sat Mar 23 2002 Ian Kent +- Add patch to implement directory ghosting and direct mounts +- Add patch to for autofs4 module to support ghosting + +* Wed Jan 17 2001 Nalin Dahyabhai +- use -fPIC instead of -fpic for modules and honor other RPM_OPT_FLAGS + +* Tue Feb 29 2000 Nalin Dahyabhai +- enable hesiod support over libbind + +* Fri Aug 13 1999 Cristian Gafton +- add patch from rth to avoid an infinite loop