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

Contents of /eclass/fcaps.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.6 - (show annotations) (download)
Sat Jun 1 02:29:49 2013 UTC (14 months ago) by vapier
Branch: MAIN
Changes since 1.5: +3 -2 lines
fcaps: _libcap_ng_verify: check the exit code of filecap in the pipeline and not the sed/sort commands

1 # Copyright 1999-2013 Gentoo Foundation
2 # Distributed under the terms of the GNU General Public License v2
3 # $Header: /var/cvsroot/gentoo-x86/eclass/fcaps.eclass,v 1.5 2013/04/28 04:24:59 vapier Exp $
4
5 # @ECLASS: fcaps.eclass
6 # @MAINTAINER:
7 # Constanze Hausner <constanze@gentoo.org>
8 # base-system@gentoo.org
9 # @BLURB: function to set POSIX file-based capabilities
10 # @DESCRIPTION:
11 # This eclass provides a function to set file-based capabilities on binaries.
12 #
13 # Due to probable capability-loss on moving or copying, this happens in
14 # pkg_postinst-phase (at least for now).
15 #
16 # @EXAMPLE:
17 # You can manually set the caps on ping and ping6 by doing:
18 # @CODE
19 # pkg_postinst() {
20 # fcaps cap_net_raw bin/ping bin/ping6
21 # }
22 # @CODE
23 #
24 # Or set it via the global ebuild var FILECAPS:
25 # @CODE
26 # FILECAPS=(
27 # cap_net_raw bin/ping bin/ping6
28 # )
29 # @CODE
30
31 if [[ ${___ECLASS_ONCE_FCAPS} != "recur -_+^+_- spank" ]] ; then
32 ___ECLASS_ONCE_FCAPS="recur -_+^+_- spank"
33
34 IUSE="+filecaps"
35
36 DEPEND="filecaps? ( || ( sys-libs/libcap sys-libs/libcap-ng ) )"
37
38 # @ECLASS-VARIABLE: FILECAPS
39 # @DEFAULT_UNSET
40 # @DESCRIPTION:
41 # An array of fcap arguments to use to automatically execute fcaps. See that
42 # function for more details.
43 #
44 # All args are consumed until the '--' marker is found. So if you have:
45 # @CODE
46 # FILECAPS=( moo cow -- fat cat -- chubby penguin )
47 # @CODE
48 #
49 # This will end up executing:
50 # @CODE
51 # fcaps moo cow
52 # fcaps fat cat
53 # fcaps chubby penguin
54 # @CODE
55 #
56 # Note: If you override pkg_postinst, you must call fcaps_pkg_postinst yourself.
57
58 # @FUNCTION: fcaps
59 # @USAGE: [-o <owner>] [-g <group>] [-m <mode>] [-M <caps mode>] <capabilities> <file[s]>
60 # @DESCRIPTION:
61 # Sets the specified capabilities on the specified files.
62 #
63 # The caps option takes the form as expected by the cap_from_text(3) man page.
64 # If no action is specified, then "=ep" will be used as a default.
65 #
66 # If the file is a relative path (e.g. bin/foo rather than /bin/foo), then the
67 # appropriate path var ($D/$ROOT/etc...) will be prefixed based on the current
68 # ebuild phase.
69 #
70 # The caps mode (default 711) is used to set the permission on the file if
71 # capabilities were properly set on the file.
72 #
73 # 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
75 # are root:root and 4711. Otherwise, the ownership and permissions will be
76 # unchanged.
77 fcaps() {
78 debug-print-function ${FUNCNAME} "$@"
79
80 # Process the user options first.
81 local owner='root'
82 local group='root'
83 local mode='4711'
84 local caps_mode='711'
85
86 while [[ $# -gt 0 ]] ; do
87 case $1 in
88 -o) owner=$2; shift;;
89 -g) group=$2; shift;;
90 -m) mode=$2; shift;;
91 -M) caps_mode=$2; shift;;
92 *) break;;
93 esac
94 shift
95 done
96
97 [[ $# -lt 2 ]] && die "${FUNCNAME}: wrong arg count"
98
99 local caps=$1
100 [[ ${caps} == *[-=+]* ]] || caps+="=ep"
101 shift
102
103 local root
104 case ${EBUILD_PHASE} in
105 compile|install|preinst)
106 root=${ED:-${D}}
107 ;;
108 postinst)
109 root=${EROOT:-${ROOT}}
110 ;;
111 esac
112
113 # Process every file!
114 local file
115 for file ; do
116 [[ ${file} != /* ]] && file="${root}${file}"
117
118 if use filecaps ; then
119 # Try to set capabilities. Ignore errors when the
120 # fs doesn't support it, but abort on all others.
121 debug-print "${FUNCNAME}: setting caps '${caps}' on '${file}'"
122
123 # If everything goes well, we don't want the file to be readable
124 # by people.
125 chmod ${caps_mode} "${file}" || die
126
127 # Set/verify funcs for sys-libs/libcap.
128 _libcap() { setcap "${caps}" "${file}" ; }
129 _libcap_verify() { setcap -v "${caps}" "${file}" >/dev/null ; }
130
131 # Set/verify funcs for sys-libs/libcap-ng.
132 # Note: filecap only supports =ep mode.
133 # It also expects a different form:
134 # setcap cap_foo,cap_bar
135 # filecap foo bar
136 _libcap_ng() {
137 local caps=",${caps%=ep}"
138 filecap "${file}" "${caps//,cap_}"
139 }
140 _libcap_ng_verify() {
141 # libcap-ng has a crappy interface
142 local rcaps icaps caps=",${caps%=ep}"
143 rcaps=$(filecap "${file}" | \
144 sed -nr \
145 -e "s:^.{${#file}} +::" \
146 -e 's:, +:\n:g' \
147 -e 2p | \
148 LC_ALL=C sort)
149 [[ ${PIPESTATUS[0]} -eq 0 ]] || return 1
150 icaps=$(echo "${caps//,cap_}" | LC_ALL=C sort)
151 [[ ${rcaps} == ${icaps} ]]
152 }
153
154 local out cmd notfound=0
155 for cmd in _libcap _libcap_ng ; do
156 if ! out=$(LC_ALL=C ${cmd} 2>&1) ; then
157 case ${out} in
158 *"command not found"*)
159 : $(( ++notfound ))
160 continue
161 ;;
162 *"Operation not supported"*)
163 local fstype=$(stat -f -c %T "${file}")
164 ewarn "Could not set caps on '${file}' due to missing filesystem support."
165 ewarn "Make sure you enable XATTR support for '${fstype}' in your kernel."
166 ewarn "You might also have to enable the relevant FS_SECURITY option."
167 break
168 ;;
169 *)
170 eerror "Setting caps '${caps}' on file '${file}' failed:"
171 eerror "${out}"
172 die "could not set caps"
173 ;;
174 esac
175 else
176 # Sanity check that everything took.
177 ${cmd}_verify || die "Checking caps '${caps}' on '${file}' failed"
178
179 # Everything worked. Move on to the next file.
180 continue 2
181 fi
182 done
183 if [[ ${notfound} -eq 2 ]] && [[ -z ${__FCAPS_WARNED} ]] ; then
184 __FCAPS_WARNED="true"
185 ewarn "Could not find cap utils; make sure libcap or libcap-ng is available."
186 fi
187 fi
188
189 # If we're still here, setcaps failed.
190 debug-print "${FUNCNAME}: setting owner/mode on '${file}'"
191 chown "${owner}:${group}" "${file}" || die
192 chmod ${mode} "${file}" || die
193 done
194 }
195
196 # @FUNCTION: fcaps_pkg_postinst
197 # @DESCRIPTION:
198 # Process the FILECAPS array.
199 fcaps_pkg_postinst() {
200 local arg args=()
201 for arg in "${FILECAPS[@]}" "--" ; do
202 if [[ ${arg} == "--" ]] ; then
203 fcaps "${args[@]}"
204 args=()
205 else
206 args+=( "${arg}" )
207 fi
208 done
209 }
210
211 EXPORT_FUNCTIONS pkg_postinst
212
213 fi

  ViewVC Help
Powered by ViewVC 1.1.20