1/*
2 * Minimal portability layer for Capsicum-related features.
3 */
4#ifndef __CAPSICUM_H__
5#define __CAPSICUM_H__
6
7#ifdef __FreeBSD__
8#include "capsicum-freebsd.h"
9#endif
10
11#ifdef __linux__
12#include "capsicum-linux.h"
13#endif
14
15/*
16 * CAP_ALL/CAP_NONE is a value in FreeBSD9.x Capsicum, but a functional macro
17 * in FreeBSD10.x Capsicum.  Always use CAP_SET_ALL/CAP_SET_NONE instead.
18 */
19#ifndef CAP_SET_ALL
20#ifdef CAP_RIGHTS_VERSION
21#define CAP_SET_ALL(rights) CAP_ALL(rights)
22#else
23#define CAP_SET_ALL(rights) *(rights) = CAP_MASK_VALID
24#endif
25#endif
26
27#ifndef CAP_SET_NONE
28#ifdef CAP_RIGHTS_VERSION
29#define CAP_SET_NONE(rights) CAP_NONE(rights)
30#else
31#define CAP_SET_NONE(rights) *(rights) = 0
32#endif
33#endif
34
35
36/************************************************************
37 * Define new-style rights in terms of old-style rights if
38 * absent.
39 ************************************************************/
40#include "capsicum-rights.h"
41
42/*
43 * Cope with systems (e.g. FreeBSD 10.x) where CAP_RENAMEAT hasn't been split out.
44 *  (src, dest): RENAMEAT, LINKAT => RENAMEAT_SOURCE, RENAMEAT_TARGET
45 */
46#ifndef CAP_RENAMEAT_SOURCE
47#define CAP_RENAMEAT_SOURCE CAP_RENAMEAT
48#endif
49#ifndef CAP_RENAMEAT_TARGET
50#define CAP_RENAMEAT_TARGET CAP_LINKAT
51#endif
52/*
53 * Cope with systems (e.g. FreeBSD 10.x) where CAP_RENAMEAT hasn't been split out.
54 *  (src, dest): 0, LINKAT => LINKAT_SOURCE, LINKAT_TARGET
55 */
56#ifndef CAP_LINKAT_SOURCE
57#define CAP_LINKAT_SOURCE CAP_LOOKUP
58#endif
59#ifndef CAP_LINKAT_TARGET
60#define CAP_LINKAT_TARGET CAP_LINKAT
61#endif
62
63#ifdef CAP_PREAD
64/* Existence of CAP_PREAD implies new-style CAP_SEEK semantics */
65#define CAP_SEEK_ASWAS 0
66#else
67/* Old-style CAP_SEEK semantics */
68#define CAP_SEEK_ASWAS CAP_SEEK
69#define CAP_PREAD CAP_READ
70#define CAP_PWRITE CAP_WRITE
71#endif
72
73#ifndef CAP_MMAP_R
74#define CAP_MMAP_R (CAP_READ|CAP_MMAP)
75#define CAP_MMAP_W (CAP_WRITE|CAP_MMAP)
76#define CAP_MMAP_X (CAP_MAPEXEC|CAP_MMAP)
77#define CAP_MMAP_RW (CAP_MMAP_R|CAP_MMAP_W)
78#define CAP_MMAP_RX (CAP_MMAP_R|CAP_MMAP_X)
79#define CAP_MMAP_WX (CAP_MMAP_W|CAP_MMAP_X)
80#define CAP_MMAP_RWX (CAP_MMAP_R|CAP_MMAP_W|CAP_MMAP_X)
81#endif
82
83#ifndef CAP_MKFIFOAT
84#define CAP_MKFIFOAT CAP_MKFIFO
85#endif
86
87#ifndef CAP_MKNODAT
88#define CAP_MKNODAT CAP_MKFIFOAT
89#endif
90
91#ifndef CAP_MKDIRAT
92#define CAP_MKDIRAT CAP_MKDIR
93#endif
94
95#ifndef CAP_UNLINKAT
96#define CAP_UNLINKAT CAP_RMDIR
97#endif
98
99#ifndef CAP_SOCK_CLIENT
100#define CAP_SOCK_CLIENT \
101        (CAP_CONNECT | CAP_GETPEERNAME | CAP_GETSOCKNAME | CAP_GETSOCKOPT | \
102         CAP_PEELOFF | CAP_READ | CAP_WRITE | CAP_SETSOCKOPT | CAP_SHUTDOWN)
103#endif
104
105#ifndef CAP_SOCK_SERVER
106#define CAP_SOCK_SERVER \
107        (CAP_ACCEPT | CAP_BIND | CAP_GETPEERNAME | CAP_GETSOCKNAME | \
108         CAP_GETSOCKOPT | CAP_LISTEN | CAP_PEELOFF | CAP_READ | CAP_WRITE | \
109         CAP_SETSOCKOPT | CAP_SHUTDOWN)
110#endif
111
112#ifndef CAP_EVENT
113#define CAP_EVENT CAP_POLL_EVENT
114#endif
115
116/************************************************************
117 * Define new-style API functions in terms of old-style API
118 * functions if absent.
119 ************************************************************/
120#ifndef HAVE_CAP_RIGHTS_GET
121/* Define cap_rights_get() in terms of old-style cap_getrights() */
122inline int cap_rights_get(int fd, cap_rights_t *rights) {
123  return cap_getrights(fd, rights);
124}
125#endif
126
127#ifndef HAVE_CAP_RIGHTS_LIMIT
128/* Define cap_rights_limit() in terms of old-style cap_new() and dup2() */
129#include <unistd.h>
130inline int cap_rights_limit(int fd, const cap_rights_t *rights) {
131  int cap = cap_new(fd, *rights);
132  if (cap < 0) return cap;
133  int rc = dup2(cap, fd);
134  if (rc < 0) return rc;
135  close(cap);
136  return rc;
137}
138#endif
139
140#include <stdio.h>
141#ifdef CAP_RIGHTS_VERSION
142/* New-style Capsicum API extras for debugging */
143static inline void cap_rights_describe(const cap_rights_t *rights, char *buffer) {
144  int ii;
145  for (ii = 0; ii < (CAP_RIGHTS_VERSION+2); ii++) {
146    int len = sprintf(buffer, "0x%016llx ", (unsigned long long)rights->cr_rights[ii]);
147    buffer += len;
148  }
149}
150
151#ifdef __cplusplus
152#include <iostream>
153#include <iomanip>
154inline std::ostream& operator<<(std::ostream& os, cap_rights_t rights) {
155  for (int ii = 0; ii < (CAP_RIGHTS_VERSION+2); ii++) {
156    os << std::hex << std::setw(16) << std::setfill('0') << (unsigned long long)rights.cr_rights[ii] << " ";
157  }
158  return os;
159}
160#endif
161
162#else
163
164static inline void cap_rights_describe(const cap_rights_t *rights, char *buffer) {
165  sprintf(buffer, "0x%016llx", (*rights));
166}
167
168#endif  /* new/old style rights manipulation */
169
170#ifdef __cplusplus
171#include <string>
172extern std::string capsicum_test_bindir;
173#endif
174
175#endif /*__CAPSICUM_H__*/
176