File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird / sysdep / linux / syspriv.h
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Aug 22 12:33:54 2017 UTC (7 years, 7 months ago) by misho
Branches: bird, MAIN
CVS tags: v1_6_8p3, v1_6_3p0, v1_6_3, HEAD
bird 1.6.3

    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>