/[gentoo-x86]/eclass/fcaps.eclass
Gentoo

Diff of /eclass/fcaps.eclass

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 1.3 Revision 1.11
1# Copyright 1999-2013 Gentoo Foundation 1# Copyright 1999-2015 Gentoo Foundation
2# Distributed under the terms of the GNU General Public License v2 2# Distributed under the terms of the GNU General Public License v2
3# $Header: /var/cvsroot/gentoo-x86/eclass/fcaps.eclass,v 1.3 2013/01/30 07:15:49 vapier Exp $ 3# $Header: /var/cvsroot/gentoo-x86/eclass/fcaps.eclass,v 1.11 2015/02/18 16:11:53 vapier Exp $
4 4
5# @ECLASS: fcaps.eclass 5# @ECLASS: fcaps.eclass
6# @MAINTAINER: 6# @MAINTAINER:
7# Constanze Hausner <constanze@gentoo.org> 7# Constanze Hausner <constanze@gentoo.org>
8# base-system@gentoo.org 8# base-system@gentoo.org
9# @BLURB: function to set POSIX file-based capabilities 9# @BLURB: function to set POSIX file-based capabilities
10# @DESCRIPTION: 10# @DESCRIPTION:
11# This eclass provides a function to set file-based capabilities on binaries. 11# This eclass provides a function to set file-based capabilities on binaries.
12# This is not the same as USE=caps which controls runtime capability changes,
13# often via packages like libcap.
12# 14#
13# Due to probable capability-loss on moving or copying, this happens in 15# Due to probable capability-loss on moving or copying, this happens in
14# pkg_postinst-phase (at least for now). 16# pkg_postinst-phase (at least for now).
15# 17#
16# @EXAMPLE: 18# @EXAMPLE:
26# FILECAPS=( 28# FILECAPS=(
27# cap_net_raw bin/ping bin/ping6 29# cap_net_raw bin/ping bin/ping6
28# ) 30# )
29# @CODE 31# @CODE
30 32
31if [[ ${___ECLASS_ONCE_FCAPS} != "recur -_+^+_- spank" ]] ; then 33if [[ -z ${_FCAPS_ECLASS} ]]; then
32___ECLASS_ONCE_FCAPS="recur -_+^+_- spank" 34_FCAPS_ECLASS=1
33 35
34IUSE="+filecaps" 36IUSE="+filecaps"
35 37
38# We can't use libcap-ng atm due to #471414.
36DEPEND="filecaps? ( sys-libs/libcap )" 39DEPEND="filecaps? ( sys-libs/libcap )"
37 40
38# @ECLASS-VARIABLE: FILECAPS 41# @ECLASS-VARIABLE: FILECAPS
39# @DEFAULT_UNSET 42# @DEFAULT_UNSET
40# @DESCRIPTION: 43# @DESCRIPTION:
70# The caps mode (default 711) is used to set the permission on the file if 73# The caps mode (default 711) is used to set the permission on the file if
71# capabilities were properly set on the file. 74# capabilities were properly set on the file.
72# 75#
73# If the system is unable to set capabilities, it will use the specified user, 76# If the system is unable to set capabilities, it will use the specified user,
74# group, and mode (presumably to make the binary set*id). The defaults there 77# group, and mode (presumably to make the binary set*id). The defaults there
75# are root:root and 4711. Otherwise, the ownership and permissions will be 78# are root:0 and 4711. Otherwise, the ownership and permissions will be
76# unchanged. 79# unchanged.
77fcaps() { 80fcaps() {
78 debug-print-function ${FUNCNAME} "$@" 81 debug-print-function ${FUNCNAME} "$@"
79 82
80 # Process the user options first. 83 # Process the user options first.
81 local owner='root' 84 local owner='root'
82 local group='root' 85 local group='0'
83 local mode='4711' 86 local mode='4711'
84 local caps_mode='711' 87 local caps_mode='711'
85 88
86 while [[ $# -gt 0 ]] ; do 89 while [[ $# -gt 0 ]] ; do
87 case $1 in 90 case $1 in
109 root=${EROOT:-${ROOT}} 112 root=${EROOT:-${ROOT}}
110 ;; 113 ;;
111 esac 114 esac
112 115
113 # Process every file! 116 # Process every file!
114 local file out 117 local file
115 for file ; do 118 for file ; do
116 [[ ${file} != /* ]] && file="${root}${file}" 119 [[ ${file} != /* ]] && file="${root}${file}"
117 120
118 if use filecaps ; then 121 if use filecaps ; then
119 # Try to set capabilities. Ignore errors when the 122 # Try to set capabilities. Ignore errors when the
122 125
123 # If everything goes well, we don't want the file to be readable 126 # If everything goes well, we don't want the file to be readable
124 # by people. 127 # by people.
125 chmod ${caps_mode} "${file}" || die 128 chmod ${caps_mode} "${file}" || die
126 129
130 # Set/verify funcs for sys-libs/libcap.
131 _libcap() { setcap "${caps}" "${file}" ; }
132 _libcap_verify() { setcap -v "${caps}" "${file}" >/dev/null ; }
133
134 # Set/verify funcs for sys-libs/libcap-ng.
135 # Note: filecap only supports =ep mode.
136 # It also expects a different form:
137 # setcap cap_foo,cap_bar
138 # filecap foo bar
139 _libcap_ng() {
140 local caps=",${caps%=ep}"
141 filecap "${file}" "${caps//,cap_}"
142 }
143 _libcap_ng_verify() {
144 # libcap-ng has a crappy interface
145 local rcaps icaps caps=",${caps%=ep}"
146 rcaps=$(filecap "${file}" | \
147 sed -nr \
148 -e "s:^.{${#file}} +::" \
149 -e 's:, +:\n:g' \
150 -e 2p | \
151 LC_ALL=C sort)
152 [[ ${PIPESTATUS[0]} -eq 0 ]] || return 1
153 icaps=$(echo "${caps//,cap_}" | LC_ALL=C sort)
154 [[ ${rcaps} == ${icaps} ]]
155 }
156
157 local out cmd notfound=0
158 for cmd in _libcap _libcap_ng ; do
127 if ! out=$(LC_ALL=C setcap "${caps}" "${file}" 2>&1) ; then 159 if ! out=$(LC_ALL=C ${cmd} 2>&1) ; then
128 if [[ ${out} != *"Operation not supported"* ]] ; then 160 case ${out} in
161 *"command not found"*)
162 : $(( ++notfound ))
163 continue
164 ;;
165 *"Operation not supported"*)
166 local fstype=$(stat -f -c %T "${file}")
167 ewarn "Could not set caps on '${file}' due to missing filesystem support:"
168 ewarn "* enable XATTR support for '${fstype}' in your kernel (if configurable)"
169 ewarn "* mount the fs with the user_xattr option (if not the default)"
170 ewarn "* enable the relevant FS_SECURITY option (if configurable)"
171 break
172 ;;
173 *)
129 eerror "Setting caps '${caps}' on file '${file}' failed:" 174 eerror "Setting caps '${caps}' on file '${file}' failed:"
130 eerror "${out}" 175 eerror "${out}"
131 die "could not set caps" 176 die "could not set caps"
177 ;;
178 esac
132 else 179 else
133 local fstype=$(stat -f -c %T "${file}") 180 # Sanity check that everything took.
134 ewarn "Could not set caps on '${file}' due to missing filesystem support." 181 ${cmd}_verify || die "Checking caps '${caps}' on '${file}' failed"
135 ewarn "Make sure you enable XATTR support for '${fstype}' in your kernel." 182
136 ewarn "You might also have to enable the relevant FS_SECURITY option." 183 # Everything worked. Move on to the next file.
184 continue 2
137 fi 185 fi
138 else 186 done
139 # Sanity check that everything took. 187 if [[ ${notfound} -eq 2 ]] && [[ -z ${_FCAPS_WARNED} ]] ; then
140 setcap -v "${caps}" "${file}" >/dev/null \ 188 _FCAPS_WARNED="true"
141 || die "Checking caps '${caps}' on '${file}' failed" 189 ewarn "Could not find cap utils; make sure libcap or libcap-ng is available."
142
143 # Everything worked. Move on to the next file.
144 continue
145 fi 190 fi
146 fi 191 fi
147 192
148 # If we're still here, setcaps failed. 193 # If we're still here, setcaps failed.
149 debug-print "${FUNCNAME}: setting owner/mode on '${file}'" 194 debug-print "${FUNCNAME}: setting owner/mode on '${file}'"

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.11

  ViewVC Help
Powered by ViewVC 1.1.20