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

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