summaryrefslogtreecommitdiff
path: root/stacks/max25-bcpr/src/bcpr_runas.c
blob: 8c930bfae8017fa2027f72b3713529d32109a305 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
 * Process identity: max25-bcprd runs unprivileged; init drops from root.
 */
#define _GNU_SOURCE
#include "bcpr/bcpr_runas.h"

#include <errno.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

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;
}
git clone -b <branch> https://cgit.mode42.com/<repo>.git
git clone -b <branch> git://cgit.mode42.com/<repo>.git

info@mode42.com