Blame SOURCES/autofs-5.1.4-fix-update_negative_cache-map-source-usage.patch

d5dcad
autofs-5.1.4 - fix update_negative_cache() map source usage
d5dcad
d5dcad
From: Ian Kent <raven@themaw.net>
d5dcad
d5dcad
File map sources can be either plain text or executable.
d5dcad
d5dcad
When the map path is specified without a type (eg. when a
d5dcad
full path is used) an instance map source is used and the
d5dcad
original map is left unchanged.
d5dcad
d5dcad
But update_negative_cache() fails to take this into account
d5dcad
causing it to update the wrong map cache.
d5dcad
d5dcad
When a map reload is done the map entry appears to not exist
d5dcad
so the new map entry is added.
d5dcad
d5dcad
This could go unnoticed except that, after a map read, the
d5dcad
map entry cache cleans stale map entries and the existence
d5dcad
of this negative entry causes the new map entry to be deleted
d5dcad
and map lookups continue to fail.
d5dcad
d5dcad
In hindsite the use of an instance map source for this is
d5dcad
probably uneccessary but changing it will be risky so, for
d5dcad
now, just make update_negative_cache() use the correct map.
d5dcad
d5dcad
Signed-off-by: Ian Kent <raven@themaw.net>
d5dcad
---
d5dcad
 CHANGELOG       |    1 +
d5dcad
 daemon/lookup.c |   38 ++++++++++++++++++++++++++++++++++++--
d5dcad
 2 files changed, 37 insertions(+), 2 deletions(-)
d5dcad
d5dcad
--- autofs-5.1.4.orig/CHANGELOG
d5dcad
+++ autofs-5.1.4/CHANGELOG
d5dcad
@@ -28,6 +28,7 @@ xx/xx/2018 autofs-5.1.5
d5dcad
 - add-man page note about extra slashes in paths.
d5dcad
 - covarity fixes.
d5dcad
 - fix program usage message.
d5dcad
+- fix update_negative_cache() map source usage.
d5dcad
 
d5dcad
 19/12/2017 autofs-5.1.4
d5dcad
 - fix spec file url.
d5dcad
--- autofs-5.1.4.orig/daemon/lookup.c
d5dcad
+++ autofs-5.1.4/daemon/lookup.c
d5dcad
@@ -1100,6 +1100,37 @@ static enum nsswitch_status lookup_map_n
d5dcad
 	return result;
d5dcad
 }
d5dcad
 
d5dcad
+static struct map_source *lookup_get_map_source(struct master_mapent *entry)
d5dcad
+{
d5dcad
+	struct map_source *map = entry->maps;
d5dcad
+	struct stat st;
d5dcad
+	char *type;
d5dcad
+
d5dcad
+	if (map->type || *map->argv[0] != '/')
d5dcad
+		return map;
d5dcad
+
d5dcad
+	if (*(map->argv[0] + 1) == '/')
d5dcad
+		return map;
d5dcad
+
d5dcad
+	if (stat(map->argv[0], &st) == -1)
d5dcad
+		return NULL;
d5dcad
+
d5dcad
+	if (!S_ISREG(st.st_mode))
d5dcad
+		return NULL;
d5dcad
+
d5dcad
+	if (st.st_mode & __S_IEXEC)
d5dcad
+		type = "program";
d5dcad
+	else
d5dcad
+		type = "file";
d5dcad
+
d5dcad
+	/* This is a file source with a path starting with "/".
d5dcad
+	 * But file maps can be either plain text or executable
d5dcad
+	 * so they use a map instance and the actual map source
d5dcad
+	 * remains untouched.
d5dcad
+	 */
d5dcad
+	return master_find_source_instance(map, type, map->format, 0, NULL);
d5dcad
+}
d5dcad
+
d5dcad
 static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name)
d5dcad
 {
d5dcad
 	struct master_mapent *entry = ap->entry;
d5dcad
@@ -1133,11 +1164,14 @@ static void update_negative_cache(struct
d5dcad
 			logmsg("key \"%s\" not found in map source(s).", name);
d5dcad
 		}
d5dcad
 
d5dcad
-		/* Doesn't exist in any source, just add it somewhere */
d5dcad
+		/* Doesn't exist in any source, just add it somewhere.
d5dcad
+		 * Also take care to use the same map source used by
d5dcad
+		 * map reads and key lookups for the update.
d5dcad
+		 */
d5dcad
 		if (source)
d5dcad
 			map = source;
d5dcad
 		else
d5dcad
-			map = entry->maps;
d5dcad
+			map = lookup_get_map_source(entry);
d5dcad
 		if (map) {
d5dcad
 			time_t now = monotonic_time(NULL);
d5dcad
 			int rv = CHE_FAIL;