]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
nsenter: read default UID and GID from target process
authorThomas Weißschuh <thomas@t-8ch.de>
Fri, 3 Mar 2023 01:39:27 +0000 (01:39 +0000)
committerThomas Weißschuh <thomas@t-8ch.de>
Fri, 3 Mar 2023 01:47:09 +0000 (01:47 +0000)
Signed-off-by: Thomas Weißschuh <thomas@t-8ch.de>
Documentation/TODO
sys-utils/nsenter.1.adoc
sys-utils/nsenter.c

index e1ee6136213ce5a19b1bb6669b29752bc8abb1b0..52321d4319b5b805261a9ede0dce743988fee1ec 100644 (file)
@@ -66,11 +66,6 @@ lscpu
   - read cpuid and uname information from file if --sysroot is specified, then
     we can prepare regression tests completely independent on hw and architecture.
 
-nsenter(1)
-----------
- - read the default UID and GID from the target process.
-   http://thread.gmane.org/gmane.linux.utilities.util-linux-ng/9553/focus=9585
-
 hwclock
 ------
  - use /var/lib/hwclock/drift to store hw-clock drift numbers.
index 2500ff20716961b536c608997ee475571b21d8d1..513d2aa5746f738c9cf99bc4c34b6f3ff7165549 100644 (file)
@@ -103,11 +103,15 @@ Enter the cgroup namespace. If no file is specified, enter the cgroup namespace
 *-T*, *--time*[=_file_]::
 Enter the time namespace. If no file is specified, enter the time namespace of the target process. If _file_ is specified, enter the time namespace specified by _file_.
 
-*-G*, *--setgid* _gid_::
-Set the group ID which will be used in the entered namespace and drop supplementary groups. *nsenter* always sets GID for user namespaces, the default is 0.
-
-*-S*, *--setuid* _uid_::
-Set the user ID which will be used in the entered namespace. *nsenter* always sets UID for user namespaces, the default is 0.
+*-G*, *--setgid*[=_gid_]::
+Set the group ID which will be used in the entered namespace and drop supplementary groups.
+*nsenter* always sets GID for user namespaces, the default is 0.
+If no argument is specified the GID of the target process is used.
+
+*-S*, *--setuid*[=_uid_]::
+Set the user ID which will be used in the entered namespace.
+*nsenter* always sets UID for user namespaces, the default is 0.
+If no argument is specified the UID of the target process is used.
 
 *--preserve-credentials*::
 Don't modify UID and GID when enter user namespace. The default is to drops supplementary groups and sets GID and UID to 0.
index 440bf3b9f877b5e6522b5335530cc2e07f717df5..c55cf173c341299d8c0d13d11fbe1023a90ba27d 100644 (file)
@@ -89,8 +89,8 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(_(" -C, --cgroup[=<file>]  enter cgroup namespace\n"), out);
        fputs(_(" -U, --user[=<file>]    enter user namespace\n"), out);
        fputs(_(" -T, --time[=<file>]    enter time namespace\n"), out);
-       fputs(_(" -S, --setuid <uid>     set uid in entered namespace\n"), out);
-       fputs(_(" -G, --setgid <gid>     set gid in entered namespace\n"), out);
+       fputs(_(" -S, --setuid=[<uid>]   set uid in entered namespace\n"), out);
+       fputs(_(" -G, --setgid=[<gid>]   set gid in entered namespace\n"), out);
        fputs(_("     --preserve-credentials do not touch uids or gids\n"), out);
        fputs(_(" -r, --root[=<dir>]     set the root directory\n"), out);
        fputs(_(" -w, --wd[=<dir>]       set the working directory\n"), out);
@@ -110,6 +110,7 @@ static void __attribute__((__noreturn__)) usage(void)
 static pid_t namespace_target_pid = 0;
 static int root_fd = -1;
 static int wd_fd = -1;
+static int uid_gid_fd = -1;
 
 static void open_target_fd(int *fd, const char *type, const char *path)
 {
@@ -241,8 +242,8 @@ int main(int argc, char *argv[])
                { "user", optional_argument, NULL, 'U' },
                { "cgroup", optional_argument, NULL, 'C' },
                { "time", optional_argument, NULL, 'T' },
-               { "setuid", required_argument, NULL, 'S' },
-               { "setgid", required_argument, NULL, 'G' },
+               { "setuid", optional_argument, NULL, 'S' },
+               { "setgid", optional_argument, NULL, 'G' },
                { "root", optional_argument, NULL, 'r' },
                { "wd", optional_argument, NULL, 'w' },
                { "wdns", optional_argument, NULL, 'W' },
@@ -261,7 +262,7 @@ int main(int argc, char *argv[])
 
        struct namespace_file *nsfile;
        int c, pass, namespaces = 0, setgroups_nerrs = 0, preserve_cred = 0;
-       bool do_rd = false, do_wd = false, force_uid = false, force_gid = false;
+       bool do_rd = false, do_wd = false, do_uid = false, force_uid = false, do_gid = false, force_gid = false;
        bool do_all = false;
        int do_fork = -1; /* unknown yet */
        char *wdns = NULL;
@@ -277,7 +278,7 @@ int main(int argc, char *argv[])
        close_stdout_atexit();
 
        while ((c =
-               getopt_long(argc, argv, "+ahVt:m::u::i::n::p::C::U::T::S:G:r::w::W:FZ",
+               getopt_long(argc, argv, "+ahVt:m::u::i::n::p::C::U::T::S::G::r::w::W:FZ",
                            longopts, NULL)) != -1) {
 
                err_exclusive_options(c, longopts, excl, excl_st);
@@ -339,11 +340,17 @@ int main(int argc, char *argv[])
                                namespaces |= CLONE_NEWTIME;
                        break;
                case 'S':
-                       uid = strtoul_or_err(optarg, _("failed to parse uid"));
+                       if (optarg)
+                               uid = strtoul_or_err(optarg, _("failed to parse uid"));
+                       else
+                               do_uid = true;
                        force_uid = true;
                        break;
                case 'G':
-                       gid = strtoul_or_err(optarg, _("failed to parse gid"));
+                       if (optarg)
+                               gid = strtoul_or_err(optarg, _("failed to parse gid"));
+                       else
+                               do_gid = true;
                        force_gid = true;
                        break;
                case 'F':
@@ -420,6 +427,8 @@ int main(int argc, char *argv[])
                open_target_fd(&root_fd, "root", NULL);
        if (do_wd)
                open_target_fd(&wd_fd, "cwd", NULL);
+       if (do_uid || do_gid)
+               open_target_fd(&uid_gid_fd, "", NULL);
 
        /*
         * Update namespaces variable to contain all requested namespaces
@@ -510,6 +519,21 @@ int main(int argc, char *argv[])
                wd_fd = -1;
        }
 
+       if (uid_gid_fd >= 0) {
+               struct stat st;
+
+               if (fstat(uid_gid_fd, &st) > 0)
+                       err(EXIT_FAILURE, _("can not get process stat"));
+
+               close(uid_gid_fd);
+               uid_gid_fd = -1;
+
+               if (do_uid)
+                       uid = st.st_uid;
+               if (do_gid)
+                       gid = st.st_gid;
+       }
+
        if (do_fork == 1)
                continue_as_child();