autofs-5.0.7 - allow use of hosts map in maps From: Ian Kent At the moment the internal hosts map can only be use as an entry in the master map but there's no reason (I can think of so far) that it shouldn't be possible to use it in map entries. --- lib/parse_subs.c | 17 +++++++---- modules/mount_autofs.c | 29 ++++++++++++++++---- modules/parse_sun.c | 71 +++++++++++++++++++++++++++++++----------------- 3 files changed, 80 insertions(+), 37 deletions(-) diff --git a/lib/parse_subs.c b/lib/parse_subs.c index 2326838..dd2a784 100644 --- a/lib/parse_subs.c +++ b/lib/parse_subs.c @@ -35,6 +35,7 @@ static struct types map_type[] = { { "ldaps", 5 }, { "hesiod", 6 }, { "userdir", 7 }, + { "hosts", 5 }, }; static unsigned int map_type_count = sizeof(map_type)/sizeof(struct types); @@ -384,7 +385,7 @@ struct map_type_info *parse_map_type_info(const char *str) return NULL; } else { *pos++ = '\0'; - while (*pos == ' ') + while (*pos && *pos == ' ') *pos++ = '\0'; map = pos; break; @@ -412,7 +413,7 @@ struct map_type_info *parse_map_type_info(const char *str) return NULL; } else { *pos++ = '\0'; - while (*pos == ' ') + while (*pos && *pos == ' ') *pos++ = '\0'; map = pos; break; @@ -458,11 +459,13 @@ struct map_type_info *parse_map_type_info(const char *str) } } - info->map = strdup(map); - if (!info->map) { - free(buf); - free_map_type_info(info); - return NULL; + if (map) { + info->map = strdup(map); + if (!info->map) { + free(buf); + free_map_type_info(info); + return NULL; + } } free(buf); diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c index 8c1e600..319f2e4 100644 --- a/modules/mount_autofs.c +++ b/modules/mount_autofs.c @@ -62,6 +62,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, char buf[MAX_ERR_BUF]; char *options, *p; int len, ret; + int hosts = 0; /* Root offset of multi-mount */ len = strlen(root); @@ -123,6 +124,8 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, ghost = 1; else if (strncmp(cp, "symlink", 7) == 0) symlnk = 1; + else if (strncmp(cp, "hosts", 5) == 0) + hosts = 1; else if (strncmp(cp, "timeout=", 8) == 0) { char *val = strchr(cp, '='); unsigned tout; @@ -164,7 +167,10 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, if (symlnk) nap->flags |= MOUNT_FLAG_SYMLINK; - argc = 1; + if (hosts) + argc = 0; + else + argc = 1; if (options) { char *t = options; @@ -176,14 +182,27 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name, } argv = (const char **) alloca((argc + 1) * sizeof(char *)); - argc = 1; - - if (!(info = parse_map_type_info(what))) { + if (hosts) + argc = 0; + else + argc = 1; + + /* + * If a mount of a hosts map is being requested it will come + * ro us via the options. Catch that below when processing the + * option and create type info struct then. + */ + if (hosts) + info = parse_map_type_info("hosts:"); + else + info = parse_map_type_info(what); + if (!info) { error(ap->logopt, MODPREFIX "failed to parse map info"); master_free_mapent(entry); return 1; } - argv[0] = info->map; + if (info->map) + argv[0] = info->map; if (options) { p = options; diff --git a/modules/parse_sun.c b/modules/parse_sun.c index bc86b5d..5ab451e 100644 --- a/modules/parse_sun.c +++ b/modules/parse_sun.c @@ -708,14 +708,18 @@ static int sun_mount(struct autofs_point *ap, const char *root, rv = mount_nfs->mount_mount(ap, root, mountpoint, strlen(mountpoint), what, fstype, options, mount_nfs->context); } else { - what = alloca(loclen + 1); - if (*loc == ':') { - loclen--; - memcpy(what, loc + 1, loclen); - what[loclen] = '\0'; - } else { - memcpy(what, loc, loclen); - what[loclen] = '\0'; + if (!loclen) + what = NULL; + else { + what = alloca(loclen + 1); + if (*loc == ':') { + loclen--; + memcpy(what, loc + 1, loclen); + what[loclen] = '\0'; + } else { + memcpy(what, loc, loclen); + what[loclen] = '\0'; + } } debug(ap->logopt, MODPREFIX @@ -812,7 +816,8 @@ update_offset_entry(struct autofs_point *ap, const char *name, mc = source->mc; - if (!*path || !*loc) { + /* Internal hosts map may have loc == NULL */ + if (!*path) { error(ap->logopt, MODPREFIX "syntax error in offset %s -> %s", path, loc); return CHE_FAIL; @@ -846,8 +851,10 @@ update_offset_entry(struct autofs_point *ap, const char *name, if (*myoptions) { strcpy(m_mapent, "-"); strcat(m_mapent, myoptions); - strcat(m_mapent, " "); - strcat(m_mapent, loc); + if (loc) { + strcat(m_mapent, " "); + strcat(m_mapent, loc); + } } else strcpy(m_mapent, loc); @@ -1448,13 +1455,17 @@ int parse_mount(struct autofs_point *ap, const char *name, l = parse_mapent(p, options, &myoptions, &loc, ap->logopt); if (!l) { - cache_delete_offset_list(mc, name); - cache_multi_unlock(me); - cache_unlock(mc); - free(path); - free(options); - pthread_setcancelstate(cur_state, NULL); - return 1; + if (!(strstr(myoptions, "fstype=autofs") && + strstr(myoptions, "hosts"))) { + error(LOGOPT_ANY, "I think I'm a hosts map? l %d", l); + cache_delete_offset_list(mc, name); + cache_multi_unlock(me); + cache_unlock(mc); + free(path); + free(options); + pthread_setcancelstate(cur_state, NULL); + return 1; + } } p += l; @@ -1605,13 +1616,23 @@ int parse_mount(struct autofs_point *ap, const char *name, p = skipspace(p); } - loclen = strlen(loc); - if (loclen == 0) { - free(loc); - free(options); - error(ap->logopt, - MODPREFIX "entry %s is empty!", name); - return 1; + /* + * If options are asking for a hosts map loc should be + * NULL but we see it can contain junk, so .... + */ + if ((strstr(options, "fstype=autofs") && + strstr(options, "hosts"))) { + loc = NULL; + loclen = 0; + } else { + loclen = strlen(loc); + if (loclen == 0) { + free(loc); + free(options); + error(ap->logopt, + MODPREFIX "entry %s is empty!", name); + return 1; + } } debug(ap->logopt,