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

Contents of /eclass/fcaps.eclass

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.11 - (hide annotations) (download)
Wed Feb 18 16:11:53 2015 UTC (3 months ago) by vapier
Branch: MAIN
CVS Tags: HEAD
Changes since 1.10: +4 -2 lines
clarify USE=filecaps intention #540430

1 vapier 1.11 # Copyright 1999-2015 Gentoo Foundation
2 vapier 1.1 # Distributed under the terms of the GNU General Public License v2
3 vapier 1.11 # $Header: /var/cvsroot/gentoo-x86/eclass/fcaps.eclass,v 1.10 2014/07/31 10:21:05 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 vapier 1.11 # This is not the same as USE=caps which controls runtime capability changes,
13     # often via packages like libcap.
14 vapier 1.1 #
15     # Due to probable capability-loss on moving or copying, this happens in
16     # pkg_postinst-phase (at least for now).
17     #
18     # @EXAMPLE:
19     # You can manually set the caps on ping and ping6 by doing:
20     # @CODE
21     # pkg_postinst() {
22     # fcaps cap_net_raw bin/ping bin/ping6
23     # }
24     # @CODE
25     #
26     # Or set it via the global ebuild var FILECAPS:
27     # @CODE
28     # FILECAPS=(
29     # cap_net_raw bin/ping bin/ping6
30     # )
31     # @CODE
32    
33 ulm 1.9 if [[ -z ${_FCAPS_ECLASS} ]]; then
34     _FCAPS_ECLASS=1
35 vapier 1.1
36     IUSE="+filecaps"
37    
38 vapier 1.7 # We can't use libcap-ng atm due to #471414.
39     DEPEND="filecaps? ( sys-libs/libcap )"
40 vapier 1.1
41     # @ECLASS-VARIABLE: FILECAPS
42     # @DEFAULT_UNSET
43     # @DESCRIPTION:
44     # An array of fcap arguments to use to automatically execute fcaps. See that
45     # function for more details.
46     #
47     # All args are consumed until the '--' marker is found. So if you have:
48     # @CODE
49     # FILECAPS=( moo cow -- fat cat -- chubby penguin )
50     # @CODE
51     #
52     # This will end up executing:
53     # @CODE
54     # fcaps moo cow
55     # fcaps fat cat
56     # fcaps chubby penguin
57     # @CODE
58     #
59     # Note: If you override pkg_postinst, you must call fcaps_pkg_postinst yourself.
60    
61     # @FUNCTION: fcaps
62 vapier 1.2 # @USAGE: [-o <owner>] [-g <group>] [-m <mode>] [-M <caps mode>] <capabilities> <file[s]>
63 vapier 1.1 # @DESCRIPTION:
64     # Sets the specified capabilities on the specified files.
65     #
66     # The caps option takes the form as expected by the cap_from_text(3) man page.
67     # If no action is specified, then "=ep" will be used as a default.
68     #
69     # If the file is a relative path (e.g. bin/foo rather than /bin/foo), then the
70     # appropriate path var ($D/$ROOT/etc...) will be prefixed based on the current
71     # ebuild phase.
72     #
73 vapier 1.2 # The caps mode (default 711) is used to set the permission on the file if
74     # capabilities were properly set on the file.
75     #
76 vapier 1.1 # If the system is unable to set capabilities, it will use the specified user,
77     # group, and mode (presumably to make the binary set*id). The defaults there
78 vapier 1.10 # are root:0 and 4711. Otherwise, the ownership and permissions will be
79 vapier 1.1 # unchanged.
80     fcaps() {
81     debug-print-function ${FUNCNAME} "$@"
82    
83     # Process the user options first.
84     local owner='root'
85 vapier 1.10 local group='0'
86 vapier 1.1 local mode='4711'
87 vapier 1.2 local caps_mode='711'
88 vapier 1.1
89     while [[ $# -gt 0 ]] ; do
90     case $1 in
91     -o) owner=$2; shift;;
92     -g) group=$2; shift;;
93     -m) mode=$2; shift;;
94 vapier 1.2 -M) caps_mode=$2; shift;;
95 vapier 1.1 *) break;;
96     esac
97     shift
98     done
99    
100     [[ $# -lt 2 ]] && die "${FUNCNAME}: wrong arg count"
101    
102     local caps=$1
103     [[ ${caps} == *[-=+]* ]] || caps+="=ep"
104     shift
105    
106     local root
107     case ${EBUILD_PHASE} in
108     compile|install|preinst)
109     root=${ED:-${D}}
110     ;;
111     postinst)
112     root=${EROOT:-${ROOT}}
113     ;;
114     esac
115    
116     # Process every file!
117 vapier 1.5 local file
118 vapier 1.1 for file ; do
119     [[ ${file} != /* ]] && file="${root}${file}"
120    
121     if use filecaps ; then
122     # Try to set capabilities. Ignore errors when the
123     # fs doesn't support it, but abort on all others.
124     debug-print "${FUNCNAME}: setting caps '${caps}' on '${file}'"
125    
126 vapier 1.2 # If everything goes well, we don't want the file to be readable
127     # by people.
128     chmod ${caps_mode} "${file}" || die
129    
130 vapier 1.5 # 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 vapier 1.6 LC_ALL=C sort)
152     [[ ${PIPESTATUS[0]} -eq 0 ]] || return 1
153 vapier 1.5 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
159     if ! out=$(LC_ALL=C ${cmd} 2>&1) ; 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 vapier 1.8 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 vapier 1.5 break
172     ;;
173     *)
174     eerror "Setting caps '${caps}' on file '${file}' failed:"
175     eerror "${out}"
176     die "could not set caps"
177     ;;
178     esac
179     else
180     # Sanity check that everything took.
181     ${cmd}_verify || die "Checking caps '${caps}' on '${file}' failed"
182    
183     # Everything worked. Move on to the next file.
184     continue 2
185     fi
186     done
187 ulm 1.9 if [[ ${notfound} -eq 2 ]] && [[ -z ${_FCAPS_WARNED} ]] ; then
188     _FCAPS_WARNED="true"
189 vapier 1.5 ewarn "Could not find cap utils; make sure libcap or libcap-ng is available."
190 vapier 1.1 fi
191     fi
192    
193     # If we're still here, setcaps failed.
194     debug-print "${FUNCNAME}: setting owner/mode on '${file}'"
195     chown "${owner}:${group}" "${file}" || die
196     chmod ${mode} "${file}" || die
197     done
198     }
199    
200     # @FUNCTION: fcaps_pkg_postinst
201     # @DESCRIPTION:
202     # Process the FILECAPS array.
203     fcaps_pkg_postinst() {
204     local arg args=()
205     for arg in "${FILECAPS[@]}" "--" ; do
206     if [[ ${arg} == "--" ]] ; then
207     fcaps "${args[@]}"
208     args=()
209     else
210     args+=( "${arg}" )
211     fi
212     done
213     }
214    
215     EXPORT_FUNCTIONS pkg_postinst
216    
217     fi

  ViewVC Help
Powered by ViewVC 1.1.20