-
Notifications
You must be signed in to change notification settings - Fork 2
/
privileges.c
73 lines (61 loc) · 1.61 KB
/
privileges.c
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
#define _GNU_SOURCE
#include <grp.h>
#include <sched.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include "logger.h"
#include "privileges.h"
static int do_unshare(bool disable_networking) {
int err = 0;
/*
* Start new processes in a new process ID namespace, this way the user
* process will not be able to see any other processes on the system other
* than itself and any child processes that it creates.
*/
int unshare_flags = CLONE_NEWPID;
if (disable_networking) {
unshare_flags |= CLONE_NEWNET;
}
err = unshare(unshare_flags);
if (err) {
perror("unshare");
goto done;
}
done:
return err;
}
int cape_drop_privileges(uid_t uid, bool disable_networking) {
/*
* Drop root privileges:
* https://wiki.sei.cmu.edu/confluence/display/c/POS36-C.+Observe+correct+revocation+order+while+relinquishing+privileges
*/
int err = 0;
const gid_t list[] = {uid};
const size_t len = sizeof(list) / sizeof(*list);
err = do_unshare(disable_networking);
if (err) {
cape_log_error("could not unshare");
goto done;
}
err = setgroups(len, list);
if (err) {
perror("setgroups");
cape_log_error("could not setgroups to: '%d'", uid);
goto done;
}
err = setgid(uid);
if (err) {
perror("setgid");
cape_log_error("could not setgid to: '%d'", uid);
goto done;
}
err = setuid(uid);
if (err) {
perror("setuid");
cape_log_error("could not setuid to: '%d'", uid);
goto done;
}
done:
return err;
}