43d1cc992a67213f73f28a5b99d11d91fc1ceb61 — Louis Solofrizzo 1 year, 6 months ago 79e52e8
Slaves & Api: Fix ARM support and handle custom domain names

Signed-off-by: Louis Solofrizzo <louis@ne02ptzero.me>
114 files changed, 8408 insertions(+), 27 deletions(-)

M api/http.go
M api/instance.go
M api/main.go
M api/slaves.go
M contrib/CMakeLists.txt
M contrib/go-lxc/lxc-binding.c
A contrib/libcap/CMakeLists.txt
A contrib/libcap/src/CHANGELOG
A contrib/libcap/src/License
A contrib/libcap/src/Make.Rules
A contrib/libcap/src/Makefile
A contrib/libcap/src/README
A contrib/libcap/src/contrib/Makefile
A contrib/libcap/src/contrib/bug400591/Makefile
A contrib/libcap/src/contrib/bug400591/bug.c
A contrib/libcap/src/contrib/pcaps4convenience
A contrib/libcap/src/contrib/pcaps4server
A contrib/libcap/src/contrib/pcaps4suid0
A contrib/libcap/src/doc/Makefile
A contrib/libcap/src/doc/cap_clear.3
A contrib/libcap/src/doc/cap_clear_flag.3
A contrib/libcap/src/doc/cap_compare.3
A contrib/libcap/src/doc/cap_copy_ext.3
A contrib/libcap/src/doc/cap_copy_int.3
A contrib/libcap/src/doc/cap_drop_bound.3
A contrib/libcap/src/doc/cap_dup.3
A contrib/libcap/src/doc/cap_free.3
A contrib/libcap/src/doc/cap_from_name.3
A contrib/libcap/src/doc/cap_from_text.3
A contrib/libcap/src/doc/cap_get_bound.3
A contrib/libcap/src/doc/cap_get_fd.3
A contrib/libcap/src/doc/cap_get_file.3
A contrib/libcap/src/doc/cap_get_flag.3
A contrib/libcap/src/doc/cap_get_pid.3
A contrib/libcap/src/doc/cap_get_proc.3
A contrib/libcap/src/doc/cap_init.3
A contrib/libcap/src/doc/cap_set_fd.3
A contrib/libcap/src/doc/cap_set_file.3
A contrib/libcap/src/doc/cap_set_flag.3
A contrib/libcap/src/doc/cap_set_proc.3
A contrib/libcap/src/doc/cap_size.3
A contrib/libcap/src/doc/cap_to_name.3
A contrib/libcap/src/doc/cap_to_text.3
A contrib/libcap/src/doc/capability.notes
A contrib/libcap/src/doc/capgetp.3
A contrib/libcap/src/doc/capsetp.3
A contrib/libcap/src/doc/capsh.1
A contrib/libcap/src/doc/getcap.8
A contrib/libcap/src/doc/libcap.3
A contrib/libcap/src/doc/old/README
A contrib/libcap/src/doc/old/_fgetfilecap.2
A contrib/libcap/src/doc/old/_fsetfilecap.2
A contrib/libcap/src/doc/old/_getfilecap.2
A contrib/libcap/src/doc/old/_getproccap.2
A contrib/libcap/src/doc/old/_setfilecap.2
A contrib/libcap/src/doc/old/_setproccap.2
A contrib/libcap/src/doc/setcap.8
A contrib/libcap/src/kdebug/Makefile
A contrib/libcap/src/kdebug/test-bash.sh
A contrib/libcap/src/kdebug/test-init.sh
A contrib/libcap/src/kdebug/test-kernel.sh
A contrib/libcap/src/kdebug/test-passwd
A contrib/libcap/src/kdebug/test-prompt.sh
A contrib/libcap/src/libcap/.gitignore
A contrib/libcap/src/libcap/Makefile
A contrib/libcap/src/libcap/_makenames.c
A contrib/libcap/src/libcap/cap_alloc.c
A contrib/libcap/src/libcap/cap_alloc.o
A contrib/libcap/src/libcap/cap_extint.c
A contrib/libcap/src/libcap/cap_extint.o
A contrib/libcap/src/libcap/cap_file.c
A contrib/libcap/src/libcap/cap_file.o
A contrib/libcap/src/libcap/cap_flag.c
A contrib/libcap/src/libcap/cap_flag.o
A contrib/libcap/src/libcap/cap_proc.c
A contrib/libcap/src/libcap/cap_proc.o
A contrib/libcap/src/libcap/cap_text.c
A contrib/libcap/src/libcap/cap_text.o
A contrib/libcap/src/libcap/include/sys/capability.h
A contrib/libcap/src/libcap/include/sys/securebits.h
A contrib/libcap/src/libcap/include/uapi/linux/capability.h
A contrib/libcap/src/libcap/include/uapi/linux/prctl.h
A contrib/libcap/src/libcap/include/uapi/linux/securebits.h
A contrib/libcap/src/libcap/libcap.h
A contrib/libcap/src/libcap/libcap.pc.in
A contrib/libcap/src/pam_cap/.gitignore
A contrib/libcap/src/pam_cap/License
A contrib/libcap/src/pam_cap/Makefile
A contrib/libcap/src/pam_cap/capability.conf
A contrib/libcap/src/pam_cap/pam_cap.c
A contrib/libcap/src/pam_cap/pam_cap.o
A contrib/libcap/src/pam_cap/test.c
A contrib/libcap/src/pgp.keys.asc
A contrib/libcap/src/progs/.gitignore
A contrib/libcap/src/progs/Makefile
A contrib/libcap/src/progs/capsh.c
A contrib/libcap/src/progs/capsh.o
A contrib/libcap/src/progs/getcap.c
A contrib/libcap/src/progs/getcap.o
A contrib/libcap/src/progs/getpcaps.c
A contrib/libcap/src/progs/getpcaps.o
A contrib/libcap/src/progs/old/README
A contrib/libcap/src/progs/old/execcap.c
A contrib/libcap/src/progs/old/setpcaps.c
A contrib/libcap/src/progs/old/sucap.c
A contrib/libcap/src/progs/quicktest.sh
A contrib/libcap/src/progs/setcap.c
A contrib/libcap/src/progs/setcap.o
A contrib/libcap/src/template.c
M contrib/lxc/CMakeLists.txt
M defs/go/CMakeLists.txt
M front/src/components/Instance.vue
M slave/instance.go
M slave/main.go
M api/http.go => api/http.go +3 -0
@@ 70,6 70,9 @@   func removeInstanceFromNginx(instance *Instance) error {
  	os.Remove("/etc/nginx/conf.d/" + instance.Name + ".cloud.louifox.house.conf")
+ 	for _, domain := range instance.Domains {
+ 		os.Remove("/etc/nginx/conf.d/" + domain + ".cloud.louifox.house.conf")
+ 	}
  	run := exec.Command("/bin/bash", "-c", "systemctl reload nginx")
  	run.Run()
  	return nil

M api/instance.go => api/instance.go +44 -2
@@ 24,17 24,17 @@ Architecture string         `json:"arch" xorm:"varchar(200)"`
  	Release      string         `json:"release" xorm:"varchar(200)"`
  	OS           string         `json:"os" xorm:"varchar(200)"`
- 	PrivateIp    bool           `json:"private_ip" xorm:"bool"`
  	Owner        string         `json:"owner" xorm:"varchar(200)"`
  	Status       InstanceStatus `json:"status" xorm:"int"`
  	TextStatus   string         `json:"text_status"`
  	IPv4         string         `json:"ipv4"`
  	IPv6         string         `json:"ipv6"`
  	Gateway      string         `json:"gateway"`
- 	Capacity     int64          `json:"capacity"`
+ 	Capacity     uint64         `json:"capacity"`
  	PhysicalNode string         `json:"physical_node" xorm:"varchar(120)"`
  	CreatedAt    time.Time      `json:"created" xorm:"created"`
  	UpdatedAt    time.Time      `json:"updated" xorm:"updated"`
+ 	Domains      []string
  }
  
  func instance_list(ctx iris.Context) {


@@ 183,7 183,49 @@ } else {
  		ctx.StatusCode(iris.StatusAccepted)
  	}
