aboutsummaryrefslogtreecommitdiffstats
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
downloadlibcap-2c9c0532daccfd300f0eb1401b15348ed19d0ce7.tar.gz
This is the source for libcap-1.0.tar.gzlibcap-1.0
http://www.kernel.org/pub/linux/libs/security/linux-privs/kernel-2.2/libcap-1.0.tar.gz
-rw-r--r--License41
-rw-r--r--Make.Rules70
-rw-r--r--Makefile29
-rw-r--r--RCS/License,v65
-rw-r--r--RCS/Make.Rules,v275
-rw-r--r--RCS/Makefile,v163
-rw-r--r--RCS/README,v89
-rw-r--r--RCS/pgp.keys.asc,v158
-rw-r--r--README29
-rw-r--r--doc/Makefile38
-rw-r--r--doc/RCS/Makefile,v137
-rw-r--r--doc/RCS/_cap_names.3,v25
-rw-r--r--doc/RCS/cap_clear.3,v169
-rw-r--r--doc/RCS/cap_copy_ext.3,v215
-rw-r--r--doc/RCS/cap_copy_int.3,v25
-rw-r--r--doc/RCS/cap_dup.3,v25
-rw-r--r--doc/RCS/cap_free.3,v25
-rw-r--r--doc/RCS/cap_from_text.3,v312
-rw-r--r--doc/RCS/cap_get_fd.3,v25
-rw-r--r--doc/RCS/cap_get_flag.3,v25
-rw-r--r--doc/RCS/cap_get_proc.3,v236
-rw-r--r--doc/RCS/cap_init.3,v157
-rw-r--r--doc/RCS/cap_set_fd.3,v25
-rw-r--r--doc/RCS/cap_set_file.3,v25
-rw-r--r--doc/RCS/cap_set_flag.3,v25
-rw-r--r--doc/RCS/cap_set_proc.3,v25
-rw-r--r--doc/RCS/cap_size.3,v25
-rw-r--r--doc/RCS/cap_to_text.3,v25
-rw-r--r--doc/RCS/capget.2,v66
-rw-r--r--doc/RCS/capgetp.3,v25
-rw-r--r--doc/RCS/capset.2,v25
-rw-r--r--doc/RCS/capsetp.3,v25
-rw-r--r--doc/_cap_names.31
-rw-r--r--doc/cap_clear.385
-rw-r--r--doc/cap_copy_ext.3102
-rw-r--r--doc/cap_copy_int.31
-rw-r--r--doc/cap_dup.31
-rw-r--r--doc/cap_free.31
-rw-r--r--doc/cap_from_text.3153
-rw-r--r--doc/cap_get_flag.31
-rw-r--r--doc/cap_get_proc.3122
-rw-r--r--doc/cap_init.380
-rw-r--r--doc/cap_set_fd.31
-rw-r--r--doc/cap_set_file.31
-rw-r--r--doc/cap_set_flag.31
-rw-r--r--doc/cap_set_proc.31
-rw-r--r--doc/cap_size.31
-rw-r--r--doc/cap_to_text.31
-rw-r--r--doc/capget.242
-rw-r--r--doc/capgetp.31
-rw-r--r--doc/capset.21
-rw-r--r--doc/capsetp.31
-rw-r--r--doc/old/RCS/README,v25
-rw-r--r--doc/old/RCS/_fgetfilecap.2,v25
-rw-r--r--doc/old/RCS/_fsetfilecap.2,v25
-rw-r--r--doc/old/RCS/_getfilecap.2,v25
-rw-r--r--doc/old/RCS/_getproccap.2,v25
-rw-r--r--doc/old/RCS/_setfilecap.2,v141
-rw-r--r--doc/old/RCS/_setproccap.2,v76
-rw-r--r--doc/old/RCS/cap_get_file.3,v202
-rw-r--r--doc/old/RCS/getcap.8,v42
-rw-r--r--doc/old/RCS/setcap.8,v51
-rw-r--r--doc/old/README1
-rw-r--r--doc/old/_fgetfilecap.21
-rw-r--r--doc/old/_fsetfilecap.21
-rw-r--r--doc/old/_getfilecap.21
-rw-r--r--doc/old/_getproccap.21
-rw-r--r--doc/old/_setfilecap.2117
-rw-r--r--doc/old/_setproccap.252
-rw-r--r--doc/old/cap_get_fd.31
-rw-r--r--doc/old/cap_get_file.394
-rw-r--r--doc/old/getcap.818
-rw-r--r--doc/old/setcap.827
-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
-rw-r--r--pgp.keys.asc100
-rw-r--r--progs/Makefile49
-rw-r--r--progs/RCS/Makefile,v187
-rw-r--r--progs/RCS/execcap.c,v119
-rw-r--r--progs/RCS/getpcaps.c,v166
-rw-r--r--progs/RCS/setpcaps.c,v207
-rw-r--r--progs/RCS/sucap.c,v266
-rw-r--r--progs/execcap.c65
-rw-r--r--progs/getpcaps.c78
-rw-r--r--progs/old/RCS/README,v25
-rw-r--r--progs/old/RCS/getcap.c,v151
-rw-r--r--progs/old/RCS/setcap.c,v168
-rw-r--r--progs/old/README1
-rw-r--r--progs/old/getcap.c64
-rw-r--r--progs/old/setcap.c122
-rw-r--r--progs/setpcaps.c145
-rw-r--r--progs/sucap.c196
-rw-r--r--template.c11
113 files changed, 10926 insertions, 0 deletions
diff --git a/License b/License
new file mode 100644
index 0000000..9289476
--- /dev/null
+++ b/License
@@ -0,0 +1,41 @@
+Unless otherwise *explicitly* stated, the following text describes the
+licensed conditions under which the contents of this libcap release
+may be used and distributed:
+
+-------------------------------------------------------------------------
+Redistribution and use in source and binary forms of libcap, with
+or without modification, are permitted provided that the following
+conditions are met:
+
+1. Redistributions of source code must retain any existing copyright
+ notice, and this entire permission notice in its entirety,
+ including the disclaimer of warranties.
+
+2. Redistributions in binary form must reproduce all prior and current
+ copyright notices, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+3. The name of any author may not be used to endorse or promote
+ products derived from this software without their specific prior
+ written permission.
+
+ALTERNATIVELY, this product may be distributed under the terms of the
+GNU General Public License, in which case the provisions of the GNU
+GPL are required INSTEAD OF the above restrictions. (This clause is
+necessary due to a potential conflict between the GNU GPL and the
+restrictions contained in a BSD-style copyright.)
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+-------------------------------------------------------------------------
+
diff --git a/Make.Rules b/Make.Rules
new file mode 100644
index 0000000..4cf64e6
--- /dev/null
+++ b/Make.Rules
@@ -0,0 +1,70 @@
+#
+# $Id: Make.Rules,v 1.7 1999/01/30 03:50:34 morgan Exp $
+#
+
+#
+## Optional prefixes:
+#
+
+# common 'packaging' directoty
+
+FAKEROOT=
+
+# Autoconf-style prefixes are activated when $(prefix) is defined.
+# Otherwise binaries and libraraies are installed in /{lib,sbin}/,
+# header files in /usr/include/ and documentation in /usr/man/man?/.
+
+ifdef prefix
+exec_prefix=$(prefix)
+lib_prefix=$(exec_prefix)
+inc_prefix=$(lib_prefix)
+man_prefix=$(prefix)
+else
+prefix=/usr
+exec_prefix=
+lib_prefix=$(exec_prefix)
+inc_prefix=$(prefix)
+man_prefix=$(prefix)
+endif
+
+# Target directories
+
+MANDIR=$(FAKEROOT)$(man_prefix)/man
+SBINDIR=$(FAKEROOT)$(exec_prefix)/sbin
+INCDIR=$(FAKEROOT)$(inc_prefix)/include
+LIBDIR=$(FAKEROOT)$(lib_prefix)/lib
+
+# common defines for libcap (suitable for 2.2.1+ Linux kernels)
+VERSION=1
+MINOR=0
+#
+
+# Compilation specifics
+
+CC=gcc
+COPTFLAGS=-O2
+DEBUG=-g #-DDEBUG
+WARNINGS=-ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
+ -Wpointer-arith -Wcast-qual -Wcast-align \
+ -Wtraditional -Wstrict-prototypes -Wmissing-prototypes \
+ -Wnested-externs -Winline -Wshadow -pedantic
+LD=ld
+LDFLAGS=-s #-g
+
+IPATH=-I$(topdir)/libcap/include
+INCS=$(topdir)/libcap/include/sys/capability.h
+LIBS=-L$(topdir)/libcap -lcap
+CFLAGS=-Dlinux $(WARNINGS) $(DEBUG) $(COPTFLAG) $(IPATH)
+
+# Global cleanup stuff
+
+LOCALCLEAN=rm -f *~ core
+DISTCLEAN=@find . \( -name '*.orig' -o -name '*.rej' \) | xargs rm -f
+
+# Flags to pass down recursive makes
+
+MAKE_DEFS = CC='$(CC)' CFLAGS='$(CFLAGS)' \
+ LD='$(LD)' LIBS='$(LIBS)' LDFLAGS='$(LDFLAGS)' \
+ VERSION='$(VERSION)' MINOR='$(MINOR)' \
+ LIBDIR='$(LIBDIR)' INCDIR='$(INCDIR)' \
+ SBINDIR='$(SBINDIR)' MANDIR='$(MANDIR)'
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..4acffd8
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,29 @@
+#
+# $Id: Makefile,v 1.4 1997/05/14 05:15:40 morgan Exp $
+#
+# Makefile for libcap
+
+topdir=$(shell pwd)
+include Make.Rules
+
+#
+# flags
+#
+
+all install clean: %: %-here
+ make -C libcap $(MAKE_DEFS) $@
+ make -C progs $(MAKE_DEFS) $@
+ make -C doc $(MAKE_DEFS) $@
+
+all-here:
+
+install-here:
+
+clean-here:
+ $(LOCALCLEAN)
+
+distclean: clean
+ $(DISTCLEAN)
+
+release: distclean
+ cd .. ; tar cvfz libcap-$(VERSION).$(MINOR).tar.gz libcap-$(VERSION).$(MINOR)
diff --git a/RCS/License,v b/RCS/License,v
new file mode 100644
index 0000000..bacc634
--- /dev/null
+++ b/RCS/License,v
@@ -0,0 +1,65 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.21.01.43.16; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@Do not abuse this!
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@Unless otherwise *explicitly* stated, the following text describes the
+licensed conditions under which the contents of this libcap release
+may be used and distributed:
+
+-------------------------------------------------------------------------
+Redistribution and use in source and binary forms of libcap, with
+or without modification, are permitted provided that the following
+conditions are met:
+
+1. Redistributions of source code must retain any existing copyright
+ notice, and this entire permission notice in its entirety,
+ including the disclaimer of warranties.
+
+2. Redistributions in binary form must reproduce all prior and current
+ copyright notices, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+3. The name of any author may not be used to endorse or promote
+ products derived from this software without their specific prior
+ written permission.
+
+ALTERNATIVELY, this product may be distributed under the terms of the
+GNU General Public License, in which case the provisions of the GNU
+GPL are required INSTEAD OF the above restrictions. (This clause is
+necessary due to a potential conflict between the GNU GPL and the
+restrictions contained in a BSD-style copyright.)
+
+THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
+INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+-------------------------------------------------------------------------
+
+@
diff --git a/RCS/Make.Rules,v b/RCS/Make.Rules,v
new file mode 100644
index 0000000..71428f9
--- /dev/null
+++ b/RCS/Make.Rules,v
@@ -0,0 +1,275 @@
+head 1.7;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.7
+date 99.01.30.03.50.34; author morgan; state Exp;
+branches;
+next 1.6;
+
+1.6
+date 98.09.20.23.10.18; author morgan; state Exp;
+branches;
+next 1.5;
+
+1.5
+date 98.06.07.01.53.44; author morgan; state Exp;
+branches;
+next 1.4;
+
+1.4
+date 98.05.17.17.31.40; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 97.05.14.05.14.35; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.05.04.05.31.12; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.00.54.04; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@revised with contributions from Zefram
+@
+
+
+1.7
+log
+@upped version to 1.0 (to match 2.2.1 Linux kernel)
+@
+text
+@#
+# $Id: Make.Rules,v 1.6 1998/09/20 23:10:18 morgan Exp morgan $
+#
+
+#
+## Optional prefixes:
+#
+
+# common 'packaging' directoty
+
+FAKEROOT=
+
+# Autoconf-style prefixes are activated when $(prefix) is defined.
+# Otherwise binaries and libraraies are installed in /{lib,sbin}/,
+# header files in /usr/include/ and documentation in /usr/man/man?/.
+
+ifdef prefix
+exec_prefix=$(prefix)
+lib_prefix=$(exec_prefix)
+inc_prefix=$(lib_prefix)
+man_prefix=$(prefix)
+else
+prefix=/usr
+exec_prefix=
+lib_prefix=$(exec_prefix)
+inc_prefix=$(prefix)
+man_prefix=$(prefix)
+endif
+
+# Target directories
+
+MANDIR=$(FAKEROOT)$(man_prefix)/man
+SBINDIR=$(FAKEROOT)$(exec_prefix)/sbin
+INCDIR=$(FAKEROOT)$(inc_prefix)/include
+LIBDIR=$(FAKEROOT)$(lib_prefix)/lib
+
+# common defines for libcap (suitable for 2.2.1+ Linux kernels)
+VERSION=1
+MINOR=0
+#
+
+# Compilation specifics
+
+CC=gcc
+COPTFLAGS=-O2
+DEBUG=-g #-DDEBUG
+WARNINGS=-ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
+ -Wpointer-arith -Wcast-qual -Wcast-align \
+ -Wtraditional -Wstrict-prototypes -Wmissing-prototypes \
+ -Wnested-externs -Winline -Wshadow -pedantic
+LD=ld
+LDFLAGS=-s #-g
+
+IPATH=-I$(topdir)/libcap/include
+INCS=$(topdir)/libcap/include/sys/capability.h
+LIBS=-L$(topdir)/libcap -lcap
+CFLAGS=-Dlinux $(WARNINGS) $(DEBUG) $(COPTFLAG) $(IPATH)
+
+# Global cleanup stuff
+
+LOCALCLEAN=rm -f *~ core
+DISTCLEAN=@@find . \( -name '*.orig' -o -name '*.rej' \) | xargs rm -f
+
+# Flags to pass down recursive makes
+
+MAKE_DEFS = CC='$(CC)' CFLAGS='$(CFLAGS)' \
+ LD='$(LD)' LIBS='$(LIBS)' LDFLAGS='$(LDFLAGS)' \
+ VERSION='$(VERSION)' MINOR='$(MINOR)' \
+ LIBDIR='$(LIBDIR)' INCDIR='$(INCDIR)' \
+ SBINDIR='$(SBINDIR)' MANDIR='$(MANDIR)'
+@
+
+
+1.6
+log
+@updated for kernel 2.1.122 (should work with 104+, since the changes
+are a library bug fix and the addition of an other example prog:
+sucap)
+@
+text
+@d2 1
+a2 1
+# $Id: Make.Rules,v 1.5 1998/06/07 01:53:44 morgan Exp morgan $
+d37 3
+a39 3
+# common defines for libcap
+VERSION=0
+MINOR=122
+@
+
+
+1.5
+log
+@updated for 0.104
+@
+text
+@d2 1
+a2 1
+# $Id: Make.Rules,v 1.4 1998/05/17 17:31:40 morgan Exp morgan $
+d39 1
+a39 1
+MINOR=104
+@
+
+
+1.4
+log
+@updated version number
+modified some compilation flags
+@
+text
+@d2 1
+a2 1
+# $Id: Make.Rules,v 1.3 1997/05/14 05:14:35 morgan Exp morgan $
+d39 1
+a39 1
+MINOR=102
+@
+
+
+1.3
+log
+@autoconf rearrangement from Zefram
+@
+text
+@d2 1
+a2 1
+# $Id: Make.Rules,v 1.2 1997/05/04 05:31:12 morgan Exp morgan $
+d39 1
+a39 1
+MINOR=85
+d46 1
+a46 1
+DEBUG=#-g -DDEBUG
+@
+
+
+1.2
+log
+@cleaner makefiles
+@
+text
+@d2 1
+a2 1
+# $Id: Make.Rules,v 1.1 1997/04/28 00:54:04 morgan Exp morgan $
+d10 1
+d13 16
+a28 2
+# include file prefix
+inc_prefix=/usr
+d30 1
+a30 2
+# library tree prefix
+lib_prefix=
+d32 4
+a35 5
+# manual tree prefix
+man_prefix=/usr
+
+# sbin directory prefix
+sbin_prefix=
+d39 1
+a39 2
+MINOR=80
+#
+a46 1
+FAKEROOT=
+d51 3
+d55 2
+a56 2
+LPATH=-L$(topdir)/libcap -lcap
+
+a58 7
+# "Interesting target directories"
+
+MANDIR=$(FAKEROOT)$(man_prefix)/man
+BINDIR=$(FAKEROOT)$(sbin_prefix)/sbin
+INCDIR=$(FAKEROOT)$(inc_prefix)/include
+LIBDIR=$(FAKEROOT)$(lib_prefix)/lib
+
+d63 8
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+# $Id: Makefile,v 1.1 1997/04/21 04:32:27 morgan Exp $
+d4 20
+d26 1
+a26 1
+MINOR=02
+d30 2
+a31 1
+ifndef CC
+a32 3
+endif
+
+ifndef COPTFLAGS
+a33 3
+endif
+
+ifndef DEBUG
+a34 3
+endif
+
+ifndef FAKEROOT
+a35 2
+endif
+
+a39 5
+
+MANDIR=$(FAKEROOT)/usr/man
+BINDIR=$(FAKEROOT)/bin
+INCDIR=$(FAKEROOT)/usr/include
+LIBDIR=$(FAKEROOT)/lib
+d44 9
+@
diff --git a/RCS/Makefile,v b/RCS/Makefile,v
new file mode 100644
index 0000000..cac5ea7
--- /dev/null
+++ b/RCS/Makefile,v
@@ -0,0 +1,163 @@
+head 1.4;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.4
+date 97.05.14.05.15.40; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 97.05.04.05.31.12; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.00.54.04; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.27; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@a start
+@
+
+
+1.4
+log
+@autoconf rearrangemnt from Zefram
+@
+text
+@#
+# $Id: Makefile,v 1.3 1997/05/04 05:31:12 morgan Exp morgan $
+#
+# Makefile for libcap
+
+topdir=$(shell pwd)
+include Make.Rules
+
+#
+# flags
+#
+
+all install clean: %: %-here
+ make -C libcap $(MAKE_DEFS) $@@
+ make -C progs $(MAKE_DEFS) $@@
+ make -C doc $(MAKE_DEFS) $@@
+
+all-here:
+
+install-here:
+
+clean-here:
+ $(LOCALCLEAN)
+
+distclean: clean
+ $(DISTCLEAN)
+
+release: distclean
+ cd .. ; tar cvfz libcap-$(VERSION).$(MINOR).tar.gz libcap-$(VERSION).$(MINOR)
+@
+
+
+1.3
+log
+@cleaner makefiles
+@
+text
+@d2 1
+a2 1
+# $Id: Makefile,v 1.2 1997/04/28 00:54:04 morgan Exp morgan $
+d6 1
+a6 1
+topdir=.
+d14 3
+a16 3
+ make -C libcap $@@
+ make -C progs $@@
+ make -C doc $@@
+@
+
+
+1.2
+log
+@revised with contributions from Zefram
+@
+text
+@d2 1
+a2 1
+# $Id: Makefile,v 1.1 1997/04/21 04:32:27 morgan Exp morgan $
+a11 2
+#
+#
+d13 8
+a20 8
+all:
+ make -C libcap all
+ make -C progs all
+
+install:
+ make -C libcap install
+ make -C progs install
+ make -C doc install
+d22 1
+a22 1
+clean:
+a23 3
+ make -C libcap clean
+ make -C progs clean
+ make -C doc clean
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+# $Id$
+d6 2
+a7 19
+ifndef CC
+CC=gcc
+endif
+export CC
+
+ifndef COPTFLAGS
+COPTFLAGS=-O2
+endif
+export COPTFLAGS
+
+ifndef DEBUG
+DEBUG=#-g -DDEBUG
+endif
+export DEBUG
+
+ifndef FAKEROOT
+FAKEROOT=
+endif
+export FAKEROOT
+a11 6
+export IPATH=-I$(shell pwd)/libcap/include
+export LPATH=-L$(shell pwd)/libcap -lcap
+export WARNINGS = -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
+ -Wpointer-arith -Wcast-qual -Wcast-align \
+ -Wtraditional -Wstrict-prototypes -Wmissing-prototypes \
+ -Wnested-externs -Winline -Wshadow -pedantic
+d22 1
+d25 1
+d28 1
+d31 4
+a34 1
+ @@find . \( -name '*.orig' -o -name '*.rej' \) | xargs rm -f
+@
diff --git a/RCS/README,v b/RCS/README,v
new file mode 100644
index 0000000..7208411
--- /dev/null
+++ b/RCS/README,v
@@ -0,0 +1,89 @@
+head 1.2;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 98.05.17.17.33.01; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.32.27; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@a start
+@
+
+
+1.2
+log
+@updated for 0.102
+@
+text
+@
+This is a library for getting and setting POSIX.1e (formerly POSIX 6)
+draft 15 capabilities.
+
+This library would not have been possible without the help of
+
+ Aleph1, Roland Buresund and Andrew Main, Alexander Kjeldaas.
+
+More information on capabilities in the Linux kernel can be found at
+
+ http://linux.kernel.org/pub/linux/libs/security/linux-privs/
+
+# INSTALLATION
+
+ Linux-Caps % make
+
+ builds the library and the programs
+
+ Linux-Caps % make install
+
+ installs the library libcap.XX.Y in /lib/
+ the binaries in /bin/
+ the <sys/capability.h> file in /usr/include
+
+* for some example programs look in progs.
+
+Cheers
+
+Andrew G. Morgan <morgan@@linux.kernel.org>
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d1 1
+d3 1
+a3 2
+capabilities. It has been written to conform to the capabilities
+associated with the capability-enhanced Linux kernel.
+d7 1
+a7 1
+ Aleph1, Roland Buresund and Andrew Main.
+d11 1
+a11 1
+ <URL:http://parc.power.net/morgan/Orange-Linux/linux-privs/>
+d25 1
+a25 7
+# TESTING (preliminary)
+
+ getcap <filename>
+
+[Not written yet:
+ setcap <filename>
+]
+d29 1
+a29 1
+Andrew G. Morgan <morgan@@parc.power.net>
+@
diff --git a/RCS/pgp.keys.asc,v b/RCS/pgp.keys.asc,v
new file mode 100644
index 0000000..cdf61a5
--- /dev/null
+++ b/RCS/pgp.keys.asc,v
@@ -0,0 +1,158 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.3
+date 99.01.30.03.49.08; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 98.05.24.21.09.12; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.01.42.57; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@For future reference.
+@
+
+
+1.3
+log
+@added Andrey's key
+@
+text
+@Type Bits/KeyID Date User ID
+pub 1024/2A398175 1996/11/17 Andrew G. Morgan <morgan@@linux.kernel.org>
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: 2.6.3a
+
+mQCNAzKOhJ4AAAEEAJ9xYnZSD1kYanF+8GUBhHf/gx6hGd8ZNmS5qIC8Qb8rMcTI
++E16nV+FnNRlPRbShITYjq1TPvVK8gTliZf41N9LRQZw0rywRt1NQyhdfKgDWYxB
+kSOwK67oDjkzzC56XS2rrGI6K3Rz/VtYElRyuQ6ZyaKTGcgU/TTwrUUqOYF1AAUR
+tChBbmRyZXcgRy4gTW9yZ2FuIDxtb3JnYW5AcGFyYy5wb3dlci5uZXQ+iQCVAwUQ
+MvNT5Cd5aW9FNqjdAQFt+wP/elq589YoIgZewnFbhB/wZ9cvNBOuDwKT7B71s5L4
+DW3cbE1SaCLgCwgZ3P5KRmqf2Yma+zAmj3zA5BqLou9czdrVeBRiIq77vDWR01q+
+vqiaQD5egroboOPt8OwT0tyTUvFTN+jVJHaBkmoYePvBvAbHJJhKuXSoRdTOgIx2
+lp6JAJUDBRAyjoSfNPCtRSo5gXUBATTWA/9IJKdFUmfndQtVPkPiQ76BUHmYXAUV
+zs/r/3V/KV14HhaPAHijAn/eCsB8vbD/WG41cjYb8VCjDE6QRmn+ydbv+7FPbBFU
+X30J8hCBLB/Ft7CL+lkMsjoZ+2usH7Wqx+yiyRdq7QLohZZy2nXSJjRzp+OFci1E
+bK45M7J9uNvl6Q==
+=tk+w
+-----END PGP PUBLIC KEY BLOCK-----
+
+Type Bits/KeyID Date User ID
+pub 1024/4536A8DD 1996/01/28 Michael K. Johnson <johnsonm@@redhat.com>
+ Michael K. Johnson <johnsonm@@nigel.vnet.net>
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: 2.6.3a
+
+mQCNAzEK0l0AAAEEAMWweYcS6ov1RISP6E7lb3vgQOrmhBy6S/8zkuHo92IkQWXm
+V9AcMUY/eJPRJH6yI6o1ZKN4InT4uCkSIQOd2C8XyeIK5jFhpmP9DhoucacNL5H7
+oCV4wtFGhUDaDl9VeTtbWLSMESxJ4T/fL/IfkW95/Q2dF7zIDid5aW9FNqjdAAUR
+tChNaWNoYWVsIEsuIEpvaG5zb24gPGpvaG5zb25tQHJlZGhhdC5jb20+iQCVAwUQ
+MuqeiDTwrUUqOYF1AQEjywP/bCWLybbZSI8plyUSWD3yxwjsE+8BiOPGRu1AARUz
+GbVZq9LqPDyjFtH9DqgXULyZtCAk8ebZonH/h/0EnZTi4tiZg3BHKXhIlWQnNz4D
+QRdtUEmMNQzi9+3mU99CBGigsrDQnNrnI88ejo/0YY3gdt6752g5HAvY13h9A0ZP
+MFWJAJUDBRAxgAouJ3lpb0U2qN0BActVA/9vgBOUheUpLPiIry/+2qqJv+e+LnHw
+DgZqROpli9bhJ4wfb1sXPYkFzchR8BUeU0NY6HvAwxEilSNPE1yQoaJuy8POtTuu
+aFO4wvuLp0v5LuatXaU8EsncwjrBsWqRB6Dqd+jyq24Pjx0YKNSRJxceiBE8SBDW
+HESAhYTYCBLy77QsTWljaGFlbCBLLiBKb2huc29uIDxqb2huc29ubUBuaWdlbC52
+bmV0Lm5ldD6JAJUDBRAxGljWe01Ojay67k0BAf3qA/48N9OvgGk9nNR+Pg6aW3rK
+2Dy8t2RQdFGd4b7gBtZeXUAklq9ppYZtS+cXFHoQ8d7K8XBjHh+rgF2oOSBQUrQf
+eb8XkKSZQxB7DZVdi1gAsOzSwCrn4TWSSKc28P4Mjuj1Jr2f1FGST1+cGIl7JbhV
+kLGjmvOIgs7lS8FE0Hhm/4kAlQMFEDEWclxEcVNogr/H7QEBN1QD/1iY+KYQyOTz
+fgaBsx+Bt11kstmOlYhXx23yK2etG0p8XCD2r3aojGOTR/e3o2bLiJo4xe+iMhOM
+dvdSzxSPGQ20wX3jGJaRrRiSClFTQbZSelGG0FcOGfM3mL5zeHaXzRcRciK3VDkD
+IFzTQ3J5NJVBIVlAkxTMIxho758lR2SjiQCVAwUQMREqFnoDqzGe1QXFAQFdpAP/
+VPPoYO50seo1rLL28AA2PVKqo6BJwj0ZMsC14MDJEKryBbj/E4Ma25uSlzBjj+t9
+rbygoz0XWUQMLh8XPAEps3nE3n8FWROsdlucGzGiDGKVEygLPzCsjR7aGEspN1Y7
+4qOZPxbpGG7B5exOLur4ACY75m6oBh+PN+Q1liCIYXKJAJUDBRAxDpk1iGe2nxKR
+G10BAeQjBACmx4DyJacQXxuckDaKMTXa8v2Q7lQpPDyHdn1oAUsx1mrbSL55v2AI
+Q0riFWcFRTERpjAToCLgQjK1pKpmJcduiXURj6TPVKd88hYkuCIpn2hIaI7SCkd8
+HZlfFiuaxVN29UbbzHv3C+mseydpkPRrovqmOSuj2xAGFALo6Vl9U4kAlQMFEDEN
+eD5EFXDNRmtCiQEBRmoEAJAuyY0F5hbweDOdeAhxLWeiTl9jGwQYDS3T5B5/9ZpC
+bJ1yX7Pk2o7LvR9tg/Ji5sfMMvIpH48DNT4kyjmmChFXCUBccwd+33ugdTcYDwLR
+Cdt7k9r2yXz1LEH+lVNKOEIhuIq8/sX61hvFR7+qSABthTLrvvynycD5n2pG3F7L
+=aGjw
+-----END PGP PUBLIC KEY BLOCK-----
+
+Type Bits/KeyID Date User ID
+pub 1024/D4F4D901 1997/03/05 Cristian Gafton <gafton@@redhat.com>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: 2.6.3a
+
+mQCNAzMdU6sAAAEEAKLF73rRJ3RUtl+y4bLUOVOV7ataJ46ZHxDZeGAVi+/suwT9
+Kq7QdaeFc4Xwaq8PVWv7pZ4/qTwHUkdbjBVeLt+KOlprvKuadyAh9aG/SqmKkEvA
+hCS3yZDwNmeSLO7VIN5ko1nIwVD4kPJvS3xX6kn6jd4mvv/qGfGvxKXU9NkBAAUR
+tCNDcmlzdGlhbiBHYWZ0b24gPGdhZnRvbkBzb3Jvc2lzLnJvPokAlQMFEDMeTlI0
+8K1FKjmBdQEBmgQD/02JxAU6+fiaBKwRIFDdsLYTy8mPgYaoul9RIX450W5D5nY/
+/696F6TfmFUzvnrvTbZUDyLxHB0mnh4SrdKRKo57i7RDrdx3Mqlt/xP4R6nHwFed
+yTMvz3KB9tYuWfC1fJp69/VRIkMrw448zKkgqHUnAKxMIHvXnV3M9jd6lXSYiQCV
+AwUQMx1Tq/GvxKXU9NkBAQE3/gP/RZMe59OkBWS4whc9c6eac6zwcC/hNc1vyiZ5
+2TEHJ10PgtNtHchD7j3xsDO17/DGEZB23OQiPAeLdqnBr+y2uiSlQfYdpVHBHX3A
+uX3onc69LpEHmUAJAVOvfU1scnDtOH/KeVN3nwc6PWLxzLWzXfUbwLNK+LiPMNMV
+1qygu+s=
+=J4G2
+-----END PGP PUBLIC KEY BLOCK-----
+
+Type Bits/KeyID Date User ID
+pub 1024/A5D75B79 1997/03/01 Andrey V. Savochkin <saw@@msu.ru>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: 2.6.3a
+
+mQCNAzMYf1MAAAEEAK1S5jgmWnn8IS9mKoSpXu87f2soQhVZ3XdvsBCK2V7BojlU
+0+JJrK+2gMH5tavyFsQ6cKch6I4xH54cS4P4tNE9M7OtfoXOxejtp9U9KZio8T0X
+gM8qOS4fTQEfmdHSA5ETe5Vv+WPZ+/3SCo5kD1uIUUwppHDgJH+l396l11t5AAUR
+tCBBbmRyZXkgVi4gU2F2b2Noa2luIDxzYXdAbXN1LnJ1PokAlQMFEDaIUh008K1F
+KjmBdQEBFtkD/38mraXdr4aEYC6lxlG3cF+59XB6FjyBYhtwgNshpI2mB5XLr25p
+f4jMFNUqnY/bGjXWKwbNguzJ0ukD8TgOg1ZXQZztRso1t1Y2M1KPbwlqj8ib1bZG
+inQO/eqLrVwFH6F9CTiF0Fgy7faAIHN6BfE0o8earrcIwjT7sxRej3lziQCVAwUQ
+M35653fqPT1smcpJAQHeqgQAlXMOru6Rz1TkslVrWD0n7dvBUHQxs0HS1pcWJnZJ
+6kcYMLSA2RBi1fRabwzuOtzK60tOmfmnD7btcGBMMflOtfSulEg/xKNw2awEsNQK
+ULEIBsvrpMr0UN4hWkxTggDXaykg7rQqgrbAsicoLuTtPDIbc+yhQcFEVGJiPO/I
+tqiJAJUDBRAzfnUef89/VVw/1FkBAQ2lA/9q6FQM4RZzp75qxZ7jqAwUy9RFAKhp
+L63YFJX3i1JsUjNoO51pjj5pEAxVVQsorqbdsmpC2aOUTf1AufEcs1kLojb3tc19
+MhXPyHTJs66QqWutdP/yOW+CLzmILAsbEgI6O+toVZ0rHVXjEtRgKUnYReHLrlYj
+RKlBnkVc3NtPcIkAlQMFEDMYf1N/pd/epddbeQEBfKYD/3x/PkH2e+Cy7YXsfwxb
+y/n+6eNIbfakSYjkwN5tDOeaKhdQKUJBKVwAzD2yrLmMDx6uW+FUOTucb6Anau6R
+iKrAJq/a4DcpAeymo7cAthVU7en7HWwebQcL4wZGao1BJI+ulynki4sIqkfbGP83
+DK775eovl5X195ZkE/wNJvoi
+=V5TY
+-----END PGP PUBLIC KEY BLOCK-----
+@
+
+
+1.2
+log
+@updated the email addresses
+@
+text
+@d76 25
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+pub 1024/2A398175 1996/11/17 Andrew G. Morgan <morgan@@parc.power.net>
+d57 1
+a57 1
+pub 1024/D4F4D901 1997/03/05 Cristian Gafton <gafton@@sorosis.ro>
+d75 1
+@
diff --git a/README b/README
new file mode 100644
index 0000000..5341b8d
--- /dev/null
+++ b/README
@@ -0,0 +1,29 @@
+
+This is a library for getting and setting POSIX.1e (formerly POSIX 6)
+draft 15 capabilities.
+
+This library would not have been possible without the help of
+
+ Aleph1, Roland Buresund and Andrew Main, Alexander Kjeldaas.
+
+More information on capabilities in the Linux kernel can be found at
+
+ http://linux.kernel.org/pub/linux/libs/security/linux-privs/
+
+# INSTALLATION
+
+ Linux-Caps % make
+
+ builds the library and the programs
+
+ Linux-Caps % make install
+
+ installs the library libcap.XX.Y in /lib/
+ the binaries in /bin/
+ the <sys/capability.h> file in /usr/include
+
+* for some example programs look in progs.
+
+Cheers
+
+Andrew G. Morgan <morgan@linux.kernel.org>
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..5f68b88
--- /dev/null
+++ b/doc/Makefile
@@ -0,0 +1,38 @@
+#
+# $Id: Makefile,v 1.4 1998/05/24 22:50:27 morgan Exp $
+#
+# Makefile for libcap documentation
+#
+
+topdir=$(shell pwd)/..
+include $(topdir)/Make.Rules
+
+MAN2S = capget.2 capset.2
+MAN3S = cap_init.3 cap_free.3 cap_dup.3 \
+ cap_clear.3 cap_get_flag.3 cap_set_flag.3 \
+ cap_get_proc.3 cap_set_proc.3 \
+ cap_copy_ext.3 cap_size.3 cap_copy_int.3 \
+ cap_from_text.3 cap_to_text.3 _cap_names.3 \
+ capsetp.3 capgetp.3
+#MAN8S = getcap.8 setcap.8
+
+MANS = $(MAN2S) $(MAN3S) $(MAN8S)
+
+all: $(MANS)
+
+install:
+ mkdir -p -m 755 $(MANDIR)/man2 $(MANDIR)/man3
+ for man in \
+ $(MANDIR)/man2 $(MAN2S) \
+ $(MANDIR)/man3 $(MAN3S) \
+ ; \
+ do \
+ case $$man in \
+ /*) sub=$$man ; continue ;; \
+ esac; \
+ install -m 644 $$man $$sub ; \
+ done
+
+clean:
+ $(LOCALCLEAN)
+
diff --git a/doc/RCS/Makefile,v b/doc/RCS/Makefile,v
new file mode 100644
index 0000000..69f32d0
--- /dev/null
+++ b/doc/RCS/Makefile,v
@@ -0,0 +1,137 @@
+head 1.4;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.4
+date 98.05.24.22.50.27; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 97.05.14.05.16.29; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.05.04.05.31.57; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@for installing manuals
+@
+
+
+1.4
+log
+@updated for 2.1.104 release
+@
+text
+@#
+# $Id: Makefile,v 1.3 1997/05/14 05:16:29 morgan Exp morgan $
+#
+# Makefile for libcap documentation
+#
+
+topdir=$(shell pwd)/..
+include $(topdir)/Make.Rules
+
+MAN2S = capget.2 capset.2
+MAN3S = cap_init.3 cap_free.3 cap_dup.3 \
+ cap_clear.3 cap_get_flag.3 cap_set_flag.3 \
+ cap_get_proc.3 cap_set_proc.3 \
+ cap_copy_ext.3 cap_size.3 cap_copy_int.3 \
+ cap_from_text.3 cap_to_text.3 _cap_names.3 \
+ capsetp.3 capgetp.3
+#MAN8S = getcap.8 setcap.8
+
+MANS = $(MAN2S) $(MAN3S) $(MAN8S)
+
+all: $(MANS)
+
+install:
+ mkdir -p -m 755 $(MANDIR)/man2 $(MANDIR)/man3
+ for man in \
+ $(MANDIR)/man2 $(MAN2S) \
+ $(MANDIR)/man3 $(MAN3S) \
+ ; \
+ do \
+ case $$man in \
+ /*) sub=$$man ; continue ;; \
+ esac; \
+ install -m 644 $$man $$sub ; \
+ done
+
+clean:
+ $(LOCALCLEAN)
+
+@
+
+
+1.3
+log
+@autoconf rearrangement from Zefram
+@
+text
+@d2 1
+a2 1
+# $Id: Makefile,v 1.2 1997/05/04 05:31:57 morgan Exp morgan $
+d10 1
+a10 2
+MAN2S = _setproccap.2 _getproccap.2 \
+ _setfilecap.2 _getfilecap.2 _fsetfilecap.2 _fgetfilecap.2
+a12 1
+ cap_get_file.3 cap_set_file.3 cap_get_fd.3 cap_set_fd.3 \
+d15 3
+a17 2
+ cap_from_text.3 cap_to_text.3 _cap_names.3
+MAN8S = getcap.8 setcap.8
+d24 1
+a24 1
+ mkdir -p -m 755 $(MANDIR)/man2 $(MANDIR)/man3 $(MANDIR)/man8
+d28 1
+a28 1
+ $(MANDIR)/man8 $(MAN8S) ; \
+@
+
+
+1.2
+log
+@cleaner
+@
+text
+@d2 1
+a2 1
+# $Id: Makefile,v 1.1 1997/04/28 00:54:52 morgan Exp morgan $
+d7 1
+a7 1
+topdir=..
+d34 1
+a34 1
+ install -m 644 -o root -g root $$man $$sub ; \
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+# $Id$
+d26 10
+a35 3
+ install -m 644 -o root -g root $(MAN2S) $(MANDIR)/man2
+ install -m 644 -o root -g root $(MAN3S) $(MANDIR)/man3
+ install -m 644 -o root -g root $(MAN8S) $(MANDIR)/man8
+@
diff --git a/doc/RCS/_cap_names.3,v b/doc/RCS/_cap_names.3,v
new file mode 100644
index 0000000..2ae4e62
--- /dev/null
+++ b/doc/RCS/_cap_names.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_from_text.3
+@
diff --git a/doc/RCS/cap_clear.3,v b/doc/RCS/cap_clear.3,v
new file mode 100644
index 0000000..3d4ef0e
--- /dev/null
+++ b/doc/RCS/cap_clear.3,v
@@ -0,0 +1,169 @@
+head 1.2;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 97.05.24.19.45.28; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.2
+log
+@corrections from Aleph1
+@
+text
+@.\"
+.\" $Id: cap_clear.3,v 1.1 1997/04/28 00:54:52 morgan Exp morgan $
+.\"
+.TH CAP_CLEAR 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_clear, cap_get_flag, cap_set_flag \- capability data object manipulation
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "int cap_clear(cap_t " cap_p );
+.sp
+.BI "int cap_get_flag(cap_t " cap_p ", cap_value_t " cap ", cap_flag_t " flag ", cap_flag_value_t *" value_p ");"
+.sp
+.BI "int cap_set_flag(cap_t " cap_p ", cap_flag_t " flag ", int " ncap ", cap_value_t *" caps ", cap_flag_value_t " value ");"
+.SH USAGE
+.B cc ... -lcap
+.SH DESCRIPTION
+.B cap_clear
+initializes the capability state in working storage identified by
+.I cap_p
+in such a way that all capability flags are cleared.
+.PP
+.B cap_get_flag
+obtains the current value of the capability flag,
+.IR flag ,
+of the capability,
+.IR cap ,
+from the capability state identified by
+.I cap_p
+and places it in the location pointed to by
+.IR value_p .
+.PP
+.B cap_set_flag
+sets the flag,
+.IR flag ,
+of each capability in the array
+.I caps
+in the capability state identified by
+.I cap_p
+to
+.IR value .
+The argument,
+.IR ncap ,
+is used to specify the number of capabilities in the array,
+.IR caps .
+.PP
+A
+.B cap_value_t
+can identify any capability, such as
+.BR CAP_CHOWN .
+A
+.B cap_flag_t
+can be set to
+.BR CAP_EFFECTIVE ,
+.B CAP_INHERITABLE
+or
+.BR CAP_PERMITTED .
+A
+.B cap_flag_value_t
+can be
+.B CAP_CLEAR
+(0) or
+.B CAP_SET
+(1).
+.SH "RETURN VALUE"
+.BR cap_clear ,
+.B cap_get_flag
+and
+.B cap_set_flag
+return zero on success, and \-1 on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+indicating that one of the arguments is invalid.
+
+.SH "CONFORMING TO"
+These functions are specified by POSIX.1e.
+.SH "SEE ALSO"
+.IR cap_copy_ext (3),
+.IR cap_from_text (3),
+.IR cap_get_file (3),
+.IR cap_get_proc (3),
+.IR cap_init (3)
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+.\" $Id$
+d4 1
+a4 1
+.TH CAP_CLEAR 3 "26th April 1997" "" "Linux Programmer's Manual"
+d6 1
+a6 1
+cap_clear, cap_get_flag, cap_set_flag \- twiddle bits in capability sets
+d10 1
+a10 1
+.BI "int cap_clear(cap_t " caps );
+d12 1
+a12 1
+.BI "int cap_get_flag(cap_t " caps ", cap_value_t " capno ", cap_flag_t " set ", cap_flag_value_t *" result_p ");"
+d14 3
+a16 1
+.BI "int cap_set_flag(cap_t " caps ", cap_flag_t " set ", int " numcaps ", cap_value_t *" capnos ", cap_flag_value_t " state ");"
+d19 3
+a21 2
+clears all bits in the capability sets of
+.IR caps .
+d24 8
+a31 8
+extracts the state of capability number
+.I capno
+from capability set
+.I set
+in
+.IR caps ,
+and writes it into
+.IR *result_p .
+d34 12
+a45 10
+sets the state of capabilities. It sets capabilities in capability set
+.I set
+in
+.IR caps
+to state
+.IR state .
+The capabilities to set are specified in an array pointed to by
+.I capnos
+of length
+.IR numcaps .
+d49 1
+a49 1
+can be set to any capability number, such as
+@
diff --git a/doc/RCS/cap_copy_ext.3,v b/doc/RCS/cap_copy_ext.3,v
new file mode 100644
index 0000000..f6d427d
--- /dev/null
+++ b/doc/RCS/cap_copy_ext.3,v
@@ -0,0 +1,215 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.3
+date 97.05.24.19.45.28; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.05.04.05.32.28; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.3
+log
+@corrections from Aleph1
+@
+text
+@.\"
+.\" $Id: cap_copy_ext.3,v 1.2 1997/05/04 05:32:28 morgan Exp morgan $
+.\"
+.TH CAP_COPY_EXT 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_copy_ext, cap_size, cap_copy_int \- capability state external representation translation
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "ssize_t cap_size(cap_t " cap_p );
+.sp
+.BI "ssize_t cap_copy_ext(void *" ext_p ", cap_t " cap_p ", ssize_t " size );
+.sp
+.BI "cap_t cap_copy_int(const void *" ext_p );
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+These functions translate a capability state from an internal representation
+into an external one. The external representation is an exportable, contiguous,
+persistent representation of a capability state in user-managed space. The
+internal representation is managed by the capability functions in working
+storage.
+.PP
+.B cap_size
+returns the total length (in bytes) that the capability state in working
+storage identified by
+.I cap_p
+would require when converted by
+.BR cap_copy_ext .
+This function is used primarily to determine the amount of buffer space that
+must be provided to the
+.B cap_copy_ext
+function in order to hold the capability data record created from
+.IR cap_p .
+.PP
+.B cap_copy_ext
+copies a capability state in working storage, identified by
+.IR cap_p ,
+from system managed space to user-managed space (pointed to by
+.IR ext_p )
+and returns the length of the resulting data record. The size parameter
+represents the maximum size, in bytes, of the resulting data record. The
+.B cap_copy_ext
+function will do any conversions necessary to convert the capability state
+from the undefined internal format to an exportable, contiguous, persistent
+data record. It is the responsibility of the user to allocate a buffer large
+enough to hold the copied data. The buffer length required to hold the copied
+data may be obtained by a call to the
+.B cap_size
+function.
+.PP
+.B cap_copy_int
+copies a capability state from a capability data record in user-managed
+space to a new capability state in working storage, allocating any
+memory necessary, and returning a pointer to the newly created capability
+state. The function initializes the capability state and then copies
+the capability state from the record painted to by
+.I ext_p
+into the capability state, converting, if necessary, the data from a
+contiguous, persistent format to an undefined, internal format. Once
+copied into internal format, the object can be manipulated by the capability
+state manipulation functions. Note that the record pointed to by
+.I ext_p
+must have been obtained from a previous, successful call to
+.B cap_copy_ext
+for this function to work successfully. The caller should free any
+releasable memory, when the capability state in working storage is no
+longer required, by calling
+.B cap_free
+with the
+.I cap_t
+as an argument.
+.SH "RETURN VALUE"
+.B cap_size
+returns the length required to hold a capability data record on success,
+and -1 on failure.
+.PP
+.B cap_copy_ext
+returns the number of bytes placed in the user managed space pointed to by
+.I ext_p
+on success, and -1 on failure.
+.PP
+.B cap_copy_int
+returns a pointer to the newly created capability state in working storage
+on success, and NULL on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+.BR ENOMEM ,
+or
+.BR ERANGE .
+.SH "CONFORMING TO"
+These functions are specified by POSIX.1e.
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_from_text (3),
+.IR cap_get_file (3),
+.IR cap_get_proc (3),
+.IR cap_init (3)
+@
+
+
+1.2
+log
+@fixed title name
+@
+text
+@d2 1
+a2 1
+.\" $Id: cap_copy_ext.3,v 1.1 1997/04/28 00:54:52 morgan Exp morgan $
+d4 1
+a4 1
+.TH CAP_COPY_EXT 3 "26th April 1997" "" "Linux Programmer's Manual"
+d6 1
+a6 1
+cap_copy_ext, cap_size, cap_copy_int \- external representation of capability sets
+d10 1
+a10 1
+.BI "ssize_t cap_copy_ext(void *" extrep ", cap_t " caps ", ssize_t " length );
+d12 1
+a12 1
+.BI "ssize_t cap_size(cap_t " caps );
+d14 4
+a17 1
+.BI "cap_t cap_copy_int(void const *" extrep );
+d19 5
+a23 2
+These functions provide an external representation of POSIX.1e capabilities,
+suitable for storage in archives or communication over pipes, for example.
+d25 8
+d34 2
+a35 7
+copies the capability sets
+.I caps
+into the buffer
+.I extrep
+(of length
+.IR length ),
+and returns indicating how much of the buffer was actually used.
+d37 13
+d51 1
+a51 3
+returns indicating how large a buffer would be required to fully represent
+the capability set
+.IR caps .
+d54 12
+a65 3
+takes a buffer
+.IR extrep ,
+whose contents are the result of a
+d67 7
+a73 4
+call, and
+reforms it into an internal-format capability set.
+The return value must eventually be disposed of by passing it to
+.BR cap_free .
+d75 9
+d85 2
+a86 1
+returns a non-NULL value on success, and NULL on failure.
+d92 1
+d94 1
+a94 1
+.BR ENOMEM .
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+.\" $Id$
+d4 1
+a4 1
+.TH CAP_INIT 3 "26th April 1997" "" "Linux Programmer's Manual"
+@
diff --git a/doc/RCS/cap_copy_int.3,v b/doc/RCS/cap_copy_int.3,v
new file mode 100644
index 0000000..508f859
--- /dev/null
+++ b/doc/RCS/cap_copy_int.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_copy_ext.3
+@
diff --git a/doc/RCS/cap_dup.3,v b/doc/RCS/cap_dup.3,v
new file mode 100644
index 0000000..18f19ac
--- /dev/null
+++ b/doc/RCS/cap_dup.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_init.3
+@
diff --git a/doc/RCS/cap_free.3,v b/doc/RCS/cap_free.3,v
new file mode 100644
index 0000000..18f19ac
--- /dev/null
+++ b/doc/RCS/cap_free.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_init.3
+@
diff --git a/doc/RCS/cap_from_text.3,v b/doc/RCS/cap_from_text.3,v
new file mode 100644
index 0000000..aae3806
--- /dev/null
+++ b/doc/RCS/cap_from_text.3,v
@@ -0,0 +1,312 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.3
+date 97.05.24.19.45.28; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.05.04.05.32.50; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.3
+log
+@corrections from Aleph1
+@
+text
+@.\"
+.\" $Id: cap_from_text.3,v 1.2 1997/05/04 05:32:50 morgan Exp morgan $
+.\" written by Andrew Main <zefram@@dcs.warwick.ac.uk>
+.\"
+.TH CAP_FROM_TEXT 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_from_text, cap_to_text, _cap_names \- capability state textual representation translation
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "cap_t cap_from_text(const char *" buf_p );
+.sp
+.BI "char *cap_to_text(cap_t " caps ", ssize_t *" length_p );
+.sp
+.B extern char const *_cap_names[];
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+These functions translate a capability state from an internal representation
+into a textual one. The internal representation is managed by the capability
+functions in working storage. The textual representation is a structured,
+human-readable, string suitable for display.
+.PP
+.B cap_from_text
+allocates and initializes a capability state in working storage. It then
+sets the contents of this newly-created capability state to the state
+represented by human-readable, null terminated character string pointed to by
+.IR buf_p .
+It returns a pointer to the newly created capability state. The
+caller should free any releasable memory, when the capability state in working
+storage is no longer required, by calling
+.B cap_free
+with
+.I cap_t
+as an argument. The function returns an error if it cannot parse the
+contents of the string pointed to by
+.I buf_p
+or does not recognize any
+.I capability_name
+or flag character as valid. The function also returns an error if any flag
+is both set and cleared within a single clause.
+.PP
+.B cap_to_text
+converts the capability state in working storage identified by
+.I cap_p
+into a null terminated human-readable string. This function allocates any
+memory necessary to contain the string, and returns a pointer to the string. If
+the pointer
+.I len_p
+is not
+.BR NULL ,
+the function shall also return the full length of the string (not including
+the null terminator) in the location pointed to by
+.IR len_p .
+The capability state in working storage, identified by
+.IR cap_p ,
+is completely represented in the character string. The caller should
+free any releasable memory, when the capability state in working
+storage is no longer required, by calling
+.B cap_free
+with
+.B cap_p
+as an argument.
+.PP
+.B _cap_names
+is an array of textual names for capability numbers. Unnamed capabilities
+have a NULL entry. (This array is not defined by POSIX.1e.)
+.SH "TEXTUAL REPRESENTATION"
+A textual representation of capability sets consists of one or more
+whitespace-separated
+.IR clauses .
+Each clause specifies some operations to a capability set; the set
+starts out with all capabilities lowered, and the meaning of the
+string is the state of the capability set after all the clauses have
+been applied in order.
+.PP
+Each clause consists of a list of comma-separated capability names
+(or the word
+.RB ` all '),
+followed by an
+.IR action-list .
+An action-list consists of a sequence of
+.I operator flag
+pairs. Legal operators are:
+.RB ` = "', '" + "', and `" - "'."
+Legal flags are:
+.RB ` e "', `" i "', and `" p "'."
+These flags are case-sensitive and specify the Effective, Inheritable
+and Permitted sets respectively.
+.PP
+In the capability name lists, all names are case-insensitive. The
+special name
+.RB ` all '
+specifies all capabilities; it is equivalent to a list naming every
+capability individually.
+.PP
+Although not defined by POSIX, unnamed capabilities can be specified
+by number.
+.PP
+The
+.RB ` = '
+operator indicates that the listed capabilities are first reset in
+all three capability sets. The subsequent flags (which are optional
+when associated with this operator) indicate that the listed
+capabilities for the corresponding set are to be raised. For example:
+"all=p" means lower every capability in the Effective and Inheritable
+sets but raise all of the Permitted capabilities;
+or, "cap_fowner=ep" means raise the Effective and Permitted
+override-file-ownership capability, while lowering this Inheritable
+capability.
+.PP
+In the case that the leading operator is
+.RB ` = ',
+and no list of capabilities is provided, the action-list is assumed to
+refer to `all' capabilities. For example, the following three
+clauses are equivalent to each other (and indicate a completely empty
+capability set): "all="; "="; "cap_chown,<every-other-capability>=".
+.PP
+The operators, `+' and `-' both require an explicit preceding
+capability list and one or more explicit trailing flags. The `+'
+operator will raise all of the listed capabilities in the flagged
+capability sets. The `-' operator will lower all of the listed
+capabilities in the flagged capability sets. For example:
+"all+p" will raise all of the Permitted capabilities; "cap_fowner+p-i"
+will raise the override-file-ownership capability in the Permitted
+capability set and lower this Inheritable capability;
+"cap_fowner+pe-i" and "cap_fowner=+pe" are equivalent.
+.SH "RETURN VALUE"
+.B cap_from_text
+and
+.B cap_to_text
+return a non-NULL value on success, and NULL on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+or
+.BR ENOMEM .
+.SH "CONFORMING TO"
+.B cap_from_text
+and
+.B cap_to_text
+are specified by POSIX.1e.
+.B _cap_names
+is a Linux extension.
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_copy_ext (3),
+.IR cap_get_file (3),
+.IR cap_get_proc (3),
+.IR cap_init (3)
+@
+
+
+1.2
+log
+@fixed title name and also made consistent with text handling
+@
+text
+@d2 1
+a2 1
+.\" $Id: cap_from_text.3,v 1.1 1997/04/28 00:54:52 morgan Exp morgan $
+d5 1
+a5 1
+.TH CAP_FROM_TEXT 3 "26th April 1997" "" "Linux Programmer's Manual"
+d7 1
+a7 1
+cap_from_text, cap_to_text, _cap_names \- textual representation of capability sets
+d11 1
+a11 1
+.BI "cap_t cap_from_text(char const *" string );
+d20 4
+a23 3
+These functions provide the interface to a textual representation of
+POSIX.1e capabilities, suitable for display to and specification by
+users.
+d26 17
+a42 5
+interprets
+.I string
+and generates the corresponding internal-format capability set.
+The return value must eventually be disposed of by passing it to
+.BR cap_free .
+d45 20
+a64 6
+formats
+.I caps
+into a string in a fixed buffer, returning a pointer to the buffer,
+and storing the length of the string in
+.IR *length_p .
+The buffer will be overwritten on the next call.
+d73 1
+a73 1
+Each clause specifies some modification to a capability set; the set
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+.\" $Id$
+d5 1
+a5 1
+.TH CAP_INIT 3 "26th April 1997" "" "Linux Programmer's Manual"
+d20 3
+a22 2
+These functions provide a textual representation of POSIX.1e capabilities,
+suitable for display to and specification by users.
+d43 1
+a43 1
+A textual representation of capability sets consists of zero or more
+d46 8
+a53 5
+Each clause specifies some modification to a capability set; the set starts
+out empty, and the meaning of the string is the state of the capability set
+after all the clauses have been applied in order.
+.PP
+Each clause consists of an optional list of comma-separated capability names,
+d55 9
+a63 3
+.IR operation ,
+followed by a possibly empty sequence of
+.IR flags .
+d65 2
+a66 1
+In the capability name lists, all names are case-insensitive. The special name
+d68 5
+a72 27
+specifies all capabilities; it is equivalent to a list naming every capability
+individually. If the list is omitted, it defaults to
+.RB ` all '.
+Unnamed capabilities can be specified by number.
+.PP
+The sequence of flags specifies a set of capability sets. The flags
+.RB ` e ',
+.RB ` i '
+and
+.RB ` p ',
+which are case-sensitive, specify the Effective, Inheritable and Permitted
+sets respectively. The empty sequence of flags specifies none of these sets.
+.PP
+The operation must be one of
+.RB ` + ',
+.RB ` - '
+or
+.RB ` = '.
+.PP
+If the operation is
+.RB ` + ',
+then the listed capability flags are
+.I set
+in the listed capability sets. Also, as an exception, an
+empty capability list is not permitted; if
+.RB ` all '
+is desired it must be specified explicitly.
+d74 11
+a84 5
+If the operation is
+.RB ` - ',
+then the listed capability flags are
+.I cleared
+in the listed capability sets.
+d86 1
+a86 1
+If the operation is
+d88 14
+a101 5
+then the listed capability flags are
+.I set
+in the listed capability sets and
+.I cleared
+in all others.
+@
diff --git a/doc/RCS/cap_get_fd.3,v b/doc/RCS/cap_get_fd.3,v
new file mode 100644
index 0000000..6ccba9e
--- /dev/null
+++ b/doc/RCS/cap_get_fd.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_get_file.3
+@
diff --git a/doc/RCS/cap_get_flag.3,v b/doc/RCS/cap_get_flag.3,v
new file mode 100644
index 0000000..1b2deda
--- /dev/null
+++ b/doc/RCS/cap_get_flag.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_clear.3
+@
diff --git a/doc/RCS/cap_get_proc.3,v b/doc/RCS/cap_get_proc.3,v
new file mode 100644
index 0000000..313ea0b
--- /dev/null
+++ b/doc/RCS/cap_get_proc.3,v
@@ -0,0 +1,236 @@
+head 1.4;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.4
+date 98.05.24.22.49.32; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 98.05.24.21.01.49; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.05.24.19.45.28; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.4
+log
+@corrected the list of processes with CAP_SETPCAP enabled
+@
+text
+@.\"
+.\" $Id: cap_get_proc.3,v 1.3 1998/05/24 21:01:49 morgan Exp morgan $
+.\"
+.TH CAP_GET_PROC 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_get_proc, cap_set_proc \- POSIX capability manipulation on
+processes
+.sp
+capgetp, capsetp \- Linux specific capability manipulation on
+arbitrary processes
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.B cap_t cap_get_proc(void);
+.br
+.BI "int cap_set_proc(cap_t " cap_p );
+.sp
+.B #undef _POSIX_SOURCE
+.br
+.B #include <sys/capability.h>
+.sp
+.BI "cap_t capgetp(pid_t " pid ", cap_t " cap_d );
+.br
+.BI "cap_t capsetp(pid_t " pid ", cap_t " cap_d );
+
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+.B cap_get_proc
+allocates a capability state in working storage, sets its state to
+that of the calling process, and returns a pointer to this newly
+created capability state. The caller should free any releasable
+memory, when the capability state in working storage is no longer
+required, by calling
+.B cap_free
+with the
+.I cap_t
+as an argument.
+.PP
+.B cap_set_proc
+sets the values for all capability flags for all capabilities with the
+capability state identified by
+.IR cap_p .
+The new capability state of the process will be completely determined by
+the contents of
+.I cap_p
+upon successful return from this function. If any flag in
+.I cap_p
+is set for any capability not currently permitted for the calling process,
+the function will fail, and the capability state of the process will remain
+unchanged.
+.PP
+.B capgetp
+fills an existing
+.BR cap_d ,
+see
+.BR cap_init (3),
+with the process capabilities of the process indicated by
+.IR pid .
+This information can also be obtained from the
+.B /proc/<pid>/status
+file.
+.PP
+.B capsetp
+attempts to set the capabilities of some other process(es),
+.IR pid .
+If
+.I pid
+is positive it refers to a specific process; if it is zero, it refers
+to the current process; -1 refers to all processes other than the
+current process and process '1' (typically
+.BR init (8));
+other negative values refer to the
+.I -pid
+process-group. In order to use this function, the current process
+must have
+.B CAP_SETPCAP
+raised in its Effective capability set. The capabilities set in the
+target process(es) are those contained in
+.IR cap_d .
+
+.SH "RETURN VALUE"
+.B cap_get_proc
+returns a non-NULL value on success, and NULL on failure.
+.PP
+.BR cap_set_proc ", " capgetp " and " capsetp
+return zero for success, and \-1 on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+.BR EPERM,
+or
+.BR ENOMEM .
+.SH "CONFORMING TO"
+.B cap_set_proc
+and
+.B cap_get_proc
+are functions specified in the draft for POSIX.1e.
+
+.SH "NOTES"
+The function
+.B capsetp
+should be used with care. It exists, primarily, to overcome a lack of
+support for capabilities in any of the filesystems supported by Linux.
+The semantics of this function may change as it is better understood.
+Please note, by default, the only processes that have
+.B CAP_SETPCAP
+available to them are processes started as a kernel-thread.
+(Typically this includes
+.BR init (8),
+kflushd and kswapd). You will need to recompile the kernel to modify
+this default.
+
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_copy_ext (3),
+.IR cap_from_text (3),
+.IR cap_get_file (3),
+.IR cap_init (3)
+@
+
+
+1.3
+log
+@added capsetp and capgetp descriptions
+@
+text
+@d2 1
+a2 1
+.\" $Id: cap_get_proc.3,v 1.2 1997/05/24 19:45:28 morgan Exp morgan $
+d109 1
+a109 1
+Please note, by default, the only process that has
+d111 5
+a115 3
+available to it, is process 1 (typically
+.BR init (8)).
+You will need to recompile the kernel to modify this default.
+@
+
+
+1.2
+log
+@corrections from Aleph1
+@
+text
+@d2 1
+a2 1
+.\" $Id: cap_get_proc.3,v 1.1 1997/04/28 00:54:52 morgan Exp morgan $
+d6 5
+a10 1
+cap_get_proc, cap_set_proc \- capability manipulation on processes
+d15 2
+d18 8
+a25 1
+.BI "int cap_set_proc(cap_t " cap_p );
+d53 30
+d87 2
+a88 2
+.B cap_set_proc
+returns zero on success, and \-1 on failure.
+d98 17
+a114 1
+These functions are specified by POSIX.1e.
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+.\" $Id$
+d4 1
+a4 1
+.TH CAP_GET_PROC 3 "26th April 1997" "" "Linux Programmer's Manual"
+d6 1
+a6 1
+cap_get_proc, cap_set_proc \- get/set capabilities of the process
+d12 4
+a15 1
+.BI "int cap_set_proc(cap_t " caps );
+d18 9
+a26 3
+returns the capability sets of the process.
+The returned value must later be disposed of by passing it to
+.BR cap_free .
+d29 11
+a39 2
+sets the capabilities of the process to
+.IR caps .
+d46 8
+@
diff --git a/doc/RCS/cap_init.3,v b/doc/RCS/cap_init.3,v
new file mode 100644
index 0000000..df24e00
--- /dev/null
+++ b/doc/RCS/cap_init.3,v
@@ -0,0 +1,157 @@
+head 1.2;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.2
+date 97.05.24.19.45.28; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.2
+log
+@corrections from Aleph1
+@
+text
+@.\"
+.\" $Id: cap_init.3,v 1.1 1997/04/28 00:54:52 morgan Exp morgan $
+.\" written by Andrew Main <zefram@@dcs.warwick.ac.uk>
+.\"
+.TH CAP_INIT 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_init, cap_free, cap_dup \- capability data object storage management
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.B cap_t cap_init(void);
+.sp
+.BI "int cap_free(void *" obj_d );
+.sp
+.BI "cap_t cap_dup(cap_t " cap_p );
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+The capabilities associated with a file or process are never edited
+directly. Instead, working storage is allocated to contain a
+representation of the capability state. Capabilities are edited and
+manipulated only within this working storage area. Once editing of
+the capability state is complete, the updated capability state is used
+to replace the capability state associated with the file or process.
+.PP
+.B cap_init
+creates a capability state in working storage and return a pointer to
+the capability state. The initial value of all flags are cleared. The
+caller should free any releasable memory, when the capability state in
+working storage is no longer required, by calling
+.B cap_free
+with the
+.I cap_t
+as an argument.
+.PP
+.B cap_free
+liberates any releasable memory that has been allocated to the
+capability state identified by
+.IR obj_d .
+The
+.I obj_d
+argument may identify either a
+.I cap_t
+entity, or a
+.I char *
+entity allocated by the
+.B cap_to_text
+function.
+.PP
+.B cap_dup
+returns a duplicate capability state in working storage given by the
+source object
+.IR cap_p ,
+allocating any memory necessary, and returning a
+pointer to the newly created capability state. Once duplicated, no
+operation on either capability state affects the other in any way.
+.SH "RETURN VALUE"
+.B cap_init
+and
+.B cap_dup
+return a non-NULL value on success, and NULL on failure.
+.PP
+.B cap_free
+returns zero on success, and \-1 on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+or
+.BR ENOMEM .
+.SH "CONFORMING TO"
+These functions are specified by POSIX.1e.
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_copy_ext (3),
+.IR cap_from_text (3),
+.IR cap_get_file (3),
+.IR cap_get_proc (3)
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+.\" $Id$
+d5 1
+a5 1
+.TH CAP_INIT 3 "26th April 1997" "" "Linux Programmer's Manual"
+d7 1
+a7 1
+cap_init, cap_free, cap_dup \- manipulate capability sets
+d13 1
+a13 1
+.BI "int cap_free(cap_t *" caps_p );
+d15 1
+a15 1
+.BI "cap_t cap_dup(cap_t " caps );
+d20 6
+a25 6
+POSIX.1e capability sets are manipulated abstractly via these interfaces. A
+.B cap_t
+is a pointer to allocated memory, containing data maintained by the
+capability library, that should not be modified directly.
+The object represents a group of three sets of capability bits; the three
+sets are the Effective, Inheritable and Permitted sets.
+d28 8
+a35 5
+returns a newly-allocated empty capability set. It is the caller's
+responsibility to eventually dispose of the capability set with
+.BR cap_free ,
+as it is with all the other functions that return a
+.BR cap_t .
+d38 12
+a49 5
+frees the resources associated with the capability set
+.IR *caps_p ,
+and sets
+.I *caps_p
+to NULL.
+d52 6
+a57 1
+returns a newly-allocated duplicate of the provided capability set.
+@
diff --git a/doc/RCS/cap_set_fd.3,v b/doc/RCS/cap_set_fd.3,v
new file mode 100644
index 0000000..6ccba9e
--- /dev/null
+++ b/doc/RCS/cap_set_fd.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_get_file.3
+@
diff --git a/doc/RCS/cap_set_file.3,v b/doc/RCS/cap_set_file.3,v
new file mode 100644
index 0000000..6ccba9e
--- /dev/null
+++ b/doc/RCS/cap_set_file.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_get_file.3
+@
diff --git a/doc/RCS/cap_set_flag.3,v b/doc/RCS/cap_set_flag.3,v
new file mode 100644
index 0000000..1b2deda
--- /dev/null
+++ b/doc/RCS/cap_set_flag.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_clear.3
+@
diff --git a/doc/RCS/cap_set_proc.3,v b/doc/RCS/cap_set_proc.3,v
new file mode 100644
index 0000000..1dd099e
--- /dev/null
+++ b/doc/RCS/cap_set_proc.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_get_proc.3
+@
diff --git a/doc/RCS/cap_size.3,v b/doc/RCS/cap_size.3,v
new file mode 100644
index 0000000..508f859
--- /dev/null
+++ b/doc/RCS/cap_size.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_copy_ext.3
+@
diff --git a/doc/RCS/cap_to_text.3,v b/doc/RCS/cap_to_text.3,v
new file mode 100644
index 0000000..2ae4e62
--- /dev/null
+++ b/doc/RCS/cap_to_text.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_from_text.3
+@
diff --git a/doc/RCS/capget.2,v b/doc/RCS/capget.2,v
new file mode 100644
index 0000000..6a07639
--- /dev/null
+++ b/doc/RCS/capget.2,v
@@ -0,0 +1,66 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 98.05.24.21.05.20; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@man page for the kernel API
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.\"
+.\" $Id: _setproccap.2,v 1.1 1997/04/28 00:54:52 morgan Exp $
+.\" written by Andrew Morgan <morgan@@linux.kernel.org>
+.\"
+.TH CAPGET 2 "17th May 1998" "Linux 2.1" "Linux Programmer's Manual"
+.SH NAME
+capget, capset \- set/get process capabilities
+.SH SYNOPSIS
+.B #undef _POSIX_SOURCE
+.br
+.B #include <sys/capability.h>
+.sp
+.BI "int capget(cap_user_header_t " header ", cap_user_data_t " data );
+.sp
+.BI "int capset(cap_user_header_t " header ", const cap_user_data_t " data );
+.SH DESCRIPTION
+These two functions are the raw kernel interface for getting and
+setting capabilities. The kernel API is likely to change and use of
+these functions (in particular the format of the
+.B cap_user_*_t
+types) is subject to change with each kernel revision.
+.sp
+These system calls are specific to Linux.
+The portable interfaces are
+.IR cap_set_proc (3)
+and
+.IR cap_get_proc (3).
+.SH "RETURN VALUE"
+On success, zero is returned. On error, -1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.SB EINVAL
+One of the arguments was invalid.
+.TP
+.SB EPERM
+An attempt was made to add a capability to the Permitted set, or to set
+a capability in the Effective or Inheritable sets that is not in the
+Permitted set.
+
+
+@
diff --git a/doc/RCS/capgetp.3,v b/doc/RCS/capgetp.3,v
new file mode 100644
index 0000000..4117f3a
--- /dev/null
+++ b/doc/RCS/capgetp.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 98.05.24.21.05.20; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@links for other functions
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_get_proc.3
+@
diff --git a/doc/RCS/capset.2,v b/doc/RCS/capset.2,v
new file mode 100644
index 0000000..a961191
--- /dev/null
+++ b/doc/RCS/capset.2,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 98.05.24.21.05.20; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@links for other functions
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man2/capget.2
+@
diff --git a/doc/RCS/capsetp.3,v b/doc/RCS/capsetp.3,v
new file mode 100644
index 0000000..4117f3a
--- /dev/null
+++ b/doc/RCS/capsetp.3,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 98.05.24.21.05.20; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@links for other functions
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man3/cap_get_proc.3
+@
diff --git a/doc/_cap_names.3 b/doc/_cap_names.3
new file mode 100644
index 0000000..83ec8b5
--- /dev/null
+++ b/doc/_cap_names.3
@@ -0,0 +1 @@
+.so man3/cap_from_text.3
diff --git a/doc/cap_clear.3 b/doc/cap_clear.3
new file mode 100644
index 0000000..859053e
--- /dev/null
+++ b/doc/cap_clear.3
@@ -0,0 +1,85 @@
+.\"
+.\" $Id: cap_clear.3,v 1.2 1997/05/24 19:45:28 morgan Exp $
+.\"
+.TH CAP_CLEAR 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_clear, cap_get_flag, cap_set_flag \- capability data object manipulation
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "int cap_clear(cap_t " cap_p );
+.sp
+.BI "int cap_get_flag(cap_t " cap_p ", cap_value_t " cap ", cap_flag_t " flag ", cap_flag_value_t *" value_p ");"
+.sp
+.BI "int cap_set_flag(cap_t " cap_p ", cap_flag_t " flag ", int " ncap ", cap_value_t *" caps ", cap_flag_value_t " value ");"
+.SH USAGE
+.B cc ... -lcap
+.SH DESCRIPTION
+.B cap_clear
+initializes the capability state in working storage identified by
+.I cap_p
+in such a way that all capability flags are cleared.
+.PP
+.B cap_get_flag
+obtains the current value of the capability flag,
+.IR flag ,
+of the capability,
+.IR cap ,
+from the capability state identified by
+.I cap_p
+and places it in the location pointed to by
+.IR value_p .
+.PP
+.B cap_set_flag
+sets the flag,
+.IR flag ,
+of each capability in the array
+.I caps
+in the capability state identified by
+.I cap_p
+to
+.IR value .
+The argument,
+.IR ncap ,
+is used to specify the number of capabilities in the array,
+.IR caps .
+.PP
+A
+.B cap_value_t
+can identify any capability, such as
+.BR CAP_CHOWN .
+A
+.B cap_flag_t
+can be set to
+.BR CAP_EFFECTIVE ,
+.B CAP_INHERITABLE
+or
+.BR CAP_PERMITTED .
+A
+.B cap_flag_value_t
+can be
+.B CAP_CLEAR
+(0) or
+.B CAP_SET
+(1).
+.SH "RETURN VALUE"
+.BR cap_clear ,
+.B cap_get_flag
+and
+.B cap_set_flag
+return zero on success, and \-1 on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+indicating that one of the arguments is invalid.
+
+.SH "CONFORMING TO"
+These functions are specified by POSIX.1e.
+.SH "SEE ALSO"
+.IR cap_copy_ext (3),
+.IR cap_from_text (3),
+.IR cap_get_file (3),
+.IR cap_get_proc (3),
+.IR cap_init (3)
diff --git a/doc/cap_copy_ext.3 b/doc/cap_copy_ext.3
new file mode 100644
index 0000000..3483b54
--- /dev/null
+++ b/doc/cap_copy_ext.3
@@ -0,0 +1,102 @@
+.\"
+.\" $Id: cap_copy_ext.3,v 1.3 1997/05/24 19:45:28 morgan Exp $
+.\"
+.TH CAP_COPY_EXT 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_copy_ext, cap_size, cap_copy_int \- capability state external representation translation
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "ssize_t cap_size(cap_t " cap_p );
+.sp
+.BI "ssize_t cap_copy_ext(void *" ext_p ", cap_t " cap_p ", ssize_t " size );
+.sp
+.BI "cap_t cap_copy_int(const void *" ext_p );
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+These functions translate a capability state from an internal representation
+into an external one. The external representation is an exportable, contiguous,
+persistent representation of a capability state in user-managed space. The
+internal representation is managed by the capability functions in working
+storage.
+.PP
+.B cap_size
+returns the total length (in bytes) that the capability state in working
+storage identified by
+.I cap_p
+would require when converted by
+.BR cap_copy_ext .
+This function is used primarily to determine the amount of buffer space that
+must be provided to the
+.B cap_copy_ext
+function in order to hold the capability data record created from
+.IR cap_p .
+.PP
+.B cap_copy_ext
+copies a capability state in working storage, identified by
+.IR cap_p ,
+from system managed space to user-managed space (pointed to by
+.IR ext_p )
+and returns the length of the resulting data record. The size parameter
+represents the maximum size, in bytes, of the resulting data record. The
+.B cap_copy_ext
+function will do any conversions necessary to convert the capability state
+from the undefined internal format to an exportable, contiguous, persistent
+data record. It is the responsibility of the user to allocate a buffer large
+enough to hold the copied data. The buffer length required to hold the copied
+data may be obtained by a call to the
+.B cap_size
+function.
+.PP
+.B cap_copy_int
+copies a capability state from a capability data record in user-managed
+space to a new capability state in working storage, allocating any
+memory necessary, and returning a pointer to the newly created capability
+state. The function initializes the capability state and then copies
+the capability state from the record painted to by
+.I ext_p
+into the capability state, converting, if necessary, the data from a
+contiguous, persistent format to an undefined, internal format. Once
+copied into internal format, the object can be manipulated by the capability
+state manipulation functions. Note that the record pointed to by
+.I ext_p
+must have been obtained from a previous, successful call to
+.B cap_copy_ext
+for this function to work successfully. The caller should free any
+releasable memory, when the capability state in working storage is no
+longer required, by calling
+.B cap_free
+with the
+.I cap_t
+as an argument.
+.SH "RETURN VALUE"
+.B cap_size
+returns the length required to hold a capability data record on success,
+and -1 on failure.
+.PP
+.B cap_copy_ext
+returns the number of bytes placed in the user managed space pointed to by
+.I ext_p
+on success, and -1 on failure.
+.PP
+.B cap_copy_int
+returns a pointer to the newly created capability state in working storage
+on success, and NULL on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+.BR ENOMEM ,
+or
+.BR ERANGE .
+.SH "CONFORMING TO"
+These functions are specified by POSIX.1e.
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_from_text (3),
+.IR cap_get_file (3),
+.IR cap_get_proc (3),
+.IR cap_init (3)
diff --git a/doc/cap_copy_int.3 b/doc/cap_copy_int.3
new file mode 100644
index 0000000..2e6e89c
--- /dev/null
+++ b/doc/cap_copy_int.3
@@ -0,0 +1 @@
+.so man3/cap_copy_ext.3
diff --git a/doc/cap_dup.3 b/doc/cap_dup.3
new file mode 100644
index 0000000..7810cff
--- /dev/null
+++ b/doc/cap_dup.3
@@ -0,0 +1 @@
+.so man3/cap_init.3
diff --git a/doc/cap_free.3 b/doc/cap_free.3
new file mode 100644
index 0000000..7810cff
--- /dev/null
+++ b/doc/cap_free.3
@@ -0,0 +1 @@
+.so man3/cap_init.3
diff --git a/doc/cap_from_text.3 b/doc/cap_from_text.3
new file mode 100644
index 0000000..26bd585
--- /dev/null
+++ b/doc/cap_from_text.3
@@ -0,0 +1,153 @@
+.\"
+.\" $Id: cap_from_text.3,v 1.3 1997/05/24 19:45:28 morgan Exp $
+.\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+.\"
+.TH CAP_FROM_TEXT 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_from_text, cap_to_text, _cap_names \- capability state textual representation translation
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "cap_t cap_from_text(const char *" buf_p );
+.sp
+.BI "char *cap_to_text(cap_t " caps ", ssize_t *" length_p );
+.sp
+.B extern char const *_cap_names[];
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+These functions translate a capability state from an internal representation
+into a textual one. The internal representation is managed by the capability
+functions in working storage. The textual representation is a structured,
+human-readable, string suitable for display.
+.PP
+.B cap_from_text
+allocates and initializes a capability state in working storage. It then
+sets the contents of this newly-created capability state to the state
+represented by human-readable, null terminated character string pointed to by
+.IR buf_p .
+It returns a pointer to the newly created capability state. The
+caller should free any releasable memory, when the capability state in working
+storage is no longer required, by calling
+.B cap_free
+with
+.I cap_t
+as an argument. The function returns an error if it cannot parse the
+contents of the string pointed to by
+.I buf_p
+or does not recognize any
+.I capability_name
+or flag character as valid. The function also returns an error if any flag
+is both set and cleared within a single clause.
+.PP
+.B cap_to_text
+converts the capability state in working storage identified by
+.I cap_p
+into a null terminated human-readable string. This function allocates any
+memory necessary to contain the string, and returns a pointer to the string. If
+the pointer
+.I len_p
+is not
+.BR NULL ,
+the function shall also return the full length of the string (not including
+the null terminator) in the location pointed to by
+.IR len_p .
+The capability state in working storage, identified by
+.IR cap_p ,
+is completely represented in the character string. The caller should
+free any releasable memory, when the capability state in working
+storage is no longer required, by calling
+.B cap_free
+with
+.B cap_p
+as an argument.
+.PP
+.B _cap_names
+is an array of textual names for capability numbers. Unnamed capabilities
+have a NULL entry. (This array is not defined by POSIX.1e.)
+.SH "TEXTUAL REPRESENTATION"
+A textual representation of capability sets consists of one or more
+whitespace-separated
+.IR clauses .
+Each clause specifies some operations to a capability set; the set
+starts out with all capabilities lowered, and the meaning of the
+string is the state of the capability set after all the clauses have
+been applied in order.
+.PP
+Each clause consists of a list of comma-separated capability names
+(or the word
+.RB ` all '),
+followed by an
+.IR action-list .
+An action-list consists of a sequence of
+.I operator flag
+pairs. Legal operators are:
+.RB ` = "', '" + "', and `" - "'."
+Legal flags are:
+.RB ` e "', `" i "', and `" p "'."
+These flags are case-sensitive and specify the Effective, Inheritable
+and Permitted sets respectively.
+.PP
+In the capability name lists, all names are case-insensitive. The
+special name
+.RB ` all '
+specifies all capabilities; it is equivalent to a list naming every
+capability individually.
+.PP
+Although not defined by POSIX, unnamed capabilities can be specified
+by number.
+.PP
+The
+.RB ` = '
+operator indicates that the listed capabilities are first reset in
+all three capability sets. The subsequent flags (which are optional
+when associated with this operator) indicate that the listed
+capabilities for the corresponding set are to be raised. For example:
+"all=p" means lower every capability in the Effective and Inheritable
+sets but raise all of the Permitted capabilities;
+or, "cap_fowner=ep" means raise the Effective and Permitted
+override-file-ownership capability, while lowering this Inheritable
+capability.
+.PP
+In the case that the leading operator is
+.RB ` = ',
+and no list of capabilities is provided, the action-list is assumed to
+refer to `all' capabilities. For example, the following three
+clauses are equivalent to each other (and indicate a completely empty
+capability set): "all="; "="; "cap_chown,<every-other-capability>=".
+.PP
+The operators, `+' and `-' both require an explicit preceding
+capability list and one or more explicit trailing flags. The `+'
+operator will raise all of the listed capabilities in the flagged
+capability sets. The `-' operator will lower all of the listed
+capabilities in the flagged capability sets. For example:
+"all+p" will raise all of the Permitted capabilities; "cap_fowner+p-i"
+will raise the override-file-ownership capability in the Permitted
+capability set and lower this Inheritable capability;
+"cap_fowner+pe-i" and "cap_fowner=+pe" are equivalent.
+.SH "RETURN VALUE"
+.B cap_from_text
+and
+.B cap_to_text
+return a non-NULL value on success, and NULL on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+or
+.BR ENOMEM .
+.SH "CONFORMING TO"
+.B cap_from_text
+and
+.B cap_to_text
+are specified by POSIX.1e.
+.B _cap_names
+is a Linux extension.
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_copy_ext (3),
+.IR cap_get_file (3),
+.IR cap_get_proc (3),
+.IR cap_init (3)
diff --git a/doc/cap_get_flag.3 b/doc/cap_get_flag.3
new file mode 100644
index 0000000..db506c6
--- /dev/null
+++ b/doc/cap_get_flag.3
@@ -0,0 +1 @@
+.so man3/cap_clear.3
diff --git a/doc/cap_get_proc.3 b/doc/cap_get_proc.3
new file mode 100644
index 0000000..3913cb2
--- /dev/null
+++ b/doc/cap_get_proc.3
@@ -0,0 +1,122 @@
+.\"
+.\" $Id: cap_get_proc.3,v 1.4 1998/05/24 22:49:32 morgan Exp $
+.\"
+.TH CAP_GET_PROC 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_get_proc, cap_set_proc \- POSIX capability manipulation on
+processes
+.sp
+capgetp, capsetp \- Linux specific capability manipulation on
+arbitrary processes
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.B cap_t cap_get_proc(void);
+.br
+.BI "int cap_set_proc(cap_t " cap_p );
+.sp
+.B #undef _POSIX_SOURCE
+.br
+.B #include <sys/capability.h>
+.sp
+.BI "cap_t capgetp(pid_t " pid ", cap_t " cap_d );
+.br
+.BI "cap_t capsetp(pid_t " pid ", cap_t " cap_d );
+
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+.B cap_get_proc
+allocates a capability state in working storage, sets its state to
+that of the calling process, and returns a pointer to this newly
+created capability state. The caller should free any releasable
+memory, when the capability state in working storage is no longer
+required, by calling
+.B cap_free
+with the
+.I cap_t
+as an argument.
+.PP
+.B cap_set_proc
+sets the values for all capability flags for all capabilities with the
+capability state identified by
+.IR cap_p .
+The new capability state of the process will be completely determined by
+the contents of
+.I cap_p
+upon successful return from this function. If any flag in
+.I cap_p
+is set for any capability not currently permitted for the calling process,
+the function will fail, and the capability state of the process will remain
+unchanged.
+.PP
+.B capgetp
+fills an existing
+.BR cap_d ,
+see
+.BR cap_init (3),
+with the process capabilities of the process indicated by
+.IR pid .
+This information can also be obtained from the
+.B /proc/<pid>/status
+file.
+.PP
+.B capsetp
+attempts to set the capabilities of some other process(es),
+.IR pid .
+If
+.I pid
+is positive it refers to a specific process; if it is zero, it refers
+to the current process; -1 refers to all processes other than the
+current process and process '1' (typically
+.BR init (8));
+other negative values refer to the
+.I -pid
+process-group. In order to use this function, the current process
+must have
+.B CAP_SETPCAP
+raised in its Effective capability set. The capabilities set in the
+target process(es) are those contained in
+.IR cap_d .
+
+.SH "RETURN VALUE"
+.B cap_get_proc
+returns a non-NULL value on success, and NULL on failure.
+.PP
+.BR cap_set_proc ", " capgetp " and " capsetp
+return zero for success, and \-1 on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+.BR EPERM,
+or
+.BR ENOMEM .
+.SH "CONFORMING TO"
+.B cap_set_proc
+and
+.B cap_get_proc
+are functions specified in the draft for POSIX.1e.
+
+.SH "NOTES"
+The function
+.B capsetp
+should be used with care. It exists, primarily, to overcome a lack of
+support for capabilities in any of the filesystems supported by Linux.
+The semantics of this function may change as it is better understood.
+Please note, by default, the only processes that have
+.B CAP_SETPCAP
+available to them are processes started as a kernel-thread.
+(Typically this includes
+.BR init (8),
+kflushd and kswapd). You will need to recompile the kernel to modify
+this default.
+
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_copy_ext (3),
+.IR cap_from_text (3),
+.IR cap_get_file (3),
+.IR cap_init (3)
diff --git a/doc/cap_init.3 b/doc/cap_init.3
new file mode 100644
index 0000000..0548cf6
--- /dev/null
+++ b/doc/cap_init.3
@@ -0,0 +1,80 @@
+.\"
+.\" $Id: cap_init.3,v 1.2 1997/05/24 19:45:28 morgan Exp $
+.\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+.\"
+.TH CAP_INIT 3 "26th May 1997" "" "Linux Programmer's Manual"
+.SH NAME
+cap_init, cap_free, cap_dup \- capability data object storage management
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.B cap_t cap_init(void);
+.sp
+.BI "int cap_free(void *" obj_d );
+.sp
+.BI "cap_t cap_dup(cap_t " cap_p );
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+The capabilities associated with a file or process are never edited
+directly. Instead, working storage is allocated to contain a
+representation of the capability state. Capabilities are edited and
+manipulated only within this working storage area. Once editing of
+the capability state is complete, the updated capability state is used
+to replace the capability state associated with the file or process.
+.PP
+.B cap_init
+creates a capability state in working storage and return a pointer to
+the capability state. The initial value of all flags are cleared. The
+caller should free any releasable memory, when the capability state in
+working storage is no longer required, by calling
+.B cap_free
+with the
+.I cap_t
+as an argument.
+.PP
+.B cap_free
+liberates any releasable memory that has been allocated to the
+capability state identified by
+.IR obj_d .
+The
+.I obj_d
+argument may identify either a
+.I cap_t
+entity, or a
+.I char *
+entity allocated by the
+.B cap_to_text
+function.
+.PP
+.B cap_dup
+returns a duplicate capability state in working storage given by the
+source object
+.IR cap_p ,
+allocating any memory necessary, and returning a
+pointer to the newly created capability state. Once duplicated, no
+operation on either capability state affects the other in any way.
+.SH "RETURN VALUE"
+.B cap_init
+and
+.B cap_dup
+return a non-NULL value on success, and NULL on failure.
+.PP
+.B cap_free
+returns zero on success, and \-1 on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EINVAL ,
+or
+.BR ENOMEM .
+.SH "CONFORMING TO"
+These functions are specified by POSIX.1e.
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_copy_ext (3),
+.IR cap_from_text (3),
+.IR cap_get_file (3),
+.IR cap_get_proc (3)
diff --git a/doc/cap_set_fd.3 b/doc/cap_set_fd.3
new file mode 100644
index 0000000..3970c34
--- /dev/null
+++ b/doc/cap_set_fd.3
@@ -0,0 +1 @@
+.so man3/cap_get_file.3
diff --git a/doc/cap_set_file.3 b/doc/cap_set_file.3
new file mode 100644
index 0000000..3970c34
--- /dev/null
+++ b/doc/cap_set_file.3
@@ -0,0 +1 @@
+.so man3/cap_get_file.3
diff --git a/doc/cap_set_flag.3 b/doc/cap_set_flag.3
new file mode 100644
index 0000000..db506c6
--- /dev/null
+++ b/doc/cap_set_flag.3
@@ -0,0 +1 @@
+.so man3/cap_clear.3
diff --git a/doc/cap_set_proc.3 b/doc/cap_set_proc.3
new file mode 100644
index 0000000..65ea3e4
--- /dev/null
+++ b/doc/cap_set_proc.3
@@ -0,0 +1 @@
+.so man3/cap_get_proc.3
diff --git a/doc/cap_size.3 b/doc/cap_size.3
new file mode 100644
index 0000000..2e6e89c
--- /dev/null
+++ b/doc/cap_size.3
@@ -0,0 +1 @@
+.so man3/cap_copy_ext.3
diff --git a/doc/cap_to_text.3 b/doc/cap_to_text.3
new file mode 100644
index 0000000..83ec8b5
--- /dev/null
+++ b/doc/cap_to_text.3
@@ -0,0 +1 @@
+.so man3/cap_from_text.3
diff --git a/doc/capget.2 b/doc/capget.2
new file mode 100644
index 0000000..9bcda65
--- /dev/null
+++ b/doc/capget.2
@@ -0,0 +1,42 @@
+.\"
+.\" $Id: capget.2,v 1.1 1998/05/24 21:05:20 morgan Exp $
+.\" written by Andrew Morgan <morgan@linux.kernel.org>
+.\"
+.TH CAPGET 2 "17th May 1998" "Linux 2.1" "Linux Programmer's Manual"
+.SH NAME
+capget, capset \- set/get process capabilities
+.SH SYNOPSIS
+.B #undef _POSIX_SOURCE
+.br
+.B #include <sys/capability.h>
+.sp
+.BI "int capget(cap_user_header_t " header ", cap_user_data_t " data );
+.sp
+.BI "int capset(cap_user_header_t " header ", const cap_user_data_t " data );
+.SH DESCRIPTION
+These two functions are the raw kernel interface for getting and
+setting capabilities. The kernel API is likely to change and use of
+these functions (in particular the format of the
+.B cap_user_*_t
+types) is subject to change with each kernel revision.
+.sp
+These system calls are specific to Linux.
+The portable interfaces are
+.IR cap_set_proc (3)
+and
+.IR cap_get_proc (3).
+.SH "RETURN VALUE"
+On success, zero is returned. On error, -1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.SB EINVAL
+One of the arguments was invalid.
+.TP
+.SB EPERM
+An attempt was made to add a capability to the Permitted set, or to set
+a capability in the Effective or Inheritable sets that is not in the
+Permitted set.
+
+
diff --git a/doc/capgetp.3 b/doc/capgetp.3
new file mode 100644
index 0000000..65ea3e4
--- /dev/null
+++ b/doc/capgetp.3
@@ -0,0 +1 @@
+.so man3/cap_get_proc.3
diff --git a/doc/capset.2 b/doc/capset.2
new file mode 100644
index 0000000..9e829cb
--- /dev/null
+++ b/doc/capset.2
@@ -0,0 +1 @@
+.so man2/capget.2
diff --git a/doc/capsetp.3 b/doc/capsetp.3
new file mode 100644
index 0000000..65ea3e4
--- /dev/null
+++ b/doc/capsetp.3
@@ -0,0 +1 @@
+.so man3/cap_get_proc.3
diff --git a/doc/old/RCS/README,v b/doc/old/RCS/README,v
new file mode 100644
index 0000000..8e261fc
--- /dev/null
+++ b/doc/old/RCS/README,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 98.05.24.22.50.55; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@description of this directory
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@these files are not relevant to this release
+@
diff --git a/doc/old/RCS/_fgetfilecap.2,v b/doc/old/RCS/_fgetfilecap.2,v
new file mode 100644
index 0000000..d5d976f
--- /dev/null
+++ b/doc/old/RCS/_fgetfilecap.2,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man2/_setfilecap.2
+@
diff --git a/doc/old/RCS/_fsetfilecap.2,v b/doc/old/RCS/_fsetfilecap.2,v
new file mode 100644
index 0000000..d5d976f
--- /dev/null
+++ b/doc/old/RCS/_fsetfilecap.2,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man2/_setfilecap.2
+@
diff --git a/doc/old/RCS/_getfilecap.2,v b/doc/old/RCS/_getfilecap.2,v
new file mode 100644
index 0000000..d5d976f
--- /dev/null
+++ b/doc/old/RCS/_getfilecap.2,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man2/_setfilecap.2
+@
diff --git a/doc/old/RCS/_getproccap.2,v b/doc/old/RCS/_getproccap.2,v
new file mode 100644
index 0000000..7b92324
--- /dev/null
+++ b/doc/old/RCS/_getproccap.2,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.so man2/_setproccap.2
+@
diff --git a/doc/old/RCS/_setfilecap.2,v b/doc/old/RCS/_setfilecap.2,v
new file mode 100644
index 0000000..61c8351
--- /dev/null
+++ b/doc/old/RCS/_setfilecap.2,v
@@ -0,0 +1,141 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.\"
+.\" $Id$
+.\" written by Andrew Main <zefram@@dcs.warwick.ac.uk>
+.\"
+.TH _SETFILECAP 2 "26th April 1997" "Linux 2.1" "Linux Programmer's Manual"
+.SH NAME
+_setfilecap, _getfilecap, _fsetfilecap, _fgetfilecap \- set/get file capabilities
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "int _setfilecap(char const *" filename ", size_t " usize ", __cap_s const *" iset ", __cap_s const *" pset ", __cap_s const *" eset );
+.sp
+.BI "int _getproccap(char const *" filename ", size_t " usize ", __cap_s *" iset ", __cap_s *" pset ", __cap_s *" eset );
+.sp
+.BI "int _fsetfilecap(int " fd ", size_t " usize ", __cap_s const *" iset ", __cap_s const *" pset ", __cap_s const *" eset );
+.sp
+.BI "int _fgetproccap(int " fd ", size_t " usize ", __cap_s *" iset ", __cap_s *" pset ", __cap_s *" eset );
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+.B _setfilecap
+sets the specified
+.IR filename 's
+Inheritable, Permitted and Effective capabilities to the sets specified.
+A NULL pointer specifies that a set should not be changed.
+.PP
+.B _fsetfilecap
+does the same thing to the file referenced by file descriptor
+.IR fd .
+.PP
+.B _getfilecap
+and
+.B _fgetfilecap
+copy the file's capability sets into the sets provided.
+A NULL pointer specifies that a set should not be returned.
+.PP
+The
+.I usize
+argument specifies the size of the user-space capability sets, in bytes.
+If the kernel uses a different size internally, it will truncate or
+zero-fill as required.
+.PP
+Files don't actually have a proper Effective capability set. Instead they
+have a single-bit flag, that indicates that the set is either full or
+empty. When setting a file's capabilities, that flag will be set if
+and only if the Effective set specified has at least one bit set.
+.SH "RETURN VALUE"
+On success, zero is returned. On error, -1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.SB EFAULT
+One of the capability arguments or the filename was an invalid data pointer.
+.TP
+.SB EPERM
+An attempt was made to set non-empty capabilities on a file,
+and the caller does not have the
+.SB CAP_FSETCAP
+capability raised.
+.TP
+.SB EPERM
+An attempt was made to set capabilities on a file, and
+the effective UID does not match the owner of the file, and the caller
+does not have the
+.SB CAP_FOWNER
+capability raised.
+.TP
+.SB EINVAL
+An attempt was made to set non-empty capabilities on a file
+residing on a file system that does not support them.
+.TP
+.SB EROFS
+An attempt was made to set capabilities on a file residing
+on a read-only file system.
+.TP
+.SB ENAMETOOLONG
+.I filename
+is too long.
+.TP
+.SB ENOENT
+The file specified does not exist.
+.TP
+.SB ENOMEM
+Insufficient kernel memory was available.
+.TP
+.SB ENOTDIR
+A component of the path prefix is not a directory.
+.TP
+.SB EACCES
+Search permission is denied on a component of the path prefix.
+.TP
+.SB ELOOP
+.I filename
+containes a circular reference (via symlinks).
+.TP
+.SB EBADF
+.I fd
+is not a valid file descriptor.
+.TP
+.SB EIO
+A hard error occurred while reading or writing the file system.
+.TP
+.SB ENOSYS
+The POSIX.1e capability system was not configured into the kernel.
+.SH "CONFORMING TO"
+These system calls are specific to Linux.
+The portable interfaces are
+.IR cap_set_file (3),
+.IR cap_get_file (3),
+.IR cap_set_fd (3),
+and
+.IR cap_get_fd (3).
+.SH "SEE ALSO"
+.IR _setproccap (2).
+
+@
diff --git a/doc/old/RCS/_setproccap.2,v b/doc/old/RCS/_setproccap.2,v
new file mode 100644
index 0000000..8c3084b
--- /dev/null
+++ b/doc/old/RCS/_setproccap.2,v
@@ -0,0 +1,76 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.\"
+.\" $Id$
+.\" written by Andrew Main <zefram@@dcs.warwick.ac.uk>
+.\"
+.TH _SETPROCCAP 2 "26th April 1997" "Linux 2.1" "Linux Programmer's Manual"
+.SH NAME
+_setproccap, _getproccap \- set/get process capabilities
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "int _setproccap(size_t " usize ", __cap_s const *" iset ", __cap_s const *" pset ", __cap_s const *" eset );
+.sp
+.BI "int _getproccap(size_t " usize ", __cap_s *" iset ", __cap_s *" pset ", __cap_s *" eset );
+.SH DESCRIPTION
+.B _setproccap
+sets the calling process'
+Inheritable, Permitted and Effective capabilities to the sets specified.
+A NULL pointer specifies that a set should not be changed.
+.PP
+.B _getproccap
+copies the process' capability sets into the sets provided.
+A NULL pointer specifies that a set should not be returned.
+.PP
+The
+.I usize
+argument specifies the size of the user-space capability sets, in bytes.
+If the kernel uses a different size internally, it will truncate or
+zero-fill as required.
+.SH "RETURN VALUE"
+On success, zero is returned. On error, -1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.SB EFAULT
+One of the capability arguments was an invalid data pointer.
+.TP
+.SB EPERM
+An attempt was made to add a capability to the Permitted set, or to set
+a capability in the Effective or Inheritable sets that is not in the
+Permitted set.
+.TP
+.SB ENOSYS
+The POSIX.1e capability system was not configured into the kernel.
+.SH "CONFORMING TO"
+These system calls are specific to Linux.
+The portable interfaces are
+.IR cap_set_proc (3)
+and
+.IR cap_get_proc (3).
+.SH "SEE ALSO"
+.IR _setfilecap (2).
+@
diff --git a/doc/old/RCS/cap_get_file.3,v b/doc/old/RCS/cap_get_file.3,v
new file mode 100644
index 0000000..6a57b4d
--- /dev/null
+++ b/doc/old/RCS/cap_get_file.3,v
@@ -0,0 +1,202 @@
+head 1.4;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.4
+date 98.05.17.17.40.28; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 98.05.17.17.39.20; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.05.24.19.45.28; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.4
+log
+@changed date of file
+@
+text
+@.\"
+.\" $Id: cap_get_file.3,v 1.3 1998/05/17 17:39:20 morgan Exp morgan $
+.\" written by Andrew Main <zefram@@dcs.warwick.ac.uk>
+.\"
+.TH CAP_GET_FILE 3 "17th May 1998" "" "Linux Programmer's Manual"
+.SH NAME
+cap_get_file, cap_set_file, cap_get_fd, cap_set_fd \- capability manipulation on files
+.sp
+.B " PLEASE NOTE NONE OF THESE FUNCTIONS ARE IMPLEMENTED IN 0.102. NEITHER IS THERE SUPPORT FOR THEM IN LINUX 2.1.102."
+.SH SYNOPSIS
+.B
+.sp
+.B #include <sys/capability.h>
+.sp
+.BI "cap_t cap_get_file(const char *" path_p );
+.sp
+.BI "int cap_set_file(const char *" path_p ", cap_t " cap_p );
+.sp
+.BI "cap_t cap_get_fd(int " fd );
+.sp
+.BI "int cap_set_fd(int " fd ", cap_t " caps );
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+.B cap_get_file
+and
+.B cap_get_fd
+allocate a capability state in working storage and set it to represent the
+capability state of the pathname pointed to by
+.I path_p
+or the file open on descriptor
+.IR fd .
+These functions return a pointer to the newly created capability
+state. The effects of reading the capability state from any file
+other than a regular file is undefined. The caller should free any
+releasable memory, when the capability state in working storage is no
+longer required, by calling
+.B cap_free
+with the used
+.I cap_t
+as an argument.
+.PP
+.B cap_set_file
+and
+.B cap_set_fd
+set the values for all capability flags for all capabilities for the pathname
+pointed to by
+.I path_p
+or the file open on descriptor
+.IR fd ,
+with the capability state identified by
+.IR cap_p .
+The new capability state of the file shall be completely determined by the
+contents of
+.IR cap_p .
+For these functions to succeed, the calling process must have the
+.B CAP_SETFCAP
+capability enabled and either the effective user ID of the process must match
+the file owner or the calling process must have the effective flag of the
+.B CAP_FOWNER
+capability set. The effects of writing the capability state to any file
+type other than a regular file are undefined.
+.SH "RETURN VALUE"
+.B cap_get_file
+and
+.B cap_get_fd
+return a non-NULL value on success, and NULL on failure.
+.PP
+.B cap_set_file
+and
+.B cap_set_fd
+return zero on success, and \-1 on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EACCES ,
+.BR EBADFD ,
+.BR ENAMETOOLONG ,
+.BR ENOENT ,
+.BR ENOMEM ,
+.BR ENOTDIR ,
+.BR EPERM ,
+or
+.BR EROFS .
+.SH "CONFORMING TO"
+These functions are specified by POSIX.1e.
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_copy_ext (3),
+.IR cap_from_text (3),
+.IR cap_get_proc (3),
+.IR cap_init (3)
+@
+
+
+1.3
+log
+@added comment about the fact that none of these functions are
+currently implemented
+@
+text
+@d2 1
+a2 1
+.\" $Id: cap_get_file.3,v 1.2 1997/05/24 19:45:28 morgan Exp morgan $
+d5 1
+a5 1
+.TH CAP_GET_FILE 3 "26th May 1997" "" "Linux Programmer's Manual"
+@
+
+
+1.2
+log
+@corrections from Aleph1
+@
+text
+@d2 1
+a2 1
+.\" $Id: cap_get_file.3,v 1.1 1997/04/28 00:54:52 morgan Exp morgan $
+d8 2
+d11 2
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+.\" $Id$
+d5 1
+a5 1
+.TH CAP_GET_FILE 3 "26th April 1997" "" "Linux Programmer's Manual"
+d7 1
+a7 1
+cap_get_file, cap_set_file, cap_get_fd, cap_set_fd \- get/set capabilities of files
+d11 1
+a11 1
+.BI "cap_t cap_get_file(char const *" filename );
+d13 1
+a13 1
+.BI "int cap_set_file(char const *" filename ", cap_t " caps );
+d25 4
+a28 3
+return the capability sets of the file specified by
+.I filename
+or
+d30 9
+a38 2
+The returned value must later be disposed of by passing it to
+.BR cap_free .
+d43 17
+a59 6
+set the capabilities of the file specified by
+.I filename
+or
+.I fd
+to
+.IR caps .
+d70 13
+@
diff --git a/doc/old/RCS/getcap.8,v b/doc/old/RCS/getcap.8,v
new file mode 100644
index 0000000..817d0a4
--- /dev/null
+++ b/doc/old/RCS/getcap.8,v
@@ -0,0 +1,42 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.\"
+.\" $Id$
+.\" written by Andrew Main <zefram@@dcs.warwick.ac.uk>
+.\"
+.TH GETCAP 8 "26th April 1997"
+.SH NAME
+getcap \- examine file capabilities
+.SH SYNOPSIS
+\fBgetcap\fP \fIfilename\fP [ ... ]
+.SH DESCRIPTION
+.B getcap
+displays the name and capabilities of each specified
+.IR filename .
+One file per line.
+.SH "SEE ALSO"
+.IR cap_get_file (3),
+.IR cap_to_text (3),
+.IR setcap (8)
+@
diff --git a/doc/old/RCS/setcap.8,v b/doc/old/RCS/setcap.8,v
new file mode 100644
index 0000000..380f126
--- /dev/null
+++ b/doc/old/RCS/setcap.8,v
@@ -0,0 +1,51 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 97.04.28.00.54.52; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@zefram's manual
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@.\"
+.\" $Id$
+.\"
+.TH SETCAP 8 "26th April 1997"
+.SH NAME
+setcap \- set file capabilities
+.SH SYNOPSIS
+\fBsetcap\fP \fIcapabilities filename\fP [ ... \fIcapabilitiesN\fP \fIfileN\fP ]
+.SH DESCRIPTION
+.B setcap
+sets the capabilities of each specified
+.I filename
+to the
+.I capabilities
+specified. The
+.I capabilities
+are specified in the form described in
+.IR cap_from_text (3).
+.PP
+The special filename, '\-',
+can be used to indicate that capabilities are read from the standard
+input. In such cases, the capability set is terminated with a blank
+line.
+.SH "SEE ALSO"
+.IR cap_from_text (3),
+.IR cap_set_file (3),
+.IR getcap (8)
+@
diff --git a/doc/old/README b/doc/old/README
new file mode 100644
index 0000000..75741d3
--- /dev/null
+++ b/doc/old/README
@@ -0,0 +1 @@
+these files are not relevant to this release
diff --git a/doc/old/_fgetfilecap.2 b/doc/old/_fgetfilecap.2
new file mode 100644
index 0000000..6ce400b
--- /dev/null
+++ b/doc/old/_fgetfilecap.2
@@ -0,0 +1 @@
+.so man2/_setfilecap.2
diff --git a/doc/old/_fsetfilecap.2 b/doc/old/_fsetfilecap.2
new file mode 100644
index 0000000..6ce400b
--- /dev/null
+++ b/doc/old/_fsetfilecap.2
@@ -0,0 +1 @@
+.so man2/_setfilecap.2
diff --git a/doc/old/_getfilecap.2 b/doc/old/_getfilecap.2
new file mode 100644
index 0000000..6ce400b
--- /dev/null
+++ b/doc/old/_getfilecap.2
@@ -0,0 +1 @@
+.so man2/_setfilecap.2
diff --git a/doc/old/_getproccap.2 b/doc/old/_getproccap.2
new file mode 100644
index 0000000..5090c98
--- /dev/null
+++ b/doc/old/_getproccap.2
@@ -0,0 +1 @@
+.so man2/_setproccap.2
diff --git a/doc/old/_setfilecap.2 b/doc/old/_setfilecap.2
new file mode 100644
index 0000000..d4a9e6b
--- /dev/null
+++ b/doc/old/_setfilecap.2
@@ -0,0 +1,117 @@
+.\"
+.\" $Id: _setfilecap.2,v 1.1 1997/04/28 00:54:52 morgan Exp $
+.\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+.\"
+.TH _SETFILECAP 2 "26th April 1997" "Linux 2.1" "Linux Programmer's Manual"
+.SH NAME
+_setfilecap, _getfilecap, _fsetfilecap, _fgetfilecap \- set/get file capabilities
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "int _setfilecap(char const *" filename ", size_t " usize ", __cap_s const *" iset ", __cap_s const *" pset ", __cap_s const *" eset );
+.sp
+.BI "int _getproccap(char const *" filename ", size_t " usize ", __cap_s *" iset ", __cap_s *" pset ", __cap_s *" eset );
+.sp
+.BI "int _fsetfilecap(int " fd ", size_t " usize ", __cap_s const *" iset ", __cap_s const *" pset ", __cap_s const *" eset );
+.sp
+.BI "int _fgetproccap(int " fd ", size_t " usize ", __cap_s *" iset ", __cap_s *" pset ", __cap_s *" eset );
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+.B _setfilecap
+sets the specified
+.IR filename 's
+Inheritable, Permitted and Effective capabilities to the sets specified.
+A NULL pointer specifies that a set should not be changed.
+.PP
+.B _fsetfilecap
+does the same thing to the file referenced by file descriptor
+.IR fd .
+.PP
+.B _getfilecap
+and
+.B _fgetfilecap
+copy the file's capability sets into the sets provided.
+A NULL pointer specifies that a set should not be returned.
+.PP
+The
+.I usize
+argument specifies the size of the user-space capability sets, in bytes.
+If the kernel uses a different size internally, it will truncate or
+zero-fill as required.
+.PP
+Files don't actually have a proper Effective capability set. Instead they
+have a single-bit flag, that indicates that the set is either full or
+empty. When setting a file's capabilities, that flag will be set if
+and only if the Effective set specified has at least one bit set.
+.SH "RETURN VALUE"
+On success, zero is returned. On error, -1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.SB EFAULT
+One of the capability arguments or the filename was an invalid data pointer.
+.TP
+.SB EPERM
+An attempt was made to set non-empty capabilities on a file,
+and the caller does not have the
+.SB CAP_FSETCAP
+capability raised.
+.TP
+.SB EPERM
+An attempt was made to set capabilities on a file, and
+the effective UID does not match the owner of the file, and the caller
+does not have the
+.SB CAP_FOWNER
+capability raised.
+.TP
+.SB EINVAL
+An attempt was made to set non-empty capabilities on a file
+residing on a file system that does not support them.
+.TP
+.SB EROFS
+An attempt was made to set capabilities on a file residing
+on a read-only file system.
+.TP
+.SB ENAMETOOLONG
+.I filename
+is too long.
+.TP
+.SB ENOENT
+The file specified does not exist.
+.TP
+.SB ENOMEM
+Insufficient kernel memory was available.
+.TP
+.SB ENOTDIR
+A component of the path prefix is not a directory.
+.TP
+.SB EACCES
+Search permission is denied on a component of the path prefix.
+.TP
+.SB ELOOP
+.I filename
+containes a circular reference (via symlinks).
+.TP
+.SB EBADF
+.I fd
+is not a valid file descriptor.
+.TP
+.SB EIO
+A hard error occurred while reading or writing the file system.
+.TP
+.SB ENOSYS
+The POSIX.1e capability system was not configured into the kernel.
+.SH "CONFORMING TO"
+These system calls are specific to Linux.
+The portable interfaces are
+.IR cap_set_file (3),
+.IR cap_get_file (3),
+.IR cap_set_fd (3),
+and
+.IR cap_get_fd (3).
+.SH "SEE ALSO"
+.IR _setproccap (2).
+
diff --git a/doc/old/_setproccap.2 b/doc/old/_setproccap.2
new file mode 100644
index 0000000..f48b521
--- /dev/null
+++ b/doc/old/_setproccap.2
@@ -0,0 +1,52 @@
+.\"
+.\" $Id: _setproccap.2,v 1.1 1997/04/28 00:54:52 morgan Exp $
+.\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+.\"
+.TH _SETPROCCAP 2 "26th April 1997" "Linux 2.1" "Linux Programmer's Manual"
+.SH NAME
+_setproccap, _getproccap \- set/get process capabilities
+.SH SYNOPSIS
+.B #include <sys/capability.h>
+.sp
+.BI "int _setproccap(size_t " usize ", __cap_s const *" iset ", __cap_s const *" pset ", __cap_s const *" eset );
+.sp
+.BI "int _getproccap(size_t " usize ", __cap_s *" iset ", __cap_s *" pset ", __cap_s *" eset );
+.SH DESCRIPTION
+.B _setproccap
+sets the calling process'
+Inheritable, Permitted and Effective capabilities to the sets specified.
+A NULL pointer specifies that a set should not be changed.
+.PP
+.B _getproccap
+copies the process' capability sets into the sets provided.
+A NULL pointer specifies that a set should not be returned.
+.PP
+The
+.I usize
+argument specifies the size of the user-space capability sets, in bytes.
+If the kernel uses a different size internally, it will truncate or
+zero-fill as required.
+.SH "RETURN VALUE"
+On success, zero is returned. On error, -1 is returned, and
+.I errno
+is set appropriately.
+.SH ERRORS
+.TP
+.SB EFAULT
+One of the capability arguments was an invalid data pointer.
+.TP
+.SB EPERM
+An attempt was made to add a capability to the Permitted set, or to set
+a capability in the Effective or Inheritable sets that is not in the
+Permitted set.
+.TP
+.SB ENOSYS
+The POSIX.1e capability system was not configured into the kernel.
+.SH "CONFORMING TO"
+These system calls are specific to Linux.
+The portable interfaces are
+.IR cap_set_proc (3)
+and
+.IR cap_get_proc (3).
+.SH "SEE ALSO"
+.IR _setfilecap (2).
diff --git a/doc/old/cap_get_fd.3 b/doc/old/cap_get_fd.3
new file mode 100644
index 0000000..3970c34
--- /dev/null
+++ b/doc/old/cap_get_fd.3
@@ -0,0 +1 @@
+.so man3/cap_get_file.3
diff --git a/doc/old/cap_get_file.3 b/doc/old/cap_get_file.3
new file mode 100644
index 0000000..cb84c2b
--- /dev/null
+++ b/doc/old/cap_get_file.3
@@ -0,0 +1,94 @@
+.\"
+.\" $Id: cap_get_file.3,v 1.4 1998/05/17 17:40:28 morgan Exp $
+.\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+.\"
+.TH CAP_GET_FILE 3 "17th May 1998" "" "Linux Programmer's Manual"
+.SH NAME
+cap_get_file, cap_set_file, cap_get_fd, cap_set_fd \- capability manipulation on files
+.sp
+.B " PLEASE NOTE NONE OF THESE FUNCTIONS ARE IMPLEMENTED IN 0.102. NEITHER IS THERE SUPPORT FOR THEM IN LINUX 2.1.102."
+.SH SYNOPSIS
+.B
+.sp
+.B #include <sys/capability.h>
+.sp
+.BI "cap_t cap_get_file(const char *" path_p );
+.sp
+.BI "int cap_set_file(const char *" path_p ", cap_t " cap_p );
+.sp
+.BI "cap_t cap_get_fd(int " fd );
+.sp
+.BI "int cap_set_fd(int " fd ", cap_t " caps );
+.SH USAGE
+.br
+.B cc ... -lcap
+.SH DESCRIPTION
+.B cap_get_file
+and
+.B cap_get_fd
+allocate a capability state in working storage and set it to represent the
+capability state of the pathname pointed to by
+.I path_p
+or the file open on descriptor
+.IR fd .
+These functions return a pointer to the newly created capability
+state. The effects of reading the capability state from any file
+other than a regular file is undefined. The caller should free any
+releasable memory, when the capability state in working storage is no
+longer required, by calling
+.B cap_free
+with the used
+.I cap_t
+as an argument.
+.PP
+.B cap_set_file
+and
+.B cap_set_fd
+set the values for all capability flags for all capabilities for the pathname
+pointed to by
+.I path_p
+or the file open on descriptor
+.IR fd ,
+with the capability state identified by
+.IR cap_p .
+The new capability state of the file shall be completely determined by the
+contents of
+.IR cap_p .
+For these functions to succeed, the calling process must have the
+.B CAP_SETFCAP
+capability enabled and either the effective user ID of the process must match
+the file owner or the calling process must have the effective flag of the
+.B CAP_FOWNER
+capability set. The effects of writing the capability state to any file
+type other than a regular file are undefined.
+.SH "RETURN VALUE"
+.B cap_get_file
+and
+.B cap_get_fd
+return a non-NULL value on success, and NULL on failure.
+.PP
+.B cap_set_file
+and
+.B cap_set_fd
+return zero on success, and \-1 on failure.
+.PP
+On failure,
+.BR errno (3)
+is set to
+.BR EACCES ,
+.BR EBADFD ,
+.BR ENAMETOOLONG ,
+.BR ENOENT ,
+.BR ENOMEM ,
+.BR ENOTDIR ,
+.BR EPERM ,
+or
+.BR EROFS .
+.SH "CONFORMING TO"
+These functions are specified by POSIX.1e.
+.SH "SEE ALSO"
+.IR cap_clear (3),
+.IR cap_copy_ext (3),
+.IR cap_from_text (3),
+.IR cap_get_proc (3),
+.IR cap_init (3)
diff --git a/doc/old/getcap.8 b/doc/old/getcap.8
new file mode 100644
index 0000000..65674ab
--- /dev/null
+++ b/doc/old/getcap.8
@@ -0,0 +1,18 @@
+.\"
+.\" $Id: getcap.8,v 1.1 1997/04/28 00:54:52 morgan Exp $
+.\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+.\"
+.TH GETCAP 8 "26th April 1997"
+.SH NAME
+getcap \- examine file capabilities
+.SH SYNOPSIS
+\fBgetcap\fP \fIfilename\fP [ ... ]
+.SH DESCRIPTION
+.B getcap
+displays the name and capabilities of each specified
+.IR filename .
+One file per line.
+.SH "SEE ALSO"
+.IR cap_get_file (3),
+.IR cap_to_text (3),
+.IR setcap (8)
diff --git a/doc/old/setcap.8 b/doc/old/setcap.8
new file mode 100644
index 0000000..d8aaa90
--- /dev/null
+++ b/doc/old/setcap.8
@@ -0,0 +1,27 @@
+.\"
+.\" $Id: setcap.8,v 1.1 1997/04/28 00:54:52 morgan Exp $
+.\"
+.TH SETCAP 8 "26th April 1997"
+.SH NAME
+setcap \- set file capabilities
+.SH SYNOPSIS
+\fBsetcap\fP \fIcapabilities filename\fP [ ... \fIcapabilitiesN\fP \fIfileN\fP ]
+.SH DESCRIPTION
+.B setcap
+sets the capabilities of each specified
+.I filename
+to the
+.I capabilities
+specified. The
+.I capabilities
+are specified in the form described in
+.IR cap_from_text (3).
+.PP
+The special filename, '\-',
+can be used to indicate that capabilities are read from the standard
+input. In such cases, the capability set is terminated with a blank
+line.
+.SH "SEE ALSO"
+.IR cap_from_text (3),
+.IR cap_set_file (3),
+.IR getcap (8)
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
+ *
+ */
diff --git a/pgp.keys.asc b/pgp.keys.asc
new file mode 100644
index 0000000..fb6baf1
--- /dev/null
+++ b/pgp.keys.asc
@@ -0,0 +1,100 @@
+Type Bits/KeyID Date User ID
+pub 1024/2A398175 1996/11/17 Andrew G. Morgan <morgan@linux.kernel.org>
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: 2.6.3a
+
+mQCNAzKOhJ4AAAEEAJ9xYnZSD1kYanF+8GUBhHf/gx6hGd8ZNmS5qIC8Qb8rMcTI
++E16nV+FnNRlPRbShITYjq1TPvVK8gTliZf41N9LRQZw0rywRt1NQyhdfKgDWYxB
+kSOwK67oDjkzzC56XS2rrGI6K3Rz/VtYElRyuQ6ZyaKTGcgU/TTwrUUqOYF1AAUR
+tChBbmRyZXcgRy4gTW9yZ2FuIDxtb3JnYW5AcGFyYy5wb3dlci5uZXQ+iQCVAwUQ
+MvNT5Cd5aW9FNqjdAQFt+wP/elq589YoIgZewnFbhB/wZ9cvNBOuDwKT7B71s5L4
+DW3cbE1SaCLgCwgZ3P5KRmqf2Yma+zAmj3zA5BqLou9czdrVeBRiIq77vDWR01q+
+vqiaQD5egroboOPt8OwT0tyTUvFTN+jVJHaBkmoYePvBvAbHJJhKuXSoRdTOgIx2
+lp6JAJUDBRAyjoSfNPCtRSo5gXUBATTWA/9IJKdFUmfndQtVPkPiQ76BUHmYXAUV
+zs/r/3V/KV14HhaPAHijAn/eCsB8vbD/WG41cjYb8VCjDE6QRmn+ydbv+7FPbBFU
+X30J8hCBLB/Ft7CL+lkMsjoZ+2usH7Wqx+yiyRdq7QLohZZy2nXSJjRzp+OFci1E
+bK45M7J9uNvl6Q==
+=tk+w
+-----END PGP PUBLIC KEY BLOCK-----
+
+Type Bits/KeyID Date User ID
+pub 1024/4536A8DD 1996/01/28 Michael K. Johnson <johnsonm@redhat.com>
+ Michael K. Johnson <johnsonm@nigel.vnet.net>
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: 2.6.3a
+
+mQCNAzEK0l0AAAEEAMWweYcS6ov1RISP6E7lb3vgQOrmhBy6S/8zkuHo92IkQWXm
+V9AcMUY/eJPRJH6yI6o1ZKN4InT4uCkSIQOd2C8XyeIK5jFhpmP9DhoucacNL5H7
+oCV4wtFGhUDaDl9VeTtbWLSMESxJ4T/fL/IfkW95/Q2dF7zIDid5aW9FNqjdAAUR
+tChNaWNoYWVsIEsuIEpvaG5zb24gPGpvaG5zb25tQHJlZGhhdC5jb20+iQCVAwUQ
+MuqeiDTwrUUqOYF1AQEjywP/bCWLybbZSI8plyUSWD3yxwjsE+8BiOPGRu1AARUz
+GbVZq9LqPDyjFtH9DqgXULyZtCAk8ebZonH/h/0EnZTi4tiZg3BHKXhIlWQnNz4D
+QRdtUEmMNQzi9+3mU99CBGigsrDQnNrnI88ejo/0YY3gdt6752g5HAvY13h9A0ZP
+MFWJAJUDBRAxgAouJ3lpb0U2qN0BActVA/9vgBOUheUpLPiIry/+2qqJv+e+LnHw
+DgZqROpli9bhJ4wfb1sXPYkFzchR8BUeU0NY6HvAwxEilSNPE1yQoaJuy8POtTuu
+aFO4wvuLp0v5LuatXaU8EsncwjrBsWqRB6Dqd+jyq24Pjx0YKNSRJxceiBE8SBDW
+HESAhYTYCBLy77QsTWljaGFlbCBLLiBKb2huc29uIDxqb2huc29ubUBuaWdlbC52
+bmV0Lm5ldD6JAJUDBRAxGljWe01Ojay67k0BAf3qA/48N9OvgGk9nNR+Pg6aW3rK
+2Dy8t2RQdFGd4b7gBtZeXUAklq9ppYZtS+cXFHoQ8d7K8XBjHh+rgF2oOSBQUrQf
+eb8XkKSZQxB7DZVdi1gAsOzSwCrn4TWSSKc28P4Mjuj1Jr2f1FGST1+cGIl7JbhV
+kLGjmvOIgs7lS8FE0Hhm/4kAlQMFEDEWclxEcVNogr/H7QEBN1QD/1iY+KYQyOTz
+fgaBsx+Bt11kstmOlYhXx23yK2etG0p8XCD2r3aojGOTR/e3o2bLiJo4xe+iMhOM
+dvdSzxSPGQ20wX3jGJaRrRiSClFTQbZSelGG0FcOGfM3mL5zeHaXzRcRciK3VDkD
+IFzTQ3J5NJVBIVlAkxTMIxho758lR2SjiQCVAwUQMREqFnoDqzGe1QXFAQFdpAP/
+VPPoYO50seo1rLL28AA2PVKqo6BJwj0ZMsC14MDJEKryBbj/E4Ma25uSlzBjj+t9
+rbygoz0XWUQMLh8XPAEps3nE3n8FWROsdlucGzGiDGKVEygLPzCsjR7aGEspN1Y7
+4qOZPxbpGG7B5exOLur4ACY75m6oBh+PN+Q1liCIYXKJAJUDBRAxDpk1iGe2nxKR
+G10BAeQjBACmx4DyJacQXxuckDaKMTXa8v2Q7lQpPDyHdn1oAUsx1mrbSL55v2AI
+Q0riFWcFRTERpjAToCLgQjK1pKpmJcduiXURj6TPVKd88hYkuCIpn2hIaI7SCkd8
+HZlfFiuaxVN29UbbzHv3C+mseydpkPRrovqmOSuj2xAGFALo6Vl9U4kAlQMFEDEN
+eD5EFXDNRmtCiQEBRmoEAJAuyY0F5hbweDOdeAhxLWeiTl9jGwQYDS3T5B5/9ZpC
+bJ1yX7Pk2o7LvR9tg/Ji5sfMMvIpH48DNT4kyjmmChFXCUBccwd+33ugdTcYDwLR
+Cdt7k9r2yXz1LEH+lVNKOEIhuIq8/sX61hvFR7+qSABthTLrvvynycD5n2pG3F7L
+=aGjw
+-----END PGP PUBLIC KEY BLOCK-----
+
+Type Bits/KeyID Date User ID
+pub 1024/D4F4D901 1997/03/05 Cristian Gafton <gafton@redhat.com>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: 2.6.3a
+
+mQCNAzMdU6sAAAEEAKLF73rRJ3RUtl+y4bLUOVOV7ataJ46ZHxDZeGAVi+/suwT9
+Kq7QdaeFc4Xwaq8PVWv7pZ4/qTwHUkdbjBVeLt+KOlprvKuadyAh9aG/SqmKkEvA
+hCS3yZDwNmeSLO7VIN5ko1nIwVD4kPJvS3xX6kn6jd4mvv/qGfGvxKXU9NkBAAUR
+tCNDcmlzdGlhbiBHYWZ0b24gPGdhZnRvbkBzb3Jvc2lzLnJvPokAlQMFEDMeTlI0
+8K1FKjmBdQEBmgQD/02JxAU6+fiaBKwRIFDdsLYTy8mPgYaoul9RIX450W5D5nY/
+/696F6TfmFUzvnrvTbZUDyLxHB0mnh4SrdKRKo57i7RDrdx3Mqlt/xP4R6nHwFed
+yTMvz3KB9tYuWfC1fJp69/VRIkMrw448zKkgqHUnAKxMIHvXnV3M9jd6lXSYiQCV
+AwUQMx1Tq/GvxKXU9NkBAQE3/gP/RZMe59OkBWS4whc9c6eac6zwcC/hNc1vyiZ5
+2TEHJ10PgtNtHchD7j3xsDO17/DGEZB23OQiPAeLdqnBr+y2uiSlQfYdpVHBHX3A
+uX3onc69LpEHmUAJAVOvfU1scnDtOH/KeVN3nwc6PWLxzLWzXfUbwLNK+LiPMNMV
+1qygu+s=
+=J4G2
+-----END PGP PUBLIC KEY BLOCK-----
+
+Type Bits/KeyID Date User ID
+pub 1024/A5D75B79 1997/03/01 Andrey V. Savochkin <saw@msu.ru>
+
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Version: 2.6.3a
+
+mQCNAzMYf1MAAAEEAK1S5jgmWnn8IS9mKoSpXu87f2soQhVZ3XdvsBCK2V7BojlU
+0+JJrK+2gMH5tavyFsQ6cKch6I4xH54cS4P4tNE9M7OtfoXOxejtp9U9KZio8T0X
+gM8qOS4fTQEfmdHSA5ETe5Vv+WPZ+/3SCo5kD1uIUUwppHDgJH+l396l11t5AAUR
+tCBBbmRyZXkgVi4gU2F2b2Noa2luIDxzYXdAbXN1LnJ1PokAlQMFEDaIUh008K1F
+KjmBdQEBFtkD/38mraXdr4aEYC6lxlG3cF+59XB6FjyBYhtwgNshpI2mB5XLr25p
+f4jMFNUqnY/bGjXWKwbNguzJ0ukD8TgOg1ZXQZztRso1t1Y2M1KPbwlqj8ib1bZG
+inQO/eqLrVwFH6F9CTiF0Fgy7faAIHN6BfE0o8earrcIwjT7sxRej3lziQCVAwUQ
+M35653fqPT1smcpJAQHeqgQAlXMOru6Rz1TkslVrWD0n7dvBUHQxs0HS1pcWJnZJ
+6kcYMLSA2RBi1fRabwzuOtzK60tOmfmnD7btcGBMMflOtfSulEg/xKNw2awEsNQK
+ULEIBsvrpMr0UN4hWkxTggDXaykg7rQqgrbAsicoLuTtPDIbc+yhQcFEVGJiPO/I
+tqiJAJUDBRAzfnUef89/VVw/1FkBAQ2lA/9q6FQM4RZzp75qxZ7jqAwUy9RFAKhp
+L63YFJX3i1JsUjNoO51pjj5pEAxVVQsorqbdsmpC2aOUTf1AufEcs1kLojb3tc19
+MhXPyHTJs66QqWutdP/yOW+CLzmILAsbEgI6O+toVZ0rHVXjEtRgKUnYReHLrlYj
+RKlBnkVc3NtPcIkAlQMFEDMYf1N/pd/epddbeQEBfKYD/3x/PkH2e+Cy7YXsfwxb
+y/n+6eNIbfakSYjkwN5tDOeaKhdQKUJBKVwAzD2yrLmMDx6uW+FUOTucb6Anau6R
+iKrAJq/a4DcpAeymo7cAthVU7en7HWwebQcL4wZGao1BJI+ulynki4sIqkfbGP83
+DK775eovl5X195ZkE/wNJvoi
+=V5TY
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/progs/Makefile b/progs/Makefile
new file mode 100644
index 0000000..49cf246
--- /dev/null
+++ b/progs/Makefile
@@ -0,0 +1,49 @@
+##
+## $Log: Makefile,v $
+## Revision 1.6 1998/09/20 23:17:32 morgan
+## added sucap.c
+##
+## Revision 1.5 1998/06/07 01:54:43 morgan
+## updated for 0.104. Added execcap.
+##
+## Revision 1.4 1997/05/14 05:18:23 morgan
+## autoconf rearrangement from Zefram
+##
+## Revision 1.3 1997/05/04 05:34:03 morgan
+## took care of case that install cannot handle more than one file
+##
+## Revision 1.2 1997/04/28 01:01:20 morgan
+## update with zefram's patches
+##
+## Revision 1.1 1997/04/21 04:34:04 morgan
+## Initial revision
+##
+##
+
+topdir=$(shell pwd)/..
+include $(topdir)/Make.Rules
+#
+# Programs: all of the examples that we will compile
+#
+PROGS=getpcaps setpcaps execcap sucap
+
+# when we have filecaps...
+#PROGS+=getcap setcap
+
+all: $(PROGS)
+
+$(PROGS): %: %.o
+ $(CC) $(LDFLAGS) -o $@ $< $(LIBS)
+
+%.o: %.c $(INCS)
+ $(CC) $(CFLAGS) -c $< -o $@
+
+install: all
+ mkdir -p -m 0755 $(SBINDIR)
+ for p in $(PROGS) ; do \
+ install -s -m 0755 $$p $(SBINDIR) ; \
+ done
+
+clean:
+ $(LOCALCLEAN)
+ rm -f *.o $(PROGS)
diff --git a/progs/RCS/Makefile,v b/progs/RCS/Makefile,v
new file mode 100644
index 0000000..c3e41ab
--- /dev/null
+++ b/progs/RCS/Makefile,v
@@ -0,0 +1,187 @@
+head 1.6;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.6
+date 98.09.20.23.17.32; author morgan; state Exp;
+branches;
+next 1.5;
+
+1.5
+date 98.06.07.01.54.43; author morgan; state Exp;
+branches;
+next 1.4;
+
+1.4
+date 97.05.14.05.18.23; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 97.05.04.05.34.03; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.01.01.20; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.34.04; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.6
+log
+@added sucap.c
+@
+text
+@##
+## $Log: Makefile,v $
+## Revision 1.5 1998/06/07 01:54:43 morgan
+## updated for 0.104. Added execcap.
+##
+## Revision 1.4 1997/05/14 05:18:23 morgan
+## autoconf rearrangement from Zefram
+##
+## Revision 1.3 1997/05/04 05:34:03 morgan
+## took care of case that install cannot handle more than one file
+##
+## Revision 1.2 1997/04/28 01:01:20 morgan
+## update with zefram's patches
+##
+## Revision 1.1 1997/04/21 04:34:04 morgan
+## Initial revision
+##
+##
+
+topdir=$(shell pwd)/..
+include $(topdir)/Make.Rules
+#
+# Programs: all of the examples that we will compile
+#
+PROGS=getpcaps setpcaps execcap sucap
+
+# when we have filecaps...
+#PROGS+=getcap setcap
+
+all: $(PROGS)
+
+$(PROGS): %: %.o
+ $(CC) $(LDFLAGS) -o $@@ $< $(LIBS)
+
+%.o: %.c $(INCS)
+ $(CC) $(CFLAGS) -c $< -o $@@
+
+install: all
+ mkdir -p -m 0755 $(SBINDIR)
+ for p in $(PROGS) ; do \
+ install -s -m 0755 $$p $(SBINDIR) ; \
+ done
+
+clean:
+ $(LOCALCLEAN)
+ rm -f *.o $(PROGS)
+@
+
+
+1.5
+log
+@updated for 0.104. Added execcap.
+@
+text
+@d3 3
+d23 1
+a23 1
+# Programs: getcap, setcap and execcap
+d25 1
+a25 1
+PROGS=getpcaps setpcaps execcap
+@
+
+
+1.4
+log
+@autoconf rearrangement from Zefram
+@
+text
+@d3 3
+a18 1
+
+d20 1
+a20 1
+# Programs: getcap and setcap
+d22 4
+a25 1
+PROGS=getcap setcap
+@
+
+
+1.3
+log
+@took care of case that install cannot handle more than one file
+@
+text
+@d3 3
+d14 1
+a14 1
+topdir=..
+d25 1
+a25 1
+ $(CC) $(LDFLAGS) -o $@@ $< $(LPATH)
+d31 1
+a31 1
+ mkdir -p $(BINDIR)
+d33 1
+a33 1
+ install -s -g root -o root -m 0111 $$p $(BINDIR) ; \
+d37 2
+a38 1
+ rm -f *~ core *.o $(PROGS)
+@
+
+
+1.2
+log
+@update with zefram's patches
+@
+text
+@d3 3
+d28 4
+a31 2
+ mkdir -p $(FAKEROOT)/bin
+ install -s -g root -o root -m 0111 $(PROGS) $(BINDIR)
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d3 2
+d6 4
+d14 1
+a14 3
+PROGS=getcap # setcap
+
+export CFLAGS =-Dlinux $(WARNINGS) $(DEBUG) $(COPTFLAG) $(IPATH)
+d18 2
+a19 2
+getcap: getcap.o
+ $(CC) -o $@@ $< $(LPATH)
+d26 1
+a26 2
+ strip $(PROGS)
+ install -g root -o root -m 0111 $(PROGS) $(FAKEROOT)/bin
+@
diff --git a/progs/RCS/execcap.c,v b/progs/RCS/execcap.c,v
new file mode 100644
index 0000000..9d1c20a
--- /dev/null
+++ b/progs/RCS/execcap.c,v
@@ -0,0 +1,119 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.3
+date 99.01.30.03.41.43; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 98.06.08.00.16.20; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 98.06.07.01.46.51; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@example program to set capabilities of other processes
+intended for use in limiting capabilities of programs later
+in a chain of execution.
+@
+
+
+1.3
+log
+@compiles on a redhat 5.2 system (glibc)
+@
+text
+@/*
+ * This was written by Andrew G. Morgan <morgan@@linux.kernel.org>
+ *
+ * This is a program that is intended to exec a subsequent program.
+ * The purpose of this 'execcap' wrapper is to limit the inheritable
+ * capabilities of the exec()'d program. All environment variables
+ * are inherited.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/capability.h>
+#include <unistd.h>
+#include <string.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+"usage: execcap <caps> <command-path> [command-args...]\n\n"
+" This program is a wrapper that can be used to limit the Inheritable\n"
+" capabilities of a program to be executed. Note, this wrapper is\n"
+" intended to assist in overcoming a lack of support for filesystem\n"
+" capability attributes and should be used to launch other files.\n"
+" This program should _NOT_ be made setuid-0.\n\n"
+"[Copyright (c) 1998 Andrew G. Morgan <morgan@@linux.kernel.org>]\n");
+
+ exit(1);
+}
+
+void main(int argc, char **argv)
+{
+ cap_t new_caps;
+
+ /* this program should not be made setuid-0 */
+ if (getuid() && !geteuid()) {
+ usage();
+ }
+
+ /* check that we have at least 2 arguments */
+ if (argc < 3) {
+ usage();
+ }
+
+ /* parse the first argument to obtain a set of capabilities */
+ new_caps = cap_from_text(argv[1]);
+ if (new_caps == NULL) {
+ fprintf(stderr, "requested capabilities were not recognized\n");
+ usage();
+ }
+
+ /* set these capabilities for the current process */
+ if (cap_set_proc(new_caps) != 0) {
+ fprintf(stderr, "unable to set capabilities: %s\n", strerror(errno));
+ usage();
+ }
+
+ /* exec the program indicated by args 2 ... */
+ execvp(argv[2], argv+2);
+
+ /* if we fall through to here, our exec failed -- announce the fact */
+ fprintf(stderr, "Unable to execute command: %s\n", strerror(errno));
+
+ usage();
+}
+@
+
+
+1.2
+log
+@change to accommodate alpha (glibc?)
+@
+text
+@d15 1
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d10 1
+@
diff --git a/progs/RCS/getpcaps.c,v b/progs/RCS/getpcaps.c,v
new file mode 100644
index 0000000..a5e1e46
--- /dev/null
+++ b/progs/RCS/getpcaps.c,v
@@ -0,0 +1,166 @@
+head 1.4;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.4
+date 98.09.20.23.07.08; author morgan; state Exp;
+branches;
+next 1.3;
+
+1.3
+date 98.06.08.00.16.58; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 98.06.07.01.49.39; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 98.04.30.02.53.00; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@@
+
+
+1.4
+log
+@fixed comment at top
+@
+text
+@/*
+ * $Id: getpcaps.c,v 1.3 1998/06/08 00:16:58 morgan Exp morgan $
+ *
+ * Copyright (c) 1997 Andrew G. Morgan <morgan@@linux.kernel.org>
+ *
+ * This displays the capabilities of a given process.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#undef _POSIX_SOURCE
+#include <sys/capability.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+"usage: getcaps <pid> [<pid> ...]\n\n"
+" This program displays the capabilities on the queried process(es).\n"
+" The capabilities are displayed in the cap_from_text(3) format.\n\n"
+"[Copyright (c) 1997-8 Andrew G. Morgan <morgan@@linux.kernel.org>]\n"
+ );
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ cap_t cap_d;
+
+ if (argc < 2) {
+ usage();
+ }
+
+ cap_d = cap_init();
+ for ( ++argv; --argc > 0; ++argv ) {
+ ssize_t length;
+ int pid;
+
+ if (cap_d == NULL) {
+ fprintf(stderr, "Failed to make a blank capability set\n"
+ " (%s)\n", strerror(errno));
+ exit(1);
+ }
+
+ pid = atoi(argv[0]);
+ /* this is a non-POSIX function */
+ if (capgetp(pid, cap_d)) {
+ fprintf(stderr, "Failed to get cap's for proccess %d:"
+ " (%s)\n", pid, strerror(errno));
+ continue;
+ } else {
+ char *result = cap_to_text(cap_d, &length);
+ fprintf(stderr, "Capabilities for `%s': %s\n", *argv, result);
+ free(result);
+ result = NULL;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * $Log: getpcaps.c,v $
+ * Revision 1.3 1998/06/08 00:16:58 morgan
+ * change to accommodate alpha (glibc?)
+ *
+ * Revision 1.2 1998/06/07 01:49:39 morgan
+ * added copyright info and some usage info. Small tidy up.
+ *
+ * Revision 1.1 1998/04/30 02:53:00 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.3
+log
+@change to accommodate alpha (glibc?)
+@
+text
+@d2 1
+a2 1
+ * $Id: getpcaps.c,v 1.2 1998/06/07 01:49:39 morgan Exp morgan $
+d6 1
+a6 1
+ * This displays the capabilities of a given file.
+d66 3
+@
+
+
+1.2
+log
+@added copyright info and some usage info. Small tidy up.
+@
+text
+@d2 1
+a2 1
+ * $Id: getpcaps.c,v 1.1 1998/04/30 02:53:00 morgan Exp morgan $
+d9 1
+d66 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id: getcap.c,v 1.3 1997/05/04 05:34:32 morgan Exp $
+d19 4
+a22 3
+ "usage: whatcaps <pid> [<pid> ...]\n"
+ "\n"
+ "\tdisplays the capabilities on the queried process(es).\n"
+a29 1
+ char *result=NULL;
+d53 1
+a53 1
+ result = cap_to_text(cap_d, &length);
+d55 2
+d64 4
+a67 1
+ * $Log: getcap.c,v $
+@
diff --git a/progs/RCS/setpcaps.c,v b/progs/RCS/setpcaps.c,v
new file mode 100644
index 0000000..621331e
--- /dev/null
+++ b/progs/RCS/setpcaps.c,v
@@ -0,0 +1,207 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.3
+date 98.09.20.23.07.08; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 98.06.08.00.17.38; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 98.06.07.01.46.51; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@example program to set capabilities of other processes
+intended for use on non-capabilitiy supporting filesystems.
+@
+
+
+1.3
+log
+@fixed comment at top
+@
+text
+@/*
+ * $Id: setpcaps.c,v 1.2 1998/06/08 00:17:38 morgan Exp morgan $
+ *
+ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@@linux.kernel.org>
+ *
+ * This sets the capabilities of a given process.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#undef _POSIX_SOURCE
+#include <sys/capability.h>
+#include <unistd.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+"usage: setcap [-q] (-|<caps>) <pid> [ ... (-|<capsN>) <pid> ]\n\n"
+" This program can be used to set the process capabilities of running\n"
+" processes. In order to work, it needs to be executing with CAP_SETPCAP\n"
+" raised, and the only capabilities that this program can bestow on others\n"
+" are a subset of its effective set. This program is mostly intended as an\n"
+" example -- a safe use of CAP_SETPCAP has yet to be demonstrated!\n\n"
+"[Copyright (c) 1997-8 Andrew G. Morgan <morgan@@linux.kernel.org>]\n"
+ );
+ exit(1);
+}
+
+#define MAXCAP 2048
+
+static int read_caps(int quiet, const char *filename, char *buffer)
+{
+ int i=MAXCAP;
+
+ if (!quiet) {
+ fprintf(stderr, "Please enter caps for file [empty line to end]:\n");
+ }
+ while (i > 0) {
+ int j = read(STDIN_FILENO, buffer, i);
+
+ if (j < 0) {
+ fprintf(stderr, "\n[Error - aborting]\n");
+ exit(1);
+ }
+
+ if (j==0 || buffer[0] == '\n') {
+ /* we're done */
+ break;
+ }
+
+ /* move on... */
+
+ i -= j;
+ buffer += j;
+ }
+
+ /* <NUL> terminate */
+ buffer[0] = '\0';
+
+ return (i < MAXCAP ? 0:-1);
+}
+
+int main(int argc, char **argv)
+{
+ char buffer[MAXCAP+1];
+ int retval, quiet=0;
+ cap_t cap_d;
+
+ if (argc < 3) {
+ usage();
+ }
+
+ while (--argc > 0) {
+ const char *text;
+ pid_t pid;
+
+ if (!strcmp(*++argv,"-q")) {
+ quiet = 1;
+ continue;
+ }
+ if (!strcmp(*argv,"-")) {
+ retval = read_caps(quiet, *argv, buffer);
+ if (retval)
+ usage();
+ text = buffer;
+ } else
+ text = *argv;
+
+ cap_d = cap_from_text(text);
+ if (cap_d == NULL) {
+ perror("fatal error");
+ usage();
+ }
+#ifndef DEBUG
+ {
+ ssize_t length;
+ char *result;
+
+ result = cap_to_text(cap_d, &length);
+ fprintf(stderr, "[caps set to:\n%s\n]\n", result);
+ free(result);
+ result = NULL;
+ }
+#endif
+
+ if (--argc <= 0)
+ usage();
+
+ pid = atoi(*++argv);
+ retval = capsetp(pid, cap_d);
+
+ if (retval != 0) {
+ fprintf(stderr, "Failed to set cap's on process `%d': (%s)\n",
+ pid, strerror(errno));
+ usage();
+ }
+#ifndef DEBUG
+ fprintf(stderr, "[caps set on %d]\n", pid);
+#endif
+ }
+
+ return 0;
+}
+
+/*
+ * $Log: setpcaps.c,v $
+ * Revision 1.2 1998/06/08 00:17:38 morgan
+ * change to accommodate alpha (glibc?)
+ *
+ * Revision 1.1 1998/06/07 01:46:51 morgan
+ * Initial revision
+ *
+ * Revision 1.2 1997/05/04 05:34:32 morgan
+ * non void main
+ *
+ * Revision 1.1 1997/04/28 01:01:20 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.2
+log
+@change to accommodate alpha (glibc?)
+@
+text
+@d2 1
+a2 1
+ * $Id: setpcaps.c,v 1.1 1998/06/07 01:46:51 morgan Exp morgan $
+d6 1
+a6 1
+ * This sets the capabilities of a given file.
+d130 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id: setcap.c,v 1.2 1997/05/04 05:34:32 morgan Exp $
+d9 1
+d129 4
+a132 1
+ * $Log: setcap.c,v $
+@
diff --git a/progs/RCS/sucap.c,v b/progs/RCS/sucap.c,v
new file mode 100644
index 0000000..dbcf69f
--- /dev/null
+++ b/progs/RCS/sucap.c,v
@@ -0,0 +1,266 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.3
+date 99.01.30.03.40.39; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 98.09.20.23.15.30; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 98.09.20.23.06.06; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@example program contributed by Finn Arne Gangstad <finnag@@guardian.no>
+@
+
+
+1.3
+log
+@compiles on a redhat 5.2 system (glibc)
+@
+text
+@/*
+ * $Id: sucap.c,v 1.2 1998/09/20 23:15:30 morgan Exp morgan $
+ *
+ * This was written by Finn Arne Gangstad <finnag@@guardian.no>
+ *
+ * This is a program that is intended to exec a subsequent program.
+ * The purpose of this 'sucap' wrapper is to change uid but keep all
+ * privileges. All environment variables are inherited.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#undef _POSIX_SOURCE
+#include <sys/capability.h>
+#include <pwd.h>
+#define __USE_BSD
+#include <grp.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+"usage: sucap <user> <group> <command-path> [command-args...]\n\n"
+" This program is a wrapper that change UID but not privileges of a\n"
+" program to be executed.\n"
+" Note, this wrapper is intended to assist in overcoming a lack of support\n"
+" for filesystem capability attributes and should be used to launch other\n"
+" files. This program should _NOT_ be made setuid-0.\n\n"
+"[Copyright (c) 1998 Finn Arne Gangstad <finnag@@guardian.no>]\n");
+
+ exit(1);
+}
+
+
+static void
+wait_on_fd(int fd)
+{
+ /* Wait until some data is available on a file descriptor, or until
+ * end of file or an error is detected */
+ char buf[1];
+ while (read(fd, buf, sizeof(buf)) == -1 && errno == EINTR) {
+ /* empty loop */
+ }
+}
+
+
+void main(int argc, char **argv)
+{
+ cap_t old_caps;
+ uid_t uid;
+ pid_t pid, parent_pid;
+ gid_t gid;
+ int pipe_fds[2];
+
+ /* this program should not be made setuid-0 */
+ if (getuid() && !geteuid()) {
+ usage();
+ }
+
+ /* check that we have at least 3 arguments */
+ if (argc < 4) {
+ usage();
+ }
+
+ /* Convert username to uid */
+ {
+ struct passwd *pw = getpwnam(argv[1]);
+ if (!pw) {
+ fprintf(stderr, "sucap: No such user: %s\n", argv[1]);
+ exit(1);
+ }
+ uid = pw->pw_uid;
+ }
+
+ /* Convert groupname to gid */
+ {
+ struct group *gr = getgrnam(argv[2]);
+ if (!gr) {
+ fprintf(stderr, "sucap: No such group: %s\n", argv[2]);
+ exit(1);
+ }
+ gid = gr->gr_gid;
+ }
+
+ /* set process group to current pid */
+ if (setpgid(0, getpid())) {
+ perror("sucap: Failed to set process group");
+ exit(1);
+ }
+
+ if (pipe(pipe_fds)) {
+ perror("sucap: pipe() failed");
+ exit(1);
+ }
+
+ parent_pid = getpid();
+
+ old_caps = cap_init();
+ if (capgetp(0, old_caps)) {
+ perror("sucap: capgetp");
+ exit(1);
+ }
+
+ {
+ ssize_t x;
+ printf("Caps: %s\n", cap_to_text(old_caps, &x));
+ }
+
+
+ /* fork off a child to do the hard work */
+ fflush(NULL);
+ pid = fork();
+ if (pid == -1) {
+ perror("sucap: fork failed");
+ exit(1);
+ }
+
+ /* 1. mother process sets gid and uid
+ * 2. child process sets capabilities of mother process
+ * 3. mother process execs whatever is to be executed
+ */
+
+ if (pid) {
+ /* Mother process. */
+ close(pipe_fds[0]);
+
+ /* Get rid of any supplemental groups */
+ if (!getuid() && setgroups(0, 0)) {
+ perror("sucap: setgroups failed");
+ exit(1);
+ }
+
+ /* Set gid and uid (this probably clears capabilities) */
+ setregid(gid, gid);
+ setreuid(uid, uid);
+
+ {
+ ssize_t x;
+ cap_t cap = cap_init();
+ capgetp(0, cap);
+ printf("Caps: %s\n", cap_to_text(cap, &x));
+ }
+
+ printf("[debug] uid:%d, real uid:%d\n", geteuid(), getuid());
+
+ /* Signal child that we want our privileges updated */
+ close(pipe_fds[1]); /* Child hangs in blocking read */
+
+ /* Wait for child process to set our privileges */
+ {
+ int status = 0;
+ if (wait(&status) == -1) {
+ perror("sucap: wait failed");
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+ fprintf(stderr, "sucap: child did not exit cleanly.\n");
+ exit(1);
+ }
+ }
+
+ {
+ ssize_t x;
+ cap_t cap = cap_init();
+ capgetp(0, cap);
+ printf("Caps: %s\n", cap_to_text(cap, &x));
+ }
+
+/* printf("[debug] uid:%d, real uid:%d\n", geteuid(), getuid()); */
+ /* exec the program indicated by args 2 ... */
+ execvp(argv[3], argv+3);
+
+ /* if we fall through to here, our exec failed -- announce the fact */
+ fprintf(stderr, "Unable to execute command: %s\n", strerror(errno));
+
+ usage();
+ } else {
+ /* Child process */
+ close(pipe_fds[1]);
+
+ /* Wait for mother process to setuid */
+ wait_on_fd(pipe_fds[0]);
+
+ /* Set privileges on mother process */
+ if (capsetp(parent_pid, old_caps)) {
+ perror("sucaps: capsetp");
+ _exit(1);
+ }
+
+ /* exit to signal mother process that we are ready */
+ _exit(0);
+ }
+}
+@
+
+
+1.2
+log
+@a few changes to make it compile for me without any warnings.
+@
+text
+@d2 1
+a2 1
+ * $Id: sucap.c,v 1.1 1998/09/20 23:06:06 morgan Exp morgan $
+d22 1
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+d14 1
+a15 1
+#include <unistd.h>
+d17 1
+d108 1
+a108 1
+ size_t x;
+d141 1
+a141 1
+ size_t x;
+d165 1
+a165 1
+ size_t x;
+@
diff --git a/progs/execcap.c b/progs/execcap.c
new file mode 100644
index 0000000..68b86d2
--- /dev/null
+++ b/progs/execcap.c
@@ -0,0 +1,65 @@
+/*
+ * This was written by Andrew G. Morgan <morgan@linux.kernel.org>
+ *
+ * This is a program that is intended to exec a subsequent program.
+ * The purpose of this 'execcap' wrapper is to limit the inheritable
+ * capabilities of the exec()'d program. All environment variables
+ * are inherited.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <sys/capability.h>
+#include <unistd.h>
+#include <string.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+"usage: execcap <caps> <command-path> [command-args...]\n\n"
+" This program is a wrapper that can be used to limit the Inheritable\n"
+" capabilities of a program to be executed. Note, this wrapper is\n"
+" intended to assist in overcoming a lack of support for filesystem\n"
+" capability attributes and should be used to launch other files.\n"
+" This program should _NOT_ be made setuid-0.\n\n"
+"[Copyright (c) 1998 Andrew G. Morgan <morgan@linux.kernel.org>]\n");
+
+ exit(1);
+}
+
+void main(int argc, char **argv)
+{
+ cap_t new_caps;
+
+ /* this program should not be made setuid-0 */
+ if (getuid() && !geteuid()) {
+ usage();
+ }
+
+ /* check that we have at least 2 arguments */
+ if (argc < 3) {
+ usage();
+ }
+
+ /* parse the first argument to obtain a set of capabilities */
+ new_caps = cap_from_text(argv[1]);
+ if (new_caps == NULL) {
+ fprintf(stderr, "requested capabilities were not recognized\n");
+ usage();
+ }
+
+ /* set these capabilities for the current process */
+ if (cap_set_proc(new_caps) != 0) {
+ fprintf(stderr, "unable to set capabilities: %s\n", strerror(errno));
+ usage();
+ }
+
+ /* exec the program indicated by args 2 ... */
+ execvp(argv[2], argv+2);
+
+ /* if we fall through to here, our exec failed -- announce the fact */
+ fprintf(stderr, "Unable to execute command: %s\n", strerror(errno));
+
+ usage();
+}
diff --git a/progs/getpcaps.c b/progs/getpcaps.c
new file mode 100644
index 0000000..46a3500
--- /dev/null
+++ b/progs/getpcaps.c
@@ -0,0 +1,78 @@
+/*
+ * $Id: getpcaps.c,v 1.4 1998/09/20 23:07:08 morgan Exp $
+ *
+ * Copyright (c) 1997 Andrew G. Morgan <morgan@linux.kernel.org>
+ *
+ * This displays the capabilities of a given process.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#undef _POSIX_SOURCE
+#include <sys/capability.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+"usage: getcaps <pid> [<pid> ...]\n\n"
+" This program displays the capabilities on the queried process(es).\n"
+" The capabilities are displayed in the cap_from_text(3) format.\n\n"
+"[Copyright (c) 1997-8 Andrew G. Morgan <morgan@linux.kernel.org>]\n"
+ );
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ cap_t cap_d;
+
+ if (argc < 2) {
+ usage();
+ }
+
+ cap_d = cap_init();
+ for ( ++argv; --argc > 0; ++argv ) {
+ ssize_t length;
+ int pid;
+
+ if (cap_d == NULL) {
+ fprintf(stderr, "Failed to make a blank capability set\n"
+ " (%s)\n", strerror(errno));
+ exit(1);
+ }
+
+ pid = atoi(argv[0]);
+ /* this is a non-POSIX function */
+ if (capgetp(pid, cap_d)) {
+ fprintf(stderr, "Failed to get cap's for proccess %d:"
+ " (%s)\n", pid, strerror(errno));
+ continue;
+ } else {
+ char *result = cap_to_text(cap_d, &length);
+ fprintf(stderr, "Capabilities for `%s': %s\n", *argv, result);
+ free(result);
+ result = NULL;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * $Log: getpcaps.c,v $
+ * Revision 1.4 1998/09/20 23:07:08 morgan
+ * fixed comment at top
+ *
+ * Revision 1.3 1998/06/08 00:16:58 morgan
+ * change to accommodate alpha (glibc?)
+ *
+ * Revision 1.2 1998/06/07 01:49:39 morgan
+ * added copyright info and some usage info. Small tidy up.
+ *
+ * Revision 1.1 1998/04/30 02:53:00 morgan
+ * Initial revision
+ *
+ */
diff --git a/progs/old/RCS/README,v b/progs/old/RCS/README,v
new file mode 100644
index 0000000..304661d
--- /dev/null
+++ b/progs/old/RCS/README,v
@@ -0,0 +1,25 @@
+head 1.1;
+access;
+symbols;
+locks; strict;
+comment @# @;
+
+
+1.1
+date 98.05.24.23.47.43; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@description
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@these files are not relevant to this release
+@
diff --git a/progs/old/RCS/getcap.c,v b/progs/old/RCS/getcap.c,v
new file mode 100644
index 0000000..04d3a1a
--- /dev/null
+++ b/progs/old/RCS/getcap.c,v
@@ -0,0 +1,151 @@
+head 1.3;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.3
+date 97.05.04.05.34.32; author morgan; state Exp;
+branches;
+next 1.2;
+
+1.2
+date 97.04.28.01.01.20; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.21.04.34.04; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@first take
+@
+
+
+1.3
+log
+@non void main
+@
+text
+@/*
+ * $Id: getcap.c,v 1.2 1997/04/28 01:01:20 morgan Exp morgan $
+ *
+ * Copyright (c) 1997 Andrew G. Morgan <morgan@@parc.power.net>
+ *
+ * This displays the capabilities of a given file.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/capability.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+ "usage: getcap <filename> [<filename> ...]\n"
+ "\n"
+ "\tdisplays the capabilities on the queried file(s).\n"
+ );
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ char *result=NULL;
+
+ if (argc < 2) {
+ usage();
+ }
+
+ for ( ++argv; --argc > 0; ++argv ) {
+ ssize_t length;
+ cap_t cap_d;
+
+ cap_d = cap_get_file(argv[0]);
+
+ if (cap_d == NULL) {
+ fprintf(stderr,
+ "Failed to get capabilities for file `%s'\n"
+ " (%s)\n", argv[0], strerror(errno));
+ continue;
+ }
+
+ result = cap_to_text(cap_d, &length);
+
+ fprintf(stderr, "Capabilities for `%s':\n%s\n", *argv, result);
+ }
+
+ return 0;
+}
+
+/*
+ * $Log: getcap.c,v $
+ * Revision 1.2 1997/04/28 01:01:20 morgan
+ * update to allow more than one argument file
+ *
+ * Revision 1.1 1997/04/21 04:34:04 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.2
+log
+@update to allow more than one argument file
+@
+text
+@d2 1
+a2 1
+ * $Id: getcap.c,v 1.1 1997/04/21 04:34:04 morgan Exp morgan $
+d24 1
+a24 1
+void main(int argc, char **argv)
+d50 1
+a50 1
+ exit(0);
+d55 3
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id$
+d17 1
+a17 1
+ "usage: getcap <filename>\n"
+d19 1
+a19 1
+ "\tdisplays the capabilities on the queried file\n"
+a26 2
+ ssize_t length;
+ cap_t cap_d;
+d28 1
+a28 1
+ if (argc != 2) {
+d32 16
+a47 6
+ cap_d = cap_get_file(argv[1]);
+ if (cap_d == NULL) {
+ fprintf(stderr,
+ "Failed to get capabilities for file %s\n"
+ " (%s)\n", argv[1], strerror(errno));
+ exit(1);
+a49 3
+ result = cap_to_text(cap_d, &length);
+
+ fprintf(stderr, "%s", result);
+d54 4
+a57 1
+ * $Log$
+@
diff --git a/progs/old/RCS/setcap.c,v b/progs/old/RCS/setcap.c,v
new file mode 100644
index 0000000..9b09195
--- /dev/null
+++ b/progs/old/RCS/setcap.c,v
@@ -0,0 +1,168 @@
+head 1.2;
+access;
+symbols;
+locks; strict;
+comment @ * @;
+
+
+1.2
+date 97.05.04.05.34.32; author morgan; state Exp;
+branches;
+next 1.1;
+
+1.1
+date 97.04.28.01.01.20; author morgan; state Exp;
+branches;
+next ;
+
+
+desc
+@update: merged code from me and zefram
+@
+
+
+1.2
+log
+@non void main
+@
+text
+@/*
+ * $Id: setcap.c,v 1.1 1997/04/28 01:01:20 morgan Exp morgan $
+ *
+ * Copyright (c) 1997 Andrew G. Morgan <morgan@@parc.power.net>
+ *
+ * This sets the capabilities of a given file.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/capability.h>
+#include <unistd.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+ "usage: setcap [-q] (-|<caps>) <filename> "
+ "[ ... (-|<capsN>) <filenameN> ]\n"
+ );
+ exit(1);
+}
+
+#define MAXCAP 2048
+
+static int read_caps(int quiet, const char *filename, char *buffer)
+{
+ int i=MAXCAP;
+
+ if (!quiet) {
+ fprintf(stderr, "Please enter caps for file [empty line to end]:\n");
+ }
+ while (i > 0) {
+ int j = read(STDIN_FILENO, buffer, i);
+
+ if (j < 0) {
+ fprintf(stderr, "\n[Error - aborting]\n");
+ exit(1);
+ }
+
+ if (j==0 || buffer[0] == '\n') {
+ /* we're done */
+ break;
+ }
+
+ /* move on... */
+
+ i -= j;
+ buffer += j;
+ }
+
+ /* <NUL> terminate */
+ buffer[0] = '\0';
+
+ return (i < MAXCAP ? 0:-1);
+}
+
+int main(int argc, char **argv)
+{
+ char buffer[MAXCAP+1];
+ int retval, quiet=0;
+ cap_t cap_d;
+
+ if (argc < 3) {
+ usage();
+ }
+
+ while (--argc > 0) {
+ const char *text;
+
+ if (!strcmp(*++argv,"-q")) {
+ quiet = 1;
+ continue;
+ }
+ if (!strcmp(*argv,"-")) {
+ retval = read_caps(quiet, *argv, buffer);
+ if (retval)
+ usage();
+ text = buffer;
+ } else
+ text = *argv;
+
+ cap_d = cap_from_text(text);
+ if (cap_d == NULL) {
+ perror("fatal error");
+ usage();
+ }
+#ifdef DEBUG
+ {
+ ssize_t length;
+ const char *result;
+
+ result = cap_to_text(cap_d, &length);
+ fprintf(stderr, "[caps set to:\n%s\n]\n", result);
+ }
+#endif
+
+ if (--argc <= 0)
+ usage();
+
+ retval = cap_set_file(*++argv, cap_d);
+
+ if (retval != 0) {
+ fprintf(stderr,
+ "Failed to set capabilities on file `%s'\n"
+ " (%s)\n", argv[0], strerror(errno));
+ usage();
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * $Log: setcap.c,v $
+ * Revision 1.1 1997/04/28 01:01:20 morgan
+ * Initial revision
+ *
+ */
+@
+
+
+1.1
+log
+@Initial revision
+@
+text
+@d2 1
+a2 1
+ * $Id: getcap.c,v 1.1 1997/04/21 04:34:04 morgan Exp morgan $
+d58 1
+a58 1
+void main(int argc, char **argv)
+d111 1
+a111 1
+ exit(0);
+d115 4
+a118 1
+ * $Log: getcap.c,v $
+@
diff --git a/progs/old/README b/progs/old/README
new file mode 100644
index 0000000..75741d3
--- /dev/null
+++ b/progs/old/README
@@ -0,0 +1 @@
+these files are not relevant to this release
diff --git a/progs/old/getcap.c b/progs/old/getcap.c
new file mode 100644
index 0000000..67d904b
--- /dev/null
+++ b/progs/old/getcap.c
@@ -0,0 +1,64 @@
+/*
+ * $Id: getcap.c,v 1.3 1997/05/04 05:34:32 morgan Exp $
+ *
+ * Copyright (c) 1997 Andrew G. Morgan <morgan@parc.power.net>
+ *
+ * This displays the capabilities of a given file.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/capability.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+ "usage: getcap <filename> [<filename> ...]\n"
+ "\n"
+ "\tdisplays the capabilities on the queried file(s).\n"
+ );
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ char *result=NULL;
+
+ if (argc < 2) {
+ usage();
+ }
+
+ for ( ++argv; --argc > 0; ++argv ) {
+ ssize_t length;
+ cap_t cap_d;
+
+ cap_d = cap_get_file(argv[0]);
+
+ if (cap_d == NULL) {
+ fprintf(stderr,
+ "Failed to get capabilities for file `%s'\n"
+ " (%s)\n", argv[0], strerror(errno));
+ continue;
+ }
+
+ result = cap_to_text(cap_d, &length);
+
+ fprintf(stderr, "Capabilities for `%s':\n%s\n", *argv, result);
+ }
+
+ return 0;
+}
+
+/*
+ * $Log: getcap.c,v $
+ * Revision 1.3 1997/05/04 05:34:32 morgan
+ * non void main
+ *
+ * Revision 1.2 1997/04/28 01:01:20 morgan
+ * update to allow more than one argument file
+ *
+ * Revision 1.1 1997/04/21 04:34:04 morgan
+ * Initial revision
+ *
+ */
diff --git a/progs/old/setcap.c b/progs/old/setcap.c
new file mode 100644
index 0000000..7d959eb
--- /dev/null
+++ b/progs/old/setcap.c
@@ -0,0 +1,122 @@
+/*
+ * $Id: setcap.c,v 1.2 1997/05/04 05:34:32 morgan Exp $
+ *
+ * Copyright (c) 1997 Andrew G. Morgan <morgan@parc.power.net>
+ *
+ * This sets the capabilities of a given file.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/capability.h>
+#include <unistd.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+ "usage: setcap [-q] (-|<caps>) <filename> "
+ "[ ... (-|<capsN>) <filenameN> ]\n"
+ );
+ exit(1);
+}
+
+#define MAXCAP 2048
+
+static int read_caps(int quiet, const char *filename, char *buffer)
+{
+ int i=MAXCAP;
+
+ if (!quiet) {
+ fprintf(stderr, "Please enter caps for file [empty line to end]:\n");
+ }
+ while (i > 0) {
+ int j = read(STDIN_FILENO, buffer, i);
+
+ if (j < 0) {
+ fprintf(stderr, "\n[Error - aborting]\n");
+ exit(1);
+ }
+
+ if (j==0 || buffer[0] == '\n') {
+ /* we're done */
+ break;
+ }
+
+ /* move on... */
+
+ i -= j;
+ buffer += j;
+ }
+
+ /* <NUL> terminate */
+ buffer[0] = '\0';
+
+ return (i < MAXCAP ? 0:-1);
+}
+
+int main(int argc, char **argv)
+{
+ char buffer[MAXCAP+1];
+ int retval, quiet=0;
+ cap_t cap_d;
+
+ if (argc < 3) {
+ usage();
+ }
+
+ while (--argc > 0) {
+ const char *text;
+
+ if (!strcmp(*++argv,"-q")) {
+ quiet = 1;
+ continue;
+ }
+ if (!strcmp(*argv,"-")) {
+ retval = read_caps(quiet, *argv, buffer);
+ if (retval)
+ usage();
+ text = buffer;
+ } else
+ text = *argv;
+
+ cap_d = cap_from_text(text);
+ if (cap_d == NULL) {
+ perror("fatal error");
+ usage();
+ }
+#ifdef DEBUG
+ {
+ ssize_t length;
+ const char *result;
+
+ result = cap_to_text(cap_d, &length);
+ fprintf(stderr, "[caps set to:\n%s\n]\n", result);
+ }
+#endif
+
+ if (--argc <= 0)
+ usage();
+
+ retval = cap_set_file(*++argv, cap_d);
+
+ if (retval != 0) {
+ fprintf(stderr,
+ "Failed to set capabilities on file `%s'\n"
+ " (%s)\n", argv[0], strerror(errno));
+ usage();
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * $Log: setcap.c,v $
+ * Revision 1.2 1997/05/04 05:34:32 morgan
+ * non void main
+ *
+ * Revision 1.1 1997/04/28 01:01:20 morgan
+ * Initial revision
+ *
+ */
diff --git a/progs/setpcaps.c b/progs/setpcaps.c
new file mode 100644
index 0000000..0389129
--- /dev/null
+++ b/progs/setpcaps.c
@@ -0,0 +1,145 @@
+/*
+ * $Id: setpcaps.c,v 1.3 1998/09/20 23:07:08 morgan Exp $
+ *
+ * Copyright (c) 1997-8 Andrew G. Morgan <morgan@linux.kernel.org>
+ *
+ * This sets the capabilities of a given process.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#undef _POSIX_SOURCE
+#include <sys/capability.h>
+#include <unistd.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+"usage: setcap [-q] (-|<caps>) <pid> [ ... (-|<capsN>) <pid> ]\n\n"
+" This program can be used to set the process capabilities of running\n"
+" processes. In order to work, it needs to be executing with CAP_SETPCAP\n"
+" raised, and the only capabilities that this program can bestow on others\n"
+" are a subset of its effective set. This program is mostly intended as an\n"
+" example -- a safe use of CAP_SETPCAP has yet to be demonstrated!\n\n"
+"[Copyright (c) 1997-8 Andrew G. Morgan <morgan@linux.kernel.org>]\n"
+ );
+ exit(1);
+}
+
+#define MAXCAP 2048
+
+static int read_caps(int quiet, const char *filename, char *buffer)
+{
+ int i=MAXCAP;
+
+ if (!quiet) {
+ fprintf(stderr, "Please enter caps for file [empty line to end]:\n");
+ }
+ while (i > 0) {
+ int j = read(STDIN_FILENO, buffer, i);
+
+ if (j < 0) {
+ fprintf(stderr, "\n[Error - aborting]\n");
+ exit(1);
+ }
+
+ if (j==0 || buffer[0] == '\n') {
+ /* we're done */
+ break;
+ }
+
+ /* move on... */
+
+ i -= j;
+ buffer += j;
+ }
+
+ /* <NUL> terminate */
+ buffer[0] = '\0';
+
+ return (i < MAXCAP ? 0:-1);
+}
+
+int main(int argc, char **argv)
+{
+ char buffer[MAXCAP+1];
+ int retval, quiet=0;
+ cap_t cap_d;
+
+ if (argc < 3) {
+ usage();
+ }
+
+ while (--argc > 0) {
+ const char *text;
+ pid_t pid;
+
+ if (!strcmp(*++argv,"-q")) {
+ quiet = 1;
+ continue;
+ }
+ if (!strcmp(*argv,"-")) {
+ retval = read_caps(quiet, *argv, buffer);
+ if (retval)
+ usage();
+ text = buffer;
+ } else
+ text = *argv;
+
+ cap_d = cap_from_text(text);
+ if (cap_d == NULL) {
+ perror("fatal error");
+ usage();
+ }
+#ifndef DEBUG
+ {
+ ssize_t length;
+ char *result;
+
+ result = cap_to_text(cap_d, &length);
+ fprintf(stderr, "[caps set to:\n%s\n]\n", result);
+ free(result);
+ result = NULL;
+ }
+#endif
+
+ if (--argc <= 0)
+ usage();
+
+ pid = atoi(*++argv);
+ retval = capsetp(pid, cap_d);
+
+ if (retval != 0) {
+ fprintf(stderr, "Failed to set cap's on process `%d': (%s)\n",
+ pid, strerror(errno));
+ usage();
+ }
+#ifndef DEBUG
+ fprintf(stderr, "[caps set on %d]\n", pid);
+#endif
+ }
+
+ return 0;
+}
+
+/*
+ * $Log: setpcaps.c,v $
+ * Revision 1.3 1998/09/20 23:07:08 morgan
+ * fixed comment at top
+ *
+ * Revision 1.2 1998/06/08 00:17:38 morgan
+ * change to accommodate alpha (glibc?)
+ *
+ * Revision 1.1 1998/06/07 01:46:51 morgan
+ * Initial revision
+ *
+ * Revision 1.2 1997/05/04 05:34:32 morgan
+ * non void main
+ *
+ * Revision 1.1 1997/04/28 01:01:20 morgan
+ * Initial revision
+ *
+ */
diff --git a/progs/sucap.c b/progs/sucap.c
new file mode 100644
index 0000000..3c9c293
--- /dev/null
+++ b/progs/sucap.c
@@ -0,0 +1,196 @@
+/*
+ * $Id: sucap.c,v 1.3 1999/01/30 03:40:39 morgan Exp $
+ *
+ * This was written by Finn Arne Gangstad <finnag@guardian.no>
+ *
+ * This is a program that is intended to exec a subsequent program.
+ * The purpose of this 'sucap' wrapper is to change uid but keep all
+ * privileges. All environment variables are inherited.
+ */
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#undef _POSIX_SOURCE
+#include <sys/capability.h>
+#include <pwd.h>
+#define __USE_BSD
+#include <grp.h>
+#include <unistd.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <string.h>
+
+static void usage(void)
+{
+ fprintf(stderr,
+"usage: sucap <user> <group> <command-path> [command-args...]\n\n"
+" This program is a wrapper that change UID but not privileges of a\n"
+" program to be executed.\n"
+" Note, this wrapper is intended to assist in overcoming a lack of support\n"
+" for filesystem capability attributes and should be used to launch other\n"
+" files. This program should _NOT_ be made setuid-0.\n\n"
+"[Copyright (c) 1998 Finn Arne Gangstad <finnag@guardian.no>]\n");
+
+ exit(1);
+}
+
+
+static void
+wait_on_fd(int fd)
+{
+ /* Wait until some data is available on a file descriptor, or until
+ * end of file or an error is detected */
+ char buf[1];
+ while (read(fd, buf, sizeof(buf)) == -1 && errno == EINTR) {
+ /* empty loop */
+ }
+}
+
+
+void main(int argc, char **argv)
+{
+ cap_t old_caps;
+ uid_t uid;
+ pid_t pid, parent_pid;
+ gid_t gid;
+ int pipe_fds[2];
+
+ /* this program should not be made setuid-0 */
+ if (getuid() && !geteuid()) {
+ usage();
+ }
+
+ /* check that we have at least 3 arguments */
+ if (argc < 4) {
+ usage();
+ }
+
+ /* Convert username to uid */
+ {
+ struct passwd *pw = getpwnam(argv[1]);
+ if (!pw) {
+ fprintf(stderr, "sucap: No such user: %s\n", argv[1]);
+ exit(1);
+ }
+ uid = pw->pw_uid;
+ }
+
+ /* Convert groupname to gid */
+ {
+ struct group *gr = getgrnam(argv[2]);
+ if (!gr) {
+ fprintf(stderr, "sucap: No such group: %s\n", argv[2]);
+ exit(1);
+ }
+ gid = gr->gr_gid;
+ }
+
+ /* set process group to current pid */
+ if (setpgid(0, getpid())) {
+ perror("sucap: Failed to set process group");
+ exit(1);
+ }
+
+ if (pipe(pipe_fds)) {
+ perror("sucap: pipe() failed");
+ exit(1);
+ }
+
+ parent_pid = getpid();
+
+ old_caps = cap_init();
+ if (capgetp(0, old_caps)) {
+ perror("sucap: capgetp");
+ exit(1);
+ }
+
+ {
+ ssize_t x;
+ printf("Caps: %s\n", cap_to_text(old_caps, &x));
+ }
+
+
+ /* fork off a child to do the hard work */
+ fflush(NULL);
+ pid = fork();
+ if (pid == -1) {
+ perror("sucap: fork failed");
+ exit(1);
+ }
+
+ /* 1. mother process sets gid and uid
+ * 2. child process sets capabilities of mother process
+ * 3. mother process execs whatever is to be executed
+ */
+
+ if (pid) {
+ /* Mother process. */
+ close(pipe_fds[0]);
+
+ /* Get rid of any supplemental groups */
+ if (!getuid() && setgroups(0, 0)) {
+ perror("sucap: setgroups failed");
+ exit(1);
+ }
+
+ /* Set gid and uid (this probably clears capabilities) */
+ setregid(gid, gid);
+ setreuid(uid, uid);
+
+ {
+ ssize_t x;
+ cap_t cap = cap_init();
+ capgetp(0, cap);
+ printf("Caps: %s\n", cap_to_text(cap, &x));
+ }
+
+ printf("[debug] uid:%d, real uid:%d\n", geteuid(), getuid());
+
+ /* Signal child that we want our privileges updated */
+ close(pipe_fds[1]); /* Child hangs in blocking read */
+
+ /* Wait for child process to set our privileges */
+ {
+ int status = 0;
+ if (wait(&status) == -1) {
+ perror("sucap: wait failed");
+ }
+ if (!WIFEXITED(status) || WEXITSTATUS(status)) {
+ fprintf(stderr, "sucap: child did not exit cleanly.\n");
+ exit(1);
+ }
+ }
+
+ {
+ ssize_t x;
+ cap_t cap = cap_init();
+ capgetp(0, cap);
+ printf("Caps: %s\n", cap_to_text(cap, &x));
+ }
+
+/* printf("[debug] uid:%d, real uid:%d\n", geteuid(), getuid()); */
+ /* exec the program indicated by args 2 ... */
+ execvp(argv[3], argv+3);
+
+ /* if we fall through to here, our exec failed -- announce the fact */
+ fprintf(stderr, "Unable to execute command: %s\n", strerror(errno));
+
+ usage();
+ } else {
+ /* Child process */
+ close(pipe_fds[1]);
+
+ /* Wait for mother process to setuid */
+ wait_on_fd(pipe_fds[0]);
+
+ /* Set privileges on mother process */
+ if (capsetp(parent_pid, old_caps)) {
+ perror("sucaps: capsetp");
+ _exit(1);
+ }
+
+ /* exit to signal mother process that we are ready */
+ _exit(0);
+ }
+}
diff --git a/template.c b/template.c
new file mode 100644
index 0000000..d1613fa
--- /dev/null
+++ b/template.c
@@ -0,0 +1,11 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 1997 <Author> <@>
+ *
+ * <Content>
+ */
+
+/*
+ * $Log$
+ */