aboutsummaryrefslogtreecommitdiff
path: root/libcap
diff options
context:
space:
mode:
authorAndrew Morgan <morgan@kernel.org>2007-07-10 20:50:21 -0700
committerAndrew Morgan <morgan@kernel.org>2007-07-10 20:50:21 -0700
commit2c9c0532daccfd300f0eb1401b15348ed19d0ce7 (patch)
tree0e850e1a45be8cb8452a5157bd4b6538eafdbebe /libcap
downloadlibcap-2c9c0532daccfd300f0eb1401b15348ed19d0ce7.tar.gz
This is the source for libcap-1.0.tar.gz
http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.2/libcap-1.0.tar.gz
Diffstat (limited to 'libcap')
-rw-r--r--libcap/Makefile77
-rw-r--r--libcap/RCS/Makefile,v256
-rw-r--r--libcap/RCS/_makenames.c,v218
-rw-r--r--libcap/RCS/cap_alloc.c,v168
-rw-r--r--libcap/RCS/cap_extint.c,v260
-rw-r--r--libcap/RCS/cap_file.c,v278
-rw-r--r--libcap/RCS/cap_flag.c,v241
-rw-r--r--libcap/RCS/cap_proc.c,v241
-rw-r--r--libcap/RCS/cap_sys.c,v176
-rw-r--r--libcap/RCS/cap_text.c,v996
-rw-r--r--libcap/RCS/libcap.h,v287
-rw-r--r--libcap/_makenames.c79
-rw-r--r--libcap/cap_alloc.c90
-rw-r--r--libcap/cap_extint.c142
-rw-r--r--libcap/cap_file.c117
-rw-r--r--libcap/cap_flag.c122
-rw-r--r--libcap/cap_proc.c100
-rw-r--r--libcap/cap_sys.c36
-rw-r--r--libcap/cap_text.c323
-rw-r--r--libcap/include/sys/RCS/capability.h,v197
-rw-r--r--libcap/include/sys/capability.h104
-rw-r--r--libcap/libcap.h125
22 files changed, 4633 insertions, 0 deletions
diff --git a/libcap/Makefile b/libcap/Makefile
new file mode 100644
index 0000000..19287da
--- /dev/null
+++ b/libcap/Makefile
@@ -0,0 +1,77 @@
+##
+## $Log: Makefile,v $
+## Revision 1.5 1998/05/24 22:54:09 morgan
+## updated for 2.1.104
+##
+## Revision 1.4 1997/05/14 05:17:13 morgan
+## autoconf rearrangement from Zefram
+##
+## Revision 1.3 1997/05/04 05:34:59 morgan
+## cleaner
+##
+## Revision 1.2 1997/04/28 00:57:11 morgan
+## fixes and zefram's patches
+##
+## Revision 1.1 1997/04/21 04:33:29 morgan
+## Initial revision
+##
+##
+##
+
+#
+# defines
+#
+topdir=$(shell pwd)/..
+include ../Make.Rules
+#
+# Library version
+#
+LIBNAME=libcap.so
+#
+
+FILES=cap_alloc cap_proc cap_extint cap_flag cap_text cap_sys
+
+# for later when there is filesystem support for cap's:
+#FILES += cap_file
+
+INCLS=libcap.h cap_names.h $(INCS)
+OBJS=$(addsuffix .o, $(FILES))
+MAJLIBNAME=$(LIBNAME).$(VERSION)
+MINLIBNAME=$(MAJLIBNAME).$(MINOR)
+
+all: $(MINLIBNAME)
+
+_makenames: _makenames.c cap_names.sed
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
+
+cap_names.h: _makenames
+ ./_makenames > cap_names.h
+
+cap_names.sed: Makefile /usr/include/linux/capability.h
+ @echo "=> making cap_names.c from <linux/capability.h>"
+ @sed -ne '/^#define[ \t]CAP[_A-Z]\+[ \t]\+[0-9]\+/{s/^#define \([^ \t]*\)[ \t]*\([^ \t]*\)/ \{ \2, \"\1\" \},/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' < /usr/include/linux/capability.h | fgrep -v 0x > cap_names.sed
+# @sed -ne '/^#define[ \t]CAP[_A-Z]\+[ \t]\+[0-9]\+/{s/^#define CAP_\([^ \t]*\)[ \t]*\([^ \t]*\)/ \{ \2, \"\1\" \},/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' < /usr/include/linux/capability.h | fgrep -v 0x > cap_names.sed
+
+$(MINLIBNAME): $(OBJS)
+ $(LD) -soname $(MAJLIBNAME) -x -shared -o $@ $(OBJS)
+ ln -sf $(MINLIBNAME) $(MAJLIBNAME)
+ ln -sf $(MAJLIBNAME) $(LIBNAME)
+
+%.o: %.c $(INCLS)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+install: all
+ mkdir -p -m 0755 $(INCDIR)/sys
+ install -m 0644 include/sys/capability.h $(INCDIR)/sys
+ mkdir -p -m 0755 $(LIBDIR)
+ install -m 0644 $(MINLIBNAME) $(LIBDIR)/$(MINLIBNAME)
+ ln -sf $(MINLIBNAME) $(LIBDIR)/$(MAJLIBNAME)
+ ln -sf $(MAJLIBNAME) $(LIBDIR)/$(LIBNAME)
+ -/sbin/ldconfig
+
+clean:
+ $(LOCALCLEAN)
+ rm -f $(OBJS) $(LIBNAME)*
+ rm -f cap_names.h cap_names.sed _makenames
+ cd include/sys && $(LOCALCLEAN)
+
diff --git a/libcap/RCS/Makefile,v b/libcap/RCS/Makefile,v
new file mode 100644
index 0000000..098675e
--- /dev/null
+++ b/libcap/RCS/Makefile,v
@@ -0,0 +1,256 @@
+head 1.5;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.5
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.4;
+
+1.4
+date 97.05.14.05.17.13; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 97.05.04.05.34.59; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.33.29; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.5
+log
+@updated for 2.1.104
+@
+text
+@##
+## $Log: Makefile,v $
+## Revision 1.4 1997/05/14 05:17:13 morgan
+## autoconf rearrangement from Zefram
+##
+## Revision 1.3 1997/05/04 05:34:59 morgan
+## cleaner
+##
+## Revision 1.2 1997/04/28 00:57:11 morgan
+## fixes and zefram's patches
+##
+## Revision 1.1 1997/04/21 04:33:29 morgan
+## Initial revision
+##
+##
+##
+
+#
+# defines
+#
+topdir=$(shell pwd)/..
+include ../Make.Rules
+#
+# Library version
+#
+LIBNAME=libcap.so
+#
+
+FILES=cap_alloc cap_proc cap_extint cap_flag cap_text cap_sys
+
+# for later when there is filesystem support for cap's:
+#FILES += cap_file
+
+INCLS=libcap.h cap_names.h $(INCS)
+OBJS=$(addsuffix .o, $(FILES))
+MAJLIBNAME=$(LIBNAME).$(VERSION)
+MINLIBNAME=$(MAJLIBNAME).$(MINOR)
+
+all: $(MINLIBNAME)
+
+_makenames: _makenames.c cap_names.sed
+ $(CC) $(CFLAGS) $(LDFLAGS) $< -o $@@
+
+cap_names.h: _makenames
+ ./_makenames > cap_names.h
+
+cap_names.sed: Makefile /usr/include/linux/capability.h
+ @@echo "=> making cap_names.c from <linux/capability.h>"
+ @@sed -ne '/^#define[ \t]CAP[_A-Z]\+[ \t]\+[0-9]\+/{s/^#define \([^ \t]*\)[ \t]*\([^ \t]*\)/ \{ \2, \"\1\" \},/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' < /usr/include/linux/capability.h | fgrep -v 0x > cap_names.sed
+# @@sed -ne '/^#define[ \t]CAP[_A-Z]\+[ \t]\+[0-9]\+/{s/^#define CAP_\([^ \t]*\)[ \t]*\([^ \t]*\)/ \{ \2, \"\1\" \},/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' < /usr/include/linux/capability.h | fgrep -v 0x > cap_names.sed
+
+$(MINLIBNAME): $(OBJS)
+ $(LD) -soname $(MAJLIBNAME) -x -shared -o $@@ $(OBJS)
+ ln -sf $(MINLIBNAME) $(MAJLIBNAME)
+ ln -sf $(MAJLIBNAME) $(LIBNAME)
+
+%.o: %.c $(INCLS)
+ $(CC) $(CFLAGS) -c $< -o $@@
+
+install: all
+ mkdir -p -m 0755 $(INCDIR)/sys
+ install -m 0644 include/sys/capability.h $(INCDIR)/sys
+ mkdir -p -m 0755 $(LIBDIR)
+ install -m 0644 $(MINLIBNAME) $(LIBDIR)/$(MINLIBNAME)
+ ln -sf $(MINLIBNAME) $(LIBDIR)/$(MAJLIBNAME)
+ ln -sf $(MAJLIBNAME) $(LIBDIR)/$(LIBNAME)
+ -/sbin/ldconfig
+
+clean:
+ $(LOCALCLEAN)
+ rm -f $(OBJS) $(LIBNAME)*
+ rm -f cap_names.h cap_names.sed _makenames
+ cd include/sys && $(LOCALCLEAN)
+
+@
+
+
+1.4
+log
+@autoconf rearrangement from Zefram
+@
+text
+@d3 3
+d29 4
+a32 2
+FILES=cap_alloc cap_file cap_proc cap_extint cap_flag cap_text cap_sys \
+ cap_names
+d34 1
+a34 1
+INCLS=libcap.h $(INCS)
+d44 2
+a45 2
+cap_names.c: _makenames
+ ./_makenames > cap_names.c
+d49 2
+a50 1
+ @@sed -ne '/^#define CAP_/{s/^#define \([^ ]*\)[ ]*\([^ ]*\)/ \{ \2, \"\1\" \},/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' < /usr/include/linux/capability.h > cap_names.sed
+d72 1
+a72 1
+ rm -f cap_names.c cap_names.sed _makenames
+@
+
+
+1.3
+log
+@cleaner
+@
+text
+@d3 3
+d18 1
+a18 1
+topdir=..
+d29 1
+a29 1
+INCS=libcap.h include/sys/capability.h
+d34 1
+a34 1
+all: $(LIBNAME)
+d37 1
+a37 1
+ $(CC) $(CFLAGS) $< -o $@@
+d46 1
+a46 1
+$(LIBNAME): $(OBJS)
+d48 2
+d51 1
+a51 1
+%.o: %.c $(INCS)
+d55 5
+a59 6
+ mkdir -p $(INCDIR)/sys
+ install -g root -o root -m 0644 include/sys/capability.h $(INCDIR)/sys
+ mkdir -p $(LIBDIR)
+ install -g root -o root -m 0444 $(LIBNAME) $(LIBDIR)/$(MINLIBNAME)
+ rm -f $(LIBDIR)/$(LIBNAME)
+ /sbin/ldconfig -nN $(LIBDIR)
+d61 1
+d65 2
+a66 1
+ rm -f $(OBJS) $(LIBNAME) cap_names.c cap_names.sed _makenames
+@
+
+
+1.2
+log
+@fixes and zefram's patches
+@
+text
+@d3 3
+d33 9
+a41 12
+cap_names.c: _makenames /usr/include/linux/capability.h
+ @@echo -e "\n=> making cap_names.c from <linux/capability.h>\n"
+ @@( \
+ echo '/** cap_names.c **'; \
+ echo ' ** automatically generated -- DO NOT EDIT! **/'; \
+ echo; \
+ echo '#include "libcap.h"'; \
+ echo; \
+ echo 'char const *_cap_names[__CAP_BITS] = {'; \
+ sed -ne '/^#define CAP_/{s/^#define \([^ ]*\)[ ]*\([^ ]*\)/ \2\/\1/;y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/;p;}' < /usr/include/linux/capability.h | ./_makenames; \
+ echo '};'; \
+ ) > $@@
+d55 2
+a56 2
+ /sbin/ldconfig
+ cd $(LIBDIR) && ln -sf $(MAJLIBNAME) $(LIBNAME)
+d60 1
+a60 1
+ rm -f $(OBJS) $(LIBNAME) cap_names.c _makenames
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d3 3
+d10 1
+a10 1
+# flags
+d12 2
+a13 5
+IPATH=-I./include
+WARNINGS = -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
+ -Wpointer-arith -Wcast-qual -Wcast-align \
+ -Wtraditional -Wstrict-prototypes -Wmissing-prototypes \
+ -Wnested-externs -Winline -Wshadow -pedantic
+a17 2
+VERSION=0
+MINOR=01
+d20 3
+a22 1
+FILES=cap_alloc cap_file cap_proc cap_extint cap_flag cap_text cap_sys
+d28 1
+a28 1
+export CFLAGS =-Dlinux $(WARNINGS) $(DEBUG) $(COPTFLAG) $(IPATH)
+d30 12
+a41 1
+all: $(LIBNAME)
+d50 5
+a54 4
+ mkdir -p $(FAKEROOT)/usr/include/sys
+ install -g root -o root -m 0644 include/sys/capability.h $(FAKEROOT)/usr/include/sys
+ mkdir -p $(FAKEROOT)/lib
+ install -g root -o root -m 0444 $(LIBNAME) $(FAKEROOT)/lib/$(MINLIBNAME)
+d56 1
+d59 3
+a61 2
+ rm -f *~ core $(OBJS) $(LIBNAME)
+ cd include/sys && rm -f *~ core
+@
diff --git a/libcap/RCS/_makenames.c,v b/libcap/RCS/_makenames.c,v
new file mode 100644
index 0000000..236d4be
--- /dev/null
+++ b/libcap/RCS/_makenames.c,v
@@ -0,0 +1,218 @@
+head 1.4;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.4
+date 98.06.07.15.50.12; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.05.04.05.35.46; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@Ansi partner to zefram's one line sed command
+@
+
+
+1.4
+log
+@updated to accommodate kernel's real header file :*)
+@
+text
+@/*
+ * $Id: _makenames.c,v 1.3 1998/05/24 22:54:09 morgan Exp morgan $
+ *
+ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@@linux.kernel.org>
+ *
+ * This is a file to make the capability <-> string mappings for
+ * libcap.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/capability.h>
+
+/*
+ * #include 'sed' generated array
+ */
+
+struct {
+ int index;
+ const char *name;
+} const list[] = {
+#include "cap_names.sed"
+ {-1, NULL}
+};
+
+/* this should be more than big enough (factor of three at least) */
+const char *pointers[8*sizeof(struct __user_cap_data_struct)];
+
+int main(void)
+{
+ int i, maxcaps=0;
+
+ for ( i=0; list[i].index >= 0 && list[i].name; ++i ) {
+ if (maxcaps < list[i].index) {
+ maxcaps = list[i].index;
+ }
+ pointers[list[i].index] = list[i].name;
+ }
+
+ printf("/*\n"
+ " * DO NOT EDIT: this file is generated automatically from\n"
+ " *\n"
+ " * <linux/capability.h>\n"
+ " */\n"
+ "#define __CAP_BITS %d\n"
+ "\n"
+ "#ifdef LIBCAP_PLEASE_INCLUDE_ARRAY\n"
+ " char const *_cap_names[__CAP_BITS] = {\n", maxcaps);
+
+ for (i=0; i<maxcaps; ++i) {
+ if (pointers[i])
+ printf(" /* %d */\t\"%s\",\n", i, pointers[i]);
+ else
+ printf(" /* %d */\tNULL,\t\t/* - presently unused */\n", i);
+ }
+
+ printf(" };\n"
+ "#endif /* LIBCAP_PLEASE_INCLUDE_ARRAY */\n"
+ "\n"
+ "/* END OF FILE */\n");
+
+ exit(0);
+}
+
+/*
+ * $Log: _makenames.c,v $
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/05/04 05:35:46 morgan
+ * cleaned up to #include sed output. also generates whole cap_names.c file
+ *
+ * Revision 1.1 1997/04/28 00:57:11 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.3
+log
+@updated for 2.1.104
+@
+text
+@d2 1
+a2 1
+ * $Id: _makenames.c,v 1.2 1997/05/04 05:35:46 morgan Exp morgan $
+d27 1
+a27 1
+const char *pointers[8*sizeof(struct _user_cap_data_struct)];
+d67 3
+@
+
+
+1.2
+log
+@cleaned up to #include sed output. also generates whole cap_names.c file
+@
+text
+@d2 1
+a2 1
+ * $Id: _makenames.c,v 1.1 1997/04/28 00:57:11 morgan Exp morgan $
+d4 1
+a4 1
+ * Copyright (c) 1997 Andrew G. Morgan <morgan@@parc.power.net>
+d26 2
+a27 1
+const char *pointers[__CAP_BITS];
+d31 1
+a31 1
+ int i;
+d34 3
+d45 1
+d47 2
+a48 3
+ "#include \"libcap.h\"\n"
+ "\n"
+ "char const *_cap_names[__CAP_BITS] = {\n");
+d50 1
+a50 1
+ for (i=0; i<__CAP_BITS; ++i) {
+d52 1
+a52 1
+ printf(" /* %d */\t\"%s\",\n", i, pointers[i]);
+d54 1
+a54 1
+ printf(" /* %d */\tNULL,\t\t/* - presently unused */\n", i);
+d57 2
+a58 1
+ printf("};\n"
+d67 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+a10 2
+#define __USE_BSD
+#include <string.h>
+d15 1
+a15 2
+ * Read the standard input for a list of index/string pairs
+ * store them in an array and then output an array setting file
+d18 7
+a24 1
+#define MAXBUFF 100
+d26 1
+a26 1
+char *pointers[__CAP_BITS];
+d28 1
+a28 1
+void main(void)
+a29 1
+ char buffer[MAXBUFF];
+d32 3
+a34 5
+ while (fgets(buffer, MAXBUFF, stdin)) {
+ char *tmp = buffer;
+
+ tmp = strtok(tmp, "/");
+ i = atoi(tmp);
+d36 9
+a44 6
+ tmp = strtok(NULL, "/");
+ if (tmp[strlen(tmp)-1] == '\n')
+ tmp[strlen(tmp)-1] = '\0';
+
+ pointers[i] = strdup(tmp);
+ }
+d52 6
+d61 4
+a64 1
+ * $Log$
+@
diff --git a/libcap/RCS/cap_alloc.c,v b/libcap/RCS/cap_alloc.c,v
new file mode 100644
index 0000000..4167830
--- /dev/null
+++ b/libcap/RCS/cap_alloc.c,v
@@ -0,0 +1,168 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.3
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.3
+log
+@updated for 2.1.104
+@
+text
+@/*
+ * $Id: cap_alloc.c,v 1.2 1997/04/28 00:57:11 morgan Exp morgan $
+ *
+ * Copyright (c) 1997-8 Andrew G Morgan <morgan@@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with allocation and deallocation of internal
+ * capability sets as specified by POSIX.1e (formerlly, POSIX 6).
+ */
+
+#include "libcap.h"
+
+/*
+ * This function duplicates an internal capability set (x3) with
+ * malloc()'d memory. It is the responsibility of the user to call
+ * cap_free() to liberate it.
+ */
+
+cap_t cap_dup(cap_t cap_d)
+{
+ cap_t result;
+
+ if (!good_cap_t(cap_d)) {
+ _cap_debug("bad argument");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ result = (cap_t) malloc( sizeof(*cap_d) );
+ if (result == NULL) {
+ _cap_debug("out of memory");
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ memcpy(result, cap_d, sizeof(*cap_d));
+
+ return result;
+}
+
+
+/*
+ * Scrub and then liberate an internal capability set.
+ */
+
+int cap_free(cap_t *cap_d_p)
+{
+ if ( cap_d_p && good_cap_t(*cap_d_p) ) {
+ memset(*cap_d_p, 0, sizeof(**cap_d_p));
+ free(*cap_d_p);
+ *cap_d_p = NULL;
+
+ return 0;
+ } else {
+ _cap_debug("no capability to liberate");
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+/*
+ * Obtain a blank set of capabilities
+ */
+
+cap_t cap_init(void)
+{
+ cap_t result = (cap_t) calloc( 1, sizeof(*result) );
+
+ if (result) {
+ result->magic = CAP_T_MAGIC;
+ result->head.version = _LINUX_CAPABILITY_VERSION;
+ } else {
+ errno = ENOMEM;
+ }
+ return result;
+}
+
+/*
+ * $Log: cap_alloc.c,v $
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.2
+log
+@fixes and zefram's patches
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_alloc.c,v 1.1 1997/04/21 04:32:52 morgan Exp morgan $
+d4 1
+a4 1
+ * Copyright (c) 1997 Andrew G Morgan <morgan@@parc.power.net>
+d68 1
+a68 1
+ cap_t result = (cap_t) malloc( sizeof(*result) );
+d72 1
+a72 1
+ memset(&result->set, 0, 3*sizeof(__cap_s));
+d81 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+a14 9
+ * Return the byte length of the capability set
+ */
+
+ssize_t cap_size(cap_t cap_d)
+{
+ return sizeof(*cap_d);
+}
+
+/*
+d51 1
+d72 1
+d80 4
+a83 1
+ * $Log$
+@
diff --git a/libcap/RCS/cap_extint.c,v b/libcap/RCS/cap_extint.c,v
new file mode 100644
index 0000000..3f07499
--- /dev/null
+++ b/libcap/RCS/cap_extint.c,v
@@ -0,0 +1,260 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.3
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.3
+log
+@updated for 2.1.104
+@
+text
+@/*
+ * $Id: cap_extint.c,v 1.2 1997/04/28 00:57:11 morgan Exp morgan $
+ *
+ * Copyright (c) 1997-8 Andrew G Morgan <morgan@@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with exchanging internal and external
+ * representations of capability sets.
+ */
+
+#include "libcap.h"
+
+/*
+ * External representation for capabilities. (exported as a fixed
+ * length (void *))
+ */
+#define CAP_EXT_MAGIC "\220\302\001\121"
+#define CAP_EXT_MAGIC_SIZE 4
+const static __u8 external_magic[CAP_EXT_MAGIC_SIZE+1] = CAP_EXT_MAGIC;
+
+struct cap_ext_struct {
+ __u8 magic[CAP_EXT_MAGIC_SIZE];
+ __u8 length_of_capset;
+/* note, we arrange these so the caps are stacked with byte-size
+ resolution */
+ __u8 bytes[CAP_SET_SIZE][NUMBER_OF_CAP_SETS];
+};
+
+/*
+ * return size of external capability set
+ */
+
+ssize_t cap_size(cap_t caps)
+{
+ return sizeof(struct cap_ext_struct);
+}
+
+/*
+ * Copy the internal (cap_d) capability set into an external
+ * representation. The external representation is portable to other
+ * Linux architectures.
+ */
+
+ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length)
+{
+ struct cap_ext_struct *result = (struct cap_ext_struct *) cap_ext;
+ __u32 *from = (__u32 *) &(cap_d->set);
+ int i;
+
+ /* valid arguments? */
+ if (!good_cap_t(cap_d) || length < sizeof(struct cap_ext_struct)
+ || cap_ext == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* fill external capability set */
+ memcpy(&result->magic, external_magic, CAP_EXT_MAGIC_SIZE);
+ result->length_of_capset = CAP_SET_SIZE;
+
+ for (i=0; i<NUMBER_OF_CAP_SETS; ++i) {
+ int j;
+ for (j=0; j<CAP_SET_SIZE; ) {
+ __u32 val = *from++;
+
+ result->bytes[j++][i] = val & 0xFF;
+ result->bytes[j++][i] = (val >>= 8) & 0xFF;
+ result->bytes[j++][i] = (val >>= 8) & 0xFF;
+ result->bytes[j++][i] = (val >> 8) & 0xFF;
+ }
+ }
+
+ /* All done: return length of external representation */
+ return (sizeof(struct cap_ext_struct));
+}
+
+/*
+ * Import an external representation to produce an internal rep.
+ * the internal rep should be liberated with cap_free().
+ */
+
+/*
+ * XXX - need to take a little more care when importing small
+ * capability sets.
+ */
+
+cap_t cap_copy_int(const void *cap_ext)
+{
+ const struct cap_ext_struct *export =
+ (const struct cap_ext_struct *) cap_ext;
+ cap_t cap_d;
+ int set, blen;
+ __u32 * to = (__u32 *) &cap_d->set;
+
+ /* Does the external representation make sense? */
+ if (export == NULL || !memcmp(export->magic, external_magic
+ , CAP_EXT_MAGIC_SIZE)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* Obtain a new internal capability set */
+ if (!(cap_d = cap_init()))
+ return NULL;
+
+ blen = export->length_of_capset;
+ for (set=0; set<=NUMBER_OF_CAP_SETS; ++set) {
+ int blk;
+ int bno = 0;
+ for (blk=0; blk<(CAP_SET_SIZE/4); ++blk) {
+ __u32 val = 0;
+
+ if (bno != blen)
+ val = export->bytes[bno++][set];
+ if (bno != blen)
+ val |= export->bytes[bno++][set] << 8;
+ if (bno != blen)
+ val |= export->bytes[bno++][set] << 16;
+ if (bno != blen)
+ val |= export->bytes[bno++][set] << 24;
+
+ *to++ = val;
+ }
+ }
+
+ /* all done */
+ return cap_d;
+}
+
+/*
+ * $Log: cap_extint.c,v $
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.2
+log
+@fixes and zefram's patches
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_extint.c,v 1.1 1997/04/21 04:32:52 morgan Exp morgan $
+d4 1
+a4 1
+ * Copyright (c) 1997 Andrew G Morgan <morgan@@parc.power.net>
+d20 1
+a20 1
+static __u8 external_magic[CAP_EXT_MAGIC_SIZE+1] = CAP_EXT_MAGIC;
+d25 3
+a27 1
+ __u8 bytes[sizeof(struct __cap_s)][3];
+d48 1
+d59 2
+a60 2
+ memcpy(&result->magic,external_magic,CAP_EXT_MAGIC_SIZE);
+ result->length_of_capset = sizeof(struct __cap_s);
+d62 1
+a62 1
+ for (i=CAP_EFFECTIVE; i<=CAP_PERMITTED; ++i) {
+d64 7
+a70 9
+ for (j=0; j<__CAP_BLKS; ++j) {
+ __u32 val;
+ int k = j << 2;
+
+ val = cap_d->set[i]._blk[j];
+ result->bytes[k++][i] = val & 0xFF;
+ result->bytes[k++][i] = (val >>= 8) & 0xFF;
+ result->bytes[k++][i] = (val >>= 8) & 0xFF;
+ result->bytes[k][i] = (val >> 8) & 0xFF;
+d94 1
+d108 1
+a108 1
+ for (set=CAP_EFFECTIVE; set<=CAP_PERMITTED; ++set) {
+d111 1
+a111 1
+ for (blk=0; blk<__CAP_BLKS; ++blk) {
+d123 1
+a123 1
+ cap_d->set[set]._blk[blk] = val;
+d133 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+d18 3
+d23 1
+d29 9
+d56 1
+d92 1
+d95 2
+a96 1
+ if (export == NULL || export->length_of_capset > sizeof(struct __cap_s)) {
+d102 20
+a121 13
+ if ((cap_d = cap_init())) {
+ int i;
+ for (i=CAP_EFFECTIVE; i<=CAP_PERMITTED; ++i) {
+ int j;
+ for (j=0; j<__CAP_BLKS; ++j) {
+ __u32 val;
+ int k = (j+1) << 2;
+
+ val = export->bytes[--k][i] << 8;
+ val |= export->bytes[--k][i]; val <<= 8;
+ val |= export->bytes[--k][i]; val <<= 8;
+ cap_d->set[i]._blk[j] = val | export->bytes[--k][i];
+ }
+d130 4
+a133 1
+ * $Log$
+@
diff --git a/libcap/RCS/cap_file.c,v b/libcap/RCS/cap_file.c,v
new file mode 100644
index 0000000..3a06923
--- /dev/null
+++ b/libcap/RCS/cap_file.c,v
@@ -0,0 +1,278 @@
+head 1.5;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.5
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.4;
+
+1.4
+date 97.05.14.05.17.13; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 97.05.04.05.35.46; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.5
+log
+@updated for 2.1.104
+@
+text
+@/*
+ * $Id: cap_file.c,v 1.4 1997/05/14 05:17:13 morgan Exp morgan $
+ *
+ * Copyright (c) 1997 Andrew G Morgan <morgan@@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with setting capabilities on files.
+ */
+
+#include "libcap.h"
+
+/*
+ * Get the capabilities of an open file, as specified by its file
+ * descriptor.
+ */
+
+cap_t cap_get_fd(int fildes)
+{
+ cap_t result;
+
+ /* allocate a new capability set */
+ result = cap_init();
+ if (result) {
+ _cap_debug("getting fildes capabilities");
+
+ /* fill the capability sets via a system call */
+ if (_fgetfilecap(fildes, sizeof(struct __cap_s),
+ &result->set[CAP_INHERITABLE],
+ &result->set[CAP_PERMITTED],
+ &result->set[CAP_EFFECTIVE] )) {
+ cap_free(&result);
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Set the capabilities on a named file.
+ */
+
+cap_t cap_get_file(const char *filename)
+{
+ cap_t result;
+
+ /* allocate a new capability set */
+ result = cap_init();
+ if (result) {
+ _cap_debug("getting named file capabilities");
+
+ /* fill the capability sets via a system call */
+ if (_getfilecap(filename, sizeof(struct __cap_s),
+ &result->set[CAP_INHERITABLE],
+ &result->set[CAP_PERMITTED],
+ &result->set[CAP_EFFECTIVE] ))
+ cap_free(&result);
+ }
+
+ return result;
+}
+
+/*
+ * Set the capabilities of an open file, as specified by its file
+ * descriptor.
+ */
+
+int cap_set_fd(int fildes, cap_t cap_d)
+{
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("setting fildes capabilities");
+ return _fsetfilecap(fildes, sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] );
+}
+
+/*
+ * Set the capabilities of a named file.
+ */
+
+int cap_set_file(const char *filename, cap_t cap_d)
+{
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("setting filename capabilities");
+ return _setfilecap(filename, sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] );
+}
+
+/*
+ * $Log: cap_file.c,v $
+ * Revision 1.4 1997/05/14 05:17:13 morgan
+ * bug-fix from zefram (errno no set on success)
+ *
+ * Revision 1.3 1997/05/04 05:35:46 morgan
+ * fixed errno setting. syscalls do this part
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.4
+log
+@bug-fix from zefram (errno no set on success)
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_file.c,v 1.3 1997/05/04 05:35:46 morgan Exp morgan $
+d4 1
+a4 1
+ * Copyright (c) 1997 Andrew G Morgan <morgan@@parc.power.net>
+d102 3
+@
+
+
+1.3
+log
+@fixed errno setting. syscalls do this part
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_file.c,v 1.2 1997/04/28 00:57:11 morgan Exp morgan $
+d70 1
+a70 10
+ if (good_cap_t(cap_d)) {
+ _cap_debug("setting fildes capabilities");
+
+ if (_fsetfilecap(fildes, sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] )) {
+ _cap_debug("failed: %s", strerror(errno));
+ }
+ } else {
+d72 1
+d75 5
+a79 1
+ return (errno ? -1:0);
+d88 1
+a88 10
+ if (good_cap_t(cap_d)) {
+ _cap_debug("setting named file capabilities");
+
+ if (_setfilecap(filename, sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] )) {
+ _cap_debug("failed: %s", strerror(errno));
+ }
+ } else {
+d90 1
+d93 5
+a97 1
+ return (errno ? -1:0);
+d102 3
+@
+
+
+1.2
+log
+@fixes and zefram's patches
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_file.c,v 1.1 1997/04/21 04:32:52 morgan Exp morgan $
+d28 1
+a28 1
+ errno = -_fgetfilecap(fildes, sizeof(struct __cap_s),
+d31 1
+a31 3
+ &result->set[CAP_EFFECTIVE] );
+
+ if (errno)
+d33 1
+d53 1
+a53 1
+ errno = -_getfilecap(filename, sizeof(struct __cap_s),
+d56 1
+a56 3
+ &result->set[CAP_EFFECTIVE] );
+
+ if (errno)
+d73 6
+a78 4
+ errno = -_fsetfilecap(fildes, sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] );
+d95 6
+a100 4
+ errno = -_setfilecap(filename, sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] );
+d110 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+d26 1
+d32 3
+d52 1
+d58 3
+d75 1
+d95 1
+d108 4
+a111 1
+ * $Log$
+@
diff --git a/libcap/RCS/cap_flag.c,v b/libcap/RCS/cap_flag.c,v
new file mode 100644
index 0000000..45a7258
--- /dev/null
+++ b/libcap/RCS/cap_flag.c,v
@@ -0,0 +1,241 @@
+head 1.4;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.4
+date 98.09.20.23.07.59; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.4
+log
+@fixed lower bound check on 'set'.
+@
+text
+@/*
+ * $Id: cap_flag.c,v 1.3 1998/05/24 22:54:09 morgan Exp morgan $
+ *
+ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with flipping of capabilities on internal
+ * capability sets as specified by POSIX.1e (formerlly, POSIX 6).
+ */
+
+#include "libcap.h"
+
+/*
+ * Return the state of a specified capability flag. The state is
+ * returned as the contents of *raised. The capability is from one of
+ * the sets stored in cap_d as specified by set and value
+ */
+
+int cap_get_flag(cap_t cap_d, cap_value_t value, cap_flag_t set,
+ cap_flag_value_t *raised)
+{
+ /*
+ * Do we have a set and a place to store its value?
+ * Is it a known capability?
+ */
+
+ if (raised && good_cap_t(cap_d) && value >= 0 && value < __CAP_BITS
+ && set >= 0 && set < NUMBER_OF_CAP_SETS) {
+ __cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE
+ + (__u8 *) &cap_d->set);
+
+ *raised = isset_cap(cap_p,value) ? CAP_SET:CAP_CLEAR;
+ return 0;
+
+ } else {
+
+ _cap_debug("invalid arguments");
+ errno = EINVAL;
+ return -1;
+
+ }
+}
+
+/*
+ * raise/lower a selection of capabilities
+ */
+
+int cap_set_flag(cap_t cap_d, cap_flag_t set,
+ int no_values, cap_value_t *array_values,
+ cap_flag_value_t raise)
+{
+ /*
+ * Do we have a set and a place to store its value?
+ * Is it a known capability?
+ */
+
+ if (good_cap_t(cap_d) && no_values > 0 && no_values <= __CAP_BITS
+ && (set >= 0) && (set < NUMBER_OF_CAP_SETS)
+ && (raise == CAP_SET || raise == CAP_CLEAR) ) {
+ int i;
+ for (i=0; i<no_values; ++i) {
+ if (array_values[i] < 0 || array_values[i] >= __CAP_BITS) {
+ _cap_debug("weird capability (%d) - skipped", array_values[i]);
+ } else {
+ int value = array_values[i];
+ __cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE
+ + (__u8 *) &cap_d->set);
+
+ if (raise == CAP_SET) {
+ cap_p->raise_cap(value);
+ } else {
+ cap_p->lower_cap(value);
+ }
+ }
+ }
+ return 0;
+
+ } else {
+
+ _cap_debug("invalid arguments");
+ errno = EINVAL;
+ return -1;
+
+ }
+}
+
+/*
+ * Reset the capability to be empty (nothing raised)
+ */
+
+int cap_clear(cap_t cap_d)
+{
+ if (good_cap_t(cap_d)) {
+
+ memset(&(cap_d->set), 0, sizeof(cap_d->set));
+ return 0;
+
+ } else {
+
+ _cap_debug("invalid pointer");
+ errno = EINVAL;
+ return -1;
+
+ }
+}
+
+/*
+ * $Log: cap_flag.c,v $
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.3
+log
+@updated for 2.1.104
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_flag.c,v 1.2 1997/04/28 00:57:11 morgan Exp morgan $
+d29 1
+a29 1
+ && set > 0 && set < NUMBER_OF_CAP_SETS) {
+d59 1
+a59 1
+ && (set > 0) && (set < NUMBER_OF_CAP_SETS)
+d110 3
+@
+
+
+1.2
+log
+@fixes and zefram's patches
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_flag.c,v 1.1 1997/04/21 04:32:52 morgan Exp morgan $
+d4 1
+a4 1
+ * Copyright (c) 1997 Andrew G. Morgan <morgan@@parc.power.net>
+d20 2
+a21 2
+int cap_get_flag(cap_t cap_d, cap_value_t value, cap_flag_t set
+ , cap_flag_value_t *raised)
+d28 4
+a31 1
+ if (raised && good_cap_t(cap_d) && value >= 0 && value < __CAP_BITS) {
+d33 1
+a33 1
+ *raised = (cap_d->set[set]._cap_raised(value)) ? CAP_SET:CAP_CLEAR;
+d49 3
+a51 3
+int cap_set_flag(cap_t cap_d, cap_flag_t set
+ , int no_values, cap_value_t *array_values
+ , cap_flag_value_t raise)
+d59 1
+a61 1
+
+d65 10
+a74 4
+ } else if (raise == CAP_SET) {
+ cap_d->set[set]._cap_raise(array_values[i]);
+ } else if (raise == CAP_CLEAR) {
+ cap_d->set[set]._cap_lower(array_values[i]);
+d96 1
+a96 1
+ memset(&(cap_d->set), 0, 3*sizeof(__cap_s));
+d110 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+d28 1
+a28 1
+ if (raised && good_cap_t(cap_d)) {
+d55 1
+a55 1
+ if (good_cap_t(cap_d) && no_values > 0 && no_values < __NR_CAP
+d60 1
+a60 1
+ if (array_values[i] < 0 || array_values[i] >= __NR_CAP) {
+d100 4
+a103 1
+ * $Log$
+@
diff --git a/libcap/RCS/cap_proc.c,v b/libcap/RCS/cap_proc.c,v
new file mode 100644
index 0000000..21a8c40
--- /dev/null
+++ b/libcap/RCS/cap_proc.c,v
@@ -0,0 +1,241 @@
+head 1.5;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.5
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.4;
+
+1.4
+date 97.05.14.05.17.13; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 97.05.04.05.35.46; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.5
+log
+@updated for 2.1.104
+@
+text
+@/*
+ * $Id: cap_proc.c,v 1.4 1997/05/14 05:17:13 morgan Exp morgan $
+ *
+ * Copyright (c) 1997-8 Andrew G Morgan <morgan@@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with setting capabilities on processes.
+ */
+
+#include "libcap.h"
+
+cap_t cap_get_proc(void)
+{
+ cap_t result;
+
+ /* allocate a new capability set */
+ result = cap_init();
+ if (result) {
+ _cap_debug("getting current process' capabilities");
+
+ /* fill the capability sets via a system call */
+ if (capget(&result->head, &result->set)) {
+ cap_free(&result);
+ }
+ }
+
+ return result;
+}
+
+int cap_set_proc(cap_t cap_d)
+{
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("setting process capabilities");
+ return capset(&cap_d->head, &cap_d->set);
+}
+
+/* the following two functions are not required by POSIX */
+
+/* read the caps on a specific process */
+
+int capgetp(pid_t pid, cap_t cap_d)
+{
+ int error;
+
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("getting process capabilities for proc %d", pid);
+
+ cap_d->head.pid = pid;
+ error = capget(&cap_d->head, &cap_d->set);
+ cap_d->head.pid = 0;
+
+ return error;
+}
+
+/* set the caps on a specific process/pg etc.. */
+
+int capsetp(pid_t pid, cap_t cap_d)
+{
+ int error;
+
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("setting process capabilities for proc %d", pid);
+ cap_d->head.pid = pid;
+ error = capset(&cap_d->head, &cap_d->set);
+ cap_d->head.pid = 0;
+
+ return error;
+}
+
+/*
+ * $Log: cap_proc.c,v $
+ * Revision 1.4 1997/05/14 05:17:13 morgan
+ * bug-fix from zefram (errno no set on success)
+ *
+ * Revision 1.3 1997/05/04 05:35:46 morgan
+ * fixed errno setting. syscalls do this part
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.4
+log
+@bug-fix from zefram (errno no set on success)
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_proc.c,v 1.3 1997/05/04 05:35:46 morgan Exp morgan $
+d4 1
+a4 1
+ * Copyright (c) 1997 Andrew G Morgan <morgan@@parc.power.net>
+d23 1
+a23 4
+ if (_getproccap(sizeof(struct __cap_s),
+ &result->set[CAP_INHERITABLE],
+ &result->set[CAP_PERMITTED],
+ &result->set[CAP_EFFECTIVE] ))
+d25 1
+d39 42
+a80 4
+ return _setproccap(sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] );
+d85 3
+@
+
+
+1.3
+log
+@fixed errno setting. syscalls do this part
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_proc.c,v 1.2 1997/04/28 00:57:11 morgan Exp morgan $
+d35 1
+a35 11
+ if (good_cap_t(cap_d)) {
+ _cap_debug("setting current process' capabilities");
+
+ /* fill the capability sets via a system call */
+ if (_setproccap(sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] )) {
+ _cap_debug("failed: %s", strerror(errno));
+ }
+ } else
+d37 2
+d40 5
+a44 1
+ return (errno ? -1:0);
+d49 3
+@
+
+
+1.2
+log
+@fixes and zefram's patches
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_proc.c,v 1.1 1997/04/21 04:32:52 morgan Exp morgan $
+d23 4
+a26 6
+ errno = -_getproccap(sizeof(struct __cap_s),
+ &result->set[CAP_INHERITABLE],
+ &result->set[CAP_PERMITTED],
+ &result->set[CAP_EFFECTIVE] );
+
+ if (errno)
+d39 6
+a44 4
+ errno = -_setproccap(sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] );
+d53 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+d21 1
+d27 3
+d39 1
+d52 4
+a55 1
+ * $Log$
+@
diff --git a/libcap/RCS/cap_sys.c,v b/libcap/RCS/cap_sys.c,v
new file mode 100644
index 0000000..bdd6098
--- /dev/null
+++ b/libcap/RCS/cap_sys.c,v
@@ -0,0 +1,176 @@
+head 1.4;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.4
+date 98.06.08.00.14.01; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.4
+log
+@change to accommodate alpha (glibc?)
+@
+text
+@/*
+ * $Id: cap_sys.c,v 1.3 1998/05/24 22:54:09 morgan Exp morgan $
+ *
+ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@@linux.kernel.org>
+ *
+ * This file contains the system calls for getting and setting
+ * capabilities
+ */
+
+#include "libcap.h"
+#define __LIBRARY__
+#include <linux/unistd.h>
+
+_syscall2(int, capget,
+ cap_user_header_t, header,
+ cap_user_data_t, data)
+
+_syscall2(int, capset,
+ cap_user_header_t, header,
+ const cap_user_data_t, data)
+
+/*
+ * $Log: cap_sys.c,v $
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.3
+log
+@updated for 2.1.104
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_sys.c,v 1.2 1997/04/28 00:57:11 morgan Exp morgan $
+d11 1
+d24 3
+@
+
+
+1.2
+log
+@fixes and zefram's patches
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_sys.c,v 1.1 1997/04/21 04:32:52 morgan Exp morgan $
+d4 1
+a4 1
+ * Copyright (c) 1997 Andrew G. Morgan <morgan@@parc.power.net>
+d13 7
+a19 41
+_syscall4(int, _setproccap,
+ size_t, usize,
+ __cap_s const *, iset,
+ __cap_s const *, pset,
+ __cap_s const *, eset)
+
+_syscall4(int, _getproccap,
+ size_t, usize,
+ __cap_s *, iset,
+ __cap_s *, pset,
+ __cap_s *, eset)
+
+/* Secondly, we have the file capabilities */
+
+_syscall5(int, _setfilecap,
+ char const *, filename,
+ size_t, usize,
+ __cap_s const *, iset,
+ __cap_s const *, pset,
+ __cap_s const *, eset)
+
+_syscall5(int, _getfilecap,
+ char const *, filename,
+ size_t, usize,
+ __cap_s *, iset,
+ __cap_s *, pset,
+ __cap_s *, eset)
+
+_syscall5(int, _fsetfilecap,
+ int, fd,
+ size_t, usize,
+ __cap_s const *, iset,
+ __cap_s const *, pset,
+ __cap_s const *, eset)
+
+_syscall5(int, _fgetfilecap,
+ int, fd,
+ size_t, usize,
+ __cap_s *, iset,
+ __cap_s *, pset,
+ __cap_s *, eset)
+d23 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+d11 1
+d21 3
+a23 3
+ __cap_s const *, iset,
+ __cap_s const *, pset,
+ __cap_s const *, eset)
+d25 1
+a25 1
+/* Secondly, we have the file capabilitiy setting */
+d37 3
+a39 3
+ __cap_s const *, iset,
+ __cap_s const *, pset,
+ __cap_s const *, eset)
+d51 3
+a53 3
+ __cap_s const *, iset,
+ __cap_s const *, pset,
+ __cap_s const *, eset)
+d56 4
+a59 1
+ * $Log$
+@
diff --git a/libcap/RCS/cap_text.c,v b/libcap/RCS/cap_text.c,v
new file mode 100644
index 0000000..d537f75
--- /dev/null
+++ b/libcap/RCS/cap_text.c,v
@@ -0,0 +1,996 @@
+head 1.4;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.4
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 97.05.04.05.37.00; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.4
+log
+@updated for 2.1.104
+@
+text
+@/*
+ * $Id: cap_text.c,v 1.3 1997/05/04 05:37:00 morgan Exp morgan $
+ *
+ * Copyright (c) 1997-8 Andrew G Morgan <morgan@@linux.kernel.org>
+ * Copyright (c) 1997 Andrew Main <zefram@@dcs.warwick.ac.uk>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with exchanging internal and textual
+ * representations of capability sets.
+ */
+
+#define LIBCAP_PLEASE_INCLUDE_ARRAY
+#include "libcap.h"
+
+#include <ctype.h>
+#include <stdio.h>
+
+char *strdup(const char *s);
+
+/* Maximum output text length (16 per cap) */
+#define CAP_TEXT_SIZE (16*__CAP_BITS)
+
+#define LIBCAP_EFF 01
+#define LIBCAP_INH 02
+#define LIBCAP_PER 04
+
+/*
+ * Parse a textual representation of capabilities, returning an internal
+ * representation.
+ */
+
+#define setbits(A,B) _setbits((__cap_s *)A, (__cap_s *)B)
+static void _setbits(__cap_s *a, __cap_s *b)
+{
+ int n;
+ for (n = __CAP_BLKS; n--; )
+ a->_blk[n] |= b->_blk[n];
+}
+
+#define clrbits(A,B) _clrbits((__cap_s *)A, (__cap_s *)B)
+static void _clrbits(__cap_s *a, __cap_s *b)
+{
+ int n;
+ for (n = __CAP_BLKS; n--; )
+ a->_blk[n] &= ~b->_blk[n];
+}
+
+static char const *namcmp(char const *str, char const *nam)
+{
+ while (*nam && tolower((unsigned char)*str) == *nam) {
+ str++;
+ nam++;
+ }
+ if (*nam || isalnum((unsigned char)*str) || *str == '_')
+ return NULL;
+ return str;
+}
+
+static int lookupname(char const **strp)
+{
+ char const *str = *strp;
+ if (isdigit(*str)) {
+ unsigned long n = strtoul(str, (char **)&str, 0);
+ if (n >= __CAP_BITS)
+ return -1;
+ *strp = str;
+ return n;
+ } else {
+ char const *s;
+ int n;
+ for (n = __CAP_BITS; n--; )
+ if (_cap_names[n] && (s = namcmp(str, _cap_names[n]))) {
+ *strp = s;
+ return n;
+ }
+ return -1;
+ }
+}
+
+cap_t cap_from_text(const char *str)
+{
+ cap_t res;
+ __cap_s allones;
+ int n;
+
+ if (str == NULL) {
+ _cap_debug("bad argument");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (!(res = cap_init()))
+ return NULL;
+ for (n = __CAP_BLKS; n--; )
+ allones._blk[n] = -1;
+ _cap_debug("%s", str);
+
+ for (;;) {
+ char op;
+ int flags = 0, listed=0;
+ __cap_s list = {{0}};
+
+ /* skip leading spaces */
+ while (isspace((unsigned char)*str))
+ str++;
+ if (!*str) {
+ _cap_debugcap("e = ", &res->set.effective);
+ _cap_debugcap("i = ", &res->set.inheritable);
+ _cap_debugcap("p = ", &res->set.permitted);
+ return res;
+ }
+
+ /* identify caps specified by this clause */
+ if (isalnum((unsigned char)*str) || *str == '_') {
+ for (;;) {
+ if (namcmp(str, "all")) {
+ str += 3;
+ list = allones;
+ } else {
+ n = lookupname(&str);
+ if (n == -1)
+ goto bad;
+ list.raise_cap(n);
+ }
+ if (*str != ',')
+ break;
+ if (!isalnum((unsigned char)*++str) && *str != '_')
+ goto bad;
+ }
+ listed = 1;
+ } else if (*str == '+' || *str == '-')
+ goto bad; /* require a list of capabilities */
+ else
+ list = allones;
+
+ /* identify first operation on list of capabilities */
+ op = *str++;
+ if (op == '=' && (*str == '+' || *str == '-')) {
+ if (!listed)
+ goto bad;
+ op = (*str++ == '+' ? 'P':'M'); /* skip '=' and take next op */
+ } else if (op != '+' && op != '-' && op != '=')
+ goto bad;
+
+ /* cycle through list of actions */
+ do {
+ _cap_debug("next char = `%c'", *str);
+ if (*str && !isspace(*str)) {
+ switch (*str++) { /* Effective, Inheritable, Permitted */
+ case 'e':
+ flags |= LIBCAP_EFF;
+ break;
+ case 'i':
+ flags |= LIBCAP_INH;
+ break;
+ case 'p':
+ flags |= LIBCAP_PER;
+ break;
+ default:
+ goto bad;
+ }
+ } else if (op != '=') {
+ _cap_debug("only '=' can be followed by space");
+ goto bad;
+ }
+
+ _cap_debug("how to read?");
+ switch (op) { /* how do we interpret the caps? */
+ case '=':
+ case 'P': /* =+ */
+ case 'M': /* =- */
+ clrbits(&res->set.effective, &list);
+ clrbits(&res->set.inheritable, &list);
+ clrbits(&res->set.permitted, &list);
+ /* fall through */
+ if (op == 'M')
+ goto minus;
+ case '+':
+ if (flags & LIBCAP_EFF)
+ setbits(&res->set.effective, &list);
+ if (flags & LIBCAP_INH)
+ setbits(&res->set.inheritable, &list);
+ if (flags & LIBCAP_PER)
+ setbits(&res->set.permitted, &list);
+ break;
+ case '-':
+ minus:
+ if (flags & LIBCAP_EFF)
+ clrbits(&res->set.effective, &list);
+ if (flags & LIBCAP_INH)
+ clrbits(&res->set.inheritable, &list);
+ if (flags & LIBCAP_PER)
+ clrbits(&res->set.permitted, &list);
+ break;
+ }
+
+ /* new directive? */
+ if (*str == '+' || *str == '-') {
+ if (!listed) {
+ _cap_debug("for + & - must list capabilities");
+ goto bad;
+ }
+ flags = 0; /* reset the flags */
+ op = *str++;
+ if (!isalpha(*str))
+ goto bad;
+ }
+ } while (*str && !isspace(*str));
+ _cap_debug("next clause");
+ }
+
+bad:
+ cap_free(&res);
+ errno = EINVAL;
+ return NULL;
+}
+
+/*
+ * Convert an internal representation to a textual one. The textual
+ * representation is stored in static memory. It will be overwritten
+ * on the next occasion that this function is called.
+ */
+
+static int getstateflags(cap_t caps, int capno)
+{
+ int f = 0;
+
+ if (isset_cap((__cap_s *)(&caps->set.effective),capno))
+ f |= LIBCAP_EFF;
+ if (isset_cap((__cap_s *)(&caps->set.inheritable),capno))
+ f |= LIBCAP_INH;
+ if (isset_cap((__cap_s *)(&caps->set.permitted),capno))
+ f |= LIBCAP_PER;
+
+ return f;
+}
+
+#define CAP_TEXT_BUFFER_ZONE 100
+
+char *cap_to_text(cap_t caps, ssize_t *length_p)
+{
+ static char buf[CAP_TEXT_SIZE+CAP_TEXT_BUFFER_ZONE];
+ char *p;
+ int histo[8] = {0};
+ int m, n, t;
+
+ /* Check arguments */
+ if (!good_cap_t(caps) || length_p == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ _cap_debugcap("e = ", &caps->set.effective);
+ _cap_debugcap("i = ", &caps->set.inheritable);
+ _cap_debugcap("p = ", &caps->set.permitted);
+
+ for (n = __CAP_BITS; n--; )
+ histo[getstateflags(caps, n)]++;
+
+ for (m=t=7; t--; )
+ if (histo[t] > histo[m])
+ m = t;
+
+ /* blank is not a valid capability set */
+ p = sprintf(buf, "=%s%s%s",
+ (m & LIBCAP_EFF) ? "e" : "",
+ (m & LIBCAP_INH) ? "i" : "",
+ (m & LIBCAP_PER) ? "p" : "" ) + buf;
+
+ for (t = 8; t--; )
+ if (t != m && histo[t]) {
+ *p++ = ' ';
+ for (n = 0; n != __CAP_BITS; n++)
+ if (getstateflags(caps, n) == t) {
+ if (_cap_names[n])
+ p += sprintf(p, "%s,", _cap_names[n]);
+ else
+ p += sprintf(p, "%d,", n);
+ if (p - buf > CAP_TEXT_SIZE) {
+ errno = ERANGE;
+ return NULL;
+ }
+ }
+ p--;
+ n = t & ~m;
+ if (n)
+ p += sprintf(p, "+%s%s%s",
+ (n & LIBCAP_EFF) ? "e" : "",
+ (n & LIBCAP_INH) ? "i" : "",
+ (n & LIBCAP_PER) ? "p" : "");
+ n = ~t & m;
+ if (n)
+ p += sprintf(p, "-%s%s%s",
+ (n & LIBCAP_EFF) ? "e" : "",
+ (n & LIBCAP_INH) ? "i" : "",
+ (n & LIBCAP_PER) ? "p" : "");
+ if (p - buf > CAP_TEXT_SIZE) {
+ errno = ERANGE;
+ return NULL;
+ }
+ }
+
+ _cap_debug("%s", buf);
+ *length_p = p - buf;
+ return (strdup(buf));
+}
+
+/*
+ * $Log: cap_text.c,v $
+ * Revision 1.3 1997/05/04 05:37:00 morgan
+ * case sensitvity to capability flags
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * zefram's replacement file with a number of bug fixes from AGM
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.3
+log
+@case sensitvity to capability flags
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_text.c,v 1.2 1997/04/28 00:57:11 morgan Exp morgan $
+d4 1
+a4 1
+ * Copyright (c) 1997 Andrew G Morgan <morgan@@parc.power.net>
+d13 1
+d19 2
+d33 2
+a34 1
+static void setbits(__cap_s *a, __cap_s *b)
+d41 2
+a42 1
+static void clrbits(__cap_s *a, __cap_s *b)
+d108 3
+a110 3
+ _cap_debugcap("e = ", &res->set[CAP_EFFECTIVE]);
+ _cap_debugcap("i = ", &res->set[CAP_INHERITABLE]);
+ _cap_debugcap("p = ", &res->set[CAP_PERMITTED]);
+d124 1
+a124 1
+ list._cap_raise(n);
+d173 3
+a175 3
+ clrbits(&res->set[CAP_EFFECTIVE], &list);
+ clrbits(&res->set[CAP_INHERITABLE], &list);
+ clrbits(&res->set[CAP_PERMITTED], &list);
+d181 1
+a181 1
+ setbits(&res->set[CAP_EFFECTIVE], &list);
+d183 1
+a183 1
+ setbits(&res->set[CAP_INHERITABLE], &list);
+d185 1
+a185 1
+ setbits(&res->set[CAP_PERMITTED], &list);
+d190 1
+a190 1
+ clrbits(&res->set[CAP_EFFECTIVE], &list);
+d192 1
+a192 1
+ clrbits(&res->set[CAP_INHERITABLE], &list);
+d194 1
+a194 1
+ clrbits(&res->set[CAP_PERMITTED], &list);
+d229 1
+a229 1
+ if (caps->set[CAP_EFFECTIVE]._cap_raised(capno))
+d231 1
+a231 1
+ if (caps->set[CAP_INHERITABLE]._cap_raised(capno))
+d233 1
+a233 1
+ if (caps->set[CAP_PERMITTED]._cap_raised(capno))
+d254 3
+a256 3
+ _cap_debugcap("e = ", &caps->set[CAP_EFFECTIVE]);
+ _cap_debugcap("i = ", &caps->set[CAP_INHERITABLE]);
+ _cap_debugcap("p = ", &caps->set[CAP_PERMITTED]);
+d306 1
+a306 1
+ return buf;
+d311 3
+@
+
+
+1.2
+log
+@zefram's replacement file with a number of bug fixes from AGM
+@
+text
+@d2 1
+a2 1
+ * $Id: cap_text.c,v 1.1 1997/04/21 04:32:52 morgan Exp morgan $
+a146 1
+ case 'E':
+a149 1
+ case 'I':
+a152 1
+ case 'P':
+d306 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+d5 1
+d16 1
+d18 2
+a19 64
+/*
+ * Some static data:
+ */
+
+/* A place to store the capability names */
+static const char * cap_text[__CAP_BITS] = {
+
+/*
+ * POSIX capabilities
+ */
+
+/* CAP_CHOWN (0) */ "cap_chown",
+/* CAP_DAC_OVERRIDE */ "cap_dac_override",
+/* CAP_DAC_READ_SEARCH */ "cap_dac_read_search",
+/* CAP_FOWNER */ "cap_fowner",
+/* CAP_FSETID */ "cap_fsetid",
+/* CAP_KILL (5) */ "cap_kill",
+/* CAP_LINK_DIR */ "cap_link_dir",
+/* CAP_SETFCAP */ "cap_setfcap",
+/* CAP_SETGID */ "cap_setgid",
+/* CAP_SETUID */ "cap_setuid",
+/* CAP_SIGMASK (10) */ "cap_sigmask",
+
+/* CAP_MAC_DOWNGRADE (11) */ "cap_mac_downgrade",
+/* CAP_MAC_READ */ "cap_mac_read",
+/* CAP_MAC_RELABEL_SUB */ "cap_mac_relabel_sub",
+/* CAP_MAC_UPGRADE */ "cap_mac_upgrade",
+/* CAP_MAC_WRITE */ "cap_mac_write",
+
+/* CAP_INF_NOFLOAT_OBJ (16) */ "cap_inf_nofloat_obj",
+/* CAP_INF_NOFLOAT_SUB */ "cap_inf_nofloat_lab",
+/* CAP_INF_RELABEL_OBJ */ "cap_inf_relabel_obj",
+/* CAP_INF_RELABEL_SUB */ "cap_inf_relabel_sub",
+
+/* CAP_AUDIT_CONTROL (20) */ "cap_audit_control",
+/* CAP_AUDIT_WRITE */ "cap_audit_write",
+
+/* (22) reserved for POSIX */ NULL,
+/* (23) reserved for POSIX */ NULL,
+/* (24) reserved for POSIX */ NULL,
+/* (25) reserved for POSIX */ NULL,
+/* (26) reserved for POSIX */ NULL,
+/* (27) reserved for POSIX */ NULL,
+/* (28) reserved for POSIX */ NULL,
+/* (29) reserved for POSIX */ NULL,
+/* (30) reserved for POSIX */ NULL,
+/* (31) reserved for POSIX */ NULL,
+
+/*
+ * Linux-specific capabilities
+ */
+
+/* CAP_LINUX_IMMUTABLE (32) */ "cap_linux_immutable",
+/* CAP_LINUX_KERNELD */ "cap_linux_kerneld",
+/* CAP_LINUX_INSMOD */ "cap_linux_insmod",
+/* CAP_LINUX_RMMOD */ "cap_linux_rmmod",
+/* CAP_LINUX_RAWIO */ "cap_linux_rawio",
+/* CAP_LINUX_ATTENTION */ "cap_linux_attention",
+/* CAP_LINUX_RANDOM */ "cap_linux_random",
+
+/*
+ * Others.. A number of others have been defined; they do not belong
+ * to Linux or POSIX. [Subject to change].
+ */
+d21 3
+a23 24
+/* CAP_NET_BIND_SERVICE (39) */ "cap_net_bind_service",
+/* CAP_NET_BROADCAST */ "cap_net_broadcast",
+/* CAP_NET_DEBUG */ "cap_net_debug",
+/* CAP_NET_FIREWALL */ "cap_net_firewall",
+/* CAP_NET_IFCONFIG */ "cap_net_ifconfig",
+/* CAP_NET_PACKET */ "cap_net_packet",
+/* CAP_NET_RAW (45) */ "cap_net_raw",
+/* CAP_NET_ROUTE */ "cap_net_route",
+/* CAP_NET_SETID */ "cap_net_setid",
+/* CAP_IPC_LOCK */ "cap_ipc_lock",
+/* CAP_IPC_OWNER */ "cap_ipc_owner",
+/* CAP_SYS_CHROOT (50) */ "cap_sys_chroot",
+/* CAP_SYS_PTRACE */ "cap_sys_ptrace",
+/* CAP_SYS_ACCOUNT */ "cap_sys_account",
+/* CAP_SYS_ADMIN */ "cap_sys_admin",
+/* CAP_SYS_BOOT */ "cap_sys_boot",
+/* CAP_SYS_DEVICES (55) */ "cap_sys_devices",
+/* CAP_SYS_NICE */ "cap_sys_nice",
+/* CAP_SYS_RESOURCE */ "cap_sys_resource",
+/* CAP_SYS_TIME */ "cap_sys_time",
+/* CAP_SYS_TTY_CONFIG */ "cap_sys_tty_config",
+/* CAP_SYS_QUOTA (60) */ "cap_sys_quota",
+
+};
+d26 2
+a27 1
+ * static parsing routines
+d30 1
+a30 6
+/*
+ * Caseless string comparison
+ */
+
+/* caseless string comparison: POSIX does not define this.. */
+static int _strCMP(const char *s, const char *t)
+d32 3
+a34 8
+ int cf;
+
+ do {
+ cf = tolower(*s) - tolower(*t);
+ ++t;
+ } while (!cf && *s++);
+
+ return cf;
+d37 1
+a37 21
+/*
+ * Locate character (c) in an array of characters (array)
+ */
+
+static int _cap_inarray(char c, const char * array)
+{
+ int i;
+
+ for (i=0; *array; ++array, ++i) {
+ if (c == *array)
+ return i;
+ }
+
+ return -1;
+}
+
+/*
+ * Locate a token (tok) in an capability array
+ */
+
+static int _cap_find_token(const char * const tok)
+d39 3
+a41 9
+ int i;
+
+ for (i=0; i<__CAP_BITS; ++i) {
+ if (cap_text[i] && !_strCMP(cap_text[i], tok)) {
+ _cap_debug("located [%s]=%d", cap_text[i], i);
+ return i;
+ }
+ }
+ return -1;
+d44 1
+a44 5
+/*
+ * This function copies the next clause (returning NULL at end)
+ */
+
+static const char *_cap_get_clause(const char *from, char **to)
+d46 3
+a48 6
+ const char *begin;
+
+ /* forget last value */
+ if (*to) {
+ free(*to);
+ *to = NULL;
+d50 1
+a50 3
+
+ /* verify that we have something to search */
+ if (from == NULL) {
+d52 1
+a52 26
+ }
+
+ /* skip leading spaces */
+ for (; *from && isspace(*from); ++from);
+
+ /* do we have a clause? */
+ if (*from) {
+ int length;
+
+ /* Skip to next space */
+ for (begin = from; *from && !isspace(*from); ++from);
+
+ length = from - begin;
+ *to = malloc(1 + length);
+ if (*to == NULL) {
+ _cap_debug("out of memory");
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ /* copy clause */
+ memcpy(*to, begin, length);
+ (*to)[length] = '\0';
+ }
+
+ return (*from ? from:NULL);
+d55 1
+a55 8
+/*
+ * Read comma separated capabilities and set them in the argument capability
+ * set.
+ */
+
+static const char * const op_list = "=+-";
+
+static char *_cap_parse_caps(char *temp, __cap_s *caps)
+d57 7
+a63 21
+ char *ops, saved;
+ const char *tok;
+
+ if (temp == NULL) {
+ _cap_debug("no capabilities provided");
+ return NULL;
+ }
+
+ /* find first non-capability char (=+-) and save for later writeback */
+ for (ops=temp; (saved=*ops) && _cap_inarray(saved, op_list) < 0; ++ops);
+ *ops = '\0';
+
+ /* loop through tokens looking up each capability and raising it in caps */
+ if (!_strCMP("all", temp)) {
+ int i;
+
+ /* A little slow but this way we only raise defined capabilities */
+ for (i=0; i<__CAP_BITS; ++i) {
+ if (cap_text[i])
+ caps->_cap_raise(i);
+ }
+d65 6
+a70 11
+ /* break string into tokens */
+ while ((tok = strtok(temp, ","))) {
+ int cap;
+
+ temp = NULL;
+
+ cap = _cap_find_token(tok);
+ if (cap == -1) {
+ _cap_debug("tok=[%s] is not known - ignoring it", tok);
+ } else {
+ caps->_cap_raise(cap);
+d72 1
+a72 22
+ }
+ }
+
+ /* writeback first operator char */
+ *ops = saved;
+
+ /* return operator list */
+ return ops;
+}
+
+/*
+ * read the operator list and set the internal flags accordingly
+ */
+
+static struct __cap_s cap_purge(const struct __cap_s *a,
+ const struct __cap_s *b)
+{
+ struct __cap_s result;
+ register i;
+
+ for (i=0; i<__CAP_BLKS; ++i) {
+ result._blk[i] = a->_blk[i] & ~b->_blk[i];
+a73 1
+ return result;
+d76 1
+a76 2
+static struct __cap_s cap_union(const struct __cap_s *a,
+ const struct __cap_s *b)
+d78 3
+a80 2
+ struct __cap_s result;
+ register i;
+d82 4
+a85 2
+ for (i=0; i<__CAP_BLKS; ++i) {
+ result._blk[i] = a->_blk[i] | b->_blk[i];
+a86 2
+ return result;
+}
+d88 20
+a107 3
+#define _LIBCAP_EQ 01
+#define _LIBCAP_PL 02
+#define _LIBCAP_MI 03
+d109 16
+a124 38
+static void _cap_parse_ops(char *temp, __cap_s *caps, cap_t cap_d)
+{
+ unsigned int state=0;
+ char c;
+
+ while ((c = *temp++)) {
+ int op;
+
+ /* Is this an operator? */
+ if ((op = _cap_inarray(c, op_list)) >= 0) {
+ c = '\0';
+ state = 1+op;
+ if (*temp && _cap_inarray(*temp, op_list) < 0)
+ continue;
+ /* Fall through for immediate action */
+ }
+ switch (c) {
+ case '\0':
+ switch ((state & 03)) {
+ case _LIBCAP_EQ:
+ memset(&(cap_d->set), 0, 3*sizeof(__cap_s));
+ break;
+ case _LIBCAP_PL:
+ cap_d->set[CAP_EFFECTIVE]
+ = cap_union(&cap_d->set[CAP_EFFECTIVE], caps);
+ cap_d->set[CAP_INHERITABLE]
+ = cap_union(&cap_d->set[CAP_EFFECTIVE], caps);
+ cap_d->set[CAP_PERMITTED]
+ = cap_union(&cap_d->set[CAP_EFFECTIVE], caps);
+ break;
+ case _LIBCAP_MI:
+ cap_d->set[CAP_EFFECTIVE]
+ = cap_purge(&cap_d->set[CAP_EFFECTIVE], caps);
+ cap_d->set[CAP_INHERITABLE]
+ = cap_purge(&cap_d->set[CAP_EFFECTIVE], caps);
+ cap_d->set[CAP_PERMITTED]
+ = cap_purge(&cap_d->set[CAP_EFFECTIVE], caps);
+ break;
+d126 38
+a163 15
+ break;
+ case 'e':
+ case 'E': /* set effective caps */
+ switch ((state & 03)) {
+ case _LIBCAP_EQ:
+ memset(&(cap_d->set[CAP_EFFECTIVE]), 0, sizeof(__cap_s));
+ break;
+ case _LIBCAP_PL:
+ cap_d->set[CAP_EFFECTIVE]
+ = cap_union(&cap_d->set[CAP_EFFECTIVE], caps);
+ break;
+ case _LIBCAP_MI:
+ cap_d->set[CAP_EFFECTIVE]
+ = cap_purge(&cap_d->set[CAP_EFFECTIVE], caps);
+ break;
+d165 28
+a192 14
+ break;
+ case 'i':
+ case 'I':
+ switch ((state & 03)) {
+ case _LIBCAP_EQ:
+ memset(&(cap_d->set[CAP_INHERITABLE]), 0, sizeof(__cap_s));
+ break;
+ case _LIBCAP_PL:
+ cap_d->set[CAP_INHERITABLE]
+ = cap_union(&cap_d->set[CAP_INHERITABLE], caps);
+ break;
+ case _LIBCAP_MI:
+ cap_d->set[CAP_INHERITABLE]
+ = cap_purge(&cap_d->set[CAP_INHERITABLE], caps);
+d195 11
+a205 15
+ break;
+ case 'p':
+ case 'P':
+ switch ((state & 03)) {
+ case _LIBCAP_EQ:
+ memset(&(cap_d->set[CAP_PERMITTED]), 0, sizeof(__cap_s));
+ break;
+ case _LIBCAP_PL:
+ cap_d->set[CAP_PERMITTED]
+ = cap_union(&cap_d->set[CAP_PERMITTED], caps);
+ break;
+ case _LIBCAP_MI:
+ cap_d->set[CAP_PERMITTED]
+ = cap_purge(&cap_d->set[CAP_PERMITTED], caps);
+ break;
+d207 2
+a208 4
+ break;
+ default:
+ _cap_debug("[%c] is ignored", c);
+ }
+d210 5
+d218 3
+a220 1
+ * Convert a textual representation to a capability set.
+d223 1
+a223 1
+cap_t cap_from_text(const char *verbose)
+d225 1
+a225 29
+ char *clause=NULL;
+ cap_t cap_d;
+
+ cap_d = cap_init();
+ if (cap_d == NULL) {
+ _cap_debug("out of memory");
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ /* Loop through clauses */
+ while ((verbose = _cap_get_clause(verbose, &clause))) {
+ struct __cap_s capabilities;
+ char *temp = clause;
+
+ /* reset local capability set */
+ memset(&capabilities, 0, sizeof(capabilities));
+
+ /* spin through capabilities listed in this clause */
+ temp = _cap_parse_caps(temp, &capabilities);
+ if (temp) {
+ /* spin through list of operators? */
+ _cap_parse_ops(temp, &capabilities, cap_d);
+ }
+ }
+
+ /* return the capability set */
+ return cap_d;
+}
+d227 6
+a232 4
+static int count_bits(struct __cap_s *cap)
+{
+ register int i,count=0;
+ register __u32 block=0;
+d234 1
+a234 6
+ for (i=0; i<__CAP_BLKS; ++i) {
+ for (block = cap->_blk[i]; block; block >>= 1) {
+ count += (block&1);
+ }
+ }
+ return count;
+a236 10
+/*
+ * Convert an internal representation to a textual one. The textual
+ * representation is stored in static memory. It will be overwritten
+ * on the next occasion that this function is called.
+ */
+
+#define _LIBCAP_EFF 01
+#define _LIBCAP_INH 02
+#define _LIBCAP_PER 04
+
+d239 1
+a239 1
+char *cap_to_text(cap_t cap_d, ssize_t *length_p)
+a240 2
+ int mone, moni, monp;
+ unsigned int persist;
+d242 3
+a244 1
+ int length, i;
+d247 1
+a247 1
+ if (!good_cap_t(cap_d) || length_p == NULL) {
+d252 30
+a281 44
+ mone = (count_bits(&cap_d->set[CAP_EFFECTIVE]) > 16) ? 1:0;
+ moni = (count_bits(&cap_d->set[CAP_INHERITABLE]) > 16) ? 1:0;
+ monp = (count_bits(&cap_d->set[CAP_PERMITTED]) > 16) ? 1:0;
+
+ *length_p = 0;
+ length = sprintf(buf, "all%se%si%sp\n",
+ mone ? "+":"-",
+ moni ? "+":"-",
+ monp ? "+":"-" );
+
+ /* loop through clustering together all caps that are stored in
+ the same selection of sets.. */
+ for (persist=0, i=0; i<=__CAP_BITS; ++i) {
+ unsigned int this=0;
+
+ /* Which have this capability set? */
+ if (i != __CAP_BITS) {
+ if ((!mone && cap_d->set[CAP_EFFECTIVE]._cap_raised(i))
+ || (mone && !cap_d->set[CAP_EFFECTIVE]._cap_raised(i)))
+ this |= _LIBCAP_EFF;
+ if ((!moni && cap_d->set[CAP_INHERITABLE]._cap_raised(i))
+ || (moni && !cap_d->set[CAP_INHERITABLE]._cap_raised(i)))
+ this |= _LIBCAP_INH;
+ if ((!monp && cap_d->set[CAP_PERMITTED]._cap_raised(i))
+ || (monp && !cap_d->set[CAP_PERMITTED]._cap_raised(i)))
+ this |= _LIBCAP_PER;
+ } else
+ this = ~0;
+
+ /* should we include this capability? */
+ if (this) {
+ if (persist && (i == __CAP_BITS || this != persist)) {
+ /* write out actionlist for persistent caps */
+ length += sprintf(length+buf, "%s%s%s\n"
+ , (persist & _LIBCAP_EFF) ?
+ (mone?"-e":"+e"):""
+ , (persist & _LIBCAP_INH) ?
+ (moni?"-i":"+i"):""
+ , (persist & _LIBCAP_PER) ?
+ (monp?"-p":"+p"):""
+ );
+ if (length > CAP_TEXT_SIZE) {
+ errno = ERANGE;
+ return NULL;
+d283 14
+a296 15
+ persist=0;
+ }
+ if (i == __CAP_BITS) {
+ /* All done */
+ break;
+ }
+
+ if (cap_text[i]) {
+ length += sprintf(length+buf, "%s%s", persist? ",":""
+ , cap_text[i]);
+ } else {
+ _cap_debug("cap [%d] not defined but is set!?", i);
+ length += sprintf(length+buf, "%s(%d)", persist?",":"", i);
+ }
+ if (length > CAP_TEXT_SIZE) {
+a299 3
+
+ /* we may have a new persistent combination */
+ persist = this;
+a300 3
+ }
+
+ /* return text */
+d302 2
+a303 1
+ *length_p = strlen(buf);
+d308 4
+a311 1
+ * $Log$
+@
diff --git a/libcap/RCS/libcap.h,v b/libcap/RCS/libcap.h,v
new file mode 100644
index 0000000..dc70111
--- /dev/null
+++ b/libcap/RCS/libcap.h,v
@@ -0,0 +1,287 @@
+head 1.5;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.5
+date 98.06.08.00.15.28; author morgan; state Exp;
+branches;
+next 1.4;
+
+1.4
+date 98.06.07.15.58.23; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 98.05.24.22.54.09; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.57.11; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.5
+log
+@accommodate alpha (glibc?)
+@
+text
+@/*
+ * $Id: libcap.h,v 1.4 1998/06/07 15:58:23 morgan Exp morgan $
+ *
+ * Copyright (c) 1997 Andrew G Morgan <morgan@@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file contains internal definitions for the various functions in
+ * this small capability library.
+ */
+
+#ifndef LIBCAP_H
+#define LIBCAP_H
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/capability.h>
+
+/* include the names for the caps and a definition of __CAP_BITS */
+#include "cap_names.h"
+
+/*
+ * This is a pointer to a struct containing three consecutive
+ * capability sets in the order of the cap_flag_t type: the are
+ * effective,inheritable and permitted. This is the type that the
+ * user-space routines think of as 'internal' capabilities - this is
+ * the type that is passed to the kernel with the system calls related
+ * to processes.
+ */
+
+#define CAP_T_MAGIC 0xCA90D0
+struct _cap_struct {
+ int magic;
+ struct __user_cap_header_struct head;
+ struct __user_cap_data_struct set;
+};
+
+/*
+ * Do we match the local kernel?
+ */
+
+#if !defined(_LINUX_CAPABILITY_VERSION) || \
+ (_LINUX_CAPABILITY_VERSION != 0x19980330)
+
+# error "Kernel <linux/capability.h> does not match library"
+# error "file "libcap.h" --> fix and recompile libcap"
+
+#endif
+
+/*
+ * kernel API cap set abstraction
+ */
+
+#define NUMBER_OF_CAP_SETS 3 /* effective, inheritable, permitted */
+#define CAP_SET_SIZE (sizeof(struct __user_cap_data_struct)/NUMBER_OF_CAP_SETS)
+#define __CAP_BLKS (CAP_SET_SIZE/sizeof(__u32))
+typedef struct {
+ __u32 _blk[__CAP_BLKS];
+} __cap_s;
+#define raise_cap(x) _blk[(x)>>5] |= (1<<((x)&31))
+#define lower_cap(x) _blk[(x)>>5] |= (1<<((x)&31))
+#define isset_cap(y,x) ((y)->_blk[(x)>>5] & (1<<((x)&31)))
+
+/*
+ * Private definitions for internal use by the library.
+ */
+
+#define good_cap_t(c) ((c) && (c)->magic == CAP_T_MAGIC)
+
+/*
+ * library debugging
+ */
+#ifdef DEBUG
+
+#include <stdio.h>
+# define _cap_debug(f, x...) { \
+ fprintf(stderr, __FUNCTION__ "(" __FILE__ ":%d): ", __LINE__); \
+ fprintf(stderr, f, ## x); \
+ fprintf(stderr, "\n"); \
+}
+# define _cap_debugcap(s, c) \
+ fprintf(stderr, __FUNCTION__ "(" __FILE__ ":%d): " s \
+ "%08x\n", __LINE__, c)
+
+#else /* !DEBUG */
+
+# define _cap_debug(f, x...)
+# define _cap_debugcap(s, c)
+
+#endif /* DEBUG */
+
+/*
+ * These are semi-public prototypes, they will only be defined in
+ * <sys/capability.h> if _POSIX_SOURCE is not #define'd, so we
+ * place them here too.
+ */
+
+extern int capset(cap_user_header_t header, cap_user_data_t data);
+extern int capget(cap_user_header_t header, const cap_user_data_t data);
+extern int capgetp(pid_t pid, cap_t cap_d);
+extern int capsetp(pid_t pid, cap_t cap_d);
+
+#endif /* LIBCAP_H */
+
+/*
+ * $Log: libcap.h,v $
+ * Revision 1.4 1998/06/07 15:58:23 morgan
+ * accommodate real kernel header files :*)
+ *
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * zefram's replacement file with a number of bug fixes from AGM
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.4
+log
+@accommodate real kernel header files :*)
+@
+text
+@d2 1
+a2 1
+ * $Id: libcap.h,v 1.3 1998/05/24 22:54:09 morgan Exp morgan $
+d15 1
+d110 3
+@
+
+
+1.3
+log
+@updated for 2.1.104
+@
+text
+@d2 1
+a2 1
+ * $Id: libcap.h,v 1.2 1997/04/28 00:57:11 morgan Exp morgan $
+d36 2
+a37 2
+ struct _user_cap_header_struct head;
+ struct _user_cap_data_struct set;
+d57 1
+a57 1
+#define CAP_SET_SIZE (sizeof(struct _user_cap_data_struct)/NUMBER_OF_CAP_SETS)
+d109 3
+@
+
+
+1.2
+log
+@zefram's replacement file with a number of bug fixes from AGM
+@
+text
+@d2 1
+a2 1
+ * $Id: libcap.h,v 1.1 1997/04/21 04:32:52 morgan Exp morgan $
+d4 1
+a4 1
+ * Copyright (c) 1997 Andrew G Morgan <morgan@@parc.power.net>
+d21 3
+d36 2
+a37 1
+ struct __cap_s set[3];
+d45 1
+a45 1
+ (_LINUX_CAPABILITY_VERSION != 0x19970420)
+d53 14
+d85 1
+a85 2
+ "%08x %08x %08x %08x\n", __LINE__, \
+ (c)->_blk[0], (c)->_blk[1], (c)->_blk[2], (c)->_blk[3])
+d100 4
+a103 10
+int _setproccap(size_t, __cap_s const *,__cap_s const *, __cap_s const *);
+int _getproccap(size_t, __cap_s *,__cap_s *, __cap_s *);
+int _setfilecap(char const *, size_t, __cap_s const *,
+ __cap_s const *, __cap_s const *);
+int _getfilecap(char const *, size_t, __cap_s *, __cap_s *, __cap_s *);
+int _fsetfilecap(int, size_t, __cap_s const *,
+ __cap_s const *, __cap_s const *);
+int _fgetfilecap(int, size_t, __cap_s *, __cap_s *, __cap_s *);
+
+extern char const *_cap_names[__CAP_BITS];
+d109 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+d19 1
+a19 2
+
+#include <linux/capability.h>
+d22 1
+a22 1
+ * This is a pointer to an struct containing three consecutive
+a47 8
+#include <sys/capability.h>
+
+/*
+ * System calls
+ */
+
+#include <linux/unistd.h>
+
+d63 1
+a63 1
+ fprintf(stderr, "\n");
+d65 4
+d73 1
+d77 5
+a81 2
+/* These are semi-public prototypes -- perhaps they should be moved to
+ <sys/capability.h> ? */
+d84 1
+a84 1
+int _getproccap(size_t, __cap_s const *,__cap_s const *, __cap_s const *);
+d87 1
+a87 2
+int _getfilecap(char const *, size_t, __cap_s const *,
+ __cap_s const *, __cap_s const *);
+d90 3
+a92 2
+int _fgetfilecap(int, size_t, __cap_s const *,
+ __cap_s const *, __cap_s const *);
+d97 4
+a100 1
+ * $Log$
+@
diff --git a/libcap/_makenames.c b/libcap/_makenames.c
new file mode 100644
index 0000000..5ef7192
--- /dev/null
+++ b/libcap/_makenames.c
@@ -0,0 +1,79 @@
+/*
+ * $Id: _makenames.c,v 1.4 1998/06/07 15:50:12 morgan Exp $
+ *
+ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@linux.kernel.org>
+ *
+ * This is a file to make the capability <-> string mappings for
+ * libcap.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <linux/capability.h>
+
+/*
+ * #include 'sed' generated array
+ */
+
+struct {
+ int index;
+ const char *name;
+} const list[] = {
+#include "cap_names.sed"
+ {-1, NULL}
+};
+
+/* this should be more than big enough (factor of three at least) */
+const char *pointers[8*sizeof(struct __user_cap_data_struct)];
+
+int main(void)
+{
+ int i, maxcaps=0;
+
+ for ( i=0; list[i].index >= 0 && list[i].name; ++i ) {
+ if (maxcaps < list[i].index) {
+ maxcaps = list[i].index;
+ }
+ pointers[list[i].index] = list[i].name;
+ }
+
+ printf("/*\n"
+ " * DO NOT EDIT: this file is generated automatically from\n"
+ " *\n"
+ " * <linux/capability.h>\n"
+ " */\n"
+ "#define __CAP_BITS %d\n"
+ "\n"
+ "#ifdef LIBCAP_PLEASE_INCLUDE_ARRAY\n"
+ " char const *_cap_names[__CAP_BITS] = {\n", maxcaps);
+
+ for (i=0; i<maxcaps; ++i) {
+ if (pointers[i])
+ printf(" /* %d */\t\"%s\",\n", i, pointers[i]);
+ else
+ printf(" /* %d */\tNULL,\t\t/* - presently unused */\n", i);
+ }
+
+ printf(" };\n"
+ "#endif /* LIBCAP_PLEASE_INCLUDE_ARRAY */\n"
+ "\n"
+ "/* END OF FILE */\n");
+
+ exit(0);
+}
+
+/*
+ * $Log: _makenames.c,v $
+ * Revision 1.4 1998/06/07 15:50:12 morgan
+ * updated to accommodate kernel's real header file :*)
+ *
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/05/04 05:35:46 morgan
+ * cleaned up to #include sed output. also generates whole cap_names.c file
+ *
+ * Revision 1.1 1997/04/28 00:57:11 morgan
+ * Initial revision
+ *
+ */
diff --git a/libcap/cap_alloc.c b/libcap/cap_alloc.c
new file mode 100644
index 0000000..3d9e7ab
--- /dev/null
+++ b/libcap/cap_alloc.c
@@ -0,0 +1,90 @@
+/*
+ * $Id: cap_alloc.c,v 1.3 1998/05/24 22:54:09 morgan Exp $
+ *
+ * Copyright (c) 1997-8 Andrew G Morgan <morgan@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with allocation and deallocation of internal
+ * capability sets as specified by POSIX.1e (formerlly, POSIX 6).
+ */
+
+#include "libcap.h"
+
+/*
+ * This function duplicates an internal capability set (x3) with
+ * malloc()'d memory. It is the responsibility of the user to call
+ * cap_free() to liberate it.
+ */
+
+cap_t cap_dup(cap_t cap_d)
+{
+ cap_t result;
+
+ if (!good_cap_t(cap_d)) {
+ _cap_debug("bad argument");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ result = (cap_t) malloc( sizeof(*cap_d) );
+ if (result == NULL) {
+ _cap_debug("out of memory");
+ errno = ENOMEM;
+ return NULL;
+ }
+
+ memcpy(result, cap_d, sizeof(*cap_d));
+
+ return result;
+}
+
+
+/*
+ * Scrub and then liberate an internal capability set.
+ */
+
+int cap_free(cap_t *cap_d_p)
+{
+ if ( cap_d_p && good_cap_t(*cap_d_p) ) {
+ memset(*cap_d_p, 0, sizeof(**cap_d_p));
+ free(*cap_d_p);
+ *cap_d_p = NULL;
+
+ return 0;
+ } else {
+ _cap_debug("no capability to liberate");
+ errno = EINVAL;
+ return -1;
+ }
+}
+
+/*
+ * Obtain a blank set of capabilities
+ */
+
+cap_t cap_init(void)
+{
+ cap_t result = (cap_t) calloc( 1, sizeof(*result) );
+
+ if (result) {
+ result->magic = CAP_T_MAGIC;
+ result->head.version = _LINUX_CAPABILITY_VERSION;
+ } else {
+ errno = ENOMEM;
+ }
+ return result;
+}
+
+/*
+ * $Log: cap_alloc.c,v $
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
diff --git a/libcap/cap_extint.c b/libcap/cap_extint.c
new file mode 100644
index 0000000..5f17f2c
--- /dev/null
+++ b/libcap/cap_extint.c
@@ -0,0 +1,142 @@
+/*
+ * $Id: cap_extint.c,v 1.3 1998/05/24 22:54:09 morgan Exp $
+ *
+ * Copyright (c) 1997-8 Andrew G Morgan <morgan@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with exchanging internal and external
+ * representations of capability sets.
+ */
+
+#include "libcap.h"
+
+/*
+ * External representation for capabilities. (exported as a fixed
+ * length (void *))
+ */
+#define CAP_EXT_MAGIC "\220\302\001\121"
+#define CAP_EXT_MAGIC_SIZE 4
+const static __u8 external_magic[CAP_EXT_MAGIC_SIZE+1] = CAP_EXT_MAGIC;
+
+struct cap_ext_struct {
+ __u8 magic[CAP_EXT_MAGIC_SIZE];
+ __u8 length_of_capset;
+/* note, we arrange these so the caps are stacked with byte-size
+ resolution */
+ __u8 bytes[CAP_SET_SIZE][NUMBER_OF_CAP_SETS];
+};
+
+/*
+ * return size of external capability set
+ */
+
+ssize_t cap_size(cap_t caps)
+{
+ return sizeof(struct cap_ext_struct);
+}
+
+/*
+ * Copy the internal (cap_d) capability set into an external
+ * representation. The external representation is portable to other
+ * Linux architectures.
+ */
+
+ssize_t cap_copy_ext(void *cap_ext, cap_t cap_d, ssize_t length)
+{
+ struct cap_ext_struct *result = (struct cap_ext_struct *) cap_ext;
+ __u32 *from = (__u32 *) &(cap_d->set);
+ int i;
+
+ /* valid arguments? */
+ if (!good_cap_t(cap_d) || length < sizeof(struct cap_ext_struct)
+ || cap_ext == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ /* fill external capability set */
+ memcpy(&result->magic, external_magic, CAP_EXT_MAGIC_SIZE);
+ result->length_of_capset = CAP_SET_SIZE;
+
+ for (i=0; i<NUMBER_OF_CAP_SETS; ++i) {
+ int j;
+ for (j=0; j<CAP_SET_SIZE; ) {
+ __u32 val = *from++;
+
+ result->bytes[j++][i] = val & 0xFF;
+ result->bytes[j++][i] = (val >>= 8) & 0xFF;
+ result->bytes[j++][i] = (val >>= 8) & 0xFF;
+ result->bytes[j++][i] = (val >> 8) & 0xFF;
+ }
+ }
+
+ /* All done: return length of external representation */
+ return (sizeof(struct cap_ext_struct));
+}
+
+/*
+ * Import an external representation to produce an internal rep.
+ * the internal rep should be liberated with cap_free().
+ */
+
+/*
+ * XXX - need to take a little more care when importing small
+ * capability sets.
+ */
+
+cap_t cap_copy_int(const void *cap_ext)
+{
+ const struct cap_ext_struct *export =
+ (const struct cap_ext_struct *) cap_ext;
+ cap_t cap_d;
+ int set, blen;
+ __u32 * to = (__u32 *) &cap_d->set;
+
+ /* Does the external representation make sense? */
+ if (export == NULL || !memcmp(export->magic, external_magic
+ , CAP_EXT_MAGIC_SIZE)) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* Obtain a new internal capability set */
+ if (!(cap_d = cap_init()))
+ return NULL;
+
+ blen = export->length_of_capset;
+ for (set=0; set<=NUMBER_OF_CAP_SETS; ++set) {
+ int blk;
+ int bno = 0;
+ for (blk=0; blk<(CAP_SET_SIZE/4); ++blk) {
+ __u32 val = 0;
+
+ if (bno != blen)
+ val = export->bytes[bno++][set];
+ if (bno != blen)
+ val |= export->bytes[bno++][set] << 8;
+ if (bno != blen)
+ val |= export->bytes[bno++][set] << 16;
+ if (bno != blen)
+ val |= export->bytes[bno++][set] << 24;
+
+ *to++ = val;
+ }
+ }
+
+ /* all done */
+ return cap_d;
+}
+
+/*
+ * $Log: cap_extint.c,v $
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
diff --git a/libcap/cap_file.c b/libcap/cap_file.c
new file mode 100644
index 0000000..0cb4114
--- /dev/null
+++ b/libcap/cap_file.c
@@ -0,0 +1,117 @@
+/*
+ * $Id: cap_file.c,v 1.5 1998/05/24 22:54:09 morgan Exp $
+ *
+ * Copyright (c) 1997 Andrew G Morgan <morgan@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with setting capabilities on files.
+ */
+
+#include "libcap.h"
+
+/*
+ * Get the capabilities of an open file, as specified by its file
+ * descriptor.
+ */
+
+cap_t cap_get_fd(int fildes)
+{
+ cap_t result;
+
+ /* allocate a new capability set */
+ result = cap_init();
+ if (result) {
+ _cap_debug("getting fildes capabilities");
+
+ /* fill the capability sets via a system call */
+ if (_fgetfilecap(fildes, sizeof(struct __cap_s),
+ &result->set[CAP_INHERITABLE],
+ &result->set[CAP_PERMITTED],
+ &result->set[CAP_EFFECTIVE] )) {
+ cap_free(&result);
+ }
+ }
+
+ return result;
+}
+
+/*
+ * Set the capabilities on a named file.
+ */
+
+cap_t cap_get_file(const char *filename)
+{
+ cap_t result;
+
+ /* allocate a new capability set */
+ result = cap_init();
+ if (result) {
+ _cap_debug("getting named file capabilities");
+
+ /* fill the capability sets via a system call */
+ if (_getfilecap(filename, sizeof(struct __cap_s),
+ &result->set[CAP_INHERITABLE],
+ &result->set[CAP_PERMITTED],
+ &result->set[CAP_EFFECTIVE] ))
+ cap_free(&result);
+ }
+
+ return result;
+}
+
+/*
+ * Set the capabilities of an open file, as specified by its file
+ * descriptor.
+ */
+
+int cap_set_fd(int fildes, cap_t cap_d)
+{
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("setting fildes capabilities");
+ return _fsetfilecap(fildes, sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] );
+}
+
+/*
+ * Set the capabilities of a named file.
+ */
+
+int cap_set_file(const char *filename, cap_t cap_d)
+{
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("setting filename capabilities");
+ return _setfilecap(filename, sizeof(struct __cap_s),
+ &cap_d->set[CAP_INHERITABLE],
+ &cap_d->set[CAP_PERMITTED],
+ &cap_d->set[CAP_EFFECTIVE] );
+}
+
+/*
+ * $Log: cap_file.c,v $
+ * Revision 1.5 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.4 1997/05/14 05:17:13 morgan
+ * bug-fix from zefram (errno no set on success)
+ *
+ * Revision 1.3 1997/05/04 05:35:46 morgan
+ * fixed errno setting. syscalls do this part
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
diff --git a/libcap/cap_flag.c b/libcap/cap_flag.c
new file mode 100644
index 0000000..7d8f967
--- /dev/null
+++ b/libcap/cap_flag.c
@@ -0,0 +1,122 @@
+/*
+ * $Id: cap_flag.c,v 1.4 1998/09/20 23:07:59 morgan Exp $
+ *
+ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with flipping of capabilities on internal
+ * capability sets as specified by POSIX.1e (formerlly, POSIX 6).
+ */
+
+#include "libcap.h"
+
+/*
+ * Return the state of a specified capability flag. The state is
+ * returned as the contents of *raised. The capability is from one of
+ * the sets stored in cap_d as specified by set and value
+ */
+
+int cap_get_flag(cap_t cap_d, cap_value_t value, cap_flag_t set,
+ cap_flag_value_t *raised)
+{
+ /*
+ * Do we have a set and a place to store its value?
+ * Is it a known capability?
+ */
+
+ if (raised && good_cap_t(cap_d) && value >= 0 && value < __CAP_BITS
+ && set >= 0 && set < NUMBER_OF_CAP_SETS) {
+ __cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE
+ + (__u8 *) &cap_d->set);
+
+ *raised = isset_cap(cap_p,value) ? CAP_SET:CAP_CLEAR;
+ return 0;
+
+ } else {
+
+ _cap_debug("invalid arguments");
+ errno = EINVAL;
+ return -1;
+
+ }
+}
+
+/*
+ * raise/lower a selection of capabilities
+ */
+
+int cap_set_flag(cap_t cap_d, cap_flag_t set,
+ int no_values, cap_value_t *array_values,
+ cap_flag_value_t raise)
+{
+ /*
+ * Do we have a set and a place to store its value?
+ * Is it a known capability?
+ */
+
+ if (good_cap_t(cap_d) && no_values > 0 && no_values <= __CAP_BITS
+ && (set >= 0) && (set < NUMBER_OF_CAP_SETS)
+ && (raise == CAP_SET || raise == CAP_CLEAR) ) {
+ int i;
+ for (i=0; i<no_values; ++i) {
+ if (array_values[i] < 0 || array_values[i] >= __CAP_BITS) {
+ _cap_debug("weird capability (%d) - skipped", array_values[i]);
+ } else {
+ int value = array_values[i];
+ __cap_s *cap_p = (__cap_s *) (set*CAP_SET_SIZE
+ + (__u8 *) &cap_d->set);
+
+ if (raise == CAP_SET) {
+ cap_p->raise_cap(value);
+ } else {
+ cap_p->lower_cap(value);
+ }
+ }
+ }
+ return 0;
+
+ } else {
+
+ _cap_debug("invalid arguments");
+ errno = EINVAL;
+ return -1;
+
+ }
+}
+
+/*
+ * Reset the capability to be empty (nothing raised)
+ */
+
+int cap_clear(cap_t cap_d)
+{
+ if (good_cap_t(cap_d)) {
+
+ memset(&(cap_d->set), 0, sizeof(cap_d->set));
+ return 0;
+
+ } else {
+
+ _cap_debug("invalid pointer");
+ errno = EINVAL;
+ return -1;
+
+ }
+}
+
+/*
+ * $Log: cap_flag.c,v $
+ * Revision 1.4 1998/09/20 23:07:59 morgan
+ * fixed lower bound check on 'set'.
+ *
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
diff --git a/libcap/cap_proc.c b/libcap/cap_proc.c
new file mode 100644
index 0000000..35c640c
--- /dev/null
+++ b/libcap/cap_proc.c
@@ -0,0 +1,100 @@
+/*
+ * $Id: cap_proc.c,v 1.5 1998/05/24 22:54:09 morgan Exp $
+ *
+ * Copyright (c) 1997-8 Andrew G Morgan <morgan@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with setting capabilities on processes.
+ */
+
+#include "libcap.h"
+
+cap_t cap_get_proc(void)
+{
+ cap_t result;
+
+ /* allocate a new capability set */
+ result = cap_init();
+ if (result) {
+ _cap_debug("getting current process' capabilities");
+
+ /* fill the capability sets via a system call */
+ if (capget(&result->head, &result->set)) {
+ cap_free(&result);
+ }
+ }
+
+ return result;
+}
+
+int cap_set_proc(cap_t cap_d)
+{
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("setting process capabilities");
+ return capset(&cap_d->head, &cap_d->set);
+}
+
+/* the following two functions are not required by POSIX */
+
+/* read the caps on a specific process */
+
+int capgetp(pid_t pid, cap_t cap_d)
+{
+ int error;
+
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("getting process capabilities for proc %d", pid);
+
+ cap_d->head.pid = pid;
+ error = capget(&cap_d->head, &cap_d->set);
+ cap_d->head.pid = 0;
+
+ return error;
+}
+
+/* set the caps on a specific process/pg etc.. */
+
+int capsetp(pid_t pid, cap_t cap_d)
+{
+ int error;
+
+ if (!good_cap_t(cap_d)) {
+ errno = EINVAL;
+ return -1;
+ }
+
+ _cap_debug("setting process capabilities for proc %d", pid);
+ cap_d->head.pid = pid;
+ error = capset(&cap_d->head, &cap_d->set);
+ cap_d->head.pid = 0;
+
+ return error;
+}
+
+/*
+ * $Log: cap_proc.c,v $
+ * Revision 1.5 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.4 1997/05/14 05:17:13 morgan
+ * bug-fix from zefram (errno no set on success)
+ *
+ * Revision 1.3 1997/05/04 05:35:46 morgan
+ * fixed errno setting. syscalls do this part
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
diff --git a/libcap/cap_sys.c b/libcap/cap_sys.c
new file mode 100644
index 0000000..896f5f2
--- /dev/null
+++ b/libcap/cap_sys.c
@@ -0,0 +1,36 @@
+/*
+ * $Id: cap_sys.c,v 1.4 1998/06/08 00:14:01 morgan Exp $
+ *
+ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@linux.kernel.org>
+ *
+ * This file contains the system calls for getting and setting
+ * capabilities
+ */
+
+#include "libcap.h"
+#define __LIBRARY__
+#include <linux/unistd.h>
+
+_syscall2(int, capget,
+ cap_user_header_t, header,
+ cap_user_data_t, data)
+
+_syscall2(int, capset,
+ cap_user_header_t, header,
+ const cap_user_data_t, data)
+
+/*
+ * $Log: cap_sys.c,v $
+ * Revision 1.4 1998/06/08 00:14:01 morgan
+ * change to accommodate alpha (glibc?)
+ *
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * fixes and zefram's patches
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
diff --git a/libcap/cap_text.c b/libcap/cap_text.c
new file mode 100644
index 0000000..53b51d0
--- /dev/null
+++ b/libcap/cap_text.c
@@ -0,0 +1,323 @@
+/*
+ * $Id: cap_text.c,v 1.4 1998/05/24 22:54:09 morgan Exp $
+ *
+ * Copyright (c) 1997-8 Andrew G Morgan <morgan@linux.kernel.org>
+ * Copyright (c) 1997 Andrew Main <zefram@dcs.warwick.ac.uk>
+ *
+ * See end of file for Log.
+ *
+ * This file deals with exchanging internal and textual
+ * representations of capability sets.
+ */
+
+#define LIBCAP_PLEASE_INCLUDE_ARRAY
+#include "libcap.h"
+
+#include <ctype.h>
+#include <stdio.h>
+
+char *strdup(const char *s);
+
+/* Maximum output text length (16 per cap) */
+#define CAP_TEXT_SIZE (16*__CAP_BITS)
+
+#define LIBCAP_EFF 01
+#define LIBCAP_INH 02
+#define LIBCAP_PER 04
+
+/*
+ * Parse a textual representation of capabilities, returning an internal
+ * representation.
+ */
+
+#define setbits(A,B) _setbits((__cap_s *)A, (__cap_s *)B)
+static void _setbits(__cap_s *a, __cap_s *b)
+{
+ int n;
+ for (n = __CAP_BLKS; n--; )
+ a->_blk[n] |= b->_blk[n];
+}
+
+#define clrbits(A,B) _clrbits((__cap_s *)A, (__cap_s *)B)
+static void _clrbits(__cap_s *a, __cap_s *b)
+{
+ int n;
+ for (n = __CAP_BLKS; n--; )
+ a->_blk[n] &= ~b->_blk[n];
+}
+
+static char const *namcmp(char const *str, char const *nam)
+{
+ while (*nam && tolower((unsigned char)*str) == *nam) {
+ str++;
+ nam++;
+ }
+ if (*nam || isalnum((unsigned char)*str) || *str == '_')
+ return NULL;
+ return str;
+}
+
+static int lookupname(char const **strp)
+{
+ char const *str = *strp;
+ if (isdigit(*str)) {
+ unsigned long n = strtoul(str, (char **)&str, 0);
+ if (n >= __CAP_BITS)
+ return -1;
+ *strp = str;
+ return n;
+ } else {
+ char const *s;
+ int n;
+ for (n = __CAP_BITS; n--; )
+ if (_cap_names[n] && (s = namcmp(str, _cap_names[n]))) {
+ *strp = s;
+ return n;
+ }
+ return -1;
+ }
+}
+
+cap_t cap_from_text(const char *str)
+{
+ cap_t res;
+ __cap_s allones;
+ int n;
+
+ if (str == NULL) {
+ _cap_debug("bad argument");
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if (!(res = cap_init()))
+ return NULL;
+ for (n = __CAP_BLKS; n--; )
+ allones._blk[n] = -1;
+ _cap_debug("%s", str);
+
+ for (;;) {
+ char op;
+ int flags = 0, listed=0;
+ __cap_s list = {{0}};
+
+ /* skip leading spaces */
+ while (isspace((unsigned char)*str))
+ str++;
+ if (!*str) {
+ _cap_debugcap("e = ", &res->set.effective);
+ _cap_debugcap("i = ", &res->set.inheritable);
+ _cap_debugcap("p = ", &res->set.permitted);
+ return res;
+ }
+
+ /* identify caps specified by this clause */
+ if (isalnum((unsigned char)*str) || *str == '_') {
+ for (;;) {
+ if (namcmp(str, "all")) {
+ str += 3;
+ list = allones;
+ } else {
+ n = lookupname(&str);
+ if (n == -1)
+ goto bad;
+ list.raise_cap(n);
+ }
+ if (*str != ',')
+ break;
+ if (!isalnum((unsigned char)*++str) && *str != '_')
+ goto bad;
+ }
+ listed = 1;
+ } else if (*str == '+' || *str == '-')
+ goto bad; /* require a list of capabilities */
+ else
+ list = allones;
+
+ /* identify first operation on list of capabilities */
+ op = *str++;
+ if (op == '=' && (*str == '+' || *str == '-')) {
+ if (!listed)
+ goto bad;
+ op = (*str++ == '+' ? 'P':'M'); /* skip '=' and take next op */
+ } else if (op != '+' && op != '-' && op != '=')
+ goto bad;
+
+ /* cycle through list of actions */
+ do {
+ _cap_debug("next char = `%c'", *str);
+ if (*str && !isspace(*str)) {
+ switch (*str++) { /* Effective, Inheritable, Permitted */
+ case 'e':
+ flags |= LIBCAP_EFF;
+ break;
+ case 'i':
+ flags |= LIBCAP_INH;
+ break;
+ case 'p':
+ flags |= LIBCAP_PER;
+ break;
+ default:
+ goto bad;
+ }
+ } else if (op != '=') {
+ _cap_debug("only '=' can be followed by space");
+ goto bad;
+ }
+
+ _cap_debug("how to read?");
+ switch (op) { /* how do we interpret the caps? */
+ case '=':
+ case 'P': /* =+ */
+ case 'M': /* =- */
+ clrbits(&res->set.effective, &list);
+ clrbits(&res->set.inheritable, &list);
+ clrbits(&res->set.permitted, &list);
+ /* fall through */
+ if (op == 'M')
+ goto minus;
+ case '+':
+ if (flags & LIBCAP_EFF)
+ setbits(&res->set.effective, &list);
+ if (flags & LIBCAP_INH)
+ setbits(&res->set.inheritable, &list);
+ if (flags & LIBCAP_PER)
+ setbits(&res->set.permitted, &list);
+ break;
+ case '-':
+ minus:
+ if (flags & LIBCAP_EFF)
+ clrbits(&res->set.effective, &list);
+ if (flags & LIBCAP_INH)
+ clrbits(&res->set.inheritable, &list);
+ if (flags & LIBCAP_PER)
+ clrbits(&res->set.permitted, &list);
+ break;
+ }
+
+ /* new directive? */
+ if (*str == '+' || *str == '-') {
+ if (!listed) {
+ _cap_debug("for + & - must list capabilities");
+ goto bad;
+ }
+ flags = 0; /* reset the flags */
+ op = *str++;
+ if (!isalpha(*str))
+ goto bad;
+ }
+ } while (*str && !isspace(*str));
+ _cap_debug("next clause");
+ }
+
+bad:
+ cap_free(&res);
+ errno = EINVAL;
+ return NULL;
+}
+
+/*
+ * Convert an internal representation to a textual one. The textual
+ * representation is stored in static memory. It will be overwritten
+ * on the next occasion that this function is called.
+ */
+
+static int getstateflags(cap_t caps, int capno)
+{
+ int f = 0;
+
+ if (isset_cap((__cap_s *)(&caps->set.effective),capno))
+ f |= LIBCAP_EFF;
+ if (isset_cap((__cap_s *)(&caps->set.inheritable),capno))
+ f |= LIBCAP_INH;
+ if (isset_cap((__cap_s *)(&caps->set.permitted),capno))
+ f |= LIBCAP_PER;
+
+ return f;
+}
+
+#define CAP_TEXT_BUFFER_ZONE 100
+
+char *cap_to_text(cap_t caps, ssize_t *length_p)
+{
+ static char buf[CAP_TEXT_SIZE+CAP_TEXT_BUFFER_ZONE];
+ char *p;
+ int histo[8] = {0};
+ int m, n, t;
+
+ /* Check arguments */
+ if (!good_cap_t(caps) || length_p == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ _cap_debugcap("e = ", &caps->set.effective);
+ _cap_debugcap("i = ", &caps->set.inheritable);
+ _cap_debugcap("p = ", &caps->set.permitted);
+
+ for (n = __CAP_BITS; n--; )
+ histo[getstateflags(caps, n)]++;
+
+ for (m=t=7; t--; )
+ if (histo[t] > histo[m])
+ m = t;
+
+ /* blank is not a valid capability set */
+ p = sprintf(buf, "=%s%s%s",
+ (m & LIBCAP_EFF) ? "e" : "",
+ (m & LIBCAP_INH) ? "i" : "",
+ (m & LIBCAP_PER) ? "p" : "" ) + buf;
+
+ for (t = 8; t--; )
+ if (t != m && histo[t]) {
+ *p++ = ' ';
+ for (n = 0; n != __CAP_BITS; n++)
+ if (getstateflags(caps, n) == t) {
+ if (_cap_names[n])
+ p += sprintf(p, "%s,", _cap_names[n]);
+ else
+ p += sprintf(p, "%d,", n);
+ if (p - buf > CAP_TEXT_SIZE) {
+ errno = ERANGE;
+ return NULL;
+ }
+ }
+ p--;
+ n = t & ~m;
+ if (n)
+ p += sprintf(p, "+%s%s%s",
+ (n & LIBCAP_EFF) ? "e" : "",
+ (n & LIBCAP_INH) ? "i" : "",
+ (n & LIBCAP_PER) ? "p" : "");
+ n = ~t & m;
+ if (n)
+ p += sprintf(p, "-%s%s%s",
+ (n & LIBCAP_EFF) ? "e" : "",
+ (n & LIBCAP_INH) ? "i" : "",
+ (n & LIBCAP_PER) ? "p" : "");
+ if (p - buf > CAP_TEXT_SIZE) {
+ errno = ERANGE;
+ return NULL;
+ }
+ }
+
+ _cap_debug("%s", buf);
+ *length_p = p - buf;
+ return (strdup(buf));
+}
+
+/*
+ * $Log: cap_text.c,v $
+ * Revision 1.4 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.3 1997/05/04 05:37:00 morgan
+ * case sensitvity to capability flags
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * zefram's replacement file with a number of bug fixes from AGM
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */
diff --git a/libcap/include/sys/RCS/capability.h,v b/libcap/include/sys/RCS/capability.h,v
new file mode 100644
index 0000000..3e65886
--- /dev/null
+++ b/libcap/include/sys/RCS/capability.h,v
@@ -0,0 +1,197 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.3
+date 98.05.24.22.53.05; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.56.38; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.33.43; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.3
+log
+@updated for 2.1.104
+@
+text
+@/*
+ * <sys/capability.h>
+ *
+ *
+ * Copyright (C) 1997 Aleph One
+ * Copyright (C) 1997-8 Andrew G. Morgan <morgan@@linux.kernel.org>
+ *
+ * POSIX.1e Standard: 25.2 Capabilities <sys/capability.h>
+ */
+
+#ifndef _SYS_CAPABILITY_H
+#define _SYS_CAPABILITY_H
+
+/*
+ * This file complements the kernel file by providing prototype
+ * information for the user library.
+ */
+
+#include <linux/capability.h>
+
+/*
+ * POSIX capability types
+ */
+
+/*
+ * Opaque capability handle (defined internally by libcap)
+ * internal capability representation
+ */
+typedef struct _cap_struct *cap_t;
+
+/* "external" capability representation is a (void *) */
+
+/*
+ * This is the type used to identify capabilities
+ */
+
+typedef int cap_value_t;
+
+/*
+ * Set identifiers
+ */
+typedef enum {
+ CAP_EFFECTIVE=0, /* Specifies the effective flag */
+ CAP_PERMITTED=1, /* Specifies the permitted flag */
+ CAP_INHERITABLE=2 /* Specifies the inheritable flag */
+} cap_flag_t;
+
+/*
+ * These are the states available to each capability
+ */
+typedef enum {
+ CAP_CLEAR=0, /* The flag is cleared/disabled */
+ CAP_SET=1 /* The flag is set/enabled */
+} cap_flag_value_t;
+
+/*
+ * User-space capability manipulation routines
+ */
+
+/* libcap/cap_alloc.c */
+cap_t cap_dup(cap_t);
+int cap_free(cap_t *);
+cap_t cap_init(void);
+
+/* libcap/cap_flag.c */
+int cap_get_flag(cap_t, cap_value_t, cap_flag_t, cap_flag_value_t *);
+int cap_set_flag(cap_t, cap_flag_t, int, cap_value_t *, cap_flag_value_t);
+int cap_clear(cap_t);
+
+/* libcap/cap_file.c */
+cap_t cap_get_fd(int);
+cap_t cap_get_file(const char *);
+int cap_set_fd(int, cap_t);
+int cap_set_file(const char *, cap_t);
+
+/* libcap/cap_proc.c */
+cap_t cap_get_proc(void);
+int cap_set_proc(cap_t);
+
+/* libcap/cap_extint.c */
+ssize_t cap_size(cap_t);
+ssize_t cap_copy_ext(void *, cap_t, ssize_t);
+cap_t cap_copy_int(const void *);
+
+/* libcap/cap_text.c */
+cap_t cap_from_text(const char *);
+char * cap_to_text(cap_t, ssize_t *);
+
+/*
+ * Linux capability system calls: defined in libcap but only available
+ * if the following _POSIX_SOURCE is _undefined_
+ */
+
+#if !defined(_POSIX_SOURCE)
+
+extern int capset(cap_user_header_t header, cap_user_data_t data);
+extern int capget(cap_user_header_t header, const cap_user_data_t data);
+extern int capgetp(pid_t pid, cap_t cap_d);
+extern int capsetp(pid_t pid, cap_t cap_d);
+extern char const *_cap_names[];
+
+#endif /* !defined(_POSIX_SOURCE) */
+
+#endif /* _SYS_CAPABILITY_H */
+@
+
+
+1.2
+log
+@update with zefram's fixes
+@
+text
+@d5 2
+a6 2
+ * Copyright (C) 1997 Aleph One
+ * Copyright (C) 1997 Andrew G. Morgan <morgan@@parc.power.net>
+a21 21
+ * Linux capability system calls: defined in libcap but only available
+ * if the following _POSIX_SOURCE is _undefined_
+ */
+
+#if !defined(_POSIX_SOURCE)
+
+int _setproccap(size_t, __cap_s const *,__cap_s const *, __cap_s const *);
+int _getproccap(size_t, __cap_s *,__cap_s *, __cap_s *);
+int _setfilecap(char const *, size_t, __cap_s const *,
+ __cap_s const *, __cap_s const *);
+int _getfilecap(char const *, size_t, __cap_s *, __cap_s *, __cap_s *);
+int _fsetfilecap(int, size_t, __cap_s const *,
+ __cap_s const *, __cap_s const *);
+int _fgetfilecap(int, size_t, __cap_s *, __cap_s *, __cap_s *);
+
+/* libcap/cap_names.c */
+extern char const *_cap_names[__CAP_BITS];
+
+#endif /* !defined(_POSIX_SOURCE) */
+
+/*
+d44 2
+a45 2
+ CAP_INHERITABLE=1, /* Specifies the inheritable flag */
+ CAP_PERMITTED=2 /* Specifies the permitted flag */
+d88 15
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d14 5
+d22 2
+a23 2
+ * This file compliments the kernel file by providing prototype
+ * information for the user library.
+d26 16
+a81 1
+ssize_t cap_size(cap_t);
+d102 1
+a107 2
+
+#define CAP_TEXT_SIZE 2048 /* Maximum text length (16 per cap) */
+@
diff --git a/libcap/include/sys/capability.h b/libcap/include/sys/capability.h
new file mode 100644
index 0000000..dd27978
--- /dev/null
+++ b/libcap/include/sys/capability.h
@@ -0,0 +1,104 @@
+/*
+ * <sys/capability.h>
+ *
+ *
+ * Copyright (C) 1997 Aleph One
+ * Copyright (C) 1997-8 Andrew G. Morgan <morgan@linux.kernel.org>
+ *
+ * POSIX.1e Standard: 25.2 Capabilities <sys/capability.h>
+ */
+
+#ifndef _SYS_CAPABILITY_H
+#define _SYS_CAPABILITY_H
+
+/*
+ * This file complements the kernel file by providing prototype
+ * information for the user library.
+ */
+
+#include <linux/capability.h>
+
+/*
+ * POSIX capability types
+ */
+
+/*
+ * Opaque capability handle (defined internally by libcap)
+ * internal capability representation
+ */
+typedef struct _cap_struct *cap_t;
+
+/* "external" capability representation is a (void *) */
+
+/*
+ * This is the type used to identify capabilities
+ */
+
+typedef int cap_value_t;
+
+/*
+ * Set identifiers
+ */
+typedef enum {
+ CAP_EFFECTIVE=0, /* Specifies the effective flag */
+ CAP_PERMITTED=1, /* Specifies the permitted flag */
+ CAP_INHERITABLE=2 /* Specifies the inheritable flag */
+} cap_flag_t;
+
+/*
+ * These are the states available to each capability
+ */
+typedef enum {
+ CAP_CLEAR=0, /* The flag is cleared/disabled */
+ CAP_SET=1 /* The flag is set/enabled */
+} cap_flag_value_t;
+
+/*
+ * User-space capability manipulation routines
+ */
+
+/* libcap/cap_alloc.c */
+cap_t cap_dup(cap_t);
+int cap_free(cap_t *);
+cap_t cap_init(void);
+
+/* libcap/cap_flag.c */
+int cap_get_flag(cap_t, cap_value_t, cap_flag_t, cap_flag_value_t *);
+int cap_set_flag(cap_t, cap_flag_t, int, cap_value_t *, cap_flag_value_t);
+int cap_clear(cap_t);
+
+/* libcap/cap_file.c */
+cap_t cap_get_fd(int);
+cap_t cap_get_file(const char *);
+int cap_set_fd(int, cap_t);
+int cap_set_file(const char *, cap_t);
+
+/* libcap/cap_proc.c */
+cap_t cap_get_proc(void);
+int cap_set_proc(cap_t);
+
+/* libcap/cap_extint.c */
+ssize_t cap_size(cap_t);
+ssize_t cap_copy_ext(void *, cap_t, ssize_t);
+cap_t cap_copy_int(const void *);
+
+/* libcap/cap_text.c */
+cap_t cap_from_text(const char *);
+char * cap_to_text(cap_t, ssize_t *);
+
+/*
+ * Linux capability system calls: defined in libcap but only available
+ * if the following _POSIX_SOURCE is _undefined_
+ */
+
+#if !defined(_POSIX_SOURCE)
+
+extern int capset(cap_user_header_t header, cap_user_data_t data);
+extern int capget(cap_user_header_t header, const cap_user_data_t data);
+extern int capgetp(pid_t pid, cap_t cap_d);
+extern int capsetp(pid_t pid, cap_t cap_d);
+extern char const *_cap_names[];
+
+#endif /* !defined(_POSIX_SOURCE) */
+
+#endif /* _SYS_CAPABILITY_H */
diff --git a/libcap/libcap.h b/libcap/libcap.h
new file mode 100644
index 0000000..2036583
--- /dev/null
+++ b/libcap/libcap.h
@@ -0,0 +1,125 @@
+/*
+ * $Id: libcap.h,v 1.5 1998/06/08 00:15:28 morgan Exp $
+ *
+ * Copyright (c) 1997 Andrew G Morgan <morgan@linux.kernel.org>
+ *
+ * See end of file for Log.
+ *
+ * This file contains internal definitions for the various functions in
+ * this small capability library.
+ */
+
+#ifndef LIBCAP_H
+#define LIBCAP_H
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/capability.h>
+
+/* include the names for the caps and a definition of __CAP_BITS */
+#include "cap_names.h"
+
+/*
+ * This is a pointer to a struct containing three consecutive
+ * capability sets in the order of the cap_flag_t type: the are
+ * effective,inheritable and permitted. This is the type that the
+ * user-space routines think of as 'internal' capabilities - this is
+ * the type that is passed to the kernel with the system calls related
+ * to processes.
+ */
+
+#define CAP_T_MAGIC 0xCA90D0
+struct _cap_struct {
+ int magic;
+ struct __user_cap_header_struct head;
+ struct __user_cap_data_struct set;
+};
+
+/*
+ * Do we match the local kernel?
+ */
+
+#if !defined(_LINUX_CAPABILITY_VERSION) || \
+ (_LINUX_CAPABILITY_VERSION != 0x19980330)
+
+# error "Kernel <linux/capability.h> does not match library"
+# error "file "libcap.h" --> fix and recompile libcap"
+
+#endif
+
+/*
+ * kernel API cap set abstraction
+ */
+
+#define NUMBER_OF_CAP_SETS 3 /* effective, inheritable, permitted */
+#define CAP_SET_SIZE (sizeof(struct __user_cap_data_struct)/NUMBER_OF_CAP_SETS)
+#define __CAP_BLKS (CAP_SET_SIZE/sizeof(__u32))
+typedef struct {
+ __u32 _blk[__CAP_BLKS];
+} __cap_s;
+#define raise_cap(x) _blk[(x)>>5] |= (1<<((x)&31))
+#define lower_cap(x) _blk[(x)>>5] |= (1<<((x)&31))
+#define isset_cap(y,x) ((y)->_blk[(x)>>5] & (1<<((x)&31)))
+
+/*
+ * Private definitions for internal use by the library.
+ */
+
+#define good_cap_t(c) ((c) && (c)->magic == CAP_T_MAGIC)
+
+/*
+ * library debugging
+ */
+#ifdef DEBUG
+
+#include <stdio.h>
+# define _cap_debug(f, x...) { \
+ fprintf(stderr, __FUNCTION__ "(" __FILE__ ":%d): ", __LINE__); \
+ fprintf(stderr, f, ## x); \
+ fprintf(stderr, "\n"); \
+}
+# define _cap_debugcap(s, c) \
+ fprintf(stderr, __FUNCTION__ "(" __FILE__ ":%d): " s \
+ "%08x\n", __LINE__, c)
+
+#else /* !DEBUG */
+
+# define _cap_debug(f, x...)
+# define _cap_debugcap(s, c)
+
+#endif /* DEBUG */
+
+/*
+ * These are semi-public prototypes, they will only be defined in
+ * <sys/capability.h> if _POSIX_SOURCE is not #define'd, so we
+ * place them here too.
+ */
+
+extern int capset(cap_user_header_t header, cap_user_data_t data);
+extern int capget(cap_user_header_t header, const cap_user_data_t data);
+extern int capgetp(pid_t pid, cap_t cap_d);
+extern int capsetp(pid_t pid, cap_t cap_d);
+
+#endif /* LIBCAP_H */
+
+/*
+ * $Log: libcap.h,v $
+ * Revision 1.5 1998/06/08 00:15:28 morgan
+ * accommodate alpha (glibc?)
+ *
+ * Revision 1.4 1998/06/07 15:58:23 morgan
+ * accommodate real kernel header files :*)
+ *
+ * Revision 1.3 1998/05/24 22:54:09 morgan
+ * updated for 2.1.104
+ *
+ * Revision 1.2 1997/04/28 00:57:11 morgan
+ * zefram's replacement file with a number of bug fixes from AGM
+ *
+ * Revision 1.1 1997/04/21 04:32:52 morgan
+ * Initial revision
+ *
+ */