+ }
+ 
+ func instance_resize(ctx iris.Context) {
+ 	id, _ := ctx.Params().GetInt64("id")
+ 	size := ctx.Params().Get("new_size")
+ 
+ 	instance := Instance{ID: id}
+ 	ok, _ := Database.Get(&instance)
+ 
+ 	if !ok {
+ 		ctx.StatusCode(iris.StatusNotFound)
+ 		return
+ 	}
+ 
+ 	err := instanceResize(&instance, size)
+ 	if err != nil {
+ 		ctx.StatusCode(iris.StatusInternalServerError)
+ 	} else {
+ 		ctx.StatusCode(iris.StatusAccepted)
+ 	}
+ }
+ 
+ func instance_domain(ctx iris.Context) {
+ 	id, _ := ctx.Params().GetInt64("id")
+ 	domain := ctx.Params().Get("domain")
+ 
+ 	instance := Instance{ID: id}
+ 	ok, _ := Database.Get(&instance)
+ 
+ 	if !ok {
+ 		ctx.StatusCode(iris.StatusNotFound)
+ 		return
+ 	}
+ 
+ 	err := addInstanceToNginx(&instance, domain)
+ 	if err != nil {
+ 		ctx.StatusCode(iris.StatusInternalServerError)
+ 		return
+ 	}
  
+ 	instance.Domains = append(instance.Domains, domain)
+ 	Database.ID(instance.ID).Cols("domains").Update(&Instance{Domains: instance.Domains})
+ 	ctx.StatusCode(iris.StatusAccepted)
  }
  
  func instance_create(instance *Instance) {

M api/main.go => api/main.go +2 -0
@@ 48,6 48,8 @@ app.Get("/api/instance/{id:int32}/network", instance_network)
  	app.Post("/api/instance/{id:int32}/bind", instance_bind)
  	app.Delete("/api/instance/{id:int32}", instance_delete)
+ 	app.Put("/api/instance/{id:int32}/resize/{new_size:string}", instance_resize)
+ 	app.Put("/api/instance/{id:int32}/domain/{domain:string}", instance_domain)
  
  	err = ssh_init()
  	if err != nil {

M api/slaves.go => api/slaves.go +16 -7
@@ 53,6 53,9 @@ json.Unmarshal(resp, &info)
  	slave.Name = info.Name
  	slave.Arch = info.Arch
+ 	if slave.Arch == "arm" {
+ 		slave.Arch = "armhf"
+ 	}
  }
  
  func getSlaveByName(name string) *Slave {


@@ 166,11 169,12 @@ }
  
  type InstanceGet struct {
- 	Name    string   `json:"name"`
- 	Status  int      `json:"status"`
- 	IPv4    []string `json:"IPv4"`
- 	IPv6    []string `json:"IPv6"`
- 	Gateway string   `json:"gateway"`
+ 	Name     string   `json:"name"`
+ 	Status   int      `json:"status"`
+ 	IPv4     []string `json:"IPv4"`
+ 	IPv6     []string `json:"IPv6"`
+ 	Gateway  string   `json:"gateway"`
+ 	Capacity uint64   `json:"capacity"`
  }
  
  func instanceGet(instance *Instance) error {


@@ 197,6 201,7 @@ instance.IPv6 = infos.IPv6[0]
  	}
  	instance.Gateway = infos.Gateway
+ 	instance.Capacity = infos.Capacity
  	return nil
  }
  


@@ 309,6 314,12 @@ return body, err
  }
  
+ func instanceResize(instance *Instance, size string) error {
+ 	slave := getSlaveByName(instance.PhysicalNode)
+ 	_, err := httpRequest("PUT", slave, "api/instance/"+instance.Name+"/resize/"+size, nil)
+ 	return err
+ }
+ 
  func createSlaves(slaves []string) {
  	for _, slave := range slaves {
  		s := &Slave{


@@ 317,6 328,4 @@ Slaves = append(Slaves, s)
  		slaveGetInfo(s)
  	}
- 
- 	log.Infof("%v", Slaves[1])
  }

M contrib/CMakeLists.txt => contrib/CMakeLists.txt +1 -0
@@ 1,3 1,4 @@ add_subdirectory(arm-linux-gnueabihf)
+ add_subdirectory(libcap)
  add_subdirectory(lxc)
  add_subdirectory(sqlite3)

M contrib/go-lxc/lxc-binding.c => contrib/go-lxc/lxc-binding.c +14 -0
@@ 56,6 56,20 @@ if (strncmp(t, "none", strlen(t)) == 0) {
  		return c->create(c, NULL, bdevtype, NULL, !!(flags & LXC_CREATE_QUIET), argv);
  	}
+ 
+         if (strcmp(bdevtype, "rbd") == 0)
+         {
+             struct bdev_specs spec = {
+                 .fstype = "ext4",
+                 .fssize = 2000000000,
+                 .rbd = {
+                     .rbdpool = "lxc"
+                 }
+             };
+ 
+             return c->create(c, t, bdevtype, &spec, !!(flags & LXC_CREATE_QUIET), argv);
+         }
+ 
  	return c->create(c, t, bdevtype, NULL, !!(flags & LXC_CREATE_QUIET), argv);
  }
  

A contrib/libcap/CMakeLists.txt => contrib/libcap/CMakeLists.txt +26 -0
@@ 0,0 1,26 @@
+ set(_libcap_dir              "${CMAKE_CURRENT_SOURCE_DIR}")
+ set(_libcap_name             "libcap")
+ set(_libcap_source_dir       "${_libcap_dir}/src")
+ set(_libcap_build_dir        "${CMAKE_CURRENT_BINARY_DIR}/src")
+ set(_libcap_lib              "${_libcap_source_dir}/libcap/libcap.a")
+ 
+ file(MAKE_DIRECTORY ${_libcap_build_dir})
+ 
+ add_custom_command(
+     OUTPUT ${_libcap_lib}
+     COMMAND CC=${_armgcc_bin} DESTDIR=${_libcap_build_dir} make -C ${_libcap_source_dir}
+     WORKING_DIRECTORY ${_libcap_build_dir}
+ )
+ 
+ add_custom_target(
+     build_libcap ALL
+     DEPENDS ${_libcap_lib}
+ )
+ 
+ add_library(
+     libcap INTERFACE
+ )
+ 
+ add_dependencies(libcap build_libcap armgcc)
+ add_to_cgo_libraries(${_libcap_source_dir}/libcap)
+ add_to_cgo_link(cap)

A contrib/libcap/src/CHANGELOG => contrib/libcap/src/CHANGELOG +17 -0
@@ 0,0 1,17 @@
+ For 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.

