Annotation of embedaddon/bird2/sysdep/linux/syspriv.h, revision 1.1.1.1
1.1 misho 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_ */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>