diff --git a/CHANGELOG b/CHANGELOG index c0c6dd6..5a594ff 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -17,6 +17,7 @@ - cthon corrections for above patch and fix shutdown expire. - cthon fix expire of wildcard and program mounts broken by above patches. +- tidy up directory cleanup and add validation check to rmdir_path. 13/7/2006 autofs-5.0.1 rc1 -------------------------- diff --git a/daemon/automount.c b/daemon/automount.c index 9c3f1e9..736d54a 100644 --- a/daemon/automount.c +++ b/daemon/automount.c @@ -106,13 +106,14 @@ int mkdir_path(const char *path, mode_t } /* Remove as much as possible of a path */ -int rmdir_path(struct autofs_point *ap, const char *path) +int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev) { int len = strlen(path); char *buf = alloca(len + 1); char *cp; int first = 1; struct stat st; + struct statfs fs; strcpy(buf, path); cp = buf + len; @@ -131,15 +132,24 @@ int rmdir_path(struct autofs_point *ap, return -1; } - if (st.st_dev != ap->dev) { - crit(ap->logopt, "attempt to remove files from a " - "mounted file system!"); - crit(ap->logopt, - "ap->dev == %llu, \"%s\" dev == %llu", ap->dev, - buf, st.st_dev); + /* Termination condition removing full path within autofs fs */ + if (st.st_dev != dev) + return 0; + + if (statfs(buf, &fs) != 0) { + error(ap->logopt, "could not stat fs of %s", buf); return -1; } + if (fs.f_type != AUTOFS_SUPER_MAGIC) { + crit(ap->logopt, "attempt to remove directory from a " + "non-autofs filesystem!"); + crit(ap->logopt, + "requestor dev == %llu, \"%s\" owner dev == %llu", + dev, buf, st.st_dev); + return -1; + } + /* * Last element of path may be a symbolic link; all others * are directories (and the last directory element is diff --git a/daemon/direct.c b/daemon/direct.c index 974a50e..e6c1f35 100644 --- a/daemon/direct.c +++ b/daemon/direct.c @@ -715,8 +715,10 @@ out_close: out_umount: umount(me->key); out_err: - if (me->dir_created) - rmdir_path(ap, me->key); + if (is_autofs_fs) { + if (stat(me->key, &st) == 0 && me->dir_created) + rmdir_path(ap, me->key, st.st_dev); + } return -1; } diff --git a/daemon/indirect.c b/daemon/indirect.c index b57bbd1..970215c 100644 --- a/daemon/indirect.c +++ b/daemon/indirect.c @@ -226,7 +226,7 @@ out_umount: umount(ap->path); out_rmdir: if (ap->dir_created) - rmdir_path(ap, ap->path); + rmdir_path(ap, ap->path, ap->dev); out_err: if (options) free(options); diff --git a/daemon/lookup.c b/daemon/lookup.c index 87be647..aeda909 100644 --- a/daemon/lookup.c +++ b/daemon/lookup.c @@ -936,8 +936,12 @@ int lookup_prune_cache(struct autofs_poi status = CHE_FAIL; if (this->ioctlfd == -1) status = cache_delete(mc, key); - if (status != CHE_FAIL) - rmdir_path(ap, path); + if (status != CHE_FAIL) { + if (ap->type == LKP_INDIRECT) + rmdir_path(ap, path, ap->dev); + else + rmdir_path(ap, path, this->dev); + } } cache_unlock(mc); diff --git a/include/automount.h b/include/automount.h index f7345c5..1c6e0dc 100644 --- a/include/automount.h +++ b/include/automount.h @@ -208,7 +208,7 @@ int do_mount(struct autofs_point *ap, co int name_len, const char *what, const char *fstype, const char *options); int mkdir_path(const char *path, mode_t mode); -int rmdir_path(struct autofs_point *ap, const char *path); +int rmdir_path(struct autofs_point *ap, const char *path, dev_t dev); /* Prototype for module functions */ diff --git a/modules/lookup_file.c b/modules/lookup_file.c index 376da2e..6485ef2 100644 --- a/modules/lookup_file.c +++ b/modules/lookup_file.c @@ -949,7 +949,7 @@ static int check_map_indirect(struct aut cache_delete(mc, "*"); if (cache_delete(mc, key) && wild & (CHE_MISSING | CHE_FAIL)) - rmdir_path(ap, key); + rmdir_path(ap, key, ap->dev); pthread_cleanup_pop(1); } diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c index 4959c12..40864d8 100644 --- a/modules/lookup_ldap.c +++ b/modules/lookup_ldap.c @@ -1543,7 +1543,7 @@ static int check_map_indirect(struct aut cache_writelock(mc); pthread_cleanup_push(cache_lock_cleanup, mc); if (cache_delete(mc, key)) - rmdir_path(ap, key); + rmdir_path(ap, key, ap->dev); pthread_cleanup_pop(1); } diff --git a/modules/lookup_nisplus.c b/modules/lookup_nisplus.c index 4ea7609..e891c25 100644 --- a/modules/lookup_nisplus.c +++ b/modules/lookup_nisplus.c @@ -401,7 +401,7 @@ static int check_map_indirect(struct aut cache_delete(mc, "*"); if (cache_delete(mc, key) && wild & (CHE_MISSING | CHE_FAIL)) - rmdir_path(ap, key); + rmdir_path(ap, key, ap->dev); pthread_cleanup_pop(1); } diff --git a/modules/lookup_yp.c b/modules/lookup_yp.c index 483e586..29a72fb 100644 --- a/modules/lookup_yp.c +++ b/modules/lookup_yp.c @@ -507,7 +507,7 @@ static int check_map_indirect(struct aut cache_delete(mc, "*"); if (cache_delete(mc, key) && wild & (CHE_MISSING | CHE_FAIL)) - rmdir_path(ap, key); + rmdir_path(ap, key, ap->dev); pthread_cleanup_pop(1); } diff --git a/modules/mount_bind.c b/modules/mount_bind.c index 695dc9a..22abd91 100644 --- a/modules/mount_bind.c +++ b/modules/mount_bind.c @@ -154,11 +154,12 @@ int mount_mount(struct autofs_point *ap, what, fullpath, NULL); if (err) { - if ((!ap->ghost && name_len) || !existed) { - if (!chdir(ap->path)) - rmdir_path(ap, name); - err = chdir("/"); - } + if (ap->type != LKP_INDIRECT) + return 1; + + if ((!ap->ghost && name_len) || !existed) + rmdir_path(ap, fullpath, ap->dev); + return 1; } else { debug(ap->logopt, @@ -202,9 +203,8 @@ int mount_mount(struct autofs_point *ap, if (ap->ghost && !status) mkdir_path(fullpath, 0555); else { - if (!chdir(ap->path)) - rmdir_path(ap, name); - err = chdir("/"); + if (ap->type == LKP_INDIRECT) + rmdir_path(ap, fullpath, ap->dev); } return 1; } else { diff --git a/modules/mount_changer.c b/modules/mount_changer.c index 29485cb..83e6bdf 100644 --- a/modules/mount_changer.c +++ b/modules/mount_changer.c @@ -129,14 +129,16 @@ int mount_mount(struct autofs_point *ap, } if (err) { - if ((!ap->ghost && name_len) || !existed) { - if (!chdir(ap->path)) - rmdir_path(ap, name); - chdir("/"); - } error(ap->logopt, MODPREFIX "failed to mount %s (type %s) on %s", what, fstype, fullpath); + + if (ap->type != LKP_INDIRECT) + return 1; + + if ((!ap->ghost && name_len) || !existed) + rmdir_path(ap, fullpath, ap->dev); + return 1; } else { debug(ap->logopt, diff --git a/modules/mount_ext2.c b/modules/mount_ext2.c index b395235..deebf8b 100644 --- a/modules/mount_ext2.c +++ b/modules/mount_ext2.c @@ -145,14 +145,16 @@ #endif } if (err) { - if ((!ap->ghost && name_len) || !existed) { - if (!chdir(ap->path)) - rmdir_path(ap, name); - err = chdir("/"); - } error(ap->logopt, MODPREFIX "failed to mount %s (type %s) on %s", what, fstype, fullpath); + + if (ap->type != LKP_INDIRECT) + return 1; + + if ((!ap->ghost && name_len) || !existed) + rmdir_path(ap, fullpath, ap->dev); + return 1; } else { debug(ap->logopt, diff --git a/modules/mount_generic.c b/modules/mount_generic.c index 37ada41..9dabfce 100644 --- a/modules/mount_generic.c +++ b/modules/mount_generic.c @@ -105,15 +105,16 @@ int mount_mount(struct autofs_point *ap, } if (err) { - if ((!ap->ghost && name_len) || !existed) { - if (!chdir(ap->path)) - rmdir_path(ap, name); - err = chdir("/"); - } error(ap->logopt, MODPREFIX "failed to mount %s (type %s) on %s", what, fstype, fullpath); + if (ap->type != LKP_INDIRECT) + return 1; + + if ((!ap->ghost && name_len) || !existed) + rmdir_path(ap, fullpath, ap->dev); + return 1; } else { debug(ap->logopt, diff --git a/modules/mount_nfs.c b/modules/mount_nfs.c index 0ab2faf..b24f54a 100644 --- a/modules/mount_nfs.c +++ b/modules/mount_nfs.c @@ -253,15 +253,16 @@ int mount_mount(struct autofs_point *ap, free_host_list(&hosts); /* If we get here we've failed to complete the mount */ - if ((!ap->ghost && name_len) || !existed) { - if (!chdir(ap->path)) - rmdir_path(ap, name); - err = chdir("/"); - } error(ap->logopt, MODPREFIX "nfs: mount failure %s on %s", what, fullpath); + if (ap->type != LKP_INDIRECT) + return 1; + + if ((!ap->ghost && name_len) || !existed) + rmdir_path(ap, fullpath, ap->dev); + return 1; }