A contrib/libcap/src/License => contrib/libcap/src/License +385 -0
@@ 0,0 1,385 @@
+ Unless otherwise *explicitly* stated, the following text describes the
+ licensed conditions under which the contents of this libcap release
+ may be used and distributed:
+ 
+ -------------------------------------------------------------------------
+ Redistribution and use in source and binary forms of libcap, with
+ or without modification, are permitted provided that the following
+ conditions are met:
+ 
+ 1. Redistributions of source code must retain any existing copyright
+    notice, and this entire permission notice in its entirety,
+    including the disclaimer of warranties.
+ 
+ 2. Redistributions in binary form must reproduce all prior and current
+    copyright notices, this list of conditions, and the following
+    disclaimer in the documentation and/or other materials provided
+    with the distribution.
+ 
+ 3. The name of any author may not be used to endorse or promote
+    products derived from this software without their specific prior
+    written permission.
+ 
+ ALTERNATIVELY, this product may be distributed under the terms of the
+ GNU General Public License (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.
+ 
+     <one line to give the program's name and a brief idea of what it does.>
+     Copyright (C) <year>  <name of author>
+ 
+     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.
+ 
+   <signature of Ty Coon>, 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.

A contrib/libcap/src/Make.Rules => contrib/libcap/src/Make.Rules +87 -0
@@ 0,0 1,87 @@
+ #
+ ## 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=$(man_prefix)/man
+ SBINDIR=$(exec_prefix)/sbin
+ INCDIR=$(inc_prefix)/include
+ LIBDIR=$(lib_prefix)/$(lib)
+ PKGCONFIGDIR=$(prefix)/$(lib)/pkgconfig
+ 
+ # common defines for libcap
+ LIBTITLE=libcap
+ VERSION=2
+ MINOR=26
+ #
+ 
+ # Compilation specifics
+ 
+ KERNEL_HEADERS := $(topdir)/libcap/include/uapi
+ IPATH += -fPIC -I$(KERNEL_HEADERS) -I$(topdir)/libcap/include
+ 
+ CC := /home/louis/Work/cisco/build/contrib/arm-linux-gnueabihf/armv7-eabihf--musl--stable-2018.11-1/bin/arm-buildroot-linux-musleabihf-gcc
+ CFLAGS := -O2 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64
+ BUILD_CC := $(CC)
+ BUILD_CFLAGS := $(CFLAGS) $(IPATH)
+ AR := /home/louis/Work/cisco/build/contrib/arm-linux-gnueabihf/armv7-eabihf--musl--stable-2018.11-1/bin/arm-buildroot-linux-musleabihf-ar
+ RANLIB := /home/louis/Work/cisco/build/contrib/arm-linux-gnueabihf/armv7-eabihf--musl--stable-2018.11-1/bin/arm-buildroot-linux-musleabihf-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
+ BUILD_GPERF := $(shell which gperf >/dev/null 2>/dev/null && echo yes)
+ 
+ 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)
+ 
+ # 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 := yes
+ 
+ # Global cleanup stuff
+ 
+ LOCALCLEAN=rm -f *~ core
+ DISTCLEAN=@find . \( -name '*.orig' -o -name '*.rej' \) | xargs rm -f

