1#ifndef __CAPSICUM_RIGHTS_H__
2#define __CAPSICUM_RIGHTS_H__
3
4#ifdef __cplusplus
5extern "C" {
6#endif
7
8#ifdef __FreeBSD__
9#include <sys/param.h>
10#if __FreeBSD_version >= 1100014 || \
11    (__FreeBSD_version >= 1001511 && __FreeBSD_version < 1100000)
12#include <sys/capsicum.h>
13#else
14#include <sys/capability.h>
15#endif
16#endif
17
18#ifdef __linux__
19#include <linux/capsicum.h>
20#endif
21
22#ifdef __cplusplus
23}
24#endif
25
26#ifndef CAP_RIGHTS_VERSION
27/************************************************************
28 * Capsicum compatibility layer: implement new (FreeBSD10.x)
29 * rights manipulation API in terms of original (FreeBSD9.x)
30 * functionality.
31 ************************************************************/
32#include <stdarg.h>
33#include <stdbool.h>
34
35/* Rights manipulation macros/functions.
36 * Note that these use variadic macros, available in C99 / C++11 (and
37 * also in earlier gcc versions).
38 */
39#define cap_rights_init(rights, ...)   _cap_rights_init((rights), __VA_ARGS__, 0ULL)
40#define cap_rights_set(rights, ...)    _cap_rights_set((rights), __VA_ARGS__, 0ULL)
41#define cap_rights_clear(rights, ...)  _cap_rights_clear((rights), __VA_ARGS__, 0ULL)
42#define cap_rights_is_set(rights, ...) _cap_rights_is_set((rights), __VA_ARGS__, 0ULL)
43
44inline cap_rights_t* _cap_rights_init(cap_rights_t *rights, ...) {
45  va_list ap;
46  cap_rights_t right;
47  *rights = 0;
48  va_start(ap, rights);
49  while (true) {
50    right = va_arg(ap, cap_rights_t);
51    *rights |= right;
52    if (right == 0) break;
53  }
54  va_end(ap);
55  return rights;
56}
57
58inline cap_rights_t* _cap_rights_set(cap_rights_t *rights, ...) {
59  va_list ap;
60  cap_rights_t right;
61  va_start(ap, rights);
62  while (true) {
63    right = va_arg(ap, cap_rights_t);
64    *rights |= right;
65    if (right == 0) break;
66  }
67  va_end(ap);
68  return rights;
69}
70
71inline cap_rights_t* _cap_rights_clear(cap_rights_t *rights, ...) {
72  va_list ap;
73  cap_rights_t right;
74  va_start(ap, rights);
75  while (true) {
76    right = va_arg(ap, cap_rights_t);
77    *rights &= ~right;
78    if (right == 0) break;
79  }
80  va_end(ap);
81  return rights;
82}
83
84inline bool _cap_rights_is_set(const cap_rights_t *rights, ...) {
85  va_list ap;
86  cap_rights_t right;
87  cap_rights_t accumulated = 0;
88  va_start(ap, rights);
89  while (true) {
90    right = va_arg(ap, cap_rights_t);
91    accumulated |= right;
92    if (right == 0) break;
93  }
94  va_end(ap);
95  return (accumulated & *rights) == accumulated;
96}
97
98inline bool _cap_rights_is_valid(const cap_rights_t *rights) {
99  return true;
100}
101
102inline cap_rights_t* cap_rights_merge(cap_rights_t *dst, const cap_rights_t *src) {
103  *dst |= *src;
104  return dst;
105}
106
107inline cap_rights_t* cap_rights_remove(cap_rights_t *dst, const cap_rights_t *src) {
108  *dst &= ~(*src);
109  return dst;
110}
111
112inline bool cap_rights_contains(const cap_rights_t *big, const cap_rights_t *little) {
113  return ((*big) & (*little)) == (*little);
114}
115
116#endif  /* old/new style rights manipulation */
117
118#endif /*__CAPSICUM_RIGHTS_H__*/
119