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 50struct nvlist; 51 52typedef struct nvlist nvlist_t; 53#endif 54 55#ifndef _CAP_CHANNEL_T_DECLARED 56#define _CAP_CHANNEL_T_DECLARED 57#ifdef WITH_CASPER 58struct cap_channel; 59 60typedef struct cap_channel cap_channel_t; 61#define CASPER_SUPPORT (1) 62#else 63struct cap_channel { 64 int cch_fd; 65 int cch_flags; 66}; 67typedef 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 75int cap_channel_flags(const cap_channel_t *chan); 76#else 77static inline int 78cap_channel_flags(const cap_channel_t *chan) 79{ 80 81 return (chan->cch_flags); 82} 83#endif 84 85static inline int 86channel_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 101cap_channel_t *cap_init(void); 102#else 103static inline cap_channel_t * 104cap_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 120cap_channel_t *cap_service_open(const cap_channel_t *chan, const char *name); 121int cap_service_limit(const cap_channel_t *chan, 122 const char * const *names, size_t nnames); 123#else 124static inline cap_channel_t * 125cap_service_open(const cap_channel_t *chan __unused, 126 const char *name __unused) 127{ 128 129 return (cap_init()); 130} 131 132static inline int 133cap_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 145cap_channel_t *cap_wrap(int sock, int flags); 146#else 147static inline cap_channel_t * 148cap_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 165int cap_unwrap(cap_channel_t *chan, int *flags); 166#else 167static inline int 168cap_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 182cap_channel_t *cap_clone(const cap_channel_t *chan); 183#else 184static inline cap_channel_t * 185cap_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 213void cap_close(cap_channel_t *chan); 214#else 215static inline void 216cap_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 231int 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 241int cap_limit_set(const cap_channel_t *chan, nvlist_t *limits); 242#else 243static inline int 244cap_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 256int cap_limit_get(const cap_channel_t *chan, nvlist_t **limitsp); 257#else 258static inline int 259cap_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 271int 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 280nvlist_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 290nvlist_t *cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl); 291#else 292static inline nvlist_t * 293cap_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