A contrib/libcap/src/Makefile => contrib/libcap/src/Makefile +42 -0
@@ 0,0 1,42 @@
+ #
+ # Makefile for libcap
+ #
+ topdir=$(shell pwd)
+ include Make.Rules
+ 
+ #
+ # flags
+ #
+ 
+ all install clean kdebug: %: %-here
+ 	$(MAKE) -C libcap $@
+ ifneq ($(PAM_CAP),no)
+ 	$(MAKE) -C pam_cap $@
+ endif
+ 	$(MAKE) -C progs $@
+ 	$(MAKE) -C doc $@
+ 	$(MAKE) -C kdebug $@
+ 
+ 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 --exclude patches libcap-$(VERSION).$(MINOR)/* && rm libcap-$(VERSION).$(MINOR)
+ 
+ test: all
+ 	cd progs && sudo ./quicktest.sh
+ 
+ morganrelease: distclean
+ 	@echo "sign the tag twice: older DSA key; and newer RSA kernel.org key"
+ 	git tag -u D41A6DF2 -s libcap-$(VERSION).$(MINOR) -m "This is libcap-$(VERSION).$(MINOR)"
+ 	git tag -u E2CCF3F4 -s libcap-korg-$(VERSION).$(MINOR) -m "This is libcap-$(VERSION).$(MINOR)"
+ 	make release
+ 	@echo "sign the tar file using korg key"
+ 	cd .. && gpg -sba -u E2CCF3F4 libcap-$(VERSION).$(MINOR).tar

A contrib/libcap/src/README => contrib/libcap/src/README +29 -0
@@ 0,0 1,29 @@
+ This is a library for getting and setting POSIX.1e (formerly POSIX 6)
+ draft 15 capabilities.
+ 
+ This library would not have been possible without the help of 
+ 
+ 	Aleph1, Roland Buresund and Andrew Main, Alexander Kjeldaas.
+ 
+ More information on capabilities in the Linux kernel can be found at
+ 
+ 	http://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 <sys/capability.h> file in /usr/include
+ 		the libcap.pc file in /usr/lib[64]/pkgconfig
+ 
+ * for some example programs look in progs.
+ 
+ Cheers
+ 
+ Andrew G. Morgan <morgan@kernel.org>

A contrib/libcap/src/contrib/Makefile => contrib/libcap/src/contrib/Makefile +3 -0
@@ 0,0 1,3 @@
+ .PHONY: all clean
+ all clean:
+ 	for x in bug* ; do make -C $$x $@ || exit 1 ; done

A contrib/libcap/src/contrib/bug400591/Makefile => contrib/libcap/src/contrib/bug400591/Makefile +9 -0
@@ 0,0 1,9 @@
+ all: 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

A contrib/libcap/src/contrib/bug400591/bug.c => contrib/libcap/src/contrib/bug400591/bug.c +43 -0
@@ 0,0 1,43 @@
+ #include <assert.h>
+ #include <stdlib.h>
+ #include <sys/capability.h>
+ 
+ /*
+  * 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;
+ }

A contrib/libcap/src/contrib/pcaps4convenience => contrib/libcap/src/contrib/pcaps4convenience +209 -0
@@ 0,0 1,209 @@
+ #!/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

A contrib/libcap/src/contrib/pcaps4server => contrib/libcap/src/contrib/pcaps4server +369 -0
@@ 0,0 1,369 @@
+ #!/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

A contrib/libcap/src/contrib/pcaps4suid0 => contrib/libcap/src/contrib/pcaps4suid0 +227 -0
@@ 0,0 1,227 @@
+ #!/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

A contrib/libcap/src/doc/Makefile => contrib/libcap/src/doc/Makefile +50 -0
@@ 0,0 1,50 @@
+ #
+ # 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 $(FAKEROOT)$(MANDIR)/man1 $(FAKEROOT)$(MANDIR)/man3 $(FAKEROOT)$(MANDIR)/man8
+ 	for man in \
+ 		$(FAKEROOT)$(MANDIR)/man1 $(MAN1S) \
+ 		$(FAKEROOT)$(MANDIR)/man3 $(MAN3S) \
+ 		$(FAKEROOT)$(MANDIR)/man8 $(MAN8S) \
+ 		; \
+ 	do \
+ 		case $$man in \
+ 		/*)	sub=$$man ; continue ;; \
+ 		esac; \
+ 		install -m 644 $$man $$sub ; \
+ 	done
+ 
+ clean:
+ 	$(LOCALCLEAN)
+ 	rm -rf html
+ 
+ 

A contrib/libcap/src/doc/cap_clear.3 => contrib/libcap/src/doc/cap_clear.3 +133 -0
@@ 0,0 1,133 @@
+ .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 <sys/capability.h>
+ .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)

A contrib/libcap/src/doc/cap_clear_flag.3 => contrib/libcap/src/doc/cap_clear_flag.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_clear.3

A contrib/libcap/src/doc/cap_compare.3 => contrib/libcap/src/doc/cap_compare.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_clear.3

A contrib/libcap/src/doc/cap_copy_ext.3 => contrib/libcap/src/doc/cap_copy_ext.3 +104 -0
@@ 0,0 1,104 @@
+ .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 <sys/capability.h>
+ .sp
+ .BI "ssize_t cap_size(cap_t " cap_p );
+ .sp
+ .BI "ssize_t cap_copy_ext(void *" ext_p ", cap_t " cap_p ", ssize_t " size );
+ .sp
+ .BI "cap_t cap_copy_int(const void *" ext_p );
+ .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)

A contrib/libcap/src/doc/cap_copy_int.3 => contrib/libcap/src/doc/cap_copy_int.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_copy_ext.3

A contrib/libcap/src/doc/cap_drop_bound.3 => contrib/libcap/src/doc/cap_drop_bound.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_get_proc.3

A contrib/libcap/src/doc/cap_dup.3 => contrib/libcap/src/doc/cap_dup.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_init.3

A contrib/libcap/src/doc/cap_free.3 => contrib/libcap/src/doc/cap_free.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_init.3

A contrib/libcap/src/doc/cap_from_name.3 => contrib/libcap/src/doc/cap_from_name.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_from_text.3

A contrib/libcap/src/doc/cap_from_text.3 => contrib/libcap/src/doc/cap_from_text.3 +233 -0
@@ 0,0 1,233 @@
+ .\"
+ .\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+ .\"
+ .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 <sys/capability.h>
+ .sp
+ .BI "cap_t cap_from_text(const char *" buf_p );
+ .sp
+ .BI "char *cap_to_text(cap_t " caps ", ssize_t *" length_p );
+ .sp
+ .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,<every-other-capability>=".
+ .PP
+ The operators, `+' and `-' both require an explicit preceding
+ capability list and one or more explicit trailing flags.  The `+'
+ operator will raise all of the listed capabilities in the flagged
+ capability sets.  The `-' operator will lower all of the listed
+ capabilities in the flagged capability sets.  For example:
+ "all+p" will raise all of the Permitted capabilities; "cap_fowner+p-i"
+ will raise the override-file-ownership capability in the Permitted
+ capability set and lower this Inheritable capability;
+ "cap_fowner+pe-i" and "cap_fowner=+pe" are equivalent.
+ .SH "RETURN VALUE"
+ .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 <stdlib.h>
+ #include <stdio.h>
+ #include <sys/capability.h>
+ 
+ #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 <textual\-cap\-set>\\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)

A contrib/libcap/src/doc/cap_get_bound.3 => contrib/libcap/src/doc/cap_get_bound.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_get_proc.3

A contrib/libcap/src/doc/cap_get_fd.3 => contrib/libcap/src/doc/cap_get_fd.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_get_file.3

A contrib/libcap/src/doc/cap_get_file.3 => contrib/libcap/src/doc/cap_get_file.3 +139 -0
@@ 0,0 1,139 @@
+ .\"
+ .\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+ .\"
+ .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 <sys/capability.h>
+ .sp
+ .BI "cap_t cap_get_file(const char *" path_p );
+ .sp
+ .BI "int cap_set_file(const char *" path_p ", cap_t " cap_p );
+ .sp
+ .BI "cap_t cap_get_fd(int " fd );
+ .sp
+ .BI "int cap_set_fd(int " fd ", cap_t " caps );
+ .sp
+ .BI "uid_t cap_get_nsowner(cap_t " caps );
+ .sp
+ .BI "int cap_set_nsowner(cap_t " caps ", uid_t " rootid );
+ .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.
+ .PP
+ A capability set held in memory can be associated with the rootid in
+ use in a specific namespace. It is possible to get and set this value
+ (in the memory copy) with
+ .BR cap_get_nsowner ()
+ and
+ .BR cap_set_nsowner ()
+ respectively. The rootid is ignored by the libcap library in all cases
+ other than when the capability is written to a file. Only if the value
+ is non-zero will the library attempt to include it in the written file
+ capability set.
+ .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)

A contrib/libcap/src/doc/cap_get_flag.3 => contrib/libcap/src/doc/cap_get_flag.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_clear.3

A contrib/libcap/src/doc/cap_get_pid.3 => contrib/libcap/src/doc/cap_get_pid.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_get_proc.3

A contrib/libcap/src/doc/cap_get_proc.3 => contrib/libcap/src/doc/cap_get_proc.3 +204 -0
@@ 0,0 1,204 @@
+ .\"
+ .\" $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 <sys/capability.h>
+ .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 <sys/types.h>
+ .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_t ,
+ 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/<pid>/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)

A contrib/libcap/src/doc/cap_init.3 => contrib/libcap/src/doc/cap_init.3 +86 -0
@@ 0,0 1,86 @@
+ .\"
+ .\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+ .\"
+ .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 <sys/capability.h>
+ .sp
+ .B cap_t cap_init(void);
+ .sp
+ .BI "int cap_free(void *" obj_d );
+ .sp
+ .BI "cap_t cap_dup(cap_t " cap_p );
+ .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)

A contrib/libcap/src/doc/cap_set_fd.3 => contrib/libcap/src/doc/cap_set_fd.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_get_file.3

A contrib/libcap/src/doc/cap_set_file.3 => contrib/libcap/src/doc/cap_set_file.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_get_file.3

A contrib/libcap/src/doc/cap_set_flag.3 => contrib/libcap/src/doc/cap_set_flag.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_clear.3

A contrib/libcap/src/doc/cap_set_proc.3 => contrib/libcap/src/doc/cap_set_proc.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_get_proc.3

A contrib/libcap/src/doc/cap_size.3 => contrib/libcap/src/doc/cap_size.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_copy_ext.3

A contrib/libcap/src/doc/cap_to_name.3 => contrib/libcap/src/doc/cap_to_name.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_from_text.3

A contrib/libcap/src/doc/cap_to_text.3 => contrib/libcap/src/doc/cap_to_text.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_from_text.3

A contrib/libcap/src/doc/capability.notes => contrib/libcap/src/doc/capability.notes +58 -0
@@ 0,0 1,58 @@
+ Overview
+ --------
+ 
+ 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!]

A contrib/libcap/src/doc/capgetp.3 => contrib/libcap/src/doc/capgetp.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_get_proc.3

A contrib/libcap/src/doc/capsetp.3 => contrib/libcap/src/doc/capsetp.3 +1 -0
@@ 0,0 1,1 @@
+ .so man3/cap_get_proc.3

A contrib/libcap/src/doc/capsh.1 => contrib/libcap/src/doc/capsh.1 +173 -0
@@ 0,0 1,173 @@
+ .\"
+ .\" capsh.1 Man page added 2009-12-23 Andrew G. Morgan <morgan@kernel.org>
+ .\"
+ .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= <id>
+ Force all
+ .B gid
+ values to equal
+ .I id
+ using the
+ .BR setgid (2)
+ system call.
+ .TP
+ .BI --groups= <id-list>
+ 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 <morgan@kernel.org>.
+ .SH "REPORTING BUGS"
+ Please report bugs to the author.
+ .SH "SEE ALSO"
+ .BR libcap (3),
+ .BR getcap (8), setcap (8)
+ and
+ .BR capabilities (7).

A contrib/libcap/src/doc/getcap.8 => contrib/libcap/src/doc/getcap.8 +33 -0
@@ 0,0 1,33 @@
+ .\"
+ .\" $Id: getcap.8,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $
+ .\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+ .\"
+ .TH GETCAP 8 "11 September 2018"
+ .SH NAME
+ getcap \- examine file capabilities
+ .SH SYNOPSIS
+ \fBgetcap\fP [-v] [-n] [-r] [-h] \fIfilename\fP [ ... ]
+ .SH DESCRIPTION
+ .B getcap
+ displays the name and capabilities of each specified
+ .SH OPTIONS
+ .TP 4
+ .B -h
+ prints quick usage.
+ .TP 4
+ .B -n
+ prints any non-zero namespace rootid value found to be associated with
+ a file's capabilities.
+ .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
+ .IR filename
+ One file per line.
+ .SH "SEE ALSO"
+ .BR cap_get_file (3),
+ .BR cap_to_text (3),
+ .BR setcap (8)

A contrib/libcap/src/doc/libcap.3 => contrib/libcap/src/doc/libcap.3 +114 -0
@@ 0,0 1,114 @@
+ .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 <sys/capability.h>
+ .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 <sys/types.h>
+ .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)

A contrib/libcap/src/doc/old/README => contrib/libcap/src/doc/old/README +1 -0
@@ 0,0 1,1 @@
+ these files are not relevant to this release

A contrib/libcap/src/doc/old/_fgetfilecap.2 => contrib/libcap/src/doc/old/_fgetfilecap.2 +1 -0
@@ 0,0 1,1 @@
+ .so man2/_setfilecap.2

A contrib/libcap/src/doc/old/_fsetfilecap.2 => contrib/libcap/src/doc/old/_fsetfilecap.2 +1 -0
@@ 0,0 1,1 @@
+ .so man2/_setfilecap.2

A contrib/libcap/src/doc/old/_getfilecap.2 => contrib/libcap/src/doc/old/_getfilecap.2 +1 -0
@@ 0,0 1,1 @@
+ .so man2/_setfilecap.2

A contrib/libcap/src/doc/old/_getproccap.2 => contrib/libcap/src/doc/old/_getproccap.2 +1 -0
@@ 0,0 1,1 @@
+ .so man2/_setproccap.2

A contrib/libcap/src/doc/old/_setfilecap.2 => contrib/libcap/src/doc/old/_setfilecap.2 +117 -0
@@ 0,0 1,117 @@
+ .\"
+ .\" $Id: _setfilecap.2,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $
+ .\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+ .\"
+ .TH _SETFILECAP 2 "26th April 1997" "Linux 2.1" "Linux Programmer's Manual"
+ .SH NAME
+ _setfilecap, _getfilecap, _fsetfilecap, _fgetfilecap \- set/get file capabilities
+ .SH SYNOPSIS
+ .B #include <sys/capability.h>
+ .sp
+ .BI "int _setfilecap(char const *" filename ", size_t " usize ", __cap_s const *" iset ", __cap_s const *" pset ", __cap_s const *" eset );
+ .sp
+ .BI "int _getproccap(char const *" filename ", size_t " usize ", __cap_s *" iset ", __cap_s *" pset ", __cap_s *" eset );
+ .sp
+ .BI "int _fsetfilecap(int " fd ", size_t " usize ", __cap_s const *" iset ", __cap_s const *" pset ", __cap_s const *" eset );
+ .sp
+ .BI "int _fgetproccap(int " fd ", size_t " usize ", __cap_s *" iset ", __cap_s *" pset ", __cap_s *" eset );
+ .SH USAGE
+ .br
+ .B cc ... -lcap
+ .SH DESCRIPTION
+ .B _setfilecap
+ sets the specified
+ .IR filename 's
+ Inheritable, Permitted and Effective capabilities to the sets specified.
+ A NULL pointer specifies that a set should not be changed.
+ .PP
+ .B _fsetfilecap
+ does the same thing to the file referenced by file descriptor
+ .IR fd .
+ .PP
+ .B _getfilecap
+ and
+ .B _fgetfilecap
+ copy the file's capability sets into the sets provided.
+ A NULL pointer specifies that a set should not be returned.
+ .PP
+ The
+ .I usize
+ argument specifies the size of the user-space capability sets, in bytes.
+ If the kernel uses a different size internally, it will truncate or
+ zero-fill as required.
+ .PP
+ Files don't actually have a proper Effective capability set.  Instead they
+ have a single-bit flag, that indicates that the set is either full or
+ empty.  When setting a file's capabilities, that flag will be set if
+ and only if the Effective set specified has at least one bit set.
+ .SH "RETURN VALUE"
+ On success, zero is returned.  On error, -1 is returned, and
+ .I errno
+ is set appropriately.
+ .SH ERRORS
+ .TP
+ .SB EFAULT
+ One of the capability arguments or the filename was an invalid data pointer.
+ .TP
+ .SB EPERM
+ An attempt was made to set non-empty capabilities on a file,
+ and the caller does not have the
+ .SB CAP_FSETCAP
+ capability raised.
+ .TP
+ .SB EPERM
+ An attempt was made to set capabilities on a file, and
+ the effective UID does not match the owner of the file, and the caller
+ does not have the
+ .SB CAP_FOWNER
+ capability raised.
+ .TP
+ .SB EINVAL
+ An attempt was made to set non-empty capabilities on a file
+ residing on a file system that does not support them.
+ .TP
+ .SB EROFS
+ An attempt was made to set capabilities on a file residing
+ on a read-only file system.
+ .TP
+ .SB ENAMETOOLONG
+ .I filename
+ is too long.
+ .TP
+ .SB ENOENT
+ The file specified does not exist.
+ .TP
+ .SB ENOMEM
+ Insufficient kernel memory was available.
+ .TP
+ .SB ENOTDIR
+ A component of the path prefix is not a directory.
+ .TP
+ .SB EACCES
+ Search permission is denied on a component of the path prefix.
+ .TP
+ .SB ELOOP
+ .I filename
+ containes a circular reference (via symlinks).
+ .TP
+ .SB EBADF
+ .I fd
+ is not a valid file descriptor.
+ .TP
+ .SB EIO
+ A hard error occurred while reading or writing the file system.
+ .TP
+ .SB ENOSYS
+ The POSIX.1e capability system was not configured into the kernel.
+ .SH "CONFORMING TO"
+ These system calls are specific to Linux.
+ The portable interfaces are
+ .IR cap_set_file (3),
+ .IR cap_get_file (3),
+ .IR cap_set_fd (3),
+ and
+ .IR cap_get_fd (3).
+ .SH "SEE ALSO"
+ .IR _setproccap (2).
+ 

A contrib/libcap/src/doc/old/_setproccap.2 => contrib/libcap/src/doc/old/_setproccap.2 +52 -0
@@ 0,0 1,52 @@
+ .\"
+ .\" $Id: _setproccap.2,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $
+ .\" written by Andrew Main <zefram@dcs.warwick.ac.uk>
+ .\"
+ .TH _SETPROCCAP 2 "26th April 1997" "Linux 2.1" "Linux Programmer's Manual"
+ .SH NAME
+ _setproccap, _getproccap \- set/get process capabilities
+ .SH SYNOPSIS
+ .B #include <sys/capability.h>
+ .sp
+ .BI "int _setproccap(size_t " usize ", __cap_s const *" iset ", __cap_s const *" pset ", __cap_s const *" eset );
+ .sp
+ .BI "int _getproccap(size_t " usize ", __cap_s *" iset ", __cap_s *" pset ", __cap_s *" eset );
+ .SH DESCRIPTION
+ .B _setproccap
+ sets the calling process'
+ Inheritable, Permitted and Effective capabilities to the sets specified.
+ A NULL pointer specifies that a set should not be changed.
+ .PP
+ .B _getproccap
+ copies the process' capability sets into the sets provided.
+ A NULL pointer specifies that a set should not be returned.
+ .PP
+ The
+ .I usize
+ argument specifies the size of the user-space capability sets, in bytes.
+ If the kernel uses a different size internally, it will truncate or
+ zero-fill as required.
+ .SH "RETURN VALUE"
+ On success, zero is returned.  On error, -1 is returned, and
+ .I errno
+ is set appropriately.
+ .SH ERRORS
+ .TP
+ .SB EFAULT
+ One of the capability arguments was an invalid data pointer.
+ .TP
+ .SB EPERM
+ An attempt was made to add a capability to the Permitted set, or to set
+ a capability in the Effective or Inheritable sets that is not in the
+ Permitted set.
+ .TP
+ .SB ENOSYS
+ The POSIX.1e capability system was not configured into the kernel.
+ .SH "CONFORMING TO"
+ These system calls are specific to Linux.
+ The portable interfaces are
+ .IR cap_set_proc (3)
+ and
+ .IR cap_get_proc (3).
+ .SH "SEE ALSO"
+ .IR _setfilecap (2).

A contrib/libcap/src/doc/setcap.8 => contrib/libcap/src/doc/setcap.8 +60 -0
@@ 0,0 1,60 @@
+ .\"
+ .\" $Id: setcap.8,v 1.1.1.1 1999/04/17 22:16:31 morgan Exp $
+ .\"
+ .TH SETCAP 8 "11 September 2018"
+ .SH NAME
+ setcap \- set file capabilities
+ .SH SYNOPSIS
+ \fBsetcap\fP [-q] [-n <rootid>] [-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 optional
+ .B -n <rootid>
+ argument can be used to set the file capability for use only in a
+ namespace with this rootid owner. The
+ .B -v
+ option is used to verify that the specified capabilities are currently
+ associated with the file. If -v and -n are supplied, the
+ .B -n <rootid>
+ argument is also verified.
+ .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. Note, setting an empty
+ capability set is
+ .B not the same
+ as removing it. An empty set can be used to guarantee a file is not
+ executed with privilege inspite of the fact that the prevailing
+ ambient+inheritable sets would otherwise bestow capabilities on
+ executed binaries.
+ .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)

A contrib/libcap/src/kdebug/Makefile => contrib/libcap/src/kdebug/Makefile +14 -0
@@ 0,0 1,14 @@
+ topdir=$(shell pwd)/..
+ include ../Make.Rules
+ 
+ test:
+ 	./test-kernel.sh
+ 
+ all:
+ 	@echo cd to kdebug to test a kernel build
+ 
+ install:
+ 
+ clean:
+ 	$(LOCALCLEAN)
+ 	rm -f fs.conf initramfs.img

A contrib/libcap/src/kdebug/test-bash.sh => contrib/libcap/src/kdebug/test-bash.sh +4 -0
@@ 0,0 1,4 @@
+ #!/bin/sh
+ # bash is used in various headers so we need a wrapper to invoke sh
+ # instead.
+ exec sh "$@"

A contrib/libcap/src/kdebug/test-init.sh => contrib/libcap/src/kdebug/test-init.sh +14 -0
@@ 0,0 1,14 @@
+ #!/bin/sh
+ PATH=/bin
+ 
+ echo -n "Mounting filesystems ... "
+ mount -t proc proc /proc
+ mount -t devtmpfs dev /dev
+ mount -t sysfs sys /sys
+ mount -t devpts pts /dev/pts
+ echo done
+ 
+ echo Hello, World
+ cd /root
+ ./quicktest.sh
+ sh -i

A contrib/libcap/src/kdebug/test-kernel.sh => contrib/libcap/src/kdebug/test-kernel.sh +67 -0
@@ 0,0 1,67 @@
+ #!/bin/bash
+ # The following is a synthesis of info in:
+ #
+ #  http://vmsplice.net/~stefan/stefanha-kernel-recipes-2015.pdf
+ #  http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/README
+ #
+ KBASE=../../linux
+ #APPEND="console=ttyS0"
+ 
+ function die {
+     echo "$*"
+     exit 1
+ }
+ 
+ pushd ..
+ make || die "failed to make libcap tree"
+ popd
+ 
+ # Assumes desired make *config (eg. make defconfig) is already done.
+ pushd $KBASE
+ pwd
+ make V=1 all || die "failed to build kernel: $0"
+ popd
+ 
+ HERE=$(/bin/pwd)
+ 
+ cat > fs.conf <<EOF
+ file /init test-init.sh 0755 0 0
+ dir /etc 0755 0 0
+ file /etc/passwd test-passwd 0444 0 0
+ dir /lib 0755 0 0
+ dir /proc 0755 0 0
+ dir /dev 0755 0 0
+ dir /sys 0755 0 0
+ dir /sbin 0755 0 0
+ file /sbin/busybox /usr/sbin/busybox 0755 0 0
+ dir /bin 0755 0 0
+ file /bin/myprompt test-prompt.sh 0755 0 0
+ file /bin/bash test-bash.sh 0755 0 0
+ dir /usr 0755 0 0
+ dir /usr/bin 0755 0 0
+ dir /root 0755 0 0
+ file /root/quicktest.sh $HERE/../progs/quicktest.sh 0755 0 0
+ file /root/setcap $HERE/../progs/setcap 0755 0 0
+ file /root/getcap $HERE/../progs/getcap 0755 0 0
+ file /root/capsh $HERE/../progs/capsh 0755 0 0
+ file /root/getpcaps $HERE/../progs/getpcaps 0755 0 0
+ EOF
+ 
+ COMMANDS="ls ln cp dmesg id pwd mkdir rmdir cat rm sh mount umount chmod less vi"
+ for f in $COMMANDS; do
+     echo slink /bin/$f /sbin/busybox 0755 0 0 >> fs.conf
+ done
+ 
+ UCOMMANDS="id cut"
+ for f in $UCOMMANDS; do
+     echo slink /usr/bin/$f /sbin/busybox 0755 0 0 >> fs.conf
+ done
+ 
+ $KBASE/usr/gen_init_cpio fs.conf | gzip -9 > initramfs.img
+ 
+ KERNEL=$KBASE/arch/x86_64/boot/bzImage
+ 
+ qemu-system-$(uname -m) -m 1024 \
+ 		   -kernel $KERNEL \
+ 		   -initrd initramfs.img \
+ 		   -append "$APPEND"

A contrib/libcap/src/kdebug/test-passwd => contrib/libcap/src/kdebug/test-passwd +2 -0
@@ 0,0 1,2 @@
+ root:x:0:0:root:/root:/bin/bash
+ nobody:x:99:99:Nobody:/:/sbin/nologin

A contrib/libcap/src/kdebug/test-prompt.sh => contrib/libcap/src/kdebug/test-prompt.sh +2 -0
@@ 0,0 1,2 @@
+ #!/bin/sh
+ echo -n "$(pwd)# "

A contrib/libcap/src/libcap/.gitignore => contrib/libcap/src/libcap/.gitignore +7 -0
@@ 0,0 1,7 @@
+ cap_names.h
+ cap_names.list.h
+ _caps_output.gperf
+ libcap.a
+ libcap.so*
+ _makenames
+ libcap.pc

A contrib/libcap/src/libcap/Makefile => contrib/libcap/src/libcap/Makefile +83 -0
@@ 0,0 1,83 @@
+ #
+ # 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 cap_file
+ 
+ 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 ($(BUILD_GPERF),yes)
+ USE_GPERF_OUTPUT = $(GPERF_OUTPUT)
+ INCLUDE_GPERF_OUTPUT = -DINCLUDE_GPERF_OUTPUT='"$(GPERF_OUTPUT)"'
+ endif
+ 
+ libcap.pc: libcap.pc.in
+ 	sed -e 's,@prefix@,$(prefix),' \
+ 		-e 's,@exec_prefix@,$(exec_prefix),' \
+ 		-e 's,@libdir@,$(LIBDIR),' \
+ 		-e 's,@includedir@,$(inc_prefix)/include,' \
+ 		-e 's,@VERSION@,$(VERSION).$(MINOR),' \
+ 		-e 's,@deps@,$(DEPS),' \
+ 		$< >$@
+ 
+ _makenames: _makenames.c cap_names.list.h
+ 	gcc $(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 *, size_t);\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 $(FAKEROOT)$(INCDIR)/sys
+ 	install -m 0644 include/sys/capability.h $(FAKEROOT)$(INCDIR)/sys
+ 	mkdir -p -m 0755 $(FAKEROOT)$(LIBDIR)
+ 	install -m 0644 $(STALIBNAME) $(FAKEROOT)$(LIBDIR)/$(STALIBNAME)
+ 	install -m 0644 $(MINLIBNAME) $(FAKEROOT)$(LIBDIR)/$(MINLIBNAME)
+ 	ln -sf $(MINLIBNAME) $(FAKEROOT)$(LIBDIR)/$(MAJLIBNAME)
+ 	ln -sf $(MAJLIBNAME) $(FAKEROOT)$(LIBDIR)/$(LIBNAME)
+ ifeq ($(FAKEROOT),)
+ 	-/sbin/ldconfig
+ endif
+ 	mkdir -p -m 0755 $(FAKEROOT)$(PKGCONFIGDIR)
+ 	install -m 0644 libcap.pc $(FAKEROOT)$(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)

A contrib/libcap/src/libcap/_makenames.c => contrib/libcap/src/libcap/_makenames.c +61 -0
@@ 0,0 1,61 @@
+ /*
+  * Copyright (c) 1997-8 Andrew G. Morgan <morgan@kernel.org>
+  *
+  * This is a file to make the capability <-> string mappings for
+  * libcap.
+  */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <sys/capability.h>
+ 
+ /*
+  * #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"
+ 	   " *     <linux/capability.h>\n"
+ 	   " */\n"
+ 	   "#define __CAP_BITS   %d\n"
+ 	   "\n"
+ 	   "#ifdef LIBCAP_PLEASE_INCLUDE_ARRAY\n"
+ 	   "  char const *_cap_names[__CAP_BITS] = {\n", maxcaps);
+ 
+     for (i=0; i<maxcaps; ++i) {
+ 	if (pointers[i])
+ 	    printf("      /* %d */\t\"%s\",\n", i, pointers[i]);
+ 	else
+ 	    printf("      /* %d */\tNULL,\t\t/* - presently unused */\n", i);
+     }
+ 
+     printf("  };\n"
+ 	   "#endif /* LIBCAP_PLEASE_INCLUDE_ARRAY */\n"
+ 	   "\n"
+ 	   "/* END OF FILE */\n");
+ 
+     exit(0);
+ }

