Accept uid and gid parameters in utils_mkdir()/utils_mkdir_recursive()
[lttng-tools.git] / src / common / runas.c
index 9029f8f74d7802416a97a5f22a0650da9378ce68..36be188fafb54036688930689d1d23781cbe000d 100644 (file)
@@ -17,6 +17,7 @@
  */
 
 #define _GNU_SOURCE
+#define _LGPL_SOURCE
 #include <errno.h>
 #include <limits.h>
 #include <stdio.h>
@@ -34,6 +35,7 @@
 #include <common/utils.h>
 #include <common/compat/mman.h>
 #include <common/compat/clone.h>
+#include <common/compat/getenv.h>
 
 #include "runas.h"
 
@@ -77,6 +79,31 @@ struct run_as_open_data {
        mode_t mode;
 };
 
+struct run_as_unlink_data {
+       const char *path;
+};
+
+struct run_as_recursive_rmdir_data {
+       const char *path;
+};
+
+#ifdef VALGRIND
+static
+int use_clone(void)
+{
+       return 0;
+}
+#else
+static
+int use_clone(void)
+{
+       return !lttng_secure_getenv("LTTNG_DEBUG_NOCLONE");
+}
+#endif
+
+LTTNG_HIDDEN
+int _utils_mkdir_recursive_unsafe(const char *path, mode_t mode);
+
 /*
  * Create recursively directory using the FULL path.
  */
@@ -90,7 +117,8 @@ int _mkdir_recursive(void *_data)
        path = data->path;
        mode = data->mode;
 
-       return utils_mkdir_recursive(path, mode);
+       /* Safe to call as we have transitioned to the requested uid/gid. */
+       return _utils_mkdir_recursive_unsafe(path, mode);
 }
 
 static
@@ -114,6 +142,34 @@ int _open(void *_data)
        return open(data->path, data->flags, data->mode);
 }
 
+static
+int _unlink(void *_data)
+{
+       int ret;
+       struct run_as_unlink_data *data = _data;
+
+       ret = unlink(data->path);
+       if (ret < 0) {
+               ret = -errno;
+       }
+
+       return ret;
+}
+
+static
+int _recursive_rmdir(void *_data)
+{
+       int ret;
+       struct run_as_recursive_rmdir_data *data = _data;
+
+       ret = utils_recursive_rmdir(data->path);
+       if (ret < 0) {
+               ret = -errno;
+       }
+
+       return ret;
+}
+
 static
 int child_run_as(void *_data)
 {
@@ -271,7 +327,7 @@ int run_as_noclone(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid)
 static
 int run_as(int (*cmd)(void *data), void *data, uid_t uid, gid_t gid)
 {
-       if (!getenv("LTTNG_DEBUG_NOCLONE")) {
+       if (use_clone()) {
                int ret;
 
                DBG("Using run_as_clone");
@@ -325,3 +381,25 @@ int run_as_open(const char *path, int flags, mode_t mode, uid_t uid, gid_t gid)
        data.mode = mode;
        return run_as(_open, &data, uid, gid);
 }
+
+LTTNG_HIDDEN
+int run_as_unlink(const char *path, uid_t uid, gid_t gid)
+{
+       struct run_as_unlink_data data;
+
+       DBG3("unlink() %s with for uid %d and gid %d",
+                       path, uid, gid);
+       data.path = path;
+       return run_as(_unlink, &data, uid, gid);
+}
+
+LTTNG_HIDDEN
+int run_as_recursive_rmdir(const char *path, uid_t uid, gid_t gid)
+{
+       struct run_as_recursive_rmdir_data data;
+
+       DBG3("recursive_rmdir() %s with for uid %d and gid %d",
+                       path, uid, gid);
+       data.path = path;
+       return run_as(_recursive_rmdir, &data, uid, gid);
+}
This page took 0.02544 seconds and 4 git commands to generate.