From 04d965d67a7264a1c7c211494aebda1953df7603 Mon Sep 17 00:00:00 2001 From: "info@mode42.com" Date: Fri, 7 Aug 2026 18:25:13 +0000 Subject: Initial push --- stacks/max25-bcpr/src/bcpr_runas.c | 81 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 stacks/max25-bcpr/src/bcpr_runas.c (limited to 'stacks/max25-bcpr/src/bcpr_runas.c') diff --git a/stacks/max25-bcpr/src/bcpr_runas.c b/stacks/max25-bcpr/src/bcpr_runas.c new file mode 100644 index 0000000..8c930bf --- /dev/null +++ b/stacks/max25-bcpr/src/bcpr_runas.c @@ -0,0 +1,81 @@ +/* + * Process identity: max25-bcprd runs unprivileged; init drops from root. + */ +#define _GNU_SOURCE +#include "bcpr/bcpr_runas.h" + +#include +#include +#include +#include +#include +#include + +int bcpr_runas_refuse_root(int dry_run) +{ + if (geteuid() == 0 && !dry_run) { + fprintf(stderr, + "max25-bcprd: refusing to run as root — use max25-bcprd-init " + "(setuid) for live SER12\n"); + return -1; + } + return 0; +} + +int bcpr_runas_drop(const bcpr_config_t *cfg) +{ + struct passwd *pw; + struct group *gr = NULL; + gid_t gid; + uid_t uid; + const char *name; + + if (!cfg || !cfg->run_user[0]) { + fprintf(stderr, "max25-bcpr: [max25-bcpr] user= required for daemon\n"); + return -1; + } + if (geteuid() != 0) { + fprintf(stderr, "max25-bcpr: privilege drop requires euid=0\n"); + return -1; + } + + pw = getpwnam(cfg->run_user); + if (!pw) { + fprintf(stderr, "max25-bcpr: unknown user=%s\n", cfg->run_user); + return -1; + } + uid = pw->pw_uid; + gid = pw->pw_gid; + name = pw->pw_name; + + if (cfg->run_group[0]) { + gr = getgrnam(cfg->run_group); + if (!gr) { + fprintf(stderr, "max25-bcpr: unknown group=%s\n", cfg->run_group); + return -1; + } + gid = gr->gr_gid; + } + + if (initgroups(name, gid) != 0) { + fprintf(stderr, "max25-bcpr: initgroups(%s) failed: %s\n", name, + strerror(errno)); + return -1; + } + if (setgid(gid) != 0) { + fprintf(stderr, "max25-bcpr: setgid failed: %s\n", strerror(errno)); + return -1; + } + if (setuid(uid) != 0) { + fprintf(stderr, "max25-bcpr: setuid failed: %s\n", strerror(errno)); + return -1; + } + if (setuid(0) == 0) { + fprintf(stderr, "max25-bcpr: privilege drop incomplete\n"); + return -1; + } + + fprintf(stderr, "max25-bcpr: running as uid=%u gid=%u (%s)\n", + (unsigned)uid, (unsigned)gid, name); + return 0; +} -- cgit v1.3.1