A contrib/libcap/src/libcap/cap_alloc.c => contrib/libcap/src/libcap/cap_alloc.c +137 -0
@@ 0,0 1,137 @@
+ /*
+  * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
+  *
+  * 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 = calloc(1, 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);
+ 
+     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;
+ }

A contrib/libcap/src/libcap/cap_alloc.o => contrib/libcap/src/libcap/cap_alloc.o +0 -0

        
A contrib/libcap/src/libcap/cap_extint.c => contrib/libcap/src/libcap/cap_extint.c +123 -0
@@ 0,0 1,123 @@
+ /*
+  * Copyright (c) 1997-8 Andrew G Morgan <morgan@kernel.org>
+  *
+  * 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; i<NUMBER_OF_CAP_SETS; ++i) {
+ 	size_t j;
+ 	for (j=0; j<CAP_SET_SIZE; ) {
+ 	    __u32 val;
+ 
+ 	    val = cap_d->u[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; set<NUMBER_OF_CAP_SETS; ++set) {
+ 	unsigned blk;
+ 	int bno = 0;
+ 	for (blk=0; blk<(CAP_SET_SIZE/sizeof(__u32)); ++blk) {
+ 	    __u32 val = 0;
+ 
+ 	    if (bno != blen)
+ 		val  = export->bytes[bno++][set];
+ 	    if (bno != blen)
+ 		val |= export->bytes[bno++][set] << 8;
+ 	    if (bno != blen)
+ 		val |= export->bytes[bno++][set] << 16;
+ 	    if (bno != blen)
+ 		val |= export->bytes[bno++][set] << 24;
+ 
+ 	    cap_d->u[blk].flat[set] = val;
+ 	}
+     }
+ 
+     /* all done */
+     return cap_d;
+ }
+ 

