summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroshogbo <oshogbo@FreeBSD.org>2016-02-25 18:23:40 +0000
committeroshogbo <oshogbo@FreeBSD.org>2016-02-25 18:23:40 +0000
commit023f14d65b31db71d1a4e6655205dd919bfeb5fb (patch)
treefaa5b7886c70249c03078cb4861e837c2d0f6582
parent85f8ae969b95a5539c68ffb09c545b5023901f4e (diff)
downloadFreeBSD-src-023f14d65b31db71d1a4e6655205dd919bfeb5fb.zip
FreeBSD-src-023f14d65b31db71d1a4e6655205dd919bfeb5fb.tar.gz
Convert casperd(8) daemon to the libcasper.
After calling the cap_init(3) function Casper will fork from it's original process, using pdfork(2). Forking from a process has a lot of advantages: 1. We have the same cwd as the original process. 2. The same uid, gid and groups. 3. The same MAC labels. 4. The same descriptor table. 5. The same routing table. 6. The same umask. 7. The same cpuset(1). From now services are also in form of libraries. We also removed libcapsicum at all and converts existing program using Casper to new architecture. Discussed with: pjd, jonathan, ed, drysdale@google.com, emaste Partially reviewed by: drysdale@google.com, bdrewery Approved by: pjd (mentor) Differential Revision: https://reviews.freebsd.org/D4277
-rw-r--r--Makefile.inc18
-rw-r--r--ObsoleteFiles.inc19
-rw-r--r--contrib/mdocml/lib.in2
-rw-r--r--contrib/tcpdump/addrtoname.c14
-rw-r--r--contrib/tcpdump/config.h.in2
-rwxr-xr-xcontrib/tcpdump/configure2
-rw-r--r--contrib/tcpdump/configure.in2
-rw-r--r--contrib/tcpdump/tcpdump.c63
-rw-r--r--etc/defaults/rc.conf1
-rw-r--r--etc/mtree/BSD.debug.dist2
-rw-r--r--etc/mtree/BSD.include.dist2
-rw-r--r--etc/mtree/BSD.root.dist4
-rw-r--r--etc/rc.d/Makefile5
-rw-r--r--etc/rc.d/casperd19
-rw-r--r--gnu/usr.bin/groff/tmac/mdoc.local.in2
-rw-r--r--lib/Makefile5
-rw-r--r--lib/libc/posix1e/posix1e.34
-rw-r--r--lib/libcapsicum/Makefile46
-rw-r--r--lib/libcapsicum/Makefile.depend19
-rw-r--r--lib/libcapsicum/libcapsicum_dns.c365
-rw-r--r--lib/libcapsicum/libcapsicum_impl.h39
-rw-r--r--lib/libcapsicum/libcapsicum_pwd.c391
-rw-r--r--lib/libcapsicum/libcapsicum_service.c97
-rw-r--r--lib/libcapsicum/libcapsicum_sysctl.c86
-rw-r--r--lib/libcasper/Makefile19
-rw-r--r--lib/libcasper/libcasper.h70
-rw-r--r--lib/libcasper/libcasper/Makefile38
-rw-r--r--lib/libcasper/libcasper/libcasper.3 (renamed from lib/libcapsicum/libcapsicum.3)43
-rw-r--r--lib/libcasper/libcasper/libcasper.c (renamed from lib/libcapsicum/libcapsicum.c)127
-rw-r--r--lib/libcasper/libcasper/libcasper.h (renamed from lib/libcapsicum/libcapsicum.h)28
-rw-r--r--lib/libcasper/libcasper/libcasper_impl.c (renamed from lib/libcapsicum/libcapsicum_service.h)16
-rw-r--r--lib/libcasper/libcasper/libcasper_impl.h82
-rw-r--r--lib/libcasper/libcasper/libcasper_service.c277
-rw-r--r--lib/libcasper/libcasper/libcasper_service.h (renamed from lib/libcasper/libcasper_impl.h)32
-rw-r--r--lib/libcasper/libcasper/service.c (renamed from lib/libcasper/libcasper.c)135
-rw-r--r--lib/libcasper/libcasper/zygote.c (renamed from sbin/casperd/zygote.c)10
-rw-r--r--lib/libcasper/libcasper/zygote.h (renamed from sbin/casperd/zygote.h)5
-rw-r--r--lib/libcasper/services/Makefile9
-rw-r--r--lib/libcasper/services/cap_dns/Makefile20
-rw-r--r--lib/libcasper/services/cap_dns/cap_dns.c (renamed from libexec/casper/dns/dns.c)359
-rw-r--r--lib/libcasper/services/cap_dns/cap_dns.h (renamed from lib/libcapsicum/libcapsicum_dns.h)6
-rw-r--r--lib/libcasper/services/cap_grp/Makefile20
-rw-r--r--lib/libcasper/services/cap_grp/cap_grp.c (renamed from lib/libcapsicum/libcapsicum_grp.c)355
-rw-r--r--lib/libcasper/services/cap_grp/cap_grp.h (renamed from lib/libcapsicum/libcapsicum_grp.h)6
-rw-r--r--lib/libcasper/services/cap_pwd/Makefile20
-rw-r--r--lib/libcasper/services/cap_pwd/cap_pwd.c (renamed from libexec/casper/pwd/pwd.c)383
-rw-r--r--lib/libcasper/services/cap_pwd/cap_pwd.h (renamed from lib/libcapsicum/libcapsicum_pwd.h)6
-rw-r--r--lib/libcasper/services/cap_random/Makefile20
-rw-r--r--lib/libcasper/services/cap_random/cap_random.c (renamed from lib/libcapsicum/libcapsicum_random.c)41
-rw-r--r--lib/libcasper/services/cap_random/cap_random.h (renamed from lib/libcapsicum/libcapsicum_random.h)6
-rw-r--r--lib/libcasper/services/cap_sysctl/Makefile20
-rw-r--r--lib/libcasper/services/cap_sysctl/cap_sysctl.c (renamed from libexec/casper/sysctl/sysctl.c)72
-rw-r--r--lib/libcasper/services/cap_sysctl/cap_sysctl.h (renamed from lib/libcapsicum/libcapsicum_sysctl.h)6
-rw-r--r--libexec/Makefile5
-rw-r--r--libexec/casper/Makefile11
-rw-r--r--libexec/casper/dns/Makefile21
-rw-r--r--libexec/casper/grp/Makefile21
-rw-r--r--libexec/casper/grp/grp.c390
-rw-r--r--libexec/casper/pwd/Makefile21
-rw-r--r--libexec/casper/random/Makefile21
-rw-r--r--libexec/casper/random/random.c82
-rw-r--r--libexec/casper/sysctl/Makefile21
-rw-r--r--libexec/rtld-elf/paths.h2
-rw-r--r--sbin/Makefile1
-rw-r--r--sbin/casperd/Makefile17
-rw-r--r--sbin/casperd/casperd.8132
-rw-r--r--sbin/casperd/casperd.c721
-rw-r--r--sbin/ping/Makefile5
-rw-r--r--sbin/ping/Makefile.depend3
-rw-r--r--sbin/ping/ping.c34
-rw-r--r--share/man/man4/capsicum.45
-rw-r--r--share/mk/bsd.libnames.mk1
-rw-r--r--share/mk/src.libnames.mk33
-rw-r--r--targets/pseudo/userland/Makefile.depend4
-rw-r--r--targets/pseudo/userland/lib/Makefile.depend12
-rw-r--r--targets/pseudo/userland/libexec/Makefile.depend5
-rw-r--r--tools/regression/capsicum/libcasper/Makefile (renamed from tools/regression/capsicum/libcapsicum/Makefile)3
-rw-r--r--tools/regression/capsicum/libcasper/dns.c (renamed from tools/regression/capsicum/libcapsicum/dns.c)6
-rw-r--r--tools/regression/capsicum/libcasper/grp.c (renamed from tools/regression/capsicum/libcapsicum/grp.c)6
-rw-r--r--tools/regression/capsicum/libcasper/pwd.c (renamed from tools/regression/capsicum/libcapsicum/pwd.c)6
-rw-r--r--tools/regression/capsicum/libcasper/sysctl.c (renamed from tools/regression/capsicum/libcapsicum/sysctl.c)6
-rw-r--r--usr.bin/kdump/Makefile6
-rw-r--r--usr.bin/kdump/kdump.c31
-rw-r--r--usr.sbin/tcpdump/tcpdump/Makefile5
-rw-r--r--usr.sbin/tcpdump/tcpdump/config.h2
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(&ltime);
}
-#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
OpenPOWER on IntegriCloud