/* * 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; }