A contrib/libcap/src/libcap/cap_extint.o => contrib/libcap/src/libcap/cap_extint.o +0 -0

        
A contrib/libcap/src/libcap/cap_file.c => contrib/libcap/src/libcap/cap_file.c +367 -0
@@ 0,0 1,367 @@
+ /*
+  * Copyright (c) 1997,2007,2016 Andrew G Morgan <morgan@kernel.org>
+  *
+  * This file deals with setting capabilities on files.
+  */
+ 
+ #include <sys/types.h>
+ #include <byteswap.h>
+ #include <sys/stat.h>
+ #include <unistd.h>
+ #include <linux/xattr.h>
+ 
+ /*
+  * We hardcode the prototypes for the Linux system calls here since
+  * there are no libcap library APIs that expose the user to these
+  * details, and that way we don't need to force clients to link any
+  * other libraries to access them.
+  */
+ extern ssize_t getxattr(const char *, const char *, void *, size_t);
+ extern ssize_t fgetxattr(int, const char *, void *, size_t);
+ extern int setxattr(const char *, const char *, const void *, size_t, int);
+ extern int fsetxattr(int, const char *, const void *, size_t, int);
+ extern int removexattr(const char *, const char *);
+ extern int fremovexattr(int, const char *);
+ 
+ #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_ns_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) {
+     case VFS_CAP_REVISION_1:
+ 	tocopy = VFS_CAP_U32_1;
+ 	bytes -= XATTR_CAPS_SZ_1;
+ 	break;
+ 
+     case VFS_CAP_REVISION_2:
+ 	tocopy = VFS_CAP_U32_2;
+ 	bytes -= XATTR_CAPS_SZ_2;
+ 	break;
+ 
+     case VFS_CAP_REVISION_3:
+ 	tocopy = VFS_CAP_U32_3;
+ 	bytes -= XATTR_CAPS_SZ_3;
+ 	result->rootid = FIXUP_32BITS(rawvfscap->rootid);
+ 	break;
+ 
+     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_ns_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) {
+     case _LINUX_CAPABILITY_VERSION_1:
+ 	magic = VFS_CAP_REVISION_1;
+ 	tocopy = VFS_CAP_U32_1;
+ 	*bytes_p = XATTR_CAPS_SZ_1;
+ 	break;
+ 
+     case _LINUX_CAPABILITY_VERSION_2:
+     case _LINUX_CAPABILITY_VERSION_3:
+ 	magic = VFS_CAP_REVISION_2;
+ 	tocopy = VFS_CAP_U32_2;
+ 	*bytes_p = XATTR_CAPS_SZ_2;
+ 	break;
+ 
+     default:
+ 	errno = EINVAL;
+ 	return -1;
+     }
+ 
+     if (cap_d->rootid != 0) {
+ 	if (cap_d->head.version < _LINUX_CAPABILITY_VERSION_3) {
+ 	    _cap_debug("namespaces with non-0 rootid unsupported by kernel");
+ 	    errno = EINVAL;
+ 	    return -1;
+ 	}
+ 	magic = VFS_CAP_REVISION_3;
+ 	tocopy = VFS_CAP_U32_3;
+ 	*bytes_p = XATTR_CAPS_SZ_3;
+ 	rawvfscap->rootid = FIXUP_32BITS(cap_d->rootid);
+     }
+ 
+     _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_ns_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_ns_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;
+ }
+ 
+ /*
+  * Get rootid as seen in the current user namespace for the file capability
+  * sets.
+  */
+ 
+ uid_t cap_get_nsowner(cap_t cap_d)
+ {
+ 	return cap_d->rootid;
+ }
+ 
+ /*
+  * 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_ns_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_ns_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);
+ }
+ 
+ /*
+  * Set rootid for the file capability sets.
+  */
+ 
+ int cap_set_nsowner(cap_t cap_d, uid_t rootid)
+ {
+ 	cap_d->rootid = rootid;
+ 	return 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;
+ }
+ 
+ uid_t cap_get_nsowner(cap_t cap_d)
+ {
+     errno = EINVAL;
+     return -1;
+ }
+ 
+ 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;
+ }
+ 
+ void cap_set_nsowner(cap_t cap_d, uid_t rootid)
+ {
+ 	errno = EINVAL;
+ 	return -1;
+ }
+ 
+ #endif /* def VFS_CAP_U32 */

