diff options
| author | Philip Sanderson <philip.k.sanderson@gmail.com> | 2011-01-20 22:37:28 -0500 |
|---|---|---|
| committer | Rusty Russell <rusty@rustcorp.com.au> | 2011-01-20 06:07:28 -0500 |
| commit | 8aeb36e8f6d7eaa9cafc970b700414205743b258 (patch) | |
| tree | 22add4e7eae6a329fb87180adb148a0b88b30516 /Documentation | |
| parent | 8a335bc631ac9c43675821580c26ebf95a3044ba (diff) | |
lguest: --username and --chroot options
I've attached a patch which implements dropping to privileges
and chrooting to a directory.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'Documentation')
| -rw-r--r-- | Documentation/lguest/lguest.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index dc73bc54cc4..f64b85bcd6d 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
| @@ -39,6 +39,9 @@ | |||
| 39 | #include <limits.h> | 39 | #include <limits.h> |
| 40 | #include <stddef.h> | 40 | #include <stddef.h> |
| 41 | #include <signal.h> | 41 | #include <signal.h> |
| 42 | #include <pwd.h> | ||
| 43 | #include <grp.h> | ||
| 44 | |||
| 42 | #include <linux/virtio_config.h> | 45 | #include <linux/virtio_config.h> |
| 43 | #include <linux/virtio_net.h> | 46 | #include <linux/virtio_net.h> |
| 44 | #include <linux/virtio_blk.h> | 47 | #include <linux/virtio_blk.h> |
| @@ -1872,6 +1875,8 @@ static struct option opts[] = { | |||
| 1872 | { "block", 1, NULL, 'b' }, | 1875 | { "block", 1, NULL, 'b' }, |
| 1873 | { "rng", 0, NULL, 'r' }, | 1876 | { "rng", 0, NULL, 'r' }, |
| 1874 | { "initrd", 1, NULL, 'i' }, | 1877 | { "initrd", 1, NULL, 'i' }, |
| 1878 | { "username", 1, NULL, 'u' }, | ||
| 1879 | { "chroot", 1, NULL, 'c' }, | ||
| 1875 | { NULL }, | 1880 | { NULL }, |
| 1876 | }; | 1881 | }; |
| 1877 | static void usage(void) | 1882 | static void usage(void) |
| @@ -1894,6 +1899,12 @@ int main(int argc, char *argv[]) | |||
| 1894 | /* If they specify an initrd file to load. */ | 1899 | /* If they specify an initrd file to load. */ |
| 1895 | const char *initrd_name = NULL; | 1900 | const char *initrd_name = NULL; |
| 1896 | 1901 | ||
| 1902 | /* Password structure for initgroups/setres[gu]id */ | ||
| 1903 | struct passwd *user_details = NULL; | ||
| 1904 | |||
| 1905 | /* Directory to chroot to */ | ||
| 1906 | char *chroot_path = NULL; | ||
| 1907 | |||
| 1897 | /* Save the args: we "reboot" by execing ourselves again. */ | 1908 | /* Save the args: we "reboot" by execing ourselves again. */ |
| 1898 | main_args = argv; | 1909 | main_args = argv; |
| 1899 | 1910 | ||
| @@ -1950,6 +1961,14 @@ int main(int argc, char *argv[]) | |||
| 1950 | case 'i': | 1961 | case 'i': |
| 1951 | initrd_name = optarg; | 1962 | initrd_name = optarg; |
| 1952 | break; | 1963 | break; |
| 1964 | case 'u': | ||
| 1965 | user_details = getpwnam(optarg); | ||
| 1966 | if (!user_details) | ||
| 1967 | err(1, "getpwnam failed, incorrect username?"); | ||
| 1968 | break; | ||
| 1969 | case 'c': | ||
| 1970 | chroot_path = optarg; | ||
| 1971 | break; | ||
| 1953 | default: | 1972 | default: |
| 1954 | warnx("Unknown argument %s", argv[optind]); | 1973 | warnx("Unknown argument %s", argv[optind]); |
| 1955 | usage(); | 1974 | usage(); |
| @@ -2021,6 +2040,37 @@ int main(int argc, char *argv[]) | |||
| 2021 | /* If we exit via err(), this kills all the threads, restores tty. */ | 2040 | /* If we exit via err(), this kills all the threads, restores tty. */ |
| 2022 | atexit(cleanup_devices); | 2041 | atexit(cleanup_devices); |
| 2023 | 2042 | ||
| 2043 | /* If requested, chroot to a directory */ | ||
| 2044 | if (chroot_path) { | ||
| 2045 | if (chroot(chroot_path) != 0) | ||
| 2046 | err(1, "chroot(\"%s\") failed", chroot_path); | ||
| 2047 | |||
| 2048 | if (chdir("/") != 0) | ||
| 2049 | err(1, "chdir(\"/\") failed"); | ||
| 2050 | |||
| 2051 | verbose("chroot done\n"); | ||
| 2052 | } | ||
| 2053 | |||
| 2054 | /* If requested, drop privileges */ | ||
| 2055 | if (user_details) { | ||
| 2056 | uid_t u; | ||
| 2057 | gid_t g; | ||
| 2058 | |||
| 2059 | u = user_details->pw_uid; | ||
| 2060 | g = user_details->pw_gid; | ||
| 2061 | |||
| 2062 | if (initgroups(user_details->pw_name, g) != 0) | ||
| 2063 | err(1, "initgroups failed"); | ||
| 2064 | |||
| 2065 | if (setresgid(g, g, g) != 0) | ||
| 2066 | err(1, "setresgid failed"); | ||
| 2067 | |||
| 2068 | if (setresuid(u, u, u) != 0) | ||
| 2069 | err(1, "setresuid failed"); | ||
| 2070 | |||
| 2071 | verbose("Dropping privileges completed\n"); | ||
| 2072 | } | ||
| 2073 | |||
| 2024 | /* Finally, run the Guest. This doesn't return. */ | 2074 | /* Finally, run the Guest. This doesn't return. */ |
| 2025 | run_guest(); | 2075 | run_guest(); |
| 2026 | } | 2076 | } |
