iof-bird / bird-2.0.1 / sysdep / linux / syspriv.h @ 6b3f1a54
History | View | Annotate | Download (1.85 KB)
1 |
#ifndef _BIRD_SYSPRIV_H_
|
---|---|
2 |
#define _BIRD_SYSPRIV_H_
|
3 |
|
4 |
#ifndef _GNU_SOURCE
|
5 |
#define _GNU_SOURCE
|
6 |
#endif
|
7 |
|
8 |
#include <unistd.h> |
9 |
#include <sys/prctl.h> |
10 |
#include <linux/capability.h> |
11 |
|
12 |
#ifndef _LINUX_CAPABILITY_VERSION_3
|
13 |
#define _LINUX_CAPABILITY_VERSION_3 0x20080522 |
14 |
#define _LINUX_CAPABILITY_U32S_3 2 |
15 |
#endif
|
16 |
|
17 |
/* CAP_TO_MASK is missing in CentOS header files */
|
18 |
#ifndef CAP_TO_MASK
|
19 |
#define CAP_TO_MASK(x) (1 << ((x) & 31)) |
20 |
#endif
|
21 |
|
22 |
/* capset() prototype is missing ... */
|
23 |
int capset(cap_user_header_t hdrp, const cap_user_data_t datap); |
24 |
|
25 |
static inline int |
26 |
set_capabilities(u32 caps) |
27 |
{ |
28 |
struct __user_cap_header_struct cap_hdr;
|
29 |
struct __user_cap_data_struct cap_dat[_LINUX_CAPABILITY_U32S_3];
|
30 |
int err;
|
31 |
|
32 |
cap_hdr.version = _LINUX_CAPABILITY_VERSION_3; |
33 |
cap_hdr.pid = 0;
|
34 |
|
35 |
memset(cap_dat, 0, sizeof(cap_dat)); |
36 |
cap_dat[0].effective = cap_dat[0].permitted = caps; |
37 |
|
38 |
err = capset(&cap_hdr, cap_dat); |
39 |
if (!err)
|
40 |
return 0; |
41 |
|
42 |
/* Kernel may support do not support our version of capability interface.
|
43 |
The last call returned supported version so we just retry it. */
|
44 |
if (errno == EINVAL)
|
45 |
{ |
46 |
err = capset(&cap_hdr, cap_dat); |
47 |
if (!err)
|
48 |
return 0; |
49 |
} |
50 |
|
51 |
return -1; |
52 |
} |
53 |
|
54 |
static void |
55 |
drop_uid(uid_t uid) |
56 |
{ |
57 |
u32 caps = |
58 |
CAP_TO_MASK(CAP_NET_BIND_SERVICE) | |
59 |
CAP_TO_MASK(CAP_NET_BROADCAST) | |
60 |
CAP_TO_MASK(CAP_NET_ADMIN) | |
61 |
CAP_TO_MASK(CAP_NET_RAW); |
62 |
|
63 |
/* change effective user ID to be able to switch to that
|
64 |
user ID completely after dropping CAP_SETUID */
|
65 |
if (seteuid(uid) < 0) |
66 |
die("seteuid: %m");
|
67 |
|
68 |
/* restrict the capabilities */
|
69 |
if (set_capabilities(caps) < 0) |
70 |
die("capset: %m");
|
71 |
|
72 |
/* keep the capabilities after dropping root ID */
|
73 |
if (prctl(PR_SET_KEEPCAPS, 1) < 0) |
74 |
die("prctl: %m");
|
75 |
|
76 |
/* completely switch to the unprivileged user ID */
|
77 |
if (setresuid(uid, uid, uid) < 0) |
78 |
die("setresuid: %m");
|
79 |
} |
80 |
|
81 |
#endif /* _BIRD_SYSPRIV_H_ */ |