]> git.proxmox.com Git - swtpm.git/commitdiff
swtpm: move process owership to common file and enable in all implementations
authorStefan Berger <stefanb@us.ibm.com>
Sat, 26 Dec 2015 21:37:58 +0000 (16:37 -0500)
committerStefan Berger <stefanb@ulinux.vnet.ibm.com>
Sun, 27 Dec 2015 23:17:49 +0000 (18:17 -0500)
Move the code to change process ownership into its own function and enable
--runas|-r <owner> in all implementations.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
man/man8/swtpm.8
man/man8/swtpm.pod
src/swtpm/cuse_tpm.c
src/swtpm/swtpm.c
src/swtpm/swtpm_chardev.c
src/swtpm/utils.c
src/swtpm/utils.h

index 0c2f931e6f92c5132abb8e931d449a98127bb2be..bbac1bc92a35d1559776a65511c2a260e70494cd 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "swtpm 8"
-.TH swtpm 8 "2015-12-20" "swtpm" ""
+.TH swtpm 8 "2015-12-26" "swtpm" ""
 .\" For nroff, turn off justification.  Always turn off hyphenation; it makes
 .\" way too many mistakes in technical documents.
 .if n .ad l
@@ -282,6 +282,9 @@ A maximum of 32 bytes are read from the file and a key is derived from it using
 .IX Item "--pid file=<pidfile>"
 This options allows to set the name of file where the process \s-1ID \s0(pid) of the \s-1TPM\s0
 will be written into.
+.IP "\fB\-r|\-\-runas <owner>\fR" 4
+.IX Item "-r|--runas <owner>"
+Switch to the given user. This option can only be used when swtpm is started as root.
 .IP "\fB\-h|\-\-help\fR" 4
 .IX Item "-h|--help"
 Display usage info.
index 3a021b4872e2728f6f62e4cd53a2335d9f486030..b2134a7b2effb77760770cb22993571aaeacdf62 100644 (file)
@@ -189,6 +189,10 @@ SHA512 hash. Currently only 128 bit keys are supported.
 This options allows to set the name of file where the process ID (pid) of the TPM
 will be written into.
 
+=item B<-r|--runas E<lt>ownerE<gt>>
+
+Switch to the given user. This option can only be used when swtpm is started as root.
+
 =item B<-h|--help>
 
 Display usage info.
index b2c39873b8063adb605064a807283b622e2f13cb..4cd1a5593d77b12b13da1adff59be24aa77b8a4a 100644 (file)
@@ -73,6 +73,7 @@
 #include "swtpm_nvfile.h"
 #include "tpmlib.h"
 #include "main.h"
+#include "utils.h"
 
 /* maximum size of request buffer */
 #define TPM_REQ_MAX 4096
@@ -217,6 +218,8 @@ static const char *usage =
 "                    :  set the directory where the TPM's state will be written\n"
 "                       into; the TPM_PATH environment variable can be used\n"
 "                       instead\n"
+"-r|--runas <user>   :  after creating the CUSE device, change to the given\n"
+"                       user\n"
 ""
 "-h|--help           :  display this help screen and terminate\n"
 "\n";
@@ -1309,7 +1312,7 @@ error_not_running:
 static void ptm_init_done(void *userdata)
 {
     struct cuse_param *param = userdata;
-    struct passwd *passwd = NULL;
+    int ret;
 
     /* at this point the entry in /dev/ is available */
     if (pidfile_write(getpid()) < 0) {
@@ -1317,31 +1320,9 @@ static void ptm_init_done(void *userdata)
     }
 
     if (param->runas) {
-        passwd = getpwnam(param->runas);
-        if (!passwd) {
-            logprintf(STDERR_FILENO,
-                      "Error: User '%s' does not exist.\n",
-                      param->runas);
-            exit(-14);
-        }
-        if (initgroups(passwd->pw_name, passwd->pw_gid) < 0) {
-            logprintf(STDERR_FILENO,
-                      "Error: initgroups(%s, %d) failed.\n",
-                      passwd->pw_name, passwd->pw_gid);
-            exit(-10);
-        }
-        if (setgid(passwd->pw_gid) < 0) {
-            logprintf(STDERR_FILENO,
-                      "Error: setgid(%d) failed.\n",
-                      passwd->pw_gid);
-            exit(-11);
-        }
-        if (setuid(passwd->pw_uid) < 0) {
-            logprintf(STDERR_FILENO,
-                      "Error: setuid(%d) failed.\n",
-                      passwd->pw_uid);
-            exit(-12);
-        }
+        ret = change_process_owner(param->runas);
+        if (ret)
+            exit(ret);
     }
 }
 
index 943ad2fae928b4b95ebe72cc8706c2dcaed6fa07..57fbd9f0225fef8c749371389be407dea06c76ef 100644 (file)
@@ -125,6 +125,7 @@ static void usage(FILE *file, const char *prgname, const char *iface)
     "                 : set the directory where the TPM's state will be written\n"
     "                   into; the TPM_PATH environment variable can be used\n"
     "                   instead\n"
+    "-r|--runas <user>: change to the given user\n"
     "-h|--help        : display this help screen and terminate\n"
     "\n",
     prgname, iface);
@@ -146,6 +147,7 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
     char *logdata = NULL;
     char *piddata = NULL;
     char *tpmstatedata = NULL;
+    char *runas = NULL;
 #ifdef DEBUG
     time_t              start_time;
 #endif
@@ -154,6 +156,7 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
         {"help"      ,       no_argument, 0, 'h'},
         {"port"      , required_argument, 0, 'p'},
         {"fd"        , required_argument, 0, 'f'},
