dfbd7cf
From f2b7c3c6bc47ba547863a66d558dae7b9ed0ce63 Mon Sep 17 00:00:00 2001
dfbd7cf
From: TJ Saunders <tj@castaglia.org>
dfbd7cf
Date: Sun, 13 Jan 2013 16:43:07 -0800
dfbd7cf
Subject: [PATCH] Add use of the new pr_fsio_set_use_mkdtemp() API, to work
dfbd7cf
 around issues seen with mod_vroot due to the fix for
dfbd7cf
 Bug#3841.
dfbd7cf
dfbd7cf
---
dfbd7cf
 mod_vroot.c |   35 ++++++++++++++++++++++++++++++++---
dfbd7cf
 1 file changed, 32 insertions(+), 3 deletions(-)
dfbd7cf
dfbd7cf
diff --git mod_vroot/mod_vroot.c mod_vroot/mod_vroot.c
dfbd7cf
index e31f11d..2fba410 100644
dfbd7cf
--- contrib/mod_vroot.c
dfbd7cf
+++ contrib/mod_vroot.c
dfbd7cf
@@ -53,6 +53,8 @@
dfbd7cf
 static pool *vroot_dir_pool = NULL;
dfbd7cf
 static pr_table_t *vroot_dirtab = NULL;
dfbd7cf
 
dfbd7cf
+static int vroot_use_mkdtemp = FALSE;
dfbd7cf
+
dfbd7cf
 static unsigned int vroot_opts = 0;
dfbd7cf
 #define	VROOT_OPT_ALLOW_SYMLINKS	0x0001
dfbd7cf
 
dfbd7cf
@@ -777,6 +779,28 @@
dfbd7cf
   return res;
dfbd7cf
 }
dfbd7cf
 
dfbd7cf
+static int vroot_lchown(pr_fs_t *fs, const char *path, uid_t uid, gid_t gid) {
dfbd7cf
+  int res;
dfbd7cf
+  char vpath[PR_TUNABLE_PATH_MAX + 1];
dfbd7cf
+
dfbd7cf
+  if (session.curr_phase == LOG_CMD ||
dfbd7cf
+      session.curr_phase == LOG_CMD_ERR ||
dfbd7cf
+      (session.sf_flags & SF_ABORT) ||
dfbd7cf
+      *vroot_base == '\0') {
dfbd7cf
+    /* NOTE: once stackable FS modules are supported, have this fall through
dfbd7cf
+     * to the next module in the stack.
dfbd7cf
+     */
dfbd7cf
+    res = lchown(path, uid, gid);
dfbd7cf
+    return res;
dfbd7cf
+  }
dfbd7cf
+
dfbd7cf
+  if (vroot_lookup_path(NULL, vpath, sizeof(vpath)-1, path, 0, NULL) < 0)
dfbd7cf
+    return -1;
dfbd7cf
+
dfbd7cf
+  res = lchown(vpath, uid, gid);
dfbd7cf
+  return res;
dfbd7cf
+}
dfbd7cf
+
dfbd7cf
 static int vroot_chroot(pr_fs_t *fs, const char *path) {
dfbd7cf
   char *chroot_path = "/", *tmp = NULL;
dfbd7cf
   config_rec *c;
dfbd7cf
@@ -1390,6 +1414,26 @@
dfbd7cf
 /* Command handlers
dfbd7cf
  */
dfbd7cf
 
dfbd7cf
+MODRET vroot_pre_mkd(cmd_rec *cmd) {
dfbd7cf
+  if (vroot_engine == FALSE ||
dfbd7cf
+      session.chroot_path == NULL) {
dfbd7cf
+    return PR_DECLINED(cmd);
dfbd7cf
+  }
dfbd7cf
+
dfbd7cf
+  vroot_use_mkdtemp = pr_fsio_set_use_mkdtemp(FALSE);
dfbd7cf
+  return PR_DECLINED(cmd);
dfbd7cf
+}
dfbd7cf
+
dfbd7cf
+MODRET vroot_post_mkd(cmd_rec *cmd) {
dfbd7cf
+  if (vroot_engine == FALSE ||
dfbd7cf
+      session.chroot_path == NULL) {
dfbd7cf
+    return PR_DECLINED(cmd);
dfbd7cf
+  }
dfbd7cf
+
dfbd7cf
+  pr_fsio_set_use_mkdtemp(vroot_use_mkdtemp);
dfbd7cf
+  return PR_DECLINED(cmd);
dfbd7cf
+}
dfbd7cf
+
dfbd7cf
 MODRET vroot_pre_pass(cmd_rec *cmd) {
dfbd7cf
   pr_fs_t *fs = NULL;
dfbd7cf
   unsigned char *use_vroot = NULL;
dfbd7cf
@@ -1433,6 +1477,7 @@
dfbd7cf
   fs->truncate = vroot_truncate;
dfbd7cf
   fs->chmod = vroot_chmod;
dfbd7cf
   fs->chown = vroot_chown;
dfbd7cf
+  fs->lchown = vroot_lchown;
dfbd7cf
   fs->chdir = vroot_chdir;
dfbd7cf
   fs->chroot = vroot_chroot;
dfbd7cf
   fs->opendir = vroot_opendir;
dfbd7cf
@@ -1564,6 +1609,12 @@
dfbd7cf
   { PRE_CMD,		C_PASS,	G_NONE,	vroot_pre_pass, FALSE, FALSE },
dfbd7cf
   { POST_CMD,		C_PASS,	G_NONE,	vroot_post_pass, FALSE, FALSE },
dfbd7cf
   { POST_CMD_ERR,	C_PASS,	G_NONE,	vroot_post_pass_err, FALSE, FALSE },
dfbd7cf
+  { PRE_CMD,		C_MKD,	G_NONE,	vroot_pre_mkd, FALSE, FALSE },
dfbd7cf
+  { POST_CMD,		C_MKD,	G_NONE,	vroot_post_mkd, FALSE, FALSE },
dfbd7cf
+  { POST_CMD_ERR,	C_MKD,	G_NONE,	vroot_post_mkd, FALSE, FALSE },
dfbd7cf
+  { PRE_CMD,		C_XMKD,	G_NONE,	vroot_pre_mkd, FALSE, FALSE },
dfbd7cf
+  { POST_CMD,		C_XMKD,	G_NONE,	vroot_post_mkd, FALSE, FALSE },
dfbd7cf
+  { POST_CMD_ERR,	C_XMKD,	G_NONE,	vroot_post_mkd, FALSE, FALSE },
dfbd7cf
   { 0, NULL }
dfbd7cf
 };
dfbd7cf