coreutils

General Software Utilities
git clone http://git.omkov.net/coreutils
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2022-09-11 03:06:17
Commit60762e4948dabba401775c448a4fbfef23d11880
Parente2140ecfeb7ffdc243fa54c13bb7465376b4a8ac

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)");
+}