1 /*- 2 * SPDX-License-Identifier: BSD-2-Clause 3 * 4 * Copyright (c) 2012-2013 The FreeBSD Foundation 5 * Copyright (c) 2015-2017 Mariusz Zaborski <oshogbo@FreeBSD.org> 6 * All rights reserved. 7 * 8 * This software was developed by Pawel Jakub Dawidek under sponsorship from 9 * the FreeBSD Foundation. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 20 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 30 * SUCH DAMAGE. 31 */ 32 33 #ifndef _LIBCASPER_H_ 34 #define _LIBCASPER_H_ 35 36 #ifdef HAVE_CASPER 37 #define WITH_CASPER 38 #endif 39 40 #include <sys/types.h> 41 #include <sys/nv.h> 42 43 #include <stdlib.h> 44 #include <unistd.h> 45 46 #define CASPER_NO_UNIQ 0x00000001 47 48 #ifndef _NVLIST_T_DECLARED 49 #define _NVLIST_T_DECLARED 50 struct nvlist; 51 52 typedef struct nvlist nvlist_t; 53 #endif 54 55 #ifndef _CAP_CHANNEL_T_DECLARED 56 #define _CAP_CHANNEL_T_DECLARED 57 #ifdef WITH_CASPER 58 struct cap_channel; 59 60 typedef struct cap_channel cap_channel_t; 61 #define CASPER_SUPPORT (1) 62 #else 63 struct cap_channel { 64 int cch_fd; 65 int cch_flags; 66 }; 67 typedef struct cap_channel cap_channel_t; 68 #define CASPER_SUPPORT (0) 69 #endif /* ! WITH_CASPER */ 70 #endif /* ! _CAP_CHANNEL_T_DECLARED */ 71 72 __BEGIN_DECLS 73 74 #ifdef WITH_CASPER 75 int cap_channel_flags(const cap_channel_t *chan); 76 #else 77 static inline int 78 cap_channel_flags(const cap_channel_t *chan) 79 { 80 81 return (chan->cch_flags); 82 } 83 #endif 84 85 static inline int 86 channel_nvlist_flags(const cap_channel_t *chan) 87 { 88 int flags; 89 90 flags = 0; 91 if ((cap_channel_flags(chan) & CASPER_NO_UNIQ) != 0) 92 flags |= NV_FLAG_NO_UNIQUE; 93 94 return (flags); 95 } 96 97 /* 98 * The functions opens unrestricted communication channel to Casper. 99 */ 100 #ifdef WITH_CASPER 101 cap_channel_t *cap_init(void); 102 #else 103 static inline cap_channel_t * 104 cap_init(void) 105 { 106 cap_channel_t *chan; 107 108 chan = (cap_channel_t *)malloc(sizeof(*chan)); 109 if (chan != NULL) { 110 chan->cch_fd = -1; 111 } 112 return (chan); 113 } 114 #endif 115 116 /* 117 * The functions to communicate with service. 118 */ 119 #ifdef WITH_CASPER 120 cap_channel_t *cap_service_open(const cap_channel_t *chan, const char *name); 121 int cap_service_limit(const cap_channel_t *chan, 122 const char * const *names, size_t nnames); 123 #else 124 static inline cap_channel_t * 125 cap_service_open(const cap_channel_t *chan __unused, 126 const char *name __unused) 127 { 128 129 return (cap_init()); 130 } 131 132 static inline int 133 cap_service_limit(const cap_channel_t *chan __unused, 134 const char * const *names __unused, size_t nnames __unused) 135 { 136 137 return (0); 138 } 139 #endif 140 141 /* 142 * The function creates cap_channel_t based on the given socket. 143 */ 144 #ifdef WITH_CASPER 145 cap_channel_t *cap_wrap(int sock, int flags); 146 #else 147 static inline cap_channel_t * 148 cap_wrap(int sock, int flags) 149 { 150 cap_channel_t *chan; 151 152 chan = cap_init(); 153 if (chan != NULL) { 154 chan->cch_fd = sock; 155 chan->cch_flags = flags; 156 } 157 return (chan); 158 } 159 #endif 160 161 /* 162 * The function returns communication socket and frees cap_channel_t. 163 */ 164 #ifdef WITH_CASPER 165 int cap_unwrap(cap_channel_t *chan, int *flags); 166 #else 167 static inline int 168 cap_unwrap(cap_channel_t *chan) 169 { 170 int fd; 171 172 fd = chan->cch_fd; 173 free(chan); 174 return (fd); 175 } 176 #endif 177 178 /* 179 * The function clones the given capability. 180 */ 181 #ifdef WITH_CASPER 182 cap_channel_t *cap_clone(const cap_channel_t *chan); 183 #else 184 static inline cap_channel_t * 185 cap_clone(const cap_channel_t *chan) 186 { 187 cap_channel_t *newchan; 188 189 newchan = cap_init(); 190 if (newchan == NULL) { 191 return (NULL); 192 } 193 194 if (chan->cch_fd == -1) { 195 newchan->cch_fd = -1; 196 } else { 197 newchan->cch_fd = dup(chan->cch_fd); 198 if (newchan->cch_fd < 0) { 199 free(newchan); 200 newchan = NULL; 201 } 202 } 203 newchan->cch_flags = chan->cch_flags; 204 205 return (newchan); 206 } 207 #endif 208 209 /* 210 * The function closes the given capability. 211 */ 212 #ifdef WITH_CASPER 213 void cap_close(cap_channel_t *chan); 214 #else 215 static inline void 216 cap_close(cap_channel_t *chan) 217 { 218 219 if (chan->cch_fd >= 0) { 220 close(chan->cch_fd); 221 } 222 free(chan); 223 } 224 #endif 225 226 /* 227 * The function returns socket descriptor associated with the given 228 * cap_channel_t for use with select(2)/kqueue(2)/etc. 229 */ 230 #ifdef WITH_CASPER 231 int cap_sock(const cap_channel_t *chan); 232 #else 233 #define cap_sock(chan) (chan->cch_fd) 234 #endif 235 236 /* 237 * The function limits the given capability. 238 * It always destroys 'limits' on return. 239 */ 240 #ifdef WITH_CASPER 241 int cap_limit_set(const cap_channel_t *chan, nvlist_t *limits); 242 #else 243 static inline int 244 cap_limit_set(const cap_channel_t *chan __unused, 245 nvlist_t *limits __unused) 246 { 247 248 return (0); 249 } 250 #endif 251 252 /* 253 * The function returns current limits of the given capability. 254 */ 255 #ifdef WITH_CASPER 256 int cap_limit_get(const cap_channel_t *chan, nvlist_t **limitsp); 257 #else 258 static inline int 259 cap_limit_get(const cap_channel_t *chan __unused, nvlist_t **limitsp) 260 { 261 262 *limitsp = nvlist_create(channel_nvlist_flags(chan)); 263 return (0); 264 } 265 #endif 266 267 /* 268 * Function sends nvlist over the given capability. 269 */ 270 #ifdef WITH_CASPER 271 int cap_send_nvlist(const cap_channel_t *chan, const nvlist_t *nvl); 272 #else 273 #define cap_send_nvlist(chan, nvl) (0) 274 #endif 275 276 /* 277 * Function receives nvlist over the given capability. 278 */ 279 #ifdef WITH_CASPER 280 nvlist_t *cap_recv_nvlist(const cap_channel_t *chan); 281 #else 282 #define cap_recv_nvlist(chan) (nvlist_create(chan->cch_flags)) 283 #endif 284 285 /* 286 * Function sends the given nvlist, destroys it and receives new nvlist in 287 * response over the given capability. 288 */ 289 #ifdef WITH_CASPER 290 nvlist_t *cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl); 291 #else 292 static inline nvlist_t * 293 cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl) 294 { 295 296 nvlist_destroy(nvl); 297 return (nvlist_create(channel_nvlist_flags(chan))); 298 } 299 #endif 300 301 __END_DECLS 302 303 #endif /* !_LIBCASPER_H_ */ 304