Annotation of embedaddon/bird/sysdep/linux/syspriv.h, revision 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>