0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-10-19 02:18:43 +00:00
bird/sysdep/linux/syspriv.h
Pavel Tvrdík 856250c27f Birdtest: Purge 'int main()' from lib/birdlib.a #2
All origin static functions from sysdep/unix/main.c were rewrited to
non-static.

All origin static global variables from sysdep/unix/main.c was rewrited
to extern.

It is possible create executables bird, birdc and birdcl as well as run
unit tests without mockuping

After remake new BIRD's build system will be this commit reverting...
2015-08-05 12:36:40 +02:00

78 lines
1.8 KiB
C

#ifndef _BIRD_SYSPRIV_H_
#define _BIRD_SYSPRIV_H_
#include <unistd.h>
#include <sys/prctl.h>
#include <linux/capability.h>
#ifndef _LINUX_CAPABILITY_VERSION_3
#define _LINUX_CAPABILITY_VERSION_3 0x20080522
#define _LINUX_CAPABILITY_U32S_3 2
#endif
/* CAP_TO_MASK is missing in CentOS header files */
#ifndef CAP_TO_MASK
#define CAP_TO_MASK(x) (1 << ((x) & 31))
#endif
/* capset() prototype is missing ... */
int capset(cap_user_header_t hdrp, const cap_user_data_t datap);
static inline int
set_capabilities(u32 caps)
{
struct __user_cap_header_struct cap_hdr;
struct __user_cap_data_struct cap_dat[_LINUX_CAPABILITY_U32S_3];
int err;
cap_hdr.version = _LINUX_CAPABILITY_VERSION_3;
cap_hdr.pid = 0;
memset(cap_dat, 0, sizeof(cap_dat));
cap_dat[0].effective = cap_dat[0].permitted = caps;
err = capset(&cap_hdr, cap_dat);
if (!err)
return 0;
/* Kernel may support do not support our version of capability interface.
The last call returned supported version so we just retry it. */
if (errno == EINVAL)
{
err = capset(&cap_hdr, cap_dat);
if (!err)
return 0;
}
return -1;
}
static void
drop_uid(uid_t uid)
{
u32 caps =
CAP_TO_MASK(CAP_NET_BIND_SERVICE) |
CAP_TO_MASK(CAP_NET_BROADCAST) |
CAP_TO_MASK(CAP_NET_ADMIN) |
CAP_TO_MASK(CAP_NET_RAW);
/* change effective user ID to be able to switch to that
user ID completely after dropping CAP_SETUID */
if (seteuid(uid) < 0)
die("seteuid: %m");
/* restrict the capabilities */
if (set_capabilities(caps) < 0)
die("capset: %m");
/* keep the capabilities after dropping root ID */
if (prctl(PR_SET_KEEPCAPS, 1) < 0)
die("prctl: %m");
/* completely switch to the unprivileged user ID */
if (setresuid(uid, uid, uid) < 0)
die("setresuid: %m");
}
#endif /* _BIRD_SYSPRIV_H_ */