You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
103 lines
3.0 KiB
103 lines
3.0 KiB
6 years ago
|
autofs-5.1.4 - fix update_negative_cache() map source usage
|
||
|
|
||
|
From: Ian Kent <raven@themaw.net>
|
||
|
|
||
|
File map sources can be either plain text or executable.
|
||
|
|
||
|
When the map path is specified without a type (eg. when a
|
||
|
full path is used) an instance map source is used and the
|
||
|
original map is left unchanged.
|
||
|
|
||
|
But update_negative_cache() fails to take this into account
|
||
|
causing it to update the wrong map cache.
|
||
|
|
||
|
When a map reload is done the map entry appears to not exist
|
||
|
so the new map entry is added.
|
||
|
|
||
|
This could go unnoticed except that, after a map read, the
|
||
|
map entry cache cleans stale map entries and the existence
|
||
|
of this negative entry causes the new map entry to be deleted
|
||
|
and map lookups continue to fail.
|
||
|
|
||
|
In hindsite the use of an instance map source for this is
|
||
|
probably uneccessary but changing it will be risky so, for
|
||
|
now, just make update_negative_cache() use the correct map.
|
||
|
|
||
|
Signed-off-by: Ian Kent <raven@themaw.net>
|
||
|
---
|
||
|
CHANGELOG | 1 +
|
||
|
daemon/lookup.c | 38 ++++++++++++++++++++++++++++++++++++--
|
||
|
2 files changed, 37 insertions(+), 2 deletions(-)
|
||
|
|
||
|
diff --git a/CHANGELOG b/CHANGELOG
|
||
|
index c39aa0e5..70e043ee 100644
|
||
|
--- a/CHANGELOG
|
||
|
+++ b/CHANGELOG
|
||
|
@@ -31,6 +31,7 @@ xx/xx/2018 autofs-5.1.5
|
||
|
- use defines for expire type.
|
||
|
- enable SIGUSR2 handling in rpm spec file.
|
||
|
- fix age setting at startup.
|
||
|
+- fix update_negative_cache() map source usage.
|
||
|
|
||
|
19/12/2017 autofs-5.1.4
|
||
|
- fix spec file url.
|
||
|
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
||
|
index 6a722b3b..418f01cb 100644
|
||
|
--- a/daemon/lookup.c
|
||
|
+++ b/daemon/lookup.c
|
||
|
@@ -1100,6 +1100,37 @@ static enum nsswitch_status lookup_map_name(struct nss_source *this,
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
+static struct map_source *lookup_get_map_source(struct master_mapent *entry)
|
||
|
+{
|
||
|
+ struct map_source *map = entry->maps;
|
||
|
+ struct stat st;
|
||
|
+ char *type;
|
||
|
+
|
||
|
+ if (map->type || *map->argv[0] != '/')
|
||
|
+ return map;
|
||
|
+
|
||
|
+ if (*(map->argv[0] + 1) == '/')
|
||
|
+ return map;
|
||
|
+
|
||
|
+ if (stat(map->argv[0], &st) == -1)
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ if (!S_ISREG(st.st_mode))
|
||
|
+ return NULL;
|
||
|
+
|
||
|
+ if (st.st_mode & __S_IEXEC)
|
||
|
+ type = "program";
|
||
|
+ else
|
||
|
+ type = "file";
|
||
|
+
|
||
|
+ /* This is a file source with a path starting with "/".
|
||
|
+ * But file maps can be either plain text or executable
|
||
|
+ * so they use a map instance and the actual map source
|
||
|
+ * remains untouched.
|
||
|
+ */
|
||
|
+ return master_find_source_instance(map, type, map->format, 0, NULL);
|
||
|
+}
|
||
|
+
|
||
|
static void update_negative_cache(struct autofs_point *ap, struct map_source *source, const char *name)
|
||
|
{
|
||
|
struct master_mapent *entry = ap->entry;
|
||
|
@@ -1133,11 +1164,14 @@ static void update_negative_cache(struct autofs_point *ap, struct map_source *so
|
||
|
logmsg("key \"%s\" not found in map source(s).", name);
|
||
|
}
|
||
|
|
||
|
- /* Doesn't exist in any source, just add it somewhere */
|
||
|
+ /* Doesn't exist in any source, just add it somewhere.
|
||
|
+ * Also take care to use the same map source used by
|
||
|
+ * map reads and key lookups for the update.
|
||
|
+ */
|
||
|
if (source)
|
||
|
map = source;
|
||
|
else
|
||
|
- map = entry->maps;
|
||
|
+ map = lookup_get_map_source(entry);
|
||
|
if (map) {
|
||
|
time_t now = monotonic_time(NULL);
|
||
|
int rv = CHE_FAIL;
|