+        {"runas"     , required_argument, 0, 'r'},
         {"terminate" ,       no_argument, 0, 't'},
         {"log"       , required_argument, 0, 'l'},
         {"key"       , required_argument, 0, 'k'},
@@ -163,7 +166,7 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
     };
 
     while (TRUE) {
-        opt = getopt_long(argc, argv, "dhp:f:t", longopts, &longindex);
+        opt = getopt_long(argc, argv, "dhp:f:tr:", longopts, &longindex);
 
         if (opt == -1)
             break;
@@ -238,12 +241,22 @@ int swtpm_main(int argc, char **argv, const char *prgname, const char *iface)
             usage(stdout, prgname, iface);
             exit(EXIT_SUCCESS);
 
+        case 'r':
+            runas = optarg;
+            break;
+
         default:
             usage(stderr, prgname, iface);
             exit(EXIT_FAILURE);
         }
     }
 
+    /* change process ownership before accessing files */
+    if (runas) {
+        if (change_process_owner(runas) < 0)
+            return EXIT_FAILURE;
+    }
+
     if (handle_log_options(logdata) < 0 ||
         handle_key_options(keydata) < 0 ||
         handle_pid_options(piddata) < 0 ||
index 41ccf1b16f9ffd476eb180f0087f38a2e7094e68..50c9fe68ea2cbfcd730a436ad1c29261c1a6e829 100644 (file)
@@ -131,6 +131,7 @@ static void usage(FILE *file, const char *prgname, const char *iface)
     "                 : set the directory where the TPM's state will be written\n"
     "                   into; the TPM_PATH environment variable can be used\n"
     "                   instead\n"
+    "-r|--runas <user>: change to the given user\n"
     "-h|--help        : display this help screen and terminate\n"
     "\n",
     prgname, iface);
@@ -152,6 +153,7 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
     char *piddata = NULL;
     char *tpmstatedata = NULL;
     char *ctrlchdata = NULL;
+    char *runas = NULL;
 #ifdef DEBUG
     time_t              start_time;
 #endif
@@ -160,6 +162,7 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
         {"help"      ,       no_argument, 0, 'h'},
         {"chardev"   , required_argument, 0, 'c'},
         {"fd"        , required_argument, 0, 'f'},
+        {"runas"     , required_argument, 0, 'r'},
         {"log"       , required_argument, 0, 'l'},
         {"key"       , required_argument, 0, 'k'},
         {"pid"       , required_argument, 0, 'P'},
@@ -169,7 +172,7 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
     };
 
     while (TRUE) {
-        opt = getopt_long(argc, argv, "dhc:f:", longopts, &longindex);
+        opt = getopt_long(argc, argv, "dhc:f:r:", longopts, &longindex);
 
         if (opt == -1)
             break;
@@ -240,6 +243,10 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
             usage(stdout, prgname, iface);
             exit(EXIT_SUCCESS);
 
+        case 'r':
+            runas = optarg;
+            break;
+
         default:
             usage(stderr, prgname, iface);
             exit(EXIT_FAILURE);
@@ -251,6 +258,12 @@ int swtpm_chardev_main(int argc, char **argv, const char *prgname, const char *i
         return EXIT_FAILURE;
     }
 
+    /* change process ownership before accessing files */
+    if (runas) {
+        if (change_process_owner(runas) < 0)
+            return EXIT_FAILURE;
+    }
+
     if (handle_log_options(logdata) < 0 ||
         handle_key_options(keydata) < 0 ||
         handle_pid_options(piddata) < 0 ||
index 30cbe4c77594415fdf837e370dc5f4d0b8d8d46a..f9d91385040ae7b574bd4ffe1b401a5a8b574835 100644 (file)
@@ -37,6 +37,8 @@
 
 #include "config.h"
 
+#include <grp.h>
+#include <pwd.h>
 #include <fcntl.h>
 #include <unistd.h>
 
@@ -66,3 +68,35 @@ err_close_pipe:
 err_exit:
     return -1;
 }
+
+int
+change_process_owner(const char *user)
+{
+    struct passwd *passwd = getpwnam(user);
+
+    if (!passwd) {
+        logprintf(STDERR_FILENO,
+                  "Error: User '%s' does not exist.\n",
+                  user);
+        return 14;
+    }
+    if (initgroups(passwd->pw_name, passwd->pw_gid) < 0) {
+        logprintf(STDERR_FILENO,
+                  "Error: initgroups(%s, %d) failed.\n",
+                  passwd->pw_name, passwd->pw_gid);
+        return -10;
+    }
+    if (setgid(passwd->pw_gid) < 0) {
+        logprintf(STDERR_FILENO,
+                  "Error: setgid(%d) failed.\n",
+                  passwd->pw_gid);
+        return -11;
+    }
+    if (setuid(passwd->pw_uid) < 0) {
+        logprintf(STDERR_FILENO,
+                  "Error: setuid(%d) failed.\n",
+                  passwd->pw_uid);
+        return -12;
+    }
+    return 0;
+}
index 6191cd4d39e886a96daa30b22cf0b362f02728aa..2912ee4d11cd43b5cf6b57cdfb8ec4dc2a4fbc22 100644 (file)
@@ -42,5 +42,6 @@
 typedef void (*sighandler_t)(int);
 
 int install_sighandlers(int pipefd[2], sighandler_t handler);
+int change_process_owner(const char *owner);
 
 #endif /* _SWTPM_UTILS_H_ */