diff options
85 files changed, 2072 insertions, 2997 deletions
diff --git a/Makefile.inc1 b/Makefile.inc1 index ed0415b..5bd9cfa 100644 --- a/Makefile.inc1 +++ b/Makefile.inc1 @@ -585,7 +585,7 @@ _worldtmp: .PHONY rm -f ${OBJTREE}${.CURDIR}/usr.bin/kdump/kdump_subr.c .endif .for _dir in \ - lib usr legacy/bin legacy/usr + lib lib/casper usr legacy/bin legacy/usr mkdir -p ${WORLDTMP}/${_dir} .endfor mtree -deU -f ${.CURDIR}/etc/mtree/BSD.usr.dist \ @@ -1870,7 +1870,7 @@ _prebuild_libs= ${_kerberos5_lib_libasn1} \ lib/libfigpar \ ${_lib_libgssapi} \ lib/libkiconv lib/libkvm lib/liblzma lib/libmd lib/libnv \ - ${_lib_libcapsicum} \ + ${_lib_casper} \ lib/ncurses/ncurses lib/ncurses/ncursesw \ lib/libopie lib/libpam ${_lib_libthr} \ ${_lib_libradius} lib/libsbuf lib/libtacplus \ @@ -1910,11 +1910,11 @@ _ofed_lib= contrib/ofed/usr.lib/ .endif .if ${MK_CASPER} != "no" -_lib_libcapsicum=lib/libcapsicum +_lib_casper= lib/libcasper .endif -lib/libcapsicum__L: lib/libnv__L lib/libpjdlog__L: lib/libutil__L +lib/libcasper__L: lib/libnv__L lib/liblzma__L: lib/libthr__L _generic_libs= ${_cddl_lib} gnu/lib ${_kerberos5_lib} lib ${_secure_lib} usr.bin/lex/lib ${_ofed_lib} diff --git a/ObsoleteFiles.inc b/ObsoleteFiles.inc index f49544e..d321abb 100644 --- a/ObsoleteFiles.inc +++ b/ObsoleteFiles.inc @@ -38,6 +38,25 @@ # xargs -n1 | sort | uniq -d; # done +# 20160225: Remove casperd and libcapsicum. +OLD_FILES+=sbin/casperd +OLD_FILES+=etc/rc.d/casperd +OLD_FILES+=usr/share/man/man8/casperd.8.gz +OLD_FILES+=usr/include/libcapsicum.h +OLD_FILES+=usr/include/libcapsicum_service.h +OLD_FILES+=usr/include/libcapsicum.h +OLD_FILES+=usr/share/man/man3/libcapsicum.3.gz +OLD_FILES+=usr/include/libcapsicum_dns.h +OLD_FILES+=usr/include/libcapsicum_grp.h +OLD_FILES+=usr/include/libcapsicum_impl.h +OLD_FILES+=usr/include/libcapsicum_pwd.h +OLD_FILES+=usr/include/libcapsicum_random.h +OLD_FILES+=usr/include/libcapsicum_sysctl.h +OLD_FILES+=libexec/casper/dns +OLD_FILES+=libexec/casper/grp +OLD_FILES+=libexec/casper/pwd +OLD_FILES+=libexec/casper/random +OLD_FILES+=libexec/casper/sysctl # 20160223: functionality from mkulzma(1) merged into mkuzip(1) OLD_FILES+=usr/bin/mkulzma # 20160211: Remove obsolete unbound-control-setup diff --git a/contrib/mdocml/lib.in b/contrib/mdocml/lib.in index ca04e94..dec561a 100644 --- a/contrib/mdocml/lib.in +++ b/contrib/mdocml/lib.in @@ -34,7 +34,7 @@ LINE("libc", "Standard C\\~Library (libc, \\-lc)") LINE("libc_r", "Reentrant C\\~Library (libc_r, \\-lc_r)") LINE("libcalendar", "Calendar Arithmetic Library (libcalendar, \\-lcalendar)") LINE("libcam", "Common Access Method User Library (libcam, \\-lcam)") -LINE("libcapsicum", "Capsicum Library (libcapsicum, \\-lcapsicum)") +LINE("libcasper", "Casper Library (libcasper, \\-lcapser)") LINE("libcdk", "Curses Development Kit Library (libcdk, \\-lcdk)") LINE("libcipher", "FreeSec Crypt Library (libcipher, \\-lcipher)") LINE("libcompat", "Compatibility Library (libcompat, \\-lcompat)") diff --git a/contrib/tcpdump/addrtoname.c b/contrib/tcpdump/addrtoname.c index b02d0f7..e224606 100644 --- a/contrib/tcpdump/addrtoname.c +++ b/contrib/tcpdump/addrtoname.c @@ -29,10 +29,10 @@ #include "config.h" #endif -#ifdef HAVE_CAPSICUM -#include <libcapsicum.h> -#include <libcapsicum_dns.h> -#endif /* HAVE_CAPSICUM */ +#ifdef HAVE_CAPSPER +#include <libcasper.h> +#include <casper/cap_dns.h> +#endif /* HAVE_CAPSPER */ #include <tcpdump-stdinc.h> #ifdef USE_ETHER_NTOHOST @@ -204,7 +204,7 @@ intoa(uint32_t addr) static uint32_t f_netmask; static uint32_t f_localnet; -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER extern cap_channel_t *capdns; #endif @@ -252,7 +252,7 @@ getname(netdissect_options *ndo, const u_char *ap) */ if (!ndo->ndo_nflag && (addr & f_netmask) == f_localnet) { -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER if (capdns != NULL) { hp = cap_gethostbyaddr(capdns, (char *)&addr, 4, AF_INET); @@ -309,7 +309,7 @@ getname6(netdissect_options *ndo, const u_char *ap) * Do not print names if -n was given. */ if (!ndo->ndo_nflag) { -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER if (capdns != NULL) { hp = cap_gethostbyaddr(capdns, (char *)&addr, sizeof(addr), AF_INET6); diff --git a/contrib/tcpdump/config.h.in b/contrib/tcpdump/config.h.in index 914289a..f233245 100644 --- a/contrib/tcpdump/config.h.in +++ b/contrib/tcpdump/config.h.in @@ -10,7 +10,7 @@ #undef HAVE_BPF_DUMP /* capsicum support available */ -#undef HAVE_CAPSICUM +#undef HAVE_CAPSPER /* Define to 1 if you have the `cap_enter' function. */ #undef HAVE_CAP_ENTER diff --git a/contrib/tcpdump/configure b/contrib/tcpdump/configure index 43b3068..390af31 100755 --- a/contrib/tcpdump/configure +++ b/contrib/tcpdump/configure @@ -4566,7 +4566,7 @@ fi $as_echo_n "checking whether to sandbox using capsicum... " >&6; } if test "x$ac_lbl_capsicum_function_seen" = "xyes" -a "x$ac_lbl_capsicum_function_not_seen" != "xyes"; then -$as_echo "#define HAVE_CAPSICUM 1" >>confdefs.h +$as_echo "#define HAVE_CAPSPER 1" >>confdefs.h { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 $as_echo "yes" >&6; } diff --git a/contrib/tcpdump/configure.in b/contrib/tcpdump/configure.in index a629559..b5ac48f 100644 --- a/contrib/tcpdump/configure.in +++ b/contrib/tcpdump/configure.in @@ -222,7 +222,7 @@ if test ! -z "$with_sandbox-capsicum" && test "$with_sandbox-capsicum" != "no" ; fi AC_MSG_CHECKING([whether to sandbox using capsicum]) if test "x$ac_lbl_capsicum_function_seen" = "xyes" -a "x$ac_lbl_capsicum_function_not_seen" != "xyes"; then - AC_DEFINE(HAVE_CAPSICUM, 1, [capsicum support available]) + AC_DEFINE(HAVE_CASPER, 1, [casper support available]) AC_MSG_RESULT(yes) else AC_MSG_RESULT(no) diff --git a/contrib/tcpdump/tcpdump.c b/contrib/tcpdump/tcpdump.c index ed3ce5e..bc0c5ee 100644 --- a/contrib/tcpdump/tcpdump.c +++ b/contrib/tcpdump/tcpdump.c @@ -87,17 +87,16 @@ extern int SIZE_BUF; #include <sys/capsicum.h> #include <sys/sysctl.h> #endif /* __FreeBSD__ */ -#ifdef HAVE_CAPSICUM -#include <libcapsicum.h> -#include <libcapsicum_dns.h> -#include <libcapsicum_service.h> +#ifdef HAVE_CAPSPER +#include <libcasper.h> +#include <casper/cap_dns.h> #include <sys/nv.h> #include <sys/capability.h> #include <sys/ioccom.h> #include <net/bpf.h> #include <fcntl.h> #include <libgen.h> -#endif /* HAVE_CAPSICUM */ +#endif /* HAVE_CAPSPER */ #include <pcap.h> #include <signal.h> #include <stdio.h> @@ -161,7 +160,7 @@ static int infoprint; char *program_name; -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER cap_channel_t *capdns; #endif @@ -485,7 +484,7 @@ struct dump_info { char *CurrentFileName; pcap_t *pd; pcap_dumper_t *p; -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER int dirfd; #endif }; @@ -909,7 +908,7 @@ get_next_file(FILE *VFile, char *ptr) return ret; } -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER static cap_channel_t * capdns_setup(void) { @@ -918,10 +917,8 @@ capdns_setup(void) int families[2]; capcas = cap_init(); - if (capcas == NULL) { - warning("unable to contact casperd"); - return (NULL); - } + if (capcas == NULL) + error("unable to create casper process"); capdnsloc = cap_service_open(capcas, "system.dns"); /* Casper capability no longer needed. */ cap_close(capcas); @@ -938,7 +935,7 @@ capdns_setup(void) return (capdnsloc); } -#endif /* HAVE_CAPSICUM */ +#endif /* HAVE_CAPSPER */ #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION static int @@ -970,7 +967,7 @@ tstamp_precision_to_string(int precision) } #endif -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER /* * Ensure that, on a dump file's descriptor, we have all the rights * necessary to make the standard I/O library work with an fdopen()ed @@ -1070,9 +1067,9 @@ main(int argc, char **argv) #endif int status; FILE *VFile; -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER cap_rights_t rights; -#endif /* HAVE_CAPSICUM */ +#endif /* HAVE_CAPSPER */ int cansandbox; #ifdef WIN32 @@ -1613,7 +1610,7 @@ main(int argc, char **argv) if (pd == NULL) error("%s", ebuf); -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER cap_rights_init(&rights, CAP_READ); if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 && errno != ENOSYS) { @@ -1850,10 +1847,10 @@ main(int argc, char **argv) exit(0); } -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER if (!nflag) capdns = capdns_setup(); -#endif /* HAVE_CAPSICUM */ +#endif /* HAVE_CAPSPER */ init_addrtoname(gndo, localnet, netmask); init_checksum(); @@ -1921,7 +1918,7 @@ main(int argc, char **argv) if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER if (RFileName == NULL && VFileName == NULL) { static const unsigned long cmds[] = { BIOCGSTATS }; @@ -1971,11 +1968,11 @@ main(int argc, char **argv) #endif /* HAVE_LIBCAP_NG */ if (p == NULL) error("%s", pcap_geterr(pd)); -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER set_dumper_capsicum_rights(p); #endif if (Cflag != 0 || Gflag != 0) { -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER dumpinfo.WFileName = strdup(basename(WFileName)); dumpinfo.dirfd = open(dirname(WFileName), O_DIRECTORY | O_RDONLY); @@ -1993,7 +1990,7 @@ main(int argc, char **argv) errno != ENOSYS) { error("unable to limit dump descriptor fcntls"); } -#else /* !HAVE_CAPSICUM */ +#else /* !HAVE_CAPSPER */ dumpinfo.WFileName = WFileName; #endif callback = dump_packet_and_trunc; @@ -2069,7 +2066,7 @@ main(int argc, char **argv) #ifdef __FreeBSD__ cansandbox = (VFileName == NULL && zflag == NULL); -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER cansandbox = (cansandbox && (nflag || capdns != NULL)); #else cansandbox = (cansandbox && nflag); @@ -2125,7 +2122,7 @@ main(int argc, char **argv) pd = pcap_open_offline(RFileName, ebuf); if (pd == NULL) error("%s", ebuf); -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER cap_rights_init(&rights, CAP_READ); if (cap_rights_limit(fileno(pcap_file(pd)), &rights) < 0 && errno != ENOSYS) { @@ -2328,7 +2325,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s /* If the time is greater than the specified window, rotate */ if (t - Gflag_time >= Gflag) { -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER FILE *fp; int fd; #endif @@ -2386,7 +2383,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER fd = openat(dump_info->dirfd, dump_info->CurrentFileName, O_CREAT | O_WRONLY | O_TRUNC, 0644); @@ -2400,7 +2397,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s dump_info->CurrentFileName); } dump_info->p = pcap_dump_fopen(dump_info->pd, fp); -#else /* !HAVE_CAPSICUM */ +#else /* !HAVE_CAPSPER */ dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); #endif #ifdef HAVE_LIBCAP_NG @@ -2409,7 +2406,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s #endif /* HAVE_LIBCAP_NG */ if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER set_dumper_capsicum_rights(dump_info->p); #endif } @@ -2426,7 +2423,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s if (size == -1) error("ftell fails on output file"); if (size > Cflag) { -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER FILE *fp; int fd; #endif @@ -2458,7 +2455,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER fd = openat(dump_info->dirfd, dump_info->CurrentFileName, O_CREAT | O_WRONLY | O_TRUNC, 0644); if (fd < 0) { @@ -2471,7 +2468,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s dump_info->CurrentFileName); } dump_info->p = pcap_dump_fopen(dump_info->pd, fp); -#else /* !HAVE_CAPSICUM */ +#else /* !HAVE_CAPSPER */ dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName); #endif #ifdef HAVE_LIBCAP_NG @@ -2480,7 +2477,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s #endif /* HAVE_LIBCAP_NG */ if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); -#ifdef HAVE_CAPSICUM +#ifdef HAVE_CAPSPER set_dumper_capsicum_rights(dump_info->p); #endif } diff --git a/etc/defaults/rc.conf b/etc/defaults/rc.conf index 12bf3f2..32bac4d 100644 --- a/etc/defaults/rc.conf +++ b/etc/defaults/rc.conf @@ -681,7 +681,6 @@ newsyslog_enable="YES" # Run newsyslog at startup. newsyslog_flags="-CN" # Newsyslog flags to create marked files mixer_enable="YES" # Run the sound mixer. opensm_enable="NO" # Opensm(8) for infiniband devices defaults to off -casperd_enable="YES" # casperd(8) daemon # rctl(8) requires kernel options RACCT and RCTL rctl_enable="YES" # Load rctl(8) rules on boot diff --git a/etc/mtree/BSD.debug.dist b/etc/mtree/BSD.debug.dist index 4a499ea..2f0aae9 100644 --- a/etc/mtree/BSD.debug.dist +++ b/etc/mtree/BSD.debug.dist @@ -15,8 +15,6 @@ lib geom .. - .. - libexec casper .. .. diff --git a/etc/mtree/BSD.include.dist b/etc/mtree/BSD.include.dist index 88e80e6..a9baa7e 100644 --- a/etc/mtree/BSD.include.dist +++ b/etc/mtree/BSD.include.dist @@ -93,6 +93,8 @@ scsi .. .. + casper + .. crypto .. dev diff --git a/etc/mtree/BSD.root.dist b/etc/mtree/BSD.root.dist index af2f6a9..1c1a1dd 100644 --- a/etc/mtree/BSD.root.dist +++ b/etc/mtree/BSD.root.dist @@ -80,12 +80,12 @@ .. .. lib + casper + .. geom .. .. libexec - casper - .. resolvconf .. .. diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 1e6e28f..6cc860b 100644 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -21,7 +21,6 @@ FILES= DAEMON \ ${_bluetooth} \ bridge \ ${_bthidd} \ - ${_casperd} \ cleanvar \ cleartmp \ cron \ @@ -176,10 +175,6 @@ FILES+= bootparams FILES+= bsnmpd .endif -.if ${MK_CASPER} != "no" -_casperd= casperd -.endif - .if ${MK_CCD} != "no" FILES+= ccd .endif diff --git a/etc/rc.d/casperd b/etc/rc.d/casperd deleted file mode 100644 index 0b80169..0000000 --- a/etc/rc.d/casperd +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# -# $FreeBSD$ -# - -# PROVIDE: casperd -# REQUIRE: NETWORKING syslogd -# BEFORE: DAEMON -# KEYWORD: shutdown - -. /etc/rc.subr - -name="casperd" -rcvar="casperd_enable" -pidfile="/var/run/${name}.pid" -command="/sbin/${name}" - -load_rc_config $name -run_rc_command "$1" diff --git a/gnu/usr.bin/groff/tmac/mdoc.local.in b/gnu/usr.bin/groff/tmac/mdoc.local.in index e7ec4cf..046b16b 100644 --- a/gnu/usr.bin/groff/tmac/mdoc.local.in +++ b/gnu/usr.bin/groff/tmac/mdoc.local.in @@ -34,7 +34,7 @@ .\" FreeBSD .Lb values .ds doc-str-Lb-libarchive Streaming Archive Library (libarchive, \-larchive) .ds doc-str-Lb-libbluetooth Bluetooth User Library (libbluetooth, \-lbluetooth) -.ds doc-str-Lb-libcapsicum Capsicum Library (libcapsicum, \-lcapsicum) +.ds doc-str-Lb-libcseper Casper Library (libcapsicum, \-lcasper) .ds doc-str-Lb-libcuse Userland Character Device Library (libcuse, \-lcuse) .ds doc-str-Lb-libedit Line Editor and History Library (libedit, \-ledit) .ds doc-str-Lb-libefi EFI Runtime Services Library (libefi, \-lefi) diff --git a/lib/Makefile b/lib/Makefile index 699aa6a..cfa0ea9 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -36,7 +36,6 @@ SUBDIR= ${SUBDIR_ORDERED} \ libbz2 \ libcalendar \ libcam \ - ${_libcapsicum} \ ${_libcasper} \ ${_libcom_err} \ libcompat \ @@ -135,8 +134,7 @@ SUBDIR_DEPEND_libbsnmp= ${_libnetgraph} SUBDIR_DEPEND_libc++:= libcxxrt SUBDIR_DEPEND_libc= libcompiler_rt SUBDIR_DEPEND_libcam= libsbuf -SUBDIR_DEPEND_libcapsicum= libnv -SUBDIR_DEPEND_libcasper= libcapsicum libnv libpjdlog +SUBDIR_DEPEND_libcasper= libnv SUBDIR_DEPEND_libdevstat= libkvm SUBDIR_DEPEND_libdpv= libfigpar ncurses libutil SUBDIR_DEPEND_libedit= ncurses @@ -171,7 +169,6 @@ _libbsnmp= libbsnmp .endif .if ${MK_CASPER} != "no" -_libcapsicum= libcapsicum _libcasper= libcasper .endif diff --git a/lib/libc/posix1e/posix1e.3 b/lib/libc/posix1e/posix1e.3 index 257b6f5..02fb3ef 100644 --- a/lib/libc/posix1e/posix1e.3 +++ b/lib/libc/posix1e/posix1e.3 @@ -25,7 +25,7 @@ .\" .\" $FreeBSD$ .\" -.Dd April 15, 2014 +.Dd February 25, 2016 .Dt POSIX1E 3 .Os .Sh NAME @@ -94,7 +94,7 @@ for mandatory access control labels. .Xr acl 3 , .Xr extattr 3 , .Xr libbsm 3 , -.Xr libcapsicum 3 , +.Xr libcasper 3 , .Xr mac 3 , .Xr capsicum 4 , .Xr ffs 7 , diff --git a/lib/libcapsicum/Makefile b/lib/libcapsicum/Makefile deleted file mode 100644 index 6ee5bb8..0000000 --- a/lib/libcapsicum/Makefile +++ /dev/null @@ -1,46 +0,0 @@ -# $FreeBSD$ - -LIB= capsicum - -SHLIB_MAJOR= 0 -SHLIBDIR?= /lib - -SRCS= libcapsicum.c -SRCS+= libcapsicum_dns.c -SRCS+= libcapsicum_grp.c -SRCS+= libcapsicum_pwd.c -SRCS+= libcapsicum_random.c -SRCS+= libcapsicum_service.c -SRCS+= libcapsicum_sysctl.c - -INCS= libcapsicum.h -INCS+= libcapsicum_dns.h -INCS+= libcapsicum_grp.h -INCS+= libcapsicum_pwd.h -INCS+= libcapsicum_random.h -INCS+= libcapsicum_service.h -INCS+= libcapsicum_sysctl.h - -LIBADD= nv - -CFLAGS+=-I${.CURDIR} -CFLAGS+=-I${.CURDIR}/../libnv - -WARNS?= 6 - -MAN+= libcapsicum.3 - -MLINKS+=libcapsicum.3 cap_init.3 -MLINKS+=libcapsicum.3 cap_wrap.3 -MLINKS+=libcapsicum.3 cap_unwrap.3 -MLINKS+=libcapsicum.3 cap_sock.3 -MLINKS+=libcapsicum.3 cap_clone.3 -MLINKS+=libcapsicum.3 cap_close.3 -MLINKS+=libcapsicum.3 cap_limit_get.3 -MLINKS+=libcapsicum.3 cap_limit_set.3 -MLINKS+=libcapsicum.3 cap_send_nvlist.3 -MLINKS+=libcapsicum.3 cap_recv_nvlist.3 -MLINKS+=libcapsicum.3 cap_xfer_nvlist.3 -MLINKS+=libcapsicum.3 cap_service_open.3 - -.include <bsd.lib.mk> diff --git a/lib/libcapsicum/Makefile.depend b/lib/libcapsicum/Makefile.depend deleted file mode 100644 index 4f7989b..0000000 --- a/lib/libcapsicum/Makefile.depend +++ /dev/null @@ -1,19 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - gnu/lib/libgcc \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/libnv \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/lib/libcapsicum/libcapsicum_dns.c b/lib/libcapsicum/libcapsicum_dns.c deleted file mode 100644 index 5f54283..0000000 --- a/lib/libcapsicum/libcapsicum_dns.c +++ /dev/null @@ -1,365 +0,0 @@ -/*- - * Copyright (c) 2012-2013 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Pawel Jakub Dawidek under sponsorship from - * the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/nv.h> - -#include <assert.h> -#include <netdb.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "libcapsicum.h" -#include "libcapsicum_dns.h" - -static struct hostent hent; - -static void -hostent_free(struct hostent *hp) -{ - unsigned int ii; - - free(hp->h_name); - hp->h_name = NULL; - if (hp->h_aliases != NULL) { - for (ii = 0; hp->h_aliases[ii] != NULL; ii++) - free(hp->h_aliases[ii]); - free(hp->h_aliases); - hp->h_aliases = NULL; - } - if (hp->h_addr_list != NULL) { - for (ii = 0; hp->h_addr_list[ii] != NULL; ii++) - free(hp->h_addr_list[ii]); - free(hp->h_addr_list); - hp->h_addr_list = NULL; - } -} - -static struct hostent * -hostent_unpack(const nvlist_t *nvl, struct hostent *hp) -{ - unsigned int ii, nitems; - char nvlname[64]; - int n; - - hostent_free(hp); - - hp->h_name = strdup(nvlist_get_string(nvl, "name")); - if (hp->h_name == NULL) - goto fail; - hp->h_addrtype = (int)nvlist_get_number(nvl, "addrtype"); - hp->h_length = (int)nvlist_get_number(nvl, "length"); - - nitems = (unsigned int)nvlist_get_number(nvl, "naliases"); - hp->h_aliases = calloc(sizeof(hp->h_aliases[0]), nitems + 1); - if (hp->h_aliases == NULL) - goto fail; - for (ii = 0; ii < nitems; ii++) { - n = snprintf(nvlname, sizeof(nvlname), "alias%u", ii); - assert(n > 0 && n < (int)sizeof(nvlname)); - hp->h_aliases[ii] = - strdup(nvlist_get_string(nvl, nvlname)); - if (hp->h_aliases[ii] == NULL) - goto fail; - } - hp->h_aliases[ii] = NULL; - - nitems = (unsigned int)nvlist_get_number(nvl, "naddrs"); - hp->h_addr_list = calloc(sizeof(hp->h_addr_list[0]), nitems + 1); - if (hp->h_addr_list == NULL) - goto fail; - for (ii = 0; ii < nitems; ii++) { - hp->h_addr_list[ii] = malloc(hp->h_length); - if (hp->h_addr_list[ii] == NULL) - goto fail; - n = snprintf(nvlname, sizeof(nvlname), "addr%u", ii); - assert(n > 0 && n < (int)sizeof(nvlname)); - bcopy(nvlist_get_binary(nvl, nvlname, NULL), - hp->h_addr_list[ii], hp->h_length); - } - hp->h_addr_list[ii] = NULL; - - return (hp); -fail: - hostent_free(hp); - h_errno = NO_RECOVERY; - return (NULL); -} - -struct hostent * -cap_gethostbyname(cap_channel_t *chan, const char *name) -{ - - return (cap_gethostbyname2(chan, name, AF_INET)); -} - -struct hostent * -cap_gethostbyname2(cap_channel_t *chan, const char *name, int type) -{ - struct hostent *hp; - nvlist_t *nvl; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "cmd", "gethostbyname"); - nvlist_add_number(nvl, "family", (uint64_t)type); - nvlist_add_string(nvl, "name", name); - nvl = cap_xfer_nvlist(chan, nvl, 0); - if (nvl == NULL) { - h_errno = NO_RECOVERY; - return (NULL); - } - if (nvlist_get_number(nvl, "error") != 0) { - h_errno = (int)nvlist_get_number(nvl, "error"); - nvlist_destroy(nvl); - return (NULL); - } - - hp = hostent_unpack(nvl, &hent); - nvlist_destroy(nvl); - return (hp); -} - -struct hostent * -cap_gethostbyaddr(cap_channel_t *chan, const void *addr, socklen_t len, - int type) -{ - struct hostent *hp; - nvlist_t *nvl; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "cmd", "gethostbyaddr"); - nvlist_add_binary(nvl, "addr", addr, (size_t)len); - nvlist_add_number(nvl, "family", (uint64_t)type); - nvl = cap_xfer_nvlist(chan, nvl, 0); - if (nvl == NULL) { - h_errno = NO_RECOVERY; - return (NULL); - } - if (nvlist_get_number(nvl, "error") != 0) { - h_errno = (int)nvlist_get_number(nvl, "error"); - nvlist_destroy(nvl); - return (NULL); - } - hp = hostent_unpack(nvl, &hent); - nvlist_destroy(nvl); - return (hp); -} - -static struct addrinfo * -addrinfo_unpack(const nvlist_t *nvl) -{ - struct addrinfo *ai; - const void *addr; - size_t addrlen; - const char *canonname; - - addr = nvlist_get_binary(nvl, "ai_addr", &addrlen); - ai = malloc(sizeof(*ai) + addrlen); - if (ai == NULL) - return (NULL); - ai->ai_flags = (int)nvlist_get_number(nvl, "ai_flags"); - ai->ai_family = (int)nvlist_get_number(nvl, "ai_family"); - ai->ai_socktype = (int)nvlist_get_number(nvl, "ai_socktype"); - ai->ai_protocol = (int)nvlist_get_number(nvl, "ai_protocol"); - ai->ai_addrlen = (socklen_t)addrlen; - canonname = nvlist_get_string(nvl, "ai_canonname"); - if (canonname != NULL) { - ai->ai_canonname = strdup(canonname); - if (ai->ai_canonname == NULL) { - free(ai); - return (NULL); - } - } else { - ai->ai_canonname = NULL; - } - ai->ai_addr = (void *)(ai + 1); - bcopy(addr, ai->ai_addr, addrlen); - ai->ai_next = NULL; - - return (ai); -} - -int -cap_getaddrinfo(cap_channel_t *chan, const char *hostname, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) -{ - struct addrinfo *firstai, *prevai, *curai; - unsigned int ii; - const nvlist_t *nvlai; - char nvlname[64]; - nvlist_t *nvl; - int error, n; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "cmd", "getaddrinfo"); - nvlist_add_string(nvl, "hostname", hostname); - nvlist_add_string(nvl, "servname", servname); - if (hints != NULL) { - nvlist_add_number(nvl, "hints.ai_flags", - (uint64_t)hints->ai_flags); - nvlist_add_number(nvl, "hints.ai_family", - (uint64_t)hints->ai_family); - nvlist_add_number(nvl, "hints.ai_socktype", - (uint64_t)hints->ai_socktype); - nvlist_add_number(nvl, "hints.ai_protocol", - (uint64_t)hints->ai_protocol); - } - nvl = cap_xfer_nvlist(chan, nvl, 0); - if (nvl == NULL) - return (EAI_MEMORY); - if (nvlist_get_number(nvl, "error") != 0) { - error = (int)nvlist_get_number(nvl, "error"); - nvlist_destroy(nvl); - return (error); - } - - nvlai = NULL; - firstai = prevai = curai = NULL; - for (ii = 0; ; ii++) { - n = snprintf(nvlname, sizeof(nvlname), "res%u", ii); - assert(n > 0 && n < (int)sizeof(nvlname)); - if (!nvlist_exists_nvlist(nvl, nvlname)) - break; - nvlai = nvlist_get_nvlist(nvl, nvlname); - curai = addrinfo_unpack(nvlai); - if (curai == NULL) - break; - if (prevai != NULL) - prevai->ai_next = curai; - else if (firstai == NULL) - firstai = curai; - prevai = curai; - } - nvlist_destroy(nvl); - if (curai == NULL && nvlai != NULL) { - if (firstai == NULL) - freeaddrinfo(firstai); - return (EAI_MEMORY); - } - - *res = firstai; - return (0); -} - -int -cap_getnameinfo(cap_channel_t *chan, const struct sockaddr *sa, socklen_t salen, - char *host, size_t hostlen, char *serv, size_t servlen, int flags) -{ - nvlist_t *nvl; - int error; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "cmd", "getnameinfo"); - nvlist_add_number(nvl, "hostlen", (uint64_t)hostlen); - nvlist_add_number(nvl, "servlen", (uint64_t)servlen); - nvlist_add_binary(nvl, "sa", sa, (size_t)salen); - nvlist_add_number(nvl, "flags", (uint64_t)flags); - nvl = cap_xfer_nvlist(chan, nvl, 0); - if (nvl == NULL) - return (EAI_MEMORY); - if (nvlist_get_number(nvl, "error") != 0) { - error = (int)nvlist_get_number(nvl, "error"); - nvlist_destroy(nvl); - return (error); - } - - if (host != NULL) - strlcpy(host, nvlist_get_string(nvl, "host"), hostlen + 1); - if (serv != NULL) - strlcpy(serv, nvlist_get_string(nvl, "serv"), servlen + 1); - nvlist_destroy(nvl); - return (0); -} - -static void -limit_remove(nvlist_t *limits, const char *prefix) -{ - const char *name; - size_t prefixlen; - void *cookie; - - prefixlen = strlen(prefix); -again: - cookie = NULL; - while ((name = nvlist_next(limits, NULL, &cookie)) != NULL) { - if (strncmp(name, prefix, prefixlen) == 0) { - nvlist_free(limits, name); - goto again; - } - } -} - -int -cap_dns_type_limit(cap_channel_t *chan, const char * const *types, - size_t ntypes) -{ - nvlist_t *limits; - unsigned int i; - char nvlname[64]; - int n; - - if (cap_limit_get(chan, &limits) < 0) - return (-1); - if (limits == NULL) - limits = nvlist_create(0); - else - limit_remove(limits, "type"); - for (i = 0; i < ntypes; i++) { - n = snprintf(nvlname, sizeof(nvlname), "type%u", i); - assert(n > 0 && n < (int)sizeof(nvlname)); - nvlist_add_string(limits, nvlname, types[i]); - } - return (cap_limit_set(chan, limits)); -} - -int -cap_dns_family_limit(cap_channel_t *chan, const int *families, - size_t nfamilies) -{ - nvlist_t *limits; - unsigned int i; - char nvlname[64]; - int n; - - if (cap_limit_get(chan, &limits) < 0) - return (-1); - if (limits == NULL) - limits = nvlist_create(0); - else - limit_remove(limits, "family"); - for (i = 0; i < nfamilies; i++) { - n = snprintf(nvlname, sizeof(nvlname), "family%u", i); - assert(n > 0 && n < (int)sizeof(nvlname)); - nvlist_add_number(limits, nvlname, (uint64_t)families[i]); - } - return (cap_limit_set(chan, limits)); -} diff --git a/lib/libcapsicum/libcapsicum_impl.h b/lib/libcapsicum/libcapsicum_impl.h deleted file mode 100644 index ce6f49f..0000000 --- a/lib/libcapsicum/libcapsicum_impl.h +++ /dev/null @@ -1,39 +0,0 @@ -/*- - * Copyright (c) 2012-2013 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Pawel Jakub Dawidek under sponsorship from - * the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _LIBCAPSICUM_IMPL_H_ -#define _LIBCAPSICUM_IMPL_H_ - -#define CASPER_SOCKPATH "/var/run/casper" - -bool fd_is_valid(int fd); - -#endif /* !_LIBCAPSICUM_IMPL_H_ */ diff --git a/lib/libcapsicum/libcapsicum_pwd.c b/lib/libcapsicum/libcapsicum_pwd.c deleted file mode 100644 index 5b44c34..0000000 --- a/lib/libcapsicum/libcapsicum_pwd.c +++ /dev/null @@ -1,391 +0,0 @@ -/*- - * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Pawel Jakub Dawidek under sponsorship from - * the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/nv.h> - -#include <assert.h> -#include <errno.h> -#include <pwd.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - -#include "libcapsicum.h" -#include "libcapsicum_pwd.h" - -static struct passwd gpwd; -static char *gbuffer; -static size_t gbufsize; - -static int -passwd_resize(void) -{ - char *buf; - - if (gbufsize == 0) - gbufsize = 1024; - else - gbufsize *= 2; - - buf = gbuffer; - gbuffer = realloc(buf, gbufsize); - if (gbuffer == NULL) { - free(buf); - gbufsize = 0; - return (ENOMEM); - } - memset(gbuffer, 0, gbufsize); - - return (0); -} - -static int -passwd_unpack_string(const nvlist_t *nvl, const char *fieldname, char **fieldp, - char **bufferp, size_t *bufsizep) -{ - const char *str; - size_t len; - - str = nvlist_get_string(nvl, fieldname); - len = strlcpy(*bufferp, str, *bufsizep); - if (len >= *bufsizep) - return (ERANGE); - *fieldp = *bufferp; - *bufferp += len + 1; - *bufsizep -= len + 1; - - return (0); -} - -static int -passwd_unpack(const nvlist_t *nvl, struct passwd *pwd, char *buffer, - size_t bufsize) -{ - int error; - - if (!nvlist_exists_string(nvl, "pw_name")) - return (EINVAL); - - memset(pwd, 0, sizeof(*pwd)); - - error = passwd_unpack_string(nvl, "pw_name", &pwd->pw_name, &buffer, - &bufsize); - if (error != 0) - return (error); - pwd->pw_uid = (uid_t)nvlist_get_number(nvl, "pw_uid"); - pwd->pw_gid = (gid_t)nvlist_get_number(nvl, "pw_gid"); - pwd->pw_change = (time_t)nvlist_get_number(nvl, "pw_change"); - error = passwd_unpack_string(nvl, "pw_passwd", &pwd->pw_passwd, &buffer, - &bufsize); - if (error != 0) - return (error); - error = passwd_unpack_string(nvl, "pw_class", &pwd->pw_class, &buffer, - &bufsize); - if (error != 0) - return (error); - error = passwd_unpack_string(nvl, "pw_gecos", &pwd->pw_gecos, &buffer, - &bufsize); - if (error != 0) - return (error); - error = passwd_unpack_string(nvl, "pw_dir", &pwd->pw_dir, &buffer, - &bufsize); - if (error != 0) - return (error); - error = passwd_unpack_string(nvl, "pw_shell", &pwd->pw_shell, &buffer, - &bufsize); - if (error != 0) - return (error); - pwd->pw_expire = (time_t)nvlist_get_number(nvl, "pw_expire"); - pwd->pw_fields = (int)nvlist_get_number(nvl, "pw_fields"); - - return (0); -} - -static int -cap_getpwcommon_r(cap_channel_t *chan, const char *cmd, const char *login, - uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, - struct passwd **result) -{ - nvlist_t *nvl; - bool getpw_r; - int error; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "cmd", cmd); - if (strcmp(cmd, "getpwent") == 0 || strcmp(cmd, "getpwent_r") == 0) { - /* Add nothing. */ - } else if (strcmp(cmd, "getpwnam") == 0 || - strcmp(cmd, "getpwnam_r") == 0) { - nvlist_add_string(nvl, "name", login); - } else if (strcmp(cmd, "getpwuid") == 0 || - strcmp(cmd, "getpwuid_r") == 0) { - nvlist_add_number(nvl, "uid", (uint64_t)uid); - } else { - abort(); - } - nvl = cap_xfer_nvlist(chan, nvl, 0); - if (nvl == NULL) { - assert(errno != 0); - *result = NULL; - return (errno); - } - error = (int)nvlist_get_number(nvl, "error"); - if (error != 0) { - nvlist_destroy(nvl); - *result = NULL; - return (error); - } - - if (!nvlist_exists_string(nvl, "pw_name")) { - /* Not found. */ - nvlist_destroy(nvl); - *result = NULL; - return (0); - } - - getpw_r = (strcmp(cmd, "getpwent_r") == 0 || - strcmp(cmd, "getpwnam_r") == 0 || strcmp(cmd, "getpwuid_r") == 0); - - for (;;) { - error = passwd_unpack(nvl, pwd, buffer, bufsize); - if (getpw_r || error != ERANGE) - break; - assert(buffer == gbuffer); - assert(bufsize == gbufsize); - error = passwd_resize(); - if (error != 0) - break; - /* Update pointers after resize. */ - buffer = gbuffer; - bufsize = gbufsize; - } - - nvlist_destroy(nvl); - - if (error == 0) - *result = pwd; - else - *result = NULL; - - return (error); -} - -static struct passwd * -cap_getpwcommon(cap_channel_t *chan, const char *cmd, const char *login, - uid_t uid) -{ - struct passwd *result; - int error, serrno; - - serrno = errno; - - error = cap_getpwcommon_r(chan, cmd, login, uid, &gpwd, gbuffer, - gbufsize, &result); - if (error != 0) { - errno = error; - return (NULL); - } - - errno = serrno; - - return (result); -} - -struct passwd * -cap_getpwent(cap_channel_t *chan) -{ - - return (cap_getpwcommon(chan, "getpwent", NULL, 0)); -} - -struct passwd * -cap_getpwnam(cap_channel_t *chan, const char *login) -{ - - return (cap_getpwcommon(chan, "getpwnam", login, 0)); -} - -struct passwd * -cap_getpwuid(cap_channel_t *chan, uid_t uid) -{ - - return (cap_getpwcommon(chan, "getpwuid", NULL, uid)); -} - -int -cap_getpwent_r(cap_channel_t *chan, struct passwd *pwd, char *buffer, - size_t bufsize, struct passwd **result) -{ - - return (cap_getpwcommon_r(chan, "getpwent_r", NULL, 0, pwd, buffer, - bufsize, result)); -} - -int -cap_getpwnam_r(cap_channel_t *chan, const char *name, struct passwd *pwd, - char *buffer, size_t bufsize, struct passwd **result) -{ - - return (cap_getpwcommon_r(chan, "getpwnam_r", name, 0, pwd, buffer, - bufsize, result)); -} - -int -cap_getpwuid_r(cap_channel_t *chan, uid_t uid, struct passwd *pwd, char *buffer, - size_t bufsize, struct passwd **result) -{ - - return (cap_getpwcommon_r(chan, "getpwuid_r", NULL, uid, pwd, buffer, - bufsize, result)); -} - -int -cap_setpassent(cap_channel_t *chan, int stayopen) -{ - nvlist_t *nvl; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "cmd", "setpassent"); - nvlist_add_bool(nvl, "stayopen", stayopen != 0); - nvl = cap_xfer_nvlist(chan, nvl, 0); - if (nvl == NULL) - return (0); - if (nvlist_get_number(nvl, "error") != 0) { - errno = nvlist_get_number(nvl, "error"); - nvlist_destroy(nvl); - return (0); - } - nvlist_destroy(nvl); - - return (1); -} - -static void -cap_set_end_pwent(cap_channel_t *chan, const char *cmd) -{ - nvlist_t *nvl; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "cmd", cmd); - /* Ignore any errors, we have no way to report them. */ - nvlist_destroy(cap_xfer_nvlist(chan, nvl, 0)); -} - -void -cap_setpwent(cap_channel_t *chan) -{ - - cap_set_end_pwent(chan, "setpwent"); -} - -void -cap_endpwent(cap_channel_t *chan) -{ - - cap_set_end_pwent(chan, "endpwent"); -} - -int -cap_pwd_limit_cmds(cap_channel_t *chan, const char * const *cmds, size_t ncmds) -{ - nvlist_t *limits, *nvl; - unsigned int i; - - if (cap_limit_get(chan, &limits) < 0) - return (-1); - if (limits == NULL) { - limits = nvlist_create(0); - } else { - if (nvlist_exists_nvlist(limits, "cmds")) - nvlist_free_nvlist(limits, "cmds"); - } - nvl = nvlist_create(0); - for (i = 0; i < ncmds; i++) - nvlist_add_null(nvl, cmds[i]); - nvlist_move_nvlist(limits, "cmds", nvl); - return (cap_limit_set(chan, limits)); -} - -int -cap_pwd_limit_fields(cap_channel_t *chan, const char * const *fields, - size_t nfields) -{ - nvlist_t *limits, *nvl; - unsigned int i; - - if (cap_limit_get(chan, &limits) < 0) - return (-1); - if (limits == NULL) { - limits = nvlist_create(0); - } else { - if (nvlist_exists_nvlist(limits, "fields")) - nvlist_free_nvlist(limits, "fields"); - } - nvl = nvlist_create(0); - for (i = 0; i < nfields; i++) - nvlist_add_null(nvl, fields[i]); - nvlist_move_nvlist(limits, "fields", nvl); - return (cap_limit_set(chan, limits)); -} - -int -cap_pwd_limit_users(cap_channel_t *chan, const char * const *names, - size_t nnames, uid_t *uids, size_t nuids) -{ - nvlist_t *limits, *users; - char nvlname[64]; - unsigned int i; - int n; - - if (cap_limit_get(chan, &limits) < 0) - return (-1); - if (limits == NULL) { - limits = nvlist_create(0); - } else { - if (nvlist_exists_nvlist(limits, "users")) - nvlist_free_nvlist(limits, "users"); - } - users = nvlist_create(0); - for (i = 0; i < nuids; i++) { - n = snprintf(nvlname, sizeof(nvlname), "uid%u", i); - assert(n > 0 && n < (int)sizeof(nvlname)); - nvlist_add_number(users, nvlname, (uint64_t)uids[i]); - } - for (i = 0; i < nnames; i++) { - n = snprintf(nvlname, sizeof(nvlname), "name%u", i); - assert(n > 0 && n < (int)sizeof(nvlname)); - nvlist_add_string(users, nvlname, names[i]); - } - nvlist_move_nvlist(limits, "users", users); - return (cap_limit_set(chan, limits)); -} diff --git a/lib/libcapsicum/libcapsicum_service.c b/lib/libcapsicum/libcapsicum_service.c deleted file mode 100644 index 6b6ceea..0000000 --- a/lib/libcapsicum/libcapsicum_service.c +++ /dev/null @@ -1,97 +0,0 @@ -/*- - * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Pawel Jakub Dawidek under sponsorship from - * the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/nv.h> - -#include <assert.h> -#include <errno.h> -#include <string.h> -#include <unistd.h> - -#include "msgio.h" - -#include "libcapsicum.h" -#include "libcapsicum_impl.h" -#include "libcapsicum_service.h" - -cap_channel_t * -cap_service_open(const cap_channel_t *chan, const char *name) -{ - cap_channel_t *newchan; - nvlist_t *nvl; - int sock, error; - - sock = -1; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "cmd", "open"); - nvlist_add_string(nvl, "service", name); - if (fd_is_valid(STDERR_FILENO)) - nvlist_add_descriptor(nvl, "stderrfd", STDERR_FILENO); - nvl = cap_xfer_nvlist(chan, nvl, 0); - if (nvl == NULL) - return (NULL); - error = (int)nvlist_get_number(nvl, "error"); - if (error != 0) { - nvlist_destroy(nvl); - errno = error; - return (NULL); - } - sock = nvlist_take_descriptor(nvl, "chanfd"); - assert(sock >= 0); - nvlist_destroy(nvl); - nvl = NULL; - if (cred_send(sock) == -1) - goto fail; - newchan = cap_wrap(sock); - if (newchan == NULL) - goto fail; - return (newchan); -fail: - error = errno; - close(sock); - errno = error; - return (NULL); -} - -int -cap_service_limit(const cap_channel_t *chan, const char * const *names, - size_t nnames) -{ - nvlist_t *limits; - unsigned int i; - - limits = nvlist_create(0); - for (i = 0; i < nnames; i++) - nvlist_add_null(limits, names[i]); - return (cap_limit_set(chan, limits)); -} diff --git a/lib/libcapsicum/libcapsicum_sysctl.c b/lib/libcapsicum/libcapsicum_sysctl.c deleted file mode 100644 index 3f1ccd9..0000000 --- a/lib/libcapsicum/libcapsicum_sysctl.c +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Pawel Jakub Dawidek under sponsorship from - * the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/nv.h> - -#include <errno.h> -#include <string.h> - -#include "libcapsicum.h" -#include "libcapsicum_sysctl.h" - -int -cap_sysctlbyname(cap_channel_t *chan, const char *name, void *oldp, - size_t *oldlenp, const void *newp, size_t newlen) -{ - nvlist_t *nvl; - const uint8_t *retoldp; - uint8_t operation; - size_t oldlen; - - operation = 0; - if (oldp != NULL) - operation |= CAP_SYSCTL_READ; - if (newp != NULL) - operation |= CAP_SYSCTL_WRITE; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "cmd", "sysctl"); - nvlist_add_string(nvl, "name", name); - nvlist_add_number(nvl, "operation", (uint64_t)operation); - if (oldp == NULL && oldlenp != NULL) - nvlist_add_null(nvl, "justsize"); - else if (oldlenp != NULL) - nvlist_add_number(nvl, "oldlen", (uint64_t)*oldlenp); - if (newp != NULL) - nvlist_add_binary(nvl, "newp", newp, newlen); - nvl = cap_xfer_nvlist(chan, nvl, 0); - if (nvl == NULL) - return (-1); - if (nvlist_get_number(nvl, "error") != 0) { - errno = (int)nvlist_get_number(nvl, "error"); - nvlist_destroy(nvl); - return (-1); - } - - if (oldp == NULL && oldlenp != NULL) { - *oldlenp = (size_t)nvlist_get_number(nvl, "oldlen"); - } else if (oldp != NULL) { - retoldp = nvlist_get_binary(nvl, "oldp", &oldlen); - memcpy(oldp, retoldp, oldlen); - if (oldlenp != NULL) - *oldlenp = oldlen; - } - nvlist_destroy(nvl); - - return (0); -} diff --git a/lib/libcasper/Makefile b/lib/libcasper/Makefile index e57accd..af0701b 100644 --- a/lib/libcasper/Makefile +++ b/lib/libcasper/Makefile @@ -1,19 +1,6 @@ # $FreeBSD$ -LIB= casper +SUBDIR= libcasper +SUBDIR+= services -SHLIB_MAJOR= 0 -SHLIBDIR?= /lib - -SRCS= libcasper.c -INCS= libcasper.h - -LIBADD= capsicum nv pjdlog - -CFLAGS+=-I${.CURDIR} -CFLAGS+=-I${.CURDIR}/../libpjdlog -CFLAGS+=-I${.CURDIR}/../../sbin/casper - -WARNS?= 6 - -.include <bsd.lib.mk> +.include <bsd.subdir.mk> diff --git a/lib/libcasper/libcasper.h b/lib/libcasper/libcasper.h deleted file mode 100644 index 91d6027..0000000 --- a/lib/libcasper/libcasper.h +++ /dev/null @@ -1,70 +0,0 @@ -/*- - * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Pawel Jakub Dawidek under sponsorship from - * the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _LIBCASPER_H_ -#define _LIBCASPER_H_ - -#ifndef _NVLIST_T_DECLARED -#define _NVLIST_T_DECLARED -struct nvlist; - -typedef struct nvlist nvlist_t; -#endif - -#define PARENT_FILENO 3 -#define EXECUTABLE_FILENO 4 -#define PROC_FILENO 5 - -struct service; -struct service_connection; - -typedef int service_limit_func_t(const nvlist_t *, const nvlist_t *); -typedef int service_command_func_t(const char *cmd, const nvlist_t *, - nvlist_t *, nvlist_t *); - -struct service_connection *service_connection_add(struct service *service, - int sock, const nvlist_t *limits); -void service_connection_remove(struct service *service, - struct service_connection *sconn); -int service_connection_clone(struct service *service, - struct service_connection *sconn); -struct service_connection *service_connection_first(struct service *service); -struct service_connection *service_connection_next(struct service_connection *sconn); -cap_channel_t *service_connection_get_chan(const struct service_connection *sconn); -int service_connection_get_sock(const struct service_connection *sconn); -const nvlist_t *service_connection_get_limits(const struct service_connection *sconn); -void service_connection_set_limits(struct service_connection *sconn, - nvlist_t *limits); - -int service_start(const char *name, int sock, service_limit_func_t *limitfunc, - service_command_func_t *commandfunc, int argc, char *argv[]); - -#endif /* !_LIBCASPER_H_ */ diff --git a/lib/libcasper/libcasper/Makefile b/lib/libcasper/libcasper/Makefile new file mode 100644 index 0000000..2a123ac --- /dev/null +++ b/lib/libcasper/libcasper/Makefile @@ -0,0 +1,38 @@ +# $FreeBSD$ + +LIB= casper + +SHLIB_MAJOR= 0 +SHLIBDIR?= /lib + +SRCS= libcasper.c +SRCS+= libcasper_impl.c +SRCS+= libcasper_service.c +SRCS+= service.c +SRCS+= zygote.c + +INCS= libcasper.h +INCS+= libcasper_service.h + +LIBADD= nv + +CFLAGS+=-I${.CURDIR} + +WARNS?= 6 + +MAN+= libcasper.3 + +MLINKS+=libcasper.3 cap_init.3 +MLINKS+=libcasper.3 cap_wrap.3 +MLINKS+=libcasper.3 cap_unwrap.3 +MLINKS+=libcasper.3 cap_sock.3 +MLINKS+=libcasper.3 cap_clone.3 +MLINKS+=libcasper.3 cap_close.3 +MLINKS+=libcasper.3 cap_limit_get.3 +MLINKS+=libcasper.3 cap_limit_set.3 +MLINKS+=libcasper.3 cap_send_nvlist.3 +MLINKS+=libcasper.3 cap_recv_nvlist.3 +MLINKS+=libcasper.3 cap_xfer_nvlist.3 +MLINKS+=libcasper.3 cap_service_open.3 + +.include <bsd.lib.mk> diff --git a/lib/libcapsicum/libcapsicum.3 b/lib/libcasper/libcasper/libcasper.3 index cbfd214..220b5b3 100644 --- a/lib/libcapsicum/libcapsicum.3 +++ b/lib/libcasper/libcasper/libcasper.3 @@ -27,8 +27,8 @@ .\" .\" $FreeBSD$ .\" -.Dd May 2, 2015 -.Dt LIBCAPSICUM 3 +.Dd February 25, 2016 +.Dt LIBCASPER 3 .Os .Sh NAME .Nm cap_init , @@ -45,9 +45,9 @@ .Nm cap_service_open .Nd "library for handling application capabilities" .Sh LIBRARY -.Lb libcapsicum +.Lb libcasper .Sh SYNOPSIS -.In libcapsicum.h +.In libcasper.h .In nv.h .Ft "cap_channel_t *" .Fn cap_init "void" @@ -71,24 +71,18 @@ .Fn cap_recv_nvlist "const cap_channel_t *chan" "int flags" .Ft "nvlist_t *" .Fn cap_xfer_nvlist "const cap_channel_t *chan" "nvlist_t *nvl" "int flags" -.In libcapsicum_service.h .Ft "cap_channel_t *" .Fn cap_service_open "const cap_channel_t *chan" "const char *name" .Sh DESCRIPTION The .Nm libcapsicum -library allows to manage application capabilities through the -.Xr casperd 8 -daemon. +library allows to manage application capabilities through the casper process. .Pp The application capability (represented by the .Vt cap_channel_t -type) is a communication channel between the caller and the -.Xr casperd 8 +type) is a communication channel between the caller and the casper process daemon or an instance of one of its services. -A capability to the -.Xr casperd 8 -daemon obtained with the +A capability to the casper process obtained with the .Fn cap_init function allows to create capabilities to casper's services via the .Fn cap_service_open @@ -96,9 +90,7 @@ function. .Pp The .Fn cap_init -function opens capability to the -.Xr casperd 8 -daemon. +function opens capability to the casper process. .Pp The .Fn cap_wrap @@ -231,9 +223,8 @@ and .Fn cap_unwrap functions always succeed. .Sh EXAMPLES -The following example first opens capability to the -.Xr casperd 8 -daemon, then using this capability creates new capability to the +The following example first opens capability to the casper then using this +capability creates new capability to the .Nm system.dns casper service and uses the latter capability to resolve IP address. .Bd -literal @@ -243,10 +234,10 @@ const char *ipstr = "127.0.0.1"; struct in_addr ip; struct hostent *hp; -/* Open capability to the Casper daemon. */ +/* Open capability to the Casper. */ capcas = cap_init(); if (capcas == NULL) - err(1, "Unable to contact Casper daemon"); + err(1, "Unable to contact Casper"); /* Enter capability mode sandbox. */ if (cap_enter() < 0 && errno != ENOSYS) @@ -290,11 +281,15 @@ printf("Name associated with %s is %s.\\n", ipstr, hp->h_name); .Xr inet_aton 3 , .Xr nv 3 , .Xr capsicum 4 , -.Xr unix 4 , -.Xr casperd 8 +.Xr unix 4 .Sh AUTHORS The -.Nm libcapsicum +.Nm libcasper library was implemented by .An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net under sponsorship from the FreeBSD Foundation. +The +.Nm libcasper +new architecture was implemented by +.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org +. diff --git a/lib/libcapsicum/libcapsicum.c b/lib/libcasper/libcasper/libcasper.c index 8c4d04d..f23d8b1 100644 --- a/lib/libcapsicum/libcapsicum.c +++ b/lib/libcasper/libcasper/libcasper.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2012-2013 The FreeBSD Foundation + * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> * All rights reserved. * * This software was developed by Pawel Jakub Dawidek under sponsorship from @@ -32,19 +33,18 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> #include <sys/socket.h> -#include <sys/un.h> #include <sys/nv.h> +#include <sys/procdesc.h> #include <assert.h> #include <errno.h> -#include <fcntl.h> #include <stdbool.h> #include <stdlib.h> #include <string.h> #include <unistd.h> -#include "libcapsicum.h" -#include "libcapsicum_impl.h" +#include "libcasper.h" +#include "libcasper_impl.h" /* * Structure describing communication channel between two separated processes. @@ -58,44 +58,61 @@ struct cap_channel { int cch_magic; /* Socket descriptor for IPC. */ int cch_sock; + /* Process descriptor for casper. */ + int cch_pd; }; -bool -fd_is_valid(int fd) +static bool +cap_add_pd(cap_channel_t *chan, int pd) { - return (fcntl(fd, F_GETFL) != -1 || errno != EBADF); + if (!fd_is_valid(pd)) + return (false); + chan->cch_pd = pd; + return (true); } cap_channel_t * cap_init(void) { + pid_t pid; + int sock[2], serrno, pfd; + bool ret; cap_channel_t *chan; - struct sockaddr_un sun; - int serrno, sock; - bzero(&sun, sizeof(sun)); - sun.sun_family = AF_UNIX; - strlcpy(sun.sun_path, CASPER_SOCKPATH, sizeof(sun.sun_path)); - sun.sun_len = SUN_LEN(&sun); - - sock = socket(AF_UNIX, SOCK_STREAM, 0); - if (sock == -1) - return (NULL); - if (connect(sock, (struct sockaddr *)&sun, sizeof(sun)) < 0) { - serrno = errno; - close(sock); - errno = serrno; + if (socketpair(PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0, + sock) == -1) { return (NULL); } - chan = cap_wrap(sock); - if (chan == NULL) { - serrno = errno; - close(sock); - errno = serrno; - return (NULL); + + pid = pdfork(&pfd, 0); + if (pid == 0) { + /* Parent. */ + close(sock[0]); + casper_main_loop(sock[1]); + /* NOTREACHED. */ + } else if (pid > 0) { + /* Child. */ + close(sock[1]); + chan = cap_wrap(sock[0]); + if (chan == NULL) { + serrno = errno; + close(sock[0]); + close(pfd); + errno = serrno; + return (NULL); + } + ret = cap_add_pd(chan, pfd); + assert(ret); + return (chan); } - return (chan); + + /* Error. */ + serrno = errno; + close(sock[0]); + close(sock[1]); + errno = serrno; + return (NULL); } cap_channel_t * @@ -109,6 +126,7 @@ cap_wrap(int sock) chan = malloc(sizeof(*chan)); if (chan != NULL) { chan->cch_sock = sock; + chan->cch_pd = -1; chan->cch_magic = CAP_CHANNEL_MAGIC; } @@ -124,6 +142,8 @@ cap_unwrap(cap_channel_t *chan) assert(chan->cch_magic == CAP_CHANNEL_MAGIC); sock = chan->cch_sock; + if (chan->cch_pd != -1) + close(chan->cch_pd); chan->cch_magic = 0; free(chan); @@ -172,6 +192,8 @@ cap_close(cap_channel_t *chan) assert(chan->cch_magic == CAP_CHANNEL_MAGIC); chan->cch_magic = 0; + if (chan->cch_pd != -1) + close(chan->cch_pd); close(chan->cch_sock); free(chan); } @@ -264,3 +286,52 @@ cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl, int flags) return (nvlist_xfer(chan->cch_sock, nvl, flags)); } + +cap_channel_t * +cap_service_open(const cap_channel_t *chan, const char *name) +{ + cap_channel_t *newchan; + nvlist_t *nvl; + int sock, error; + + sock = -1; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "open"); + nvlist_add_string(nvl, "service", name); + nvl = cap_xfer_nvlist(chan, nvl, 0); + if (nvl == NULL) + return (NULL); + error = (int)nvlist_get_number(nvl, "error"); + if (error != 0) { + nvlist_destroy(nvl); + errno = error; + return (NULL); + } + sock = nvlist_take_descriptor(nvl, "chanfd"); + assert(sock >= 0); + nvlist_destroy(nvl); + nvl = NULL; + newchan = cap_wrap(sock); + if (newchan == NULL) + goto fail; + return (newchan); +fail: + error = errno; + close(sock); + errno = error; + return (NULL); +} + +int +cap_service_limit(const cap_channel_t *chan, const char * const *names, + size_t nnames) +{ + nvlist_t *limits; + unsigned int i; + + limits = nvlist_create(0); + for (i = 0; i < nnames; i++) + nvlist_add_null(limits, names[i]); + return (cap_limit_set(chan, limits)); +} diff --git a/lib/libcapsicum/libcapsicum.h b/lib/libcasper/libcasper/libcasper.h index c7110d8..2d6f158 100644 --- a/lib/libcapsicum/libcapsicum.h +++ b/lib/libcasper/libcasper/libcasper.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2012-2013 The FreeBSD Foundation + * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> * All rights reserved. * * This software was developed by Pawel Jakub Dawidek under sponsorship from @@ -29,8 +30,10 @@ * $FreeBSD$ */ -#ifndef _LIBCAPSICUM_H_ -#define _LIBCAPSICUM_H_ +#ifndef _LIBCASPER_H_ +#define _LIBCASPER_H_ + +#include <sys/types.h> #ifndef _NVLIST_T_DECLARED #define _NVLIST_T_DECLARED @@ -47,11 +50,18 @@ typedef struct cap_channel cap_channel_t; #endif /* - * The function opens unrestricted communication channel to Casper. + * The functions opens unrestricted communication channel to Casper. */ cap_channel_t *cap_init(void); /* + * The functions to communicate with service. + */ +cap_channel_t *cap_service_open(const cap_channel_t *chan, const char *name); +int cap_service_limit(const cap_channel_t *chan, + const char * const *names, size_t nnames); + +/* * The function creates cap_channel_t based on the given socket. */ cap_channel_t *cap_wrap(int sock); @@ -88,16 +98,6 @@ int cap_limit_set(const cap_channel_t *chan, nvlist_t *limits); */ int cap_limit_get(const cap_channel_t *chan, nvlist_t **limitsp); -#ifdef TODO -/* - * The function registers a service within provided Casper's capability. - * It will run with the same privileges the process has at the time of - * calling this function. - */ -int cap_service_register(cap_channel_t *chan, const char *name, - cap_func_t *func); -#endif - /* * Function sends nvlist over the given capability. */ @@ -112,4 +112,4 @@ nvlist_t *cap_recv_nvlist(const cap_channel_t *chan, int flags); */ nvlist_t *cap_xfer_nvlist(const cap_channel_t *chan, nvlist_t *nvl, int flags); -#endif /* !_LIBCAPSICUM_H_ */ +#endif /* !_LIBCASPER_H_ */ diff --git a/lib/libcapsicum/libcapsicum_service.h b/lib/libcasper/libcasper/libcasper_impl.c index 05c654f..57d4899 100644 --- a/lib/libcapsicum/libcapsicum_service.h +++ b/lib/libcasper/libcasper/libcasper_impl.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation + * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> * All rights reserved. * * This software was developed by Pawel Jakub Dawidek under sponsorship from @@ -29,12 +30,15 @@ * $FreeBSD$ */ -#ifndef _LIBCAPSICUM_SERVICE_H_ -#define _LIBCAPSICUM_SERVICE_H_ +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> -cap_channel_t *cap_service_open(const cap_channel_t *chan, const char *name); +#include "libcasper_impl.h" -int cap_service_limit(const cap_channel_t *chan, const char * const *names, - size_t nnames); +bool +fd_is_valid(int fd) +{ -#endif /* !_LIBCAPSICUM_SERVICE_H_ */ + return (fcntl(fd, F_GETFL) != -1 || errno != EBADF); +} diff --git a/lib/libcasper/libcasper/libcasper_impl.h b/lib/libcasper/libcasper/libcasper_impl.h new file mode 100644 index 0000000..bf2e6ce --- /dev/null +++ b/lib/libcasper/libcasper/libcasper_impl.h @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2013 The FreeBSD Foundation + * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _LIBCASPER_IMPL_H_ +#define _LIBCASPER_IMPL_H_ + +#include <stdbool.h> + +#include "libcasper.h" +#include "libcasper_service.h" + +struct service; +struct service_connection; + +bool fd_is_valid(int fd); + +/* Private service functions. */ +struct service *service_alloc(const char *name, + service_limit_func_t *limitfunc, + service_command_func_t *commandfunc); +void service_free(struct service *service); +void service_message(struct service *service, + struct service_connection *sconn); +void service_start(struct service *service, int sock); +const char *service_name(struct service *service); + +/* Private service connection functions. */ +struct service_connection *service_connection_add(struct service *service, + int sock, const nvlist_t *limits); +void service_connection_remove( + struct service *service, + struct service_connection *sconn); +int service_connection_clone( + struct service *service, + struct service_connection *sconn); +struct service_connection *service_connection_first( + struct service *service); +struct service_connection *service_connection_next( + struct service_connection *sconn); +cap_channel_t *service_connection_get_chan( + const struct service_connection *sconn); +int service_connection_get_sock( + const struct service_connection *sconn); +const nvlist_t *service_connection_get_limits( + const struct service_connection *sconn); +void service_connection_set_limits( + struct service_connection *sconn, + nvlist_t *limits); + +/* Private libcasper functions. */ +void casper_main_loop(int fd); + +#endif /* !_LIBCASPER_IMPL_H_ */ diff --git a/lib/libcasper/libcasper/libcasper_service.c b/lib/libcasper/libcasper/libcasper_service.c new file mode 100644 index 0000000..5b1c7c8 --- /dev/null +++ b/lib/libcasper/libcasper/libcasper_service.c @@ -0,0 +1,277 @@ +/*- + * Copyright (c) 2012 The FreeBSD Foundation + * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> + * All rights reserved. + * + * This software was developed by Pawel Jakub Dawidek under sponsorship from + * the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/types.h> +#include <sys/queue.h> +#include <sys/socket.h> +#include <sys/nv.h> + +#include <assert.h> +#include <errno.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "libcasper_impl.h" +#include "zygote.h" + +struct casper_service { + struct service *cs_service; + TAILQ_ENTRY(casper_service) cs_next; +}; + +static TAILQ_HEAD(, casper_service) casper_services = + TAILQ_HEAD_INITIALIZER(casper_services); + +#define CORE_CASPER_NAME "core.casper" +#define CSERVICE_IS_CORE(service) \ + (strcmp(service_name(service->cs_service), CORE_CASPER_NAME) == 0) + +static struct casper_service * +service_find(const char *name) +{ + struct casper_service *casserv; + + TAILQ_FOREACH(casserv, &casper_services, cs_next) { + if (strcmp(service_name(casserv->cs_service), name) == 0) + break; + } + return (casserv); +} + +struct casper_service * +service_register(const char *name, service_limit_func_t *limitfunc, + service_command_func_t *commandfunc) +{ + struct casper_service *casserv; + + if (commandfunc == NULL) + return (NULL); + if (name == NULL || name[0] == '\0') + return (NULL); + if (service_find(name) != NULL) + return (NULL); + + casserv = malloc(sizeof(*casserv)); + if (casserv == NULL) + return (NULL); + + casserv->cs_service = service_alloc(name, limitfunc, commandfunc); + if (casserv->cs_service == NULL) { + free(casserv); + return (NULL); + } + TAILQ_INSERT_TAIL(&casper_services, casserv, cs_next); + + return (casserv); +} + +static bool +casper_allowed_service(const nvlist_t *limits, const char *service) +{ + + if (limits == NULL) + return (true); + + if (nvlist_exists_null(limits, service)) + return (true); + + return (false); +} + +static int +casper_limit(const nvlist_t *oldlimits, const nvlist_t *newlimits) +{ + const char *name; + int type; + void *cookie; + + cookie = NULL; + while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { + if (type != NV_TYPE_NULL) + return (EINVAL); + if (!casper_allowed_service(oldlimits, name)) + return (ENOTCAPABLE); + } + + return (0); +} + +static void +service_execute(int chanfd) +{ + struct service *service; + nvlist_t *nvl; + int procfd; + + nvl = nvlist_recv(chanfd, 0); + if (nvl == NULL) + exit(1); + service = (struct service *)(uintptr_t)nvlist_take_number(nvl, + "service"); + //XXX: We should remove this? + procfd = nvlist_take_descriptor(nvl, "procfd"); + nvlist_destroy(nvl); + + service_start(service, chanfd); + /* Not reached. */ + exit(1); +} + +static int +casper_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, + nvlist_t *nvlout) +{ + struct casper_service *casserv; + const char *servname; + nvlist_t *nvl; + int chanfd, procfd, error; + + if (strcmp(cmd, "open") != 0) + return (EINVAL); + if (!nvlist_exists_string(nvlin, "service")) + return (EINVAL); + + servname = nvlist_get_string(nvlin, "service"); + casserv = service_find(servname); + if (casserv == NULL) + return (ENOENT); + + if (!casper_allowed_service(limits, servname)) + return (ENOTCAPABLE); + + if (zygote_clone(service_execute, &chanfd, &procfd) == -1) + return (errno); + + nvl = nvlist_create(0); + nvlist_add_number(nvl, "service", + (uint64_t)(uintptr_t)casserv->cs_service); + nvlist_move_descriptor(nvl, "procfd", procfd); + if (nvlist_send(chanfd, nvl) == -1) { + error = errno; + nvlist_destroy(nvl); + close(chanfd); + return (error); + } + nvlist_destroy(nvl); + + nvlist_move_descriptor(nvlout, "chanfd", chanfd); + + return (0); +} + +static void +service_register_core(int fd) +{ + struct casper_service *casserv; + struct service_connection *sconn; + + casserv = service_register(CORE_CASPER_NAME, casper_limit, + casper_command); + sconn = service_connection_add(casserv->cs_service, fd, NULL); + if (sconn == NULL) { + close(fd); + abort(); + } +} + +void +casper_main_loop(int fd) +{ + fd_set fds; + struct casper_service *casserv; + struct service_connection *sconn, *sconntmp; + int sock, maxfd, ret; + + if (zygote_init() < 0) + exit(1); + + /* + * Register core services. + */ + service_register_core(fd); + + for (;;) { + FD_ZERO(&fds); + FD_SET(fd, &fds); + maxfd = -1; + TAILQ_FOREACH(casserv, &casper_services, cs_next) { + /* We handle only core services. */ + if (!CSERVICE_IS_CORE(casserv)) + continue; + for (sconn = service_connection_first(casserv->cs_service); + sconn != NULL; + sconn = service_connection_next(sconn)) { + sock = service_connection_get_sock(sconn); + FD_SET(sock, &fds); + maxfd = sock > maxfd ? sock : maxfd; + } + } + if (maxfd == -1) { + /* Nothing to do. */ + exit(0); + } + maxfd++; + + + assert(maxfd <= (int)FD_SETSIZE); + ret = select(maxfd, &fds, NULL, NULL, NULL); + assert(ret == -1 || ret > 0); /* select() cannot timeout */ + if (ret == -1) { + if (errno == EINTR) + continue; + exit(1); + } + + TAILQ_FOREACH(casserv, &casper_services, cs_next) { + /* We handle only core services. */ + if (!CSERVICE_IS_CORE(casserv)) + continue; + for (sconn = service_connection_first(casserv->cs_service); + sconn != NULL; sconn = sconntmp) { + /* + * Prepare for connection to be removed from + * the list on failure. + */ + sconntmp = service_connection_next(sconn); + sock = service_connection_get_sock(sconn); + if (FD_ISSET(sock, &fds)) { + service_message(casserv->cs_service, + sconn); + } + } + } + } +} diff --git a/lib/libcasper/libcasper_impl.h b/lib/libcasper/libcasper/libcasper_service.h index 320f21a..4efbeb2 100644 --- a/lib/libcasper/libcasper_impl.h +++ b/lib/libcasper/libcasper/libcasper_service.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation + * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> * All rights reserved. * * This software was developed by Pawel Jakub Dawidek under sponsorship from @@ -29,18 +30,31 @@ * $FreeBSD$ */ -#ifndef _LIBCASPER_IMPL_H_ -#define _LIBCASPER_IMPL_H_ +#ifndef _LIBCASPER_SERVICE_H_ +#define _LIBCASPER_SERVICE_H_ -#include "libcasper.h" +#ifndef _NVLIST_T_DECLARED +#define _NVLIST_T_DECLARED +struct nvlist; -struct service; -struct service_connection; +typedef struct nvlist nvlist_t; +#endif -struct service * service_alloc(const char *name, +typedef int service_limit_func_t(const nvlist_t *, const nvlist_t *); +typedef int service_command_func_t(const char *cmd, const nvlist_t *, + nvlist_t *, nvlist_t *); + +struct casper_service *service_register(const char *name, service_limit_func_t *limitfunc, service_command_func_t *commandfunc); -void service_free(struct service *service); -void service_message(struct service *service, struct service_connection *sconn); +#define __constructor __attribute__((constructor)) +#define CREATE_SERVICE(name, limit_func, command_func) \ + static __constructor void \ + init_casper_service(void) \ + { \ + \ + (void)service_register(name, limit_func, \ + command_func); \ + } -#endif /* !_LIBCASPER_IMPL_H_ */ +#endif /* !_LIBCASPER_SERVICE_H_ */ diff --git a/lib/libcasper/libcasper.c b/lib/libcasper/libcasper/service.c index e241888..e02d7d9 100644 --- a/lib/libcasper/libcasper.c +++ b/lib/libcasper/libcasper/service.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2013 The FreeBSD Foundation + * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> * All rights reserved. * * This software was developed by Pawel Jakub Dawidek under sponsorship from @@ -31,11 +32,8 @@ __FBSDID("$FreeBSD$"); #include <sys/types.h> -#include <sys/capsicum.h> #include <sys/queue.h> #include <sys/socket.h> -#include <sys/stat.h> -#include <sys/un.h> #include <sys/nv.h> #include <assert.h> @@ -50,10 +48,8 @@ __FBSDID("$FreeBSD$"); #include <strings.h> #include <unistd.h> -#include <libcapsicum.h> -#include <libcasper.h> -#include <libcasper_impl.h> -#include <pjdlog.h> +#include "libcasper.h" +#include "libcasper_impl.h" /* * Currently there is only one service_connection per service. @@ -114,7 +110,7 @@ service_free(struct service *service) { struct service_connection *sconn; - PJDLOG_ASSERT(service->s_magic == SERVICE_MAGIC); + assert(service->s_magic == SERVICE_MAGIC); service->s_magic = 0; while ((sconn = service_connection_first(service)) != NULL) @@ -130,17 +126,14 @@ service_connection_add(struct service *service, int sock, struct service_connection *sconn; int serrno; - PJDLOG_ASSERT(service->s_magic == SERVICE_MAGIC); + assert(service->s_magic == SERVICE_MAGIC); sconn = malloc(sizeof(*sconn)); - if (sconn == NULL) { - pjdlog_error("Unable to allocate memory for service connection."); + if (sconn == NULL) return (NULL); - } sconn->sc_chan = cap_wrap(sock); if (sconn->sc_chan == NULL) { serrno = errno; - pjdlog_error("Unable to wrap communication channel."); free(sconn); errno = serrno; return (NULL); @@ -151,7 +144,6 @@ service_connection_add(struct service *service, int sock, sconn->sc_limits = nvlist_clone(limits); if (sconn->sc_limits == NULL) { serrno = errno; - pjdlog_error("Unable to clone limits."); (void)cap_unwrap(sconn->sc_chan); free(sconn); errno = serrno; @@ -168,8 +160,8 @@ service_connection_remove(struct service *service, struct service_connection *sconn) { - PJDLOG_ASSERT(service->s_magic == SERVICE_MAGIC); - PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + assert(service->s_magic == SERVICE_MAGIC); + assert(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); TAILQ_REMOVE(&service->s_connections, sconn, sc_next); sconn->sc_magic = 0; @@ -206,10 +198,10 @@ service_connection_first(struct service *service) { struct service_connection *sconn; - PJDLOG_ASSERT(service->s_magic == SERVICE_MAGIC); + assert(service->s_magic == SERVICE_MAGIC); sconn = TAILQ_FIRST(&service->s_connections); - PJDLOG_ASSERT(sconn == NULL || + assert(sconn == NULL || sconn->sc_magic == SERVICE_CONNECTION_MAGIC); return (sconn); } @@ -218,10 +210,10 @@ struct service_connection * service_connection_next(struct service_connection *sconn) { - PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + assert(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); sconn = TAILQ_NEXT(sconn, sc_next); - PJDLOG_ASSERT(sconn == NULL || + assert(sconn == NULL || sconn->sc_magic == SERVICE_CONNECTION_MAGIC); return (sconn); } @@ -230,7 +222,7 @@ cap_channel_t * service_connection_get_chan(const struct service_connection *sconn) { - PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + assert(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); return (sconn->sc_chan); } @@ -239,7 +231,7 @@ int service_connection_get_sock(const struct service_connection *sconn) { - PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + assert(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); return (cap_sock(sconn->sc_chan)); } @@ -248,7 +240,7 @@ const nvlist_t * service_connection_get_limits(const struct service_connection *sconn) { - PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + assert(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); return (sconn->sc_limits); } @@ -258,38 +250,12 @@ service_connection_set_limits(struct service_connection *sconn, nvlist_t *limits) { - PJDLOG_ASSERT(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); + assert(sconn->sc_magic == SERVICE_CONNECTION_MAGIC); nvlist_destroy(sconn->sc_limits); sconn->sc_limits = limits; } -#if 0 -static void -casper_message_connection(struct service *service, const nvlist_t *nvl) -{ - - service_connection_add(&service->s_connections, - nvlist_get_descriptor(nvl, "sock")); -} - -static void -casper_message(const cap_channel_t *capcas, struct service *service) -{ - const char *cmd; - nvlist_t *nvl; - - nvl = cap_recv_nvlist(capcas, 0); - if (nvl == NULL) - pjdlog_exit(1, "Unable to receive message from Casper"); - cmd = nvlist_get_string(nvl, "cmd"); - if (strcmp(cmd, "connection") == 0) - casper_message_connection(service, nvl); - else - PJDLOG_ABORT("Unknown command from Casper: %s.", cmd); -} -#endif - void service_message(struct service *service, struct service_connection *sconn) { @@ -299,12 +265,6 @@ service_message(struct service *service, struct service_connection *sconn) nvlin = cap_recv_nvlist(service_connection_get_chan(sconn), 0); if (nvlin == NULL) { - if (errno == ENOTCONN) { - pjdlog_debug(1, "Connection closed by the client."); - } else { - pjdlog_errno(LOG_ERR, - "Unable to receive message from client"); - } service_connection_remove(service, sconn); return; } @@ -313,15 +273,16 @@ service_message(struct service *service, struct service_connection *sconn) nvlout = nvlist_create(0); cmd = nvlist_get_string(nvlin, "cmd"); - pjdlog_debug(1, "Command received from client: %s.", cmd); - if (pjdlog_debug_get() >= 2) - nvlist_fdump(nvlin, stderr); if (strcmp(cmd, "limit_set") == 0) { nvlist_t *nvllim; nvllim = nvlist_take_nvlist(nvlin, "limits"); - error = service->s_limit(service_connection_get_limits(sconn), - nvllim); + if (service->s_limit == NULL) { + error = EOPNOTSUPP; + } else { + error = service->s_limit( + service_connection_get_limits(sconn), nvllim); + } if (error == 0) { service_connection_set_limits(sconn, nvllim); /* Function consumes nvllim. */ @@ -354,14 +315,9 @@ service_message(struct service *service, struct service_connection *sconn) nvlist_destroy(nvlin); nvlist_add_number(nvlout, "error", (uint64_t)error); - pjdlog_debug(1, "Sending reply to client (error=%d).", error); - if (pjdlog_debug_get() >= 2) - nvlist_fdump(nvlout, stderr); - if (cap_send_nvlist(service_connection_get_chan(sconn), nvlout) == -1) { - pjdlog_errno(LOG_ERR, "Unable to send message to client"); + if (cap_send_nvlist(service_connection_get_chan(sconn), nvlout) == -1) service_connection_remove(service, sconn); - } nvlist_destroy(nvlout); } @@ -374,28 +330,26 @@ fd_add(fd_set *fdsp, int maxfd, int fd) return (fd > maxfd ? fd : maxfd); } -int -service_start(const char *name, int sock, service_limit_func_t *limitfunc, - service_command_func_t *commandfunc, int argc, char *argv[]) +const char * +service_name(struct service *service) { - struct service *service; - struct service_connection *sconn, *sconntmp; - fd_set fds; - int maxfd, nfds, serrno; - assert(argc == 2); + assert(service->s_magic == SERVICE_MAGIC); + return (service->s_name); +} - pjdlog_init(PJDLOG_MODE_STD); - pjdlog_debug_set(atoi(argv[1])); +void +service_start(struct service *service, int sock) +{ + struct service_connection *sconn, *sconntmp; + fd_set fds; + int maxfd, nfds; - service = service_alloc(name, limitfunc, commandfunc); - if (service == NULL) - return (errno); - if (service_connection_add(service, sock, NULL) == NULL) { - serrno = errno; - service_free(service); - return (serrno); - } + assert(service != NULL); + assert(service->s_magic == SERVICE_MAGIC); + setproctitle("%s", service->s_name); + if (service_connection_add(service, sock, NULL) == NULL) + exit(1); for (;;) { FD_ZERO(&fds); @@ -406,17 +360,16 @@ service_start(const char *name, int sock, service_limit_func_t *limitfunc, service_connection_get_sock(sconn)); } - PJDLOG_ASSERT(maxfd >= 0); - PJDLOG_ASSERT(maxfd + 1 <= (int)FD_SETSIZE); + assert(maxfd >= 0); + assert(maxfd + 1 <= (int)FD_SETSIZE); nfds = select(maxfd + 1, &fds, NULL, NULL, NULL); if (nfds < 0) { if (errno != EINTR) - pjdlog_errno(LOG_ERR, "select() failed"); + exit(1); continue; } else if (nfds == 0) { /* Timeout. */ - PJDLOG_ABORT("select() timeout"); - continue; + abort(); } for (sconn = service_connection_first(service); sconn != NULL; @@ -437,5 +390,5 @@ service_start(const char *name, int sock, service_limit_func_t *limitfunc, } } - return (0); + exit(0); } diff --git a/sbin/casperd/zygote.c b/lib/libcasper/libcasper/zygote.c index 5bc9396..e554a3e 100644 --- a/sbin/casperd/zygote.c +++ b/lib/libcasper/libcasper/zygote.c @@ -1,5 +1,6 @@ /*- * Copyright (c) 2012 The FreeBSD Foundation + * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> * All rights reserved. * * This software was developed by Pawel Jakub Dawidek under sponsorship from @@ -45,10 +46,6 @@ __FBSDID("$FreeBSD$"); #include <strings.h> #include <unistd.h> -#include <libcapsicum.h> -#include <libcapsicum_impl.h> -#include <pjdlog.h> - #include "zygote.h" /* Zygote info. */ @@ -126,8 +123,7 @@ zygote_main(int sock) setproctitle("zygote"); - if (pjdlog_mode_get() != PJDLOG_MODE_STD) - stdnull(); + stdnull(); for (fd = STDERR_FILENO + 1; fd < sock; fd++) close(fd); closefrom(sock + 1); @@ -136,7 +132,7 @@ zygote_main(int sock) nvlin = nvlist_recv(sock, 0); if (nvlin == NULL) { if (errno == ENOTCONN) { - /* Casperd exited. */ + /* Casper exited. */ exit(0); } continue; diff --git a/sbin/casperd/zygote.h b/lib/libcasper/libcasper/zygote.h index 4c9c771..e147287 100644 --- a/sbin/casperd/zygote.h +++ b/lib/libcasper/libcasper/zygote.h @@ -1,5 +1,6 @@ /*- * Copyright (c) 2012 The FreeBSD Foundation + * Copyright (c) 2015 Mariusz Zaborski <oshogbo@FreeBSD.org> * All rights reserved. * * This software was developed by Pawel Jakub Dawidek under sponsorship from @@ -34,7 +35,7 @@ typedef void zygote_func_t(int); -int zygote_init(void); -int zygote_clone(zygote_func_t *func, int *chanfdp, int *procfdp); +int zygote_init(void); +int zygote_clone(zygote_func_t *func, int *chanfdp, int *procfdp); #endif /* !_ZYGOTE_H_ */ diff --git a/lib/libcasper/services/Makefile b/lib/libcasper/services/Makefile new file mode 100644 index 0000000..39b79af --- /dev/null +++ b/lib/libcasper/services/Makefile @@ -0,0 +1,9 @@ +# $FreeBSD$ + +SUBDIR= cap_dns +SUBDIR+= cap_grp +SUBDIR+= cap_pwd +SUBDIR+= cap_random +SUBDIR+= cap_sysctl + +.include <bsd.subdir.mk> diff --git a/lib/libcasper/services/cap_dns/Makefile b/lib/libcasper/services/cap_dns/Makefile new file mode 100644 index 0000000..871975d --- /dev/null +++ b/lib/libcasper/services/cap_dns/Makefile @@ -0,0 +1,20 @@ +# $FreeBSD$ + +LIB= cap_dns + +SHLIB_MAJOR= 0 +SHLIBDIR?= /lib/casper +INCSDIR?= ${INCLUDEDIR}/casper + +SRCS= cap_dns.c + +INCS= cap_dns.h + +LIBADD= nv + +CFLAGS+=-I${.CURDIR} +CFLAGS+=-I${.CURDIR}/../libcasper + +WARNS?= 6 + +.include <bsd.lib.mk> diff --git a/libexec/casper/dns/dns.c b/lib/libcasper/services/cap_dns/cap_dns.c index dbdb2a2..873af4c 100644 --- a/libexec/casper/dns/dns.c +++ b/lib/libcasper/services/cap_dns/cap_dns.c @@ -30,6 +30,7 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/dnv.h> #include <sys/nv.h> #include <netinet/in.h> @@ -38,12 +39,341 @@ __FBSDID("$FreeBSD$"); #include <netdb.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> -#include <libcapsicum.h> -#include <libcapsicum_dns.h> #include <libcasper.h> -#include <pjdlog.h> +#include <libcasper_service.h> +#include "cap_dns.h" + +static struct hostent hent; + +static void +hostent_free(struct hostent *hp) +{ + unsigned int ii; + + free(hp->h_name); + hp->h_name = NULL; + if (hp->h_aliases != NULL) { + for (ii = 0; hp->h_aliases[ii] != NULL; ii++) + free(hp->h_aliases[ii]); + free(hp->h_aliases); + hp->h_aliases = NULL; + } + if (hp->h_addr_list != NULL) { + for (ii = 0; hp->h_addr_list[ii] != NULL; ii++) + free(hp->h_addr_list[ii]); + free(hp->h_addr_list); + hp->h_addr_list = NULL; + } +} + +static struct hostent * +hostent_unpack(const nvlist_t *nvl, struct hostent *hp) +{ + unsigned int ii, nitems; + char nvlname[64]; + int n; + + hostent_free(hp); + + hp->h_name = strdup(nvlist_get_string(nvl, "name")); + if (hp->h_name == NULL) + goto fail; + hp->h_addrtype = (int)nvlist_get_number(nvl, "addrtype"); + hp->h_length = (int)nvlist_get_number(nvl, "length"); + + nitems = (unsigned int)nvlist_get_number(nvl, "naliases"); + hp->h_aliases = calloc(sizeof(hp->h_aliases[0]), nitems + 1); + if (hp->h_aliases == NULL) + goto fail; + for (ii = 0; ii < nitems; ii++) { + n = snprintf(nvlname, sizeof(nvlname), "alias%u", ii); + assert(n > 0 && n < (int)sizeof(nvlname)); + hp->h_aliases[ii] = + strdup(nvlist_get_string(nvl, nvlname)); + if (hp->h_aliases[ii] == NULL) + goto fail; + } + hp->h_aliases[ii] = NULL; + + nitems = (unsigned int)nvlist_get_number(nvl, "naddrs"); + hp->h_addr_list = calloc(sizeof(hp->h_addr_list[0]), nitems + 1); + if (hp->h_addr_list == NULL) + goto fail; + for (ii = 0; ii < nitems; ii++) { + hp->h_addr_list[ii] = malloc(hp->h_length); + if (hp->h_addr_list[ii] == NULL) + goto fail; + n = snprintf(nvlname, sizeof(nvlname), "addr%u", ii); + assert(n > 0 && n < (int)sizeof(nvlname)); + bcopy(nvlist_get_binary(nvl, nvlname, NULL), + hp->h_addr_list[ii], hp->h_length); + } + hp->h_addr_list[ii] = NULL; + + return (hp); +fail: + hostent_free(hp); + h_errno = NO_RECOVERY; + return (NULL); +} + +struct hostent * +cap_gethostbyname(cap_channel_t *chan, const char *name) +{ + + return (cap_gethostbyname2(chan, name, AF_INET)); +} + +struct hostent * +cap_gethostbyname2(cap_channel_t *chan, const char *name, int type) +{ + struct hostent *hp; + nvlist_t *nvl; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "gethostbyname"); + nvlist_add_number(nvl, "family", (uint64_t)type); + nvlist_add_string(nvl, "name", name); + nvl = cap_xfer_nvlist(chan, nvl, 0); + if (nvl == NULL) { + h_errno = NO_RECOVERY; + return (NULL); + } + if (nvlist_get_number(nvl, "error") != 0) { + h_errno = (int)nvlist_get_number(nvl, "error"); + nvlist_destroy(nvl); + return (NULL); + } + + hp = hostent_unpack(nvl, &hent); + nvlist_destroy(nvl); + return (hp); +} + +struct hostent * +cap_gethostbyaddr(cap_channel_t *chan, const void *addr, socklen_t len, + int type) +{ + struct hostent *hp; + nvlist_t *nvl; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "gethostbyaddr"); + nvlist_add_binary(nvl, "addr", addr, (size_t)len); + nvlist_add_number(nvl, "family", (uint64_t)type); + nvl = cap_xfer_nvlist(chan, nvl, 0); + if (nvl == NULL) { + h_errno = NO_RECOVERY; + return (NULL); + } + if (nvlist_get_number(nvl, "error") != 0) { + h_errno = (int)nvlist_get_number(nvl, "error"); + nvlist_destroy(nvl); + return (NULL); + } + hp = hostent_unpack(nvl, &hent); + nvlist_destroy(nvl); + return (hp); +} + +static struct addrinfo * +addrinfo_unpack(const nvlist_t *nvl) +{ + struct addrinfo *ai; + const void *addr; + size_t addrlen; + const char *canonname; + + addr = nvlist_get_binary(nvl, "ai_addr", &addrlen); + ai = malloc(sizeof(*ai) + addrlen); + if (ai == NULL) + return (NULL); + ai->ai_flags = (int)nvlist_get_number(nvl, "ai_flags"); + ai->ai_family = (int)nvlist_get_number(nvl, "ai_family"); + ai->ai_socktype = (int)nvlist_get_number(nvl, "ai_socktype"); + ai->ai_protocol = (int)nvlist_get_number(nvl, "ai_protocol"); + ai->ai_addrlen = (socklen_t)addrlen; + canonname = dnvlist_get_string(nvl, "ai_canonname", NULL); + if (canonname != NULL) { + ai->ai_canonname = strdup(canonname); + if (ai->ai_canonname == NULL) { + free(ai); + return (NULL); + } + } else { + ai->ai_canonname = NULL; + } + ai->ai_addr = (void *)(ai + 1); + bcopy(addr, ai->ai_addr, addrlen); + ai->ai_next = NULL; + + return (ai); +} + +int +cap_getaddrinfo(cap_channel_t *chan, const char *hostname, const char *servname, + const struct addrinfo *hints, struct addrinfo **res) +{ + struct addrinfo *firstai, *prevai, *curai; + unsigned int ii; + const nvlist_t *nvlai; + char nvlname[64]; + nvlist_t *nvl; + int error, n; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "getaddrinfo"); + if (hostname != NULL) + nvlist_add_string(nvl, "hostname", hostname); + if (servname != NULL) + nvlist_add_string(nvl, "servname", servname); + if (hints != NULL) { + nvlist_add_number(nvl, "hints.ai_flags", + (uint64_t)hints->ai_flags); + nvlist_add_number(nvl, "hints.ai_family", + (uint64_t)hints->ai_family); + nvlist_add_number(nvl, "hints.ai_socktype", + (uint64_t)hints->ai_socktype); + nvlist_add_number(nvl, "hints.ai_protocol", + (uint64_t)hints->ai_protocol); + } + nvl = cap_xfer_nvlist(chan, nvl, 0); + if (nvl == NULL) + return (EAI_MEMORY); + if (nvlist_get_number(nvl, "error") != 0) { + error = (int)nvlist_get_number(nvl, "error"); + nvlist_destroy(nvl); + return (error); + } + + nvlai = NULL; + firstai = prevai = curai = NULL; + for (ii = 0; ; ii++) { + n = snprintf(nvlname, sizeof(nvlname), "res%u", ii); + assert(n > 0 && n < (int)sizeof(nvlname)); + if (!nvlist_exists_nvlist(nvl, nvlname)) + break; + nvlai = nvlist_get_nvlist(nvl, nvlname); + curai = addrinfo_unpack(nvlai); + if (curai == NULL) + break; + if (prevai != NULL) + prevai->ai_next = curai; + else if (firstai == NULL) + firstai = curai; + prevai = curai; + } + nvlist_destroy(nvl); + if (curai == NULL && nvlai != NULL) { + if (firstai == NULL) + freeaddrinfo(firstai); + return (EAI_MEMORY); + } + + *res = firstai; + return (0); +} + +int +cap_getnameinfo(cap_channel_t *chan, const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, char *serv, size_t servlen, int flags) +{ + nvlist_t *nvl; + int error; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "getnameinfo"); + nvlist_add_number(nvl, "hostlen", (uint64_t)hostlen); + nvlist_add_number(nvl, "servlen", (uint64_t)servlen); + nvlist_add_binary(nvl, "sa", sa, (size_t)salen); + nvlist_add_number(nvl, "flags", (uint64_t)flags); + nvl = cap_xfer_nvlist(chan, nvl, 0); + if (nvl == NULL) + return (EAI_MEMORY); + if (nvlist_get_number(nvl, "error") != 0) { + error = (int)nvlist_get_number(nvl, "error"); + nvlist_destroy(nvl); + return (error); + } + + if (host != NULL && nvlist_exists_string(nvl, "host")) + strlcpy(host, nvlist_get_string(nvl, "host"), hostlen + 1); + if (serv != NULL && nvlist_exists_string(nvl, "serv")) + strlcpy(serv, nvlist_get_string(nvl, "serv"), servlen + 1); + nvlist_destroy(nvl); + return (0); +} + +static void +limit_remove(nvlist_t *limits, const char *prefix) +{ + const char *name; + size_t prefixlen; + void *cookie; + + prefixlen = strlen(prefix); +again: + cookie = NULL; + while ((name = nvlist_next(limits, NULL, &cookie)) != NULL) { + if (strncmp(name, prefix, prefixlen) == 0) { + nvlist_free(limits, name); + goto again; + } + } +} + +int +cap_dns_type_limit(cap_channel_t *chan, const char * const *types, + size_t ntypes) +{ + nvlist_t *limits; + unsigned int i; + char nvlname[64]; + int n; + + if (cap_limit_get(chan, &limits) < 0) + return (-1); + if (limits == NULL) + limits = nvlist_create(0); + else + limit_remove(limits, "type"); + for (i = 0; i < ntypes; i++) { + n = snprintf(nvlname, sizeof(nvlname), "type%u", i); + assert(n > 0 && n < (int)sizeof(nvlname)); + nvlist_add_string(limits, nvlname, types[i]); + } + return (cap_limit_set(chan, limits)); +} + +int +cap_dns_family_limit(cap_channel_t *chan, const int *families, + size_t nfamilies) +{ + nvlist_t *limits; + unsigned int i; + char nvlname[64]; + int n; + + if (cap_limit_get(chan, &limits) < 0) + return (-1); + if (limits == NULL) + limits = nvlist_create(0); + else + limit_remove(limits, "family"); + for (i = 0; i < nfamilies; i++) { + n = snprintf(nvlname, sizeof(nvlname), "family%u", i); + assert(n > 0 && n < (int)sizeof(nvlname)); + nvlist_add_number(limits, nvlname, (uint64_t)families[i]); + } + return (cap_limit_set(chan, limits)); +} + +/* + * Service functions. + */ static bool dns_allowed_type(const nvlist_t *limits, const char *type) { @@ -246,8 +576,10 @@ dns_getnameinfo(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) if (error != 0) goto out; - nvlist_move_string(nvlout, "host", host); - nvlist_move_string(nvlout, "serv", serv); + if (host != NULL) + nvlist_move_string(nvlout, "host", host); + if (serv != NULL) + nvlist_move_string(nvlout, "serv", serv); out: if (error != 0) { free(host); @@ -267,7 +599,8 @@ addrinfo_pack(const struct addrinfo *ai) nvlist_add_number(nvl, "ai_socktype", (uint64_t)ai->ai_socktype); nvlist_add_number(nvl, "ai_protocol", (uint64_t)ai->ai_protocol); nvlist_add_binary(nvl, "ai_addr", ai->ai_addr, (size_t)ai->ai_addrlen); - nvlist_add_string(nvl, "ai_canonname", ai->ai_canonname); + if (ai->ai_canonname != NULL) + nvlist_add_string(nvl, "ai_canonname", ai->ai_canonname); return (nvl); } @@ -285,11 +618,9 @@ dns_getaddrinfo(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) if (!dns_allowed_type(limits, "ADDR")) return (NO_RECOVERY); - hostname = nvlist_get_string(nvlin, "hostname"); - servname = nvlist_get_string(nvlin, "servname"); + hostname = dnvlist_get_string(nvlin, "hostname", NULL); + servname = dnvlist_get_string(nvlin, "servname", NULL); if (nvlist_exists_number(nvlin, "hints.ai_flags")) { - size_t addrlen; - hints.ai_flags = (int)nvlist_get_number(nvlin, "hints.ai_flags"); hints.ai_family = (int)nvlist_get_number(nvlin, @@ -427,10 +758,4 @@ dns_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, return (error); } -int -main(int argc, char *argv[]) -{ - - return (service_start("system.dns", PARENT_FILENO, dns_limit, - dns_command, argc, argv)); -} +CREATE_SERVICE("system.dns", dns_limit, dns_command); diff --git a/lib/libcapsicum/libcapsicum_dns.h b/lib/libcasper/services/cap_dns/cap_dns.h index 0223510..ea37542 100644 --- a/lib/libcapsicum/libcapsicum_dns.h +++ b/lib/libcasper/services/cap_dns/cap_dns.h @@ -29,8 +29,8 @@ * $FreeBSD$ */ -#ifndef _LIBCAPSICUM_DNS_H_ -#define _LIBCAPSICUM_DNS_H_ +#ifndef _CAP_DNS_H_ +#define _CAP_DNS_H_ #include <sys/socket.h> /* socklen_t */ @@ -54,4 +54,4 @@ int cap_dns_type_limit(cap_channel_t *chan, const char * const *types, int cap_dns_family_limit(cap_channel_t *chan, const int *families, size_t nfamilies); -#endif /* !_LIBCAPSICUM_DNS_H_ */ +#endif /* !_CAP_DNS_H_ */ diff --git a/lib/libcasper/services/cap_grp/Makefile b/lib/libcasper/services/cap_grp/Makefile new file mode 100644 index 0000000..81b9477 --- /dev/null +++ b/lib/libcasper/services/cap_grp/Makefile @@ -0,0 +1,20 @@ +# $FreeBSD$ + +LIB= cap_grp + +SHLIB_MAJOR= 0 +SHLIBDIR?= /lib/casper +INCSDIR?= ${INCLUDEDIR}/casper + +SRCS= cap_grp.c + +INCS= cap_grp.h + +LIBADD= nv + +CFLAGS+=-I${.CURDIR} +CFLAGS+=-I${.CURDIR}/../libcasper + +WARNS?= 6 + +.include <bsd.lib.mk> diff --git a/lib/libcapsicum/libcapsicum_grp.c b/lib/libcasper/services/cap_grp/cap_grp.c index 44d573e..d358cea 100644 --- a/lib/libcapsicum/libcapsicum_grp.c +++ b/lib/libcasper/services/cap_grp/cap_grp.c @@ -39,10 +39,11 @@ __FBSDID("$FreeBSD$"); #include <grp.h> #include <stdlib.h> #include <string.h> -#include <unistd.h> -#include "libcapsicum.h" -#include "libcapsicum_grp.h" +#include <libcasper.h> +#include <libcasper_service.h> + +#include "cap_grp.h" static struct group ggrp; static char *gbuffer; @@ -436,3 +437,351 @@ cap_grp_limit_groups(cap_channel_t *chan, const char * const *names, nvlist_move_nvlist(limits, "groups", groups); return (cap_limit_set(chan, limits)); } + +/* + * Service functions. + */ +static bool +grp_allowed_cmd(const nvlist_t *limits, const char *cmd) +{ + + if (limits == NULL) + return (true); + + /* + * If no limit was set on allowed commands, then all commands + * are allowed. + */ + if (!nvlist_exists_nvlist(limits, "cmds")) + return (true); + + limits = nvlist_get_nvlist(limits, "cmds"); + return (nvlist_exists_null(limits, cmd)); +} + +static int +grp_allowed_cmds(const nvlist_t *oldlimits, const nvlist_t *newlimits) +{ + const char *name; + void *cookie; + int type; + + cookie = NULL; + while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { + if (type != NV_TYPE_NULL) + return (EINVAL); + if (!grp_allowed_cmd(oldlimits, name)) + return (ENOTCAPABLE); + } + + return (0); +} + +static bool +grp_allowed_group(const nvlist_t *limits, const char *gname, gid_t gid) +{ + const char *name; + void *cookie; + int type; + + if (limits == NULL) + return (true); + + /* + * If no limit was set on allowed groups, then all groups are allowed. + */ + if (!nvlist_exists_nvlist(limits, "groups")) + return (true); + + limits = nvlist_get_nvlist(limits, "groups"); + cookie = NULL; + while ((name = nvlist_next(limits, &type, &cookie)) != NULL) { + switch (type) { + case NV_TYPE_NUMBER: + if (gid != (gid_t)-1 && + nvlist_get_number(limits, name) == (uint64_t)gid) { + return (true); + } + break; + case NV_TYPE_STRING: + if (gname != NULL && + strcmp(nvlist_get_string(limits, name), + gname) == 0) { + return (true); + } + break; + default: + abort(); + } + } + + return (false); +} + +static int +grp_allowed_groups(const nvlist_t *oldlimits, const nvlist_t *newlimits) +{ + const char *name, *gname; + void *cookie; + gid_t gid; + int type; + + cookie = NULL; + while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { + switch (type) { + case NV_TYPE_NUMBER: + gid = (gid_t)nvlist_get_number(newlimits, name); + gname = NULL; + break; + case NV_TYPE_STRING: + gid = (gid_t)-1; + gname = nvlist_get_string(newlimits, name); + break; + default: + return (EINVAL); + } + if (!grp_allowed_group(oldlimits, gname, gid)) + return (ENOTCAPABLE); + } + + return (0); +} + +static bool +grp_allowed_field(const nvlist_t *limits, const char *field) +{ + + if (limits == NULL) + return (true); + + /* + * If no limit was set on allowed fields, then all fields are allowed. + */ + if (!nvlist_exists_nvlist(limits, "fields")) + return (true); + + limits = nvlist_get_nvlist(limits, "fields"); + return (nvlist_exists_null(limits, field)); +} + +static int +grp_allowed_fields(const nvlist_t *oldlimits, const nvlist_t *newlimits) +{ + const char *name; + void *cookie; + int type; + + cookie = NULL; + while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { + if (type != NV_TYPE_NULL) + return (EINVAL); + if (!grp_allowed_field(oldlimits, name)) + return (ENOTCAPABLE); + } + + return (0); +} + +static bool +grp_pack(const nvlist_t *limits, const struct group *grp, nvlist_t *nvl) +{ + char nvlname[64]; + int n; + + if (grp == NULL) + return (true); + + /* + * If either name or GID is allowed, we allow it. + */ + if (!grp_allowed_group(limits, grp->gr_name, grp->gr_gid)) + return (false); + + if (grp_allowed_field(limits, "gr_name")) + nvlist_add_string(nvl, "gr_name", grp->gr_name); + else + nvlist_add_string(nvl, "gr_name", ""); + if (grp_allowed_field(limits, "gr_passwd")) + nvlist_add_string(nvl, "gr_passwd", grp->gr_passwd); + else + nvlist_add_string(nvl, "gr_passwd", ""); + if (grp_allowed_field(limits, "gr_gid")) + nvlist_add_number(nvl, "gr_gid", (uint64_t)grp->gr_gid); + else + nvlist_add_number(nvl, "gr_gid", (uint64_t)-1); + if (grp_allowed_field(limits, "gr_mem") && grp->gr_mem[0] != NULL) { + unsigned int ngroups; + + for (ngroups = 0; grp->gr_mem[ngroups] != NULL; ngroups++) { + n = snprintf(nvlname, sizeof(nvlname), "gr_mem[%u]", + ngroups); + assert(n > 0 && n < (ssize_t)sizeof(nvlname)); + nvlist_add_string(nvl, nvlname, grp->gr_mem[ngroups]); + } + nvlist_add_number(nvl, "gr_nmem", (uint64_t)ngroups); + } + + return (true); +} + +static int +grp_getgrent(const nvlist_t *limits, const nvlist_t *nvlin __unused, + nvlist_t *nvlout) +{ + struct group *grp; + + for (;;) { + errno = 0; + grp = getgrent(); + if (errno != 0) + return (errno); + if (grp_pack(limits, grp, nvlout)) + return (0); + } + + /* NOTREACHED */ +} + +static int +grp_getgrnam(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) +{ + struct group *grp; + const char *name; + + if (!nvlist_exists_string(nvlin, "name")) + return (EINVAL); + name = nvlist_get_string(nvlin, "name"); + assert(name != NULL); + + errno = 0; + grp = getgrnam(name); + if (errno != 0) + return (errno); + + (void)grp_pack(limits, grp, nvlout); + + return (0); +} + +static int +grp_getgrgid(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) +{ + struct group *grp; + gid_t gid; + + if (!nvlist_exists_number(nvlin, "gid")) + return (EINVAL); + + gid = (gid_t)nvlist_get_number(nvlin, "gid"); + + errno = 0; + grp = getgrgid(gid); + if (errno != 0) + return (errno); + + (void)grp_pack(limits, grp, nvlout); + + return (0); +} + +static int +grp_setgroupent(const nvlist_t *limits __unused, const nvlist_t *nvlin, + nvlist_t *nvlout __unused) +{ + int stayopen; + + if (!nvlist_exists_bool(nvlin, "stayopen")) + return (EINVAL); + + stayopen = nvlist_get_bool(nvlin, "stayopen") ? 1 : 0; + + return (setgroupent(stayopen) == 0 ? EFAULT : 0); +} + +static int +grp_setgrent(const nvlist_t *limits __unused, const nvlist_t *nvlin __unused, + nvlist_t *nvlout __unused) +{ + + return (setgrent() == 0 ? EFAULT : 0); +} + +static int +grp_endgrent(const nvlist_t *limits __unused, const nvlist_t *nvlin __unused, + nvlist_t *nvlout __unused) +{ + + endgrent(); + + return (0); +} + +static int +grp_limit(const nvlist_t *oldlimits, const nvlist_t *newlimits) +{ + const nvlist_t *limits; + const char *name; + void *cookie; + int error, type; + + if (oldlimits != NULL && nvlist_exists_nvlist(oldlimits, "cmds") && + !nvlist_exists_nvlist(newlimits, "cmds")) { + return (ENOTCAPABLE); + } + if (oldlimits != NULL && nvlist_exists_nvlist(oldlimits, "fields") && + !nvlist_exists_nvlist(newlimits, "fields")) { + return (ENOTCAPABLE); + } + if (oldlimits != NULL && nvlist_exists_nvlist(oldlimits, "groups") && + !nvlist_exists_nvlist(newlimits, "groups")) { + return (ENOTCAPABLE); + } + + cookie = NULL; + while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { + if (type != NV_TYPE_NVLIST) + return (EINVAL); + limits = nvlist_get_nvlist(newlimits, name); + if (strcmp(name, "cmds") == 0) + error = grp_allowed_cmds(oldlimits, limits); + else if (strcmp(name, "fields") == 0) + error = grp_allowed_fields(oldlimits, limits); + else if (strcmp(name, "groups") == 0) + error = grp_allowed_groups(oldlimits, limits); + else + error = EINVAL; + if (error != 0) + return (error); + } + + return (0); +} + +static int +grp_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, + nvlist_t *nvlout) +{ + int error; + + if (!grp_allowed_cmd(limits, cmd)) + return (ENOTCAPABLE); + + if (strcmp(cmd, "getgrent") == 0 || strcmp(cmd, "getgrent_r") == 0) + error = grp_getgrent(limits, nvlin, nvlout); + else if (strcmp(cmd, "getgrnam") == 0 || strcmp(cmd, "getgrnam_r") == 0) + error = grp_getgrnam(limits, nvlin, nvlout); + else if (strcmp(cmd, "getgrgid") == 0 || strcmp(cmd, "getgrgid_r") == 0) + error = grp_getgrgid(limits, nvlin, nvlout); + else if (strcmp(cmd, "setgroupent") == 0) + error = grp_setgroupent(limits, nvlin, nvlout); + else if (strcmp(cmd, "setgrent") == 0) + error = grp_setgrent(limits, nvlin, nvlout); + else if (strcmp(cmd, "endgrent") == 0) + error = grp_endgrent(limits, nvlin, nvlout); + else + error = EINVAL; + + return (error); +} + +CREATE_SERVICE("system.grp", grp_limit, grp_command); diff --git a/lib/libcapsicum/libcapsicum_grp.h b/lib/libcasper/services/cap_grp/cap_grp.h index e0b44f0..68595c1 100644 --- a/lib/libcapsicum/libcapsicum_grp.h +++ b/lib/libcasper/services/cap_grp/cap_grp.h @@ -29,8 +29,8 @@ * $FreeBSD$ */ -#ifndef _LIBCAPSICUM_GRP_H_ -#define _LIBCAPSICUM_GRP_H_ +#ifndef _CAP_GRP_H_ +#define _CAP_GRP_H_ struct group *cap_getgrent(cap_channel_t *chan); struct group *cap_getgrnam(cap_channel_t *chan, const char *name); @@ -54,4 +54,4 @@ int cap_grp_limit_fields(cap_channel_t *chan, const char * const *fields, int cap_grp_limit_groups(cap_channel_t *chan, const char * const *names, size_t nnames, gid_t *gids, size_t ngids); -#endif /* !_LIBCAPSICUM_GRP_H_ */ +#endif /* !_CAP_GRP_H_ */ diff --git a/lib/libcasper/services/cap_pwd/Makefile b/lib/libcasper/services/cap_pwd/Makefile new file mode 100644 index 0000000..34b8a12 --- /dev/null +++ b/lib/libcasper/services/cap_pwd/Makefile @@ -0,0 +1,20 @@ +# $FreeBSD$ + +LIB= cap_pwd + +SHLIB_MAJOR= 0 +SHLIBDIR?= /lib/casper +INCSDIR?= ${INCLUDEDIR}/casper + +SRCS= cap_pwd.c + +INCS= cap_pwd.h + +LIBADD= nv + +CFLAGS+=-I${.CURDIR} +CFLAGS+=-I${.CURDIR}/../libcasper + +WARNS?= 6 + +.include <bsd.lib.mk> diff --git a/libexec/casper/pwd/pwd.c b/lib/libcasper/services/cap_pwd/cap_pwd.c index 0a06c5f..254e244 100644 --- a/libexec/casper/pwd/pwd.c +++ b/lib/libcasper/services/cap_pwd/cap_pwd.c @@ -30,17 +30,372 @@ #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); +#include <sys/types.h> #include <sys/nv.h> +#include <assert.h> #include <errno.h> #include <pwd.h> #include <stdlib.h> #include <string.h> +#include <unistd.h> -#include <libcapsicum.h> #include <libcasper.h> -#include <pjdlog.h> +#include <libcasper_service.h> +#include "cap_pwd.h" + +static struct passwd gpwd; +static char *gbuffer; +static size_t gbufsize; + +static int +passwd_resize(void) +{ + char *buf; + + if (gbufsize == 0) + gbufsize = 1024; + else + gbufsize *= 2; + + buf = gbuffer; + gbuffer = realloc(buf, gbufsize); + if (gbuffer == NULL) { + free(buf); + gbufsize = 0; + return (ENOMEM); + } + memset(gbuffer, 0, gbufsize); + + return (0); +} + +static int +passwd_unpack_string(const nvlist_t *nvl, const char *fieldname, char **fieldp, + char **bufferp, size_t *bufsizep) +{ + const char *str; + size_t len; + + str = nvlist_get_string(nvl, fieldname); + len = strlcpy(*bufferp, str, *bufsizep); + if (len >= *bufsizep) + return (ERANGE); + *fieldp = *bufferp; + *bufferp += len + 1; + *bufsizep -= len + 1; + + return (0); +} + +static int +passwd_unpack(const nvlist_t *nvl, struct passwd *pwd, char *buffer, + size_t bufsize) +{ + int error; + + if (!nvlist_exists_string(nvl, "pw_name")) + return (EINVAL); + + memset(pwd, 0, sizeof(*pwd)); + + error = passwd_unpack_string(nvl, "pw_name", &pwd->pw_name, &buffer, + &bufsize); + if (error != 0) + return (error); + pwd->pw_uid = (uid_t)nvlist_get_number(nvl, "pw_uid"); + pwd->pw_gid = (gid_t)nvlist_get_number(nvl, "pw_gid"); + pwd->pw_change = (time_t)nvlist_get_number(nvl, "pw_change"); + error = passwd_unpack_string(nvl, "pw_passwd", &pwd->pw_passwd, &buffer, + &bufsize); + if (error != 0) + return (error); + error = passwd_unpack_string(nvl, "pw_class", &pwd->pw_class, &buffer, + &bufsize); + if (error != 0) + return (error); + error = passwd_unpack_string(nvl, "pw_gecos", &pwd->pw_gecos, &buffer, + &bufsize); + if (error != 0) + return (error); + error = passwd_unpack_string(nvl, "pw_dir", &pwd->pw_dir, &buffer, + &bufsize); + if (error != 0) + return (error); + error = passwd_unpack_string(nvl, "pw_shell", &pwd->pw_shell, &buffer, + &bufsize); + if (error != 0) + return (error); + pwd->pw_expire = (time_t)nvlist_get_number(nvl, "pw_expire"); + pwd->pw_fields = (int)nvlist_get_number(nvl, "pw_fields"); + + return (0); +} + +static int +cap_getpwcommon_r(cap_channel_t *chan, const char *cmd, const char *login, + uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, + struct passwd **result) +{ + nvlist_t *nvl; + bool getpw_r; + int error; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", cmd); + if (strcmp(cmd, "getpwent") == 0 || strcmp(cmd, "getpwent_r") == 0) { + /* Add nothing. */ + } else if (strcmp(cmd, "getpwnam") == 0 || + strcmp(cmd, "getpwnam_r") == 0) { + nvlist_add_string(nvl, "name", login); + } else if (strcmp(cmd, "getpwuid") == 0 || + strcmp(cmd, "getpwuid_r") == 0) { + nvlist_add_number(nvl, "uid", (uint64_t)uid); + } else { + abort(); + } + nvl = cap_xfer_nvlist(chan, nvl, 0); + if (nvl == NULL) { + assert(errno != 0); + *result = NULL; + return (errno); + } + error = (int)nvlist_get_number(nvl, "error"); + if (error != 0) { + nvlist_destroy(nvl); + *result = NULL; + return (error); + } + + if (!nvlist_exists_string(nvl, "pw_name")) { + /* Not found. */ + nvlist_destroy(nvl); + *result = NULL; + return (0); + } + + getpw_r = (strcmp(cmd, "getpwent_r") == 0 || + strcmp(cmd, "getpwnam_r") == 0 || strcmp(cmd, "getpwuid_r") == 0); + + for (;;) { + error = passwd_unpack(nvl, pwd, buffer, bufsize); + if (getpw_r || error != ERANGE) + break; + assert(buffer == gbuffer); + assert(bufsize == gbufsize); + error = passwd_resize(); + if (error != 0) + break; + /* Update pointers after resize. */ + buffer = gbuffer; + bufsize = gbufsize; + } + + nvlist_destroy(nvl); + + if (error == 0) + *result = pwd; + else + *result = NULL; + + return (error); +} + +static struct passwd * +cap_getpwcommon(cap_channel_t *chan, const char *cmd, const char *login, + uid_t uid) +{ + struct passwd *result; + int error, serrno; + + serrno = errno; + + error = cap_getpwcommon_r(chan, cmd, login, uid, &gpwd, gbuffer, + gbufsize, &result); + if (error != 0) { + errno = error; + return (NULL); + } + + errno = serrno; + + return (result); +} + +struct passwd * +cap_getpwent(cap_channel_t *chan) +{ + + return (cap_getpwcommon(chan, "getpwent", NULL, 0)); +} + +struct passwd * +cap_getpwnam(cap_channel_t *chan, const char *login) +{ + + return (cap_getpwcommon(chan, "getpwnam", login, 0)); +} + +struct passwd * +cap_getpwuid(cap_channel_t *chan, uid_t uid) +{ + + return (cap_getpwcommon(chan, "getpwuid", NULL, uid)); +} + +int +cap_getpwent_r(cap_channel_t *chan, struct passwd *pwd, char *buffer, + size_t bufsize, struct passwd **result) +{ + + return (cap_getpwcommon_r(chan, "getpwent_r", NULL, 0, pwd, buffer, + bufsize, result)); +} + +int +cap_getpwnam_r(cap_channel_t *chan, const char *name, struct passwd *pwd, + char *buffer, size_t bufsize, struct passwd **result) +{ + + return (cap_getpwcommon_r(chan, "getpwnam_r", name, 0, pwd, buffer, + bufsize, result)); +} + +int +cap_getpwuid_r(cap_channel_t *chan, uid_t uid, struct passwd *pwd, char *buffer, + size_t bufsize, struct passwd **result) +{ + + return (cap_getpwcommon_r(chan, "getpwuid_r", NULL, uid, pwd, buffer, + bufsize, result)); +} + +int +cap_setpassent(cap_channel_t *chan, int stayopen) +{ + nvlist_t *nvl; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "setpassent"); + nvlist_add_bool(nvl, "stayopen", stayopen != 0); + nvl = cap_xfer_nvlist(chan, nvl, 0); + if (nvl == NULL) + return (0); + if (nvlist_get_number(nvl, "error") != 0) { + errno = nvlist_get_number(nvl, "error"); + nvlist_destroy(nvl); + return (0); + } + nvlist_destroy(nvl); + + return (1); +} + +static void +cap_set_end_pwent(cap_channel_t *chan, const char *cmd) +{ + nvlist_t *nvl; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", cmd); + /* Ignore any errors, we have no way to report them. */ + nvlist_destroy(cap_xfer_nvlist(chan, nvl, 0)); +} + +void +cap_setpwent(cap_channel_t *chan) +{ + + cap_set_end_pwent(chan, "setpwent"); +} + +void +cap_endpwent(cap_channel_t *chan) +{ + + cap_set_end_pwent(chan, "endpwent"); +} + +int +cap_pwd_limit_cmds(cap_channel_t *chan, const char * const *cmds, size_t ncmds) +{ + nvlist_t *limits, *nvl; + unsigned int i; + + if (cap_limit_get(chan, &limits) < 0) + return (-1); + if (limits == NULL) { + limits = nvlist_create(0); + } else { + if (nvlist_exists_nvlist(limits, "cmds")) + nvlist_free_nvlist(limits, "cmds"); + } + nvl = nvlist_create(0); + for (i = 0; i < ncmds; i++) + nvlist_add_null(nvl, cmds[i]); + nvlist_move_nvlist(limits, "cmds", nvl); + return (cap_limit_set(chan, limits)); +} + +int +cap_pwd_limit_fields(cap_channel_t *chan, const char * const *fields, + size_t nfields) +{ + nvlist_t *limits, *nvl; + unsigned int i; + + if (cap_limit_get(chan, &limits) < 0) + return (-1); + if (limits == NULL) { + limits = nvlist_create(0); + } else { + if (nvlist_exists_nvlist(limits, "fields")) + nvlist_free_nvlist(limits, "fields"); + } + nvl = nvlist_create(0); + for (i = 0; i < nfields; i++) + nvlist_add_null(nvl, fields[i]); + nvlist_move_nvlist(limits, "fields", nvl); + return (cap_limit_set(chan, limits)); +} + +int +cap_pwd_limit_users(cap_channel_t *chan, const char * const *names, + size_t nnames, uid_t *uids, size_t nuids) +{ + nvlist_t *limits, *users; + char nvlname[64]; + unsigned int i; + int n; + + if (cap_limit_get(chan, &limits) < 0) + return (-1); + if (limits == NULL) { + limits = nvlist_create(0); + } else { + if (nvlist_exists_nvlist(limits, "users")) + nvlist_free_nvlist(limits, "users"); + } + users = nvlist_create(0); + for (i = 0; i < nuids; i++) { + n = snprintf(nvlname, sizeof(nvlname), "uid%u", i); + assert(n > 0 && n < (int)sizeof(nvlname)); + nvlist_add_number(users, nvlname, (uint64_t)uids[i]); + } + for (i = 0; i < nnames; i++) { + n = snprintf(nvlname, sizeof(nvlname), "name%u", i); + assert(n > 0 && n < (int)sizeof(nvlname)); + nvlist_add_string(users, nvlname, names[i]); + } + nvlist_move_nvlist(limits, "users", users); + return (cap_limit_set(chan, limits)); +} + + +/* + * Service functions. + */ static bool pwd_allowed_cmd(const nvlist_t *limits, const char *cmd) { @@ -111,7 +466,7 @@ pwd_allowed_user(const nvlist_t *limits, const char *uname, uid_t uid) } break; default: - PJDLOG_ABORT("Unexpected type %d.", type); + abort(); } } @@ -264,7 +619,8 @@ pwd_pack(const nvlist_t *limits, const struct passwd *pwd, nvlist_t *nvl) } static int -pwd_getpwent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) +pwd_getpwent(const nvlist_t *limits, const nvlist_t *nvlin __unused, + nvlist_t *nvlout) { struct passwd *pwd; @@ -289,7 +645,7 @@ pwd_getpwnam(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) if (!nvlist_exists_string(nvlin, "name")) return (EINVAL); name = nvlist_get_string(nvlin, "name"); - PJDLOG_ASSERT(name != NULL); + assert(name != NULL); errno = 0; pwd = getpwnam(name); @@ -323,7 +679,8 @@ pwd_getpwuid(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) } static int -pwd_setpassent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) +pwd_setpassent(const nvlist_t *limits __unused, const nvlist_t *nvlin, + nvlist_t *nvlout __unused) { int stayopen; @@ -336,7 +693,8 @@ pwd_setpassent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) } static int -pwd_setpwent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) +pwd_setpwent(const nvlist_t *limits __unused, const nvlist_t *nvlin __unused, + nvlist_t *nvlout __unused) { setpwent(); @@ -345,7 +703,8 @@ pwd_setpwent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) } static int -pwd_endpwent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) +pwd_endpwent(const nvlist_t *limits __unused, const nvlist_t *nvlin __unused, + nvlist_t *nvlout __unused) { endpwent(); @@ -421,10 +780,4 @@ pwd_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, return (error); } -int -main(int argc, char *argv[]) -{ - - return (service_start("system.pwd", PARENT_FILENO, pwd_limit, - pwd_command, argc, argv)); -} +CREATE_SERVICE("system.pwd", pwd_limit, pwd_command); diff --git a/lib/libcapsicum/libcapsicum_pwd.h b/lib/libcasper/services/cap_pwd/cap_pwd.h index 960a490..a75fba7 100644 --- a/lib/libcapsicum/libcapsicum_pwd.h +++ b/lib/libcasper/services/cap_pwd/cap_pwd.h @@ -29,8 +29,8 @@ * $FreeBSD$ */ -#ifndef _LIBCAPSICUM_PWD_H_ -#define _LIBCAPSICUM_PWD_H_ +#ifndef _CAP_PWD_H_ +#define _CAP_PWD_H_ struct passwd *cap_getpwent(cap_channel_t *chan); struct passwd *cap_getpwnam(cap_channel_t *chan, const char *login); @@ -54,4 +54,4 @@ int cap_pwd_limit_fields(cap_channel_t *chan, const char * const *fields, int cap_pwd_limit_users(cap_channel_t *chan, const char * const *names, size_t nnames, uid_t *uids, size_t nuids); -#endif /* !_LIBCAPSICUM_PWD_H_ */ +#endif /* !_CAP_PWD_H_ */ diff --git a/lib/libcasper/services/cap_random/Makefile b/lib/libcasper/services/cap_random/Makefile new file mode 100644 index 0000000..2447236 --- /dev/null +++ b/lib/libcasper/services/cap_random/Makefile @@ -0,0 +1,20 @@ +# $FreeBSD$ + +LIB= cap_random + +SHLIB_MAJOR= 0 +SHLIBDIR?= /lib/casper +INCSDIR?= ${INCLUDEDIR}/casper + +SRCS= cap_random.c + +INCS= cap_random.h + +LIBADD= nv + +CFLAGS+=-I${.CURDIR} +CFLAGS+=-I${.CURDIR}/../libcasper + +WARNS?= 6 + +.include <bsd.lib.mk> diff --git a/lib/libcapsicum/libcapsicum_random.c b/lib/libcasper/services/cap_random/cap_random.c index 2a7b109..d19fe96 100644 --- a/lib/libcapsicum/libcapsicum_random.c +++ b/lib/libcasper/services/cap_random/cap_random.c @@ -34,10 +34,14 @@ __FBSDID("$FreeBSD$"); #include <assert.h> #include <errno.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> -#include "libcapsicum.h" -#include "libcapsicum_random.h" +#include <libcasper.h> +#include <libcasper_service.h> + +#include "cap_random.h" #define MAXSIZE (1024 * 1024) @@ -78,3 +82,36 @@ cap_random_buf(cap_channel_t *chan, void *buf, size_t nbytes) return (0); } + +/* + * Service functions. + */ + +static int +random_command(const char *cmd, const nvlist_t *limits __unused, + nvlist_t *nvlin, nvlist_t *nvlout) +{ + void *data; + size_t size; + + if (strcmp(cmd, "generate") != 0) + return (EINVAL); + if (!nvlist_exists_number(nvlin, "size")) + return (EINVAL); + + size = (size_t)nvlist_get_number(nvlin, "size"); + if (size == 0 || size > MAXSIZE) + return (EINVAL); + + data = malloc(size); + if (data == NULL) + return (ENOMEM); + + arc4random_buf(data, size); + + nvlist_move_binary(nvlout, "data", data, size); + + return (0); +} + +CREATE_SERVICE("system.random", NULL, random_command); diff --git a/lib/libcapsicum/libcapsicum_random.h b/lib/libcasper/services/cap_random/cap_random.h index 672afa0..2039b5f 100644 --- a/lib/libcapsicum/libcapsicum_random.h +++ b/lib/libcasper/services/cap_random/cap_random.h @@ -29,9 +29,9 @@ * $FreeBSD$ */ -#ifndef _LIBCAPSICUM_RANDOM_H_ -#define _LIBCAPSICUM_RANDOM_H_ +#ifndef _CAP_RANDOM_H_ +#define _CAP_RANDOM_H_ int cap_random_buf(cap_channel_t *chan, void *buf, size_t nbytes); -#endif /* !_LIBCAPSICUM_RANDOM_H_ */ +#endif /* !_CAP_RANDOM_H_ */ diff --git a/lib/libcasper/services/cap_sysctl/Makefile b/lib/libcasper/services/cap_sysctl/Makefile new file mode 100644 index 0000000..779ed7e --- /dev/null +++ b/lib/libcasper/services/cap_sysctl/Makefile @@ -0,0 +1,20 @@ +# $FreeBSD$ + +LIB= cap_sysctl + +SHLIB_MAJOR= 0 +SHLIBDIR?= /lib/casper +INCSDIR?= ${INCLUDEDIR}/casper + +SRCS= cap_sysctl.c + +INCS= cap_sysctl.h + +LIBADD= nv + +CFLAGS+=-I${.CURDIR} +CFLAGS+=-I${.CURDIR}/../libcasper + +WARNS?= 6 + +.include <bsd.lib.mk> diff --git a/libexec/casper/sysctl/sysctl.c b/lib/libcasper/services/cap_sysctl/cap_sysctl.c index 4cbc505..7611d64 100644 --- a/libexec/casper/sysctl/sysctl.c +++ b/lib/libcasper/services/cap_sysctl/cap_sysctl.c @@ -34,15 +34,66 @@ __FBSDID("$FreeBSD$"); #include <sys/sysctl.h> #include <sys/nv.h> +#include <assert.h> #include <errno.h> #include <stdlib.h> #include <string.h> -#include <libcapsicum.h> -#include <libcapsicum_sysctl.h> #include <libcasper.h> -#include <pjdlog.h> +#include <libcasper_service.h> +#include "cap_sysctl.h" + +int +cap_sysctlbyname(cap_channel_t *chan, const char *name, void *oldp, + size_t *oldlenp, const void *newp, size_t newlen) +{ + nvlist_t *nvl; + const uint8_t *retoldp; + uint8_t operation; + size_t oldlen; + + operation = 0; + if (oldp != NULL) + operation |= CAP_SYSCTL_READ; + if (newp != NULL) + operation |= CAP_SYSCTL_WRITE; + + nvl = nvlist_create(0); + nvlist_add_string(nvl, "cmd", "sysctl"); + nvlist_add_string(nvl, "name", name); + nvlist_add_number(nvl, "operation", (uint64_t)operation); + if (oldp == NULL && oldlenp != NULL) + nvlist_add_null(nvl, "justsize"); + else if (oldlenp != NULL) + nvlist_add_number(nvl, "oldlen", (uint64_t)*oldlenp); + if (newp != NULL) + nvlist_add_binary(nvl, "newp", newp, newlen); + nvl = cap_xfer_nvlist(chan, nvl, 0); + if (nvl == NULL) + return (-1); + if (nvlist_get_number(nvl, "error") != 0) { + errno = (int)nvlist_get_number(nvl, "error"); + nvlist_destroy(nvl); + return (-1); + } + + if (oldp == NULL && oldlenp != NULL) { + *oldlenp = (size_t)nvlist_get_number(nvl, "oldlen"); + } else if (oldp != NULL) { + retoldp = nvlist_get_binary(nvl, "oldp", &oldlen); + memcpy(oldp, retoldp, oldlen); + if (oldlenp != NULL) + *oldlenp = oldlen; + } + nvlist_destroy(nvl); + + return (0); +} + +/* + * Service functions. + */ static int sysctl_check_one(const nvlist_t *nvl, bool islimit) { @@ -119,7 +170,7 @@ sysctl_allowed(const nvlist_t *limits, const char *chname, uint64_t choperation) cookie = NULL; while ((name = nvlist_next(limits, &type, &cookie)) != NULL) { - PJDLOG_ASSERT(type == NV_TYPE_NUMBER); + assert(type == NV_TYPE_NUMBER); operation = nvlist_get_number(limits, name); if ((operation & choperation) != choperation) @@ -147,11 +198,10 @@ sysctl_allowed(const nvlist_t *limits, const char *chname, uint64_t choperation) static int sysctl_limit(const nvlist_t *oldlimits, const nvlist_t *newlimits) { - const nvlist_t *nvl; const char *name; void *cookie; uint64_t operation; - int error, type; + int type; cookie = NULL; while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { @@ -196,7 +246,7 @@ sysctl_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, if (!nvlist_exists_binary(nvlin, "newp")) return (EINVAL); newp = nvlist_get_binary(nvlin, "newp", &newlen); - PJDLOG_ASSERT(newp != NULL && newlen > 0); + assert(newp != NULL && newlen > 0); } else { newp = NULL; newlen = 0; @@ -240,10 +290,4 @@ sysctl_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, return (0); } -int -main(int argc, char *argv[]) -{ - - return (service_start("system.sysctl", PARENT_FILENO, sysctl_limit, - sysctl_command, argc, argv)); -} +CREATE_SERVICE("system.sysctl", sysctl_limit, sysctl_command); diff --git a/lib/libcapsicum/libcapsicum_sysctl.h b/lib/libcasper/services/cap_sysctl/cap_sysctl.h index d0df143..2af6d21 100644 --- a/lib/libcapsicum/libcapsicum_sysctl.h +++ b/lib/libcasper/services/cap_sysctl/cap_sysctl.h @@ -29,8 +29,8 @@ * $FreeBSD$ */ -#ifndef _LIBCAPSICUM_SYSCTL_H_ -#define _LIBCAPSICUM_SYSCTL_H_ +#ifndef _CAP_SYSCTL_H_ +#define _CAP_SYSCTL_H_ #define CAP_SYSCTL_READ 0x01 #define CAP_SYSCTL_WRITE 0x02 @@ -40,4 +40,4 @@ int cap_sysctlbyname(cap_channel_t *chan, const char *name, void *oldp, size_t *oldlenp, const void *newp, size_t newlen); -#endif /* !_LIBCAPSICUM_SYSCTL_H_ */ +#endif /* !_CAP_SYSCTL_H_ */ diff --git a/libexec/Makefile b/libexec/Makefile index a8ace18..b60cc34 100644 --- a/libexec/Makefile +++ b/libexec/Makefile @@ -5,7 +5,6 @@ SUBDIR= ${_atf} \ ${_atrun} \ - ${_casper} \ ${_comsat} \ ${_dma} \ getty \ @@ -38,10 +37,6 @@ _atrun= atrun SUBDIR+= bootpd .endif -.if ${MK_CASPER} != "no" -_casper= casper -.endif - .if ${MK_FINGER} != "no" SUBDIR+= fingerd .endif diff --git a/libexec/casper/Makefile b/libexec/casper/Makefile deleted file mode 100644 index ed6bd7b..0000000 --- a/libexec/casper/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# $FreeBSD$ - -.include <bsd.own.mk> - -SUBDIR= dns -SUBDIR+=grp -SUBDIR+=pwd -SUBDIR+=random -SUBDIR+=sysctl - -.include <bsd.subdir.mk> diff --git a/libexec/casper/dns/Makefile b/libexec/casper/dns/Makefile deleted file mode 100644 index b101891..0000000 --- a/libexec/casper/dns/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR} ${.CURDIR}/../../../sbin/casper - -PROG= dns - -SRCS= dns.c - -LIBADD= casper nv - -BINDIR= /libexec/casper - -CFLAGS+=-I${.CURDIR} -CFLAGS+=-I${.CURDIR}/../../../lib/libcapsicum -CFLAGS+=-I${.CURDIR}/../../../lib/libcasper -CFLAGS+=-I${.CURDIR}/../../../lib/libpjdlog -CFLAGS+=-I${.CURDIR}/../../../sbin/casper - -MAN= - -.include <bsd.prog.mk> diff --git a/libexec/casper/grp/Makefile b/libexec/casper/grp/Makefile deleted file mode 100644 index 75274d1..0000000 --- a/libexec/casper/grp/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR} ${.CURDIR}/../../../sbin/casper - -PROG= grp - -SRCS= grp.c - -LIBADD= casper nv pjdlog - -BINDIR= /libexec/casper - -CFLAGS+=-I${.CURDIR} -CFLAGS+=-I${.CURDIR}/../../../lib/libcapsicum -CFLAGS+=-I${.CURDIR}/../../../lib/libcasper -CFLAGS+=-I${.CURDIR}/../../../lib/libpjdlog -CFLAGS+=-I${.CURDIR}/../../../sbin/casper - -MAN= - -.include <bsd.prog.mk> diff --git a/libexec/casper/grp/grp.c b/libexec/casper/grp/grp.c deleted file mode 100644 index 5b3e13d..0000000 --- a/libexec/casper/grp/grp.c +++ /dev/null @@ -1,390 +0,0 @@ -/*- - * Copyright (c) 2013 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Pawel Jakub Dawidek under sponsorship from - * the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/nv.h> - -#include <assert.h> -#include <errno.h> -#include <grp.h> -#include <stdlib.h> -#include <string.h> - -#include <libcapsicum.h> -#include <libcasper.h> -#include <pjdlog.h> - -static bool -grp_allowed_cmd(const nvlist_t *limits, const char *cmd) -{ - - if (limits == NULL) - return (true); - - /* - * If no limit was set on allowed commands, then all commands - * are allowed. - */ - if (!nvlist_exists_nvlist(limits, "cmds")) - return (true); - - limits = nvlist_get_nvlist(limits, "cmds"); - return (nvlist_exists_null(limits, cmd)); -} - -static int -grp_allowed_cmds(const nvlist_t *oldlimits, const nvlist_t *newlimits) -{ - const char *name; - void *cookie; - int type; - - cookie = NULL; - while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { - if (type != NV_TYPE_NULL) - return (EINVAL); - if (!grp_allowed_cmd(oldlimits, name)) - return (ENOTCAPABLE); - } - - return (0); -} - -static bool -grp_allowed_group(const nvlist_t *limits, const char *gname, gid_t gid) -{ - const char *name; - void *cookie; - int type; - - if (limits == NULL) - return (true); - - /* - * If no limit was set on allowed groups, then all groups are allowed. - */ - if (!nvlist_exists_nvlist(limits, "groups")) - return (true); - - limits = nvlist_get_nvlist(limits, "groups"); - cookie = NULL; - while ((name = nvlist_next(limits, &type, &cookie)) != NULL) { - switch (type) { - case NV_TYPE_NUMBER: - if (gid != (gid_t)-1 && - nvlist_get_number(limits, name) == (uint64_t)gid) { - return (true); - } - break; - case NV_TYPE_STRING: - if (gname != NULL && - strcmp(nvlist_get_string(limits, name), - gname) == 0) { - return (true); - } - break; - default: - PJDLOG_ABORT("Unexpected type %d.", type); - } - } - - return (false); -} - -static int -grp_allowed_groups(const nvlist_t *oldlimits, const nvlist_t *newlimits) -{ - const char *name, *gname; - void *cookie; - gid_t gid; - int type; - - cookie = NULL; - while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { - switch (type) { - case NV_TYPE_NUMBER: - gid = (gid_t)nvlist_get_number(newlimits, name); - gname = NULL; - break; - case NV_TYPE_STRING: - gid = (gid_t)-1; - gname = nvlist_get_string(newlimits, name); - break; - default: - return (EINVAL); - } - if (!grp_allowed_group(oldlimits, gname, gid)) - return (ENOTCAPABLE); - } - - return (0); -} - -static bool -grp_allowed_field(const nvlist_t *limits, const char *field) -{ - - if (limits == NULL) - return (true); - - /* - * If no limit was set on allowed fields, then all fields are allowed. - */ - if (!nvlist_exists_nvlist(limits, "fields")) - return (true); - - limits = nvlist_get_nvlist(limits, "fields"); - return (nvlist_exists_null(limits, field)); -} - -static int -grp_allowed_fields(const nvlist_t *oldlimits, const nvlist_t *newlimits) -{ - const char *name; - void *cookie; - int type; - - cookie = NULL; - while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { - if (type != NV_TYPE_NULL) - return (EINVAL); - if (!grp_allowed_field(oldlimits, name)) - return (ENOTCAPABLE); - } - - return (0); -} - -static bool -grp_pack(const nvlist_t *limits, const struct group *grp, nvlist_t *nvl) -{ - char nvlname[64]; - int n; - - if (grp == NULL) - return (true); - - /* - * If either name or GID is allowed, we allow it. - */ - if (!grp_allowed_group(limits, grp->gr_name, grp->gr_gid)) - return (false); - - if (grp_allowed_field(limits, "gr_name")) - nvlist_add_string(nvl, "gr_name", grp->gr_name); - else - nvlist_add_string(nvl, "gr_name", ""); - if (grp_allowed_field(limits, "gr_passwd")) - nvlist_add_string(nvl, "gr_passwd", grp->gr_passwd); - else - nvlist_add_string(nvl, "gr_passwd", ""); - if (grp_allowed_field(limits, "gr_gid")) - nvlist_add_number(nvl, "gr_gid", (uint64_t)grp->gr_gid); - else - nvlist_add_number(nvl, "gr_gid", (uint64_t)-1); - if (grp_allowed_field(limits, "gr_mem") && grp->gr_mem[0] != NULL) { - unsigned int ngroups; - - for (ngroups = 0; grp->gr_mem[ngroups] != NULL; ngroups++) { - n = snprintf(nvlname, sizeof(nvlname), "gr_mem[%u]", - ngroups); - assert(n > 0 && n < sizeof(nvlname)); - nvlist_add_string(nvl, nvlname, grp->gr_mem[ngroups]); - } - nvlist_add_number(nvl, "gr_nmem", (uint64_t)ngroups); - } - - return (true); -} - -static int -grp_getgrent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) -{ - struct group *grp; - - for (;;) { - errno = 0; - grp = getgrent(); - if (errno != 0) - return (errno); - if (grp_pack(limits, grp, nvlout)) - return (0); - } - - /* NOTREACHED */ -} - -static int -grp_getgrnam(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) -{ - struct group *grp; - const char *name; - - if (!nvlist_exists_string(nvlin, "name")) - return (EINVAL); - name = nvlist_get_string(nvlin, "name"); - PJDLOG_ASSERT(name != NULL); - - errno = 0; - grp = getgrnam(name); - if (errno != 0) - return (errno); - - (void)grp_pack(limits, grp, nvlout); - - return (0); -} - -static int -grp_getgrgid(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) -{ - struct group *grp; - gid_t gid; - - if (!nvlist_exists_number(nvlin, "gid")) - return (EINVAL); - - gid = (gid_t)nvlist_get_number(nvlin, "gid"); - - errno = 0; - grp = getgrgid(gid); - if (errno != 0) - return (errno); - - (void)grp_pack(limits, grp, nvlout); - - return (0); -} - -static int -grp_setgroupent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) -{ - int stayopen; - - if (!nvlist_exists_bool(nvlin, "stayopen")) - return (EINVAL); - - stayopen = nvlist_get_bool(nvlin, "stayopen") ? 1 : 0; - - return (setgroupent(stayopen) == 0 ? EFAULT : 0); -} - -static int -grp_setgrent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) -{ - - return (setgrent() == 0 ? EFAULT : 0); -} - -static int -grp_endgrent(const nvlist_t *limits, const nvlist_t *nvlin, nvlist_t *nvlout) -{ - - endgrent(); - - return (0); -} - -static int -grp_limit(const nvlist_t *oldlimits, const nvlist_t *newlimits) -{ - const nvlist_t *limits; - const char *name; - void *cookie; - int error, type; - - if (oldlimits != NULL && nvlist_exists_nvlist(oldlimits, "cmds") && - !nvlist_exists_nvlist(newlimits, "cmds")) { - return (ENOTCAPABLE); - } - if (oldlimits != NULL && nvlist_exists_nvlist(oldlimits, "fields") && - !nvlist_exists_nvlist(newlimits, "fields")) { - return (ENOTCAPABLE); - } - if (oldlimits != NULL && nvlist_exists_nvlist(oldlimits, "groups") && - !nvlist_exists_nvlist(newlimits, "groups")) { - return (ENOTCAPABLE); - } - - cookie = NULL; - while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { - if (type != NV_TYPE_NVLIST) - return (EINVAL); - limits = nvlist_get_nvlist(newlimits, name); - if (strcmp(name, "cmds") == 0) - error = grp_allowed_cmds(oldlimits, limits); - else if (strcmp(name, "fields") == 0) - error = grp_allowed_fields(oldlimits, limits); - else if (strcmp(name, "groups") == 0) - error = grp_allowed_groups(oldlimits, limits); - else - error = EINVAL; - if (error != 0) - return (error); - } - - return (0); -} - -static int -grp_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, - nvlist_t *nvlout) -{ - int error; - - if (!grp_allowed_cmd(limits, cmd)) - return (ENOTCAPABLE); - - if (strcmp(cmd, "getgrent") == 0 || strcmp(cmd, "getgrent_r") == 0) - error = grp_getgrent(limits, nvlin, nvlout); - else if (strcmp(cmd, "getgrnam") == 0 || strcmp(cmd, "getgrnam_r") == 0) - error = grp_getgrnam(limits, nvlin, nvlout); - else if (strcmp(cmd, "getgrgid") == 0 || strcmp(cmd, "getgrgid_r") == 0) - error = grp_getgrgid(limits, nvlin, nvlout); - else if (strcmp(cmd, "setgroupent") == 0) - error = grp_setgroupent(limits, nvlin, nvlout); - else if (strcmp(cmd, "setgrent") == 0) - error = grp_setgrent(limits, nvlin, nvlout); - else if (strcmp(cmd, "endgrent") == 0) - error = grp_endgrent(limits, nvlin, nvlout); - else - error = EINVAL; - - return (error); -} - -int -main(int argc, char *argv[]) -{ - - return (service_start("system.grp", PARENT_FILENO, grp_limit, - grp_command, argc, argv)); -} diff --git a/libexec/casper/pwd/Makefile b/libexec/casper/pwd/Makefile deleted file mode 100644 index 23ad3f2..0000000 --- a/libexec/casper/pwd/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR} ${.CURDIR}/../../../sbin/casper - -PROG= pwd - -SRCS= pwd.c - -LIBADD= casper nv pjdlog - -BINDIR= /libexec/casper - -CFLAGS+=-I${.CURDIR} -CFLAGS+=-I${.CURDIR}/../../../lib/libcapsicum -CFLAGS+=-I${.CURDIR}/../../../lib/libcasper -CFLAGS+=-I${.CURDIR}/../../../lib/libpjdlog -CFLAGS+=-I${.CURDIR}/../../../sbin/casper - -MAN= - -.include <bsd.prog.mk> diff --git a/libexec/casper/random/Makefile b/libexec/casper/random/Makefile deleted file mode 100644 index 3b5d155..0000000 --- a/libexec/casper/random/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR} ${.CURDIR}/../../../sbin/casper - -PROG= random - -SRCS= random.c - -LIBADD= casper nv - -BINDIR= /libexec/casper - -CFLAGS+=-I${.CURDIR} -CFLAGS+=-I${.CURDIR}/../../../lib/libcapsicum -CFLAGS+=-I${.CURDIR}/../../../lib/libcasper -CFLAGS+=-I${.CURDIR}/../../../lib/libpjdlog -CFLAGS+=-I${.CURDIR}/../../../sbin/casper - -MAN= - -.include <bsd.prog.mk> diff --git a/libexec/casper/random/random.c b/libexec/casper/random/random.c deleted file mode 100644 index db91685..0000000 --- a/libexec/casper/random/random.c +++ /dev/null @@ -1,82 +0,0 @@ -/*- - * Copyright (c) 2012-2013 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Pawel Jakub Dawidek under sponsorship from - * the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/nv.h> - -#include <errno.h> -#include <stdlib.h> -#include <string.h> - -#include <libcapsicum.h> -#include <libcasper.h> -#include <pjdlog.h> - -#define MAXSIZE (1024 * 1024) - -static int -random_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, - nvlist_t *nvlout) -{ - void *data; - size_t size; - - if (strcmp(cmd, "generate") != 0) - return (EINVAL); - if (!nvlist_exists_number(nvlin, "size")) - return (EINVAL); - - size = (size_t)nvlist_get_number(nvlin, "size"); - if (size == 0 || size > MAXSIZE) - return (EINVAL); - - data = malloc(size); - if (data == NULL) - return (ENOMEM); - - arc4random_buf(data, size); - - nvlist_move_binary(nvlout, "data", data, size); - - return (0); -} - -int -main(int argc, char *argv[]) -{ - - /* - * TODO: Sandbox this. - */ - - return (service_start("system.random", PARENT_FILENO, NULL, - random_command, argc, argv)); -} diff --git a/libexec/casper/sysctl/Makefile b/libexec/casper/sysctl/Makefile deleted file mode 100644 index 24152ab..0000000 --- a/libexec/casper/sysctl/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# $FreeBSD$ - -.PATH: ${.CURDIR} ${.CURDIR}/../../../sbin/casper - -PROG= sysctl - -SRCS= sysctl.c - -LIBADD= casper nv pjdlog - -BINDIR= /libexec/casper - -CFLAGS+=-I${.CURDIR} -CFLAGS+=-I${.CURDIR}/../../../lib/libcapsicum -CFLAGS+=-I${.CURDIR}/../../../lib/libcasper -CFLAGS+=-I${.CURDIR}/../../../lib/libpjdlog -CFLAGS+=-I${.CURDIR}/../../../sbin/casper - -MAN= - -.include <bsd.prog.mk> diff --git a/libexec/rtld-elf/paths.h b/libexec/rtld-elf/paths.h index 7d9d372..69b1d03 100644 --- a/libexec/rtld-elf/paths.h +++ b/libexec/rtld-elf/paths.h @@ -52,7 +52,7 @@ #endif #ifndef STANDARD_LIBRARY_PATH -#define STANDARD_LIBRARY_PATH "/lib:/usr/lib" +#define STANDARD_LIBRARY_PATH "/lib/casper:/lib:/usr/lib" #endif #ifndef LD_ diff --git a/sbin/Makefile b/sbin/Makefile index 3b17e10..affca8e 100644 --- a/sbin/Makefile +++ b/sbin/Makefile @@ -71,7 +71,6 @@ SUBDIR=adjkerntz \ umount SUBDIR.${MK_ATM}+= atm -SUBDIR.${MK_CASPER}+= casperd SUBDIR.${MK_CCD}+= ccdconfig SUBDIR.${MK_CXX}+= devd SUBDIR.${MK_HAST}+= hastctl diff --git a/sbin/casperd/Makefile b/sbin/casperd/Makefile deleted file mode 100644 index 93f145c..0000000 --- a/sbin/casperd/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ - -PROG= casperd - -SRCS= casperd.c zygote.c - -LIBADD= casper nv pjdlog util - -MAN= casperd.8 - -CFLAGS+=-I${.CURDIR} -CFLAGS+=-I${.CURDIR}/../../lib/libcapsicum -CFLAGS+=-I${.CURDIR}/../../lib/libcasper -CFLAGS+=-I${.CURDIR}/../../lib/libnv -CFLAGS+=-I${.CURDIR}/../../lib/libpjdlog - -.include <bsd.prog.mk> diff --git a/sbin/casperd/casperd.8 b/sbin/casperd/casperd.8 deleted file mode 100644 index 945b517..0000000 --- a/sbin/casperd/casperd.8 +++ /dev/null @@ -1,132 +0,0 @@ -.\" Copyright (c) 2013 The FreeBSD Foundation -.\" All rights reserved. -.\" -.\" This documentation was written by Pawel Jakub Dawidek under sponsorship -.\" from the FreeBSD Foundation. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd October 26, 2013 -.Dt CASPERD 8 -.Os -.Sh NAME -.Nm casperd -.Nd "Capability Services friendly daemon" -.Sh SYNOPSIS -.Nm -.Op Fl Fhv -.Op Fl l Ar listenqueue -.Op Fl D Ar servconfdir -.Op Fl P Ar pidfile -.Op Fl S Ar sockpath -.Sh DESCRIPTION -The -.Nm -daemon hosts various services that can be accessed through -libcapsicum's capabilities by programs running in sandboxes. -For example it is prohibited to send UDP packets to arbitrary destinations -when operating in capability mode, which makes DNS resolution impossible. -To make it possible the -.Nm -daemon provides the -.Nm system.dns -service that proxies DNS resolution requests through a dedicated, -non-sandboxed process provided by -.Nm . -.Pp -The -.Nm -daemon can be started with the following command line arguments: -.Bl -tag -width ".Fl D Ar servconfdir" -.It Fl D Ar servconfdir -Specify alternative location of the service configuration directory. -The default location is -.Pa /etc/casper/ . -.It Fl F -Start the -.Nm -daemon in the foreground. -By default -.Nm -starts in the background. -.It Fl h -Print the -.Nm -usage message. -.It Fl l Ar listenqueue -Specify depth of socket listen queue for the -.Nm -daemon. -The default queue length is -.Pa SOMAXCONN . -.It Fl P Ar pidfile -Specify alternative location of a file where main process PID will be -stored. -The default location is -.Pa /var/run/casperd.pid . -.It Fl S Ar sockpath -Specify alternative location of the -.Xr unix 4 -domain socket used to connect to the -.Nm -daemon. -The default location is -.Pa /var/run/casper . -.It Fl v -Print or log verbose/debugging information. -This option can be specified multiple times to raise the verbosity -level. -.El -.Sh FILES -.Bl -tag -width ".Pa /var/run/casperd.pid" -compact -.It Pa /etc/casper/ -The configuration directory for -.Nm -services. -.It Pa /var/run/casper -.Xr unix 4 -domain socket used to connect to the -.Nm -daemon. -.It Pa /var/run/casperd.pid -The default location of the -.Nm -PID file. -.El -.Sh EXIT STATUS -The -.Nm -daemon exits 0 on success, and >0 if an error occurs. -.Sh SEE ALSO -.Xr cap_enter 2 , -.Xr libcapsicum 3 , -.Xr pidfile 3 , -.Xr capsicum 4 , -.Xr unix 4 -.Sh AUTHORS -The -.Nm -was implemented by -.An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net -under sponsorship from the FreeBSD Foundation. diff --git a/sbin/casperd/casperd.c b/sbin/casperd/casperd.c deleted file mode 100644 index 65da58a..0000000 --- a/sbin/casperd/casperd.c +++ /dev/null @@ -1,721 +0,0 @@ -/*- - * Copyright (c) 2012 The FreeBSD Foundation - * All rights reserved. - * - * This software was developed by Pawel Jakub Dawidek under sponsorship from - * the FreeBSD Foundation. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/types.h> -#include <sys/capsicum.h> -#include <sys/queue.h> -#include <sys/socket.h> -#include <sys/stat.h> -#include <sys/un.h> -#include <sys/nv.h> - -#include <assert.h> -#include <dirent.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <libutil.h> -#include <paths.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <strings.h> -#include <unistd.h> - -#include <libcapsicum.h> -#include <libcapsicum_impl.h> -#include <libcasper.h> -#include <libcasper_impl.h> -#include <msgio.h> -#include <pjdlog.h> - -#include "msgio.h" - -#include "zygote.h" - -#define CASPERD_PIDFILE "/var/run/casperd.pid" -#define CASPERD_SERVCONFDIR "/etc/casper" -#define CASPERD_SOCKPATH "/var/run/casper" - -typedef void service_function_t(struct service_connection *, const nvlist_t *, - nvlist_t *); - -struct casper_service { - const char *cs_name; - const char *cs_execpath; - struct service *cs_service; - nvlist_t *cs_attrs; - TAILQ_ENTRY(casper_service) cs_next; -}; - -static TAILQ_HEAD(, casper_service) casper_services = - TAILQ_HEAD_INITIALIZER(casper_services); - -#define SERVICE_IS_CORE(service) ((service)->cs_execpath == NULL) - -static void service_external_execute(int chanfd); - -#define KEEP_ERRNO(work) do { \ - int _serrno; \ - \ - _serrno = errno; \ - work; \ - errno = _serrno; \ -} while (0) - -static struct casper_service * -service_find(const char *name) -{ - struct casper_service *casserv; - - TAILQ_FOREACH(casserv, &casper_services, cs_next) { - if (strcmp(casserv->cs_name, name) == 0) - break; - } - return (casserv); -} - -/* - * Function always consumes the given attrs. - */ -static void -service_register(nvlist_t *attrs) -{ - struct casper_service *casserv; - const char *name; - - PJDLOG_ASSERT(nvlist_exists_string(attrs, "name")); - PJDLOG_ASSERT(nvlist_exists_string(attrs, "execpath") || - (nvlist_exists_number(attrs, "commandfunc") && - nvlist_exists_number(attrs, "limitfunc"))); - - name = nvlist_get_string(attrs, "name"); - PJDLOG_ASSERT(name != NULL); - if (name[0] == '\0') { - pjdlog_error("Unable to register service with an empty name."); - nvlist_destroy(attrs); - return; - } - if (service_find(name) != NULL) { - pjdlog_error("Service \"%s\" is already registered.", name); - nvlist_destroy(attrs); - return; - } - - casserv = malloc(sizeof(*casserv)); - if (casserv == NULL) { - pjdlog_errno(LOG_ERR, "Unable to register service \"%s\"", - name); - nvlist_destroy(attrs); - return; - } - casserv->cs_name = name; - if (nvlist_exists_string(attrs, "execpath")) { - struct stat sb; - - PJDLOG_ASSERT(!nvlist_exists_number(attrs, "commandfunc")); - PJDLOG_ASSERT(!nvlist_exists_number(attrs, "limitfunc")); - - casserv->cs_service = NULL; - - casserv->cs_execpath = nvlist_get_string(attrs, "execpath"); - if (casserv->cs_execpath == NULL || - casserv->cs_execpath[0] == '\0') { - pjdlog_error("Unable to register service with an empty execpath."); - free(casserv); - nvlist_destroy(attrs); - return; - } - if (stat(casserv->cs_execpath, &sb) == -1) { - pjdlog_errno(LOG_ERR, - "Unable to register service \"%s\", problem with executable \"%s\"", - name, casserv->cs_execpath); - free(casserv); - nvlist_destroy(attrs); - return; - } - } else /* if (nvlist_exists_number(attrs, "commandfunc")) */ { - PJDLOG_ASSERT(!nvlist_exists_string(attrs, "execpath")); - - casserv->cs_execpath = NULL; - - casserv->cs_service = service_alloc(name, - (void *)(uintptr_t)nvlist_get_number(attrs, "limitfunc"), - (void *)(uintptr_t)nvlist_get_number(attrs, "commandfunc")); - if (casserv->cs_service == NULL) { - pjdlog_errno(LOG_ERR, - "Unable to register service \"%s\"", name); - free(casserv); - nvlist_destroy(attrs); - return; - } - } - casserv->cs_attrs = attrs; - TAILQ_INSERT_TAIL(&casper_services, casserv, cs_next); - pjdlog_debug(1, "Service %s successfully registered.", - casserv->cs_name); -} - -static bool -casper_allowed_service(const nvlist_t *limits, const char *service) -{ - - if (limits == NULL) - return (true); - - if (nvlist_exists_null(limits, service)) - return (true); - - return (false); -} - -static int -casper_limit(const nvlist_t *oldlimits, const nvlist_t *newlimits) -{ - const char *name; - int type; - void *cookie; - - cookie = NULL; - while ((name = nvlist_next(newlimits, &type, &cookie)) != NULL) { - if (type != NV_TYPE_NULL) - return (EINVAL); - if (!casper_allowed_service(oldlimits, name)) - return (ENOTCAPABLE); - } - - return (0); -} - -static int -casper_command(const char *cmd, const nvlist_t *limits, nvlist_t *nvlin, - nvlist_t *nvlout) -{ - struct casper_service *casserv; - const char *servname; - nvlist_t *nvl; - int chanfd, execfd, procfd, error; - - if (strcmp(cmd, "open") != 0) - return (EINVAL); - if (!nvlist_exists_string(nvlin, "service")) - return (EINVAL); - - servname = nvlist_get_string(nvlin, "service"); - - casserv = service_find(servname); - if (casserv == NULL) - return (ENOENT); - - if (!casper_allowed_service(limits, servname)) - return (ENOTCAPABLE); - -#ifdef O_EXEC_WORKING - execfd = open(casserv->cs_execpath, O_EXEC); -#else - execfd = open(casserv->cs_execpath, O_RDONLY); -#endif - if (execfd < -1) { - error = errno; - pjdlog_errno(LOG_ERR, - "Unable to open executable '%s' of service '%s'", - casserv->cs_execpath, casserv->cs_name); - return (error); - } - - if (zygote_clone(service_external_execute, &chanfd, &procfd) == -1) { - error = errno; - close(execfd); - return (error); - } - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "service", casserv->cs_name); - if (nvlist_exists_descriptor(nvlin, "stderrfd")) { - nvlist_move_descriptor(nvl, "stderrfd", - nvlist_take_descriptor(nvlin, "stderrfd")); - } - nvlist_move_descriptor(nvl, "execfd", execfd); - nvlist_move_descriptor(nvl, "procfd", procfd); - if (nvlist_send(chanfd, nvl) == -1) { - error = errno; - pjdlog_errno(LOG_ERR, "Unable to send nvlist"); - nvlist_destroy(nvl); - close(chanfd); - return (error); - } - nvlist_destroy(nvl); - - nvlist_move_descriptor(nvlout, "chanfd", chanfd); - - return (0); -} - -static void -fdswap(int *fd0, int *fd1) -{ - int tmpfd; - - PJDLOG_VERIFY((tmpfd = dup(*fd0)) != -1); - PJDLOG_VERIFY(dup2(*fd1, *fd0) != -1); - PJDLOG_VERIFY(dup2(tmpfd, *fd1) != -1); - close(tmpfd); - tmpfd = *fd0; - *fd0 = *fd1; - *fd1 = tmpfd; -} - -static void -fdmove(int *oldfdp, int newfd) -{ - - if (*oldfdp != newfd) { - PJDLOG_VERIFY(dup2(*oldfdp, newfd) != -1); - close(*oldfdp); - *oldfdp = newfd; - } -} - -static void -fdcloexec(int fd) -{ - int flags; - - flags = fcntl(fd, F_GETFD); - PJDLOG_ASSERT(flags != -1); - if ((flags & FD_CLOEXEC) != 0) - PJDLOG_VERIFY(fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) != -1); -} - -static void -service_register_core(void) -{ - nvlist_t *nvl; - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "name", "core.casper"); - nvlist_add_number(nvl, "limitfunc", (uint64_t)(uintptr_t)casper_limit); - nvlist_add_number(nvl, "commandfunc", - (uint64_t)(uintptr_t)casper_command); - service_register(nvl); -} - -static int -setup_creds(int sock) -{ - struct cmsgcred cred; - - if (cred_recv(sock, &cred) == -1) - return (-1); - - if (setgroups((int)cred.cmcred_ngroups, cred.cmcred_groups) == -1) - return (-1); - - if (setgid(cred.cmcred_groups[0]) == -1) - return (-1); - - if (setuid(cred.cmcred_euid) == -1) - return (-1); - - return (0); -} - -static void -service_external_execute(int chanfd) -{ - char *service, *argv[3]; - int stderrfd, execfd, procfd; - nvlist_t *nvl; - - nvl = nvlist_recv(chanfd, 0); - if (nvl == NULL) - pjdlog_exit(1, "Unable to receive nvlist"); - service = nvlist_take_string(nvl, "service"); - PJDLOG_ASSERT(service != NULL); - if (nvlist_exists_descriptor(nvl, "stderrfd")) { - stderrfd = nvlist_take_descriptor(nvl, "stderrfd"); - } else { - stderrfd = open(_PATH_DEVNULL, O_RDWR); - if (stderrfd < 0) - pjdlog_exit(1, "Unable to open %s", _PATH_DEVNULL); - } - execfd = nvlist_take_descriptor(nvl, "execfd"); - procfd = nvlist_take_descriptor(nvl, "procfd"); - nvlist_destroy(nvl); - - /* - * Move all descriptors into right slots. - */ - - if (stderrfd != STDERR_FILENO) { - if (chanfd == STDERR_FILENO) - fdswap(&stderrfd, &chanfd); - else if (execfd == STDERR_FILENO) - fdswap(&stderrfd, &execfd); - else if (procfd == STDERR_FILENO) - fdswap(&stderrfd, &procfd); - fdmove(&stderrfd, STDERR_FILENO); - } - fdcloexec(stderrfd); - - if (chanfd != PARENT_FILENO) { - if (execfd == PARENT_FILENO) - fdswap(&chanfd, &execfd); - else if (procfd == PARENT_FILENO) - fdswap(&chanfd, &procfd); - fdmove(&chanfd, PARENT_FILENO); - } - fdcloexec(chanfd); - - if (execfd != EXECUTABLE_FILENO) { - if (procfd == EXECUTABLE_FILENO) - fdswap(&execfd, &procfd); - fdmove(&execfd, EXECUTABLE_FILENO); - } - fdcloexec(execfd); - - if (procfd != PROC_FILENO) - fdmove(&procfd, PROC_FILENO); - fdcloexec(procfd); - - /* - * Use credentials of the caller process. - */ - setup_creds(chanfd); - - argv[0] = service; - asprintf(&argv[1], "%d", pjdlog_debug_get()); - argv[2] = NULL; - - fexecve(execfd, argv, NULL); - pjdlog_exit(1, "Unable to execute service %s", service); -} - -static void -service_register_external_one(const char *dirpath, int dfd, - const char *filename) -{ - char execpath[FILENAME_MAX]; - nvlist_t *nvl; - ssize_t done; - int fd; - - fd = openat(dfd, filename, O_RDONLY); - if (fd == -1) { - pjdlog_errno(LOG_ERR, "Unable to open \"%s/%s\"", dirpath, - filename); - return; - } - - done = read(fd, execpath, sizeof(execpath)); - if (done == -1) { - pjdlog_errno(LOG_ERR, "Unable to read content of \"%s/%s\"", - dirpath, filename); - close(fd); - return; - } - close(fd); - if (done == sizeof(execpath)) { - pjdlog_error("Executable path too long in \"%s/%s\".", dirpath, - filename); - return; - } - execpath[done] = '\0'; - while (done > 0) { - if (execpath[--done] == '\n') - execpath[done] = '\0'; - } - - nvl = nvlist_create(0); - nvlist_add_string(nvl, "name", filename); - nvlist_add_string(nvl, "execpath", execpath); - if (nvlist_error(nvl) != 0) { - pjdlog_common(LOG_ERR, 0, nvlist_error(nvl), - "Unable to allocate attributes for service \"%s/%s\"", - dirpath, filename); - nvlist_destroy(nvl); - return; - } - - service_register(nvl); - /* service_register() consumed nvl. */ -} - -static uint8_t -file_type(int dfd, const char *filename) -{ - struct stat sb; - - if (fstatat(dfd, filename, &sb, AT_SYMLINK_NOFOLLOW) == -1) { - pjdlog_errno(LOG_ERR, "Unable to stat \"%s\"", filename); - return (DT_UNKNOWN); - } - return (IFTODT(sb.st_mode)); -} - -static void -service_register_external(const char *dirpath) -{ - DIR *dirp; - struct dirent *dp; - int dfd; - - dirp = opendir(dirpath); - if (dirp == NULL) { - pjdlog_errno(LOG_WARNING, "Unable to open \"%s\"", dirpath); - return; - } - dfd = dirfd(dirp); - PJDLOG_ASSERT(dfd >= 0); - while ((dp = readdir(dirp)) != NULL) { - dp->d_type = file_type(dfd, dp->d_name); - /* We are only interested in regular files, skip the rest. */ - if (dp->d_type != DT_REG) { - pjdlog_debug(1, - "File \"%s/%s\" is not a regular file, skipping.", - dirpath, dp->d_name); - continue; - } - service_register_external_one(dirpath, dfd, dp->d_name); - } - closedir(dirp); -} - -static void -casper_accept(int lsock) -{ - struct casper_service *casserv; - struct service_connection *sconn; - int sock; - - sock = accept(lsock, NULL, NULL); - if (sock == -1) { - pjdlog_errno(LOG_ERR, "Unable to accept casper connection"); - return; - } - casserv = service_find("core.casper"); - PJDLOG_ASSERT(casserv != NULL); - - sconn = service_connection_add(casserv->cs_service, sock, NULL); - if (sconn == NULL) { - close(sock); - return; - } -} - -static void -main_loop(int lqlen, const char *sockpath, struct pidfh *pfh) -{ - fd_set fds; - struct sockaddr_un sun; - struct casper_service *casserv; - struct service_connection *sconn, *sconntmp; - int lsock, sock, maxfd, ret; - mode_t oldumask; - - lsock = socket(AF_UNIX, SOCK_STREAM, 0); - if (lsock == -1) - pjdlog_exit(1, "Unable to create socket"); - - (void)unlink(sockpath); - - bzero(&sun, sizeof(sun)); - sun.sun_family = AF_UNIX; - PJDLOG_VERIFY(strlcpy(sun.sun_path, sockpath, sizeof(sun.sun_path)) < - sizeof(sun.sun_path)); - sun.sun_len = SUN_LEN(&sun); - - oldumask = umask(S_IXUSR | S_IXGRP | S_IXOTH); - if (bind(lsock, (struct sockaddr *)&sun, sizeof(sun)) == -1) - pjdlog_exit(1, "Unable to bind to %s", sockpath); - (void)umask(oldumask); - if (listen(lsock, lqlen) == -1) - pjdlog_exit(1, "Unable to listen on %s", sockpath); - - for (;;) { - FD_ZERO(&fds); - FD_SET(lsock, &fds); - maxfd = lsock; - TAILQ_FOREACH(casserv, &casper_services, cs_next) { - /* We handle only core services. */ - if (!SERVICE_IS_CORE(casserv)) - continue; - for (sconn = service_connection_first(casserv->cs_service); - sconn != NULL; - sconn = service_connection_next(sconn)) { - sock = service_connection_get_sock(sconn); - FD_SET(sock, &fds); - maxfd = sock > maxfd ? sock : maxfd; - } - } - maxfd++; - - PJDLOG_ASSERT(maxfd <= (int)FD_SETSIZE); - ret = select(maxfd, &fds, NULL, NULL, NULL); - PJDLOG_ASSERT(ret == -1 || ret > 0); /* select() cannot timeout */ - if (ret == -1) { - if (errno == EINTR) - continue; - KEEP_ERRNO((void)pidfile_remove(pfh)); - pjdlog_exit(1, "select() failed"); - } - - if (FD_ISSET(lsock, &fds)) - casper_accept(lsock); - TAILQ_FOREACH(casserv, &casper_services, cs_next) { - /* We handle only core services. */ - if (!SERVICE_IS_CORE(casserv)) - continue; - for (sconn = service_connection_first(casserv->cs_service); - sconn != NULL; sconn = sconntmp) { - /* - * Prepare for connection to be removed from - * the list on failure. - */ - sconntmp = service_connection_next(sconn); - sock = service_connection_get_sock(sconn); - if (FD_ISSET(sock, &fds)) { - service_message(casserv->cs_service, - sconn); - } - } - } - } -} - -static void -usage(void) -{ - - pjdlog_exitx(1, - "usage: casperd [-Fhv] [-D servconfdir] [-P pidfile] [-S sockpath]"); -} - -int -main(int argc, char *argv[]) -{ - struct pidfh *pfh; - const char *pidfile, *servconfdir, *sockpath; - pid_t otherpid; - int ch, debug, lqlen; - bool foreground; - - pjdlog_init(PJDLOG_MODE_STD); - - debug = 0; - foreground = false; - lqlen = SOMAXCONN; - pidfile = CASPERD_PIDFILE; - servconfdir = CASPERD_SERVCONFDIR; - sockpath = CASPERD_SOCKPATH; - - while ((ch = getopt(argc, argv, "D:Fhl:P:S:v")) != -1) { - switch (ch) { - case 'D': - servconfdir = optarg; - break; - case 'F': - foreground = true; - break; - case 'l': - lqlen = strtol(optarg, NULL, 0); - if (lqlen < 1) - lqlen = SOMAXCONN; - break; - case 'P': - pidfile = optarg; - break; - case 'S': - sockpath = optarg; - break; - case 'v': - debug++; - break; - case 'h': - default: - usage(); - } - } - argc -= optind; - argv += optind; - - if (argc != 0) - usage(); - - if (!foreground) - pjdlog_mode_set(PJDLOG_MODE_SYSLOG); - pjdlog_prefix_set("(casperd) "); - pjdlog_debug_set(debug); - - if (zygote_init() < 0) - pjdlog_exit(1, "Unable to create zygote process"); - - pfh = pidfile_open(pidfile, 0600, &otherpid); - if (pfh == NULL) { - if (errno == EEXIST) { - pjdlog_exitx(1, "casperd already running, pid: %jd.", - (intmax_t)otherpid); - } - pjdlog_errno(LOG_WARNING, "Cannot open or create pidfile %s", - pidfile); - } - - if (!foreground) { - if (daemon(0, 0) == -1) { - KEEP_ERRNO((void)pidfile_remove(pfh)); - pjdlog_exit(1, "Unable to go into background"); - } - } - - /* Write PID to a file. */ - if (pidfile_write(pfh) == -1) { - pjdlog_errno(LOG_WARNING, "Unable to write to pidfile %s", - pidfile); - } else { - pjdlog_debug(1, "PID stored in %s.", pidfile); - } - - /* - * Register core services. - */ - service_register_core(); - /* - * Register external services. - */ - service_register_external(servconfdir); - - /* - * Wait for connections. - */ - main_loop(lqlen, sockpath, pfh); -} diff --git a/sbin/ping/Makefile b/sbin/ping/Makefile index 533f8b8..31e6153 100644 --- a/sbin/ping/Makefile +++ b/sbin/ping/Makefile @@ -11,8 +11,9 @@ WARNS?= 3 LIBADD= m .if ${MK_CASPER} != "no" && !defined(RESCUE) -LIBADD+= capsicum -CFLAGS+=-DHAVE_LIBCAPSICUM +LIBADD+= casper +LIBADD+= cap_dns +CFLAGS+=-DHAVE_LIBCASPER .endif .if !defined(RELEASE_CRUNCH) diff --git a/sbin/ping/Makefile.depend b/sbin/ping/Makefile.depend index 35832c2..5222563 100644 --- a/sbin/ping/Makefile.depend +++ b/sbin/ping/Makefile.depend @@ -9,7 +9,8 @@ DIRDEPS = \ include/xlocale \ lib/${CSU_DIR} \ lib/libc \ - lib/libcapsicum \ + lib/libcasper/libcasper \ + lib/libcasper/services \ lib/libcompiler_rt \ lib/libipsec \ lib/libnv \ diff --git a/sbin/ping/ping.c b/sbin/ping/ping.c index 23d5696..1831cb7 100644 --- a/sbin/ping/ping.c +++ b/sbin/ping/ping.c @@ -75,10 +75,10 @@ __FBSDID("$FreeBSD$"); #include <netinet/ip_icmp.h> #include <netinet/ip_var.h> #include <arpa/inet.h> -#ifdef HAVE_LIBCAPSICUM -#include <libcapsicum.h> -#include <libcapsicum_dns.h> -#include <libcapsicum_service.h> + +#ifdef HAVE_LIBCASPER +#include <libcasper.h> +#include <casper/cap_dns.h> #endif #ifdef IPSEC @@ -204,13 +204,13 @@ static double tsumsq = 0.0; /* sum of all times squared, for std. dev. */ static volatile sig_atomic_t finish_up; static volatile sig_atomic_t siginfo_p; -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER static cap_channel_t *capdns; #endif static void fill(char *, char *); static u_short in_cksum(u_short *, int); -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER static cap_channel_t *capdns_setup(void); #endif static void check_status(void); @@ -553,7 +553,7 @@ main(int argc, char *const *argv) if (options & F_PINGFILLED) { fill((char *)datap, payload); } -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER capdns = capdns_setup(); #endif if (source) { @@ -562,7 +562,7 @@ main(int argc, char *const *argv) if (inet_aton(source, &sock_in.sin_addr) != 0) { shostname = source; } else { -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER if (capdns != NULL) hp = cap_gethostbyname2(capdns, source, AF_INET); @@ -596,7 +596,7 @@ main(int argc, char *const *argv) if (inet_aton(target, &to->sin_addr) != 0) { hostname = target; } else { -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER if (capdns != NULL) hp = cap_gethostbyname2(capdns, target, AF_INET); else @@ -614,7 +614,7 @@ main(int argc, char *const *argv) hostname = hnamebuf; } -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER /* From now on we will use only reverse DNS lookups. */ if (capdns != NULL) { const char *types[1]; @@ -722,7 +722,7 @@ main(int argc, char *const *argv) if (options & F_NUMERIC) cansandbox = true; -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER else if (capdns != NULL) cansandbox = true; #endif @@ -1704,7 +1704,7 @@ pr_addr(struct in_addr ina) if (options & F_NUMERIC) return inet_ntoa(ina); -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER if (capdns != NULL) hp = cap_gethostbyaddr(capdns, (char *)&ina, 4, AF_INET); else @@ -1788,7 +1788,7 @@ fill(char *bp, char *patp) } } -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER static cap_channel_t * capdns_setup(void) { @@ -1797,10 +1797,8 @@ capdns_setup(void) int families[1]; capcas = cap_init(); - if (capcas == NULL) { - warn("unable to contact casperd"); - return (NULL); - } + if (capcas == NULL) + err(1, "unable to create casper process"); capdnsloc = cap_service_open(capcas, "system.dns"); /* Casper capability no longer needed. */ cap_close(capcas); @@ -1816,7 +1814,7 @@ capdns_setup(void) return (capdnsloc); } -#endif /* HAVE_LIBCAPSICUM */ +#endif /* HAVE_LIBCASPER */ #if defined(IPSEC) && defined(IPSEC_POLICY_IPSEC) #define SECOPT " [-P policy]" diff --git a/share/man/man4/capsicum.4 b/share/man/man4/capsicum.4 index 1d208b0..afdf586 100644 --- a/share/man/man4/capsicum.4 +++ b/share/man/man4/capsicum.4 @@ -26,7 +26,7 @@ .\" .\" $FreeBSD$ .\" -.Dd July 25, 2015 +.Dd February 25, 2016 .Dt CAPSICUM 4 .Os .Sh NAME @@ -104,9 +104,8 @@ associated with file descriptors; described in greater detail in .Xr shm_open 2 , .Xr write 2 , .Xr cap_rights_get 3 , -.Xr libcapsicum 3 , +.Xr casper 3 , .Xr procdesc 4 , -.Xr casperd 8 .Sh HISTORY .Nm first appeared in diff --git a/share/mk/bsd.libnames.mk b/share/mk/bsd.libnames.mk index d22f99a..6db6973 100644 --- a/share/mk/bsd.libnames.mk +++ b/share/mk/bsd.libnames.mk @@ -30,7 +30,6 @@ LIBBZ2?= ${DESTDIR}${LIBDIR}/libbz2.a LIBC?= ${DESTDIR}${LIBDIR}/libc.a LIBCALENDAR?= ${DESTDIR}${LIBDIR}/libcalendar.a LIBCAM?= ${DESTDIR}${LIBDIR}/libcam.a -LIBCAPSICUM?= ${DESTDIR}${LIBDIR}/libcapsicum.a LIBCASPER?= ${DESTDIR}${LIBDIR}/libcasper.a LIBCOMPAT?= ${DESTDIR}${LIBDIR}/libcompat.a LIBCOMPILER_RT?=${DESTDIR}${LIBDIR}/libcompiler_rt.a diff --git a/share/mk/src.libnames.mk b/share/mk/src.libnames.mk index d27597f..902f4fb 100644 --- a/share/mk/src.libnames.mk +++ b/share/mk/src.libnames.mk @@ -68,8 +68,12 @@ _LIBRARIES= \ c_pic \ calendar \ cam \ - capsicum \ casper \ + cap_dns \ + cap_grp \ + cap_pwd \ + cap_random \ + cap_sysctl \ com_err \ compiler_rt \ crypt \ @@ -211,9 +215,13 @@ _DP_bsnmp= crypto .endif _DP_geom= bsdxml sbuf _DP_cam= sbuf -_DP_casper= capsicum nv pjdlog -_DP_capsicum= nv _DP_kvm= elf +_DP_casper= nv +_DP_cap_dns= nv +_DP_cap_grp= nv +_DP_cap_pwd= nv +_DP_cap_random= nv +_DP_cap_sysctl= nv _DP_pjdlog= util _DP_opie= md _DP_usb= pthread @@ -507,6 +515,25 @@ LIBTERMCAPWDIR= ${LIBNCURSESWDIR} LIB${lib:tu}DIR?= ${OBJTOP}/lib/lib${lib} .endfor +# Casper exception. +LIBCAP_CASPERDIR= ${OBJTOP}/lib/libcasper/libcasper +LIBCAP_CASPER= ${DESTDIR}${LIBDIR}/libcasper.a + +LIBCAP_DNSDIR= ${OBJTOP}/lib/libcasper/services/cap_dns +LIBCAP_DNS?= ${DESTDIR}${LIBDIR}/libcap_dns.a + +LIBCAP_GRPDIR= ${OBJTOP}/lib/libcasper/services/cap_grp +LIBCAP_GRP?= ${DESTDIR}${LIBDIR}/libcap_grp.a + +LIBCAP_PWDDIR= ${OBJTOP}/lib/libcasper/services/cap_pwd +LIBCAP_PWD?= ${DESTDIR}${LIBDIR}/libcap_pwd.a + +LIBCAP_RANDOMDIR= ${OBJTOP}/lib/libcasper/services/cap_random +LIBCAP_RANDOM?= ${DESTDIR}${LIBDIR}/libcap_random.a + +LIBCAP_SYSCTLDIR= ${OBJTOP}/lib/libcasper/services/cap_sysctl +LIBCAP_SYSCTL?= ${DESTDIR}${LIBDIR}/libcap_sysctl.a + # Validate that listed LIBADD are valid. .for _l in ${LIBADD} .if empty(_LIBRARIES:M${_l}) diff --git a/targets/pseudo/userland/Makefile.depend b/targets/pseudo/userland/Makefile.depend index cebce7c..dcb8706 100644 --- a/targets/pseudo/userland/Makefile.depend +++ b/targets/pseudo/userland/Makefile.depend @@ -894,10 +894,6 @@ DIRDEPS.powerpc= \ DIRDEPS+= usr.bin/dtc .endif -.if ${MK_CASPER} == "yes" -DIRDEPS+= sbin/casperd -.endif - DIRDEPS+= ${DIRDEPS.${MACHINE}:U} diff --git a/targets/pseudo/userland/lib/Makefile.depend b/targets/pseudo/userland/lib/Makefile.depend index 1b2c35b..bfd444f 100644 --- a/targets/pseudo/userland/lib/Makefile.depend +++ b/targets/pseudo/userland/lib/Makefile.depend @@ -33,7 +33,6 @@ DIRDEPS = \ lib/libc++ \ lib/libcalendar \ lib/libcam \ - lib/libcasper \ lib/libcom_err/doc \ lib/libcompat \ lib/libcompiler_rt \ @@ -187,4 +186,15 @@ DIRDEPS+= \ DIRDEPS+= lib/libnandfs .endif +.if ${MK_CASPER} != "no" +DIRDEPS+= \ + lib/libcasper \ + lib/libcasper/services/cap_dns \ + lib/libcasper/services/cap_grp \ + lib/libcasper/services/cap_pwd \ + lib/libcasper/services/cap_random \ + lib/libcasper/services/cap_sysctl \ + +.endif + .include <dirdeps.mk> diff --git a/targets/pseudo/userland/libexec/Makefile.depend b/targets/pseudo/userland/libexec/Makefile.depend index 427268c..6bdd31e 100644 --- a/targets/pseudo/userland/libexec/Makefile.depend +++ b/targets/pseudo/userland/libexec/Makefile.depend @@ -10,11 +10,6 @@ DIRDEPS = \ libexec/bootpd/bootpgw \ libexec/bootpd/tools/bootpef \ libexec/bootpd/tools/bootptest \ - libexec/casper/dns \ - libexec/casper/grp \ - libexec/casper/pwd \ - libexec/casper/random \ - libexec/casper/sysctl \ libexec/comsat \ libexec/fingerd \ libexec/ftpd \ diff --git a/tools/regression/capsicum/libcapsicum/Makefile b/tools/regression/capsicum/libcasper/Makefile index 468fa33..b024c3b 100644 --- a/tools/regression/capsicum/libcapsicum/Makefile +++ b/tools/regression/capsicum/libcasper/Makefile @@ -12,7 +12,6 @@ CFLAGS+= -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wunused-parameter CFLAGS+= -Wcast-align -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls CFLAGS+= -Wold-style-definition -Wno-pointer-sign -CFLAGS+= -I${.CURDIR}/../../../../lib/libcapsicum CFLAGS+= -ggdb SERVTEST= ${SERVICES:=.t} @@ -22,7 +21,7 @@ all: ${SERVTEST} .for SERVICE in ${SERVICES} ${SERVICE}.t: ${SERVICE}.c - ${CC} ${CFLAGS} ${@:.t=.c} -o $@ -lcapsicum -lnv + ${CC} ${CFLAGS} ${@:.t=.c} -o $@ -lnv -lcasper -lcap_${@:.t=} .endfor diff --git a/tools/regression/capsicum/libcapsicum/dns.c b/tools/regression/capsicum/libcasper/dns.c index 4426bf3..eb364da 100644 --- a/tools/regression/capsicum/libcapsicum/dns.c +++ b/tools/regression/capsicum/libcasper/dns.c @@ -44,9 +44,9 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> -#include <libcapsicum.h> -#include <libcapsicum_dns.h> -#include <libcapsicum_service.h> +#include <libcasper.h> + +#include <casper/cap_dns.h> static int ntest = 1; diff --git a/tools/regression/capsicum/libcapsicum/grp.c b/tools/regression/capsicum/libcasper/grp.c index dbffeaf..7b8ada5 100644 --- a/tools/regression/capsicum/libcapsicum/grp.c +++ b/tools/regression/capsicum/libcasper/grp.c @@ -41,9 +41,9 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> -#include <libcapsicum.h> -#include <libcapsicum_grp.h> -#include <libcapsicum_service.h> +#include <libcasper.h> + +#include <casper/cap_grp.h> static int ntest = 1; diff --git a/tools/regression/capsicum/libcapsicum/pwd.c b/tools/regression/capsicum/libcasper/pwd.c index 23e81a3..b102700 100644 --- a/tools/regression/capsicum/libcapsicum/pwd.c +++ b/tools/regression/capsicum/libcasper/pwd.c @@ -41,9 +41,9 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> -#include <libcapsicum.h> -#include <libcapsicum_pwd.h> -#include <libcapsicum_service.h> +#include <libcasper.h> + +#include <casper/cap_pwd.h> static int ntest = 1; diff --git a/tools/regression/capsicum/libcapsicum/sysctl.c b/tools/regression/capsicum/libcasper/sysctl.c index f3ae307..f326820 100644 --- a/tools/regression/capsicum/libcapsicum/sysctl.c +++ b/tools/regression/capsicum/libcasper/sysctl.c @@ -44,9 +44,9 @@ __FBSDID("$FreeBSD$"); #include <string.h> #include <unistd.h> -#include <libcapsicum.h> -#include <libcapsicum_service.h> -#include <libcapsicum_sysctl.h> +#include <libcasper.h> + +#include <casper/cap_sysctl.h> /* * We need some sysctls to perform the tests on. diff --git a/usr.bin/kdump/Makefile b/usr.bin/kdump/Makefile index 40109f0..f80f668 100644 --- a/usr.bin/kdump/Makefile +++ b/usr.bin/kdump/Makefile @@ -11,8 +11,10 @@ CFLAGS+= -I${.CURDIR}/../ktrace -I${.CURDIR} -I${.CURDIR}/../.. -I. LIBADD= sysdecode .if ${MK_CASPER} != "no" -LIBADD+= capsicum -CFLAGS+=-DHAVE_LIBCAPSICUM +LIBADD+= casper +LIBADD+= cap_grp +LIBADD+= cap_pwd +CFLAGS+=-DHAVE_LIBCASPER .endif NO_WERROR?= YES diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 52001d2..e45a733 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -61,7 +61,7 @@ extern int errno; #include <sys/un.h> #include <sys/queue.h> #include <sys/wait.h> -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER #include <sys/nv.h> #endif #include <arpa/inet.h> @@ -70,12 +70,6 @@ extern int errno; #include <err.h> #include <grp.h> #include <inttypes.h> -#ifdef HAVE_LIBCAPSICUM -#include <libcapsicum.h> -#include <libcapsicum_grp.h> -#include <libcapsicum_pwd.h> -#include <libcapsicum_service.h> -#endif #include <locale.h> #include <netdb.h> #include <nl_types.h> @@ -91,6 +85,13 @@ extern int errno; #include "ktrace.h" #include "kdump_subr.h" +#ifdef HAVE_LIBCASPER +#include <libcasper.h> + +#include <casper/cap_grp.h> +#include <casper/cap_pwd.h> +#endif + u_int abidump(struct ktr_header *); int fetchprocinfo(struct ktr_header *, u_int *); int fread_tail(void *, int, int); @@ -151,7 +152,7 @@ struct proc_info static TAILQ_HEAD(trace_procs, proc_info) trace_procs; -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER static cap_channel_t *cappwd, *capgrp; #endif @@ -180,7 +181,7 @@ localtime_init(void) (void)localtime(<ime); } -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER static int cappwdgrp_setup(cap_channel_t **cappwdp, cap_channel_t **capgrpp) { @@ -189,8 +190,8 @@ cappwdgrp_setup(cap_channel_t **cappwdp, cap_channel_t **capgrpp) capcas = cap_init(); if (capcas == NULL) { - warn("unable to contact casperd"); - return (-1); + err(1, "unable to create casper process"); + exit(1); } cappwdloc = cap_service_open(capcas, "system.pwd"); capgrploc = cap_service_open(capcas, "system.grp"); @@ -222,7 +223,7 @@ cappwdgrp_setup(cap_channel_t **cappwdp, cap_channel_t **capgrpp) *capgrpp = capgrploc; return (0); } -#endif /* HAVE_LIBCAPSICUM */ +#endif /* HAVE_LIBCASPER */ int main(int argc, char *argv[]) @@ -302,7 +303,7 @@ main(int argc, char *argv[]) strerror_init(); localtime_init(); -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER if (resolv != 0) { if (cappwdgrp_setup(&cappwd, &capgrp) < 0) { cappwd = NULL; @@ -1648,7 +1649,7 @@ ktrstat(struct stat *statp) if (resolv == 0) { pwd = NULL; } else { -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER if (cappwd != NULL) pwd = cap_getpwuid(cappwd, statp->st_uid); else @@ -1662,7 +1663,7 @@ ktrstat(struct stat *statp) if (resolv == 0) { grp = NULL; } else { -#ifdef HAVE_LIBCAPSICUM +#ifdef HAVE_LIBCASPER if (capgrp != NULL) grp = cap_getgrgid(capgrp, statp->st_gid); else diff --git a/usr.sbin/tcpdump/tcpdump/Makefile b/usr.sbin/tcpdump/tcpdump/Makefile index d54b9bf..ec585f4 100644 --- a/usr.sbin/tcpdump/tcpdump/Makefile +++ b/usr.sbin/tcpdump/tcpdump/Makefile @@ -177,8 +177,9 @@ CFLAGS+= -DLBL_ALIGN LIBADD= l pcap .if ${MK_CASPER} != "no" -LIBADD+= capsicum -CFLAGS+=-DHAVE_CAPSICUM +LIBADD+= casper +LIBADD+= cap_dns +CFLAGS+=-DHAVE_CASPER .endif .if ${MK_OPENSSL} != "no" LIBADD+= crypto diff --git a/usr.sbin/tcpdump/tcpdump/config.h b/usr.sbin/tcpdump/tcpdump/config.h index a3e6f3d..dbd03f7 100644 --- a/usr.sbin/tcpdump/tcpdump/config.h +++ b/usr.sbin/tcpdump/tcpdump/config.h @@ -15,7 +15,7 @@ /* capsicum support available */ /* See Makefile */ -/* #undef HAVE_CAPSICUM */ +/* #undef HAVE_CAPSPER */ /* Define to 1 if you have the `cap_enter' function. */ #define HAVE_CAP_ENTER 1 |