Lines 287-321
Link Here
|
287 |
eerror "${FUNCNAME}: IMAGE is unset" |
287 |
eerror "${FUNCNAME}: IMAGE is unset" |
288 |
return 1 |
288 |
return 1 |
289 |
fi |
289 |
fi |
290 |
# total suid control. |
290 |
|
291 |
if hasq suidctl $FEATURES; then |
291 |
### |
292 |
sfconf=/etc/portage/suidctl.conf |
292 |
### Controls permissions of files with SetId permissions. |
293 |
vecho ">>> Performing suid scan in ${IMAGE}" |
293 |
### |
294 |
for i in $(find ${IMAGE}/ -type f \( -perm -4000 -o -perm -2000 \) ); do |
294 |
### Todo: |
295 |
if [ -s "${sfconf}" ]; then |
295 |
### - Add a bit of flexibility to the file format (comments everywhere, |
296 |
suid="$(grep ^${i/${IMAGE}/}$ ${sfconf})" |
296 |
### decorating spaces, and maybe allow space characters |
297 |
if [ "${suid}" = "${i/${IMAGE}/}" ]; then |
297 |
### as field separators... -the file is grealty easier to read |
298 |
vecho "- ${i/${IMAGE}/} is an approved suid file" |
298 |
### with tabulations, though the line length greatly increase...). |
|
|
299 |
### - Maybe support empty fields (they would match any value...), though it |
300 |
### greatly diminishes the usefulness of the setid-control feature. |
301 |
### - Maybe support more flexible file permissions (like "ugo-s", |
302 |
### for the last field -well, for now, it works out of the box, |
303 |
### but we might try some checks on this field, so we me think a bit |
304 |
### about it). |
305 |
### - Maybe support to configure the user and group to set, |
306 |
### for full customization... |
307 |
### - Maybe add a check to inform the user when an entry is outdated and |
308 |
### might be removed (like the original file |
309 |
### does not have SetId permissions set anymore). |
310 |
### |
311 |
|
312 |
### Defines miscellaneous needed variables. |
313 |
local SetId_control_feature_name="setid-control" |
314 |
local SetId_control_configuration_file_path="/etc/portage/setid-control.conf" |
315 |
local SetId_permissions_to_set_field_index="6" |
316 |
|
317 |
### Checks that the SetId control feature is activated. |
318 |
if hasq "${SetId_control_feature_name}" "${FEATURES}" |
319 |
then |
320 |
vecho ">>> Performing SetId scan in \"${IMAGE}\"..." |
321 |
|
322 |
### Loop on files with SetId permissions. |
323 |
for File_virtual_path in $(find "${IMAGE}/" -type f -perm -4000 -o -perm -2000) |
324 |
do |
325 |
### Defines variables for needed informations about the package and file. |
326 |
local Package_category_and_name="${CATEGORY}/${PN}" |
327 |
local File_absolute_path="${File_virtual_path#${IMAGE}}" |
328 |
local File_user=$(find "${File_virtual_path}" -printf "%u") ### "%u" means the file owner name or id |
329 |
local File_group=$(find "${File_virtual_path}" -printf "%g") ### "%g" means the file group name or id |
330 |
local File_permissions=$(find "${File_virtual_path}" -printf "%04m") ### "%04m" means the file permissions (with leading zeros) |
331 |
|
332 |
### Tries to match the file with existing entries |
333 |
### from the configuration file. Notes we do not care if |
334 |
### the configuration file does not exist, as it is handled later. |
335 |
### ("-m" means "--max-count"; "-E" means "--extended-regexp") |
336 |
### @todo Maybe check the fields individually, for customized |
337 |
### warning messages (well, probably overkill). |
338 |
### @todo For the regex ending, if there are spaces (though illegal |
339 |
### as per configuration file format specifications), |
340 |
### accept the line... as we do not use the |
341 |
### file permission field elsewhere, for now, this is ok, |
342 |
### but if we later parse the entry to get |
343 |
### the value of this field, the spaces will have |
344 |
### to be removed. |
345 |
Needed_entry_regex="${Package_category_and_name}:${File_virtual_path}:${File_user}:${File_group}:${File_permissions}([[:space:]]*|:.*)$" |
346 |
Authorization_entry=$(grep -m 1 -E "^${Needed_entry_regex}" "${SetId_control_configuration_file_path}") |
347 |
|
348 |
### Checks if the file matched an existing entry |
349 |
### from the configuration file. |
350 |
if [ -n "${Authorization_entry}" ] |
351 |
then |
352 |
### Gets the file permissions to set, from |
353 |
### the authorization entry, if present. |
354 |
### ("-d" means "--delimiter"; "-f" means "--fields") |
355 |
File_permissions_to_set=$(echo "${Authorization_entry}" | cut -d ":" -f "${SetId_permissions_to_set_field_index}") |
356 |
|
357 |
### Keeps the file permissions as is, if |
358 |
### the file permission to set field is not present, or empty, |
359 |
### or identical to the file original permissions. |
360 |
if [ -z "${File_permissions_to_set}" ] || [ "${File_permissions_to_set}" = "${File_permissions}" ] |
361 |
then |
362 |
vecho ">>> File \"${File_absolute_path}\" requested SetId permissions, and has been authorized to keep them, as per configuration." |
363 |
|
364 |
### Continues to the next file with SetId permissions. |
365 |
continue |
299 |
else |
366 |
else |
300 |
vecho ">>> Removing sbit on non registered ${i/${IMAGE}/}" |
367 |
vecho ">>> File \"${File_absolute_path}\" requested SetId permissions, and is registered, so we will apply the configuration..." |
301 |
for x in 5 4 3 2 1 0; do echo -ne "\a"; sleep 0.25 ; done |
368 |
|
302 |
vecho -ne "\a" |
369 |
### Sets the file permission, as per configuration. |
303 |
ls_ret=$(ls -ldh "${i}") |
370 |
### @todo Sanity checks on file permissions to set? |
304 |
chmod ugo-s "${i}" |
371 |
chmod "${File_permissions_to_set}" "${File_virtual_path}" |
305 |
grep ^#${i/${IMAGE}/}$ ${sfconf} > /dev/null || { |
372 |
|
306 |
# sandbox prevents us from writing directly |
373 |
File_set_permissions=$(find "${File_virtual_path}" -printf "%04m") ### "%04m" means the file permissions (with leading zeros) |
307 |
# to files outside of the sandbox, but this |
374 |
|
308 |
# can easly be bypassed using the addwrite() function |
375 |
vecho ">>> File \"${File_absolute_path}\" now has permissions: \"${File_set_permissions}\" (previously: \"${File_permissions}\")." |
309 |
addwrite "${sfconf}" |
376 |
|
310 |
vecho ">>> Appending commented out entry to ${sfconf} for ${PF}" |
377 |
### Continues to the next file with SetId permissions. |
311 |
echo "## ${ls_ret%${IMAGE}*}${ls_ret#*${IMAGE}}" >> ${sfconf} |
378 |
continue |
312 |
echo "#${i/${IMAGE}/}" >> ${sfconf} |
|
|
313 |
# no delwrite() eh? |
314 |
# delwrite ${sconf} |
315 |
} |
316 |
fi |
379 |
fi |
|
|
380 |
|
381 |
#Checks that the file owner, group and permissions, match. |
317 |
else |
382 |
else |
318 |
vecho "suidctl feature set but you are lacking a ${sfconf}" |
383 |
vecho ">>> File \"${File_absolute_path}\" requested SetId permissions, but is unregistered, so we will strip them..." |
|
|
384 |
|
385 |
### Removes the SetId permissions from the file. |
386 |
chmod ugo-s "${File_virtual_path}" |
387 |
|
388 |
### Defines the secure SetId permissions (ie., no SetId permissions). |
389 |
Secure_SetId_permissions=$(find "${File_virtual_path}" -printf "%04m") ### "%04m" means the file permissions (with leading zeros) |
390 |
|
391 |
### Constructs a configuration file default (secure) entry for the current file. |
392 |
Default_entry="${Package_category_and_name}:${File_absolute_path}:${File_user}:${File_group}:${File_permissions}:${Secure_SetId_permissions}" |
393 |
|
394 |
### Creates the configuration file parent directory, if needed. |
395 |
if [ ! -d $(dirname "${SetId_control_configuration_file_path}") ] |
396 |
then |
397 |
addwrite "/" ### Sandbox bypassing |
398 |
mkdir -p $(dirname "${SetId_control_configuration_file_path}") |
399 |
export SANDBOX_WRITE="${SANDBOX_WRITE%:/}" ### Sandbox restoring |
400 |
fi |
401 |
|
402 |
### Creates a base configuration files, if not present (for the comments on the file format). |
403 |
if [ ! -f "${SetId_control_configuration_file_path}" ] |
404 |
then |
405 |
SetId_control_default_configuration_file_path="/usr/share/portage/setid-control.conf.default" ### !!! Place it elsewhere? (directly in "/etc/portage"? -without the ".default" suffix-, in which case this block should be removed) |
406 |
addwrite "${SetId_control_configuration_file_path}" ### Sandbox bypassing |
407 |
cp "${SetId_control_default_configuration_file_path}" "${SetId_control_configuration_file_path}" |
408 |
export SANDBOX_WRITE="${SANDBOX_WRITE%:${SetId_control_configuration_file_path}}" ### Sandbox restoring |
409 |
fi |
410 |
|
411 |
### Adds the default entry to the configuration file. |
412 |
addwrite "${SetId_control_configuration_file_path}" ### Sandbox bypassing |
413 |
echo "${Default_entry}" >> "${SetId_control_configuration_file_path}" |
414 |
export SANDBOX_WRITE="${SANDBOX_WRITE%:${SetId_control_configuration_file_path}}" ### Sandbox restoring |
415 |
|
416 |
### Displays a warning. |
417 |
ebeep 3 && epause 5 |
418 |
ewarn |
419 |
ewarn "You have the \"${SetId_control_feature_name}\" feature set in your \"/etc/make.conf\" file," |
420 |
ewarn "and the current package requests SetId permissions for the file:" |
421 |
ewarn "\"${File_absolute_path}\"," |
422 |
ewarn "which cannot be found in the SetId control configuration file." |
423 |
ewarn |
424 |
ewarn "If you already have an entry, for the same package and file path," |
425 |
ewarn "it probably means that the file user, group, or original permissions," |
426 |
ewarn "have changed. In this case, check the default entry which was added" |
427 |
ewarn "to the configuration file, and adapt your configuration as needed." |
428 |
ewarn |
429 |
ewarn "The following default (secure) entry was added to the configuration file" |
430 |
ewarn "(${SetId_control_configuration_file_path}):" |
431 |
ewarn "${Default_entry}" |
432 |
ewarn |
433 |
ewarn "The file has been stripped from its SetId permissions. If know what" |
434 |
ewarn "you are doing, and want \`emerge\` to keep these permissions, follow" |
435 |
ewarn "the instructions from the SetId control configuration file." |
436 |
ewarn |
437 |
|
438 |
### Continues to the next file with SetId permissions. |
439 |
continue |
319 |
fi |
440 |
fi |
320 |
done |
441 |
done |
321 |
fi |
442 |
fi |