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

Reply via email to