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

Contents of /eclass/fcaps.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.7 - (hide annotations) (download)
Sun Jun 2 15:21:04 2013 UTC (15 months, 2 weeks ago) by vapier
Branch: MAIN
Changes since 1.6: +3 -2 lines
force libcap until the libcap-ng bugs can get sorted out #471414

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

  ViewVC Help
Powered by ViewVC 1.1.20