libcap-2.24/CHANGELOG0000664000076400007640000000076412257340725013457 0ustar andrewandrewFor release notes and other info pointers: http://sites.google.com/site/fullycapable/ See GIT repository for detailed source history https://git.kernel.org/cgit/linux/kernel/git/morgan/libcap.git/ Or simply download the source: git clone git://git.kernel.org/pub/scm/linux/kernel/git/morgan/libcap.git The license for this library is here: https://git.kernel.org/cgit/linux/kernel/git/morgan/libcap.git/tree/License please submit patches compatible with this to morgan at kernel.org. libcap-2.24/contrib/0000775000076400007640000000000012253502644013672 5ustar andrewandrewlibcap-2.24/contrib/pcaps4suid00000664000076400007640000001272412253502644015762 0ustar andrewandrew#!/bin/bash # vim:expandtab:tabstop=4 # # author: chris friedhoff - chris@friedhoff.org # version: pcaps4suid0 3 Tue Mar 11 2008 # # # changelog: # 1 - initial release suid02pcaps # 2 - renamend to pcaps4suid0 # implement idea of change between permitted/effective set # or iherited/effective set (pam_cap.so) # 3 - changed 'attr -S -r' to 'setcap -r' and removed attr code # # # # change different suid-0 binaries away from suid-0 to using # POSIX Capabilities through their Permitted and Effective Set # --> legacy support # --> use SET=pe # # # OR change different suid-0 binaries away from suid-0 to using # POSIX Capabilities through their Inherited and Effective Set # --> PAM support to set Inheritance set through pam_cap.so # --> use SET=ie # # # # ############################################################### # for example use this find call: # find {,/usr}{/bin,/sbin} -perm -4000 -uid 0 -exec ls -l {} \; ############################################################### ##HERE WE ADD APPS ################## ## these apps uses their POSIX Caps ################################### # see /usr/include/linux/capability.h #ping=cap_net_raw ping=13 #traceroute=cap_net_raw traceroute=13 chsh=0,2,4,7 chfn=0,2,4,7 Xorg=1,6,7,17,21,26 chage=2 #passwd=0,2,4,7 #passwd 0,1 passwd=0,1,3 #PAM unix_chkpwd=1 mount=1,21 umount=1,21 # this apps were converted/reverted ################################### APPSARRAY=( ping traceroute chsh chfn Xorg chage passwd unix_chkpwd mount umount ) # we put it into this set ######################### #SET=pe SET=ie ##FROM HERE ONLY LOGIC ###################### #save assumption!? export PATH=/sbin:/bin:/usr/sbin:/usr/bin/:usr/local/sbin:/usr/local/bin p4s_test(){ # are we sane? WICH=`which which 2>/dev/null` if [ $WICH == "" ]; then # thats bad echo "Sorry, I haven't found which" exit fi # we needt his apps CHMOD=`which chmod 2>/dev/null` SETCAP=`which setcap 2>/dev/null` if [ "$CHMOD" == "" -o "$SETCAP" == "" ]; then echo "Sorry, I'm missing chmod or setcap !" exit fi # checking setcap for SET_SETFCAP PCap ? # for now we stick to root if [ "$( id -u )" != "0" ]; then echo "Sorry, you must be root !" exit 1 fi } p4s_app_convert(){ # convert a single app # $1 is app name; $2 is POSIX Caps # well symlinks to apps, so we use -a ... APP=`which -a $1 2>/dev/null` if [ "$APP" != "" ]; then FOUND=no for i in $APP; do # ... and are looking for symlinks if [ -f "$i" -a ! -L $i -a "$FOUND"=="no" ]; then echo "converting $i" chmod u-s $i setcap $2=$SET $i FOUND=yes fi done if [ "$FOUND" == "no" ]; then # 'which' found only symlinks echo "1 haven't found $1" fi else # 'which' hasn't anything given back echo "haven't found $1" fi } p4s_app_revert(){ # revert a singel app # $1 is app name APP=`which -a $1 2>/dev/null` if [ "$APP" != "" ]; then FOUND=no for i in $APP; do if [ -f "$i" -a ! -L $i -a "$FOUND"=="no" ]; then echo "reverting $i" chmod u+s $i setcap -r $i 2>/dev/null FOUND=yes fi done if [ "$FOUND" == "no" ]; then echo "1 haven't found $1" fi else echo "haven't found $1" fi } p4s_convert(){ # we go throug the APPSARRAY and call s2p_app_convert to do the job COUNTER=0 let UPPER=${#APPSARRAY[*]}-1 until [ $COUNTER == $UPPER ]; do p4s_app_convert ${APPSARRAY[$COUNTER]} ${!APPSARRAY[$COUNTER]} let COUNTER+=1 done } p4s_revert(){ COUNTER=0 let UPPER=${#APPSARRAY[*]}-1 until [ $COUNTER == $UPPER ]; do p4s_app_revert ${APPSARRAY[$COUNTER]} let COUNTER+=1 done } p4s_usage(){ echo echo "pcaps4suid0" echo echo "pcaps4suid0 changes the file system entry of binaries from using setuid-0" echo "to using POSIX Capabilities by granting the necessary Privileges" echo "This is done by storing the needed POSIX Capabilities into the extended" echo "attribute capability through setcap." echo "Following the idea of setuid - granting a binary the privilege regardless" echo "of the user, the POSIX Capabilities are stored into the Permitted and" echo "Effective set." echo "If you are using pam_cap.so, you might want to change the set into the" echo "Inherited and Effective set (check for the SET var)." echo echo "You need and I will check fot the utilities which, chmod and setcap." echo echo "Your Filesystem has to support extended attributes and your kernel must have" echo "support for POSIX File Capabilities (CONFIG_SECURITY_FILE_CAPABILITIES)." echo echo "Usage: pcaps4suid0 [con(vert)|rev(ert)|help]" echo echo " con|convert - from setuid0 to POSIX Capabilities" echo " rev|revert - from POSIX Capabilities back to setui0" echo " help - this help message" echo } case "$1" in con|convert) p4s_test p4s_convert exit 0 ;; rev|revert) p4s_test p4s_revert exit 0 ;; help) p4s_usage exit 0 ;; *) echo "Try 'pcaps4suid0 help' for more information" exit 1 ;; esac libcap-2.24/contrib/pcaps4convenience0000664000076400007640000001171212253502644017226 0ustar andrewandrew#!/bin/bash # vim:expandtab:tabstop=4 # # author: chris friedhoff - chris@friedhoff.org # version: pcaps4convenience 2 Tue Mar 11 2008 # # # changelog: # 1 - initial release pcaps4convenience # 2 - changed 'attr -S -r' to 'setcap -r' and removed attr code # # # the user has the necessary POSIX Capabilities in his Inheritance # set and the applications are accepting the needed PCaps through # their Inheritance set. # a user who has not the PCaps in his Inheritance set CAN NOT # successfully execute the apps # --> SET=ie # (if SET=pe than you relax the security level of your machine) # # # ##HERE WE ADD APPS ################## ## these apps uses their POSIX Caps ################################### # see /usr/include/linux/capability.h # adjust - if needed and wanted - /etc/security/capability.conf #eject=cap_dac_read_search,cap_sys_rawio eject=2,17 #killall=cap_kill killall=5 #modprobe=cap_sys_module modprobe=16 #ntpdate=cap_net_bind_service,cap_sys_time ntpdate=10,25 #qemu=cap_net_admin qemu=12 #route=cap_net_admin route=12 # this apps were converted/reverted ################################### APPSARRAY=( eject killall modprobe ntpdate qemu route ) # we put it into this set ######################### SET=ie ##FROM HERE ONLY LOGIC ###################### #save assumption!? export PATH=/sbin:/bin:/usr/sbin:/usr/bin/:usr/local/sbin:/usr/local/bin p4c_test(){ # are we sane? WICH=`which which 2>/dev/null` if [ $WICH == "" ]; then # thats bad echo "Sorry, I haven't found which" exit fi # we needt his apps SETCAP=`which setcap 2>/dev/null` if [ "$SETCAP" == "" ]; then echo "Sorry, I'm missing setcap !" exit fi # checking setcap for SET_SETFCAP PCap ? # for now we stick to root if [ "$( id -u )" != "0" ]; then echo "Sorry, you must be root !" exit 1 fi } p4c_app_convert(){ # convert a single app # $1 is app name; $2 is POSIX Caps # well symlinks to apps, so we use -a ... APP=`which -a $1 2>/dev/null` if [ "$APP" != "" ]; then FOUND=no for i in $APP; do # ... and are looking for symlinks if [ -f "$i" -a ! -L $i -a "$FOUND"=="no" ]; then echo "converting $i" setcap $2=$SET $i FOUND=yes fi done if [ "$FOUND" == "no" ]; then # 'which' found only symlinks echo "1 haven't found $1" fi else # 'which' hasn't anything given back echo "haven't found $1" fi } p4c_app_revert(){ # revert a singel app # $1 is app name APP=`which -a $1 2>/dev/null` if [ "$APP" != "" ]; then FOUND=no for i in $APP; do if [ -f "$i" -a ! -L $i -a "$FOUND"=="no" ]; then echo "reverting $i" setcap -r $i 2>/dev/null FOUND=yes fi done if [ "$FOUND" == "no" ]; then echo "1 haven't found $1" fi else echo "haven't found $1" fi } p4c_convert(){ # we go throug the APPSARRAY and call s2p_app_convert to do the job COUNTER=0 let UPPER=${#APPSARRAY[*]}-1 until [ $COUNTER == $UPPER ]; do p4c_app_convert ${APPSARRAY[$COUNTER]} ${!APPSARRAY[$COUNTER]} let COUNTER+=1 done } p4c_revert(){ COUNTER=0 let UPPER=${#APPSARRAY[*]}-1 until [ $COUNTER == $UPPER ]; do p4c_app_revert ${APPSARRAY[$COUNTER]} let COUNTER+=1 done } p4c_usage(){ echo echo "pcaps4convenience" echo echo "pcaps4convenience stores the needed POSIX Capabilities for binaries to" echo "run successful into their Inheritance and Effective Set." echo "The user who wants to execute this binaries successful has to have the" echo "necessary POSIX Capabilities in his Inheritable Set. This might be done" echo "through the PAM module pam_cap.so." echo "A user who has not the needed PCaps in his Inheritance Set CAN NOT execute" echo "these binaries successful." echo "(well, still per sudo or su -c - but thats not the point here)" echo echo "You need and I will check fot the utilities which and setcap." echo echo "Your Filesystem has to support extended attributes and your kernel must have" echo "support for POSIX File Capabilities (CONFIG_SECURITY_FILE_CAPABILITIES)." echo echo "Usage: pcaps4convenience [con(vert)|rev(ert)|help]" echo echo " con|convert - from setuid0 to POSIX Capabilities" echo " rev|revert - from POSIX Capabilities back to setui0" echo " help - this help message" echo } case "$1" in con|convert) p4c_test p4c_convert exit 0 ;; rev|revert) p4c_test p4c_revert exit 0 ;; help) p4c_usage exit 0 ;; *) echo "Try 'pcaps4convenience help' for more information" exit 1 ;; esac libcap-2.24/contrib/Makefile0000664000076400007640000000012112253502644015324 0ustar andrewandrew.PHONY: all clean all clean: for x in bug* ; do make -C $$x $@ || exit 1 ; done libcap-2.24/contrib/pcaps4server0000664000076400007640000002317412253502644016245 0ustar andrewandrew#!/bin/sh # vim: tabstop=4 # # author: chris friedhoff - chris@friedhoff.org # version: pcaps4server 5 Tue Mar 11 2008 # # # changelog: # 1 - initial release pcaps4convenience # 1 - 2007.02.15 - initial release # 2 - 2007.11.02 - changed to new setfcaps api; each app is now callable; supressed error of id # 3 - 2007.12.28 - changed to libcap2 package setcap/getcap # 4 - renamed to pcaps4server # removed suid0 and convenience files, # they are now in pcaps4suid0 resp. pcaps4convenience # 5 - changed 'attr -S -r' to 'setcap -r' and removed attr code # # ########################################################################### # change the installation of different server to be able not to run as root # and have their own unpriviledged user. The binary has the needed POSIX # Capabilities. # to ensure that the server is really started as his respective user, we set # the suid bit (BUT NOT 0)! # paths are hard coded and derive from a slackware system # change it to your needs !! ########################################################################### VERBOSE="-v" #VERBOSE="" APPS="" message(){ printRedMessage "$1" } printRedMessage(){ # print message red and turn back to white echo -e "\n\033[00;31m $1 ...\033[00;00m\n" } printGreenMessage(){ # print message red and turn back to white echo -e "\033[00;32m $1 ...\033[00;00m\n" sleep 0.5 } checkReturnCode(){ if [ "$?" != "0" ]; then printRedMessage "!! I'M HAVING A PROBLEM !! THE RETURNCODE IS NOT 0 !! I STOP HERE !!" exit 1 else printGreenMessage ":-)" sleep 0.5 fi } p4r_test(){ #for now, we work with root if [ "$( id -u )" != "0" ]; then echo "Sorry, you must be root !" exit fi } # apache 1.3 ######## #APPS="$APPS apache1" apache1_convert(){ message "converting apache1" if [ "$( id -g apache 2>/dev/null )" == "" ]; then groupadd -g 60 apache fi if [ "$( id -u apache 2>/dev/null )" == "" ]; then useradd -g apache -d / -u 600 apache fi sed -i -e "{s|^\(User\).*|\1 apache|; s|^\(Group\) .*|\1 apache|}" /etc/apache/httpd.conf chown $VERBOSE -R apache:apache /var/run/apache/ chown $VERBOSE -R apache:apache /etc/apache/ chown $VERBOSE -R apache:apache /var/log/apache/ chown $VERBOSE apache:apache /usr/sbin/httpd chmod $VERBOSE u+s /usr/sbin/httpd setcap cap_net_bind_service=ep /usr/sbin/httpd checkReturnCode } apache1_revert(){ message "reverting apache1" chown $VERBOSE -R root:root /var/run/apache/ chown $VERBOSE -R root:root /etc/apache/ chown $VERBOSE -R root:root /var/log/apache/ chown $VERBOSE root:root /usr/sbin/httpd chmod $VERBOSE u-s /usr/sbin/httpd setcap -r /usr/sbin/httpd checkReturnCode sed -i -e "{s|^\(User\).*|\1 nobody|; s|^\(Group\).*|\1 nogroup|}" /etc/apache/httpd.conf userdel apache groupdel apache } # apache 2.x ######## APPS="$APPS apache2" apache2_convert(){ message "converting apache2" if [ "$( id -g apache 2>/dev/null )" == "" ]; then groupadd -g 60 apache fi if [ "$( id -u apache 2>/dev/null )" == "" ]; then useradd -g apache -d / -u 600 apache fi sed -i -e "{s|^\(User\).*|\1 apache|; s|^\(Group\) .*|\1 apache|}" /etc/httpd/httpd.conf chown $VERBOSE -R apache:apache /var/run/httpd/ chown $VERBOSE -R apache:apache /etc/httpd/ chown $VERBOSE -R apache:apache /var/log/httpd/ chown $VERBOSE apache:apache /usr/sbin/httpd chmod $VERBOSE u+s /usr/sbin/httpd #setfcaps -c cap_net_bind_service=p -e /usr/sbin/httpd setcap cap_net_bind_service=ep /usr/sbin/httpd checkReturnCode } apache2_revert(){ message "reverting apache2" chown $VERBOSE -R root:root /var/run/httpd/ chown $VERBOSE -R root:root /etc/httpd/ chown $VERBOSE -R root:root /var/log/httpd/ chown $VERBOSE root:root /usr/sbin/httpd chmod $VERBOSE u-s /usr/sbin/httpd setcap -r /usr/sbin/httpd checkReturnCode sed -i -e "{s|^\(User\).*|\1 nobody|; s|^\(Group\).*|\1 nogroup|}" /etc/httpd/httpd.conf userdel apache groupdel apache } # samba ####### APPS="$APPS samba" samba_convert(){ message "converting samba" if [ "$( id -g samba 2>/dev/null )" == "" ]; then groupadd -g 61 samba fi if [ "$( id -u samba 2>/dev/null )" == "" ]; then useradd -g samba -d / -u 610 samba fi chown $VERBOSE -R samba:samba /var/log/samba chown $VERBOSE -R samba:samba /etc/samba chown $VERBOSE -R samba:samba /var/run/samba chown $VERBOSE -R samba:samba /var/cache/samba chown $VERBOSE samba:samba /usr/sbin/smbd /usr/sbin/nmbd chmod $VERBOSE u+s /usr/sbin/smbd /usr/sbin/nmbd setcap cap_net_bind_service,cap_sys_resource,cap_dac_override=ep /usr/sbin/smbd checkReturnCode setcap cap_net_bind_service=ep /usr/sbin/nmbd checkReturnCode } samba_revert(){ message "reverting samba" chown $VERBOSE -R root:root /var/log/samba chown $VERBOSE -R root:root /etc/samba chown $VERBOSE -R root:root /var/run/samba chown $VERBOSE -R root:root /var/cache/samba chown $VERBOSE root:root /usr/sbin/smbd /usr/sbin/nmbd chmod $VERBOSE u-s /usr/sbin/smbd /usr/sbin/nmbd setcap -r /usr/sbin/smbd checkReturnCode setcap -r /usr/sbin/nmbd checkReturnCode userdel samba groupdel samba } # bind ###### APPS="$APPS bind" bind_convert(){ message "converting bind" if [ "$( id -g bind 2>/dev/null )" == "" ]; then groupadd -g 62 bind fi if [ "$( id -u bind 2>/dev/null )" == "" ]; then useradd -g bind -d / -u 620 bind fi chown $VERBOSE -R bind:bind /var/run/named chown $VERBOSE -R bind:bind /var/named chown $VERBOSE bind:bind /etc/rndc.key chown $VERBOSE bind:bind /usr/sbin/named chmod $VERBOSE u+s /usr/sbin/named setcap cap_net_bind_service=ep /usr/sbin/named checkReturnCode } bind_revert(){ message "reverting bind" chown $VERBOSE -R root:root /var/run/named chown $VERBOSE -R root:root /var/named chown $VERBOSE root:root /etc/rndc.key chown $VERBOSE root:root /usr/sbin/named chmod $VERBOSE u-s /usr/sbin/named setcap -r /usr/sbin/named checkReturnCode userdel bind groupdel bind } # dhcpd ####### APPS="$APPS dhcpd" dhcpd_convert(){ message "converting dhcpd" if [ "$( id -g dhcpd 2>/dev/null )" == "" ]; then groupadd -g 63 dhcpd fi if [ "$( id -u dhcpd 2>/dev/null )" == "" ]; then useradd -g dhcpd -d / -u 630 dhcpd fi chown $VERBOSE dhcpd:dhcpd /var/run/dhcpd chown $VERBOSE dhcpd:dhcpd /etc/dhcpd.conf chown $VERBOSE -R dhcpd:dhcpd /var/state/dhcp/ chown $VERBOSE dhcpd:dhcpd /usr/sbin/dhcpd chmod $VERBOSE u+s /usr/sbin/dhcpd setcap cap_net_bind_service,cap_net_raw=ep /usr/sbin/dhcpd checkReturnCode } dhcpd_revert(){ message "reverting dhcpd" chown $VERBOSE root:root /var/run/dhcpd chown $VERBOSE root:root /etc/dhcpd.conf chown $VERBOSE -R root:root /var/state/dhcp/ chown $VERBOSE root:root /usr/sbin/dhcpd chmod $VERBOSE u-s /usr/sbin/dhcpd setcap -r /usr/sbin/dhcpd checkReturnCode userdel dhcpd groupdel dhcpd } # cupsd ####### APPS="$APPS cupsd" cupsd_convert(){ message "converting cupsd" if [ "$( id -g cupsd 2>/dev/null )" == "" ]; then groupadd -g 64 cupsd fi if [ "$( id -u cupsd 2>/dev/null )" == "" ]; then useradd -g cupsd -d / -u 640 cupsd fi sed -i -e "{s|^\(User\).*|\1 cupsd|; s|^\(Group\) .*|\1 cupsd|}" /etc/cups/cupsd.conf chown $VERBOSE -R cupsd:cupsd /etc/cups chown $VERBOSE -R cupsd:cupsd /var/cache/cups chown $VERBOSE -R cupsd:cupsd /var/log/cups chown $VERBOSE -R cupsd:cupsd /var/spool/cups chown $VERBOSE -R cupsd:cupsd /var/run/cups chown $VERBOSE cupsd:cupsd /usr/sbin/cupsd chmod $VERBOSE u+s /usr/sbin/cupsd setcap cap_net_bind_service,cap_dac_read_search=ep /usr/sbin/cupsd checkReturnCode } cupsd_revert(){ message "reverting cupsd" chown $VERBOSE -R root:root /etc/cups chown $VERBOSE -R root:lp /var/cache/cups chown $VERBOSE -R root:root /var/log/cups chown $VERBOSE -R root:root /var/spool/cups chown $VERBOSE root:lp /var/run/cups chown $VERBOSE lp:sys /var/run/cups/certs chmod $VERBOSE 750 /var/run/cups/certs chown $VERBOSE root:root /usr/sbin/cupsd chmod $VERBOSE u-s /usr/sbin/cupsd setcap -r /usr/sbin/cupsd checkReturnCode sed -i -e "{s|^\(User\).*|\1 lp|; s|^\(Group\) .*|\1 sys|}" /etc/cups/cupsd.conf userdel cupsd groupdel cupsd } usage_message(){ echo "Try 'pcaps4server help' for more information" } p4r_usage(){ echo echo "pcaps4server" echo echo "pcaps4server stores the needed POSIX Capabilities for server binaries to" echo "run successful into their Permitted and Effective Set." echo "The server are now able to run as an unpriviledged user." echo "For each server software an unpriviledged user is added the system." echo "The ownership of all the respective paths are changed to this user." echo "To ensure that the server is starting as this unpriviledgesd user, the" echo "suid bit (NOT 0) is set." echo "Effectively this means every user can start this server daemons (for now)." echo "All paths are hard coded!" echo "You have been warned. Enjoy!" echo echo "Your Filesystem has to support extended attributes and your kernel must have" echo "support for POSIX File Capabilities (CONFIG_SECURITY_FILE_CAPABILITIES)." echo echo "Usage: pcaps4server [PROG] [con(vert)|rev(ert)|help]" echo echo " con|convert - from setuid0 to POSIX Capabilities" echo " rev|revert - from POSIX Capabilities back to setui0" echo " help - this help message" echo echo " PROG: $APPS" echo } case "$1" in con|convert) p4r_test for j in $APPS; do ${j}_convert done exit ;; rev|renvert) p4r_test for j in $APPS; do ${j}_revert done exit ;; help) p4r_usage exit ;; esac for i in ${APPS}; do if [ "$1" == "$i" ]; then case "$2" in con|convert) p4r_test ${i}_convert exit ;; rev|revert) p4r_test ${i}_revert exit ;; *) usage_message exit 1 ;; esac fi done usage_message libcap-2.24/contrib/bug400591/0000775000076400007640000000000012253502644015132 5ustar andrewandrewlibcap-2.24/contrib/bug400591/bug.c0000664000076400007640000000145012253502644016053 0ustar andrewandrew#include #include #include /* * Original from http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=400591 * * Modified to test more functions.. AGM - 2008/07/06. */ int main (int argc, char *argv[]) { cap_t caps, caps2; ssize_t size, copy_size; void *buffer; char *text1, *text2; assert((caps = cap_get_pid(1))); text1 = cap_to_text(caps, NULL); assert(text1); size = cap_size (caps); assert (size>0 && size<1024); buffer = malloc (size); assert (buffer); copy_size = cap_copy_ext (buffer, caps, size); assert (copy_size == size); caps2 = cap_copy_int(buffer); assert (caps2); text2 = cap_to_text(caps2, NULL); assert(text2); assert(strcmp(text1, text2) == 0); assert(cap_compare(caps, caps2) == 0); return 0; } libcap-2.24/contrib/bug400591/Makefile0000664000076400007640000000024612253502644016574 0ustar andrewandrewall: bug bug: bug.c ../../libcap Makefile make -C ../../libcap cc -g -I../../libcap/include --static -o $@ $< -L../../libcap -lcap ./bug clean: rm -f bug.o bug libcap-2.24/doc/0000775000076400007640000000000012253502644012777 5ustar andrewandrewlibcap-2.24/doc/capsh.10000664000076400007640000001071612253502644014164 0ustar andrewandrew.\" .\" capsh.1 Man page added 2009-12-23 Andrew G. Morgan .\" .TH CAPSH 1 "2011-04-24" "libcap 2" "User Commands" .SH NAME capsh \- capability shell wrapper .SH SYNOPSIS .B capsh [\fIOPTION\fR]... .SH DESCRIPTION Linux capability support and use can be explored and constrained with this tool. This tool provides a handy wrapper for certain types of capability testing and environment creation. It also provides some debugging features useful for summarizing capability state. .SH OPTIONS The tool takes a number of optional arguments, acting on them in the order they are provided. They are as follows: .TP 22 .B --print Display prevailing capability and related state. .TP .BI -- " [args]" Execute .B /bin/bash with trailing arguments. Note, you can use .B -c 'command to execute' for specific commands. .TP .B == Execute .B capsh again with remaining arguments. Useful for testing .BR exec () behavior. .TP .BI --caps= cap-set Set the prevailing process capabilities to those specified by .IR cap-set . Where .I cap-set is a text-representation of capability state as per .BR cap_from_text (3). .TP .BI --drop= cap-list Remove the listed capabilities from the prevailing bounding set. The capabilites are a comma separated list of capabilities as recognized by the .BR cap_from_name (3) function. Use of this feature requires that the capsh program is operating with .B CAP_SETPCAP in its effective set. .TP .BI --inh= cap-list Set the inheritable set of capabilities for the current process to equal those provided in the comma separated list. For this action to succeed, the prevailing process should already have each of these capabilities in the union of the current inheritable and permitted capability sets, or the capsh program is operating with .B CAP_SETPCAP in its effective set. .TP .BI --user= username Assume the identity of the named user. That is, look up the user's .IR uid " and " gid with .BR getpwuid (3) and their group memberships with .BR getgrouplist (3) and set them all. .TP .BI --uid= id Force all .B uid values to equal .I id using the .BR setuid (2) system call. .TP .BI --gid= Force all .B gid values to equal .I id using the .BR setgid (2) system call. .TP .BI --groups= Set the supplementary groups to the numerical list provided. The groups are set with the .BR setgroups (2) system call. .TP .BI --keep= <0|1> In a non-pure capability mode, the kernel provides liberal privilege to the super-user. However, it is normally the case that when the super-user changes .I uid to some lesser user, then capabilities are dropped. For these situations, the kernel can permit the process to retain its capabilities after a .BR setuid (2) system call. This feature is known as .I keep-caps support. The way to activate it using this script is with this argument. Setting the value to 1 will cause .I keep-caps to be active. Setting it to 0 will cause keep-caps to deactivate for the current process. In all cases, .I keep-caps is deactivated when an .BR exec () is performed. See .B --secbits for ways to disable this feature. .TP .BI --secbits= N XXX - need to document this feature. .TP .BI --chroot= path Execute the .BR chroot (2) system call with the new root-directory (/) equal to .IR path . This operation requires .B CAP_SYS_CHROOT to be in effect. .TP .BI --forkfor= sec .TP .BI --killit= sig .TP .BI --decode= N This is a convenience feature. If you look at .B /proc/1/status there are some capability related fields of the following form: CapInh: 0000000000000000 CapPrm: ffffffffffffffff CapEff: fffffffffffffeff CapBnd: ffffffffffffffff This option provides a quick way to decode a capability vector represented in this form. For example, the missing capability from this effective set is 0x0100. By running: capsh --decode=0x0100 we observe that the missing capability is: .BR cap_setpcap . .TP .BI --supports= xxx As the kernel evolves, more capabilities are added. This option can be used to verify the existence of a capability on the system. For example, .BI --supports= cap_syslog will cause capsh to promptly exit with a status of 1 when run on kernel 2.6.27. However, when run on kernel 2.6.38 it will silently succeed. .TP .SH "EXIT STATUS" Following successful execution the tool exits with status 0. Following an error, the tool immediately exits with status 1. .SH AUTHOR Written by Andrew G. Morgan . .SH "REPORTING BUGS" Please report bugs to the author. .SH "SEE ALSO" .BR libcap (3), .BR getcap (8), setcap (8) and .BR capabilities (7). libcap-2.24/doc/cap_get_proc.30000664000076400007640000001267212253502644015520 0ustar andrewandrew.\" .\" $Id: cap_get_proc.3,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $ .\" .TH CAP_GET_PROC 3 "2008-05-11" "" "Linux Programmer's Manual" .SH NAME cap_get_proc, cap_set_proc, capgetp, cap_get_bound, cap_drop_bound \- capability manipulation on processes .SH SYNOPSIS .B #include .sp .B "cap_t cap_get_proc(void);" .sp .BI "int cap_set_proc(cap_t " cap_p ); .sp .BI "int cap_get_bound(cap_value_t " cap ); .sp .BI "CAP_IS_SUPPORTED(cap_value_t " cap ); .sp .BI "int cap_drop_bound(cap_value_t " cap ); .sp .B #include .sp .BI "cap_t cap_get_pid(pid_t " pid ); .sp Link with \fI-lcap\fP. .SH DESCRIPTION .BR 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 .BR cap_free () with the .I cap_t as an argument. .PP .BR cap_set_proc () sets the values for all capability flags for all capabilities to 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 .BR cap_get_pid () returns .IR 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 .I /proc//status file. .PP .BR cap_get_bound () with a .I cap as an argument returns the current value of this bounding set capability flag in effect for the current process. This operation is unpriveged. Note, a macro function .BI "CAP_IS_SUPPORTED(cap_value_t " cap ) is provided that evaluates to true (1) if the system supports the specified capability, .IR cap . If the system does not support the capability, this function returns 0. This macro works by testing for an error condition with .BR cap_get_bound (). .PP .BR cap_drop_bound () can be used to lower the specified bounding set capability, .BR cap , To complete successfully, the prevailing .I effective capability set must have a raised .BR CAP_SETPCAP . .SH "RETURN VALUE" The functions .BR cap_get_proc () and .BR cap_get_pid () return a non-NULL value on success, and NULL on failure. .PP The function .BR cap_get_bound () returns -1 if the requested capability is unknown, otherwise the return value reflects the current state of that capability in the prevailing bounding set. Note, a macro function, .PP The functions .BR cap_set_proc () and .BR cap_drop_bound () return zero for success, and \-1 on failure. .PP On failure, .I errno is set to .BR EINVAL , .BR EPERM, or .BR ENOMEM . .SH "CONFORMING TO" .BR cap_set_proc () and .BR cap_get_proc () are specified in the withdrawn POSIX.1e draft specification. .BR cap_get_pid () is a Linux extension. .SH "NOTES" The library also supports the deprecated functions: .PP .BI "int capgetp(pid_t " pid ", cap_t " cap_d ); .PP .BI "int capsetp(pid_t " pid ", cap_t " cap_d ); .PP .BR capgetp () attempts to obtain the capabilities of some other process; storing the capabilities in a pre-allocated .IR cap_d . See .BR cap_init () for information on allocating an empty capability set. This function, .BR capgetp (), is deprecated, you should use .BR cap_get_pid (). .PP .BR 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 kernel must support it and 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 . Kernels that support filesystem capabilities redefine the semantics of .B CAP_SETPCAP and on such systems this function will always fail for any target not equal to the current process. .BR capsetp () returns zero for success, and \-1 on failure. Where supported by the kernel, the function .BR capsetp () should be used with care. It existed, primarily, to overcome an early lack of support for capabilities in the filesystems supported by Linux. Note that, 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 EXAMPLE The code segment below raises the .B CAP_FOWNER and .B CAP_SETFCAP effective capabilities for the caller: .nf cap_t caps; cap_value_t cap_list[2]; if (!CAP_IS_SUPPORTED(CAP_SETFCAP)) /* handle error */ caps = cap_get_proc(); if (caps == NULL) /* handle error */; cap_list[0] = CAP_FOWNER; cap_list[1] = CAP_SETFCAP; if (cap_set_flag(caps, CAP_EFFECTIVE, 2, cap_list, CAP_SET) == -1) /* handle error */; if (cap_set_proc(caps) == -1) /* handle error */; if (cap_free(caps) == -1) /* handle error */; .fi .SH "SEE ALSO" .BR libcap (3), .BR cap_clear (3), .BR cap_copy_ext (3), .BR cap_from_text (3), .BR cap_get_file (3), .BR cap_init (3), .BR capabilities (7) libcap-2.24/doc/cap_init.30000664000076400007640000000450712253502644014657 0ustar andrewandrew.\" .\" written by Andrew Main .\" .TH CAP_INIT 3 "2008-05-11" "" "Linux Programmer's Manual" .SH NAME cap_init, cap_free, cap_dup \- capability data object storage management .SH SYNOPSIS .B #include .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 ); .sp Link with \fI-lcap\fP. .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 .BR cap_init () creates a capability state in working storage and returns 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 .BR cap_free () with the .I cap_t as an argument. .PP .BR 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 .BR cap_to_text () function. .PP .BR 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. When the duplicated capability state in working storage is no longer required, the caller should free any releasable memory by calling .BR cap_free () with the .I cap_t as an argument. .SH "RETURN VALUE" .BR cap_init () and .BR cap_dup () return a non-NULL value on success, and NULL on failure. .PP .BR cap_free () returns zero on success, and \-1 on failure. .PP On failure, .I errno is set to .BR EINVAL or .BR ENOMEM . .SH "CONFORMING TO" These functions are specified in the withdrawn POSIX.1e draft specification. .SH "SEE ALSO" .BR libcap (3), .BR cap_clear (3), .BR cap_copy_ext (3), .BR cap_from_text (3), .BR cap_get_file (3), .BR cap_get_proc (3), .BR capabilities (7) libcap-2.24/doc/cap_size.30000664000076400007640000000003012253502644014651 0ustar andrewandrew.so man3/cap_copy_ext.3 libcap-2.24/doc/cap_get_pid.30000664000076400007640000000003012253502644015312 0ustar andrewandrew.so man3/cap_get_proc.3 libcap-2.24/doc/capgetp.30000664000076400007640000000003012253502644014477 0ustar andrewandrew.so man3/cap_get_proc.3 libcap-2.24/doc/cap_get_flag.30000664000076400007640000000002512253502644015453 0ustar andrewandrew.so man3/cap_clear.3 libcap-2.24/doc/libcap.30000664000076400007640000000624012253502644014317 0ustar andrewandrew.TH LIBCAP 3 "2008-07-29" "" "Linux Programmer's Manual" .SH NAME cap_clear, cap_clear_flag, cap_compare, cap_copy_ext, cap_copy_int, \ cap_free, cap_from_name, cap_from_text, cap_get_fd, cap_get_file, \ cap_get_flag, cap_get_pid, cap_get_proc, cap_set_fd, cap_set_file, \ cap_set_flag, cap_set_proc, cap_size, cap_to_name, cap_to_text, \ cap_get_pid, cap_dup \- capability data object manipulation .SH SYNOPSIS .nf .B #include .sp .BI "int cap_clear(cap_t " cap_p ); .sp .BI "int cap_clear_flag(cap_t " cap_p ", cap_flag_t " flag ");" .sp .BI "int cap_compare(cap_t " cap_a ", cap_t " cap_b ");" .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 ); .sp .BI "int cap_free(void *" obj_d ); .sp .BI "int cap_from_name(const char *" name ", cap_value_t *" cap_p ); .sp .BI "cap_t cap_from_text(const char *" buf_p ); .sp .BI "cap_t cap_get_fd(int " fd ); .sp .BI "cap_t cap_get_file(const char *" path_p ); .sp .BI "int cap_get_flag(cap_t " cap_p ", cap_value_t " cap , .BI " cap_flag_t " flag ", cap_flag_value_t *" value_p ");" .sp .B #include .BI "cap_t cap_get_pid(pid_t " pid ); .sp .B "cap_t cap_get_proc(void);" .sp .BI "int cap_set_fd(int " fd ", cap_t " caps ); .sp .BI "int cap_set_file(const char *" path_p ", cap_t " cap_p ); .sp .sp .BI "int cap_set_flag(cap_t " cap_p ", cap_flag_t " flag ", int " ncap , .BI " const cap_value_t *" caps ", cap_flag_value_t " value ");" .BI "int cap_set_proc(cap_t " cap_p ); .sp .BI "ssize_t cap_size(cap_t " cap_p ); .sp .BI "char *cap_to_name(cap_value_t " cap ); .sp .BI "char *cap_to_text(cap_t " caps ", ssize_t *" length_p ); .sp .BI "cap_t cap_get_pid(pid_t " pid ); .sp .BI "cap_t cap_dup(cap_t " cap_p ); .sp Link with \fI-lcap\fP. .fi .SH DESCRIPTION These functions work on a capability state held in working storage. A .I cap_t holds information about the capabilities in each of the three sets, Permitted, Inheritable, and Effective. Each capability in a set may be clear (disabled, 0) or set (enabled, 1). .PP These functions work with the following data types: .TP 18 .I cap_value_t identifies a capability, such as .BR CAP_CHOWN . .TP .I cap_flag_t identifies one of the three flags associated with a capability (i.e., it identifies one of the three capability sets). Valid values for this type are .BR CAP_EFFECTIVE , .B CAP_INHERITABLE or .BR CAP_PERMITTED . .TP .I cap_flag_value_t identifies the setting of a particular capability flag (i.e, the value of a capability in a set). Valid values for this type are .BR CAP_CLEAR (0) or .BR CAP_SET (1). .SH "RETURN VALUE" The return value is generally specific to the individual function called. On failure, .I errno is set appropriately. .SH "CONFORMING TO" These functions are as per the withdrawn POSIX.1e draft specification. The following functions are Linux extensions: .BR cap_clear_flag (), .BR cap_compare (), .BR cap_from_name (), .BR cap_to_name (), and .BR cap_compare (). .SH "SEE ALSO" .BR cap_clear (3), .BR cap_copy_ext (3), .BR cap_from_text (3), .BR cap_get_file (3), .BR cap_get_proc (3), .BR cap_init (3), .BR capabilities (7), .BR getpid (2) .BR capsh (1) libcap-2.24/doc/cap_free.30000664000076400007640000000002412253502644014623 0ustar andrewandrew.so man3/cap_init.3 libcap-2.24/doc/cap_compare.30000664000076400007640000000002512253502644015331 0ustar andrewandrew.so man3/cap_clear.3 libcap-2.24/doc/capability.notes0000664000076400007640000000472712253502644016204 0ustar andrewandrewOverview -------- As of Linux 2.2.0, the power of the superuser has been partitioned into a set of discrete capabilities (in other places, these capabilities are know as privileges). The contents of the libcap package are a library and a number of simple programs that are intended to show how an application/daemon can be protected (with wrappers) or rewritten to take advantage of this fine grained approach to constraining the danger to your system from programs running as 'root'. Notes on securing your system ----------------------------- Adopting a role approach to system security: changing all of the system binaries and directories to be owned by some user that cannot log on. You might like to create a user with the name 'system' who's account is locked with a '*' password. This user can be made the owner of all of the system directories on your system and critical system binaries too. Why is this a good idea? In a simple case, the CAP_FUSER capabilty is required for the superuser to delete files owned by a non-root user in a 'sticky-bit' protected non-root owned directory. Thus, the sticky bit can help you protect the /lib/ directory from an compromized daemon where the directory and the files it contains are owned by the system user. It can be protected by using a wrapper like execcap to ensure that the daemon is not running with the CAP_FUSER capability... Limiting the damage: If your daemon only needs to be setuid-root in order to bind to a low numbered port. You should restrict it to only having access to the CAP_NET_BIND_SERVICE capability. Coupled with not having any files on the system owned by root, it becomes significantly harder for such a daemon to damage your system. Note, you should think of this kind of trick as making things harder for a potential attacker to exploit a hole in a daemon of this type. Being able to bind to any privileged port is still a formidable privilege and can lead to difficult but 'interesting' man in the middle attacks -- hijack the telnet port for example and masquerade as the login program... Collecting passwords for another day. The /proc/ filesystem: This Linux-specific directory tree holds most of the state of the system in a form that can sometimes be manipulated by file read/writes. Take care to ensure that the filesystem is not mounted with uid=0, since root (with no capabilities) would still be able to read sensitive files in the /proc/ tree - kcore for example. [Patch is available for 2.2.1 - I just wrote it!] libcap-2.24/doc/cap_get_fd.30000664000076400007640000000003012253502644015127 0ustar andrewandrew.so man3/cap_get_file.3 libcap-2.24/doc/cap_clear.30000664000076400007640000000646612253502644015010 0ustar andrewandrew.TH CAP_CLEAR 3 "2008-05-11" "" "Linux Programmer's Manual" .SH NAME cap_clear, cap_clear_flag, cap_get_flag, cap_set_flag, cap_compare \- capability data object manipulation .SH SYNOPSIS .nf .B #include .sp .BI "int cap_clear(cap_t " cap_p ); .sp .BI "int cap_clear_flag(cap_t " cap_p ", cap_flag_t " flag ");" .sp .BI "int cap_get_flag(cap_t " cap_p ", cap_value_t " cap , .BI " 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 , .BI " const cap_value_t *" caps \ ", cap_flag_value_t " value ");" .sp .BI "int cap_compare(cap_t " cap_a ", cap_t " cap_b ");" .sp Link with \fI-lcap\fP. .fi .SH DESCRIPTION These functions work on a capability state held in working storage. A .I cap_t holds information about the capabilities in each of the three sets, Permitted, Inheritable, and Effective. Each capability in a set may be clear (disabled, 0) or set (enabled, 1). .PP These functions work with the following data types: .TP 18 .I cap_value_t identifies a capability, such as .BR CAP_CHOWN . .TP .I cap_flag_t identifies one of the three flags associated with a capability (i.e., it identifies one of the three capability sets). Valid values for this type are .BR CAP_EFFECTIVE , .B CAP_INHERITABLE or .BR CAP_PERMITTED . .TP .I cap_flag_value_t identifies the setting of a particular capability flag (i.e, the value of a capability in a set). Valid values for this type are .B CAP_CLEAR (0) or .B CAP_SET (1). .PP .BR cap_clear () initializes the capability state in working storage identified by .I cap_p so that all capability flags are cleared. .PP .BR cap_clear_flag () clears all of the capabilities of the specified capability flag, .IR flag . .PP .BR 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 .BR 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 .BR cap_compare () compares two full capability sets and, in the spirit of .BR memcmp (), returns zero if the two capability sets are identical. A positive return value, .BR status , indicates there is a difference between them. The returned value carries further information about which of three sets, .I cap_flag_t .BR flag , differ. Specifically, the macro .B CAP_DIFFERS .RI ( status ", " flag ) evaluates to non-zero if the returned status differs in its .I flag components. .SH "RETURN VALUE" .BR cap_clear (), .BR cap_clear_flag (), .BR cap_get_flag () .BR cap_set_flag () and .BR cap_compare () return zero on success, and \-1 on failure. Other return values for .BR cap_compare () are described above. .PP On failure, .I errno is set to .BR EINVAL , indicating that one of the arguments is invalid. .SH "CONFORMING TO" These functions are as per the withdrawn POSIX.1e draft specification. .BR cap_clear_flag () and .BR cap_compare () are Linux extensions. .SH "SEE ALSO" .BR libcap (3), .BR cap_copy_ext (3), .BR cap_from_text (3), .BR cap_get_file (3), .BR cap_get_proc (3), .BR cap_init (3), .BR capabilities (7) libcap-2.24/doc/cap_set_fd.30000664000076400007640000000003012253502644015143 0ustar andrewandrew.so man3/cap_get_file.3 libcap-2.24/doc/cap_clear_flag.30000664000076400007640000000002512253502644015762 0ustar andrewandrew.so man3/cap_clear.3 libcap-2.24/doc/cap_to_name.30000664000076400007640000000003112253502644015322 0ustar andrewandrew.so man3/cap_from_text.3 libcap-2.24/doc/Makefile0000664000076400007640000000204712253502644014442 0ustar andrewandrew# # Makefile for libcap documentation # topdir=$(shell pwd)/.. include $(topdir)/Make.Rules MAN1S = capsh.1 MAN3S = cap_init.3 cap_free.3 cap_dup.3 \ cap_clear.3 cap_clear_flag.3 cap_get_flag.3 cap_set_flag.3 \ cap_compare.3 cap_get_proc.3 cap_get_pid.3 cap_set_proc.3 \ cap_get_file.3 cap_get_fd.3 cap_set_file.3 cap_set_fd.3 \ cap_copy_ext.3 cap_size.3 cap_copy_int.3 \ cap_from_text.3 cap_to_text.3 cap_from_name.3 cap_to_name.3 \ capsetp.3 capgetp.3 libcap.3 \ cap_get_bound.3 cap_drop_bound.3 MAN8S = getcap.8 setcap.8 MANS = $(MAN1S) $(MAN3S) $(MAN8S) all: $(MANS) .PHONY: html html: mkdir -p html for man in $(MANS) ; \ do \ egrep '^\.so man' $$man > /dev/null || \ groff -man -Thtml $$man > html/$$man.html ; \ done install: mkdir -p -m 755 $(MANDIR)/man1 $(MANDIR)/man3 $(MANDIR)/man8 for man in \ $(MANDIR)/man1 $(MAN1S) \ $(MANDIR)/man3 $(MAN3S) \ $(MANDIR)/man8 $(MAN8S) \ ; \ do \ case $$man in \ /*) sub=$$man ; continue ;; \ esac; \ install -m 644 $$man $$sub ; \ done clean: $(LOCALCLEAN) rm -rf html libcap-2.24/doc/cap_from_name.30000664000076400007640000000003112253502644015643 0ustar andrewandrew.so man3/cap_from_text.3 libcap-2.24/doc/cap_set_file.30000664000076400007640000000003012253502644015471 0ustar andrewandrew.so man3/cap_get_file.3 libcap-2.24/doc/cap_dup.30000664000076400007640000000002412253502644014472 0ustar andrewandrew.so man3/cap_init.3 libcap-2.24/doc/cap_set_proc.30000664000076400007640000000003012253502644015515 0ustar andrewandrew.so man3/cap_get_proc.3 libcap-2.24/doc/cap_copy_ext.30000664000076400007640000000671612253502644015552 0ustar andrewandrew.TH CAP_COPY_EXT 3 "2008-05-11" "" "Linux Programmer's Manual" .SH NAME cap_copy_ext, cap_size, cap_copy_int \- capability state external representation translation .SH SYNOPSIS .B #include .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 ); .sp Link with \fI-lcap\fP. .SH DESCRIPTION These functions translate between internal and external representations of a capability state. 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 .BR 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 .BR cap_copy_ext () function in order to hold the capability data record created from .IR cap_p . .PP .BR 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 .BR 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 .BR cap_size () function. .PP .BR 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 pointed 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 (see .BR cap_clear (3)). Note that the record pointed to by .I ext_p must have been obtained from a previous, successful call to .BR 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 .BR cap_free () with the .I cap_t as an argument. .SH "RETURN VALUE" .BR cap_size () returns the length required to hold a capability data record on success, and -1 on failure. .PP .BR 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 .BR 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 is set to .BR EINVAL , .BR ENOMEM , or .BR ERANGE . .SH "CONFORMING TO" These functions are specified in the withdrawn POSIX.1e draft specification. .SH "SEE ALSO" .BR libcap (3), .BR cap_clear (3), .BR cap_from_text (3), .BR cap_get_file (3), .BR cap_get_proc (3), .BR cap_init (3), .BR capabilities (7) libcap-2.24/doc/cap_copy_int.30000664000076400007640000000003012253502644015523 0ustar andrewandrew.so man3/cap_copy_ext.3 libcap-2.24/doc/cap_from_text.30000664000076400007640000001620212253502644015716 0ustar andrewandrew.\" .\" written by Andrew Main .\" .TH CAP_FROM_TEXT 3 "2008-05-10" "" "Linux Programmer's Manual" .SH NAME cap_from_text, cap_to_text, cap_to_name, cap_from_name \- capability state textual representation translation .SH SYNOPSIS .B #include .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 .BI "int cap_from_name(const char *" name ", cap_value_t *" cap_p ); .sp .BI "char *cap_to_name(cap_value_t " cap ); .sp Link with \fI-lcap\fP. .SH DESCRIPTION These functions translate a capability state between an internal representation and 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 .BR 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 a human-readable, nul-terminated character string pointed to by .IR buf_p . It returns a pointer to the newly created capability state. When the capability state in working storage is no longer required, the caller should free any releasable memory by calling .BR 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 .BR cap_to_text () converts the capability state in working storage identified by .I cap_p into a nul-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 NULL, the function shall also return the full length of the string (not including the nul 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. When the capability state in working storage is no longer required, the caller should free any releasable memory by calling .BR cap_free () with the returned string pointer as an argument. .PP .BR cap_from_name () converts a text representation of a capability, such as "cap_chown", to its numerical representation .RB ( CAP_CHOWN=0 ), writing the decoded value into .IR *cap_p . If .I cap_p is NULL no result is written, but the return code of the function indicates whether or not the specified capability can be represented by the library. .PP .BR cap_to_name () converts a capability index value, .IR cap , to a libcap-allocated textual string. This string should be deallocated with .BR cap_free (). .SH "TEXTUAL REPRESENTATION" A textual representation of capability sets consists of one or more whitespace-separated .IR clauses . Each clause specifies some operations on 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 Unnamed capabilities can also be specified by number. This feature ensures that libcap can support capabilities that were not allocated at the time libcap was compiled. However, generally upgrading libcap will add names for recently allocated capabilities. .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,=". .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" .BR cap_from_text (), .BR cap_to_text () and .BR cap_to_name () return a non-NULL value on success, and NULL on failure. .BR cap_from_name () returns 0 for success, and -1 on failure (unknown capability). .PP On failure, .I errno is set to .BR EINVAL , or .BR ENOMEM . .SH "CONFORMING TO" .BR cap_from_text () and .BR cap_to_text () are specified by the withdrawn POSIX.1e draft specification. .BR cap_from_name () and .BR cap_to_name () are Linux extensions. .SH EXAMPLE The example program below demonstrates the use of .BR cap_from_text () and .BR cap_to_text (). The following shell session shows a some example runs: .in +4n .nf $ ./a.out "cap_chown=p cap_chown+e" caps_to_text() returned "= cap_chown+ep" $ ./a.out "all=pe cap_chown-e cap_kill-pe" caps_to_text() returned "=ep cap_chown-e cap_kill-ep" .fi .in The source code of the program is as follows: .nf #include #include #include #define handle_error(msg) \\ do { perror(msg); exit(EXIT_FAILURE); } while (0) int main(int argc, char *argv[]) { cap_t caps; char *txt_caps; if (argc != 2) { fprintf(stderr, "%s \\n", argv[0]); exit(EXIT_FAILURE); } caps = cap_from_text(argv[1]); if (caps == NULL) handle_error("cap_from_text"); txt_caps = cap_to_text(caps, NULL); if (txt_caps == NULL) handle_error("cap_to_text"); printf("caps_to_text() returned \\"%s\\"\\n", txt_caps); if (cap_free(txt_caps) != 0 || cap_free(caps) != 0) handle_error("cap_free"); exit(EXIT_SUCCESS); } .fi .SH "SEE ALSO" .BR libcap (3), .BR cap_clear (3), .BR cap_compare (3), .BR cap_copy_ext (3), .BR cap_get_file (3), .BR cap_get_proc (3), .BR cap_init (3), .BR capabilities (7) libcap-2.24/doc/getcap.80000664000076400007640000000115512253502644014335 0ustar andrewandrew.\" .\" $Id: getcap.8,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $ .\" written by Andrew Main .\" .TH GETCAP 8 "12 Nov 2007" .SH NAME getcap \- examine file capabilities .SH SYNOPSIS \fBgetcap\fP [-v] [-r] [-h] \fIfilename\fP [ ... ] .SH DESCRIPTION .B getcap displays the name and capabilities of each specified .SH OPTIONS .TP 4 .B -r enables recursive search. .TP 4 .B -v enables to display all searched entries, even if it has no file-capabilities. .TP 4 .B -h prints quick usage. .TP 4 .IR filename One file per line. .SH "SEE ALSO" .BR cap_get_file (3), .BR cap_to_text (3), .BR setcap (8) libcap-2.24/doc/cap_get_bound.30000664000076400007640000000003012253502644015645 0ustar andrewandrew.so man3/cap_get_proc.3 libcap-2.24/doc/old/0000775000076400007640000000000012253502644013555 5ustar andrewandrewlibcap-2.24/doc/old/_getproccap.20000664000076400007640000000002712253502644016125 0ustar andrewandrew.so man2/_setproccap.2 libcap-2.24/doc/old/README0000664000076400007640000000005512253502644014435 0ustar andrewandrewthese files are not relevant to this release libcap-2.24/doc/old/_fsetfilecap.20000664000076400007640000000002712253502644016263 0ustar andrewandrew.so man2/_setfilecap.2 libcap-2.24/doc/old/_getfilecap.20000664000076400007640000000002712253502644016101 0ustar andrewandrew.so man2/_setfilecap.2 libcap-2.24/doc/old/_fgetfilecap.20000664000076400007640000000002712253502644016247 0ustar andrewandrew.so man2/_setfilecap.2 libcap-2.24/doc/old/_setproccap.20000664000076400007640000000320012253502644016135 0ustar andrewandrew.\" .\" $Id: _setproccap.2,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $ .\" written by Andrew Main .\" .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 .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). libcap-2.24/doc/old/_setfilecap.20000664000076400007640000000644712253502644016131 0ustar andrewandrew.\" .\" $Id: _setfilecap.2,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $ .\" written by Andrew Main .\" .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 .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). libcap-2.24/doc/cap_to_text.30000664000076400007640000000003112253502644015366 0ustar andrewandrew.so man3/cap_from_text.3 libcap-2.24/doc/cap_get_file.30000664000076400007640000000646512253502644015477 0ustar andrewandrew.\" .\" written by Andrew Main .\" .TH CAP_GET_FILE 3 "2008-05-11" "" "Linux Programmer's Manual" .SH NAME cap_get_file, cap_set_file, cap_get_fd, cap_set_fd \- capability manipulation on files .SH SYNOPSIS .B .sp .B #include .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 ); .sp Link with \fI-lcap\fP. .SH DESCRIPTION .BR cap_get_file () and .BR 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 .BR cap_free () with the used .I cap_t as an argument. .PP .BR cap_set_file () and .BR 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 is completely determined by the contents of .IR cap_p . A NULL value for .IR cap_p is used to indicate that capabilities for the file should be deleted. For these functions to succeed, the calling process must have the effective capability, .BR CAP_SETFCAP , enabled and either the effective user ID of the process must match the file owner or the calling process must have the .B CAP_FOWNER flag in its effective capability set. The effects of writing the capability state to any file type other than a regular file are undefined. .SH "RETURN VALUE" .BR cap_get_file () and .BR cap_get_fd () return a non-NULL value on success, and NULL on failure. .PP .BR cap_set_file () and .BR cap_set_fd () return zero on success, and \-1 on failure. .PP On failure, .I errno 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 withdrawn POSIX.1e draft specification. .SH NOTES Support for file capabilities is provided on Linux since version 2.6.24. On Linux, the file Effective set is a single bit. If it is enabled, then all Permitted capabilities are enabled in the Effective set of the calling process when the file is executed; otherwise, no capabilities are enabled in the process's Effective set following an .BR execve (2). Because the file Effective set is a single bit, if any capability is enabled in the Effective set of the .I cap_t given to .BR cap_set_file () or .BR cap_set_fd (), then all capabilities whose Permitted or Inheritable flag is enabled must also have the Effective flag enabled. Conversely, if the Effective bit is enabled on a file, then the .I cap_t returned by .BR cap_get_file() and .BR cap_get_fd() will have the Effective flag enabled for each capability that has the Permitted or Inheritable flag enabled. .SH "SEE ALSO" .BR libcap (3), .BR cap_clear (3), .BR cap_copy_ext (3), .BR cap_from_text (3), .BR cap_get_proc (3), .BR cap_init (3), .BR capabilities (7) libcap-2.24/doc/setcap.80000664000076400007640000000217612253502644014355 0ustar andrewandrew.\" .\" $Id: setcap.8,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $ .\" .TH SETCAP 8 "24th October 2008" .SH NAME setcap \- set file capabilities .SH SYNOPSIS \fBsetcap\fP [-q] [-v] (\fIcapabilities|-|-r) filename\fP [ ... \fIcapabilitiesN\fP \fIfileN\fP ] .SH DESCRIPTION In the absence of the .B -v (verify) option .B setcap sets the capabilities of each specified .I filename to the .I capabilities specified. The .B -v option is used to verify that the specified capabilities are currently associated with the file. .PP The .I capabilities are specified in the form described in .IR cap_from_text (3). .PP The special capability string, .BR '-' , 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. .PP The special capability string, .BR '-r' , is used to remove a capability set from a file. .PP The .B -q flag is used to make the program less verbose in its output. .SH "EXIT CODE" The .B setcap program will exit with a 0 exit code if successful. On failure, the exit code is 1. .SH "SEE ALSO" .BR cap_from_text (3), .BR cap_set_file (3), .BR getcap (8) libcap-2.24/doc/cap_drop_bound.30000664000076400007640000000003012253502644016032 0ustar andrewandrew.so man3/cap_get_proc.3 libcap-2.24/doc/capsetp.30000664000076400007640000000003012253502644014513 0ustar andrewandrew.so man3/cap_get_proc.3 libcap-2.24/doc/cap_set_flag.30000664000076400007640000000002512253502644015467 0ustar andrewandrew.so man3/cap_clear.3 libcap-2.24/libcap/0000775000076400007640000000000012262403350013456 5ustar andrewandrewlibcap-2.24/libcap/libcap.pc.in0000664000076400007640000000031412256337645015657 0ustar andrewandrewprefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libcap Description: libcap Version: @VERSION@ Libs: -L${libdir} -lcap Libs.private: @deps@ Cflags: -I${includedir} libcap-2.24/libcap/cap_file.c0000664000076400007640000001540112256342721015374 0ustar andrewandrew/* * Copyright (c) 1997,2007 Andrew G Morgan * * This file deals with setting capabilities on files. */ #include #include #include #include #include #define XATTR_SECURITY_PREFIX "security." #include "libcap.h" #ifdef VFS_CAP_U32 #if VFS_CAP_U32 != __CAP_BLKS # error VFS representation of capabilities is not the same size as kernel #endif #if __BYTE_ORDER == __BIG_ENDIAN #define FIXUP_32BITS(x) bswap_32(x) #else #define FIXUP_32BITS(x) (x) #endif static cap_t _fcaps_load(struct vfs_cap_data *rawvfscap, cap_t result, int bytes) { __u32 magic_etc; unsigned tocopy, i; magic_etc = FIXUP_32BITS(rawvfscap->magic_etc); switch (magic_etc & VFS_CAP_REVISION_MASK) { #ifdef VFS_CAP_REVISION_1 case VFS_CAP_REVISION_1: tocopy = VFS_CAP_U32_1; bytes -= XATTR_CAPS_SZ_1; break; #endif #ifdef VFS_CAP_REVISION_2 case VFS_CAP_REVISION_2: tocopy = VFS_CAP_U32_2; bytes -= XATTR_CAPS_SZ_2; break; #endif default: cap_free(result); result = NULL; return result; } /* * Verify that we loaded exactly the right number of bytes */ if (bytes != 0) { cap_free(result); result = NULL; return result; } for (i=0; i < tocopy; i++) { result->u[i].flat[CAP_INHERITABLE] = FIXUP_32BITS(rawvfscap->data[i].inheritable); result->u[i].flat[CAP_PERMITTED] = FIXUP_32BITS(rawvfscap->data[i].permitted); if (magic_etc & VFS_CAP_FLAGS_EFFECTIVE) { result->u[i].flat[CAP_EFFECTIVE] = result->u[i].flat[CAP_INHERITABLE] | result->u[i].flat[CAP_PERMITTED]; } } while (i < __CAP_BLKS) { result->u[i].flat[CAP_INHERITABLE] = result->u[i].flat[CAP_PERMITTED] = result->u[i].flat[CAP_EFFECTIVE] = 0; i++; } return result; } static int _fcaps_save(struct vfs_cap_data *rawvfscap, cap_t cap_d, int *bytes_p) { __u32 eff_not_zero, magic; unsigned tocopy, i; if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } switch (cap_d->head.version) { #ifdef _LINUX_CAPABILITY_VERSION_1 case _LINUX_CAPABILITY_VERSION_1: magic = VFS_CAP_REVISION_1; tocopy = VFS_CAP_U32_1; *bytes_p = XATTR_CAPS_SZ_1; break; #endif #ifdef _LINUX_CAPABILITY_VERSION_2 case _LINUX_CAPABILITY_VERSION_2: magic = VFS_CAP_REVISION_2; tocopy = VFS_CAP_U32_2; *bytes_p = XATTR_CAPS_SZ_2; break; #endif #ifdef _LINUX_CAPABILITY_VERSION_3 case _LINUX_CAPABILITY_VERSION_3: magic = VFS_CAP_REVISION_2; tocopy = VFS_CAP_U32_2; *bytes_p = XATTR_CAPS_SZ_2; break; #endif default: errno = EINVAL; return -1; } _cap_debug("setting named file capabilities"); for (eff_not_zero = 0, i = 0; i < tocopy; i++) { eff_not_zero |= cap_d->u[i].flat[CAP_EFFECTIVE]; } while (i < __CAP_BLKS) { if ((cap_d->u[i].flat[CAP_EFFECTIVE] || cap_d->u[i].flat[CAP_INHERITABLE] || cap_d->u[i].flat[CAP_PERMITTED])) { /* * System does not support these capabilities */ errno = EINVAL; return -1; } i++; } for (i=0; i < tocopy; i++) { rawvfscap->data[i].permitted = FIXUP_32BITS(cap_d->u[i].flat[CAP_PERMITTED]); rawvfscap->data[i].inheritable = FIXUP_32BITS(cap_d->u[i].flat[CAP_INHERITABLE]); if (eff_not_zero && ((~(cap_d->u[i].flat[CAP_EFFECTIVE])) & (cap_d->u[i].flat[CAP_PERMITTED] | cap_d->u[i].flat[CAP_INHERITABLE]))) { errno = EINVAL; return -1; } } if (eff_not_zero == 0) { rawvfscap->magic_etc = FIXUP_32BITS(magic); } else { rawvfscap->magic_etc = FIXUP_32BITS(magic|VFS_CAP_FLAGS_EFFECTIVE); } return 0; /* success */ } /* * 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) { struct vfs_cap_data rawvfscap; int sizeofcaps; _cap_debug("getting fildes capabilities"); /* fill the capability sets via a system call */ sizeofcaps = fgetxattr(fildes, XATTR_NAME_CAPS, &rawvfscap, sizeof(rawvfscap)); if (sizeofcaps < ssizeof(rawvfscap.magic_etc)) { cap_free(result); result = NULL; } else { result = _fcaps_load(&rawvfscap, result, sizeofcaps); } } return result; } /* * Get the capabilities from a named file. */ cap_t cap_get_file(const char *filename) { cap_t result; /* allocate a new capability set */ result = cap_init(); if (result) { struct vfs_cap_data rawvfscap; int sizeofcaps; _cap_debug("getting filename capabilities"); /* fill the capability sets via a system call */ sizeofcaps = getxattr(filename, XATTR_NAME_CAPS, &rawvfscap, sizeof(rawvfscap)); if (sizeofcaps < ssizeof(rawvfscap.magic_etc)) { cap_free(result); result = NULL; } else { result = _fcaps_load(&rawvfscap, result, sizeofcaps); } } 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) { struct vfs_cap_data rawvfscap; int sizeofcaps; struct stat buf; if (fstat(fildes, &buf) != 0) { _cap_debug("unable to stat file descriptor %d", fildes); return -1; } if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) { _cap_debug("file descriptor %d for non-regular file", fildes); errno = EINVAL; return -1; } if (cap_d == NULL) { _cap_debug("deleting fildes capabilities"); return fremovexattr(fildes, XATTR_NAME_CAPS); } else if (_fcaps_save(&rawvfscap, cap_d, &sizeofcaps) != 0) { return -1; } _cap_debug("setting fildes capabilities"); return fsetxattr(fildes, XATTR_NAME_CAPS, &rawvfscap, sizeofcaps, 0); } /* * Set the capabilities of a named file. */ int cap_set_file(const char *filename, cap_t cap_d) { struct vfs_cap_data rawvfscap; int sizeofcaps; struct stat buf; if (lstat(filename, &buf) != 0) { _cap_debug("unable to stat file [%s]", filename); return -1; } if (S_ISLNK(buf.st_mode) || !S_ISREG(buf.st_mode)) { _cap_debug("file [%s] is not a regular file", filename); errno = EINVAL; return -1; } if (cap_d == NULL) { _cap_debug("removing filename capabilities"); return removexattr(filename, XATTR_NAME_CAPS); } else if (_fcaps_save(&rawvfscap, cap_d, &sizeofcaps) != 0) { return -1; } _cap_debug("setting filename capabilities"); return setxattr(filename, XATTR_NAME_CAPS, &rawvfscap, sizeofcaps, 0); } #else /* ie. ndef VFS_CAP_U32 */ cap_t cap_get_fd(int fildes) { errno = EINVAL; return NULL; } cap_t cap_get_file(const char *filename) { errno = EINVAL; return NULL; } int cap_set_fd(int fildes, cap_t cap_d) { errno = EINVAL; return -1; } int cap_set_file(const char *filename, cap_t cap_d) { errno = EINVAL; return -1; } #endif /* def VFS_CAP_U32 */ libcap-2.24/libcap/libcap.h0000664000076400007640000001340112256345537015077 0ustar andrewandrew/* * Copyright (c) 1997 Andrew G Morgan * * This file contains internal definitions for the various functions in * this small capability library. */ #ifndef LIBCAP_H #define LIBCAP_H #include #include #include #include #include #include #ifndef __u8 #define __u8 uint8_t #endif /* __8 */ #ifndef __u32 #define __u32 uint32_t #endif /* __u32 */ /* include the names for the caps and a definition of __CAP_BITS */ #include "cap_names.h" #ifndef _LINUX_CAPABILITY_U32S_1 # define _LINUX_CAPABILITY_U32S_1 1 #endif /* ndef _LINUX_CAPABILITY_U32S */ /* * Do we match the local kernel? */ #if !defined(_LINUX_CAPABILITY_VERSION) # error Kernel does not support library # error file "libcap.h" --> fix and recompile libcap #elif !defined(_LINUX_CAPABILITY_VERSION_2) # warning Kernel does not support 64-bit capabilities # warning and libcap is being built with no support for 64-bit capabilities # ifndef _LINUX_CAPABILITY_VERSION_1 # define _LINUX_CAPABILITY_VERSION_1 0x19980330 # endif # _LIBCAP_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1 # _LIBCAP_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1 #elif defined(_LINUX_CAPABILITY_VERSION_3) # if (_LINUX_CAPABILITY_VERSION_3 != 0x20080522) # error Kernel v3 does not match library # error file "libcap.h" --> fix and recompile libcap # else # define _LIBCAP_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_3 # define _LIBCAP_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_3 # endif #elif (_LINUX_CAPABILITY_VERSION_2 != 0x20071026) # error Kernel does not match library # error file "libcap.h" --> fix and recompile libcap #else # define _LIBCAP_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_2 # define _LIBCAP_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_2 #endif #undef _LINUX_CAPABILITY_VERSION #undef _LINUX_CAPABILITY_U32S /* * 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. */ #if defined(VFS_CAP_REVISION_MASK) && !defined(VFS_CAP_U32) # define VFS_CAP_U32_1 1 # define XATTR_CAPS_SZ_1 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_1)) # define VFS_CAP_U32 VFS_CAP_U32_1 struct _cap_vfs_cap_data { __le32 magic_etc; struct { __le32 permitted; __le32 inheritable; } data[VFS_CAP_U32_1]; }; # define vfs_cap_data _cap_vfs_cap_data #endif #ifndef CAP_TO_INDEX # define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */ #endif /* ndef CAP_TO_INDEX */ #ifndef CAP_TO_MASK # define CAP_TO_MASK(x) (1 << ((x) & 31)) #endif /* ndef CAP_TO_MASK */ #define NUMBER_OF_CAP_SETS 3 /* effective, inheritable, permitted */ #define __CAP_BLKS (_LIBCAP_CAPABILITY_U32S) #define CAP_SET_SIZE (__CAP_BLKS * sizeof(__u32)) #define CAP_T_MAGIC 0xCA90D0 struct _cap_struct { struct __user_cap_header_struct head; union { struct __user_cap_data_struct set; __u32 flat[NUMBER_OF_CAP_SETS]; } u[_LIBCAP_CAPABILITY_U32S]; }; /* the maximum bits supportable */ #define __CAP_MAXBITS (__CAP_BLKS * 32) /* string magic for cap_free */ #define CAP_S_MAGIC 0xCA95D0 /* * kernel API cap set abstraction */ #define raise_cap(x,set) u[(x)>>5].flat[set] |= (1<<((x)&31)) #define lower_cap(x,set) u[(x)>>5].flat[set] &= ~(1<<((x)&31)) #define isset_cap(y,x,set) ((y)->u[(x)>>5].flat[set] & (1<<((x)&31))) /* * Private definitions for internal use by the library. */ #define __libcap_check_magic(c,magic) ((c) && *(-1+(__u32 *)(c)) == (magic)) #define good_cap_t(c) __libcap_check_magic(c, CAP_T_MAGIC) #define good_cap_string(c) __libcap_check_magic(c, CAP_S_MAGIC) /* * These match CAP_DIFFERS() expectations */ #define LIBCAP_EFF (1 << CAP_EFFECTIVE) #define LIBCAP_INH (1 << CAP_INHERITABLE) #define LIBCAP_PER (1 << CAP_PERMITTED) /* * library debugging */ #ifdef DEBUG #include # define _cap_debug(f, x...) do { \ fprintf(stderr, "%s(%s:%d): ", __FUNCTION__, __FILE__, __LINE__); \ fprintf(stderr, f, ## x); \ fprintf(stderr, "\n"); \ } while (0) # define _cap_debugcap(s, c, set) do { \ unsigned _cap_index; \ fprintf(stderr, "%s(%s:%d): %s", __FUNCTION__, __FILE__, __LINE__, s); \ for (_cap_index=_LIBCAP_CAPABILITY_U32S; _cap_index-- > 0; ) { \ fprintf(stderr, "%08x", (c).u[_cap_index].flat[set]); \ } \ fprintf(stderr, "\n"); \ } while (0) #else /* !DEBUG */ # define _cap_debug(f, x...) # define _cap_debugcap(s, c, set) #endif /* DEBUG */ extern char *_libcap_strdup(const char *text); /* * These are semi-public prototypes, they will only be defined in * 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); /* prctl based API for altering character of current process */ #define PR_GET_KEEPCAPS 7 #define PR_SET_KEEPCAPS 8 #define PR_CAPBSET_READ 23 #define PR_CAPBSET_DROP 24 #define PR_GET_SECUREBITS 27 #define PR_SET_SECUREBITS 28 /* * The library compares sizeof() with integer return values. To avoid * signed/unsigned comparisons, leading to unfortunate * misinterpretations of -1, we provide a convenient cast-to-signed-integer * version of sizeof(). */ #define ssizeof(x) ((ssize_t) sizeof(x)) #endif /* LIBCAP_H */ libcap-2.24/libcap/_makenames.c0000664000076400007640000000245212253502644015733 0ustar andrewandrew/* * Copyright (c) 1997-8 Andrew G. Morgan * * This is a file to make the capability <-> string mappings for * libcap. */ #include #include #include /* * #include 'sed' generated array */ struct { const char *name; int index; } const list[] = { #include "cap_names.list.h" {NULL, -1} }; /* 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 + 1; } pointers[list[i].index] = list[i].name; } printf("/*\n" " * DO NOT EDIT: this file is generated automatically from\n" " *\n" " * \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 * * This file deals with getting and setting capabilities on processes. */ #include #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->u[0].set)) { cap_free(result); result = NULL; } } return result; } int cap_set_proc(cap_t cap_d) { int retval; if (!good_cap_t(cap_d)) { errno = EINVAL; return -1; } _cap_debug("setting process capabilities"); retval = capset(&cap_d->head, &cap_d->u[0].set); return retval; } /* 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->u[0].set); cap_d->head.pid = 0; return error; } /* allocate space for and return capabilities of target process */ cap_t cap_get_pid(pid_t pid) { cap_t result; result = cap_init(); if (result) { if (capgetp(pid, result) != 0) { int my_errno; my_errno = errno; cap_free(result); errno = my_errno; result = NULL; } } return result; } /* 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->u[0].set); cap_d->head.version = _LIBCAP_CAPABILITY_VERSION; cap_d->head.pid = 0; return error; } /* get a capability from the bounding set */ int cap_get_bound(cap_value_t cap) { int result; result = prctl(PR_CAPBSET_READ, cap); return result; } /* drop a capability from the bounding set */ int cap_drop_bound(cap_value_t cap) { int result; result = prctl(PR_CAPBSET_DROP, cap); return result; } libcap-2.24/libcap/.gitignore0000664000076400007640000000011712253502644015453 0ustar andrewandrewcap_names.h cap_names.list.h _caps_output.gperf libcap.a libcap.so* _makenames libcap-2.24/libcap/Makefile0000664000076400007640000000560012262377347015137 0ustar andrewandrew# # defines # topdir=$(shell pwd)/.. include ../Make.Rules # # Library version # LIBNAME=$(LIBTITLE).so STALIBNAME=$(LIBTITLE).a # FILES=cap_alloc cap_proc cap_extint cap_flag cap_text # make including file support something you can override (no libattr # no support). ifeq ($(LIBATTR),yes) FILES += cap_file LDFLAGS += -lattr DEPS = -lattr endif INCLS=libcap.h cap_names.h $(INCS) OBJS=$(addsuffix .o, $(FILES)) MAJLIBNAME=$(LIBNAME).$(VERSION) MINLIBNAME=$(MAJLIBNAME).$(MINOR) GPERF_OUTPUT = _caps_output.gperf all: $(MINLIBNAME) $(STALIBNAME) libcap.pc ifeq ($(shell gperf --version > /dev/null 2>&1 && echo yes),yes) USE_GPERF_OUTPUT = $(GPERF_OUTPUT) INCLUDE_GPERF_OUTPUT = -include $(GPERF_OUTPUT) endif libcap.pc: libcap.pc.in sed -e 's,@prefix@,$(prefix),' \ -e 's,@exec_prefix@,$(exec_prefix),' \ -e 's,@libdir@,$(lib_prefix)/$(lib),' \ -e 's,@includedir@,$(inc_prefix)/include,' \ -e 's,@VERSION@,$(VERSION).$(MINOR),' \ -e 's,@deps@,$(DEPS),' \ $< >$@ _makenames: _makenames.c cap_names.list.h $(BUILD_CC) $(BUILD_CFLAGS) $< -o $@ cap_names.h: _makenames ./_makenames > cap_names.h $(GPERF_OUTPUT): cap_names.list.h perl -e 'print "struct __cap_token_s { const char *name; int index; };\n%{\nconst struct __cap_token_s *__cap_lookup_name(const char *, unsigned int);\n%}\n%%\n"; while ($$l = <>) { $$l =~ s/[\{\"]//g; $$l =~ s/\}.*// ; print $$l; }' < $< | gperf --ignore-case --language=ANSI-C --readonly --null-strings --global-table --hash-function-name=__cap_hash_name --lookup-function-name="__cap_lookup_name" -c -t -m20 $(INDENT) > $@ cap_names.list.h: Makefile $(KERNEL_HEADERS)/linux/capability.h @echo "=> making $@ from $(KERNEL_HEADERS)/linux/capability.h" perl -e 'while ($$l=<>) { if ($$l =~ /^\#define[ \t](CAP[_A-Z]+)[ \t]+([0-9]+)\s+$$/) { $$tok=$$1; $$val=$$2; $$tok =~ tr/A-Z/a-z/; print "{\"$$tok\",$$val},\n"; } }' $(KERNEL_HEADERS)/linux/capability.h | fgrep -v 0x > $@ $(STALIBNAME): $(OBJS) $(AR) rcs $@ $^ $(RANLIB) $@ $(MINLIBNAME): $(OBJS) $(LD) $(CFLAGS) $(LDFLAGS) -Wl,-soname,$(MAJLIBNAME) -o $@ $^ ln -sf $(MINLIBNAME) $(MAJLIBNAME) ln -sf $(MAJLIBNAME) $(LIBNAME) %.o: %.c $(INCLS) $(CC) $(CFLAGS) $(IPATH) -c $< -o $@ cap_text.o: cap_text.c $(USE_GPERF_OUTPUT) $(INCLS) $(CC) $(CFLAGS) $(IPATH) $(INCLUDE_GPERF_OUTPUT) -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 $(STALIBNAME) $(LIBDIR)/$(STALIBNAME) install -m 0644 $(MINLIBNAME) $(LIBDIR)/$(MINLIBNAME) ln -sf $(MINLIBNAME) $(LIBDIR)/$(MAJLIBNAME) ln -sf $(MAJLIBNAME) $(LIBDIR)/$(LIBNAME) ifeq ($(FAKEROOT),) -/sbin/ldconfig endif mkdir -p -m 0755 $(PKGCONFIGDIR) install -m 0644 libcap.pc $(PKGCONFIGDIR)/libcap.pc clean: $(LOCALCLEAN) rm -f $(OBJS) $(LIBNAME)* $(STALIBNAME) libcap.pc rm -f cap_names.h cap_names.list.h _makenames $(GPERF_OUTPUT) cd include/sys && $(LOCALCLEAN) libcap-2.24/libcap/cap_extint.c0000664000076400007640000000563112256344671016002 0ustar andrewandrew/* * Copyright (c) 1997-8 Andrew G Morgan * * This file deals with exchanging internal and external * representations of capability sets. */ #include "libcap.h" /* * External representation for capabilities. (exported as a fixed * length) */ #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 ssizeof(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; int i; /* valid arguments? */ if (!good_cap_t(cap_d) || length < ssizeof(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; iu[j/sizeof(__u32)].flat[i]; 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 (ssizeof(struct cap_ext_struct)); } /* * Import an external representation to produce an internal rep. * the internal rep should be liberated with cap_free(). */ 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; /* 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; setbytes[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; cap_d->u[blk].flat[set] = val; } } /* all done */ return cap_d; } libcap-2.24/libcap/include/0000775000076400007640000000000012253502716015107 5ustar andrewandrewlibcap-2.24/libcap/include/uapi/0000775000076400007640000000000012261142606016042 5ustar andrewandrewlibcap-2.24/libcap/include/uapi/linux/0000775000076400007640000000000012262401332017174 5ustar andrewandrewlibcap-2.24/libcap/include/uapi/linux/prctl.h0000664000076400007640000001215112261142522020473 0ustar andrewandrew#ifndef _LINUX_PRCTL_H #define _LINUX_PRCTL_H /* Values to pass as first argument to prctl() */ #define PR_SET_PDEATHSIG 1 /* Second arg is a signal */ #define PR_GET_PDEATHSIG 2 /* Second arg is a ptr to return the signal */ /* Get/set current->mm->dumpable */ #define PR_GET_DUMPABLE 3 #define PR_SET_DUMPABLE 4 /* Get/set unaligned access control bits (if meaningful) */ #define PR_GET_UNALIGN 5 #define PR_SET_UNALIGN 6 # define PR_UNALIGN_NOPRINT 1 /* silently fix up unaligned user accesses */ # define PR_UNALIGN_SIGBUS 2 /* generate SIGBUS on unaligned user access */ /* Get/set whether or not to drop capabilities on setuid() away from * uid 0 (as per security/commoncap.c) */ #define PR_GET_KEEPCAPS 7 #define PR_SET_KEEPCAPS 8 /* Get/set floating-point emulation control bits (if meaningful) */ #define PR_GET_FPEMU 9 #define PR_SET_FPEMU 10 # define PR_FPEMU_NOPRINT 1 /* silently emulate fp operations accesses */ # define PR_FPEMU_SIGFPE 2 /* don't emulate fp operations, send SIGFPE instead */ /* Get/set floating-point exception mode (if meaningful) */ #define PR_GET_FPEXC 11 #define PR_SET_FPEXC 12 # define PR_FP_EXC_SW_ENABLE 0x80 /* Use FPEXC for FP exception enables */ # define PR_FP_EXC_DIV 0x010000 /* floating point divide by zero */ # define PR_FP_EXC_OVF 0x020000 /* floating point overflow */ # define PR_FP_EXC_UND 0x040000 /* floating point underflow */ # define PR_FP_EXC_RES 0x080000 /* floating point inexact result */ # define PR_FP_EXC_INV 0x100000 /* floating point invalid operation */ # define PR_FP_EXC_DISABLED 0 /* FP exceptions disabled */ # define PR_FP_EXC_NONRECOV 1 /* async non-recoverable exc. mode */ # define PR_FP_EXC_ASYNC 2 /* async recoverable exception mode */ # define PR_FP_EXC_PRECISE 3 /* precise exception mode */ /* Get/set whether we use statistical process timing or accurate timestamp * based process timing */ #define PR_GET_TIMING 13 #define PR_SET_TIMING 14 # define PR_TIMING_STATISTICAL 0 /* Normal, traditional, statistical process timing */ # define PR_TIMING_TIMESTAMP 1 /* Accurate timestamp based process timing */ #define PR_SET_NAME 15 /* Set process name */ #define PR_GET_NAME 16 /* Get process name */ /* Get/set process endian */ #define PR_GET_ENDIAN 19 #define PR_SET_ENDIAN 20 # define PR_ENDIAN_BIG 0 # define PR_ENDIAN_LITTLE 1 /* True little endian mode */ # define PR_ENDIAN_PPC_LITTLE 2 /* "PowerPC" pseudo little endian */ /* Get/set process seccomp mode */ #define PR_GET_SECCOMP 21 #define PR_SET_SECCOMP 22 /* Get/set the capability bounding set (as per security/commoncap.c) */ #define PR_CAPBSET_READ 23 #define PR_CAPBSET_DROP 24 /* Get/set the process' ability to use the timestamp counter instruction */ #define PR_GET_TSC 25 #define PR_SET_TSC 26 # define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */ # define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */ /* Get/set securebits (as per security/commoncap.c) */ #define PR_GET_SECUREBITS 27 #define PR_SET_SECUREBITS 28 /* * Get/set the timerslack as used by poll/select/nanosleep * A value of 0 means "use default" */ #define PR_SET_TIMERSLACK 29 #define PR_GET_TIMERSLACK 30 #define PR_TASK_PERF_EVENTS_DISABLE 31 #define PR_TASK_PERF_EVENTS_ENABLE 32 /* * Set early/late kill mode for hwpoison memory corruption. * This influences when the process gets killed on a memory corruption. */ #define PR_MCE_KILL 33 # define PR_MCE_KILL_CLEAR 0 # define PR_MCE_KILL_SET 1 # define PR_MCE_KILL_LATE 0 # define PR_MCE_KILL_EARLY 1 # define PR_MCE_KILL_DEFAULT 2 #define PR_MCE_KILL_GET 34 /* * Tune up process memory map specifics. */ #define PR_SET_MM 35 # define PR_SET_MM_START_CODE 1 # define PR_SET_MM_END_CODE 2 # define PR_SET_MM_START_DATA 3 # define PR_SET_MM_END_DATA 4 # define PR_SET_MM_START_STACK 5 # define PR_SET_MM_START_BRK 6 # define PR_SET_MM_BRK 7 # define PR_SET_MM_ARG_START 8 # define PR_SET_MM_ARG_END 9 # define PR_SET_MM_ENV_START 10 # define PR_SET_MM_ENV_END 11 # define PR_SET_MM_AUXV 12 # define PR_SET_MM_EXE_FILE 13 /* * Set specific pid that is allowed to ptrace the current task. * A value of 0 mean "no process". */ #define PR_SET_PTRACER 0x59616d61 # define PR_SET_PTRACER_ANY ((unsigned long)-1) #define PR_SET_CHILD_SUBREAPER 36 #define PR_GET_CHILD_SUBREAPER 37 /* * If no_new_privs is set, then operations that grant new privileges (i.e. * execve) will either fail or not grant them. This affects suid/sgid, * file capabilities, and LSMs. * * Operations that merely manipulate or drop existing privileges (setresuid, * capset, etc.) will still work. Drop those privileges if you want them gone. * * Changing LSM security domain is considered a new privilege. So, for example, * asking selinux for a specific new context (e.g. with runcon) will result * in execve returning -EPERM. * * See Documentation/prctl/no_new_privs.txt for more details. */ #define PR_SET_NO_NEW_PRIVS 38 #define PR_GET_NO_NEW_PRIVS 39 #define PR_GET_TID_ADDRESS 40 #endif /* _LINUX_PRCTL_H */ libcap-2.24/libcap/include/uapi/linux/securebits.h0000664000076400007640000000427312261142476021535 0ustar andrewandrew#ifndef _UAPI_LINUX_SECUREBITS_H #define _UAPI_LINUX_SECUREBITS_H /* Each securesetting is implemented using two bits. One bit specifies whether the setting is on or off. The other bit specify whether the setting is locked or not. A setting which is locked cannot be changed from user-level. */ #define issecure_mask(X) (1 << (X)) #define SECUREBITS_DEFAULT 0x00000000 /* When set UID 0 has no special privileges. When unset, we support inheritance of root-permissions and suid-root executable under compatibility mode. We raise the effective and inheritable bitmasks *of the executable file* if the effective uid of the new process is 0. If the real uid is 0, we raise the effective (legacy) bit of the executable file. */ #define SECURE_NOROOT 0 #define SECURE_NOROOT_LOCKED 1 /* make bit-0 immutable */ #define SECBIT_NOROOT (issecure_mask(SECURE_NOROOT)) #define SECBIT_NOROOT_LOCKED (issecure_mask(SECURE_NOROOT_LOCKED)) /* When set, setuid to/from uid 0 does not trigger capability-"fixup". When unset, to provide compatiblility with old programs relying on set*uid to gain/lose privilege, transitions to/from uid 0 cause capabilities to be gained/lost. */ #define SECURE_NO_SETUID_FIXUP 2 #define SECURE_NO_SETUID_FIXUP_LOCKED 3 /* make bit-2 immutable */ #define SECBIT_NO_SETUID_FIXUP (issecure_mask(SECURE_NO_SETUID_FIXUP)) #define SECBIT_NO_SETUID_FIXUP_LOCKED \ (issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED)) /* When set, a process can retain its capabilities even after transitioning to a non-root user (the set-uid fixup suppressed by bit 2). Bit-4 is cleared when a process calls exec(); setting both bit 4 and 5 will create a barrier through exec that no exec()'d child can use this feature again. */ #define SECURE_KEEP_CAPS 4 #define SECURE_KEEP_CAPS_LOCKED 5 /* make bit-4 immutable */ #define SECBIT_KEEP_CAPS (issecure_mask(SECURE_KEEP_CAPS)) #define SECBIT_KEEP_CAPS_LOCKED (issecure_mask(SECURE_KEEP_CAPS_LOCKED)) #define SECURE_ALL_BITS (issecure_mask(SECURE_NOROOT) | \ issecure_mask(SECURE_NO_SETUID_FIXUP) | \ issecure_mask(SECURE_KEEP_CAPS)) #define SECURE_ALL_LOCKS (SECURE_ALL_BITS << 1) #endif /* _UAPI_LINUX_SECUREBITS_H */ libcap-2.24/libcap/include/uapi/linux/capability.h0000664000076400007640000002565712262401332021505 0ustar andrewandrew/* * This is * * Andrew G. Morgan * Alexander Kjeldaas * with help from Aleph1, Roland Buresund and Andrew Main. * * See here for the libcap library ("POSIX draft" compliance): * * http://www.kernel.org/pub/linux/libs/security/linux-privs/ */ #ifndef _UAPI_LINUX_CAPABILITY_H #define _UAPI_LINUX_CAPABILITY_H #include struct task_struct; /* User-level do most of the mapping between kernel and user capabilities based on the version tag given by the kernel. The kernel might be somewhat backwards compatible, but don't bet on it. */ /* Note, cap_t, is defined by POSIX (draft) to be an "opaque" pointer to a set of three capability sets. The transposition of 3*the following structure to such a composite is better handled in a user library since the draft standard requires the use of malloc/free etc.. */ #define _LINUX_CAPABILITY_VERSION_1 0x19980330 #define _LINUX_CAPABILITY_U32S_1 1 #define _LINUX_CAPABILITY_VERSION_2 0x20071026 /* deprecated - use v3 */ #define _LINUX_CAPABILITY_U32S_2 2 #define _LINUX_CAPABILITY_VERSION_3 0x20080522 #define _LINUX_CAPABILITY_U32S_3 2 typedef struct __user_cap_header_struct { __u32 version; int pid; } __user *cap_user_header_t; typedef struct __user_cap_data_struct { __u32 effective; __u32 permitted; __u32 inheritable; } __user *cap_user_data_t; #define VFS_CAP_REVISION_MASK 0xFF000000 #define VFS_CAP_REVISION_SHIFT 24 #define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK #define VFS_CAP_FLAGS_EFFECTIVE 0x000001 #define VFS_CAP_REVISION_1 0x01000000 #define VFS_CAP_U32_1 1 #define XATTR_CAPS_SZ_1 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_1)) #define VFS_CAP_REVISION_2 0x02000000 #define VFS_CAP_U32_2 2 #define XATTR_CAPS_SZ_2 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_2)) #define XATTR_CAPS_SZ XATTR_CAPS_SZ_2 #define VFS_CAP_U32 VFS_CAP_U32_2 #define VFS_CAP_REVISION VFS_CAP_REVISION_2 struct vfs_cap_data { __le32 magic_etc; /* Little endian */ struct { __le32 permitted; /* Little endian */ __le32 inheritable; /* Little endian */ } data[VFS_CAP_U32]; }; #ifndef __KERNEL__ /* * Backwardly compatible definition for source code - trapped in a * 32-bit world. If you find you need this, please consider using * libcap to untrap yourself... */ #define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1 #define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1 #endif /** ** POSIX-draft defined capabilities. **/ /* In a system with the [_POSIX_CHOWN_RESTRICTED] option defined, this overrides the restriction of changing file ownership and group ownership. */ #define CAP_CHOWN 0 /* Override all DAC access, including ACL execute access if [_POSIX_ACL] is defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */ #define CAP_DAC_OVERRIDE 1 /* Overrides all DAC restrictions regarding read and search on files and directories, including ACL restrictions if [_POSIX_ACL] is defined. Excluding DAC access covered by CAP_LINUX_IMMUTABLE. */ #define CAP_DAC_READ_SEARCH 2 /* Overrides all restrictions about allowed operations on files, where file owner ID must be equal to the user ID, except where CAP_FSETID is applicable. It doesn't override MAC and DAC restrictions. */ #define CAP_FOWNER 3 /* Overrides the following restrictions that the effective user ID shall match the file owner ID when setting the S_ISUID and S_ISGID bits on that file; that the effective group ID (or one of the supplementary group IDs) shall match the file owner ID when setting the S_ISGID bit on that file; that the S_ISUID and S_ISGID bits are cleared on successful return from chown(2) (not implemented). */ #define CAP_FSETID 4 /* Overrides the restriction that the real or effective user ID of a process sending a signal must match the real or effective user ID of the process receiving the signal. */ #define CAP_KILL 5 /* Allows setgid(2) manipulation */ /* Allows setgroups(2) */ /* Allows forged gids on socket credentials passing. */ #define CAP_SETGID 6 /* Allows set*uid(2) manipulation (including fsuid). */ /* Allows forged pids on socket credentials passing. */ #define CAP_SETUID 7 /** ** Linux-specific capabilities **/ /* Without VFS support for capabilities: * Transfer any capability in your permitted set to any pid, * remove any capability in your permitted set from any pid * With VFS support for capabilities (neither of above, but) * Add any capability from current's capability bounding set * to the current process' inheritable set * Allow taking bits out of capability bounding set * Allow modification of the securebits for a process */ #define CAP_SETPCAP 8 /* Allow modification of S_IMMUTABLE and S_APPEND file attributes */ #define CAP_LINUX_IMMUTABLE 9 /* Allows binding to TCP/UDP sockets below 1024 */ /* Allows binding to ATM VCIs below 32 */ #define CAP_NET_BIND_SERVICE 10 /* Allow broadcasting, listen to multicast */ #define CAP_NET_BROADCAST 11 /* Allow interface configuration */ /* Allow administration of IP firewall, masquerading and accounting */ /* Allow setting debug option on sockets */ /* Allow modification of routing tables */ /* Allow setting arbitrary process / process group ownership on sockets */ /* Allow binding to any address for transparent proxying (also via NET_RAW) */ /* Allow setting TOS (type of service) */ /* Allow setting promiscuous mode */ /* Allow clearing driver statistics */ /* Allow multicasting */ /* Allow read/write of device-specific registers */ /* Allow activation of ATM control sockets */ #define CAP_NET_ADMIN 12 /* Allow use of RAW sockets */ /* Allow use of PACKET sockets */ /* Allow binding to any address for transparent proxying (also via NET_ADMIN) */ #define CAP_NET_RAW 13 /* Allow locking of shared memory segments */ /* Allow mlock and mlockall (which doesn't really have anything to do with IPC) */ #define CAP_IPC_LOCK 14 /* Override IPC ownership checks */ #define CAP_IPC_OWNER 15 /* Insert and remove kernel modules - modify kernel without limit */ #define CAP_SYS_MODULE 16 /* Allow ioperm/iopl access */ /* Allow sending USB messages to any device via /proc/bus/usb */ #define CAP_SYS_RAWIO 17 /* Allow use of chroot() */ #define CAP_SYS_CHROOT 18 /* Allow ptrace() of any process */ #define CAP_SYS_PTRACE 19 /* Allow configuration of process accounting */ #define CAP_SYS_PACCT 20 /* Allow configuration of the secure attention key */ /* Allow administration of the random device */ /* Allow examination and configuration of disk quotas */ /* Allow setting the domainname */ /* Allow setting the hostname */ /* Allow calling bdflush() */ /* Allow mount() and umount(), setting up new smb connection */ /* Allow some autofs root ioctls */ /* Allow nfsservctl */ /* Allow VM86_REQUEST_IRQ */ /* Allow to read/write pci config on alpha */ /* Allow irix_prctl on mips (setstacksize) */ /* Allow flushing all cache on m68k (sys_cacheflush) */ /* Allow removing semaphores */ /* Used instead of CAP_CHOWN to "chown" IPC message queues, semaphores and shared memory */ /* Allow locking/unlocking of shared memory segment */ /* Allow turning swap on/off */ /* Allow forged pids on socket credentials passing */ /* Allow setting readahead and flushing buffers on block devices */ /* Allow setting geometry in floppy driver */ /* Allow turning DMA on/off in xd driver */ /* Allow administration of md devices (mostly the above, but some extra ioctls) */ /* Allow tuning the ide driver */ /* Allow access to the nvram device */ /* Allow administration of apm_bios, serial and bttv (TV) device */ /* Allow manufacturer commands in isdn CAPI support driver */ /* Allow reading non-standardized portions of pci configuration space */ /* Allow DDI debug ioctl on sbpcd driver */ /* Allow setting up serial ports */ /* Allow sending raw qic-117 commands */ /* Allow enabling/disabling tagged queuing on SCSI controllers and sending arbitrary SCSI commands */ /* Allow setting encryption key on loopback filesystem */ /* Allow setting zone reclaim policy */ #define CAP_SYS_ADMIN 21 /* Allow use of reboot() */ #define CAP_SYS_BOOT 22 /* Allow raising priority and setting priority on other (different UID) processes */ /* Allow use of FIFO and round-robin (realtime) scheduling on own processes and setting the scheduling algorithm used by another process. */ /* Allow setting cpu affinity on other processes */ #define CAP_SYS_NICE 23 /* Override resource limits. Set resource limits. */ /* Override quota limits. */ /* Override reserved space on ext2 filesystem */ /* Modify data journaling mode on ext3 filesystem (uses journaling resources) */ /* NOTE: ext2 honors fsuid when checking for resource overrides, so you can override using fsuid too */ /* Override size restrictions on IPC message queues */ /* Allow more than 64hz interrupts from the real-time clock */ /* Override max number of consoles on console allocation */ /* Override max number of keymaps */ #define CAP_SYS_RESOURCE 24 /* Allow manipulation of system clock */ /* Allow irix_stime on mips */ /* Allow setting the real-time clock */ #define CAP_SYS_TIME 25 /* Allow configuration of tty devices */ /* Allow vhangup() of tty */ #define CAP_SYS_TTY_CONFIG 26 /* Allow the privileged aspects of mknod() */ #define CAP_MKNOD 27 /* Allow taking of leases on files */ #define CAP_LEASE 28 #define CAP_AUDIT_WRITE 29 #define CAP_AUDIT_CONTROL 30 #define CAP_SETFCAP 31 /* Override MAC access. The base kernel enforces no MAC policy. An LSM may enforce a MAC policy, and if it does and it chooses to implement capability based overrides of that policy, this is the capability it should use to do so. */ #define CAP_MAC_OVERRIDE 32 /* Allow MAC configuration or state changes. The base kernel requires no MAC configuration. An LSM may enforce a MAC policy, and if it does and it chooses to implement capability based checks on modifications to that policy or the data required to maintain it, this is the capability it should use to do so. */ #define CAP_MAC_ADMIN 33 /* Allow configuring the kernel's syslog (printk behaviour) */ #define CAP_SYSLOG 34 /* Allow triggering something that will wake the system */ #define CAP_WAKE_ALARM 35 /* Allow preventing system suspends */ #define CAP_BLOCK_SUSPEND 36 #define CAP_LAST_CAP CAP_BLOCK_SUSPEND #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) /* * Bit location of each capability (used by user-space library and kernel) */ #define CAP_TO_INDEX(x) ((x) >> 5) /* 1 << 5 == bits in __u32 */ #define CAP_TO_MASK(x) (1 << ((x) & 31)) /* mask for indexed __u32 */ #endif /* _UAPI_LINUX_CAPABILITY_H */ libcap-2.24/libcap/include/sys/0000775000076400007640000000000012261143000015707 5ustar andrewandrewlibcap-2.24/libcap/include/sys/securebits.h0000664000076400007640000000046112253502644020247 0ustar andrewandrew/* * * Copyright (C) 2010 Serge Hallyn */ #ifndef _SYS_SECUREBITS_H #define _SYS_SECUREBITS_H #ifdef __cplusplus extern "C" { #endif #ifndef __user #define __user #endif #include #ifdef __cplusplus } #endif #endif /* _SYS_SECUREBITS_H */ libcap-2.24/libcap/include/sys/capability.h0000664000076400007640000000637212261143000020211 0ustar andrewandrew/* * * * Copyright (C) 1997 Aleph One * Copyright (C) 1997-8,2008 Andrew G. Morgan * * defunct POSIX.1e Standard: 25.2 Capabilities */ #ifndef _SYS_CAPABILITY_H #define _SYS_CAPABILITY_H #ifdef __cplusplus extern "C" { #endif /* * This file complements the kernel file by providing prototype * information for the user library. */ #include #include #include #ifndef __user #define __user #endif #include #include /* * 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 */ extern cap_t cap_dup(cap_t); extern int cap_free(void *); extern cap_t cap_init(void); /* libcap/cap_flag.c */ extern int cap_get_flag(cap_t, cap_value_t, cap_flag_t, cap_flag_value_t *); extern int cap_set_flag(cap_t, cap_flag_t, int, const cap_value_t *, cap_flag_value_t); extern int cap_clear(cap_t); extern int cap_clear_flag(cap_t, cap_flag_t); /* libcap/cap_file.c */ extern cap_t cap_get_fd(int); extern cap_t cap_get_file(const char *); extern int cap_set_fd(int, cap_t); extern int cap_set_file(const char *, cap_t); /* libcap/cap_proc.c */ extern cap_t cap_get_proc(void); extern cap_t cap_get_pid(pid_t); extern int cap_set_proc(cap_t); extern int cap_get_bound(cap_value_t); extern int cap_drop_bound(cap_value_t); #define CAP_IS_SUPPORTED(cap) (cap_get_bound(cap) >= 0) /* libcap/cap_extint.c */ extern ssize_t cap_size(cap_t); extern ssize_t cap_copy_ext(void *, cap_t, ssize_t); extern cap_t cap_copy_int(const void *); /* libcap/cap_text.c */ extern cap_t cap_from_text(const char *); extern char * cap_to_text(cap_t, ssize_t *); extern int cap_from_name(const char *, cap_value_t *); extern char * cap_to_name(cap_value_t); #define CAP_DIFFERS(result, flag) (((result) & (1 << (flag))) != 0) extern int cap_compare(cap_t, cap_t); /* system calls - look to libc for function to system call mapping */ 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); /* deprecated - use cap_get_pid() */ extern int capgetp(pid_t pid, cap_t cap_d); /* not valid with filesystem capability support - use cap_set_proc() */ extern int capsetp(pid_t pid, cap_t cap_d); #ifdef __cplusplus } #endif #endif /* _SYS_CAPABILITY_H */ libcap-2.24/libcap/include/linux/0000775000076400007640000000000012261142715016244 5ustar andrewandrewlibcap-2.24/libcap/cap_text.c0000664000076400007640000002317112253502644015443 0ustar andrewandrew/* * Copyright (c) 1997-8,2007-8 Andrew G Morgan * Copyright (c) 1997 Andrew Main * * This file deals with exchanging internal and textual * representations of capability sets. */ #define _GNU_SOURCE #include #define LIBCAP_PLEASE_INCLUDE_ARRAY #include "libcap.h" #include #include /* Maximum output text length (16 per cap) */ #define CAP_TEXT_SIZE (16*__CAP_MAXBITS) /* * Parse a textual representation of capabilities, returning an internal * representation. */ #define raise_cap_mask(flat, c) (flat)[CAP_TO_INDEX(c)] |= CAP_TO_MASK(c) static void setbits(cap_t a, const __u32 *b, cap_flag_t set, unsigned blks) { int n; for (n = blks; n--; ) { a->u[n].flat[set] |= b[n]; } } static void clrbits(cap_t a, const __u32 *b, cap_flag_t set, unsigned blks) { int n; for (n = blks; n--; ) a->u[n].flat[set] &= ~b[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 void forceall(__u32 *flat, __u32 value, unsigned blks) { unsigned n; for (n = blks; n--; flat[n] = value); return; } static int lookupname(char const **strp) { union { char const *constp; char *p; } str; str.constp = *strp; if (isdigit(*str.constp)) { unsigned long n = strtoul(str.constp, &str.p, 0); if (n >= __CAP_MAXBITS) return -1; *strp = str.constp; return n; } else { int c; unsigned len; for (len=0; (c = str.constp[len]); ++len) { if (!(isalpha(c) || (c == '_'))) { break; } } #ifdef GPERF_DOWNCASE const struct __cap_token_s *token_info; token_info = __cap_lookup_name(str.constp, len); if (token_info != NULL) { *strp = str.constp + len; return token_info->index; } #else /* ie., ndef GPERF_DOWNCASE */ char const *s; unsigned n; for (n = __CAP_BITS; n--; ) if (_cap_names[n] && (s = namcmp(str.constp, _cap_names[n]))) { *strp = s; return n; } #endif /* def GPERF_DOWNCASE */ return -1; /* No definition available */ } } cap_t cap_from_text(const char *str) { cap_t res; int n; unsigned cap_blks; if (str == NULL) { _cap_debug("bad argument"); errno = EINVAL; return NULL; } if (!(res = cap_init())) return NULL; switch (res->head.version) { case _LINUX_CAPABILITY_VERSION_1: cap_blks = _LINUX_CAPABILITY_U32S_1; break; case _LINUX_CAPABILITY_VERSION_2: cap_blks = _LINUX_CAPABILITY_U32S_2; break; case _LINUX_CAPABILITY_VERSION_3: cap_blks = _LINUX_CAPABILITY_U32S_3; break; default: errno = EINVAL; return NULL; } _cap_debug("%s", str); for (;;) { __u32 list[__CAP_BLKS]; char op; int flags = 0, listed=0; forceall(list, 0, __CAP_BLKS); /* skip leading spaces */ while (isspace((unsigned char)*str)) str++; if (!*str) { _cap_debugcap("e = ", *res, CAP_EFFECTIVE); _cap_debugcap("i = ", *res, CAP_INHERITABLE); _cap_debugcap("p = ", *res, CAP_PERMITTED); return res; } /* identify caps specified by this clause */ if (isalnum((unsigned char)*str) || *str == '_') { for (;;) { if (namcmp(str, "all")) { str += 3; forceall(list, ~0, cap_blks); } else { n = lookupname(&str); if (n == -1) goto bad; raise_cap_mask(list, 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 { forceall(list, ~0, cap_blks); } /* 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, list, CAP_EFFECTIVE, cap_blks); clrbits(res, list, CAP_PERMITTED, cap_blks); clrbits(res, list, CAP_INHERITABLE, cap_blks); if (op == 'M') goto minus; /* fall through */ case '+': if (flags & LIBCAP_EFF) setbits(res, list, CAP_EFFECTIVE, cap_blks); if (flags & LIBCAP_PER) setbits(res, list, CAP_PERMITTED, cap_blks); if (flags & LIBCAP_INH) setbits(res, list, CAP_INHERITABLE, cap_blks); break; case '-': minus: if (flags & LIBCAP_EFF) clrbits(res, list, CAP_EFFECTIVE, cap_blks); if (flags & LIBCAP_PER) clrbits(res, list, CAP_PERMITTED, cap_blks); if (flags & LIBCAP_INH) clrbits(res, list, CAP_INHERITABLE, cap_blks); 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); res = NULL; errno = EINVAL; return res; } /* * lookup a capability name and return its numerical value */ int cap_from_name(const char *name, cap_value_t *value_p) { int n; if (((n = lookupname(&name)) >= 0) && (value_p != NULL)) { *value_p = (unsigned) n; } return -(n < 0); } /* * Convert a single capability index number into a string representation */ char *cap_to_name(cap_value_t cap) { if ((cap < 0) || (cap >= __CAP_BITS)) { #if UINT_MAX != 4294967295U # error Recompile with correctly sized numeric array #endif char *tmp, *result; asprintf(&tmp, "%u", cap); result = _libcap_strdup(tmp); free(tmp); return result; } else { return _libcap_strdup(_cap_names[cap]); } } /* * 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(caps, capno, CAP_EFFECTIVE)) { f |= LIBCAP_EFF; } if (isset_cap(caps, capno, CAP_PERMITTED)) { f |= LIBCAP_PER; } if (isset_cap(caps, capno, CAP_INHERITABLE)) { f |= LIBCAP_INH; } return f; } #define CAP_TEXT_BUFFER_ZONE 100 char *cap_to_text(cap_t caps, ssize_t *length_p) { char buf[CAP_TEXT_SIZE+CAP_TEXT_BUFFER_ZONE]; char *p; int histo[8]; int m, t; unsigned n; unsigned cap_maxbits, cap_blks; /* Check arguments */ if (!good_cap_t(caps)) { errno = EINVAL; return NULL; } switch (caps->head.version) { case _LINUX_CAPABILITY_VERSION_1: cap_blks = _LINUX_CAPABILITY_U32S_1; break; case _LINUX_CAPABILITY_VERSION_2: cap_blks = _LINUX_CAPABILITY_U32S_2; break; case _LINUX_CAPABILITY_VERSION_3: cap_blks = _LINUX_CAPABILITY_U32S_3; break; default: errno = EINVAL; return NULL; } cap_maxbits = 32 * cap_blks; _cap_debugcap("e = ", *caps, CAP_EFFECTIVE); _cap_debugcap("i = ", *caps, CAP_INHERITABLE); _cap_debugcap("p = ", *caps, CAP_PERMITTED); memset(histo, 0, sizeof(histo)); /* default prevailing state to the upper - unnamed bits */ for (n = cap_maxbits-1; n > __CAP_BITS; n--) histo[getstateflags(caps, n)]++; /* find which combination of capability sets shares the most bits we bias to preferring non-set (m=0) with the >= 0 test. Failing to do this causes strange things to happen with older systems that don't know about bits 32+. */ for (m=t=7; t--; ) if (histo[t] >= histo[m]) m = t; /* capture remaining bits - selecting m from only the unnamed bits, we maximize the likelihood that we won't see numeric capability values in the text output. */ while (n--) histo[getstateflags(caps, n)]++; /* 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_maxbits; n++) if (getstateflags(caps, n) == t) { char *this_cap_name; this_cap_name = cap_to_name(n); if ((strlen(this_cap_name) + (p - buf)) > CAP_TEXT_SIZE) { cap_free(this_cap_name); errno = ERANGE; return NULL; } p += sprintf(p, "%s,", this_cap_name); cap_free(this_cap_name); } 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); if (length_p) { *length_p = p - buf; } return (_libcap_strdup(buf)); } libcap-2.24/libcap/cap_alloc.c0000664000076400007640000000527212256344465015563 0ustar andrewandrew/* * Copyright (c) 1997-8 Andrew G Morgan * * This file deals with allocation and deallocation of internal * capability sets as specified by POSIX.1e (formerlly, POSIX 6). */ #include "libcap.h" /* * Obtain a blank set of capabilities */ cap_t cap_init(void) { __u32 *raw_data; cap_t result; raw_data = malloc( sizeof(__u32) + sizeof(*result) ); if (raw_data == NULL) { _cap_debug("out of memory"); errno = ENOMEM; return NULL; } *raw_data = CAP_T_MAGIC; result = (cap_t) (raw_data + 1); memset(result, 0, sizeof(*result)); result->head.version = _LIBCAP_CAPABILITY_VERSION; capget(&result->head, NULL); /* load the kernel-capability version */ switch (result->head.version) { #ifdef _LINUX_CAPABILITY_VERSION_1 case _LINUX_CAPABILITY_VERSION_1: break; #endif #ifdef _LINUX_CAPABILITY_VERSION_2 case _LINUX_CAPABILITY_VERSION_2: break; #endif #ifdef _LINUX_CAPABILITY_VERSION_3 case _LINUX_CAPABILITY_VERSION_3: break; #endif default: /* No idea what to do */ cap_free(result); result = NULL; break; } return result; } /* * This is an internal library function to duplicate a string and * tag the result as something cap_free can handle. */ char *_libcap_strdup(const char *old) { __u32 *raw_data; if (old == NULL) { errno = EINVAL; return NULL; } raw_data = malloc( sizeof(__u32) + strlen(old) + 1 ); if (raw_data == NULL) { errno = ENOMEM; return NULL; } *(raw_data++) = CAP_S_MAGIC; strcpy((char *) raw_data, old); return ((char *) raw_data); } /* * This function duplicates an internal capability set 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_init(); if (result == NULL) { _cap_debug("out of memory"); return NULL; } memcpy(result, cap_d, sizeof(*cap_d)); return result; } /* * Scrub and then liberate an internal capability set. */ int cap_free(void *data_p) { if ( !data_p ) return 0; if ( good_cap_t(data_p) ) { data_p = -1 + (__u32 *) data_p; memset(data_p, 0, sizeof(__u32) + sizeof(struct _cap_struct)); free(data_p); data_p = NULL; return 0; } if ( good_cap_string(data_p) ) { size_t length = strlen(data_p) + sizeof(__u32); data_p = -1 + (__u32 *) data_p; memset(data_p, 0, length); free(data_p); data_p = NULL; return 0; } _cap_debug("don't recognize what we're supposed to liberate"); errno = EINVAL; return -1; } libcap-2.24/libcap/cap_flag.c0000664000076400007640000000606512253502644015373 0ustar andrewandrew/* * Copyright (c) 1997-8,2008 Andrew G. Morgan * * 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) { *raised = isset_cap(cap_d,value,set) ? 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, const 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= __CAP_BITS) { _cap_debug("weird capability (%d) - skipped", array_values[i]); } else { int value = array_values[i]; if (raise == CAP_SET) { cap_d->raise_cap(value,set); } else { cap_d->lower_cap(value,set); } } } 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->u), 0, sizeof(cap_d->u)); return 0; } else { _cap_debug("invalid pointer"); errno = EINVAL; return -1; } } /* * Reset the all of the capability bits for one of the flag sets */ int cap_clear_flag(cap_t cap_d, cap_flag_t flag) { switch (flag) { case CAP_EFFECTIVE: case CAP_PERMITTED: case CAP_INHERITABLE: if (good_cap_t(cap_d)) { unsigned i; for (i=0; i<_LIBCAP_CAPABILITY_U32S; i++) { cap_d->u[i].flat[flag] = 0; } return 0; } /* * fall through */ default: _cap_debug("invalid pointer"); errno = EINVAL; return -1; } } /* * Compare two capability sets */ int cap_compare(cap_t a, cap_t b) { unsigned i; int result; if (!(good_cap_t(a) && good_cap_t(b))) { _cap_debug("invalid arguments"); errno = EINVAL; return -1; } for (i=0, result=0; i<_LIBCAP_CAPABILITY_U32S; i++) { result |= ((a->u[i].flat[CAP_EFFECTIVE] != b->u[i].flat[CAP_EFFECTIVE]) ? LIBCAP_EFF : 0) | ((a->u[i].flat[CAP_INHERITABLE] != b->u[i].flat[CAP_INHERITABLE]) ? LIBCAP_INH : 0) | ((a->u[i].flat[CAP_PERMITTED] != b->u[i].flat[CAP_PERMITTED]) ? LIBCAP_PER : 0); } return result; } libcap-2.24/License0000664000076400007640000004742012253502644013546 0ustar andrewandrewUnless 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 (v2.0 - see below), 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. ------------------------------------------------------------------------- ------------------------- Full text of gpl-2.0.txt: ------------------------- GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. libcap-2.24/Makefile0000664000076400007640000000137012257342055013675 0ustar andrewandrew# # Makefile for libcap # topdir=$(shell pwd) include Make.Rules # # flags # all install clean: %: %-here $(MAKE) -C libcap $@ ifneq ($(PAM_CAP),no) $(MAKE) -C pam_cap $@ endif $(MAKE) -C progs $@ $(MAKE) -C doc $@ all-here: install-here: clean-here: $(LOCALCLEAN) distclean: clean $(DISTCLEAN) release: distclean cd .. && ln -s libcap libcap-$(VERSION).$(MINOR) && tar cvf libcap-$(VERSION).$(MINOR).tar libcap-$(VERSION).$(MINOR)/* && rm libcap-$(VERSION).$(MINOR) cd .. && gpg -sba -u E2CCF3F4 libcap-$(VERSION).$(MINOR).tar tagrelease: distclean @echo "sign the tag twice: older DSA key; and newer RSA kernel.org key" git tag -u D41A6DF2 -s libcap-$(VERSION).$(MINOR) git tag -u E2CCF3F4 -s libcap-korg-$(VERSION).$(MINOR) make release libcap-2.24/Make.Rules0000664000076400007640000000464212262401745014131 0ustar andrewandrew# ## Optional prefixes: # # common 'packaging' directoty FAKEROOT=$(DESTDIR) # Autoconf-style prefixes are activated when $(prefix) is defined. # Otherwise binaries and libraries are installed in /{lib,sbin}/, # header files in /usr/include/ and documentation in /usr/man/man?/. # These choices are motivated by the fact that getcap and setcap are # administrative operations that could be needed to recover a system. ifndef lib lib=$(shell ldd /usr/bin/ld|egrep "ld-linux|ld.so"|cut -d/ -f2) endif ifdef prefix exec_prefix=$(prefix) lib_prefix=$(exec_prefix) inc_prefix=$(lib_prefix) man_prefix=$(prefix)/share else prefix=/usr exec_prefix= lib_prefix=$(exec_prefix) inc_prefix=$(prefix) man_prefix=$(prefix)/share endif # Target directories MANDIR=$(FAKEROOT)$(man_prefix)/man SBINDIR=$(FAKEROOT)$(exec_prefix)/sbin INCDIR=$(FAKEROOT)$(inc_prefix)/include LIBDIR=$(FAKEROOT)$(lib_prefix)/$(lib) PKGCONFIGDIR=$(FAKEROOT)$(prefix)/$(lib)/pkgconfig # common defines for libcap LIBTITLE=libcap VERSION=2 MINOR=24 # # Compilation specifics KERNEL_HEADERS := $(topdir)/libcap/include/uapi IPATH += -fPIC -I$(KERNEL_HEADERS) -I$(topdir)/libcap/include CC := gcc CFLAGS := -O2 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 BUILD_CC := $(CC) BUILD_CFLAGS := $(CFLAGS) $(IPATH) AR := ar RANLIB := ranlib DEBUG = -g #-DDEBUG WARNINGS=-Wall -Wwrite-strings \ -Wpointer-arith -Wcast-qual -Wcast-align \ -Wstrict-prototypes -Wmissing-prototypes \ -Wnested-externs -Winline -Wshadow LD=$(CC) -Wl,-x -shared LDFLAGS := #-g SYSTEM_HEADERS = /usr/include INCS=$(topdir)/libcap/include/sys/capability.h LDFLAGS += -L$(topdir)/libcap CFLAGS += -Dlinux $(WARNINGS) $(DEBUG) PAM_CAP := $(shell if [ -f /usr/include/security/pam_modules.h ]; then echo yes ; else echo no ; fi) INDENT := $(shell if [ -n "$(which indent 2>/dev/null)" ]; then echo "| indent -kr" ; fi) DYNAMIC := $(shell if [ ! -d "$(topdir)/.git" ]; then echo yes; fi) LIBATTR := yes # When installing setcap, set its inheritable bit to be able to place # capabilities on files. It can be used in conjunction with pam_cap # (associated with su and certain users say) to make it useful for # specially blessed users. If you wish to drop this install feature, # use this command when running install # # make RAISE_SETFCAP=no install # RAISE_SETFCAP := $(LIBATTR) # Global cleanup stuff LOCALCLEAN=rm -f *~ core DISTCLEAN=@find . \( -name '*.orig' -o -name '*.rej' \) | xargs rm -f libcap-2.24/pam_cap/0000775000076400007640000000000012262401332013622 5ustar andrewandrewlibcap-2.24/pam_cap/capability.conf0000664000076400007640000000340112262401332016610 0ustar andrewandrew# # /etc/security/capability.conf # # this is a sample capability file (to be used in conjunction with # the pam_cap.so module) # # In order to use this module, it must have been linked with libcap # and thus you'll know about Linux's capability support. # [If you don't know about libcap, the sources for it are here: # # http://www.kernel.org/pub/linux/libs/security/linux-privs/ # # .] # # Here are some sample lines (remove the preceding '#' if you want to # use them ## user 'morgan' gets the CAP_SETFCAP inheritable capability (commented out!) #cap_setfcap morgan ## user 'luser' inherits the CAP_DAC_OVERRIDE capability (commented out!) #cap_dac_override luser ## 'everyone else' gets no inheritable capabilities (restrictive config) none * ## if there is no '*' entry, all users not explicitly mentioned will ## get all available capabilities. This is a permissive default, and ## possibly not what you want... On first reading, you might think this ## is a security problem waiting to happen, but it defaults to not being ## so in this sample file! Further, by 'get', we mean 'get in their inheritable ## set'. That is, if you look at a random process, even one run by root, ## you will see it has no inheritable capabilities (by default): ## ## $ /sbin/capsh --decode=$(grep CapInh /proc/1/status|awk '{print $2}') ## 0000000000000000= ## ## The pam_cap module simply alters the value of this capability ## set. Including the 'none *' forces use of this module with an ## unspecified user to have their inheritable set forced to zero. ## ## Omitting the line will cause the inheritable set to be unmodified ## from what the parent process had (which is generally 0 unless the ## invoking user was bestowed with some inheritable capabilities by a ## previous invocation). libcap-2.24/pam_cap/test.c0000664000076400007640000000036012253502644014754 0ustar andrewandrew#include #include #include int main(int argc, char **argv) { if (pam_sm_authenticate(NULL, 0, 0, NULL) != PAM_SUCCESS) { printf("failed to authenticate\n"); exit(1); } exit(0); } libcap-2.24/pam_cap/.gitignore0000664000076400007640000000002712253502644015621 0ustar andrewandrewpam_cap.so testcompile libcap-2.24/pam_cap/Makefile0000664000076400007640000000142712253502644015276 0ustar andrewandrew# simple make file for the pam_cap module topdir=$(shell pwd)/.. include ../Make.Rules # Note (as the author of much of the Linux-PAM library, I am confident # that this next line does *not* require -lpam on it.) If you think it # does, *verify that it does*, and if you observe that it fails as # written (and you know why it fails), email me and explain why. Thanks! LDLIBS += -L../libcap -lcap all: pam_cap.so $(MAKE) testcompile install: all mkdir -p -m 0755 $(LIBDIR)/security install -m 0755 pam_cap.so $(LIBDIR)/security pam_cap.so: pam_cap.o $(LD) $(LDFLAGS) -o pam_cap.so $< $(LDLIBS) pam_cap.o: pam_cap.c $(CC) $(CFLAGS) $(IPATH) -c $< -o $@ testcompile: test.c pam_cap.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $+ -lpam -ldl $(LDLIBS) clean: rm -f *.o *.so testcompile *~ libcap-2.24/pam_cap/License0000664000076400007640000000400712253502644015140 0ustar andrewandrewUnless otherwise *explicitly* stated the following text describes the licensed conditions under which the contents of this module release may be distributed: ------------------------------------------------------------------------- Redistribution and use in source and binary forms of this module, 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 Library General Public License, in which case the provisions of the GNU LGPL are required INSTEAD OF the above restrictions. (This clause is necessary due to a potential conflict between the GNU LGPL 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. ------------------------------------------------------------------------- libcap-2.24/pam_cap/pam_cap.c0000664000076400007640000001554412253502644015407 0ustar andrewandrew/* * Copyright (c) 1999,2007 Andrew G. Morgan * * The purpose of this module is to enforce inheritable capability sets * for a specified user. */ /* #define DEBUG */ #include #include #include #include #include #include #include #include #include #define USER_CAP_FILE "/etc/security/capability.conf" #define CAP_FILE_BUFFER_SIZE 4096 #define CAP_FILE_DELIMITERS " \t\n" #define CAP_COMBINED_FORMAT "%s all-i %s+i" #define CAP_DROP_ALL "%s all-i" struct pam_cap_s { int debug; const char *user; const char *conf_filename; }; /* obtain the inheritable capabilities for the current user */ static char *read_capabilities_for_user(const char *user, const char *source) { char *cap_string = NULL; char buffer[CAP_FILE_BUFFER_SIZE], *line; FILE *cap_file; cap_file = fopen(source, "r"); if (cap_file == NULL) { D(("failed to open capability file")); return NULL; } while ((line = fgets(buffer, CAP_FILE_BUFFER_SIZE, cap_file))) { int found_one = 0; const char *cap_text; cap_text = strtok(line, CAP_FILE_DELIMITERS); if (cap_text == NULL) { D(("empty line")); continue; } if (*cap_text == '#') { D(("comment line")); continue; } while ((line = strtok(NULL, CAP_FILE_DELIMITERS))) { if (strcmp("*", line) == 0) { D(("wildcard matched")); found_one = 1; cap_string = strdup(cap_text); break; } if (strcmp(user, line) == 0) { D(("exact match for user")); found_one = 1; cap_string = strdup(cap_text); break; } D(("user is not [%s] - skipping", line)); } cap_text = NULL; line = NULL; if (found_one) { D(("user [%s] matched - caps are [%s]", user, cap_string)); break; } } fclose(cap_file); memset(buffer, 0, CAP_FILE_BUFFER_SIZE); return cap_string; } /* * Set capabilities for current process to match the current * permitted+executable sets combined with the configured inheritable * set. */ static int set_capabilities(struct pam_cap_s *cs) { cap_t cap_s; ssize_t length = 0; char *conf_icaps; char *proc_epcaps; char *combined_caps; int ok = 0; cap_s = cap_get_proc(); if (cap_s == NULL) { D(("your kernel is capability challenged - upgrade: %s", strerror(errno))); return 0; } conf_icaps = read_capabilities_for_user(cs->user, cs->conf_filename ? cs->conf_filename:USER_CAP_FILE ); if (conf_icaps == NULL) { D(("no capabilities found for user [%s]", cs->user)); goto cleanup_cap_s; } proc_epcaps = cap_to_text(cap_s, &length); if (proc_epcaps == NULL) { D(("unable to convert process capabilities to text")); goto cleanup_icaps; } /* * This is a pretty inefficient way to combine * capabilities. However, it seems to be the most straightforward * one, given the limitations of the POSIX.1e draft spec. The spec * is optimized for applications that know the capabilities they * want to manipulate at compile time. */ combined_caps = malloc(1+strlen(CAP_COMBINED_FORMAT) +strlen(proc_epcaps)+strlen(conf_icaps)); if (combined_caps == NULL) { D(("unable to combine capabilities into one string - no memory")); goto cleanup_epcaps; } if (!strcmp(conf_icaps, "none")) { sprintf(combined_caps, CAP_DROP_ALL, proc_epcaps); } else if (!strcmp(conf_icaps, "all")) { /* no change */ sprintf(combined_caps, "%s", proc_epcaps); } else { sprintf(combined_caps, CAP_COMBINED_FORMAT, proc_epcaps, conf_icaps); } D(("combined_caps=[%s]", combined_caps)); cap_free(cap_s); cap_s = cap_from_text(combined_caps); _pam_overwrite(combined_caps); _pam_drop(combined_caps); #ifdef DEBUG { char *temp = cap_to_text(cap_s, NULL); D(("abbreviated caps for process will be [%s]", temp)); cap_free(temp); } #endif /* DEBUG */ if (cap_s == NULL) { D(("no capabilies to set")); } else if (cap_set_proc(cap_s) == 0) { D(("capabilities were set correctly")); ok = 1; } else { D(("failed to set specified capabilities: %s", strerror(errno))); } cleanup_epcaps: cap_free(proc_epcaps); cleanup_icaps: _pam_overwrite(conf_icaps); _pam_drop(conf_icaps); cleanup_cap_s: if (cap_s) { cap_free(cap_s); cap_s = NULL; } return ok; } /* log errors */ static void _pam_log(int err, const char *format, ...) { va_list args; va_start(args, format); openlog("pam_cap", LOG_CONS|LOG_PID, LOG_AUTH); vsyslog(err, format, args); va_end(args); closelog(); } static void parse_args(int argc, const char **argv, struct pam_cap_s *pcs) { int ctrl=0; /* step through arguments */ for (ctrl=0; argc-- > 0; ++argv) { if (!strcmp(*argv, "debug")) { pcs->debug = 1; } else if (!memcmp(*argv, "config=", 7)) { pcs->conf_filename = 7 + *argv; } else { _pam_log(LOG_ERR, "unknown option; %s", *argv); } } } int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv) { int retval; struct pam_cap_s pcs; char *conf_icaps; memset(&pcs, 0, sizeof(pcs)); parse_args(argc, argv, &pcs); retval = pam_get_user(pamh, &pcs.user, NULL); if (retval == PAM_CONV_AGAIN) { D(("user conversation is not available yet")); memset(&pcs, 0, sizeof(pcs)); return PAM_INCOMPLETE; } if (retval != PAM_SUCCESS) { D(("pam_get_user failed: %s", pam_strerror(pamh, retval))); memset(&pcs, 0, sizeof(pcs)); return PAM_AUTH_ERR; } conf_icaps = read_capabilities_for_user(pcs.user, pcs.conf_filename ? pcs.conf_filename:USER_CAP_FILE ); memset(&pcs, 0, sizeof(pcs)); if (conf_icaps) { D(("it appears that there are capabilities for this user [%s]", conf_icaps)); /* We could also store this as a pam_[gs]et_data item for use by the setcred call to follow. As it is, there is a small race associated with a redundant read. Oh well, if you care, send me a patch.. */ _pam_overwrite(conf_icaps); _pam_drop(conf_icaps); return PAM_SUCCESS; } else { D(("there are no capabilities restrctions on this user")); return PAM_IGNORE; } } int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc, const char **argv) { int retval; struct pam_cap_s pcs; if (!(flags & PAM_ESTABLISH_CRED)) { D(("we don't handle much in the way of credentials")); return PAM_IGNORE; } memset(&pcs, 0, sizeof(pcs)); parse_args(argc, argv, &pcs); retval = pam_get_item(pamh, PAM_USER, (const void **)&pcs.user); if ((retval != PAM_SUCCESS) || (pcs.user == NULL) || !(pcs.user[0])) { D(("user's name is not set")); return PAM_AUTH_ERR; } retval = set_capabilities(&pcs); memset(&pcs, 0, sizeof(pcs)); return (retval ? PAM_SUCCESS:PAM_IGNORE ); } libcap-2.24/pgp.keys.asc0000664000076400007640000003604412257340725014475 0ustar andrewandrewmorgan@kernel.org upload/signature key. pub 4096R/E2CCF3F4 2011-10-07 Andrew G. Morgan (Work Address) uid Andrew G. Morgan -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.15 (GNU/Linux) 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 9ifyrw== =Ibs8 -----END PGP PUBLIC KEY BLOCK----- pub 1024D/D41A6DF2 2002-09-23 Andrew G. Morgan -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.15 (GNU/Linux) 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 U4shHkPGIMgQWLcRZDepovlpGVXLmXEf =oXom -----END PGP PUBLIC KEY BLOCK----- The following is my DSA key 'D41A6DF2' signed with my old '2A398175' RSA key. -----BEGIN PGP MESSAGE----- Version: 2.6.3a owF9k82L42QAxmccVjFzUNjbHLQLHlbDTJq0aZuRAd+8+WgmaZqkTZtWWchHk6Zt vpOmGcT1A1zm5EVZPXhQYW972IMHFVxQPK14UNjLICKiexBkEQQ9iI7zB/hcf4eH B57f6dY7O5e2jt76ab/58Db7HPVasb3NvLvzT/5G44+H1uSpW0/fffDih3Dv9+uv /ka/9Nh3n/h865FH0Qd1/f7Ny4/jg28/uPJ9tvvRjTdPrz1z+vVnyf4t50T95vmr /gtninr/q7NP56+8/4Xb/tlJl9d/vXNj9+bnly6/vHX2p56urvwQ/3j3y92Pt/eO 3w57h3vO7O+/tn+5dw17HT555/bOe9YTQZR6ZrjPNHHQYjhi6zz7/4VmeUGuKbxS U3RaEmBNZCc1WupD8QIjo1ma+VF4WOPDQuFra/ygftCqXeVlHZP8sNg8i8AoCGZh fljjorTmh25Uy2az2jzP40MMK8vywAuL2Ds470eQQOV9miGUEbQ1GjCBRjiueCyY /AIn6us6u0h5K5z4dicUYcpIejfI/WklrHqzoZyEJYZgKhHUyfZAqDhIiuS4bYw6 kpD17ZilgSMMSFWCq3JmY2UyWuCcTg6lruy7GuXSCcqYApJXvS4qGVhXj5obxTwm xZBtEVijhw0qfYMNWpSma67mMBlEqcIWp8sxFYSar5fQC/AOi6CmLsq0yFdJ15RF NCTri824zjIYMYsDthVH6fmWXjVcDdfBplsk7cEg8U6GSkeM5KjPNpEgn4YTsIxi q1MsMzpqVoumabn0VPZHBpvnNmrE5TzU+oxbke1WOaqwVcD0hhw4acNJ2UFINchc qjs1KjBAjWid2dZkAsYJjtOVnXRPRnLSn617U8Vo9oM2mnZpW1CEVgydRlQoqzHS t1gSYBEzNmCDZGyPcwJv1CWSlIR9dp0yGTUky6buaAbdWxDLOYs2iNRR6knCT+AY byBW1WmiMI5my8BDWxiXSBjI68aKMDtt+6RIyY1GBSnjNAh/GZZZnfE8tnDRE6kx LHNqCRA3DxPP59NGwzflmVF6ieupk561SQtpvTBB36xEZZ6iuXestywhHlvqUh2T SzsYNQTWLhCBxdd24MwtH3SsMVVNCa5Q+XxlB+TKguQ5s1Gfs1l2w0JA2xxYXJyO g6UtglJlEE7tQbCZQKAKhgeACDUacs1BitNx3inQETimyE7X8qVgnsbjBTALmeLT XCwcf7EE0EU0wjAzZ6FmBAttIukZOKWWcjRngH2EHLWNIY1cGMTKzP/o9S8= =cdkf -----END PGP MESSAGE----- Type Bits/KeyID Date User ID pub 1024/2A398175 1996/11/17 Andrew G. Morgan Andrew G. Morgan -----BEGIN PGP PUBLIC KEY BLOCK----- Version: 2.6.3a mQCNAzKOhJ4AAAEEAJ9xYnZSD1kYanF+8GUBhHf/gx6hGd8ZNmS5qIC8Qb8rMcTI +E16nV+FnNRlPRbShITYjq1TPvVK8gTliZf41N9LRQZw0rywRt1NQyhdfKgDWYxB kSOwK67oDjkzzC56XS2rrGI6K3Rz/VtYElRyuQ6ZyaKTGcgU/TTwrUUqOYF1AAUR tCpBbmRyZXcgRy4gTW9yZ2FuIDxtb3JnYW5AbGludXgua2VybmVsLm9yZz6JAJUD BRA2iFK0NPCtRSo5gXUBAalqA/9s3Hx8BUESiC9PpL88KSVe3ENoO0ogAuMDK3vj k2a17Twxi92Dc/NPXr8ewEKF/h1GiRetLBVPGaSVC+602+2cr5SHqzUzAeyF2Xa6 VAxCskxkAssTxIW7nyAMWaOB5A/1xm3YChawVQx3XIvbIp+HXHDNr/60COtlGm7I IcHftbQnQW5kcmV3IEcuIE1vcmdhbiA8bW9yZ2FuQHRyYW5zbWV0YS5jb20+iQCV AwUQNohVmTTwrUUqOYF1AQEgWwP+K94N0OO+I2A7lnP5Jp7O+kfMJCFxPZOeozrq O8uKsAs03ekS+kDJ3p2ec65BOzZyweHEu1HtOtdZbXsN3zynLKBwJrvvaHBQpAqv BrjfNsl9a+NFmfa4fmdPWTzCaG2rmFlaQvZ6FP7QrHXB/1+VlH0gJ90FOgAd3Qyp 4hhW9g8= =qQJI -----END PGP PUBLIC KEY BLOCK----- Type Bits/KeyID Date User ID pub 1024/4536A8DD 1996/01/28 Michael K. Johnson Michael K. Johnson -----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 -----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 -----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----- libcap-2.24/progs/0000775000076400007640000000000012262403350013356 5ustar andrewandrewlibcap-2.24/progs/capsh.c0000664000076400007640000003714212253502644014635 0ustar andrewandrew/* * Copyright (c) 2008-11 Andrew G. Morgan * * This is a simple 'bash' wrapper program that can be used to * raise and lower both the bset and pI capabilities before invoking * /bin/bash (hardcoded right now). * * The --print option can be used as a quick test whether various * capability manipulations work as expected (or not). */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MAX_GROUPS 100 /* max number of supplementary groups for user */ static const cap_value_t raise_setpcap[1] = { CAP_SETPCAP }; static const cap_value_t raise_chroot[1] = { CAP_SYS_CHROOT }; static char *binary(unsigned long value) { static char string[8*sizeof(unsigned long) + 1]; unsigned i; i = sizeof(string); string[--i] = '\0'; do { string[--i] = (value & 1) ? '1' : '0'; value >>= 1; } while ((i > 0) && value); return string + i; } int main(int argc, char *argv[], char *envp[]) { pid_t child; unsigned i; child = 0; for (i=1; igr_gid; } else { group_list[g_count] = strtoul(ptr, NULL, 0); } } free(buf); if (setgroups(g_count, group_list) != 0) { fprintf(stderr, "Failed to setgroups.\n"); exit(1); } free(group_list); } else if (!memcmp("--user=", argv[i], 7)) { struct passwd *pwd; const char *user; gid_t groups[MAX_GROUPS]; int status, ngroups; user = argv[i] + 7; pwd = getpwnam(user); if (pwd == NULL) { fprintf(stderr, "User [%s] not known\n", user); exit(1); } ngroups = MAX_GROUPS; status = getgrouplist(user, pwd->pw_gid, groups, &ngroups); if (status < 1) { perror("Unable to get group list for user"); exit(1); } status = setgroups(ngroups, groups); if (status != 0) { perror("Unable to set group list for user"); exit(1); } status = setgid(pwd->pw_gid); if (status < 0) { fprintf(stderr, "Failed to set gid=%u(user=%s): %s\n", pwd->pw_gid, user, strerror(errno)); exit(1); } status = setuid(pwd->pw_uid); if (status < 0) { fprintf(stderr, "Failed to set uid=%u(user=%s): %s\n", pwd->pw_uid, user, strerror(errno)); exit(1); } } else if (!memcmp("--decode=", argv[i], 9)) { unsigned long long value; unsigned cap; const char *sep = ""; /* Note, if capabilities become longer than 64-bits we'll need to fixup the following code.. */ value = strtoull(argv[i]+9, NULL, 16); printf("0x%016llx=", value); for (cap=0; (cap < 64) && (value >> cap); ++cap) { if (value & (1ULL << cap)) { char *ptr; ptr = cap_to_name(cap); if (ptr != NULL) { printf("%s%s", sep, ptr); cap_free(ptr); } else { printf("%s%u", sep, cap); } sep = ","; } } printf("\n"); } else if (!memcmp("--supports=", argv[i], 11)) { cap_value_t cap; if (cap_from_name(argv[i] + 11, &cap) < 0) { fprintf(stderr, "cap[%s] not recognized by library\n", argv[i] + 11); exit(1); } if (!CAP_IS_SUPPORTED(cap)) { fprintf(stderr, "cap[%s=%d] not supported by kernel\n", argv[i] + 11, cap); exit(1); } } else if (!strcmp("--print", argv[i])) { unsigned cap; int set, status, j; cap_t all; char *text; const char *sep; struct group *g; gid_t groups[MAX_GROUPS], gid; uid_t uid; struct passwd *u; all = cap_get_proc(); text = cap_to_text(all, NULL); printf("Current: %s\n", text); cap_free(text); cap_free(all); printf("Bounding set ="); sep = ""; for (cap=0; (set = cap_get_bound(cap)) >= 0; cap++) { char *ptr; if (!set) { continue; } ptr = cap_to_name(cap); if (ptr == NULL) { printf("%s%u", sep, cap); } else { printf("%s%s", sep, ptr); cap_free(ptr); } sep = ","; } printf("\n"); set = prctl(PR_GET_SECUREBITS); if (set >= 0) { const char *b; b = binary(set); /* use verilog convention for binary string */ printf("Securebits: 0%o/0x%x/%u'b%s\n", set, set, (unsigned) strlen(b), b); printf(" secure-noroot: %s (%s)\n", (set & 1) ? "yes":"no", (set & 2) ? "locked":"unlocked"); printf(" secure-no-suid-fixup: %s (%s)\n", (set & 4) ? "yes":"no", (set & 8) ? "locked":"unlocked"); printf(" secure-keep-caps: %s (%s)\n", (set & 16) ? "yes":"no", (set & 32) ? "locked":"unlocked"); } else { printf("[Securebits ABI not supported]\n"); set = prctl(PR_GET_KEEPCAPS); if (set >= 0) { printf(" prctl-keep-caps: %s (locking not supported)\n", set ? "yes":"no"); } else { printf("[Keepcaps ABI not supported]\n"); } } uid = getuid(); u = getpwuid(uid); printf("uid=%u(%s)\n", getuid(), u ? u->pw_name : "???"); gid = getgid(); g = getgrgid(gid); printf("gid=%u(%s)\n", gid, g ? g->gr_name : "???"); printf("groups="); status = getgroups(MAX_GROUPS, groups); sep = ""; for (j=0; j < status; j++) { g = getgrgid(groups[j]); printf("%s%u(%s)", sep, groups[j], g ? g->gr_name : "???"); sep = ","; } printf("\n"); } else if ((!strcmp("--", argv[i])) || (!strcmp("==", argv[i]))) { argv[i] = strdup(argv[i][0] == '-' ? "/bin/bash" : argv[0]); argv[argc] = NULL; execve(argv[i], argv+i, envp); fprintf(stderr, "execve /bin/bash failed!\n"); exit(1); } else { usage: printf("usage: %s [args ...]\n" " --help this message (or try 'man capsh')\n" " --print display capability relevant state\n" " --decode=xxx decode a hex string to a list of caps\n" " --supports=xxx exit 1 if capability xxx unsupported\n" " --drop=xxx remove xxx,.. capabilities from bset\n" " --caps=xxx set caps as per cap_from_text()\n" " --inh=xxx set xxx,.. inheritiable set\n" " --secbits= write a new value for securebits\n" " --keep= set keep-capabability bit to \n" " --uid= set uid to (hint: id )\n" " --gid= set gid to (hint: id )\n" " --groups=g,... set the supplemental groups\n" " --user= set uid,gid and groups to that of user\n" " --chroot=path chroot(2) to this path\n" " --killit= send signal(n) to child\n" " --forkfor= fork and make child sleep for sec\n" " == re-exec(capsh) with args as for --\n" " -- remaing arguments are for /bin/bash\n" " (without -- [%s] will simply exit(0))\n", argv[0], argv[0]); exit(strcmp("--help", argv[i]) != 0); } } exit(0); } libcap-2.24/progs/.gitignore0000664000076400007640000000005112253502644015350 0ustar andrewandrewcapsh getcap getpcaps setcap verify-caps libcap-2.24/progs/Makefile0000664000076400007640000000124012253502644015021 0ustar andrewandrew topdir=$(shell pwd)/.. include $(topdir)/Make.Rules # # Programs: all of the examples that we will compile # PROGS=getpcaps capsh ifeq ($(LIBATTR),yes) PROGS += getcap setcap endif BUILD=$(PROGS) ifneq ($(DYNAMIC),yes) LDFLAGS += --static endif LDLIBS += -L../libcap -lcap all: $(BUILD) $(BUILD): %: %.o $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< $(LDLIBS) %.o: %.c $(INCS) $(CC) $(IPATH) $(CFLAGS) -c $< -o $@ install: all mkdir -p -m 0755 $(SBINDIR) for p in $(PROGS) ; do \ install -m 0755 $$p $(SBINDIR) ; \ done ifeq ($(RAISE_SETFCAP),yes) $(SBINDIR)/setcap cap_setfcap=i $(SBINDIR)/setcap endif clean: $(LOCALCLEAN) rm -f *.o $(BUILD) tcapsh ping hack.sh libcap-2.24/progs/quicktest.sh0000775000076400007640000000750512256356221015747 0ustar andrewandrew#!/bin/bash # # Run through a series of tests to try out the various capability # manipulations posible through exec. # # [Run this as root in a root-enabled process tree.] try_capsh () { echo "TEST: ./capsh $*" ./capsh "$@" if [ $? -ne 0 ]; then echo FAILED return 1 else echo PASSED return 0 fi } fail_capsh () { echo -n "EXPECT FAILURE: " try_capsh "$@" if [ $? -eq 1 ]; then echo "[WHICH MEANS A PASS!]" return 0 else echo "Undesired result - aborting" echo "PROBLEM TEST: $*" exit 1 fi } pass_capsh () { echo -n "EXPECT SUCCESS: " try_capsh "$@" if [ $? -eq 0 ]; then return 0 else echo "Undesired result - aborting" echo "PROBLEM TEST: $*" exit 1 fi } pass_capsh --print # Make a local non-setuid-0 version of capsh and call it privileged cp ./capsh ./privileged && chmod -s ./privileged if [ $? -ne 0 ]; then echo "Failed to copy capsh for capability manipulation" exit 1 fi # Give it the forced capability it could need ./setcap all=ep ./privileged if [ $? -ne 0 ]; then echo "Failed to set all capabilities on file" exit 1 fi ./setcap cap_setuid,cap_setgid=ep ./privileged if [ $? -ne 0 ]; then echo "Failed to set limited capabilities on privileged file" exit 1 fi # Explore keep_caps support pass_capsh --keep=0 --keep=1 --keep=0 --keep=1 --print rm -f tcapsh cp capsh tcapsh chown root.root tcapsh chmod u+s tcapsh ls -l tcapsh # leverage keep caps maintain capabilities accross a change of uid # from setuid root to capable luser (as per wireshark/dumpcap 0.99.7) pass_capsh --uid=500 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin=ip\" --uid=500 --caps=\"cap_net_raw,cap_net_admin=pie\" --print" # This fails, on 2.6.24, but shouldn't pass_capsh --uid=500 -- -c "./tcapsh --keep=1 --caps=\"cap_net_raw,cap_net_admin=ip\" --uid=500 --forkfor=10 --caps= --print --killit=9 --print" # only continue with these if --secbits is supported ./capsh --secbits=0x2f > /dev/null 2>&1 if [ $? -ne 0 ]; then echo "unable to test securebits manipulation - assume not supported (PASS)" rm -f tcapsh rm -f privileged exit 0 fi pass_capsh --secbits=42 --print fail_capsh --secbits=32 --keep=1 --keep=0 --print pass_capsh --secbits=10 --keep=0 --keep=1 --print fail_capsh --secbits=47 -- -c "./tcapsh --user=nobody" rm -f tcapsh # Suppress uid=0 privilege fail_capsh --secbits=47 --print -- -c "./capsh --user=nobody" # suppress uid=0 privilege and test this privileged pass_capsh --secbits=0x2f --print -- -c "./privileged --user=nobody" # observe that the bounding set can be used to suppress this forced capability fail_capsh --drop=cap_setuid --secbits=0x2f --print -- -c "./privileged --user=nobody" # change the way the capability is obtained (make it inheritable) ./setcap cap_setuid,cap_setgid=ei ./privileged # Note, the bounding set (edited with --drop) only limits p # capabilities, not i's. pass_capsh --secbits=47 --inh=cap_setuid,cap_setgid --drop=cap_setuid \ --uid=500 --print -- -c "./privileged --user=nobody" rm -f ./privileged # test that we do not support capabilities on setuid shell-scripts cat > hack.sh <&1 | cut -d: -f2) if [ "\$caps" != " =" ]; then echo "Shell script got [\$caps] - you should upgrade your kernel" exit 1 else ls -l \$0 echo "Good, no capabilities [\$caps] for this setuid-0 shell script" fi exit 0 EOF chmod +xs hack.sh ./capsh --uid=500 --inh=none --print -- ./hack.sh status=$? rm -f ./hack.sh if [ $status -ne 0 ]; then echo "shell scripts can have capabilities (bug)" exit 1 fi # Max lockdown pass_capsh --keep=1 --user=nobody --caps=cap_setpcap=ep \ --drop=all --secbits=0x2f --caps= --print # Verify we can chroot pass_capsh --chroot=$(/bin/pwd) pass_capsh --chroot=$(/bin/pwd) == fail_capsh --chroot=$(/bin/pwd) -- -c "echo oops" libcap-2.24/progs/old/0000775000076400007640000000000012253502644014142 5ustar andrewandrewlibcap-2.24/progs/old/sucap.c0000664000076400007640000001062512253502644015425 0ustar andrewandrew/* * $Id: sucap.c,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $ * * This was written by Finn Arne Gangstad * * 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 #include #include #undef _POSIX_SOURCE #include #include #define __USE_BSD #include #include #include #include #include #include static void usage(void) { fprintf(stderr, "usage: sucap [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 ]\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 */ } } int 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); } return 0; } libcap-2.24/progs/old/execcap.c0000664000076400007640000000352412253502644015722 0ustar andrewandrew/* * This was written by Andrew G. Morgan * * 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 #include #include #include #include #include #include static void usage(void) { fprintf(stderr, "usage: execcap [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 ]\n"); exit(1); } int 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(); return 0; } libcap-2.24/progs/old/README0000664000076400007640000000005512253502644015022 0ustar andrewandrewthese files are not relevant to this release libcap-2.24/progs/old/setpcaps.c0000664000076400007640000000463312253502644016136 0ustar andrewandrew/* * Copyright (c) 1997-8 Andrew G. Morgan * * This sets the capabilities of a given process. */ #include #include #include #include #include #undef _POSIX_SOURCE #include #include static void usage(void) { fprintf(stderr, "usage: setcap [-q] (-|) [ ... (-|) ]\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 ]\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; } /* 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); cap_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; } libcap-2.24/progs/setcap.c0000664000076400007640000001012512253502644015006 0ustar andrewandrew/* * Copyright (c) 1997,2007-8 Andrew G. Morgan * * This sets/verifies the capabilities of a given file. */ #include #include #include #include #include #include static void usage(void) { fprintf(stderr, "usage: setcap [-q] [-v] (-r|-|) " "[ ... (-r|-|) ]\n" "\n" " Note must be a regular (non-symlink) file.\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; } /* terminate */ buffer[0] = '\0'; return (i < MAXCAP ? 0:-1); } int main(int argc, char **argv) { int tried_to_cap_setfcap = 0; char buffer[MAXCAP+1]; int retval, quiet=0, verify=0; cap_t mycaps; cap_value_t capflag; if (argc < 3) { usage(); } mycaps = cap_get_proc(); if (mycaps == NULL) { fprintf(stderr, "warning - unable to get process capabilities" " (old libcap?)\n"); } while (--argc > 0) { const char *text; cap_t cap_d; if (!strcmp(*++argv, "-q")) { quiet = 1; continue; } if (!strcmp(*argv, "-v")) { verify = 1; continue; } if (!strcmp(*argv, "-r")) { cap_d = NULL; } else { 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: [%s]\n", result); } #endif } if (--argc <= 0) usage(); /* * Set the filesystem capability for this file. */ if (verify) { cap_t cap_on_file; int cmp; if (cap_d == NULL) { cap_d = cap_from_text("="); } cap_on_file = cap_get_file(*++argv); if (cap_on_file == NULL) { cap_on_file = cap_from_text("="); } cmp = cap_compare(cap_on_file, cap_d); cap_free(cap_on_file); if (cmp != 0) { if (!quiet) { printf("%s differs in [%s%s%s]\n", *argv, CAP_DIFFERS(cmp, CAP_PERMITTED) ? "p" : "", CAP_DIFFERS(cmp, CAP_INHERITABLE) ? "i" : "", CAP_DIFFERS(cmp, CAP_EFFECTIVE) ? "e" : ""); } exit(1); } if (!quiet) { printf("%s: OK\n", *argv); } } else { if (!tried_to_cap_setfcap) { capflag = CAP_SETFCAP; /* * Raise the effective CAP_SETFCAP. */ if (cap_set_flag(mycaps, CAP_EFFECTIVE, 1, &capflag, CAP_SET) != 0) { perror("unable to manipulate CAP_SETFCAP - " "try a newer libcap?"); exit(1); } if (cap_set_proc(mycaps) != 0) { perror("unable to set CAP_SETFCAP effective capability"); exit(1); } tried_to_cap_setfcap = 1; } retval = cap_set_file(*++argv, cap_d); if (retval != 0) { int explained = 0; #ifdef linux cap_value_t cap; cap_flag_value_t per_state; for (cap = 0; cap_get_flag(cap_d, cap, CAP_PERMITTED, &per_state) != -1; cap++) { cap_flag_value_t inh_state, eff_state; cap_get_flag(cap_d, cap, CAP_INHERITABLE, &inh_state); cap_get_flag(cap_d, cap, CAP_EFFECTIVE, &eff_state); if ((inh_state | per_state) != eff_state) { fprintf(stderr, "NOTE: Under Linux, effective file capabilities must either be empty, or\n" " exactly match the union of selected permitted and inheritable bits.\n"); explained = 1; break; } } #endif /* def linux */ fprintf(stderr, "Failed to set capabilities on file `%s' (%s)\n", argv[0], strerror(errno)); if (!explained) { usage(); } } } if (cap_d) { cap_free(cap_d); } } exit(0); } libcap-2.24/progs/getpcaps.c0000664000076400007640000000223212253502644015335 0ustar andrewandrew/* * Copyright (c) 1997,2008 Andrew G. Morgan * * This displays the capabilities of given target process(es). */ #include #include #include #include #include #include static void usage(void) { fprintf(stderr, "usage: getcaps [ ...]\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,2007 Andrew G. Morgan ]\n" ); exit(1); } int main(int argc, char **argv) { int retval = 0; if (argc < 2) { usage(); } for ( ++argv; --argc > 0; ++argv ) { ssize_t length; int pid; cap_t cap_d; pid = atoi(argv[0]); cap_d = cap_get_pid(pid); if (cap_d == NULL) { fprintf(stderr, "Failed to get cap's for proccess %d:" " (%s)\n", pid, strerror(errno)); retval = 1; continue; } else { char *result = cap_to_text(cap_d, &length); fprintf(stderr, "Capabilities for `%s': %s\n", *argv, result); cap_free(result); result = NULL; cap_free(cap_d); } } return retval; } libcap-2.24/progs/getcap.c0000664000076400007640000000407312253502644014777 0ustar andrewandrew/* * Copyright (c) 1997,2007 Andrew G. Morgan * * This displays the capabilities of a given file. */ #define _XOPEN_SOURCE 500 #include #include #include #include #include #include #include #include #include #include static int verbose = 0; static int recursive = 0; static void usage(void) { fprintf(stderr, "usage: getcap [-v] [-r] [-h] [ ...]\n" "\n" "\tdisplays the capabilities on the queried file(s).\n" ); exit(1); } static int do_getcap(const char *fname, const struct stat *stbuf, int tflag, struct FTW* ftwbuf) { cap_t cap_d; char *result; if (tflag != FTW_F) { if (verbose) { printf("%s (Not a regular file)\n", fname); } return 0; } cap_d = cap_get_file(fname); if (cap_d == NULL) { if (errno != ENODATA) { fprintf(stderr, "Failed to get capabilities of file `%s' (%s)\n", fname, strerror(errno)); } else if (verbose) { printf("%s\n", fname); } return 0; } result = cap_to_text(cap_d, NULL); if (!result) { fprintf(stderr, "Failed to get capabilities of human readable format at `%s' (%s)\n", fname, strerror(errno)); cap_free(cap_d); return 0; } printf("%s %s\n", fname, result); cap_free(cap_d); cap_free(result); return 0; } int main(int argc, char **argv) { int i, c; while ((c = getopt(argc, argv, "rvh")) > 0) { switch(c) { case 'r': recursive = 1; break; case 'v': verbose = 1; break; default: usage(); } } if (!argv[optind]) usage(); for (i=optind; argv[i] != NULL; i++) { struct stat stbuf; if (lstat(argv[i], &stbuf) != 0) { fprintf(stderr, "%s (%s)\n", argv[i], strerror(errno)); } else if (recursive) { nftw(argv[i], do_getcap, 20, FTW_PHYS); } else { int tflag = S_ISREG(stbuf.st_mode) ? FTW_F : (S_ISLNK(stbuf.st_mode) ? FTW_SL : FTW_NS); do_getcap(argv[i], &stbuf, tflag, 0); } } return 0; } libcap-2.24/README0000664000076400007640000000126712256337645013132 0ustar andrewandrewThis 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://sites.google.com/site/fullycapable/ # INSTALLATION Linux-Caps % make builds the library and the programs Linux-Caps % make install installs the library libcap.XX.Y in /lib[64]/ the binaries in /sbin/ the file in /usr/include the libcap.pc file in /usr/lib[64]/pkgconfig * for some example programs look in progs. Cheers Andrew G. Morgan libcap-2.24/template.c0000664000076400007640000000007412253502644014212 0ustar andrewandrew/* * Copyright (c) 1997 <@> * * */