- 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.
This commit is contained in:
parent
ad62197f9f
commit
c5187b0dbf
226
autofs-5.0.4-always-read-file-maps.patch
Normal file
226
autofs-5.0.4-always-read-file-maps.patch
Normal file
@ -0,0 +1,226 @@
|
||||
autofs-5.0.4 - always read file maps
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
autofs tries to not load an entire map into the internal cache unless it
|
||||
has to. For maps that do get loaded into the cache it relies on checks to
|
||||
work out if a map is up to date in order to trigger a map read. This is
|
||||
fine for maps that can do direct key lookups but file maps need to do a
|
||||
linear search through the file when locating an entry for a key. For large
|
||||
maps this can be a huge overhead. This patch make autofs always load file
|
||||
based maps at start and makes use of the map file mtime to discover if the
|
||||
cache needs to be refreshed.
|
||||
---
|
||||
|
||||
CHANGELOG | 1 +
|
||||
daemon/lookup.c | 9 +++++--
|
||||
modules/lookup_file.c | 65 ++++++++++++++++---------------------------------
|
||||
3 files changed, 28 insertions(+), 47 deletions(-)
|
||||
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index d4dd70b..afd1335 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -14,6 +14,7 @@
|
||||
- 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.
|
||||
|
||||
4/11/2008 autofs-5.0.4
|
||||
-----------------------
|
||||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
||||
index 741d846..e034348 100644
|
||||
--- a/daemon/lookup.c
|
||||
+++ b/daemon/lookup.c
|
||||
@@ -283,10 +283,13 @@ static int do_read_map(struct autofs_point *ap, struct map_source *map, time_t a
|
||||
* for the fail cases to function correctly and to cache the
|
||||
* lookup handle.
|
||||
*
|
||||
- * We always need to whole map for direct mounts in order to
|
||||
- * mount the triggers.
|
||||
+ * We always need to read the whole map for direct mounts in
|
||||
+ * order to mount the triggers. We also want to read the whole
|
||||
+ * map if it's a file map to avoid potentially lengthy linear
|
||||
+ * file scanning.
|
||||
*/
|
||||
- if (!(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
|
||||
+ if (strcmp(map->type, "file") &&
|
||||
+ !(ap->flags & MOUNT_FLAG_GHOST) && ap->type != LKP_DIRECT)
|
||||
return NSS_STATUS_SUCCESS;
|
||||
|
||||
if (!map->stale)
|
||||
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
|
||||
index 95b9f6f..aafeb8b 100644
|
||||
--- a/modules/lookup_file.c
|
||||
+++ b/modules/lookup_file.c
|
||||
@@ -44,7 +44,6 @@ typedef enum { esc_none, esc_char, esc_val, esc_all } ESCAPES;
|
||||
|
||||
struct lookup_context {
|
||||
const char *mapname;
|
||||
- time_t mtime;
|
||||
struct parse_mod *parse;
|
||||
};
|
||||
|
||||
@@ -54,7 +53,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
||||
{
|
||||
struct lookup_context *ctxt;
|
||||
char buf[MAX_ERR_BUF];
|
||||
- struct stat st;
|
||||
|
||||
*context = NULL;
|
||||
|
||||
@@ -87,15 +85,6 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
||||
return 1;
|
||||
}
|
||||
|
||||
- if (stat(ctxt->mapname, &st)) {
|
||||
- free(ctxt);
|
||||
- logmsg(MODPREFIX "file map %s, could not stat",
|
||||
- argv[0]);
|
||||
- return 1;
|
||||
- }
|
||||
-
|
||||
- ctxt->mtime = st.st_mtime;
|
||||
-
|
||||
if (!mapfmt)
|
||||
mapfmt = MAPFMT_DEFAULT;
|
||||
|
||||
@@ -391,9 +380,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
||||
int blen;
|
||||
char *path;
|
||||
char *ent;
|
||||
- struct stat st;
|
||||
FILE *f;
|
||||
- int fd;
|
||||
unsigned int path_len, ent_len;
|
||||
int entry, cur_state;
|
||||
|
||||
@@ -428,8 +415,6 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
- fd = fileno(f);
|
||||
-
|
||||
while(1) {
|
||||
entry = read_one(logopt, f, path, &path_len, ent, &ent_len);
|
||||
if (!entry) {
|
||||
@@ -504,13 +489,6 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
||||
break;
|
||||
}
|
||||
|
||||
- if (fstat(fd, &st)) {
|
||||
- crit(logopt, MODPREFIX "file map %s, could not stat",
|
||||
- ctxt->mapname);
|
||||
- return NSS_STATUS_UNAVAIL;
|
||||
- }
|
||||
- ctxt->mtime = st.st_mtime;
|
||||
-
|
||||
fclose(f);
|
||||
|
||||
return NSS_STATUS_SUCCESS;
|
||||
@@ -642,9 +620,7 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
||||
struct mapent_cache *mc;
|
||||
char *key;
|
||||
char *mapent;
|
||||
- struct stat st;
|
||||
FILE *f;
|
||||
- int fd;
|
||||
unsigned int k_len, m_len;
|
||||
int entry;
|
||||
|
||||
@@ -684,8 +660,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
|
||||
- fd = fileno(f);
|
||||
-
|
||||
while(1) {
|
||||
entry = read_one(ap->logopt, f, key, &k_len, mapent, &m_len);
|
||||
if (!entry) {
|
||||
@@ -748,13 +722,6 @@ int lookup_read_map(struct autofs_point *ap, time_t age, void *context)
|
||||
break;
|
||||
}
|
||||
|
||||
- if (fstat(fd, &st)) {
|
||||
- crit(ap->logopt,
|
||||
- MODPREFIX "file map %s, could not stat",
|
||||
- ctxt->mapname);
|
||||
- return NSS_STATUS_UNAVAIL;
|
||||
- }
|
||||
- ctxt->mtime = st.st_mtime;
|
||||
source->age = age;
|
||||
|
||||
fclose(f);
|
||||
@@ -951,9 +918,6 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
if (ret == CHE_FAIL)
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
|
||||
- if (ret & CHE_UPDATED)
|
||||
- source->stale = 1;
|
||||
-
|
||||
pthread_cleanup_push(cache_lock_cleanup, mc);
|
||||
cache_writelock(mc);
|
||||
exists = cache_lookup_distinct(mc, key);
|
||||
@@ -963,7 +927,6 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
free(exists->mapent);
|
||||
exists->mapent = NULL;
|
||||
exists->status = 0;
|
||||
- source->stale = 1;
|
||||
}
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
@@ -985,14 +948,8 @@ static int check_map_indirect(struct autofs_point *ap,
|
||||
we = cache_lookup_distinct(mc, "*");
|
||||
if (we) {
|
||||
/* Wildcard entry existed and is now gone */
|
||||
- if (we->source == source && (wild & CHE_MISSING)) {
|
||||
+ if (we->source == source && (wild & CHE_MISSING))
|
||||
cache_delete(mc, "*");
|
||||
- source->stale = 1;
|
||||
- }
|
||||
- } else {
|
||||
- /* Wildcard not in map but now is */
|
||||
- if (wild & (CHE_OK | CHE_UPDATED))
|
||||
- source->stale = 1;
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
|
||||
@@ -1062,9 +1019,28 @@ 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;
|
||||
|
||||
+ /*
|
||||
+ * 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;
|
||||
+ }
|
||||
+
|
||||
cache_readlock(mc);
|
||||
+ me = cache_lookup_first(mc);
|
||||
+ if (me && st.st_mtime <= me->age)
|
||||
+ goto do_cache_lookup;
|
||||
+ else
|
||||
+ source->stale = 1;
|
||||
+
|
||||
me = cache_lookup_distinct(mc, key);
|
||||
if (me && me->multi)
|
||||
lkp_key = strdup(me->multi->key);
|
||||
@@ -1088,6 +1064,7 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
||||
}
|
||||
|
||||
cache_readlock(mc);
|
||||
+do_cache_lookup:
|
||||
me = cache_lookup(mc, key);
|
||||
/* Stale mapent => check for entry in alternate source or wildcard */
|
||||
if (me && !me->mapent) {
|
552
autofs-5.0.4-code-analysis-corrections.patch
Normal file
552
autofs-5.0.4-code-analysis-corrections.patch
Normal file
@ -0,0 +1,552 @@
|
||||
autofs-5.0.4 - code analysis corrections
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Several mistakes have been reported by Paul Wankadia <junyer@google.com>:
|
||||
- a malloc(3) allocation return was not being checked in make_fullpath().
|
||||
- a double free and a use after free was identified in lookup_prune_cache().
|
||||
- off-by-one buffer overflow in lib/macros.c:macro_parse_globalvar().
|
||||
- several potential buffer overflows in modules/parse_hesiod.c.
|
||||
- double free in daemon/indirect.c:do_mount_autofs_indirect().
|
||||
- bogus struct name used for sizeof in lib/cache.c:cache_init() and
|
||||
lib/cache.c:cache_init_null_cache().
|
||||
- in daemon/direct.c:handle_packet_expire_direct master_unlock_mutex() not
|
||||
needed and mutexes not unlocked for file descriptor fail case.
|
||||
- in modules/lookup_multi.c:lookup_init() struct module_info array not
|
||||
checked before free for allocation failure case.
|
||||
- in modules/lookup_program.c:lookup_mount() mapent not freed on cache update failure.
|
||||
- in modules/mount_nfs.c allocation of mount location not checked.
|
||||
- in modules/parse_sun.c:parse_mapent() mount location not freed on syntax error.
|
||||
- in modules/parse_sun.c:parse_mount() mount location not freed on syntax error.
|
||||
- in modules/parse_sun.c:parse_init() a malloc is not checked and the
|
||||
handling of the fail case is poor.
|
||||
- in lib/mounts.c:tree_make_mnt_tree() variable ent is not freed on ent->path
|
||||
alloc fail.
|
||||
- in modules/replicated.c:add_host() NULL pointer dereference.
|
||||
- add missing pthread_attr_destroy() in lib/alarm.c:alarm_start_handler().
|
||||
- add missing pthread_attr_destroy() in daemon/state.c:st_start_handler().
|
||||
- add missing fclose() in lib/defaults.c:*defaults_get_searchdns().
|
||||
- add missing close()es in modules/mount_changer.c:swapCD().
|
||||
---
|
||||
|
||||
daemon/direct.c | 6 ++-
|
||||
daemon/indirect.c | 3 +-
|
||||
daemon/lookup.c | 20 +++++-------
|
||||
daemon/state.c | 6 ++-
|
||||
lib/alarm.c | 6 ++-
|
||||
lib/cache.c | 4 +-
|
||||
lib/defaults.c | 1 +
|
||||
lib/macros.c | 2 +
|
||||
lib/mounts.c | 5 ++-
|
||||
modules/lookup_multi.c | 15 +++++----
|
||||
modules/lookup_program.c | 4 ++
|
||||
modules/mount_changer.c | 2 +
|
||||
modules/mount_nfs.c | 5 +++
|
||||
modules/parse_hesiod.c | 79 ++++++++++++++++++++++++++++++++++++++++------
|
||||
modules/parse_sun.c | 18 ++++++----
|
||||
modules/replicated.c | 2 +
|
||||
16 files changed, 123 insertions(+), 55 deletions(-)
|
||||
|
||||
|
||||
diff --git a/daemon/direct.c b/daemon/direct.c
|
||||
index 2d979f1..fc3c969 100644
|
||||
--- a/daemon/direct.c
|
||||
+++ b/daemon/direct.c
|
||||
@@ -1088,7 +1088,6 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
||||
crit(ap->logopt, "can't find map entry for (%lu,%lu)",
|
||||
(unsigned long) pkt->dev, (unsigned long) pkt->ino);
|
||||
master_source_unlock(ap->entry);
|
||||
- master_mutex_unlock();
|
||||
pthread_setcancelstate(state, NULL);
|
||||
return 1;
|
||||
}
|
||||
@@ -1098,8 +1097,9 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
||||
int ioctlfd;
|
||||
ops->open(ap->logopt, &ioctlfd, me->dev, me->key);
|
||||
if (ioctlfd == -1) {
|
||||
- crit(ap->logopt, "can't open ioctlfd for %s",
|
||||
- me->key);
|
||||
+ crit(ap->logopt, "can't open ioctlfd for %s", me->key);
|
||||
+ cache_unlock(mc);
|
||||
+ master_source_unlock(ap->entry);
|
||||
pthread_setcancelstate(state, NULL);
|
||||
return 1;
|
||||
}
|
||||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
||||
index 2ccbc53..f40c393 100644
|
||||
--- a/daemon/indirect.c
|
||||
+++ b/daemon/indirect.c
|
||||
@@ -159,6 +159,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
|
||||
}
|
||||
|
||||
free(options);
|
||||
+ options = NULL;
|
||||
|
||||
ret = stat(root, &st);
|
||||
if (ret == -1) {
|
||||
@@ -167,8 +168,6 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
|
||||
goto out_umount;
|
||||
}
|
||||
|
||||
- options = NULL;
|
||||
-
|
||||
if (ops->open(ap->logopt, &ap->ioctlfd, st.st_dev, root)) {
|
||||
crit(ap->logopt,
|
||||
"failed to create ioctl fd for autofs path %s", ap->path);
|
||||
diff --git a/daemon/lookup.c b/daemon/lookup.c
|
||||
index e034348..fd2ce55 100644
|
||||
--- a/daemon/lookup.c
|
||||
+++ b/daemon/lookup.c
|
||||
@@ -1001,12 +1001,16 @@ static char *make_fullpath(const char *root, const char *key)
|
||||
if (l > KEY_MAX_LEN)
|
||||
return NULL;
|
||||
path = malloc(l);
|
||||
+ if (!path)
|
||||
+ return NULL;
|
||||
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);
|
||||
}
|
||||
return path;
|
||||
@@ -1076,10 +1080,6 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age)
|
||||
this = cache_lookup_distinct(mc, key);
|
||||
if (!this) {
|
||||
cache_unlock(mc);
|
||||
- free(key);
|
||||
- if (next_key)
|
||||
- free(next_key);
|
||||
- free(path);
|
||||
goto next;
|
||||
}
|
||||
|
||||
@@ -1097,18 +1097,14 @@ int lookup_prune_cache(struct autofs_point *ap, time_t age)
|
||||
}
|
||||
cache_unlock(mc);
|
||||
|
||||
- if (!next_key) {
|
||||
- free(key);
|
||||
- free(path);
|
||||
- cache_readlock(mc);
|
||||
- continue;
|
||||
- }
|
||||
next:
|
||||
cache_readlock(mc);
|
||||
- me = cache_lookup_distinct(mc, next_key);
|
||||
+ if (next_key) {
|
||||
+ me = cache_lookup_distinct(mc, next_key);
|
||||
+ free(next_key);
|
||||
+ }
|
||||
free(key);
|
||||
free(path);
|
||||
- free(next_key);
|
||||
}
|
||||
pthread_cleanup_pop(1);
|
||||
map->stale = 0;
|
||||
diff --git a/daemon/state.c b/daemon/state.c
|
||||
index cd63be1..606743b 100644
|
||||
--- a/daemon/state.c
|
||||
+++ b/daemon/state.c
|
||||
@@ -1140,9 +1140,9 @@ int st_start_handler(void)
|
||||
}
|
||||
|
||||
status = pthread_create(&thid, pattrs, st_queue_handler, NULL);
|
||||
- if (status)
|
||||
- return 0;
|
||||
|
||||
- return 1;
|
||||
+ pthread_attr_destroy(pattrs);
|
||||
+
|
||||
+ return !status;
|
||||
}
|
||||
|
||||
diff --git a/lib/alarm.c b/lib/alarm.c
|
||||
index 1e32291..46df38a 100755
|
||||
--- a/lib/alarm.c
|
||||
+++ b/lib/alarm.c
|
||||
@@ -238,9 +238,9 @@ int alarm_start_handler(void)
|
||||
}
|
||||
|
||||
status = pthread_create(&thid, pattrs, alarm_handler, NULL);
|
||||
- if (status)
|
||||
- return 0;
|
||||
|
||||
- return 1;
|
||||
+ pthread_attr_destroy(pattrs);
|
||||
+
|
||||
+ return !status;
|
||||
}
|
||||
|
||||
diff --git a/lib/cache.c b/lib/cache.c
|
||||
index edb3192..4cb4582 100644
|
||||
--- a/lib/cache.c
|
||||
+++ b/lib/cache.c
|
||||
@@ -192,7 +192,7 @@ struct mapent_cache *cache_init(struct autofs_point *ap, struct map_source *map)
|
||||
|
||||
mc->size = defaults_get_map_hash_table_size();
|
||||
|
||||
- mc->hash = malloc(mc->size * sizeof(struct entry *));
|
||||
+ mc->hash = malloc(mc->size * sizeof(struct mapent *));
|
||||
if (!mc->hash) {
|
||||
free(mc);
|
||||
return NULL;
|
||||
@@ -243,7 +243,7 @@ struct mapent_cache *cache_init_null_cache(struct master *master)
|
||||
|
||||
mc->size = NULL_MAP_HASHSIZE;
|
||||
|
||||
- mc->hash = malloc(mc->size * sizeof(struct entry *));
|
||||
+ mc->hash = malloc(mc->size * sizeof(struct mapent *));
|
||||
if (!mc->hash) {
|
||||
free(mc);
|
||||
return NULL;
|
||||
diff --git a/lib/defaults.c b/lib/defaults.c
|
||||
index 0d39716..e507a59 100644
|
||||
--- a/lib/defaults.c
|
||||
+++ b/lib/defaults.c
|
||||
@@ -565,6 +565,7 @@ struct ldap_searchdn *defaults_get_searchdns(void)
|
||||
|
||||
if (!new) {
|
||||
defaults_free_searchdns(sdn);
|
||||
+ fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
diff --git a/lib/macros.c b/lib/macros.c
|
||||
index 85f9cd3..32b70bf 100644
|
||||
--- a/lib/macros.c
|
||||
+++ b/lib/macros.c
|
||||
@@ -165,7 +165,7 @@ int macro_parse_globalvar(const char *define)
|
||||
char buf[MAX_MACRO_STRING];
|
||||
char *pbuf, *value;
|
||||
|
||||
- if (strlen(define) > MAX_MACRO_STRING)
|
||||
+ if (strlen(define) >= MAX_MACRO_STRING)
|
||||
return 0;
|
||||
|
||||
strcpy(buf, define);
|
||||
diff --git a/lib/mounts.c b/lib/mounts.c
|
||||
index b98e1a4..08ca4e3 100644
|
||||
--- a/lib/mounts.c
|
||||
+++ b/lib/mounts.c
|
||||
@@ -257,10 +257,10 @@ struct mnt_list *get_mnt_list(const char *table, const char *path, int include)
|
||||
|
||||
if (mptr == list)
|
||||
list = ent;
|
||||
+ else
|
||||
+ last->next = ent;
|
||||
|
||||
ent->next = mptr;
|
||||
- if (last)
|
||||
- last->next = ent;
|
||||
|
||||
ent->path = malloc(len + 1);
|
||||
if (!ent->path) {
|
||||
@@ -705,6 +705,7 @@ struct mnt_list *tree_make_mnt_tree(const char *table, const char *path)
|
||||
ent->path = malloc(len + 1);
|
||||
if (!ent->path) {
|
||||
endmntent(tab);
|
||||
+ free(ent);
|
||||
tree_free_mnt_tree(tree);
|
||||
return NULL;
|
||||
}
|
||||
diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
|
||||
index 1bf2e0a..6ec8434 100644
|
||||
--- a/modules/lookup_multi.c
|
||||
+++ b/modules/lookup_multi.c
|
||||
@@ -212,14 +212,15 @@ nomem:
|
||||
logerr(MODPREFIX "error: %s", estr);
|
||||
error_out:
|
||||
if (ctxt) {
|
||||
- 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);
|
||||
- }
|
||||
- if (ctxt->m)
|
||||
+ 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);
|
||||
diff --git a/modules/lookup_program.c b/modules/lookup_program.c
|
||||
index 9878936..5b295a5 100644
|
||||
--- a/modules/lookup_program.c
|
||||
+++ b/modules/lookup_program.c
|
||||
@@ -396,8 +396,10 @@ next:
|
||||
cache_writelock(mc);
|
||||
ret = cache_update(mc, source, name, mapent, time(NULL));
|
||||
cache_unlock(mc);
|
||||
- if (ret == CHE_FAIL)
|
||||
+ if (ret == CHE_FAIL) {
|
||||
+ free(mapent);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
+ }
|
||||
|
||||
debug(ap->logopt, MODPREFIX "%s -> %s", name, mapent);
|
||||
|
||||
diff --git a/modules/mount_changer.c b/modules/mount_changer.c
|
||||
index 92bb72b..c30190d 100644
|
||||
--- a/modules/mount_changer.c
|
||||
+++ b/modules/mount_changer.c
|
||||
@@ -162,6 +162,7 @@ int swapCD(const char *device, const char *slotName)
|
||||
logerr(MODPREFIX
|
||||
"Device %s is not an ATAPI compliant CD changer.",
|
||||
device);
|
||||
+ close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -169,6 +170,7 @@ int swapCD(const char *device, const char *slotName)
|
||||
slot = ioctl(fd, CDROM_SELECT_DISC, slot);
|
||||
if (slot < 0) {
|
||||
logerr(MODPREFIX "CDROM_SELECT_DISC failed");
|
||||
+ close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c
|
||||
index 20732f8..6f54f47 100644
|
||||
--- a/modules/mount_nfs.c
|
||||
+++ b/modules/mount_nfs.c
|
||||
@@ -221,6 +221,11 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, int
|
||||
/* Not a local host - do an NFS mount */
|
||||
|
||||
loc = malloc(strlen(this->name) + 1 + strlen(this->path) + 1);
|
||||
+ if (!loc) {
|
||||
+ char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ error(ap->logopt, "malloc: %s", estr);
|
||||
+ return 1;
|
||||
+ }
|
||||
strcpy(loc, this->name);
|
||||
strcat(loc, ":");
|
||||
strcat(loc, this->path);
|
||||
diff --git a/modules/parse_hesiod.c b/modules/parse_hesiod.c
|
||||
index d5bb0f4..7a6a57d 100644
|
||||
--- a/modules/parse_hesiod.c
|
||||
+++ b/modules/parse_hesiod.c
|
||||
@@ -46,6 +46,12 @@ static int parse_afs(struct autofs_point *ap,
|
||||
|
||||
/* Isolate the source for this AFS fs. */
|
||||
for (i = 0; (!isspace(p[i]) && i < source_len); i++) {
|
||||
+ if (!p[i]) {
|
||||
+ error(ap->logopt, MODPREFIX
|
||||
+ "unexpeced end of input looking for AFS "
|
||||
+ "source: %s", p);
|
||||
+ return 1;
|
||||
+ }
|
||||
source[i] = p[i];
|
||||
}
|
||||
|
||||
@@ -56,8 +62,14 @@ static int parse_afs(struct autofs_point *ap,
|
||||
while ((*p) && (isspace(*p)))
|
||||
p++;
|
||||
|
||||
- /* Isolate the source for this AFS fs. */
|
||||
+ /* Isolate the options for this AFS fs. */
|
||||
for (i = 0; (!isspace(p[i]) && i < options_len); i++) {
|
||||
+ if (!p[i]) {
|
||||
+ error(ap->logopt, MODPREFIX
|
||||
+ "unexpeced end of input looking for AFS "
|
||||
+ "options: %s", p);
|
||||
+ return 1;
|
||||
+ }
|
||||
options[i] = p[i];
|
||||
}
|
||||
options[i] = 0;
|
||||
@@ -106,6 +118,12 @@ static int parse_nfs(struct autofs_point *ap,
|
||||
|
||||
/* Isolate the remote mountpoint for this NFS fs. */
|
||||
for (i = 0; (!isspace(p[i]) && i < (int) sizeof(mount)); i++) {
|
||||
+ if (!p[i]) {
|
||||
+ error(ap->logopt, MODPREFIX
|
||||
+ "unexpeced end of input looking for NFS "
|
||||
+ "mountpoint: %s", p);
|
||||
+ return 1;
|
||||
+ }
|
||||
mount[i] = p[i];
|
||||
}
|
||||
|
||||
@@ -118,15 +136,26 @@ static int parse_nfs(struct autofs_point *ap,
|
||||
|
||||
/* Isolate the remote host. */
|
||||
for (i = 0; (!isspace(p[i]) && i < source_len); i++) {
|
||||
+ if (!p[i]) {
|
||||
+ error(ap->logopt, MODPREFIX
|
||||
+ "unexpeced end of input looking for NFS "
|
||||
+ "host: %s", p);
|
||||
+ return 1;
|
||||
+ }
|
||||
source[i] = p[i];
|
||||
}
|
||||
|
||||
source[i] = 0;
|
||||
p += i;
|
||||
|
||||
+ if (strlen(source) + strlen(mount) + 2 > source_len) {
|
||||
+ error(ap->logopt, MODPREFIX "entry too log for mount source");
|
||||
+ return 1;
|
||||
+ }
|
||||
+
|
||||
/* Append ":mountpoint" to the source to get "host:mountpoint". */
|
||||
- strncat(source, ":", source_len);
|
||||
- strncat(source, mount, source_len);
|
||||
+ strcat(source, ":");
|
||||
+ strcat(source, mount);
|
||||
|
||||
/* Skip whitespace. */
|
||||
while ((*p) && (isspace(*p)))
|
||||
@@ -134,6 +163,12 @@ static int parse_nfs(struct autofs_point *ap,
|
||||
|
||||
/* Isolate the mount options. */
|
||||
for (i = 0; (!isspace(p[i]) && i < options_len); i++) {
|
||||
+ if (!p[i]) {
|
||||
+ error(ap->logopt, MODPREFIX
|
||||
+ "unexpeced end of input looking for NFS "
|
||||
+ "mount options: %s", p);
|
||||
+ return 1;
|
||||
+ }
|
||||
options[i] = p[i];
|
||||
}
|
||||
options[i] = 0;
|
||||
@@ -178,6 +213,12 @@ static int parse_generic(struct autofs_point *ap,
|
||||
|
||||
/* Isolate the source for this fs. */
|
||||
for (i = 0; (!isspace(p[i]) && i < source_len); i++) {
|
||||
+ if (!p[i]) {
|
||||
+ error(ap->logopt, MODPREFIX
|
||||
+ "unexpeced end of input looking for generic "
|
||||
+ "mount source: %s", p);
|
||||
+ return 1;
|
||||
+ }
|
||||
source[i] = p[i];
|
||||
}
|
||||
|
||||
@@ -190,6 +231,12 @@ static int parse_generic(struct autofs_point *ap,
|
||||
|
||||
/* Isolate the mount options. */
|
||||
for (i = 0; (!isspace(p[i]) && i < options_len); i++) {
|
||||
+ if (!p[i]) {
|
||||
+ error(ap->logopt, MODPREFIX
|
||||
+ "unexpeced end of input looking for generic "
|
||||
+ "mount options: %s", p);
|
||||
+ return 1;
|
||||
+ }
|
||||
options[i] = p[i];
|
||||
}
|
||||
options[i] = 0;
|
||||
@@ -227,6 +274,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
|
||||
char options[HESIOD_LEN + 1];
|
||||
char *q;
|
||||
const char *p;
|
||||
+ int ret;
|
||||
|
||||
ap->entry->current = NULL;
|
||||
master_source_current_signal(ap->entry);
|
||||
@@ -250,19 +298,28 @@ int parse_mount(struct autofs_point *ap, const char *name,
|
||||
return 1;
|
||||
/* If it's an AFS fs... */
|
||||
} else if (!strcasecmp(fstype, "afs"))
|
||||
- parse_afs(ap, mapent, name, name_len,
|
||||
- source, sizeof(source), options, sizeof(options));
|
||||
+ ret = parse_afs(ap, mapent, name, name_len,
|
||||
+ source, sizeof(source), options,
|
||||
+ sizeof(options));
|
||||
/* If it's NFS... */
|
||||
else if (!strcasecmp(fstype, "nfs"))
|
||||
- parse_nfs(ap, mapent, name, name_len,
|
||||
- source, sizeof(source), options, sizeof(options));
|
||||
+ ret = parse_nfs(ap, mapent, name, name_len,
|
||||
+ source, sizeof(source), options,
|
||||
+ sizeof(options));
|
||||
/* Punt. */
|
||||
else
|
||||
- parse_generic(ap, mapent, name, name_len, source, sizeof(source),
|
||||
- options, sizeof(options));
|
||||
+ ret = parse_generic(ap, mapent, name, name_len,
|
||||
+ source, sizeof(source), options,
|
||||
+ sizeof(options));
|
||||
|
||||
- debug(ap->logopt,
|
||||
- MODPREFIX "mount %s is type %s from %s", name, fstype, source);
|
||||
+ if (ret) {
|
||||
+ error(ap->logopt, MODPREFIX "failed to parse entry");
|
||||
+ return 1;
|
||||
+ } else {
|
||||
+ debug(ap->logopt,
|
||||
+ MODPREFIX "mount %s is type %s from %s",
|
||||
+ name, fstype, source);
|
||||
+ }
|
||||
|
||||
return do_mount(ap, ap->path, name, name_len, source, fstype, options);
|
||||
}
|
||||
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
|
||||
index 72e51e2..ed73e46 100644
|
||||
--- a/modules/parse_sun.c
|
||||
+++ b/modules/parse_sun.c
|
||||
@@ -379,15 +379,17 @@ int parse_init(int argc, const char *const *argv, void **context)
|
||||
if (ctxt->optstr) {
|
||||
noptstr =
|
||||
(char *) realloc(ctxt->optstr, optlen + len + 2);
|
||||
- if (!noptstr)
|
||||
- break;
|
||||
- noptstr[optlen] = ',';
|
||||
- strcpy(noptstr + optlen + 1, argv[i] + offset);
|
||||
- optlen += len + 1;
|
||||
+ if (noptstr) {
|
||||
+ noptstr[optlen] = ',';
|
||||
+ strcpy(noptstr + optlen + 1, argv[i] + offset);
|
||||
+ optlen += len + 1;
|
||||
+ }
|
||||
} else {
|
||||
noptstr = (char *) malloc(len + 1);
|
||||
- strcpy(noptstr, argv[i] + offset);
|
||||
- optlen = len;
|
||||
+ if (noptstr) {
|
||||
+ strcpy(noptstr, argv[i] + offset);
|
||||
+ optlen = len;
|
||||
+ }
|
||||
}
|
||||
if (!noptstr) {
|
||||
char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
@@ -895,6 +897,7 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
|
||||
if (*p == '/') {
|
||||
warn(logopt, MODPREFIX "error location begins with \"/\"");
|
||||
free(myoptions);
|
||||
+ free(loc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1636,6 +1639,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
|
||||
/* Location can't begin with a '/' */
|
||||
if (*p == '/') {
|
||||
free(options);
|
||||
+ free(loc);
|
||||
warn(ap->logopt,
|
||||
MODPREFIX "error location begins with \"/\"");
|
||||
return 1;
|
||||
diff --git a/modules/replicated.c b/modules/replicated.c
|
||||
index 63829a2..835af97 100644
|
||||
--- a/modules/replicated.c
|
||||
+++ b/modules/replicated.c
|
||||
@@ -304,7 +304,7 @@ static int add_host(struct host **list, struct host *host)
|
||||
{
|
||||
struct host *this, *last;
|
||||
|
||||
- if (!list) {
|
||||
+ if (!*list) {
|
||||
*list = host;
|
||||
return 1;
|
||||
}
|
3262
autofs-5.0.4-configure-libtirpc.patch
Normal file
3262
autofs-5.0.4-configure-libtirpc.patch
Normal file
File diff suppressed because it is too large
Load Diff
1137
autofs-5.0.4-easy-alloca-replacements.patch
Normal file
1137
autofs-5.0.4-easy-alloca-replacements.patch
Normal file
File diff suppressed because it is too large
Load Diff
52
autofs-5.0.4-fix-hosts-map-use-after-free.patch
Normal file
52
autofs-5.0.4-fix-hosts-map-use-after-free.patch
Normal file
@ -0,0 +1,52 @@
|
||||
autofs-5.0.4 - fix hosts map use after free
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
This patch fixed use a map entry after it has been freed in the
|
||||
hosts map lookup module.
|
||||
---
|
||||
|
||||
CHANGELOG | 1 +
|
||||
modules/lookup_hosts.c | 8 +++++---
|
||||
2 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index eb4a189..3199e4d 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -9,6 +9,7 @@
|
||||
Valerie Aurora Henson).
|
||||
- clear the quoted flag after each character from program map input.
|
||||
- use CLOEXEC flag for setmntent also.
|
||||
+- fix hosts map use after free.
|
||||
|
||||
4/11/2008 autofs-5.0.4
|
||||
-----------------------
|
||||
diff --git a/modules/lookup_hosts.c b/modules/lookup_hosts.c
|
||||
index 93b975a..d3ae0e2 100644
|
||||
--- a/modules/lookup_hosts.c
|
||||
+++ b/modules/lookup_hosts.c
|
||||
@@ -138,17 +138,19 @@ int lookup_mount(struct autofs_point *ap, const char *name, int name_len, void *
|
||||
/* Check if we recorded a mount fail for this key anywhere */
|
||||
me = lookup_source_mapent(ap, name, LKP_DISTINCT);
|
||||
if (me) {
|
||||
+ struct mapent_cache *fmc = me->mc;
|
||||
+
|
||||
if (me->status >= time(NULL)) {
|
||||
- cache_unlock(me->mc);
|
||||
+ cache_unlock(fmc);
|
||||
return NSS_STATUS_NOTFOUND;
|
||||
}
|
||||
|
||||
if (!me->mapent) {
|
||||
- cache_delete(me->mc, name);
|
||||
+ cache_delete(fmc, name);
|
||||
me = NULL;
|
||||
}
|
||||
|
||||
- cache_unlock(me->mc);
|
||||
+ cache_unlock(fmc);
|
||||
}
|
||||
|
||||
cache_readlock(mc);
|
235
autofs-5.0.4-force-unlink-umount.patch
Normal file
235
autofs-5.0.4-force-unlink-umount.patch
Normal file
@ -0,0 +1,235 @@
|
||||
autofs-5.0.4 - force unlink umount at startup
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Version 5.0.3 autofs would unlink existing mounts at startup. This
|
||||
functioned OK most of the time but caused processes whose working
|
||||
directory was within unlinked automounted directories to not get a
|
||||
correct pwd reported by the system.
|
||||
|
||||
There can be situations where the unlink umounting is desirable, such
|
||||
as when the daemon is forceably killed and we want to get rid of any
|
||||
existing mounts at startup. This change provides a way to force this
|
||||
old behavior by passing the "--force" option to the daemon. This can
|
||||
also be done by using the "forcestart" and "forcerestart" actions to
|
||||
the init script.
|
||||
|
||||
Note that the old behavior will always be used if the kernel does not
|
||||
include the iotcl re-implementation which provides the ability to
|
||||
re-connect to existing mounts.
|
||||
---
|
||||
|
||||
CHANGELOG | 2 ++
|
||||
daemon/automount.c | 14 +++++++++++++-
|
||||
daemon/direct.c | 2 +-
|
||||
daemon/indirect.c | 2 +-
|
||||
include/automount.h | 3 +++
|
||||
man/automount.8 | 13 +++++++++++++
|
||||
redhat/autofs.init.in | 10 +++++++++-
|
||||
samples/rc.autofs.in | 10 +++++++++-
|
||||
8 files changed, 51 insertions(+), 5 deletions(-)
|
||||
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 7dee674..d4dd70b 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -12,6 +12,8 @@
|
||||
- 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.
|
||||
|
||||
4/11/2008 autofs-5.0.4
|
||||
-----------------------
|
||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
||||
index f04273f..e20e7c9 100644
|
||||
--- a/daemon/automount.c
|
||||
+++ b/daemon/automount.c
|
||||
@@ -57,6 +57,7 @@ static char *pid_file = NULL; /* File in which to keep pid */
|
||||
unsigned int global_random_selection; /* use random policy when selecting
|
||||
* which multi-mount host to mount */
|
||||
long global_negative_timeout = -1;
|
||||
+int do_force_unlink = 0; /* Forceably unlink mount tree at startup */
|
||||
|
||||
static int start_pipefd[2];
|
||||
static int st_stat = 0;
|
||||
@@ -1798,6 +1799,7 @@ int main(int argc, char *argv[])
|
||||
{"version", 0, 0, 'V'},
|
||||
{"set-log-priority", 1, 0, 'l'},
|
||||
{"dont-check-daemon", 0, 0, 'C'},
|
||||
+ {"force", 0, 0, 'F'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
@@ -1819,7 +1821,7 @@ int main(int argc, char *argv[])
|
||||
daemon_check = 1;
|
||||
|
||||
opterr = 0;
|
||||
- while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:C", long_options, NULL)) != EOF) {
|
||||
+ while ((opt = getopt_long(argc, argv, "+hp:t:vdD:fVrO:l:n:CF", long_options, NULL)) != EOF) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
usage();
|
||||
@@ -1892,6 +1894,10 @@ int main(int argc, char *argv[])
|
||||
daemon_check = 0;
|
||||
break;
|
||||
|
||||
+ case 'F':
|
||||
+ do_force_unlink = 1;
|
||||
+ break;
|
||||
+
|
||||
case '?':
|
||||
case ':':
|
||||
printf("%s: Ambiguous or unknown options\n", program);
|
||||
@@ -2066,6 +2072,12 @@ int main(int argc, char *argv[])
|
||||
exit(3);
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Mmm ... reset force unlink umount so we don't also do this
|
||||
+ * in future when we receive a HUP signal.
|
||||
+ */
|
||||
+ do_force_unlink = 0;
|
||||
+
|
||||
res = write(start_pipefd[1], pst_stat, sizeof(*pst_stat));
|
||||
close(start_pipefd[1]);
|
||||
|
||||
diff --git a/daemon/direct.c b/daemon/direct.c
|
||||
index d9dda3d..2d979f1 100644
|
||||
--- a/daemon/direct.c
|
||||
+++ b/daemon/direct.c
|
||||
@@ -335,7 +335,7 @@ int do_mount_autofs_direct(struct autofs_point *ap, struct mnt_list *mnts, struc
|
||||
/* Calculate the timeouts */
|
||||
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
|
||||
|
||||
- if (ops->version) {
|
||||
+ if (ops->version && !do_force_unlink) {
|
||||
ap->flags |= MOUNT_FLAG_REMOUNT;
|
||||
ret = try_remount(ap, me, t_direct);
|
||||
ap->flags &= ~MOUNT_FLAG_REMOUNT;
|
||||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
||||
index 0721707..2ccbc53 100644
|
||||
--- a/daemon/indirect.c
|
||||
+++ b/daemon/indirect.c
|
||||
@@ -97,7 +97,7 @@ static int do_mount_autofs_indirect(struct autofs_point *ap, const char *root)
|
||||
|
||||
ap->exp_runfreq = (timeout + CHECK_RATIO - 1) / CHECK_RATIO;
|
||||
|
||||
- if (ops->version) {
|
||||
+ if (ops->version && !do_force_unlink) {
|
||||
ap->flags |= MOUNT_FLAG_REMOUNT;
|
||||
ret = try_remount(ap, NULL, t_indirect);
|
||||
ap->flags &= ~MOUNT_FLAG_REMOUNT;
|
||||
diff --git a/include/automount.h b/include/automount.h
|
||||
index 46cb6c6..1f14d5b 100644
|
||||
--- a/include/automount.h
|
||||
+++ b/include/automount.h
|
||||
@@ -428,6 +428,9 @@ struct autofs_point {
|
||||
struct list_head submounts; /* List of child submounts */
|
||||
};
|
||||
|
||||
+/* Foreably unlink existing mounts at startup. */
|
||||
+extern int do_force_unlink;
|
||||
+
|
||||
/* Standard functions used by daemon or modules */
|
||||
|
||||
#define MOUNT_OFFSET_OK 0
|
||||
diff --git a/man/automount.8 b/man/automount.8
|
||||
index d9285bf..9fcaaf4 100644
|
||||
--- a/man/automount.8
|
||||
+++ b/man/automount.8
|
||||
@@ -84,6 +84,11 @@ path name as specified in the master map.
|
||||
.TP
|
||||
.I "\-C, \-\-dont-check-daemon"
|
||||
Don't check if the daemon is currently running (see NOTES).
|
||||
+.TP
|
||||
+.I "\-F, \-\-force"
|
||||
+Force an unlink umount of existing mounts under autofs managed mount points
|
||||
+during startup. This can cause problems for processes with working directories
|
||||
+within these mounts (see NOTES).
|
||||
.SH ARGUMENTS
|
||||
\fBautomount\fP takes one optional argument, the name of the master map to
|
||||
use.
|
||||
@@ -132,6 +137,14 @@ for certain types of automount maps. The mounts of the seperate daemons
|
||||
might interfere with one another. The implications of running multiple
|
||||
daemon instances needs to be checked and tested before we can say this
|
||||
is supported.
|
||||
+.P
|
||||
+If the option to force an unlink of mounts at startup is used then processes
|
||||
+whose working directory is within unlinked automounted directories will not
|
||||
+get the correct pwd from the system. This is because, after the mount is
|
||||
+unlinked from the mount tree, anything that needs to walk back up the mount
|
||||
+tree to construct a path, such as getcwd(2) and the proc filesystem
|
||||
+/proc/<pid>/cwd, cannot work because the point from which the path is
|
||||
+constructed has been detached from the mount tree.
|
||||
.SH "SEE ALSO"
|
||||
.BR autofs (5),
|
||||
.BR autofs (8),
|
||||
diff --git a/redhat/autofs.init.in b/redhat/autofs.init.in
|
||||
index 65c786e..471667e 100644
|
||||
--- a/redhat/autofs.init.in
|
||||
+++ b/redhat/autofs.init.in
|
||||
@@ -137,6 +137,10 @@ case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
+ forcestart)
|
||||
+ OPTIONS="$OPTIONS --force"
|
||||
+ start
|
||||
+ ;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
@@ -146,6 +150,10 @@ case "$1" in
|
||||
restart)
|
||||
restart
|
||||
;;
|
||||
+ forcerestart)
|
||||
+ OPTIONS="$OPTIONS --force"
|
||||
+ restart
|
||||
+ ;;
|
||||
reload)
|
||||
reload
|
||||
;;
|
||||
@@ -155,7 +163,7 @@ case "$1" in
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
- echo $"Usage: $0 {start|stop|status|restart|reload|condrestart}"
|
||||
+ echo $"Usage: $0 {start|forcestart|stop|status|restart|orcerestart|reload|condrestart}"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
||||
diff --git a/samples/rc.autofs.in b/samples/rc.autofs.in
|
||||
index 51f5b02..2877fe2 100644
|
||||
--- a/samples/rc.autofs.in
|
||||
+++ b/samples/rc.autofs.in
|
||||
@@ -117,17 +117,25 @@ case "$1" in
|
||||
start)
|
||||
start
|
||||
;;
|
||||
+ forcestart)
|
||||
+ OPTIONS="$OPTIONS --force"
|
||||
+ start
|
||||
+ ;;
|
||||
stop)
|
||||
stop
|
||||
;;
|
||||
restart)
|
||||
restart
|
||||
;;
|
||||
+ forcerestart)
|
||||
+ OPTIONS="$OPTIONS --force"
|
||||
+ restart
|
||||
+ ;;
|
||||
reload)
|
||||
reload
|
||||
;;
|
||||
*)
|
||||
- echo $"Usage: $0 {start|stop|restart|reload}"
|
||||
+ echo $"Usage: $0 {start|forcestart|stop|restart|forcerestart|reload}"
|
||||
exit 1;
|
||||
;;
|
||||
esac
|
1018
autofs-5.0.4-ipv6-name-and-address-support.patch
Normal file
1018
autofs-5.0.4-ipv6-name-and-address-support.patch
Normal file
File diff suppressed because it is too large
Load Diff
462
autofs-5.0.4-ipv6-parse.patch
Normal file
462
autofs-5.0.4-ipv6-parse.patch
Normal file
@ -0,0 +1,462 @@
|
||||
autofs-5.0.4 - ipv6 parse
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
Since ipv6 addresses use a colon separator and we use the colon quite a
|
||||
bit as a delimiting character we need to distinguish between when the
|
||||
colon is the delimeter we are looking for and when it is part of an ipv6
|
||||
address. Since there is widespread use of "[" and "]" to provide the
|
||||
ability to separate a port specification from an ipv6 address this
|
||||
convention has also been used in autofs.
|
||||
---
|
||||
|
||||
CHANGELOG | 1
|
||||
include/parse_subs.h | 8 +++
|
||||
lib/master_tok.l | 10 ++--
|
||||
lib/parse_subs.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
modules/lookup_file.c | 40 +++++++------------
|
||||
modules/lookup_ldap.c | 21 ++++++++--
|
||||
modules/mount_autofs.c | 29 +++++---------
|
||||
modules/parse_sun.c | 16 ++++---
|
||||
modules/replicated.c | 26 +++++++++++-
|
||||
9 files changed, 187 insertions(+), 63 deletions(-)
|
||||
|
||||
|
||||
--- autofs-5.0.4.orig/include/parse_subs.h
|
||||
+++ autofs-5.0.4/include/parse_subs.h
|
||||
@@ -20,6 +20,12 @@
|
||||
|
||||
struct mapent;
|
||||
|
||||
+struct map_type_info {
|
||||
+ char *type;
|
||||
+ char *format;
|
||||
+ char *map;
|
||||
+};
|
||||
+
|
||||
const char *skipspace(const char *);
|
||||
int check_colon(const char *);
|
||||
int chunklen(const char *, int);
|
||||
@@ -27,5 +33,7 @@ int strmcmp(const char *, const char *,
|
||||
char *dequote(const char *, int, unsigned int);
|
||||
int span_space(const char *, unsigned int);
|
||||
char *sanitize_path(const char *, int, unsigned int, unsigned int);
|
||||
+void free_map_type_info(struct map_type_info *);
|
||||
+struct map_type_info *parse_map_type_info(const char *);
|
||||
|
||||
#endif
|
||||
--- autofs-5.0.4.orig/lib/master_tok.l
|
||||
+++ autofs-5.0.4/lib/master_tok.l
|
||||
@@ -96,10 +96,12 @@ SLASHIFYSTR (--(no-)?slashify-colons)
|
||||
NUMBER [0-9]+
|
||||
|
||||
DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:)
|
||||
-DNSERVSTR2 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/)
|
||||
-DNSERVSTR3 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:)
|
||||
-DNSERVSTR4 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/)
|
||||
-DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4})
|
||||
+DNSERVSTR2 (\[([[:xdigit:]]:.)+\](:[0-9]+)?:)
|
||||
+DNSERVSTR3 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/)
|
||||
+DNSERVSTR4 (\/\/\[([[:xdigit:]]:.)+\](:[0-9]+)?\/)
|
||||
+DNSERVSTR5 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:)
|
||||
+DNSERVSTR6 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/)
|
||||
+DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}|{DNSERVSTR5}|{DNSERVSTR6})
|
||||
|
||||
AT_CN ([cC][[nN])
|
||||
AT_NMN ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE])
|
||||
--- autofs-5.0.4.orig/lib/parse_subs.c
|
||||
+++ autofs-5.0.4/lib/parse_subs.c
|
||||
@@ -56,14 +56,13 @@ int check_colon(const char *str)
|
||||
char *ptr = (char *) str;
|
||||
|
||||
/* Colon escape */
|
||||
- if (*ptr == ':')
|
||||
+ if (!strncmp(ptr, ":/", 2))
|
||||
return 1;
|
||||
|
||||
- while (*ptr && *ptr != ':' && *ptr != '/') {
|
||||
+ while (*ptr && strncmp(ptr, ":/", 2))
|
||||
ptr++;
|
||||
- }
|
||||
|
||||
- if (!*ptr || *ptr == '/')
|
||||
+ if (!*ptr)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
@@ -93,12 +92,12 @@ int chunklen(const char *whence, int exp
|
||||
n++;
|
||||
if (*str == '"')
|
||||
break;
|
||||
- if (*str == ':')
|
||||
+ if (!strncmp(str, ":/", 2))
|
||||
expect_colon = 0;
|
||||
}
|
||||
break;
|
||||
case ':':
|
||||
- if (expect_colon)
|
||||
+ if (expect_colon && !strncmp(str, ":/", 2))
|
||||
expect_colon = 0;
|
||||
continue;
|
||||
case ' ':
|
||||
@@ -300,3 +299,91 @@ char *sanitize_path(const char *path, in
|
||||
return s_path;
|
||||
}
|
||||
|
||||
+void free_map_type_info(struct map_type_info *info)
|
||||
+{
|
||||
+ if (info->type)
|
||||
+ free(info->type);
|
||||
+ if (info->format)
|
||||
+ free(info->format);
|
||||
+ if (info->map)
|
||||
+ free(info->map);
|
||||
+ free(info);
|
||||
+ return;
|
||||
+}
|
||||
+
|
||||
+struct map_type_info *parse_map_type_info(const char *str)
|
||||
+{
|
||||
+ struct map_type_info *info;
|
||||
+ char *buf, *type, *fmt, *map, *tmp;
|
||||
+
|
||||
+ buf = strdup(str);
|
||||
+ if (!buf)
|
||||
+ return NULL;
|
||||
+
|
||||
+ info = malloc(sizeof(struct map_type_info));
|
||||
+ if (!info) {
|
||||
+ free(buf);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ memset(info, 0, sizeof(struct map_type_info));
|
||||
+
|
||||
+ type = fmt = NULL;
|
||||
+
|
||||
+ /* Look for space terminator - ignore local options */
|
||||
+ map = buf;
|
||||
+ for (tmp = buf; *tmp; tmp++) {
|
||||
+ if (*tmp == ' ') {
|
||||
+ *tmp = '\0';
|
||||
+ break;
|
||||
+ } else if (*tmp == ',') {
|
||||
+ type = buf;
|
||||
+ *tmp++ = '\0';
|
||||
+ fmt = tmp;
|
||||
+ } else if (*tmp == ':') {
|
||||
+ if (!fmt)
|
||||
+ type = buf;
|
||||
+ *tmp++ = '\0';
|
||||
+ map = tmp;
|
||||
+ } else if (*tmp == '[') {
|
||||
+ /*
|
||||
+ * Unescaped '[' is a syntax error here as only
|
||||
+ * an ldap map with a type specified should contain
|
||||
+ * them.
|
||||
+ */
|
||||
+ free(buf);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if (*tmp == '\\')
|
||||
+ tmp++;
|
||||
+ }
|
||||
+
|
||||
+ if (type) {
|
||||
+ info->type = strdup(type);
|
||||
+ if (!info->type) {
|
||||
+ free(buf);
|
||||
+ free_map_type_info(info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (fmt) {
|
||||
+ info->format = strdup(fmt);
|
||||
+ if (!info->format) {
|
||||
+ free(buf);
|
||||
+ free_map_type_info(info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ info->map = strdup(map);
|
||||
+ if (!info->map) {
|
||||
+ free(buf);
|
||||
+ free_map_type_info(info);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ free(buf);
|
||||
+
|
||||
+ return info;
|
||||
+}
|
||||
+
|
||||
--- autofs-5.0.4.orig/modules/lookup_file.c
|
||||
+++ autofs-5.0.4/modules/lookup_file.c
|
||||
@@ -523,10 +523,10 @@ prepare_plus_include(struct autofs_point
|
||||
{
|
||||
struct map_source *current;
|
||||
struct map_source *source;
|
||||
- char *type, *map, *fmt;
|
||||
+ struct map_type_info *info;
|
||||
const char *argv[2];
|
||||
int argc;
|
||||
- char *buf, *tmp;
|
||||
+ char *buf;
|
||||
|
||||
current = ap->entry->current;
|
||||
ap->entry->current = NULL;
|
||||
@@ -548,33 +548,19 @@ prepare_plus_include(struct autofs_point
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- type = fmt = NULL;
|
||||
-
|
||||
- /* Look for space terminator - ignore local options */
|
||||
- map = buf;
|
||||
- for (tmp = buf; *tmp; tmp++) {
|
||||
- if (*tmp == ' ') {
|
||||
- *tmp = '\0';
|
||||
- break;
|
||||
- } else if (*tmp == ',') {
|
||||
- type = buf;
|
||||
- *tmp++ = '\0';
|
||||
- fmt = tmp;
|
||||
- } else if (*tmp == ':') {
|
||||
- if (!fmt)
|
||||
- type = buf;
|
||||
- *tmp++ = '\0';
|
||||
- map = tmp;
|
||||
- }
|
||||
- if (*tmp == '\\')
|
||||
- tmp++;
|
||||
+ if (!(info = parse_map_type_info(buf))) {
|
||||
+ error(ap->logopt, MODPREFIX "failed to parse map info");
|
||||
+ free(buf);
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
argc = 1;
|
||||
- argv[0] = map;
|
||||
+ argv[0] = info->map;
|
||||
argv[1] = NULL;
|
||||
|
||||
- source = master_find_source_instance(current, type, fmt, argc, argv);
|
||||
+ source = master_find_source_instance(current,
|
||||
+ info->type, info->format,
|
||||
+ argc, argv);
|
||||
if (source)
|
||||
/*
|
||||
* Make sure included map age is in sync with its owner
|
||||
@@ -582,8 +568,11 @@ prepare_plus_include(struct autofs_point
|
||||
*/
|
||||
source->age = age;
|
||||
else {
|
||||
- source = master_add_source_instance(current, type, fmt, age, argc, argv);
|
||||
+ source = master_add_source_instance(current,
|
||||
+ info->type, info->format,
|
||||
+ age, argc, argv);
|
||||
if (!source) {
|
||||
+ free_map_type_info(info);
|
||||
free(buf);
|
||||
error(ap->logopt, "failed to add included map instance");
|
||||
return NULL;
|
||||
@@ -594,6 +583,7 @@ prepare_plus_include(struct autofs_point
|
||||
if (inc)
|
||||
source->recurse = 1;
|
||||
|
||||
+ free_map_type_info(info);
|
||||
free(buf);
|
||||
|
||||
return source;
|
||||
--- autofs-5.0.4.orig/modules/lookup_ldap.c
|
||||
+++ autofs-5.0.4/modules/lookup_ldap.c
|
||||
@@ -1119,11 +1119,26 @@ static int parse_server_string(unsigned
|
||||
memcpy(ctxt->server, s, l);
|
||||
*/
|
||||
}
|
||||
- } else if (strchr(ptr, ':') != NULL) {
|
||||
- char *q = NULL;
|
||||
+ } else if (strchr(ptr, ':') != NULL || *ptr == '[') {
|
||||
+ const char *q = NULL;
|
||||
|
||||
/* Isolate the server. Include the port spec */
|
||||
- q = strchr(ptr, ':');
|
||||
+ if (*ptr != '[')
|
||||
+ q = strchr(ptr, ':');
|
||||
+ else {
|
||||
+ q = ++ptr;
|
||||
+ while (*q == ':' || isxdigit(*q))
|
||||
+ q++;
|
||||
+ if (*q != ']') {
|
||||
+ crit(logopt, MODPREFIX
|
||||
+ "invalid LDAP map syntax %s", ptr);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ q++;
|
||||
+ if (*q == ':')
|
||||
+ q++;
|
||||
+ }
|
||||
+
|
||||
if (isdigit(*q))
|
||||
while (isdigit(*q))
|
||||
q++;
|
||||
--- autofs-5.0.4.orig/modules/mount_autofs.c
|
||||
+++ autofs-5.0.4/modules/mount_autofs.c
|
||||
@@ -50,7 +50,7 @@ int mount_mount(struct autofs_point *ap,
|
||||
int argc, status, ghost = ap->flags & MOUNT_FLAG_GHOST;
|
||||
time_t timeout = ap->exp_timeout;
|
||||
unsigned logopt = ap->logopt;
|
||||
- char *type, *format, *tmp, *tmp2;
|
||||
+ struct map_type_info *info;
|
||||
struct master *master;
|
||||
struct master_mapent *entry;
|
||||
struct map_source *source;
|
||||
@@ -174,21 +174,12 @@ int mount_mount(struct autofs_point *ap,
|
||||
|
||||
argc = 1;
|
||||
|
||||
- type = NULL;
|
||||
- format = NULL;
|
||||
-
|
||||
- tmp = strchr(what, ':');
|
||||
- if (tmp) {
|
||||
- *tmp++ = '\0';
|
||||
- tmp2 = strchr(what, ',');
|
||||
- if (tmp2) {
|
||||
- *tmp2++ = '\0';
|
||||
- format = tmp2;
|
||||
- }
|
||||
- type = (char *) what;
|
||||
- argv[0] = tmp;
|
||||
- } else
|
||||
- argv[0] = (char *) what;
|
||||
+ if (!(info = parse_map_type_info(what))) {
|
||||
+ error(ap->logopt, MODPREFIX "failed to parse map info");
|
||||
+ master_free_mapent(entry);
|
||||
+ return 1;
|
||||
+ }
|
||||
+ argv[0] = info->map;
|
||||
|
||||
if (options) {
|
||||
p = options;
|
||||
@@ -202,13 +193,17 @@ int mount_mount(struct autofs_point *ap,
|
||||
}
|
||||
argv[argc] = NULL;
|
||||
|
||||
- source = master_add_map_source(entry, type, format, time(NULL), argc, argv);
|
||||
+ 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");
|
||||
master_free_mapent(entry);
|
||||
+ free_map_type_info(info);
|
||||
return 1;
|
||||
}
|
||||
+ free_map_type_info(info);
|
||||
|
||||
source->mc = cache_init(entry->ap, source);
|
||||
if (!source->mc) {
|
||||
--- autofs-5.0.4.orig/modules/parse_sun.c
|
||||
+++ autofs-5.0.4/modules/parse_sun.c
|
||||
@@ -245,7 +245,9 @@ int expandsunent(const char *src, char *
|
||||
*(dst++) =
|
||||
(seen_colons && slashify_colons) ? '/' : ':';
|
||||
len++;
|
||||
- seen_colons = 1;
|
||||
+ /* Were looking for the colon preceeding a path */
|
||||
+ if (*src == '/')
|
||||
+ seen_colons = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -814,21 +816,23 @@ static int validate_location(char *loc)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
- * If a ':' is present now it must be a host name, except
|
||||
+ * If a ':/' is present now it must be a host name, except
|
||||
* for those special file systems like sshfs which use "#"
|
||||
- * and "@" in the host name part.
|
||||
+ * and "@" in the host name part and ipv6 addresses that
|
||||
+ * have ":", "[" and "]".
|
||||
*/
|
||||
if (check_colon(ptr)) {
|
||||
- while (*ptr && *ptr != ':') {
|
||||
+ while (*ptr && strncmp(ptr, ":/", 2)) {
|
||||
if (!(isalnum(*ptr) ||
|
||||
*ptr == '-' || *ptr == '.' || *ptr == '_' ||
|
||||
*ptr == ',' || *ptr == '(' || *ptr == ')' ||
|
||||
- *ptr == '#' || *ptr == '@'))
|
||||
+ *ptr == '#' || *ptr == '@' || *ptr == ':' ||
|
||||
+ *ptr == '[' || *ptr == ']'))
|
||||
return 0;
|
||||
ptr++;
|
||||
}
|
||||
|
||||
- if (*ptr && *ptr == ':')
|
||||
+ if (*ptr && !strncmp(ptr, ":/", 2))
|
||||
ptr++;
|
||||
}
|
||||
|
||||
--- autofs-5.0.4.orig/modules/replicated.c
|
||||
+++ autofs-5.0.4/modules/replicated.c
|
||||
@@ -1168,6 +1168,28 @@ static int add_local_path(struct host **
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static char *seek_delim(const char *s)
|
||||
+{
|
||||
+ const char *p = s;
|
||||
+ char *delim;
|
||||
+
|
||||
+ delim = strpbrk(p, "(, \t:");
|
||||
+ if (delim && *delim != ':')
|
||||
+ return delim;
|
||||
+
|
||||
+ while (*p) {
|
||||
+ if (*p != ':') {
|
||||
+ p++;
|
||||
+ continue;
|
||||
+ }
|
||||
+ if (!strncmp(p, ":/", 2))
|
||||
+ return (char *) p;
|
||||
+ p++;
|
||||
+ }
|
||||
+
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
int parse_location(unsigned logopt, struct host **hosts, const char *list)
|
||||
{
|
||||
char *str, *p, *delim;
|
||||
@@ -1187,7 +1209,7 @@ int parse_location(unsigned logopt, stru
|
||||
int weight = 0;
|
||||
|
||||
p += strspn(p, " \t,");
|
||||
- delim = strpbrk(p, "(, \t:");
|
||||
+ delim = seek_delim(p);
|
||||
|
||||
if (delim) {
|
||||
if (*delim == '(') {
|
||||
@@ -1211,7 +1233,7 @@ int parse_location(unsigned logopt, stru
|
||||
|
||||
/* Oh boy - might have spaces in the path */
|
||||
next = path;
|
||||
- while (*next && *next != ':')
|
||||
+ while (*next && strncmp(next, ":/", 2))
|
||||
next++;
|
||||
|
||||
/* No spaces in host names at least */
|
||||
--- autofs-5.0.4.orig/CHANGELOG
|
||||
+++ autofs-5.0.4/CHANGELOG
|
||||
@@ -19,6 +19,7 @@
|
||||
- make some easy alloca replacements (Valerie Aurora Henson).
|
||||
- update to configure libtirpc if present.
|
||||
- update to provide ipv6 name and address support.
|
||||
+- update to provide ipv6 address parsing.
|
||||
|
||||
4/11/2008 autofs-5.0.4
|
||||
-----------------------
|
352
autofs-5.0.4-library-reload-fix-update.patch
Normal file
352
autofs-5.0.4-library-reload-fix-update.patch
Normal file
@ -0,0 +1,352 @@
|
||||
autofs-5.0.4 - library reload fix update
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
We still have a problem with libxml2 being unloaded before its thread
|
||||
specific data destructor is called. This is due to the main thread
|
||||
exiting (closing the handle we hold open to prevent this) before all
|
||||
the mount handling threads have actually completed. This patch makes
|
||||
the mount handling threads joinable (and joins with them as they exit)
|
||||
to ensure that the mount handling threads have completed before allowing
|
||||
the main thread to complete.
|
||||
---
|
||||
|
||||
daemon/automount.c | 35 +++++++++++++++++++++++------------
|
||||
daemon/direct.c | 7 ++++---
|
||||
daemon/indirect.c | 7 ++++---
|
||||
daemon/state.c | 7 ++++---
|
||||
include/master.h | 3 +++
|
||||
lib/master.c | 38 ++++++++++++++++++++++++++++++++++----
|
||||
modules/mount_autofs.c | 4 ++--
|
||||
7 files changed, 74 insertions(+), 27 deletions(-)
|
||||
|
||||
|
||||
diff --git a/daemon/automount.c b/daemon/automount.c
|
||||
index e120f50..f04273f 100644
|
||||
--- a/daemon/automount.c
|
||||
+++ b/daemon/automount.c
|
||||
@@ -69,8 +69,9 @@ static size_t kpkt_len;
|
||||
/* Does kernel know about SOCK_CLOEXEC and friends */
|
||||
static int cloexec_works = 0;
|
||||
|
||||
-/* Attribute to create detached thread */
|
||||
-pthread_attr_t thread_attr;
|
||||
+/* Attributes for creating detached and joinable threads */
|
||||
+pthread_attr_t th_attr;
|
||||
+pthread_attr_t th_attr_detached;
|
||||
|
||||
struct master_readmap_cond mrc = {
|
||||
PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, NULL, 0, 0, 0, 0};
|
||||
@@ -1192,7 +1193,7 @@ static pthread_t do_signals(struct master *master, int sig)
|
||||
if (status)
|
||||
fatal(status);
|
||||
|
||||
- status = pthread_create(&thid, &thread_attr, do_notify_state, &r_sig);
|
||||
+ status = pthread_create(&thid, &th_attr_detached, do_notify_state, &r_sig);
|
||||
if (status) {
|
||||
error(master->logopt,
|
||||
"mount state notify thread create failed");
|
||||
@@ -1281,7 +1282,7 @@ static int do_hup_signal(struct master *master, time_t age)
|
||||
|
||||
master->reading = 1;
|
||||
|
||||
- status = pthread_create(&thid, &thread_attr, do_read_master, NULL);
|
||||
+ status = pthread_create(&thid, &th_attr_detached, do_read_master, NULL);
|
||||
if (status) {
|
||||
error(logopt,
|
||||
"master read map thread create failed");
|
||||
@@ -1327,7 +1328,7 @@ static void *statemachine(void *arg)
|
||||
case SIGTERM:
|
||||
case SIGINT:
|
||||
case SIGUSR2:
|
||||
- if (master_list_empty(master_list))
|
||||
+ if (master_done(master_list))
|
||||
return NULL;
|
||||
case SIGUSR1:
|
||||
do_signals(master_list, sig);
|
||||
@@ -1448,8 +1449,6 @@ static void handle_mounts_cleanup(void *arg)
|
||||
master_mutex_unlock();
|
||||
|
||||
destroy_logpri_fifo(ap);
|
||||
- master_free_mapent_sources(ap->entry, 1);
|
||||
- master_free_mapent(ap->entry);
|
||||
|
||||
if (clean) {
|
||||
if (rmdir(path) == -1) {
|
||||
@@ -1461,8 +1460,12 @@ static void handle_mounts_cleanup(void *arg)
|
||||
|
||||
info(logopt, "shut down path %s", path);
|
||||
|
||||
- /* If we are the last tell the state machine to shutdown */
|
||||
- if (!submount && master_list_empty(master_list))
|
||||
+ /*
|
||||
+ * If we are not a submount send a signal to the signal handler
|
||||
+ * so it can join with any completed handle_mounts() threads and
|
||||
+ * perform final cleanup.
|
||||
+ */
|
||||
+ if (!submount)
|
||||
pthread_kill(state_mach_thid, SIGTERM);
|
||||
|
||||
return;
|
||||
@@ -1980,7 +1983,15 @@ int main(int argc, char *argv[])
|
||||
exit(1);
|
||||
}
|
||||
|
||||
- if (pthread_attr_init(&thread_attr)) {
|
||||
+ if (pthread_attr_init(&th_attr)) {
|
||||
+ logerr("%s: failed to init thread attribute struct!",
|
||||
+ program);
|
||||
+ close(start_pipefd[1]);
|
||||
+ release_flag_file();
|
||||
+ exit(1);
|
||||
+ }
|
||||
+
|
||||
+ if (pthread_attr_init(&th_attr_detached)) {
|
||||
logerr("%s: failed to init thread attribute struct!",
|
||||
program);
|
||||
close(start_pipefd[1]);
|
||||
@@ -1989,7 +2000,7 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
|
||||
if (pthread_attr_setdetachstate(
|
||||
- &thread_attr, PTHREAD_CREATE_DETACHED)) {
|
||||
+ &th_attr_detached, PTHREAD_CREATE_DETACHED)) {
|
||||
logerr("%s: failed to set detached thread attribute!",
|
||||
program);
|
||||
close(start_pipefd[1]);
|
||||
@@ -1999,7 +2010,7 @@ int main(int argc, char *argv[])
|
||||
|
||||
#ifdef _POSIX_THREAD_ATTR_STACKSIZE
|
||||
if (pthread_attr_setstacksize(
|
||||
- &thread_attr, PTHREAD_STACK_MIN*64)) {
|
||||
+ &th_attr_detached, PTHREAD_STACK_MIN*64)) {
|
||||
logerr("%s: failed to set stack size thread attribute!",
|
||||
program);
|
||||
close(start_pipefd[1]);
|
||||
diff --git a/daemon/direct.c b/daemon/direct.c
|
||||
index c0243c4..d9dda3d 100644
|
||||
--- a/daemon/direct.c
|
||||
+++ b/daemon/direct.c
|
||||
@@ -37,7 +37,8 @@
|
||||
|
||||
#include "automount.h"
|
||||
|
||||
-extern pthread_attr_t thread_attr;
|
||||
+/* Attribute to create detached thread */
|
||||
+extern pthread_attr_t th_attr_detached;
|
||||
|
||||
struct mnt_params {
|
||||
char *options;
|
||||
@@ -1142,7 +1143,7 @@ int handle_packet_expire_direct(struct autofs_point *ap, autofs_packet_expire_di
|
||||
debug(ap->logopt, "token %ld, name %s",
|
||||
(unsigned long) pkt->wait_queue_token, mt->name);
|
||||
|
||||
- status = pthread_create(&thid, &thread_attr, do_expire_direct, mt);
|
||||
+ status = pthread_create(&thid, &th_attr_detached, do_expire_direct, mt);
|
||||
if (status) {
|
||||
error(ap->logopt, "expire thread create failed");
|
||||
ops->send_fail(ap->logopt,
|
||||
@@ -1451,7 +1452,7 @@ int handle_packet_missing_direct(struct autofs_point *ap, autofs_packet_missing_
|
||||
mt->gid = pkt->gid;
|
||||
mt->wait_queue_token = pkt->wait_queue_token;
|
||||
|
||||
- status = pthread_create(&thid, &thread_attr, do_mount_direct, mt);
|
||||
+ status = pthread_create(&thid, &th_attr_detached, do_mount_direct, mt);
|
||||
if (status) {
|
||||
error(ap->logopt, "missing mount thread create failed");
|
||||
ops->send_fail(ap->logopt,
|
||||
diff --git a/daemon/indirect.c b/daemon/indirect.c
|
||||
index 9d3745c..0721707 100644
|
||||
--- a/daemon/indirect.c
|
||||
+++ b/daemon/indirect.c
|
||||
@@ -36,7 +36,8 @@
|
||||
|
||||
#include "automount.h"
|
||||
|
||||
-extern pthread_attr_t thread_attr;
|
||||
+/* Attribute to create detached thread */
|
||||
+extern pthread_attr_t th_attr_detached;
|
||||
|
||||
static pthread_mutex_t ea_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
@@ -647,7 +648,7 @@ int handle_packet_expire_indirect(struct autofs_point *ap, autofs_packet_expire_
|
||||
mt->len = pkt->len;
|
||||
mt->wait_queue_token = pkt->wait_queue_token;
|
||||
|
||||
- status = pthread_create(&thid, &thread_attr, do_expire_indirect, mt);
|
||||
+ status = pthread_create(&thid, &th_attr_detached, do_expire_indirect, mt);
|
||||
if (status) {
|
||||
error(ap->logopt, "expire thread create failed");
|
||||
ops->send_fail(ap->logopt,
|
||||
@@ -835,7 +836,7 @@ int handle_packet_missing_indirect(struct autofs_point *ap, autofs_packet_missin
|
||||
mt->gid = pkt->gid;
|
||||
mt->wait_queue_token = pkt->wait_queue_token;
|
||||
|
||||
- status = pthread_create(&thid, &thread_attr, do_mount_indirect, mt);
|
||||
+ status = pthread_create(&thid, &th_attr_detached, do_mount_indirect, mt);
|
||||
if (status) {
|
||||
error(ap->logopt, "expire thread create failed");
|
||||
ops->send_fail(ap->logopt,
|
||||
diff --git a/daemon/state.c b/daemon/state.c
|
||||
index 87c16a6..cd63be1 100644
|
||||
--- a/daemon/state.c
|
||||
+++ b/daemon/state.c
|
||||
@@ -16,7 +16,8 @@
|
||||
|
||||
#include "automount.h"
|
||||
|
||||
-extern pthread_attr_t thread_attr;
|
||||
+/* Attribute to create detached thread */
|
||||
+extern pthread_attr_t th_attr_detached;
|
||||
|
||||
struct state_queue {
|
||||
pthread_t thid;
|
||||
@@ -292,7 +293,7 @@ static enum expire expire_proc(struct autofs_point *ap, int now)
|
||||
else
|
||||
expire = expire_proc_direct;
|
||||
|
||||
- status = pthread_create(&thid, &thread_attr, expire, ea);
|
||||
+ status = pthread_create(&thid, &th_attr_detached, expire, ea);
|
||||
if (status) {
|
||||
error(ap->logopt,
|
||||
"expire thread create for %s failed", ap->path);
|
||||
@@ -519,7 +520,7 @@ static unsigned int st_readmap(struct autofs_point *ap)
|
||||
ra->ap = ap;
|
||||
ra->now = now;
|
||||
|
||||
- status = pthread_create(&thid, &thread_attr, do_readmap, ra);
|
||||
+ status = pthread_create(&thid, &th_attr_detached, do_readmap, ra);
|
||||
if (status) {
|
||||
error(ap->logopt, "read map thread create failed");
|
||||
st_readmap_cleanup(ra);
|
||||
diff --git a/include/master.h b/include/master.h
|
||||
index 6d801a9..c519e97 100644
|
||||
--- a/include/master.h
|
||||
+++ b/include/master.h
|
||||
@@ -48,6 +48,7 @@ struct master_mapent {
|
||||
struct map_source *maps;
|
||||
struct autofs_point *ap;
|
||||
struct list_head list;
|
||||
+ struct list_head join;
|
||||
};
|
||||
|
||||
struct master {
|
||||
@@ -61,6 +62,7 @@ struct master {
|
||||
unsigned int logopt;
|
||||
struct mapent_cache *nc;
|
||||
struct list_head mounts;
|
||||
+ struct list_head completed;
|
||||
};
|
||||
|
||||
/* From the yacc master map parser */
|
||||
@@ -109,6 +111,7 @@ void master_notify_state_change(struct master *, int);
|
||||
int master_mount_mounts(struct master *, time_t, int);
|
||||
extern inline unsigned int master_get_logopt(void);
|
||||
int master_list_empty(struct master *);
|
||||
+int master_done(struct master *);
|
||||
int master_kill(struct master *);
|
||||
|
||||
#endif
|
||||
diff --git a/lib/master.c b/lib/master.c
|
||||
index e1cc062..762094f 100644
|
||||
--- a/lib/master.c
|
||||
+++ b/lib/master.c
|
||||
@@ -32,8 +32,8 @@ struct master *master_list = NULL;
|
||||
|
||||
extern long global_negative_timeout;
|
||||
|
||||
-/* Attribute to create detached thread */
|
||||
-extern pthread_attr_t thread_attr;
|
||||
+/* Attribute to create a joinable thread */
|
||||
+extern pthread_attr_t th_attr;
|
||||
|
||||
extern struct startup_cond suc;
|
||||
|
||||
@@ -704,11 +704,16 @@ void master_add_mapent(struct master *master, struct master_mapent *entry)
|
||||
|
||||
void master_remove_mapent(struct master_mapent *entry)
|
||||
{
|
||||
+ struct master *master = entry->master;
|
||||
+
|
||||
if (entry->ap->submount)
|
||||
return;
|
||||
|
||||
- if (!list_empty(&entry->list))
|
||||
+ if (!list_empty(&entry->list)) {
|
||||
list_del_init(&entry->list);
|
||||
+ list_add(&entry->join, &master->completed);
|
||||
+ }
|
||||
+
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -786,6 +791,7 @@ struct master *master_new(const char *name, unsigned int timeout, unsigned int g
|
||||
master->logopt = master->default_logging;
|
||||
|
||||
INIT_LIST_HEAD(&master->mounts);
|
||||
+ INIT_LIST_HEAD(&master->completed);
|
||||
|
||||
return master;
|
||||
}
|
||||
@@ -993,7 +999,7 @@ static int master_do_mount(struct master_mapent *entry)
|
||||
|
||||
debug(ap->logopt, "mounting %s", entry->path);
|
||||
|
||||
- status = pthread_create(&thid, &thread_attr, handle_mounts, &suc);
|
||||
+ status = pthread_create(&thid, &th_attr, handle_mounts, &suc);
|
||||
if (status) {
|
||||
crit(ap->logopt,
|
||||
"failed to create mount handler thread for %s",
|
||||
@@ -1170,6 +1176,30 @@ int master_list_empty(struct master *master)
|
||||
return res;
|
||||
}
|
||||
|
||||
+int master_done(struct master *master)
|
||||
+{
|
||||
+ struct list_head *head, *p;
|
||||
+ struct master_mapent *entry;
|
||||
+ int res = 0;
|
||||
+
|
||||
+ master_mutex_lock();
|
||||
+ head = &master->completed;
|
||||
+ p = head->next;
|
||||
+ while (p != head) {
|
||||
+ entry = list_entry(p, struct master_mapent, join);
|
||||
+ p = p->next;
|
||||
+ list_del(&entry->join);
|
||||
+ pthread_join(entry->thid, NULL);
|
||||
+ master_free_mapent_sources(entry, 1);
|
||||
+ master_free_mapent(entry);
|
||||
+ }
|
||||
+ if (list_empty(&master->mounts))
|
||||
+ res = 1;
|
||||
+ master_mutex_unlock();
|
||||
+
|
||||
+ return res;
|
||||
+}
|
||||
+
|
||||
inline unsigned int master_get_logopt(void)
|
||||
{
|
||||
return master_list ? master_list->logopt : LOGOPT_NONE;
|
||||
diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
|
||||
index 82a5ef3..44fc043 100644
|
||||
--- a/modules/mount_autofs.c
|
||||
+++ b/modules/mount_autofs.c
|
||||
@@ -30,7 +30,7 @@
|
||||
#define MODPREFIX "mount(autofs): "
|
||||
|
||||
/* Attribute to create detached thread */
|
||||
-extern pthread_attr_t thread_attr;
|
||||
+extern pthread_attr_t th_attr_detached;
|
||||
extern struct startup_cond suc;
|
||||
|
||||
int mount_version = AUTOFS_MOUNT_VERSION; /* Required by protocol */
|
||||
@@ -235,7 +235,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
|
||||
suc.done = 0;
|
||||
suc.status = 0;
|
||||
|
||||
- if (pthread_create(&thid, &thread_attr, handle_mounts, &suc)) {
|
||||
+ if (pthread_create(&thid, &th_attr_detached, handle_mounts, &suc)) {
|
||||
crit(ap->logopt,
|
||||
MODPREFIX
|
||||
"failed to create mount handler thread for %s",
|
@ -0,0 +1,222 @@
|
||||
autofs-5.0.4 - make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit
|
||||
|
||||
From: Valerie Aurora Henson <vaurora@redhat.com>
|
||||
|
||||
Non-critical changes to make auditing buffer lengths easier.
|
||||
|
||||
* Some buffers were the wrong (too big) size, some were used twice for
|
||||
different purposes.
|
||||
* Use sizeof(buf) instead of repeating the *MAX* define in functions
|
||||
that need to know the size of a statically allocated buffer.
|
||||
* Fix a compiler warning about discarding the const on a string.
|
||||
---
|
||||
|
||||
CHANGELOG | 1 +
|
||||
modules/lookup_ldap.c | 51 ++++++++++++++++++++++---------------------------
|
||||
2 files changed, 24 insertions(+), 28 deletions(-)
|
||||
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index afd1335..417a001 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -15,6 +15,7 @@
|
||||
- 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.
|
||||
|
||||
4/11/2008 autofs-5.0.4
|
||||
-----------------------
|
||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
||||
index bee97ae..d8a60d3 100644
|
||||
--- a/modules/lookup_ldap.c
|
||||
+++ b/modules/lookup_ldap.c
|
||||
@@ -272,7 +272,7 @@ LDAP *init_ldap_connection(unsigned logopt, const char *uri, struct lookup_conte
|
||||
|
||||
static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt, const char *class, const char *key)
|
||||
{
|
||||
- char buf[PARSE_MAX_BUF];
|
||||
+ char buf[MAX_ERR_BUF];
|
||||
char *query, *dn, *qdn;
|
||||
LDAPMessage *result, *e;
|
||||
struct ldap_searchdn *sdns = NULL;
|
||||
@@ -296,7 +296,7 @@ static int get_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
|
||||
|
||||
query = alloca(l);
|
||||
if (query == NULL) {
|
||||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ char *estr = strerror_r(errno, buf, sizeof(buf));
|
||||
crit(logopt, MODPREFIX "alloca: %s", estr);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
@@ -1082,7 +1082,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
|
||||
}
|
||||
if (!tmp) {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
return 0;
|
||||
}
|
||||
@@ -1104,7 +1104,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
|
||||
tmp = malloc(l + 1);
|
||||
if (!tmp) {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
crit(logopt, MODPREFIX "malloc: %s", estr);
|
||||
return 0;
|
||||
}
|
||||
@@ -1139,7 +1139,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
|
||||
/* Isolate the server's name. */
|
||||
if (!tmp) {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
return 0;
|
||||
}
|
||||
@@ -1180,7 +1180,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
|
||||
ctxt->mapname = map;
|
||||
else {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
if (ctxt->server)
|
||||
free(ctxt->server);
|
||||
@@ -1191,7 +1191,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
|
||||
base = malloc(l + 1);
|
||||
if (!base) {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
if (ctxt->server)
|
||||
free(ctxt->server);
|
||||
@@ -1205,7 +1205,7 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
|
||||
char *map = malloc(l + 1);
|
||||
if (!map) {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
if (ctxt->server)
|
||||
free(ctxt->server);
|
||||
@@ -1318,7 +1318,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
||||
/* 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);
|
||||
+ char *estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
return 1;
|
||||
}
|
||||
@@ -1419,8 +1419,9 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
||||
unsigned int timeout = master->default_timeout;
|
||||
unsigned int logging = master->default_logging;
|
||||
unsigned int logopt = master->logopt;
|
||||
- int rv, l, count, blen;
|
||||
- char buf[PARSE_MAX_BUF];
|
||||
+ int rv, l, count;
|
||||
+ char buf[MAX_ERR_BUF];
|
||||
+ char parse_buf[PARSE_MAX_BUF];
|
||||
char *query;
|
||||
LDAPMessage *result, *e;
|
||||
char *class, *info, *entry;
|
||||
@@ -1442,7 +1443,7 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
||||
|
||||
query = alloca(l);
|
||||
if (query == NULL) {
|
||||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ char *estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "alloca: %s", estr);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
@@ -1532,19 +1533,13 @@ int lookup_read_master(struct master *master, time_t age, void *context)
|
||||
goto next;
|
||||
}
|
||||
|
||||
- blen = strlen(*keyValue) + 1 + strlen(*values) + 2;
|
||||
- if (blen > PARSE_MAX_BUF) {
|
||||
+ if (snprintf(parse_buf, sizeof(parse_buf), "%s %s",
|
||||
+ *keyValue, *values) >= sizeof(parse_buf)) {
|
||||
error(logopt, MODPREFIX "map entry too long");
|
||||
ldap_value_free(values);
|
||||
goto next;
|
||||
}
|
||||
- memset(buf, 0, PARSE_MAX_BUF);
|
||||
-
|
||||
- strcpy(buf, *keyValue);
|
||||
- strcat(buf, " ");
|
||||
- strcat(buf, *values);
|
||||
-
|
||||
- master_parse_entry(buf, timeout, logging, age);
|
||||
+ master_parse_entry(parse_buf, timeout, logging, age);
|
||||
next:
|
||||
ldap_value_free(keyValue);
|
||||
e = ldap_next_entry(ldap, e);
|
||||
@@ -1561,7 +1556,7 @@ static int get_percent_decoded_len(const char *name)
|
||||
{
|
||||
int escapes = 0;
|
||||
int escaped = 0;
|
||||
- char *tmp = name;
|
||||
+ const char *tmp = name;
|
||||
int look_for_close = 0;
|
||||
|
||||
while (*tmp) {
|
||||
@@ -2060,7 +2055,7 @@ static int do_get_entries(struct ldap_search_params *sp, struct map_source *sour
|
||||
mapent = malloc(v_len + 1);
|
||||
if (!mapent) {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
ldap_value_free_len(bvValues);
|
||||
goto next;
|
||||
@@ -2080,7 +2075,7 @@ static int do_get_entries(struct ldap_search_params *sp, struct map_source *sour
|
||||
mapent_len = new_size;
|
||||
} else {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "realloc: %s", estr);
|
||||
}
|
||||
}
|
||||
@@ -2181,7 +2176,7 @@ static int read_one_map(struct autofs_point *ap,
|
||||
|
||||
sp.query = alloca(l);
|
||||
if (sp.query == NULL) {
|
||||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ char *estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
return NSS_STATUS_UNAVAIL;
|
||||
}
|
||||
@@ -2335,7 +2330,7 @@ static int lookup_one(struct autofs_point *ap,
|
||||
|
||||
query = alloca(l);
|
||||
if (query == NULL) {
|
||||
- char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ char *estr = strerror_r(errno, buf, sizeof(buf));
|
||||
crit(ap->logopt, MODPREFIX "malloc: %s", estr);
|
||||
if (enc_len1) {
|
||||
free(enc_key1);
|
||||
@@ -2507,7 +2502,7 @@ static int lookup_one(struct autofs_point *ap,
|
||||
mapent = malloc(v_len + 1);
|
||||
if (!mapent) {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "malloc: %s", estr);
|
||||
ldap_value_free_len(bvValues);
|
||||
goto next;
|
||||
@@ -2527,7 +2522,7 @@ static int lookup_one(struct autofs_point *ap,
|
||||
mapent_len = new_size;
|
||||
} else {
|
||||
char *estr;
|
||||
- estr = strerror_r(errno, buf, MAX_ERR_BUF);
|
||||
+ estr = strerror_r(errno, buf, sizeof(buf));
|
||||
logerr(MODPREFIX "realloc: %s", estr);
|
||||
}
|
||||
}
|
61
autofs-5.0.4-renew-sasl-creds-upon-reconnect-fail.patch
Normal file
61
autofs-5.0.4-renew-sasl-creds-upon-reconnect-fail.patch
Normal file
@ -0,0 +1,61 @@
|
||||
autofs-5.0.4 - renew sasl creds upon reconnect fail
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
If a server re-connect fails it could be due to the authentication
|
||||
credentail having timed out. So we need to dispose of this and retry
|
||||
the connection including refreshing re-authenticating.
|
||||
---
|
||||
|
||||
CHANGELOG | 1 +
|
||||
modules/lookup_ldap.c | 17 +++++++++++++++++
|
||||
2 files changed, 18 insertions(+), 0 deletions(-)
|
||||
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index b093451..7dee674 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -11,6 +11,7 @@
|
||||
- use CLOEXEC flag for setmntent also.
|
||||
- fix hosts map use after free.
|
||||
- fix uri list locking (again).
|
||||
+- check for stale SASL credentials upon connect fail.
|
||||
|
||||
4/11/2008 autofs-5.0.4
|
||||
-----------------------
|
||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
||||
index b6784e1..bee97ae 100644
|
||||
--- a/modules/lookup_ldap.c
|
||||
+++ b/modules/lookup_ldap.c
|
||||
@@ -675,6 +675,13 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
|
||||
|
||||
if (ctxt->server || !ctxt->uris) {
|
||||
ldap = do_connect(logopt, ctxt->server, ctxt);
|
||||
+#ifdef WITH_SASL
|
||||
+ /* Dispose of the sasl authentication connection and try again. */
|
||||
+ if (!ldap) {
|
||||
+ autofs_sasl_dispose(ctxt);
|
||||
+ ldap = connect_to_server(logopt, ctxt->server, ctxt);
|
||||
+ }
|
||||
+#endif
|
||||
return ldap;
|
||||
}
|
||||
|
||||
@@ -682,6 +689,16 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
|
||||
this = ctxt->uri;
|
||||
uris_mutex_unlock(ctxt);
|
||||
ldap = do_connect(logopt, this->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) {
|
||||
+ autofs_sasl_dispose(ctxt);
|
||||
+ ldap = connect_to_server(logopt, this->uri, ctxt);
|
||||
+ }
|
||||
+#endif
|
||||
if (ldap)
|
||||
return ldap;
|
||||
|
224
autofs-5.0.4-uris-list-locking-fix.patch
Normal file
224
autofs-5.0.4-uris-list-locking-fix.patch
Normal file
@ -0,0 +1,224 @@
|
||||
autofs-5.0.4 - uris list locking fix
|
||||
|
||||
From: Ian Kent <raven@themaw.net>
|
||||
|
||||
The ldap uris list doesn't need to change we just need to keep
|
||||
track of current server uri in the list and try to connect in
|
||||
a round robin order. Also it's possible multiple concurrent
|
||||
connection attempts may not be able to use the full list of
|
||||
servers (if one is present).
|
||||
---
|
||||
|
||||
CHANGELOG | 1 +
|
||||
include/lookup_ldap.h | 3 +-
|
||||
modules/lookup_ldap.c | 68 ++++++++++++++++++++++---------------------------
|
||||
3 files changed, 33 insertions(+), 39 deletions(-)
|
||||
|
||||
|
||||
diff --git a/CHANGELOG b/CHANGELOG
|
||||
index 3199e4d..b093451 100644
|
||||
--- a/CHANGELOG
|
||||
+++ b/CHANGELOG
|
||||
@@ -10,6 +10,7 @@
|
||||
- clear the quoted flag after each character from program map input.
|
||||
- use CLOEXEC flag for setmntent also.
|
||||
- fix hosts map use after free.
|
||||
+- fix uri list locking (again).
|
||||
|
||||
4/11/2008 autofs-5.0.4
|
||||
-----------------------
|
||||
diff --git a/include/lookup_ldap.h b/include/lookup_ldap.h
|
||||
index f9ed778..b47bf5d 100644
|
||||
--- a/include/lookup_ldap.h
|
||||
+++ b/include/lookup_ldap.h
|
||||
@@ -55,7 +55,8 @@ struct lookup_context {
|
||||
* given in configuration.
|
||||
*/
|
||||
pthread_mutex_t uris_mutex;
|
||||
- struct list_head *uri;
|
||||
+ struct list_head *uris;
|
||||
+ struct ldap_uri *uri;
|
||||
char *cur_host;
|
||||
struct ldap_searchdn *sdns;
|
||||
|
||||
diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
|
||||
index 6ba80eb..b6784e1 100644
|
||||
--- a/modules/lookup_ldap.c
|
||||
+++ b/modules/lookup_ldap.c
|
||||
@@ -137,7 +137,7 @@ static void uris_mutex_unlock(struct lookup_context *ctxt)
|
||||
return;
|
||||
}
|
||||
|
||||
-int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
|
||||
+int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
|
||||
{
|
||||
int rv;
|
||||
|
||||
@@ -147,16 +147,14 @@ int bind_ldap_anonymous(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt
|
||||
rv = ldap_simple_bind_s(ldap, NULL, NULL);
|
||||
|
||||
if (rv != LDAP_SUCCESS) {
|
||||
- if (!ctxt->uri) {
|
||||
+ if (!ctxt->uris) {
|
||||
crit(logopt, MODPREFIX
|
||||
"Unable to bind to the LDAP server: "
|
||||
"%s, error %s", ctxt->server ? "" : "(default)",
|
||||
ldap_err2string(rv));
|
||||
} else {
|
||||
- struct ldap_uri *uri;
|
||||
- uri = list_entry(ctxt->uri->next, struct ldap_uri, list);
|
||||
info(logopt, MODPREFIX "Unable to bind to the LDAP server: "
|
||||
- "%s, error %s", uri->uri, ldap_err2string(rv));
|
||||
+ "%s, error %s", uri, ldap_err2string(rv));
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@@ -498,7 +496,7 @@ static int find_query_dn(unsigned logopt, LDAP *ldap, struct lookup_context *ctx
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
|
||||
+static int do_bind(unsigned logopt, LDAP *ldap, const char *uri, struct lookup_context *ctxt)
|
||||
{
|
||||
char *host = NULL, *nhost;
|
||||
int rv, need_base = 1;
|
||||
@@ -511,11 +509,11 @@ static int do_bind(unsigned logopt, LDAP *ldap, struct lookup_context *ctxt)
|
||||
rv = autofs_sasl_bind(logopt, ldap, ctxt);
|
||||
debug(logopt, MODPREFIX "autofs_sasl_bind returned %d", rv);
|
||||
} else {
|
||||
- rv = bind_ldap_anonymous(logopt, ldap, ctxt);
|
||||
+ rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt);
|
||||
debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
|
||||
}
|
||||
#else
|
||||
- rv = bind_ldap_anonymous(logopt, ldap, ctxt);
|
||||
+ rv = bind_ldap_anonymous(logopt, ldap, uri, ctxt);
|
||||
debug(logopt, MODPREFIX "ldap anonymous bind returned %d", rv);
|
||||
#endif
|
||||
|
||||
@@ -584,7 +582,7 @@ static LDAP *do_connect(unsigned logopt, const char *uri, struct lookup_context
|
||||
if (!ldap)
|
||||
return NULL;
|
||||
|
||||
- if (!do_bind(logopt, ldap, ctxt)) {
|
||||
+ if (!do_bind(logopt, ldap, uri, ctxt)) {
|
||||
unbind_ldap_connection(logopt, ldap, ctxt);
|
||||
return NULL;
|
||||
}
|
||||
@@ -612,7 +610,7 @@ static LDAP *connect_to_server(unsigned logopt, const char *uri, struct lookup_c
|
||||
return NULL;
|
||||
}
|
||||
|
||||
- if (!do_bind(logopt, ldap, ctxt)) {
|
||||
+ if (!do_bind(logopt, ldap, uri, ctxt)) {
|
||||
unbind_ldap_connection(logopt, ldap, ctxt);
|
||||
autofs_sasl_dispose(ctxt);
|
||||
error(logopt, MODPREFIX "cannot bind to server");
|
||||
@@ -638,36 +636,34 @@ static LDAP *find_server(unsigned logopt, struct lookup_context *ctxt)
|
||||
{
|
||||
LDAP *ldap = NULL;
|
||||
struct ldap_uri *this;
|
||||
- struct list_head *p;
|
||||
- LIST_HEAD(tmp);
|
||||
+ struct list_head *p, *first;
|
||||
|
||||
/* Try each uri in list, add connect fails to tmp list */
|
||||
uris_mutex_lock(ctxt);
|
||||
- p = ctxt->uri->next;
|
||||
- while(p != ctxt->uri) {
|
||||
+ if (!ctxt->uri)
|
||||
+ first = ctxt->uris;
|
||||
+ else
|
||||
+ first = &ctxt->uri->list;
|
||||
+ uris_mutex_unlock(ctxt);
|
||||
+ p = first->next;
|
||||
+ while(p != first) {
|
||||
+ /* Skip list head */
|
||||
+ if (p == ctxt->uris) {
|
||||
+ p = p->next;
|
||||
+ continue;
|
||||
+ }
|
||||
this = list_entry(p, struct ldap_uri, list);
|
||||
- uris_mutex_unlock(ctxt);
|
||||
debug(logopt, "trying server %s", this->uri);
|
||||
ldap = connect_to_server(logopt, this->uri, ctxt);
|
||||
if (ldap) {
|
||||
info(logopt, "connected to uri %s", this->uri);
|
||||
uris_mutex_lock(ctxt);
|
||||
+ ctxt->uri = this;
|
||||
+ uris_mutex_unlock(ctxt);
|
||||
break;
|
||||
}
|
||||
- uris_mutex_lock(ctxt);
|
||||
p = p->next;
|
||||
- list_del_init(&this->list);
|
||||
- list_add_tail(&this->list, &tmp);
|
||||
}
|
||||
- /*
|
||||
- * Successfuly connected uri (head of list) and untried uris are
|
||||
- * in ctxt->uri list. Make list of remainder and failed uris with
|
||||
- * failed uris at end and assign back to ctxt-uri.
|
||||
- */
|
||||
- list_splice(ctxt->uri, &tmp);
|
||||
- INIT_LIST_HEAD(ctxt->uri);
|
||||
- list_splice(&tmp, ctxt->uri);
|
||||
- uris_mutex_unlock(ctxt);
|
||||
|
||||
return ldap;
|
||||
}
|
||||
@@ -677,23 +673,19 @@ static LDAP *do_reconnect(unsigned logopt, struct lookup_context *ctxt)
|
||||
struct ldap_uri *this;
|
||||
LDAP *ldap;
|
||||
|
||||
- if (ctxt->server || !ctxt->uri) {
|
||||
+ if (ctxt->server || !ctxt->uris) {
|
||||
ldap = do_connect(logopt, ctxt->server, ctxt);
|
||||
return ldap;
|
||||
}
|
||||
|
||||
uris_mutex_lock(ctxt);
|
||||
- this = list_entry(ctxt->uri->next, struct ldap_uri, list);
|
||||
+ this = ctxt->uri;
|
||||
uris_mutex_unlock(ctxt);
|
||||
ldap = do_connect(logopt, this->uri, ctxt);
|
||||
if (ldap)
|
||||
return ldap;
|
||||
|
||||
- /* Failed to connect, put at end of list */
|
||||
- uris_mutex_lock(ctxt);
|
||||
- list_del_init(&this->list);
|
||||
- list_add_tail(&this->list, ctxt->uri);
|
||||
- uris_mutex_unlock(ctxt);
|
||||
+ /* Failed to connect, try to find a new server */
|
||||
|
||||
#ifdef WITH_SASL
|
||||
autofs_sasl_dispose(ctxt);
|
||||
@@ -1259,8 +1251,8 @@ static void free_context(struct lookup_context *ctxt)
|
||||
free(ctxt->cur_host);
|
||||
if (ctxt->base)
|
||||
free(ctxt->base);
|
||||
- if (ctxt->uri)
|
||||
- defaults_free_uris(ctxt->uri);
|
||||
+ if (ctxt->uris)
|
||||
+ defaults_free_uris(ctxt->uris);
|
||||
ret = pthread_mutex_destroy(&ctxt->uris_mutex);
|
||||
if (ret)
|
||||
fatal(ret);
|
||||
@@ -1344,7 +1336,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
||||
if (uris) {
|
||||
validate_uris(uris);
|
||||
if (!list_empty(uris))
|
||||
- ctxt->uri = uris;
|
||||
+ ctxt->uris = uris;
|
||||
else {
|
||||
error(LOGOPT_ANY,
|
||||
"no valid uris found in config list"
|
||||
@@ -1375,7 +1367,7 @@ int lookup_init(const char *mapfmt, int argc, const char *const *argv, void **co
|
||||
}
|
||||
#endif
|
||||
|
||||
- if (ctxt->server || !ctxt->uri) {
|
||||
+ if (ctxt->server || !ctxt->uris) {
|
||||
ldap = connect_to_server(LOGOPT_NONE, ctxt->server, ctxt);
|
||||
if (!ldap) {
|
||||
free_context(ctxt);
|
41
autofs.spec
41
autofs.spec
@ -4,7 +4,7 @@
|
||||
Summary: A tool for automatically mounting and unmounting filesystems
|
||||
Name: autofs
|
||||
Version: 5.0.4
|
||||
Release: 8
|
||||
Release: 9
|
||||
Epoch: 1
|
||||
License: GPLv2+
|
||||
Group: System Environment/Daemons
|
||||
@ -19,6 +19,18 @@ Patch6: autofs-5.0.4-fix-select-fd-limit.patch
|
||||
Patch7: autofs-5.0.4-make-hash-table-scale-to-thousands-of-entries.patch
|
||||
Patch8: autofs-5.0.4-fix-quoted-mess.patch
|
||||
Patch9: autofs-5.0.4-use-CLOEXEC-flag-setmntent.patch
|
||||
Patch10: autofs-5.0.4-fix-hosts-map-use-after-free.patch
|
||||
Patch11: autofs-5.0.4-uris-list-locking-fix.patch
|
||||
Patch12: autofs-5.0.4-renew-sasl-creds-upon-reconnect-fail.patch
|
||||
Patch13: autofs-5.0.4-library-reload-fix-update.patch
|
||||
Patch14: autofs-5.0.4-force-unlink-umount.patch
|
||||
Patch15: autofs-5.0.4-always-read-file-maps.patch
|
||||
Patch16: autofs-5.0.4-code-analysis-corrections.patch
|
||||
Patch17: autofs-5.0.4-make-MAX_ERR_BUF-and-PARSE_MAX_BUF-use-easier-to-audit.patch
|
||||
Patch18: autofs-5.0.4-easy-alloca-replacements.patch
|
||||
Patch19: autofs-5.0.4-configure-libtirpc.patch
|
||||
Patch20: autofs-5.0.4-ipv6-name-and-address-support.patch
|
||||
Patch21: autofs-5.0.4-ipv6-parse.patch
|
||||
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
|
||||
BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel module-init-tools util-linux nfs-utils e2fsprogs
|
||||
Requires: kernel >= 2.6.17
|
||||
@ -69,10 +81,22 @@ echo %{version}-%{release} > .version
|
||||
%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
|
||||
|
||||
%build
|
||||
#CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
|
||||
%configure --disable-mount-locking --enable-ignore-busy
|
||||
%configure --disable-mount-locking --enable-ignore-busy --with-libtirpc
|
||||
make initdir=%{_initrddir} DONTSTRIP=1
|
||||
|
||||
%install
|
||||
@ -121,6 +145,19 @@ fi
|
||||
%{_libdir}/autofs/
|
||||
|
||||
%changelog
|
||||
* Mon Feb 16 2009 Ian Kent <ikent@redhat.com> - 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 <ikent@redhat.com> - 5.0.4-8
|
||||
- rename program map parsing bug fix patch.
|
||||
- use CLOEXEC flag functionality for setmntent also, if present.
|
||||
|
Loading…
Reference in New Issue
Block a user