Package: fakechroot Version: 2.17.2-1 Severity: normal Tags: patch Dear Maintainer,
The command chfn fails in a fakechroot environment : it is setuid root, and the variable LD_LIBRARY_PATH is ignored. As a result, it tries to alter /etc/passwd outside of the (fake)chroot and fails because of insufficient permissions. This prevents the installation of avahi-daemon, colord, usbmuxd and logcheck : # aptitude install avahi-daemon ... Setting up avahi-daemon (0.6.31-4) ... chfn: PAM: System error adduser: `/usr/bin/chfn -f Avahi mDNS daemon avahi' returned error code 1. Exiting. dpkg: error processing package avahi-daemon (--configure): subprocess installed post-installation script returned error exit status 1 ... (in the (fake)chroot : # cat /usr/sbin/policy-rc.d #!/bin/sh exit 101 # cat /sbin/start-stop-daemon #!/bin/sh echo echo "Warning: Fake start-stop-daemon called, doing nothing") Is it possible to add a replacement for chfn ? Here is a (unoptimized !) example : it just changes /etc/passwd inside of the (fake)chroot (no need of setuid/setgid). Regards, JH Chatenet *** rustine14.patch diff -Naur a/scripts/chfn.fakechroot.sh b/scripts/chfn.fakechroot.sh --- a/scripts/chfn.fakechroot.sh 1970-01-01 01:00:00.000000000 +0100 +++ b/scripts/chfn.fakechroot.sh 2014-04-14 21:51:42.000000000 +0200 @@ -0,0 +1,181 @@ +#!@SHELL@ + +# chfn +# +# Replacement for chfn command which changes a gecos field in +# etc/passwd under the (fake)chroot. There is no locking and no permission check. + +which_option() { + option_name="$1" + option_value="$2" + case $option_name in + -f|--full-name) + has_new_name=1 + new_name="$(echo $option_value|tr -d ':,=')" + ;; + -h|--home-phone) + has_new_home_phone=1 + new_home_phone="$(echo $option_value|tr -d ':,=')" + ;; + -o|--other) + has_new_other=1 + new_other="$(echo $option_value|tr -d ':')" + ;; + -r|--room) + has_new_room=1 + new_room="$(echo $option_value|tr -d ':,=')" + ;; + -R|--root) + has_root=1 + root="$option_value" + ;; + -w|--work-phone) + has_new_work_phone=1 + new_work_phone="$(echo $option_value|tr -d ':,=')" + ;; + esac +} + +parse_gecos_field() { + gecos_field="$1" + + old_name="${gecos_field%%,*}" + gecos_field="${gecos_field#$old_name}" + + if [ -z "$gecos_field" ]; then + return + else + gecos_field="${gecos_field#,}" + fi + + old_room="${gecos_field%%,*}" + gecos_field="${gecos_field#$old_room}" + gecos_field="${gecos_field#,}" + + old_work_phone="${gecos_field%%,*}" + gecos_field="${gecos_field#$old_work_phone}" + gecos_field="${gecos_field#,}" + + old_home_phone="${gecos_field%%,*}" + gecos_field="${gecos_field#$old_home_phone}" + gecos_field="${gecos_field#,}" + + if [ -n "$gecos_field" ]; then + has_old_other=1 + old_other="$gecos_field" + fi +} + +while [ $# -gt 0 ]; do + case $1 in + -u|--help) + echo "fakechroot : replacement of chfn" + chfn -u + exit 0 + ;; + -f|--full-name|-h|--home-phone|-o|--other|-r|--room|-R|--root|-w|--work-phone) + option_name="$1" + option_value="$2" + which_option "$option_name" "$option_value" + shift 2 + ;; + --full-name=*|--home-phone=*|--other=*|--room=*|--root=*|--work-phone=*) + option_name="${1%%=*}" + option_value="${1#*=}" + which_option "$option_name" "$option_value" + shift + ;; + -f*|-h*|-o*|-r*|-R*|-w*) + option_value="${1#-?}" + option_name="${1%$option_value}" + which_option "$option_name" "$option_value" + shift + ;; + --) + shift + break + ;; + *) + break + ;; + esac +done + +if [ $# -gt 0 ]; then + user="$1" +else + user=$(id -u -n) +fi + + +# Where is the root ? +if [ -n "$root" ]; then + if [ "${root#/}" != "$root" ]; then + root="${FAKECHROOT_BASE_ORIG}${root}" + fi +else + root="$FAKECHROOT_BASE_ORIG" +fi + +if [ ! -e "$root/etc/passwd" ]; then + echo "fakechroot chfn replacement : $root/etc/passwd : no such file" >&2 + exit 1 +fi + +# Is there such user ? +grep -q "^${user}:" "$root/etc/passwd" +ret=$? + +if [ $ret -eq 1 ]; then + echo "fakechroot chfn replacement : $user : no such user" >&2 + exit 2 +elif [ $ret -eq 2 ]; then + echo "fakechroot chfn replacement : grep error" >&2 + exit 3 +fi + +# What is the old gecos field ? +old_gecos_field=$(sed -n "/^${user}/ {s/^\([^:]*:\)\{4\}\([^:]*\):.*$/\2/;p;q}" "$root/etc/passwd") + +parse_gecos_field "$old_gecos_field" + +# Assemble new gecos + +if [ -n "$has_new_name" ]; then + new_gecos_field="$new_name" +else + new_gecos_field="$old_name" +fi + +if [ -n "$has_new_room" ]; then + new_gecos_field="${new_gecos_field},$new_room" +else + new_gecos_field="${new_gecos_field},$old_room" +fi + +if [ -n "$has_new_work_phone" ]; then + new_gecos_field="${new_gecos_field},$new_work_phone" +else + new_gecos_field="${new_gecos_field},$old_work_phone" +fi + +if [ -n "$has_new_home_phone" ]; then + new_gecos_field="${new_gecos_field},$new_home_phone" +else + new_gecos_field="${new_gecos_field},$old_home_phone" +fi + +if [ -n "$has_new_other" ]; then + new_gecos_field="${new_gecos_field},$new_other" +elif [ -n "$has_old_other" ]; then + new_gecos_field="${new_gecos_field},$old_other" +fi + +name_only="${new_gecos_field%%,*}" + +if [ "${new_gecos_field#$name_only}" = ",,," ]; then + new_gecos_field="$name_only" +fi + +# New /etc/passwd +sed -i "s/^\(${user}:\([^:]*:\)\{3\}\)\([^:]*\)/\1${new_gecos_field}/" "$root/etc/passwd" diff -Naur a/scripts/chroot.env.sh b/scripts/chroot.env.sh --- a/scripts/chroot.env.sh 2014-04-15 17:31:38.000000000 +0200 +++ b/scripts/chroot.env.sh 2014-04-17 08:26:46.000000000 +0200 @@ -10,6 +10,7 @@ fakechroot_chroot_env_cmd_subst="" for fakechroot_chroot_env_d in `echo $PATH | tr ':' ' '`; do fakechroot_chroot_env_cmd_subst="$fakechroot_chroot_env_cmd_subst + $fakechroot_chroot_env_d/chfn=@bindir@/chfn.fakechroot $fakechroot_chroot_env_d/chroot=@sbindir@/chroot.fakechroot $fakechroot_chroot_env_d/env=@bindir@/env.fakechroot $fakechroot_chroot_env_d/ischroot=/bin/true diff -Naur a/scripts/Makefile.am b/scripts/Makefile.am --- a/scripts/Makefile.am 2014-04-15 17:26:38.000000000 +0200 +++ b/scripts/Makefile.am 2014-04-17 08:27:34.000000000 +0200 @@ -1,10 +1,10 @@ sysconfdir = @sysconfdir@/@PACKAGE@ -src_wrappers = chroot.fakechroot.sh env.fakechroot.sh fakechroot.sh ldd.fakechroot.pl +src_wrappers = chfn.fakechroot.sh chroot.fakechroot.sh env.fakechroot.sh fakechroot.sh ldd.fakechroot.pl src_envs = chroot.env.sh debootstrap.env.sh rinse.env.sh example_scripts = relocatesymlinks.sh restoremode.sh savemode.sh -bin_SCRIPTS = env.fakechroot fakechroot ldd.fakechroot +bin_SCRIPTS = chfn.fakechroot env.fakechroot fakechroot ldd.fakechroot sbin_SCRIPTS = chroot.fakechroot sysconf_DATA = chroot.env debootstrap.env rinse.env @@ -26,6 +26,10 @@ -e 's,[@]SHELL[@],$(SHELL),g' \ -e 's,[@]VERSION[@],$(VERSION),g' +chfn.fakechroot: $(srcdir)/chfn.fakechroot.sh + $(do_subst) < $(srcdir)/chfn.fakechroot.sh> $@ + chmod +x $@ + chroot.env: $(srcdir)/chroot.env.sh $(do_subst) < $(srcdir)/chroot.env.sh > $@ chmod +x $@ -- System Information: Debian Release: jessie/sid APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 2.6.32-5-amd64 (SMP w/2 CPU cores) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Shell: /bin/sh linked to /bin/dash Versions of packages fakechroot depends on: ii libfakechroot 2.17.2-1 fakechroot recommends no packages. fakechroot suggests no packages. -- no debconf information -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org