A contrib/libcap/src/libcap/cap_file.o => contrib/libcap/src/libcap/cap_file.o +0 -0

        
A contrib/libcap/src/libcap/cap_flag.c => contrib/libcap/src/libcap/cap_flag.c +150 -0
@@ 0,0 1,150 @@
+ /*
+  * Copyright (c) 1997-8,2008 Andrew G. Morgan <morgan@kernel.org>
+  *
+  * 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<no_values; ++i) {
+ 	    if (array_values[i] < 0 || array_values[i] >= __CAP_BITS) {
+ 		_cap_debug("weird capability (%d) - skipped", array_values[i]);
+ 	    } else {
+ 		int value = array_values[i];
+ 
+ 		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;
+ }

A contrib/libcap/src/libcap/cap_flag.o => contrib/libcap/src/libcap/cap_flag.o +0 -0

        
A contrib/libcap/src/libcap/cap_proc.c => contrib/libcap/src/libcap/cap_proc.c +191 -0
@@ 0,0 1,191 @@
+ /*
+  * Copyright (c) 1997-8,2007,2011 Andrew G Morgan <morgan@kernel.org>
+  *
+  * This file deals with getting and setting capabilities on processes.
+  */
+ 
+ #include <sys/prctl.h>
+ 
+ #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;
+ }
+ 
+ /* the kernel api requires unsigned long arguments */
+ #define pr_arg(x) ((unsigned long) x)
+ 
+ /* get a capability from the bounding set */
+ 
+ int cap_get_bound(cap_value_t cap)
+ {
+     int result;
+ 
+     result = prctl(PR_CAPBSET_READ, pr_arg(cap));
+     if (result < 0) {
+ 	errno = -result;
+ 	return -1;
+     }
+     return result;
+ }
+ 
+ /* drop a capability from the bounding set */
+ 
+ int cap_drop_bound(cap_value_t cap)
+ {
+     int result;
+ 
+     result = prctl(PR_CAPBSET_DROP, pr_arg(cap));
+     if (result < 0) {
+ 	errno = -result;
+ 	return -1;
+     }
+     return result;
+ }
+ 
+ /* get a capability from the ambient set */
+ 
+ int cap_get_ambient(cap_value_t cap)
+ {
+     int result;
+     result = prctl(PR_CAP_AMBIENT, pr_arg(PR_CAP_AMBIENT_IS_SET),
+ 		   pr_arg(cap), pr_arg(0), pr_arg(0));
+     if (result < 0) {
+ 	errno = -result;
+ 	return -1;
+     }
+     return result;
+ }
+ 
+ /* modify a single ambient capability value */
+ 
+ int cap_set_ambient(cap_value_t cap, cap_flag_value_t set)
+ {
+     int result, val;
+     switch (set) {
+     case CAP_SET:
+ 	val = PR_CAP_AMBIENT_RAISE;
+ 	break;
+     case CAP_CLEAR:
+ 	val = PR_CAP_AMBIENT_LOWER;
+ 	break;
+     default:
+ 	errno = EINVAL;
+ 	return -1;
+     }
+     result = prctl(PR_CAP_AMBIENT, pr_arg(val), pr_arg(cap),
+ 		   pr_arg(0), pr_arg(0));
+     if (result < 0) {
+ 	errno = -result;
+ 	return -1;
+     }
+     return result;
+ }
+ 
+ /* erase all ambient capabilities */
+ 
+ int cap_reset_ambient()
+ {
+     int result;
+ 
+     result = prctl(PR_CAP_AMBIENT, pr_arg(PR_CAP_AMBIENT_CLEAR_ALL),
+ 		   pr_arg(0), pr_arg(0), pr_arg(0));
+     if (result < 0) {
+ 	errno = -result;
+ 	return -1;
+     }
+     return result;
+ }

A contrib/libcap/src/libcap/cap_proc.o => contrib/libcap/src/libcap/cap_proc.o +0 -0

        
A contrib/libcap/src/libcap/cap_text.c => contrib/libcap/src/libcap/cap_text.c +434 -0
@@ 0,0 1,434 @@
+ /*
+  * Copyright (c) 1997-8,2007-8 Andrew G Morgan <morgan@kernel.org>
+  * Copyright (c) 1997 Andrew Main <zefram@dcs.warwick.ac.uk>
+  *
+  * This file deals with exchanging internal and textual
+  * representations of capability sets.
+  */
+ 
+ #define _GNU_SOURCE
+ #include <stdio.h>
+ 
+ #define LIBCAP_PLEASE_INCLUDE_ARRAY
+ #include "libcap.h"
+ 
+ #include <ctype.h>
+ #include <limits.h>
+ 
+ #ifdef INCLUDE_GPERF_OUTPUT
+ /* we need to include it after #define _GNU_SOURCE is set */
+ #include INCLUDE_GPERF_OUTPUT
+ #endif
+ 
+ /* 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;