Author | Jamozed <[email protected]> |
Date | 2022-09-11 03:06:17 |
Commit | 60762e4948dabba401775c448a4fbfef23d11880 |
Parent | e2140ecfeb7ffdc243fa54c13bb7465376b4a8ac |
relogin: Add relogin utility
Diffstat
M | CMakeLists.txt | | | 5 | +++-- |
M | README.md | | | 3 | ++- |
A | src/relogin.c | | | 81 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 86 insertions, 3 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 9eb8a66..23071d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,11 +1,11 @@ -cmake_minimum_required(VERSION 3.12) +cmake_minimum_required(VERSION 3.14) project(coreutils LANGUAGES C) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin) set(CMAKE_STATIC_LIBRARY_PREFIX "") -file(GLOB SRC_UTIL ${PROJECT_SOURCE_DIR}/src/util/*) +file(GLOB SRC_UTIL CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/src/util/*) add_library(libutil STATIC ${SRC_UTIL}) @@ -32,6 +32,7 @@ add_executable(od ${PROJECT_SOURCE_DIR}/src/od.c) add_executable(pwd ${PROJECT_SOURCE_DIR}/src/pwd.c) add_executable(rand ${PROJECT_SOURCE_DIR}/src/rand.c) add_executable(realpath ${PROJECT_SOURCE_DIR}/src/realpath.c) +add_executable(relogin ${PROJECT_SOURCE_DIR}/src/relogin.c) add_executable(rmdir ${PROJECT_SOURCE_DIR}/src/rmdir.c) add_executable(sleep ${PROJECT_SOURCE_DIR}/src/sleep.c) add_executable(sum ${PROJECT_SOURCE_DIR}/src/sum.c) diff --git a/README.md b/README.md index f67042b..2ff6bd0 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,7 @@ A collection of general software utilities commonly found on UNIX systems. | pwd | Print working directory | POSIX | | rand | Generate random string | | | realpath | Resolve an absolute pathname | | +| relogin | Invoke a command as a specified user | | | rmdir | Remove directories | POSIX | | sleep | Suspend execution for an interval | POSIX | | sum | Write file checksums and block counts | | @@ -49,7 +50,7 @@ A collection of general software utilities commonly found on UNIX systems. ### Dependencies -- CMake >= 3.12, to build +- CMake >= 3.14, to build ### Building diff --git a/src/relogin.c b/src/relogin.c new file mode 100644 index 0000000..6392211 --- /dev/null +++ b/src/relogin.c @@ -0,0 +1,81 @@ +// relogin.c, version 0.1.0 +// OMKOV coreutils relogin +// Copyright (C) 2022, Jakob Wakeling +// MIT Licence + +#include "util/error.h" +#include "util/optget.h" + +#include <grp.h> +#include <pwd.h> +#include <sys/types.h> +#include <unistd.h> + +#include <errno.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <stdnoreturn.h> +#include <string.h> + +#define VERSION "0.1.0" + +static struct lop lops[] = { + { "help", ARG_NUL, 256 }, + { "version", ARG_NUL, 257 }, + { NULL, 0, 0 } +}; + +static inline int relogin(const char *user, char *av[]); + +static void hlp(void); +static void ver(void); + +int main(int ac, char *av[]) { A0 = av[0]; + struct opt opt = OPTGET_INIT; opt.str = ""; opt.lops = lops; + for (int o; (o = optget(&opt, av, 1)) != -1;) switch (o) { + case 256: { hlp(); return 0; } + case 257: { ver(); return 0; } + default: { return 1; } + } + + if (opt.ind + 0 >= ac) { error(1, "missing user operand"); } + if (opt.ind + 1 >= ac) { error(1, "missing command operand"); } + + if (relogin(av[1], &av[2])) { error(1, "%s: %s\n", av[1], serr()); } + + return 0; +} + +static inline int relogin(const char *user, char *av[]) { + struct passwd *pw; + if ((pw = getpwnam(user)) == NULL) { error(1, "%s", serr()); } + + if (initgroups(pw->pw_name, pw->pw_gid) == -1) { error(1, "%s", serr()); } + if (setgid(pw->pw_gid) == -1) { error(1, "%s", serr()); } + if (setuid(pw->pw_uid) == -1) { error(1, "%s", serr()); } + + setenv("HOME", pw->pw_dir, 1); setenv("LOGNAME", pw->pw_name, 1); + setenv("USER", pw->pw_name, 1); unsetenv("MAIL"); + + unsetenv("DOAS_USER"); unsetenv("SUDO_UID"); unsetenv("SUDO_GID"); + unsetenv("SUDO_USER"); unsetenv("SUDO_COMMAND"); + + if (execvp(av[0], &av[0]) == -1) { error(1, "%s", serr()); } + + return 0; +} + +static void hlp(void) { + puts("relogin - invoke a command as a specified user\n"); + puts("usage: relogin user command [argument...]\n"); + puts("options:"); + puts(" --help Display help information"); + puts(" --version Display version information"); +} + +static void ver() { + puts("OMKOV coreutils relogin, version " VERSION); + puts("Copyright (C) 2022, Jakob Wakeling"); + puts("MIT Licence (https://opensource.org/licenses/MIT)"); +}