+++ /dev/null
-diff -Nurp autofs-4.1.4.orig/lib/cache.c autofs-4.1.4/lib/cache.c
---- autofs-4.1.4.orig/lib/cache.c 2005-02-06 14:00:53.000000000 +0800
-+++ autofs-4.1.4/lib/cache.c 2005-05-07 17:29:21.000000000 +0800
-@@ -337,8 +337,10 @@ void cache_clean(const char *root, time_
- if (!path)
- return;
-
-- if (is_mounted(_PATH_MOUNTED, path))
-+ if (is_mounted(_PATH_MOUNTED, path)) {
-+ free(path);
- continue;
-+ }
-
- if (me->age < age) {
- mapent_hash[i] = me->next;
-diff -Nurp autofs-4.1.4.orig/modules/lookup_file.c autofs-4.1.4/modules/lookup_file.c
---- autofs-4.1.4.orig/modules/lookup_file.c 2005-04-06 23:14:23.000000000 +0800
-+++ autofs-4.1.4/modules/lookup_file.c 2005-05-07 17:27:30.000000000 +0800
-@@ -157,6 +157,10 @@ static int read_one(FILE *f, char *key,
- break;
-
- case st_compare:
-+ if (kptr - key > KEY_MAX_LEN) {
-+ state = st_badent;
-+ break;
-+ }
- if (ch == '\n')
- state = st_begin;
- else if (isspace(ch) && !escape) {
-diff -Nurp autofs-4.1.4.orig/modules/parse_sun.c autofs-4.1.4/modules/parse_sun.c
---- autofs-4.1.4.orig/modules/parse_sun.c 2005-05-07 17:39:44.000000000 +0800
-+++ autofs-4.1.4/modules/parse_sun.c 2005-05-07 17:35:27.000000000 +0800
-@@ -680,6 +680,10 @@ static int sun_mount(const char *root, c
- "mounting root %s, mountpoint %s, what %s, fstype %s, options %s\n",
- root, mountpoint, what, fstype, options);
-
-+ /* A malformed entry of the form key /xyz will trigger this case */
-+ if (!what || *what == '\0')
-+ return 1;
-+
- if (!strcmp(fstype, "nfs")) {
- rv = mount_nfs->mount_mount(root, mountpoint, strlen(mountpoint),
- what, fstype, options, mount_nfs->context);
-@@ -695,6 +699,18 @@ static int sun_mount(const char *root, c
- return rv;
- }
-
-+static int key_exists(struct multi_mnt *list, char *path, int pathlen)
-+{
-+ struct multi_mnt *mmptr = list;
-+
-+ while (mmptr && pathlen == strlen(mmptr->path)) {
-+ if (!strncmp(mmptr->path, path, pathlen))
-+ return 1;
-+ mmptr = mmptr->next;
-+ }
-+ return 0;
-+}
-+
- /*
- * Build list of mounts in shortest -> longest order.
- * Pass in list head and return list head.
-@@ -725,6 +741,12 @@ struct multi_mnt *multi_add_list(struct
- mmptr = mmptr->next;
- }
-
-+ /* if a multimount entry has duplicate keys, it is invalid */
-+ if (key_exists(mmptr, path, plen)) {
-+ free(new);
-+ return NULL;
-+ }
-+
- if (old)
- old->next = new;
- new->next = mmptr;
+++ /dev/null
-diff -Nurp autofs-4.1.4.orig/modules/parse_sun.c autofs-4.1.4/modules/parse_sun.c
---- autofs-4.1.4.orig/modules/parse_sun.c 2005-04-05 20:42:42.000000000 +0800
-+++ autofs-4.1.4/modules/parse_sun.c 2005-04-25 10:00:13.000000000 +0800
-@@ -766,7 +766,16 @@ static int check_is_multi(const char *ma
- {
- const char *p = (char *) mapent;
- int multi = 0;
-- int first_chunk = 0;
-+ int not_first_chunk = 0;
-+
-+ if (!p) {
-+ crit("check_is_multi: unexpected NULL map entry pointer");
-+ return 0;
-+ }
-+
-+ /* If first character is "/" it's a multi-mount */
-+ if (*p == '/')
-+ return 1;
-
- while (*p) {
- p = skipspace(p);
-@@ -779,7 +788,7 @@ static int check_is_multi(const char *ma
- * path that begins with '/' indicates a mutil-mount
- * entry.
- */
-- if (first_chunk) {
-+ if (not_first_chunk) {
- if (*p == '/' || *p == '-') {
- multi = 1;
- break;
-@@ -796,7 +805,7 @@ static int check_is_multi(const char *ma
- * after which it's a multi mount.
- */
- p += chunklen(p, check_colon(p));
-- first_chunk++;
-+ not_first_chunk++;
- }
-
- return multi;
-@@ -883,7 +892,12 @@ int parse_mount(const char *root, const
- return 1;
- }
-
-- path = dequote(p, l = chunklen(p, 0));
-+ if (*p != '/') {
-+ l = 0;
-+ path = dequote("/", 1);
-+ } else
-+ path = dequote(p, l = chunklen(p, 0));
-+
- if (!path) {
- error(MODPREFIX "out of memory");
- free(myoptions);
+++ /dev/null
---- autofs-4.1.4/daemon/automount.c.no-unlink 2005-07-11 13:28:57.000000000 -0500
-+++ autofs-4.1.4/daemon/automount.c 2005-07-11 13:50:46.000000000 -0500
-@@ -216,16 +216,38 @@ static int walk_tree(const char *base, i
- static int rm_unwanted_fn(const char *file, const struct stat *st, int when, void *arg)
- {
- int rmsymlink = *(int *) arg;
-+ struct stat newst;
-
- if (when == 0) {
- if (st->st_dev != ap.dev)
- return 0;
-- } else {
-- info("rm_unwanted: %s\n", file);
-- if (S_ISDIR(st->st_mode))
-- rmdir(file);
-- else if (!S_ISLNK(st->st_mode) || rmsymlink)
-- unlink(file);
-+ return 1;
-+ }
-+
-+ if (lstat(file, &newst)) {
-+ crit ("rm_unwanted: unable to stat file, possible race "
-+ "condition.");
-+ return 0;
-+ }
-+
-+ if (newst.st_dev != ap.dev) {
-+ crit ("rm_unwanted: file %s has the wrong device, possible "
-+ "race condition.",file);
-+ return 0;
-+ }
-+
-+ if (S_ISDIR(newst.st_mode)) {
-+ if (rmdir(file)) {
-+ info ("rm_unwanted: unable to remove directory"
-+ " %s", file);
-+ return 0;
-+ }
-+ } else if (S_ISREG(newst.st_mode)) {
-+ crit ("rm_unwanted: attempting to remove files from a mounted "
-+ "directory.");
-+ return 0;
-+ } else if (S_ISLNK(newst.st_mode) && rmsymlink) {
-+ unlink(file);
- }
-
- return 1;
+++ /dev/null
-diff -Nurp autofs-4.1.4.orig/modules/mount_nfs.c autofs-4.1.4/modules/mount_nfs.c
---- autofs-4.1.4.orig/modules/mount_nfs.c 2005-04-25 10:55:27.000000000 +0800
-+++ autofs-4.1.4/modules/mount_nfs.c 2005-04-25 10:56:15.000000000 +0800
-@@ -31,6 +31,7 @@
- #include <netinet/in.h>
- #include <linux/nfs.h>
- #include <linux/nfs2.h>
-+#include <ctype.h>
-
- #define MODULE_MOUNT
- #include "automount.h"
-@@ -105,28 +106,117 @@ int is_local_addr(const char *host, cons
-
- return 1;
- }
-+
-+/*
-+ * If the entry doesn't contain a ',' or doesn't contain more than
-+ * one ':' then @what is not a replicated server entry.
-+ */
-+static int inline is_replicated_entry(char *what)
-+{
-+ return strchr(what, ',') ||
-+ (strchr(what, ':') != strrchr(what, ':'));
-+}
-+
-+/*
-+ * Check to see if the 'host:path' or 'host' is on the local machine
-+ * Returns < 0 if there is a host lookup problem, otherwise returns 0
-+ * if it's not a local mount, and returns > 0 if it is a local mount.
-+ */
-+int is_local_mount(const char *hostpath)
-+{
-+ struct hostent *he;
-+ char **haddr;
-+ char *delim;
-+ char *hostname;
-+ int hostnamelen;
-+ int local = 0;
-+
-+ debug(MODPREFIX "is_local_mount: %s", hostpath);
-+ delim = strpbrk(hostpath,":");
-+
-+ if (delim)
-+ hostnamelen = delim - hostpath;
-+ else
-+ hostnamelen = strlen(hostpath);
-+
-+ hostname = malloc(hostnamelen+1);
-+ strncpy(hostname, hostpath, hostnamelen);
-+ hostname[hostnamelen] = '\0';
-+ he = gethostbyname(hostname);
-+ if (!he) {
-+ error(MODPREFIX "host %s: lookup failure", hostname);
-+ return -1;
-+ }
-+
-+ for (haddr = he->h_addr_list; *haddr; haddr++) {
-+ local = is_local_addr(hostname, *haddr, he->h_length);
-+ if (local < 0)
-+ return local;
-+ if (local) {
-+ debug(MODPREFIX "host %s: is localhost",
-+ hostname);
-+ return local;
-+ }
-+ }
-+ return 0;
-+}
-+
- /*
- * Given a mount string, return (in the same string) the
-- * best mount to use based on weight/locality/rpctime
-+ * best mount to use based on locality/weight/rpctime.
-+ *
-+ * If longtimeout is set to 0 then we only do 100 ms pings to hosts. In
-+ * the event that this fails, we call ourself recursively with the
-+ * longtimeout option set to 1. In this case we ping for up to 10s and
-+ * skip logic for detecting if a localhost has been passed. (if a local
-+ * host had been passed, we would have returned that mount as the best
-+ * mount. The skipping of local maps in this case is an optimization).
-+ *
- * - return -1 and what = '\0' on error,
- * 1 and what = local mount path if local bind,
- * else 0 and what = remote mount path
- */
--int get_best_mount(char *what, const char *original, int longtimeout, int skiplocal)
-+int get_best_mount(char *what, const char *original, int longtimeout)
- {
- char *p = what;
- char *winner = NULL;
- int winner_weight = INT_MAX, local = 0;
- double winner_time = 0;
-- char *delim;
-+ char *delim, *pstrip;
- int sec = (longtimeout) ? 10 : 0;
- int micros = (longtimeout) ? 0 : 100000;
-+ int skiplocal = longtimeout; /* clearly local is not available */
-
- if (!p) {
- *what = '\0';
- return -1;
- }
-
-+ /*
-+ * If only one mountpoint has been passed in, we don't need to
-+ * do anything except strip whitespace from the end of the string.
-+ */
-+ if (!is_replicated_entry(p)) {
-+ for (pstrip = p+strlen(p) - 1; pstrip >= p; pstrip--)
-+ if (isspace(*pstrip))
-+ *pstrip = '\0';
-+
-+ /* Check if the host is the localhost */
-+ if (is_local_mount(p) > 0) {
-+ debug(MODPREFIX "host %s: is localhost", p);
-+
-+ /* Strip off hostname and ':' */
-+ delim = strchr(p,':');
-+ while (delim && *delim != '\0') {
-+ delim++;
-+ *what = *delim;
-+ what++;
-+ }
-+ return 1;
-+ }
-+ return 0;
-+ }
-+
- while (p && *p) {
- char *next;
- unsigned int ping_stat = 0;
-@@ -171,37 +261,17 @@ int get_best_mount(char *what, const cha
- /* p points to a server, "next is our next parse point */
- if (!skiplocal) {
- /* Check if it's localhost */
-- struct hostent *he;
-- char **haddr;
--
-- he = gethostbyname(p);
-- if (!he) {
-- error(MODPREFIX "host %s: lookup failure", p);
-- p = next;
-- continue;
-- }
--
-- /* Check each host in round robin list */
-- for (haddr = he->h_addr_list; *haddr; haddr++) {
-- local = is_local_addr(p, *haddr, he->h_length);
--
-- if (local < 0)
-- continue;
--
-- if (local) {
-- winner = p;
-- break;
-- }
-- }
--
-+ local = is_local_mount(p);
- if (local < 0) {
- local = 0;
- p = next;
- continue;
- }
-
-- if (local)
-+ if (local) {
-+ winner = p;
- break;
-+ }
- }
-
- /* ping each (or the) entry to see if it's alive. */
-@@ -214,6 +284,7 @@ int get_best_mount(char *what, const cha
- /* First unweighted or only host is alive so set winner */
- if (!winner) {
- winner = p;
-+ winner_time = 1;
- /* No more to check, return it */
- if (!next || !*next)
- break;
-@@ -256,7 +327,7 @@ int get_best_mount(char *what, const cha
- */
- if (!local && winner_weight == INT_MAX) {
- /* We had more than one contender and none responded in time */
-- if (winner_time != 0 && winner_time > 500) {
-+ if (winner_time == 0 || winner_time > 500) {
- /* We've already tried a longer timeout */
- if (!longtimeout) {
- /* Reset string and try again */
-@@ -267,16 +338,14 @@ int get_best_mount(char *what, const cha
- "retrying with longer timeout",
- original);
-
-- return get_best_mount(what, original, 1, 1);
-+ return get_best_mount(what, original, 1);
- }
- }
- }
-
-- /* No winner found so bail */
-- if (!winner) {
-- *what = '\0';
-- return 0;
-- }
-+ /* No winner found so return first */
-+ if (!winner)
-+ winner = what;
-
- /*
- * We now have our winner, copy it to the front of the string,
-@@ -395,7 +464,7 @@ int mount_mount(const char *root, const
- /* No colon, take this as a bind (local) entry */
- local = 1;
- } else if (!nosymlink) {
-- local = get_best_mount(whatstr, what, 0, 0);
-+ local = get_best_mount(whatstr, what, 0);
- if (!*whatstr) {
- warn(MODPREFIX "no host elected");
- return 1;