r905 - in trunk: . ATTACHMENTS ATTACHMENTS/more_control_and_pkg_man MAINTAINER OLD PREVIOUS_FORMAT

tushar at linuxfromscratch.org tushar at linuxfromscratch.org
Wed Nov 3 21:13:08 PST 2004


Author: tushar
Date: 2004-11-03 22:13:06 -0700 (Wed, 03 Nov 2004)
New Revision: 905

Added:
   trunk/ATTACHMENTS/more_control_and_pkg_man/
   trunk/ATTACHMENTS/more_control_and_pkg_man/more_control_helpers.tar.bz2
   trunk/OLD/more_control_and_pkg_man.txt
   trunk/more_control_and_pkg_man.txt
Removed:
   trunk/PREVIOUS_FORMAT/more_control_and_pkg_man.txt
Modified:
   trunk/MAINTAINER/STATUS
Log:
Update Hint: more_control_and_pkg_man

Added: trunk/ATTACHMENTS/more_control_and_pkg_man/more_control_helpers.tar.bz2
===================================================================
(Binary files differ)


Property changes on: trunk/ATTACHMENTS/more_control_and_pkg_man/more_control_helpers.tar.bz2
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Modified: trunk/MAINTAINER/STATUS
===================================================================
--- trunk/MAINTAINER/STATUS	2004-11-01 06:57:29 UTC (rev 904)
+++ trunk/MAINTAINER/STATUS	2004-11-04 05:13:06 UTC (rev 905)
@@ -46,7 +46,6 @@
    * lyx: No response from author.
    * lzw_graphics: No response from author.
    * metalog: Could not contact author.
-   * more_control_and_pkg_man: Conversion in progress.
    * newbie: No response from author.
    * nfs: No response from author.
    * openssh_remote_floppy: No response from author.

Added: trunk/OLD/more_control_and_pkg_man.txt
===================================================================
--- trunk/OLD/more_control_and_pkg_man.txt	2004-11-01 06:57:29 UTC (rev 904)
+++ trunk/OLD/more_control_and_pkg_man.txt	2004-11-04 05:13:06 UTC (rev 905)
@@ -0,0 +1,1496 @@
+TITLE:		More control and package management using package users (v0.8)
+LFS VERSION:	3.1 (should work with later versions with minor changes)
+AUTHOR:		Matthias S. Benkmann <m.s.b at gmx.net>
+
+SYNOPSIS:
+	-You want to know which packages your files belong to ?
+	-You want to deinstall software that doesn't have make uninstall ?
+	-You are bothered by programs installed setuid root behind your back ?
+	-You don't want packages to overwrite files from other packages ?
+	-You don't like package managers like RPM ?
+	-YOU WANT TOTAL CONTROL USING ONLY UNIX BUILTINS ?
+
+HINT:
+
+LEGALESE: The author does not take responsibility for any damage of any kind
+caused directly or indirectly by applying the methods described below. 
+There is no warranty of any kind, not even the implied warranty of fitness for
+the purposes mentioned in the text, on any of the programs/scripts/commands 
+listed below and the author may not be held liable for any damage of any kind 
+caused by the execution of said programs/scripts/commands.
+Proceed at your own risk!
+
+########################################################################### 
+ Changelog
+###########################################################################
+
+2002-01-30  -added Changelog
+            -moved "chown 0.10000 `cat /tmp/installdirs`" command up (before
+             glibc package user is created)
+            -add_package_user: create home directory with "mkdir -p"
+                               use $grpfile everywhere instead of /etc/group
+            -improved mammoth sentence in Introduction
+            -added note about possibility to have user name==group name
+            -source bashrc_basic in bashrc_package
+            -minor textual changes
+
+2002-02-18
+            -added section "Security issues with NFS"
+            -submitted v0.7
+            
+2002-03-16  -added note, that on Linux make doesn't need to be setgid kmem
+
+2002-04-20
+            -changed LFS VERSION header to be more conservative
+            -added <br> tags to the synopsis for the sake of the hints 
+             index
+            -added group mmedia to the list of suggested groups 
+            -submitted v0.8
+            
+
+
+########################################################################### 
+ Introduction
+###########################################################################
+
+Let's say I have written a program that you would like to use. To make it
+easier for you I come over to install it for you. Would you give me the root
+account and then leave the room ? No ? Then why do you give it to complete
+strangers who you have never seen in your life, to install software packages
+pulled from some Internet server, that come with no warranty and don't even 
+list their contents in the README, although they will happily spread them all 
+over your system ?
+It is a mystery why Unix admins who wouldn't even trust their employer with
+more than a normal user account carelessly execute complex and incomprehensible
+installation scripts with full root rights.
+
+Users and groups are the basic security principle in a Unix system. They have
+been used successfully for a long time to control who has created a file and 
+who is allowed to delete or change this file. But this control has only been
+imposed on the files of ordinary users. What a waste! I suggest to extend
+this control to all system files.
+
+
+#############################################################################
+ Package users
+#############################################################################
+
+The basic idea of this scheme is easily explained. Every package belongs to a 
+certain "package user". This is a special user account whose HOME directory
+is /usr/src/<package> (or wherever you keep the tarballs for the package).
+Usually this account has no password so that only root can su to a package 
+user, which ensures that package users do not open an additional way into the 
+system and undermine security.
+Of course you *may* set passwords anyway to allow a co-admin who you want to
+be able to install and maintain certain software packages to do so without 
+having access to the actual root account. This co-admin could for instance
+install, delete, change additional libraries which might be necessary for his
+workgroup. He would be unable, though, to remove or modify libraries which 
+don't belong to him/her, such as libc.
+
+Every package user has a primary group that reflects the purpose of the
+package, such as "system" for essential packages, "devel" for packages
+related to software development and so on. There are other useful
+organizational schemes, of course. You might want to have the group reflect
+the workgroup of the above-mentioned co-admin who installed the file for 
+instance. Another possibility is to create a new group for every package
+user with the same name as the user name. That way, even if a file needs to
+be setuid root (and consequently has to be owned by root), the group of the
+file tells you about the package where it originates. 
+
+In addition to the primary group, there is the secondary group which is the
+same for all package users. This is the "install" group. All directories
+that packages are allowed to install stuff in belong to the install group.
+This includes directories such as /bin and /usr/bin but excludes directories
+like /root or /. The directories owned by the install group are always
+group-writeable. Without further preparation this does not give added security
+or control because every package could replace the files from a different
+package (the change would be visible in the output from ls -la, though).
+For this reason we make all install directories sticky. The sticky attribute
+allows users to create new files and delete or modify their own files in
+the directory while preventing them from writing or deleting files from other
+users.
+
+
+############################################################################
+ How to install software
+############################################################################
+
+Isn't this all very tedious ? Not if you use this script:
+
+-------------------- begin $LFS/sbin/install_package ------------------------
+#!/bin/sh
+if [ $# -ne 3 ]; then
+echo USAGE: install_package description name group
+echo "!!Don't forget to put description in quotes if it contains spaces.!!"
+echo "This will create a new package user name in group. This will set up"
+echo "a home directory for this package user. After that, this script will"
+echo "automatically su to the new user so that you can begin with the"
+echo "installation right away. "
+exit 1
+fi
+
+if [ $UID -ne 0 ]; then echo Please run this script as root. ; exit 1; fi
+add_package_user "${1}" $2 10000 20000 $3 10000 20000 || exit 1
+su $2
+------------------- end $LFS/sbin/install_package ----------------------------
+
+The above script is a shortcut for the following script, which does the
+actual adding of the package user in a certain range of UIDs and GIDs:
+
+-------------------- begin $LFS/sbin/add_package_user -----------------------
+#!/bin/sh
+
+if [ $# -lt 7 ]; then
+echo 'Copyright (c) 2000 Matthias Benkmann'
+echo 'USAGE: '
+echo 'add_package_user description name minuid maxuid group mingid maxgid [-d home]'
+echo 
+echo Don\'t forget to put description in quotes. 
+echo description must be valid for a /etc/passwd entry, that means especially
+echo that it must not contain \":\".
+echo If group doesn\'t exist, it will be added. 
+echo group will be the user\'s main group. 
+echo 'The user will also belong to group "install" (created if necessary).'
+echo 'A home directory /usr/src/name (or home if -d home specified) 
+echo will be created if it doesn\'t exist
+echo 'and the files from /etc/skel-package will be copied into it (existing'
+echo 'target files will *not* be overwritten)'
+echo 'minuid (incl.) and maxuid (excl.)  determine'
+echo 'the range of UIDs used by this script. The script will pick the first'
+echo 'UID greater than all UIDs from this range already in use.' 
+echo 'If that UID is out of range (i.e. equal to maxuid), the'
+echo 'script will pick the first available UID in this range. If the range is'
+echo 'full, the script will give up. This process ensures that UIDs for packages'
+echo that have been removed, don\'t get reassigned unless really necessary.
+echo 'This avoids trouble if some files were overlooked when removing the package.'
+echo 'Otherwise these files might be assigned to the wrong package.'
+echo 'mingid (incl.) and maxgid (excl.) define'
+echo 'the permissible range for the GID of group if it has to be added (and '
+echo 'the install group if it must be added).'
+exit 1
+fi
+
+grpfile=/etc/group
+passwd=/etc/passwd
+homebase=/usr/src
+skel=/etc/skel-package
+description=$1
+name=$2
+minuid=$3
+maxuid=$4
+gname=$5
+mingid=$6
+maxgid=$7
+home=$homebase/$name
+
+set -- "$@" _eNd_OF_lisT_
+while [ "$1" != "_eNd_OF_lisT_" ]; do
+  case "$1" in
+    -d) shift 1
+        if [ "$1" = "_eNd_OF_lisT_" ]; then
+          echo 1>&2 "-d directory name missing!"
+          exit 1
+        fi
+        home="$1"
+        shift 1
+        ;;
+    *) temp="$1" 
+       shift 1
+       set -- "$@" "$temp"
+       ;;
+  esac     
+done
+shift 1 #throw away _eNd_OF_lisT_
+
+if [ $UID -ne 0 ]; then echo Please run this script as root. ; exit 1; fi
+
+#test if user already exists
+grep "^$name:.*" $passwd
+if [ $? -eq 0 ]; then 
+  echo 'Package user does already exist! Do su '$name' to do maintenance work.'
+  exit 1
+fi 
+
+#test if minuid, maxuid, mingid and maxgid are integers, otherwise set
+#to defaults.
+error=0
+expr ${minuid} + 1 2>/dev/null 1>&2 || error=1
+expr ${maxuid} + 1 2>/dev/null 1>&2 || error=1
+expr ${mingid} + 1 2>/dev/null 1>&2 || error=1
+expr ${maxgid} + 1 2>/dev/null 1>&2 || error=1
+
+if [ $error -eq 1 ]; then
+  echo Error: Illegal numeric value!
+  exit 1
+fi
+
+if [ $minuid -ge $maxuid ]; then
+  echo 'Error: minuid must be less than maxuid !' 
+  exit 1
+fi
+
+if [ $mingid -ge $maxgid ]; then
+  echo 'Error: mingid must be less than maxgid !' 
+  exit 1
+fi
+
+
+uidlist=`cut -d : -f 3 $passwd | sort -n`
+
+#find last used UID within range
+u=0
+for i in $uidlist
+do
+  if [ $i -ge $maxuid ]; then break; fi
+  if [ $i -ge $minuid ]; then u=$i; fi 
+done
+
+#if no UID from the range is used, pick the first, otherwise pick the one
+#immediately following the last UID in use.
+if [ $u -eq 0 ]; then u=$minuid; else u=`expr $u + 1`; fi
+
+#if the last UID used from the range is maxuid-1, i.e. we may 
+#not use its successor as UID, then we look for the first unused uid
+#in the range.
+if [ $u -ge $maxuid ]; then
+  u=$minuid
+  for i in $uidlist
+  do
+    if [ $u -eq $i ]; then u=`expr $u + 1` ; fi
+    if [ $i -ge $maxuid ]; then break; fi
+  done  
+
+  if [ $u -ge $maxuid ]; then
+    echo Error: UID range is full!
+    exit 1
+  fi
+fi
+
+echo Will create user $name with uid: $u
+
+unset uidlist
+
+#############################################################################
+#                                 group
+#############################################################################
+
+#execute the following for gname and "install" to get gids for those 2 groups
+
+g=0
+creategroup=0
+for group in install $gname
+do
+  oldg=$g #save gid from previous run
+  createinstall=$creategroup
+  creategroup=0
+ 
+  #test if group already exists and extract gid if so
+  g=`grep ^${group}:.\* $grpfile | cut -d : -f 3 -`
+
+  #if group does not exist, then check range for a free gid
+  if [ z$g = z ]; then 
+    creategroup=1
+    
+    gidlist=`cut -d : -f 3 $grpfile | sort -n`
+
+    #find last used GID within range
+    g=0
+    for i in $gidlist
+    do
+      if [ $i -ge $maxgid ]; then break; fi
+      if [ $i -ge $mingid ]; then g=$i; fi
+    done
+
+    #if no GID from the range is used, pick the first, otherwise pick the one
+    #immediately following the last GID in use.
+    if [ $g -eq 0 ]; then g=$mingid; else g=`expr $g + 1`; fi
+    
+    #don't reuse gid from previous run 
+    if [ $g -eq $oldg ]; then g=`expr $g + 1`; fi
+
+    #if the last GID used from the range is maxgid-1, i.e. we may 
+    #not use its successor as GID, then we look for the first unused gid
+    #in the range.
+    if [ $g -ge $maxgid ]; then
+      g=$mingid
+      for i in $gidlist
+      do
+        if [ $g -eq $i ]; then g=`expr $g + 1` ; fi
+        if [ $g -eq $oldg ]; then g=`expr $g + 1` ; fi
+        if [ $i -ge $maxgid ]; then break; fi
+      done  
+
+      if [ $g -ge $maxgid ]; then
+        echo Error: GID range is full!
+        exit 1
+      fi
+    fi
+  fi
+done
+
+unset gidlist
+
+if [ $createinstall -eq 1 ]; then
+  echo Creating group install with gid $oldg
+  groupadd -g $oldg install || exit 1
+else
+  echo Group install has gid $oldg
+fi
+if [ $creategroup -eq 1 ]; then
+  echo Creating group $gname with gid $g
+  groupadd -g $g $gname || exit 1
+else 
+  echo Group $gname has gid $g
+fi
+
+
+
+useradd -c "${description}" -d ${home} -g ${gname} -G install \
+        -s /bin/bash -u ${u} ${name}  || exit 1
+
+mkdir -p $home || exit 1
+
+yes n|cp -ai -R ${skel}/{[^.],.[^.],..?}* ${home} 2>/dev/null >/dev/null
+
+cd ${home}
+chown --recursive ${u}.${g} .
+
+
+exit 0
+-------------------- end $LFS/sbin/add_package_user ------------------------
+
+
+If you use these scripts, you can install a new package like this
+
+install_package 'Foo description' foo foogroup
+
+and the package user foo will be created and you will automatically be su'd to 
+it and put into the package user's home directory. Now just copy the tarball
+from your download directory, untar and install. It's no more work than
+doing it as root.
+
+
+############################################################################
+ Pitfalls and Solutions
+############################################################################
+ 
+There are some pitfalls when you use this system. The following situations are
+common:
+
+1. A package install script is poorly written and insists on changing
+   ownership/permissions of system directories or its own files.
+   
+2. A package install script has a legitimate reason to change 
+   ownership/permissions of files it installs.
+   
+3. Package A contains a program that is also part of package B. Package B
+   was installed first.
+   
+4. A package tests if the user installing it is root and does not install
+   certain programs otherwise.
+   
+5. A package creates a directory that other packages need to write to.
+
+1-3 usually result in an "Operation not permitted" error during make install.
+Note that this is not actually a flaw of the package user scheme, it's a
+feature. It's the reason why we made the install directories sticky and use
+package users in the first place. We don't want stuff like this to happen
+without our (divine :-) intervention. Fixing these issues is usually easy:
+
+1. Look at the output from "make install". It will contain the offending
+   command such as "install --owner root foo /bin" right before the
+   "Operation not permitted" error. grep through the Makefiles of the package
+   and remove the offending switch (in this case "--owner foo"). 
+   Sometimes you may not want to remove it altogether but may need to change 
+   it to something harmless. For instance "install -m 4755 ..." which tries to 
+   set the setuid bit should be changed to "install -m 755 ...".
+   You can automate these changes with a sed script or use a wrapper script
+   around install (see below) to avoid having to manually change Makefiles.
+   Note that you either have to perform these changes *after* the configure
+   step or you have to modify the source Makefiles (usually Makefile.in or
+   Makefile.am).
+
+2. This is basically like 1 but in this case the package actually has a reason
+   (that you accept) for doing what it does. This is seldom but happens for
+   some packages that install setuid root programs that you want to have
+   setuid root, such as ping. In this case, act like in case 1 and execute
+   the appropriate changes manually as root afterwards,
+   such as chown root.root /bin/ping && chmod 4755 /bin/ping.
+   
+3. In this case you have to decide which package you actually want to provide
+   the program in question. If you want to replace package B's program with
+   that of package A, simply delete the program manually as root.
+   If you don't want package A to overwrite the program with its own,
+   grep through the Makefiles for the name of the program in question (and
+   its manpages). Usually you will find a list like
+   PROGRAMS=foo bar fubar barfu
+   and it is sufficient to remove the program from this list. In very rare
+   cases you may need to remove some "install <programname> <destination>"
+   lines from the Makefile.
+   
+4. This case is usually documented in the INSTALL file of the package and a 
+   make target to install the programs left out, such as "install-root", is 
+   provided. So this is not normally an issue.
+
+5. This case is easy to fix by assigning the directory in question to the 
+   install group and making it group-writeable and sticky. This does not even
+   have to be done as root. The package user who created the directory has the
+   permissions to do it. So you can insert an appropriate line into the 
+   Makefile.
+
+Manually changing Makefiles is annoying, even if it happens only occasionally.
+Sed scripts do help but they have to be custom fitted to every package that
+needs them. There is a better solution, though. While building LFS with the
+package user scheme, I have noticed that although there are a lot of possible
+things a Makefile could contain which would trigger an 
+"Operation not permitted" error, only few of them are actually used.
+So far I have only encountered these problems in connection with mkdir, chgrp,
+chown and install. 
+I have written the following scripts to handle them automatically. If you make
+sure the directory where these scripts are located (in my case /usr/src/lfs)
+is the first in the PATH for every package user, you should be able to install
+most LFS packages without having to fix any Makefiles manually. 
+
+ATTENTION! These wrapper scripts allow "make install" to complete without
+aborting due to "Operation not permitted" errors. However, some of the
+operations that are suppressed this way are legitimate (see 2. above).
+For that reason, the wrapper scripts output lines beginning with "***"
+to stderr that contain the original command that the installation wanted to
+execute. 
+You *must* check these lines and if it was a legitimate operation you have to
+take appropriate action manually or the programs in question will not
+work properly. The following is a list of things you should look for and
+what you have to do:
+
+1. "*** install -m 4xxx -o root" : This wants to make a binary setuid root.
+   The important thing here is "-m 4x". Many install scripts try to use
+   "install -m 755 -o root" or something similar. This can be ignored. The
+   owner (specified with "-o owner") is only important for binaries with mode
+   4xxx (specified with "-m 4xxx").  If you decide that the binary really 
+   should be setuid root (for the LFS base packages this is usually okay)
+   you have to do
+       chown root.root <binaryname>
+       chmod u+s <binaryname>
+
+2. "*** chgrp xxx" : This wants to change the group of a binary. This is
+   usually only done if a binary is made setgid. You will see that in the
+   output of "ls -l" like this
+   rwxr-sr-x   1 util-lin tty          8348 Dec  3  2000 write
+   The "s" in the group field tells you this is a setgid binary.
+   Right now the chgrp wrapper below only intercepts chgrp for xxx=tty
+   because that is the only thing needed for installing LFS. 
+   If such a call has been intercepted and you want the binary to be setgid,
+   you have to do the following:
+   	chgrp xxx <binaryname>
+   	chmod g+s <binaryname>
+
+TIP:
+    It is important that you check the error log religiously when installing
+    a package as a package user, especially if you use the scripts below.
+    
+    To make this easier, install like this
+    
+      make install 3>&1 1>&2 2>&3 | tee install.err
+      
+    This will give you the normal make output (i.e. errors and normal messages)
+    to the screen but in addition to that it will put a copy of all error 
+    messages into install.err. You can "cat install.err" after the installation
+    to examine error messages.
+    Note that "make install | tee install.err" does *not* work. This would
+    copy all normal messages *without* the errors.
+    
+    If you want to redirect screen output (i.e. the complete install log,
+    including errors and non-errors) to a file, do it like this
+
+      { make install 3>&1 1>&2 2>&3 | tee install.err ;} &>install.log
+
+    You should probably create a shell function for this to save you typing.
+
+
+Here are the wrapper scripts:
+
+------------- begin $LFS/usr/src/lfs/wrappers/mkdir --------------------------
+#!/bin/sh
+
+DAISY_CHAIN=""
+
+for p in $(type -ap mkdir) ; do
+  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
+done
+
+if [ ! -n "$DAISY_CHAIN" ]; then
+  echo Cannot find real ${0##*/} command 
+  exit 1
+fi
+
+if [ $UID == 0 ]; then
+  exec $DAISY_CHAIN "$@"
+fi
+
+watchdir=/usr/share/locale
+
+cmdline="$@"
+
+dirs=""
+for((i=$#; $i>0;))
+do
+  a="$1"
+  shift 1; i=$(($i-1))
+  case "$a" in
+    $watchdir/*) dirs="$dirs ""`expr $a : "$watchdir/\(.*\)"`" 
+                 set -- "$@" "$a" 
+                 ;;
+    *) set -- "$@" "$a" ;;
+  esac
+done
+
+$DAISY_CHAIN "$@" || exit $?
+
+test z"$dirs" != z &&
+echo 1>&2 '***' mkdir "$cmdline"
+for dir in $dirs ; do
+  cumuldir=""
+  for d in `echo $dirs | sed 's#/# #g' -` ; do
+    cumuldir=$cumuldir$d/
+    chgrp install $watchdir/$cumuldir
+    chmod g+w,o+t $watchdir/$cumuldir
+  done  
+done
+exit 0
+------------ end $LFS/usr/src/lfs/wrappers/mkdir --------------------------
+
+------------ begin $LFS/usr/src/lfs/wrappers/chgrp ------------------------
+#!/bin/sh
+
+DAISY_CHAIN=""
+
+for p in $(type -ap chgrp) ; do
+  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
+done
+
+if [ ! -n "$DAISY_CHAIN" ]; then
+  echo Cannot find real ${0##*/} command 
+  exit 1
+fi
+
+if [ $UID == 0 ]; then
+  exec $DAISY_CHAIN "$@"
+fi
+
+if [ "$1" == "tty" ]; then
+  echo 1>&2 '***' chgrp "$@"  
+else
+  $DAISY_CHAIN "$@" || exit $?
+fi
+
+exit 0
+------------ end $LFS/usr/src/lfs/wrappers/chgrp --------------------------
+
+------------ begin $LFS/usr/src/lfs/wrappers/chown ------------------------
+#!/bin/sh
+
+DAISY_CHAIN=""
+
+for p in $(type -ap chown) ; do
+  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
+done
+
+if [ ! -n "$DAISY_CHAIN" ]; then
+  echo Cannot find real ${0##*/} command 
+  exit 1
+fi
+
+if [ $UID == 0 ]; then
+  exec $DAISY_CHAIN "$@"
+fi
+
+if [ "$1" == "root.root" ]; then
+  echo 1>&2 '***' chown "$@"  
+else
+  $DAISY_CHAIN "$@" || exit $?
+fi
+
+exit 0
+-------------- end $LFS/usr/src/lfs/wrappers/chown ------------------------
+
+------------ begin $LFS/usr/src/lfs/wrappers/install ----------------------
+#!/bin/sh
+
+localedir=/usr/share/locale
+cmdline="$@"
+manpagesowner=man-pages
+
+DAISY_CHAIN=""
+
+for p in $(type -ap install) ; do
+  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
+done
+
+if [ ! -n "$DAISY_CHAIN" ]; then
+  echo Cannot find real ${0##*/} command 
+  exit 1
+fi
+
+if [ $UID == 0 ]; then
+  exec $DAISY_CHAIN "$@"
+fi
+
+
+	#********** test if we create directories ********************
+if [ \( z"$1" = z"-d" \) -o \( z"$1" = z"-m" -a z"$3" = z"-d" \) ]; then  
+  locdirs=""
+  notify=0
+  havedir=0
+  for((i=$#; $i>0; ))
+  do
+    a="$1"
+    shift 1; i=$(($i-1))
+    case "$a" in
+      -o|-g|--owner|--group) notify=1 
+      			shift 1; i=$(($i-1))
+          		set -- "$@" 
+          ;;
+      $localedir/*) if [ ! -d "$a" ]; then
+      		      locdirs="$locdirs ""`expr $a : "$localedir/\(.*\)"`" 
+                      set -- "$@" "$a"
+                      havedir=1
+                    else
+                      notify=1
+                      set -- "$@"
+                    fi  
+                   ;;
+      */*|/sbin) if [ ! -d "$a" ]; then 
+      	     set -- "$@" "$a" 
+      	     havedir=1
+      	   else
+      	     notify=1
+      	     set -- "$@"
+      	   fi             
+      	   ;;
+      *) set -- "$@" "$a" ;;
+    esac
+  done
+  
+  test $notify -eq 1 -o z"$locdirs" != z && \
+  					echo 1>&2 '***' install "$cmdline"
+
+  test $havedir -eq 0 && exit 0
+
+  $DAISY_CHAIN "$@" || exit $?
+  
+  test z"$locdirs" != z &&
+  for dir in $locdirs ; do
+    cumuldir=""
+    for d in `echo $locdirs | sed 's#/# #g' -` ; do
+      cumuldir=$cumuldir$d/
+      if [ -d $localedir/$cumuldir ]; then
+        chgrp install $localedir/$cumuldir
+        chmod g+w,o+t $localedir/$cumuldir
+      fi  
+    done  
+  done
+
+else  #if "$1" != "-d"  ,i.e. we do not create directories *****************
+  notify=0
+  for((i=$# ; $i>0; ))
+  do
+    a="$1"
+    shift 1; i=$(($i-1))
+    case "$a" in
+     -m)      set -- "$@" "$a" 
+              a="$1"
+              shift 1; i=$(($i-1))
+              case "$a" in
+                4755) notify=1 ; set -- "$@" "755" ;;
+                *) set -- "$@" "$a"  ;;
+              esac
+          ;;
+      -m4755) notify=1 ; set -- "$@" "-m755" ;;
+      -o|-g|--owner|--group)    notify=1 
+      		shift 1; i=$(($i-1))
+          	set -- "$@" 
+          ;;
+      */man/man?/*) 
+                if [ -e "$a" -a ! -O "$a" ]; then
+                  if [ `find "$a" -printf \%u` = $manpagesowner ]; then
+                    notify=1
+                    set -- "$@" not_installed
+                  else
+                    set -- "$@" "$a"
+                  fi  
+                else
+                  set -- "$@" "$a"
+                fi
+          ;;    
+      *) set -- "$@" "$a" ;;
+    esac
+  done
+
+  test $notify -eq 1 && echo 1>&2 '***' install "$cmdline"
+
+  $DAISY_CHAIN "$@" || exit $?
+fi
+
+exit 0
+----------- end $LFS/usr/src/lfs/wrappers/install --------------------------
+
+If you improve any of these scripts, I would be grateful if you could mail
+me your changes together with a note saying which package prompted the
+change. Note that these scripts are supposed to have minimal intrusiveness.
+So writing a common case "-m*)" instead of the case "-m4755" is undesirable.
+The scripts should only deal with the problems that have actually been
+encountered, not all possible problems.
+
+#############################################################################
+ LFS specifics
+#############################################################################
+ 
+For the user name of the package users I always use the name of the package
+without the version number, including dashes and possibly exceeding 8
+characters in length, e.g. "util-linux". 
+Aside from ls -l which chops off the last characters
+of the user name I have not noticed any problems with this. The other programs
+I have tested seem to deal with these user names just fine. 
+If you encounter problems, please report them to me.
+
+Now how do we apply the above to the building of an LFS system ?
+
+##########################################################################
+Pre-chroot phase 
+##########################################################################
+
+We don't use package users in the pre-chroot phase. This does not mean we
+install as root. I suggest building the pre-chroot system as a normal user.
+That way, you can later distinguish files created inside chroot (these
+have uid 0 or the uid of a package user) and remaining files created during 
+the pre-chroot phase (these carry the uid of your normal user account on
+your host system). Building as an ordinary user also protects you against 
+typos that might otherwise cause a package to overwrite files on your host
+system.
+
+The actual commands of the pre-chroot phase don't need be changed but you
+have to do some additional things.
+The first problem is that we need find right after installing glibc inside
+chroot. The best thing to do is to build a static version during the 
+pre-chroot phase like this:
+
+./configure --prefix=$LFS/usr --disable-nls &&
+make LDFLAGS=-static CPPFLAGS=-Dre_max_failures=re_max_f2 &&
+make libexecdir=$LFS/usr/bin install
+
+Another problem is that some programs such as chown can not resolve usernames
+before glibc is installed. Fortunately most programs accept a numeric UID
+or GID. There is one nasty exception, though: su. The most fundamental
+program when using package users doesn't swallow numeric ids :-|
+
+Now how do we become a package user before glibc is installed ? 
+If you guessed that I have a written a script to replace it, you guessed ...
+... wrong :-) I have written a C program to replace it. 
+
+It just happens that sh-utils
+contains an su program which is not used in LFS. It gets installed 
+statically linked during the pre-chroot phase, is never used there (assuming
+a standard LFS build), gets replaced with a dynamically linked version when 
+sh-utils is reinstalled and then is finally replaced by the su from shadow 
+which is the version we will use when the LFS system is finished. So all
+you need to do is to replace the file src/su.c in the sh-utils source tree
+with the following file before compiling your chapter 5 sh-utils.
+Note that if you compile chapter 5 as non-root, you need to issue the command
+`make install-root' after `make install' or sh-utils won't install su.
+
+-------- begin $LFS/usr/src/sh-utils/sh-utils-<version>/src/su.c ------------
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <ctype.h>
+#include <grp.h>
+
+#define NUMGIDS 1024
+
+int main(int argc,char* argv[])
+{
+  char* Res;
+  char Buffy[4096];
+  uid_t tuid=-1,uid;
+  gid_t gid;
+  int i;
+  FILE* File;
+  char* command=NULL;
+  char* shell;
+  char* HOME;
+  gid_t gid_list[NUMGIDS];
+  ssize_t NumGids=0;
+
+  if (argc>1) 
+  {
+    if (strcmp(argv[1],"--help")==0) 
+      { fprintf(stdout,"There is no help!\n"); exit(0);}
+    if (strcmp(argv[1],"--version")==0) {fprintf(stdout,"0.6\n"); exit(0); }
+  }
+
+  if ((argc==4) && (strcmp(argv[2],"-c")==0)) command=argv[3]; else
+  if (argc!=2)
+  {
+    fprintf(stdout,"USAGE: su username|uid [-c command]\n");
+    return 1;
+  };
+
+  i=0;
+  while(isdigit(argv[1][i])) ++i;
+  if (argv[1][i]==0) tuid=atol(argv[1]);
+
+  File=fopen("/etc/passwd","rb");
+  if (File==NULL) {perror("/etc/passwd"); return 1;};
+  
+  while(1)
+  {
+    errno=0;
+    Res=fgets(Buffy,1024,File);
+    if (Res==NULL) {
+      if (errno!=0) perror("/etc/passwd"); 
+        else fprintf(stderr,"su: User not found!\n");
+      return 1;
+    };
+    
+    Res=strtok(Buffy,":");
+    if (Res==NULL) continue;
+    strtok(NULL,":");
+    uid=atol(strtok(NULL,":"));
+    gid=atol(strtok(NULL,":"));
+    strtok(NULL,":");
+    HOME=strtok(NULL,":");
+    shell=strtok(NULL,":");
+    if (tuid==uid) {argv[1]=strdup(Buffy); break;}
+    if (strcmp(argv[1],Buffy)==0) break;
+  };
+  HOME=strdup(HOME);
+  shell=strdup(shell);
+  
+  File=fopen("/etc/group","rb");
+  if (File==NULL) {perror("/etc/group"); return 1;};
+  
+  while(1)
+  {
+ContinueReadingEtcGroup:
+    errno=0;
+    Res=fgets(Buffy,1024,File);
+    if (Res==NULL) {
+      if (errno!=0) {perror("/etc/group"); return 1;} else break;
+    };
+    
+    Res=strtok(Buffy,":,\n");
+    if (Res==NULL) continue;
+    strtok(NULL,":,\n");
+    gid_list[NumGids]=atol(strtok(NULL,":,\n"));
+    Res=strtok(NULL,":,\n");
+
+    while(Res!=NULL)
+    {
+      if (strcmp(Res,argv[1])==0) 
+      {
+        ++NumGids;
+        if (NumGids>=NUMGIDS) goto SetNewIdentity; 
+        		 else goto ContinueReadingEtcGroup;
+      };
+      Res=strtok(NULL,":,\n");
+    };
+  };
+
+SetNewIdentity:
+  if (command==NULL) command=shell;
+  setenv("HOME",HOME,1);
+  setgroups(NumGids,gid_list);
+  setgid(gid);
+  setuid(uid);
+  errno=0;
+  i=system(command);
+  if (((i<0) || (i==127)) && (errno!=0)) {perror("/bin/sh"); return 1;};
+  return i;
+};
+-------- end $LFS/usr/src/sh-utils/sh-utils-<version>/src/su.c ------------
+
+This su program accepts user names as well as numeric UIDs. It does its own
+name resolution using /etc/passwd so it works even without glibc being
+installed. 
+Note that sh-utils installs the su program with the setuid bit set. 
+If you install the pre-chroot system as an ordinary user (which you should 
+for safety reasons), this will result in a su that doesn't work even when 
+executed by root. Simply remove the setuid bit like this
+
+chmod u-s $LFS/bin/su
+
+and su will work fine once we have entered the chroot environment (where
+we work as root). Note that this allows you to su from root to a package
+user but not the other way around. If you want to be able to su from a package
+user to root you will have to make su setuid root 
+(i.e. chown root.root $LFS/bin/su && chmod u+s $LFS/bin/su). Make sure that
+you don't keep such an su lying around on a system that others have access to.
+The above su does not check for a password, so if you make it setuid root,
+everyone can use it to become root without a password!
+
+
+##########################################################################  
+ Chroot phase - preparing the LFS system: 
+##########################################################################
+ 
+This is the tricky part. Once we
+have entered chroot, we have to assign install directories to the
+install group and make them group-writeable. However, since glibc is not
+yet installed, we can't use user names, yet. Furthermore, groupadd and useradd
+which are part of the shadow package are not installed, yet.
+This means that we can't create any package users, at least not without
+editing /etc/group and /etc/passwd manually. 
+But don't despair. The following
+scripts make nice replacements for useradd and groupadd as long as shadow
+isn't there. Note that they only accept the exact syntax with which the
+useradd and groupadd commands are used in the add_package_user script.
+I assume you will be using the install_package/add_package_user scripts to
+add package users to the system. Here are the scripts:
+
+--------------------- begin $LFS/usr/sbin/useradd ----------------------------  
+#!/bin/sh
+if [ $# -ne 13 -o z$1 != z-c -o z$3 != z-d -o z$5 != z-g -o z$7 != z-G -o z$9 != z-s -o z${11} != z-u ]; then
+echo 1>&2 USAGE: useradd -c description -d home -g maingroup -G addgroup -s shell -u uid login 
+exit 1
+fi
+
+#test if user already exists
+grep "^${13}:.*" /etc/passwd 
+if [ $? -eq 0 ]; then
+  echo 1>&2 $0: User does already exist
+  exit 1
+fi       
+
+g=`grep ^${6}:.\* /etc/group | cut -d : -f 3 -`
+if [ z${g} = z ]; then
+  echo 1>&2 $0: Group ${6} does not exist!
+  exit 1
+fi
+
+grep ^${8}:.\* /etc/group >/dev/null || \
+{
+  echo 1>&2 $0: Group ${8} does not exist!
+  exit 1
+}
+
+
+cp /etc/passwd /tmp/passwd123456
+echo "${13}:x:${12}:$g:$2:$4:/bin/bash" \
+| sort -t : -k3,3n -m /tmp/passwd123456 - > /etc/passwd
+
+
+cp /etc/group /tmp/group123456
+sed  -e 's/^\('"${8}"':[^:]*:[0-9]*:..*\)$/\1,'"${13}"'/' \
+     -e 's/^\('"${8}"':[^:]*:[0-9]*\):$/\1:'"${13}"'/' \
+     						/tmp/group123456 >/etc/group
+---------------------- end $LFS/usr/sbin/useradd ----------------------------  
+
+--------------------- begin $LFS/usr/sbin/groupadd --------------------------
+#!/bin/sh
+if [ $# -ne 3 -o z$1 != z-g ]; then
+echo 1>&2 USAGE: groupadd -g gid groupname
+exit 1
+fi
+
+#test if group already exists
+grep "^${3}:.*" /etc/group 
+if [ $? -eq 0 ]; then
+  echo 1>&2 $0: Group does already exist
+  exit 1
+fi       
+
+cp /etc/group /tmp/group123456
+echo ${3}:x:${2}: | sort -t : -k3,3n -m /tmp/group123456 - > /etc/group
+--------------------- end $LFS/usr/sbin/groupadd ----------------------------
+
+These scripts overcome the problem of the missing shadow utilities. 
+
+With the above scripts and su program we now have everything we need to
+begin our chroot phase. 
+
+###########################################################################
+ Tips before you chroot
+###########################################################################
+ 
+Whenever add_package_user creates a new package user it copies the files
+from /etc/skel-package (if you create this directory) to the new package
+user's home directory. Symlinks are copied as symlinks.
+A useful symlink to place in /etc/skel-package is one like
+
+.bashrc -> /etc/bashrc_package 
+
+with something like the following:
+
+------------------ begin $LFS/etc/bashrc_package --------------------------
+#first load basic configuration to make system work normal
+source /etc/bashrc_basic
+
+export PATH=/usr/src/lfs/wrappers:$PATH
+
+#make prompt reflect that we are a package user. Do it via USER_PROMPT_COMMAND
+#rather than PROMPT_COMMAND because we want to keep root's prompt if we su to root
+export USER_PROMPT_COMMAND='PS1="package \u:"`pwd`"> "'
+
+alias mafobu='make -f /usr/src/lfs/mafobu'
+
+#The following command will put us in the home directory. 
+cd
+------------------ end $LFS/etc/bashrc_package ----------------------------
+
+------------------ begin $LFS/etc/bashrc_basic ----------------------------
+#This file should be sourced by all users' .bashrc files
+
+if [ $UID -eq 0 ]; then
+  export PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin
+else
+  export PATH=/usr/local/bin:/bin:/usr/bin
+fi
+
+  #set a red prompt when user is root. If a user wants to override this
+  #s/he should use USER_PROMPT_COMMAND instead of PROMPT_COMMAND in order to 
+  #keep 
+  #root's prompt when su'ed to root. If a user wants to change PS1 directly
+  #s/he should do "unset USER_PROMPT_COMMAND".
+export PROMPT_COMMAND='if [ $UID -eq 0 ]; then \
+  PS1="\[\033[0;31m\]root@\h:"`pwd -P`"# \[\033[0m\]" ; \
+    else eval $USER_PROMPT_COMMAND ; fi'
+  #make PROMPT_COMMAND read-only to protect against careless users
+declare -r PROMPT_COMMAND
+  #set a reasonable default USER_PROMPT_COMMAND
+export USER_PROMPT_COMMAND='PS1="\u@\h:"`pwd`"> "'
+
+  #make keys (del, bs, home, end,...) work normal
+export INPUTRC=/etc/inputrc
+bind -f $INPUTRC
+------------------ end $LFS/etc/bashrc_basic ------------------------------
+
+
+
+Another useful file to place in /etc/skel-package is a .project file like
+this:
+
+------------------ begin $LFS/etc/skel-package/.project ------------------
+DESCRIPTION:
+  bogus package
+CONTENTS:
+  foo,bar,fubar
+LAST UPDATED:
+  30 Feb 2042
+DOWNLOAD LOCATION:
+  ftp://ftp.gnu.org/gnu/foo/
+WEB SITE:
+  <none>
+INSTALL NOTES:
+GENERAL NOTES:
+----------------- end $LFS/etc/skel-package/.project ------------------
+
+Update this file whenever you re/install a package. It is called .project
+so that it is automatically displayed when you issue the command 
+"finger <package>" or "pinky -l <package>".
+
+
+###########################################################################
+ Inside the chroot environment
+###########################################################################
+
+After you have chroot'ed do
+
+groupadd -g 10000 install
+
+which will create the install group. Now use 
+
+chown 0.10000 `cat /tmp/installdirs`
+chmod ug=rwx,o=rx `cat /tmp/installdirs`
+
+to assign directories to the install group. Note that we do not make the
+directories sticky, yet. This is because they still contain files belonging
+to root or some unknown user (if you installed pre-chroot as non-root). These
+files must be overwriteable. The file /tmp/installdirs is the following list:
+
+----------------- begin $LFS/tmp/installdirs ------------------------------
+/usr/bin
+/usr/etc
+/usr/sbin
+/usr/include
+/usr/lib
+/usr/man/man?
+/usr/doc
+/usr/info
+/usr/local/man/man?
+/usr/local/doc
+/usr/share
+/usr/share/dict
+/usr/share/doc
+/usr/share/info
+/usr/share/locale
+/usr/share/man/man1
+/usr/share/man/man2
+/usr/share/man/man3
+/usr/share/man/man4
+/usr/share/man/man5
+/usr/share/man/man6
+/usr/share/man/man7
+/usr/share/man/man8
+/usr/share/nls
+/usr/share/misc
+/usr/share/terminfo
+/usr/share/zoneinfo
+/usr/share/i18n
+/usr/share/aclocal
+/usr/local/bin
+/usr/local/etc
+/usr/local/include
+/usr/local/lib
+/usr/local/sbin
+/usr/local/share
+/usr/local/share/dict
+/usr/local/share/doc
+/usr/local/share/info
+/usr/local/share/locale
+/usr/local/share/man/man1
+/usr/local/share/man/man2
+/usr/local/share/man/man3
+/usr/local/share/man/man4
+/usr/local/share/man/man5
+/usr/local/share/man/man6
+/usr/local/share/man/man7
+/usr/local/share/man/man8
+/usr/local/share/nls
+/usr/local/share/misc
+/usr/local/share/terminfo
+/usr/local/share/zoneinfo
+/etc
+/sbin
+/bin
+/lib
+----------------- end $LFS/tmp/installdirs --------------------------------
+
+Now do
+
+chown 0.10000 /usr/share/info/dir
+chmod ug=rw,o=r /usr/share/info/dir
+
+which makes sure packages can install their info pages. 
+
+
+
+#########################################################################
+ Chroot phase -installing the packages 
+#########################################################################
+
+Now we can finally install glibc. Create /dev/null as root by doing
+
+mknod -m 0666 /dev/null c 1 3
+
+then do
+
+install_package "GNU C library" glibc system
+
+which will create the system group and a user glibc and will also su to the new
+glibc package user. Note that the mkdir and install wrapper
+don't work properly during the installation of glibc because they use
+the name "install" rather than the gid. This means we have to do the
+following *after* installing glibc:
+
+find /usr/share/locale/* -type d -user glibc -exec chmod ug=rwx,o=rxt \{\} \;\
+					 -exec chgrp install \{\} \;
+
+
+Now do
+
+exit
+
+to become root and begin installing the rest of the packages. Use the command
+
+install_package <description> <packagename> <group>
+
+to create and become the package user. Then unpack in that user's home 
+directory and use the guidelines below and the book's directions to 
+install each package.
+
+############################################################################
+ Group guidelines
+############################################################################
+
+I recommend the following groups for use with package users:
+
+devel: development related stuff, e.g. compilers. This is not restricted to
+       software development. TeX for instance would belong in this group.
+       
+utils: Most software fits into this category, even somewhat essential software 
+       like grep or text editors.
+      
+net: network related stuff such as an ftp daemon or a web browser. This
+     group overlaps with other groups to a large extent. It should be used
+     in preference of the other groups whenever a package is clearly focused
+     towards Internet, LAN, WWW,... A utility like wget for instance would
+     go in net rather than utils. Exceptions from this rule are the groups
+     docs, addons, games and mmedia. If a package fits into one of those 
+     groups, use the respective group instead of net.
+     
+docs: Documentation related packages, such as a tarball with Linux howtos.
+      Note that software to create documentation such as XML processors should
+      probably go in devel and software to view or post-process documentation
+      such as man or groff should probably go in utils.
+      
+system: important system software, such as bash. This group should be used
+        only for really essential packages. Most packages you would put in 
+        this group are better put into "utils". Vi for instance belongs in 
+        utils. 
+        It is unlikely that any package not part of basic LFS belongs in the
+        system group.
+        
+libs: What utils is for executables, libs is for libraries. Libraries that are
+      not strongly related to any of the other categories should go here, such
+      as zlib or libpng.
+      Essential system libraries such as glibc, ncurses or gettext should
+      go in system instead.
+      The libs group is also used for run-time environments such as the
+      Java Virtual Machine, dosemu and wine. Other emulators like MAME for
+      instance should probably go into games instead. 
+     
+games: what do you expect ;-)
+
+mmedia: This is the group for audio and video editors, mp3 players etc.
+
+apps: Applications such as spreadsheets and word processors (not text editors)
+      but also CAD software and graphics software such as Gimp.
+      The apps group is a bit like utils, but apps are usually more user 
+      friendly and more streamlined and focused than utils. 
+      Apps feel less geekish and nerdish than
+      utils. Emacs for instance belongs in utils, not in apps.
+      
+addons: plugins, filters and similar that are meant to be used in conjunction
+       with another package.
+       
+x: software that relates to the X Window System in general and does not fit
+   into any of the other categories, such as the X server itself or window 
+   managers.
+   Most X software should be put into other more specific groups.
+   A game like xmines would go in games for instance and a text editor for
+   X would go in utils.
+   
+kde: Software that relates to KDE and does not fit into
+     any other category. This group should be used with care. 
+     Do *not* use it for all KDE software. K Office for instance belongs in
+     apps. Konqueror belongs in net.
+     
+gnome: Software that relates to GNOME and does not fit into
+       any other category. This group should be used with care. 
+       Do *not* use it for all GNOME software. Gimp for instance belongs 
+       in apps. A GNOME-aware window manager that works with plain X should
+       go in the x group.
+
+The following is a list of the LFS packages with the user.group assignments
+I think are appropriate. The user name in general should be the name of
+the main tarball without extensions and version. The groups try to follow
+the guidelines above but sometimes it is hard to find the "correct" group.
+The list also contains some notes I made when I installed them. 
+If you use the mkdir, chgrp and install wrappers, you should
+not have any trouble.
+
+glibc.system:
+  see above.
+
+MAKEDEV: not installed as a package user
+
+man-pages.docs
+findutils.utils
+mawk.devel:
+	rm /usr/bin/mawk /usr/share/man/man1/mawk.1 
+	as root before `make install'
+ncurses.system
+vim.utils
+ed.utils
+gcc.devel:
+	Before `make install' assign the /usr/lib/gcc-lib and /usr/include/g++
+	to the gcc package user by doing (as root)
+	  chown -R gcc. /usr/lib/gcc-lib /usr/include/g++
+bison.devel
+less.utils
+groff.utils
+man.utils
+perl.utils
+m4.devel
+texinfo.utils
+autoconf.devel
+automake.devel:
+	Creates the directory /usr/share/aclocal. This directory is written to
+	by other packages, so chgrp install and chmod g+w,o+t it.
+
+bash.system:
+	When ./configure is done as a package user (more precisely when done 
+	in a su environment), it will fail to detect /dev/stdin. This will 
+	cause bash to compile an emulation of /dev/std* and /dev/fd/*. 
+	I actually prefer this emulation because it matches the description 
+	in the manpage while the normal behaviour (i.e. to open the 
+	respective device) does not always.  If a normal bash is desired, 
+	use sed to change configure and replace 
+	"test -r /dev/stdin" with "test -e /dev/stdin" (same for /dev/fd). 
+	[ This information is for bash 2.05, I reported the issue so it may
+	be fixed in future versions. ]
+flex.devel
+file.utils
+libtool.devel
+bin86.devel
+binutils.devel
+bzip2.utils
+gettext.system
+kbd.system
+diffutils.utils
+e2fsprogs.utils
+fileutils.system
+grep.utils
+gzip.utils
+lilo.system
+make.devel:
+	make wants to be setgid kmem in order for the -l option to work.
+	If you are not a developer who knows what this option does, you
+	don't need it and should not give make special privileges.
+	[UPDATE] On Linux the -l option seems to work even if make is not
+	setgid kmem.
+
+linux kernel: not installed as package user
+modutils.system:
+	The modutils check if modules are owned by root before using them.
+	This is the reason why the linux kernel should be compiled and
+	installed as root, rather than as a package user.
+
+netkit-base.net
+patch.utils
+procinfo.utils
+procps.utils
+psmisc.utils
+sed.utils
+sh-utils.system
+net-tools.net
+shadow.system:
+	This package installs quite a few setuid root progs. If you're not
+	religious about package users you might want to install this one
+	as root.root to make life easier for yourself.
+	If you do install as package user don't forget to make the
+	binaries in question setuid root manually afterwards.
+	After installing shadow make sure that the useradd and groupadd
+	scripts have been properly replaced. Execute
+	  find / -maxdepth 3 -name groupadd
+	to make sure that you don't have 2 copies (e.g. one in /sbin and
+	one in /usr/sbin)  
+	
+
+sysklogd.system
+	This package has /usr/bin/install hardwired, so install with
+	  make INSTALL=install install
+	to make it use the wrapper.
+
+sysvinit.system:
+	This one is a bit tricky. You have to create /dev/initctl manually
+	as root	*before* doing "make install" because a package user does
+	not have permission to write to /dev. So do (as root!!)
+	  rm -f /dev/initctl
+	  mknod -m 600 /dev/initctl p
+
+tar.utils
+textutils.utils
+util-linux.system:
+	Don't forget to make mount and umount setuid root manually after
+	installing this package. And the write program wants to be
+	setgid tty.
+
+###########################################################################
+ Final steps
+###########################################################################
+
+After installing everything, make the install directories sticky:
+
+chmod ug=rwx,o=rxt `cat /tmp/installdirs`
+
+If you installed pre-chroot as a normal user there are now some directories
+owned by that user even though they should be owned by a package user. This
+happens because the package users in question did not/could not recreate
+these directories. The following script will fix that. It works by looking
+for directories not owned by a registered user (-nouser option). The list
+of these directories is processed in a for loop. For each directory find is
+then used to look for all files owned by a registered user and to list those
+users. With "sort -u" (unique) we get a list of registered users that have
+files in the directory in question and wc tells us how many of these users
+there are. If there is only one such user (i.e. all files in the directory
+belong either to an unregistered user or the one registered user we 
+identified) then we assign the directory to this user.
+
+----------------- begin $LFS/usr/src/lfs/fixowner -------------------------
+#!/bin/sh   
+#find all directories owned by an unknown user (i.e. the normal user
+#account you installed pre-chroot with, if you installed as a normal
+#user) and assign those that have an unambiguous intended owner (i.e.
+#only files belonging to a single owner aside from the unknown one
+#are found in the directory) to that owner.
+get_dir_owners() 
+{ 
+  owners=`find $1 -not -nouser -printf "%u\n" | sort -u `
+  num=`echo $owners | wc -w | tr -d " "`
+} 
+
+for dir in `find / -path "/proc" -prune -or -type d -nouser -print` 
+do 
+  get_dir_owners $dir 
+  if [ $num == 1 ]; then 
+    chown `echo $owners | tr -d " "`. $dir 
+    chmod u=rwx,go=rx $dir 
+    echo "Assigning $dir to $owners"
+  fi  
+done
+----------------- end $LFS/usr/src/lfs/fixowner ---------------------------
+
+Finally you should
+use find to find files that still belong to the user you
+installed pre-chroot with. You can also use find to identify any directories
+that are group-writeable and not sticky. You should also check for setuid
+and setgid programs that don't belong to root. Apply your common sense to
+deal with these files (or send me a mail so I can mention the issue here).
+
+find / -path "/proc/*" -prune -or -perm +u+s -printf "%p: suid %u\n"
+find / -path "/proc/*" -prune -or -perm +g+s -printf "%p: sgid %g\n"
+find / -path "/proc/*" -prune -or \
+       -type d -perm +o+w -not -perm +o+t -printf "%p: world-writeable\n"
+find / -path "/proc/*" -prune -or -type d -perm +g+w -not -perm +o+w \
+                             -not -perm +o+t -printf "%p: group-writeable\n"
+find / -path "/proc/*" -prune -or \
+       -not -type d -not -type l -perm +o+w -printf "%p: world-writeable\n"
+find / -path "/proc/*" -prune -or -path "/dev/*" -prune -or \
+       -not -type d -not -type l -perm +g+w -not -perm +o+w \
+                                           -printf "%p: group-writeable\n"
+find / -path "/proc/*" -prune -or -nouser -printf "%p: unknown user: %u\n"
+find / -path "/proc/*" -prune -or -nogroup -printf "%p: unknown group: %g\n"
+
+
+
+###########################################################################
+ Security issues with NFS
+###########################################################################
+
+If you use the network filesystem NFS, there are some things you need to
+look out for when using the package user system described in this hint.
+A fundamental security problem with NFS is that it blindly trusts the uid and 
+gid of the client. If an attacker can get access to the root account on a
+system in your network that is allowed to mount NFS shares from your server,
+or if the attacker can attach his own computer to your network, then this
+attacker can pretend to be anyone. NFS will happily allow the attacker to
+work in the NFS exported directory as any user he wants to be.
+The only exception is the root account. By default NFS exports directories 
+with the root_squash option that maps all incoming requests from uid 0 to 
+anonuid (65534 unless set in /etc/exports) and gid 0 to anongid
+(65534 unless set in /etc/exports). This protects files owned by 
+root.root. On a normal system this includes most files in /bin, /etc, /lib
+and most other directories except /home. If you use the package user scheme,
+however, most of these files are owned by package users. These files are
+not protected by the root_squash option. 
+In order to make NFS exports secure, you have to add the option "all_squash"
+to every entry in /etc/exports that exports a directory that contains 
+files owned by package users. Note that all_squash is always a good idea
+because even systems that don't use package users usually have some programs 
+owned by other users such as daemon or bin and other groups such as tty, 
+because they need to be setuid or setgid.

Deleted: trunk/PREVIOUS_FORMAT/more_control_and_pkg_man.txt
===================================================================
--- trunk/PREVIOUS_FORMAT/more_control_and_pkg_man.txt	2004-11-01 06:57:29 UTC (rev 904)
+++ trunk/PREVIOUS_FORMAT/more_control_and_pkg_man.txt	2004-11-04 05:13:06 UTC (rev 905)
@@ -1,1496 +0,0 @@
-TITLE:		More control and package management using package users (v0.8)
-LFS VERSION:	3.1 (should work with later versions with minor changes)
-AUTHOR:		Matthias S. Benkmann <m.s.b at gmx.net>
-
-SYNOPSIS:
-	-You want to know which packages your files belong to ?
-	-You want to deinstall software that doesn't have make uninstall ?
-	-You are bothered by programs installed setuid root behind your back ?
-	-You don't want packages to overwrite files from other packages ?
-	-You don't like package managers like RPM ?
-	-YOU WANT TOTAL CONTROL USING ONLY UNIX BUILTINS ?
-
-HINT:
-
-LEGALESE: The author does not take responsibility for any damage of any kind
-caused directly or indirectly by applying the methods described below. 
-There is no warranty of any kind, not even the implied warranty of fitness for
-the purposes mentioned in the text, on any of the programs/scripts/commands 
-listed below and the author may not be held liable for any damage of any kind 
-caused by the execution of said programs/scripts/commands.
-Proceed at your own risk!
-
-########################################################################### 
- Changelog
-###########################################################################
-
-2002-01-30  -added Changelog
-            -moved "chown 0.10000 `cat /tmp/installdirs`" command up (before
-             glibc package user is created)
-            -add_package_user: create home directory with "mkdir -p"
-                               use $grpfile everywhere instead of /etc/group
-            -improved mammoth sentence in Introduction
-            -added note about possibility to have user name==group name
-            -source bashrc_basic in bashrc_package
-            -minor textual changes
-
-2002-02-18
-            -added section "Security issues with NFS"
-            -submitted v0.7
-            
-2002-03-16  -added note, that on Linux make doesn't need to be setgid kmem
-
-2002-04-20
-            -changed LFS VERSION header to be more conservative
-            -added <br> tags to the synopsis for the sake of the hints 
-             index
-            -added group mmedia to the list of suggested groups 
-            -submitted v0.8
-            
-
-
-########################################################################### 
- Introduction
-###########################################################################
-
-Let's say I have written a program that you would like to use. To make it
-easier for you I come over to install it for you. Would you give me the root
-account and then leave the room ? No ? Then why do you give it to complete
-strangers who you have never seen in your life, to install software packages
-pulled from some Internet server, that come with no warranty and don't even 
-list their contents in the README, although they will happily spread them all 
-over your system ?
-It is a mystery why Unix admins who wouldn't even trust their employer with
-more than a normal user account carelessly execute complex and incomprehensible
-installation scripts with full root rights.
-
-Users and groups are the basic security principle in a Unix system. They have
-been used successfully for a long time to control who has created a file and 
-who is allowed to delete or change this file. But this control has only been
-imposed on the files of ordinary users. What a waste! I suggest to extend
-this control to all system files.
-
-
-#############################################################################
- Package users
-#############################################################################
-
-The basic idea of this scheme is easily explained. Every package belongs to a 
-certain "package user". This is a special user account whose HOME directory
-is /usr/src/<package> (or wherever you keep the tarballs for the package).
-Usually this account has no password so that only root can su to a package 
-user, which ensures that package users do not open an additional way into the 
-system and undermine security.
-Of course you *may* set passwords anyway to allow a co-admin who you want to
-be able to install and maintain certain software packages to do so without 
-having access to the actual root account. This co-admin could for instance
-install, delete, change additional libraries which might be necessary for his
-workgroup. He would be unable, though, to remove or modify libraries which 
-don't belong to him/her, such as libc.
-
-Every package user has a primary group that reflects the purpose of the
-package, such as "system" for essential packages, "devel" for packages
-related to software development and so on. There are other useful
-organizational schemes, of course. You might want to have the group reflect
-the workgroup of the above-mentioned co-admin who installed the file for 
-instance. Another possibility is to create a new group for every package
-user with the same name as the user name. That way, even if a file needs to
-be setuid root (and consequently has to be owned by root), the group of the
-file tells you about the package where it originates. 
-
-In addition to the primary group, there is the secondary group which is the
-same for all package users. This is the "install" group. All directories
-that packages are allowed to install stuff in belong to the install group.
-This includes directories such as /bin and /usr/bin but excludes directories
-like /root or /. The directories owned by the install group are always
-group-writeable. Without further preparation this does not give added security
-or control because every package could replace the files from a different
-package (the change would be visible in the output from ls -la, though).
-For this reason we make all install directories sticky. The sticky attribute
-allows users to create new files and delete or modify their own files in
-the directory while preventing them from writing or deleting files from other
-users.
-
-
-############################################################################
- How to install software
-############################################################################
-
-Isn't this all very tedious ? Not if you use this script:
-
--------------------- begin $LFS/sbin/install_package ------------------------
-#!/bin/sh
-if [ $# -ne 3 ]; then
-echo USAGE: install_package description name group
-echo "!!Don't forget to put description in quotes if it contains spaces.!!"
-echo "This will create a new package user name in group. This will set up"
-echo "a home directory for this package user. After that, this script will"
-echo "automatically su to the new user so that you can begin with the"
-echo "installation right away. "
-exit 1
-fi
-
-if [ $UID -ne 0 ]; then echo Please run this script as root. ; exit 1; fi
-add_package_user "${1}" $2 10000 20000 $3 10000 20000 || exit 1
-su $2
-------------------- end $LFS/sbin/install_package ----------------------------
-
-The above script is a shortcut for the following script, which does the
-actual adding of the package user in a certain range of UIDs and GIDs:
-
--------------------- begin $LFS/sbin/add_package_user -----------------------
-#!/bin/sh
-
-if [ $# -lt 7 ]; then
-echo 'Copyright (c) 2000 Matthias Benkmann'
-echo 'USAGE: '
-echo 'add_package_user description name minuid maxuid group mingid maxgid [-d home]'
-echo 
-echo Don\'t forget to put description in quotes. 
-echo description must be valid for a /etc/passwd entry, that means especially
-echo that it must not contain \":\".
-echo If group doesn\'t exist, it will be added. 
-echo group will be the user\'s main group. 
-echo 'The user will also belong to group "install" (created if necessary).'
-echo 'A home directory /usr/src/name (or home if -d home specified) 
-echo will be created if it doesn\'t exist
-echo 'and the files from /etc/skel-package will be copied into it (existing'
-echo 'target files will *not* be overwritten)'
-echo 'minuid (incl.) and maxuid (excl.)  determine'
-echo 'the range of UIDs used by this script. The script will pick the first'
-echo 'UID greater than all UIDs from this range already in use.' 
-echo 'If that UID is out of range (i.e. equal to maxuid), the'
-echo 'script will pick the first available UID in this range. If the range is'
-echo 'full, the script will give up. This process ensures that UIDs for packages'
-echo that have been removed, don\'t get reassigned unless really necessary.
-echo 'This avoids trouble if some files were overlooked when removing the package.'
-echo 'Otherwise these files might be assigned to the wrong package.'
-echo 'mingid (incl.) and maxgid (excl.) define'
-echo 'the permissible range for the GID of group if it has to be added (and '
-echo 'the install group if it must be added).'
-exit 1
-fi
-
-grpfile=/etc/group
-passwd=/etc/passwd
-homebase=/usr/src
-skel=/etc/skel-package
-description=$1
-name=$2
-minuid=$3
-maxuid=$4
-gname=$5
-mingid=$6
-maxgid=$7
-home=$homebase/$name
-
-set -- "$@" _eNd_OF_lisT_
-while [ "$1" != "_eNd_OF_lisT_" ]; do
-  case "$1" in
-    -d) shift 1
-        if [ "$1" = "_eNd_OF_lisT_" ]; then
-          echo 1>&2 "-d directory name missing!"
-          exit 1
-        fi
-        home="$1"
-        shift 1
-        ;;
-    *) temp="$1" 
-       shift 1
-       set -- "$@" "$temp"
-       ;;
-  esac     
-done
-shift 1 #throw away _eNd_OF_lisT_
-
-if [ $UID -ne 0 ]; then echo Please run this script as root. ; exit 1; fi
-
-#test if user already exists
-grep "^$name:.*" $passwd
-if [ $? -eq 0 ]; then 
-  echo 'Package user does already exist! Do su '$name' to do maintenance work.'
-  exit 1
-fi 
-
-#test if minuid, maxuid, mingid and maxgid are integers, otherwise set
-#to defaults.
-error=0
-expr ${minuid} + 1 2>/dev/null 1>&2 || error=1
-expr ${maxuid} + 1 2>/dev/null 1>&2 || error=1
-expr ${mingid} + 1 2>/dev/null 1>&2 || error=1
-expr ${maxgid} + 1 2>/dev/null 1>&2 || error=1
-
-if [ $error -eq 1 ]; then
-  echo Error: Illegal numeric value!
-  exit 1
-fi
-
-if [ $minuid -ge $maxuid ]; then
-  echo 'Error: minuid must be less than maxuid !' 
-  exit 1
-fi
-
-if [ $mingid -ge $maxgid ]; then
-  echo 'Error: mingid must be less than maxgid !' 
-  exit 1
-fi
-
-
-uidlist=`cut -d : -f 3 $passwd | sort -n`
-
-#find last used UID within range
-u=0
-for i in $uidlist
-do
-  if [ $i -ge $maxuid ]; then break; fi
-  if [ $i -ge $minuid ]; then u=$i; fi 
-done
-
-#if no UID from the range is used, pick the first, otherwise pick the one
-#immediately following the last UID in use.
-if [ $u -eq 0 ]; then u=$minuid; else u=`expr $u + 1`; fi
-
-#if the last UID used from the range is maxuid-1, i.e. we may 
-#not use its successor as UID, then we look for the first unused uid
-#in the range.
-if [ $u -ge $maxuid ]; then
-  u=$minuid
-  for i in $uidlist
-  do
-    if [ $u -eq $i ]; then u=`expr $u + 1` ; fi
-    if [ $i -ge $maxuid ]; then break; fi
-  done  
-
-  if [ $u -ge $maxuid ]; then
-    echo Error: UID range is full!
-    exit 1
-  fi
-fi
-
-echo Will create user $name with uid: $u
-
-unset uidlist
-
-#############################################################################
-#                                 group
-#############################################################################
-
-#execute the following for gname and "install" to get gids for those 2 groups
-
-g=0
-creategroup=0
-for group in install $gname
-do
-  oldg=$g #save gid from previous run
-  createinstall=$creategroup
-  creategroup=0
- 
-  #test if group already exists and extract gid if so
-  g=`grep ^${group}:.\* $grpfile | cut -d : -f 3 -`
-
-  #if group does not exist, then check range for a free gid
-  if [ z$g = z ]; then 
-    creategroup=1
-    
-    gidlist=`cut -d : -f 3 $grpfile | sort -n`
-
-    #find last used GID within range
-    g=0
-    for i in $gidlist
-    do
-      if [ $i -ge $maxgid ]; then break; fi
-      if [ $i -ge $mingid ]; then g=$i; fi
-    done
-
-    #if no GID from the range is used, pick the first, otherwise pick the one
-    #immediately following the last GID in use.
-    if [ $g -eq 0 ]; then g=$mingid; else g=`expr $g + 1`; fi
-    
-    #don't reuse gid from previous run 
-    if [ $g -eq $oldg ]; then g=`expr $g + 1`; fi
-
-    #if the last GID used from the range is maxgid-1, i.e. we may 
-    #not use its successor as GID, then we look for the first unused gid
-    #in the range.
-    if [ $g -ge $maxgid ]; then
-      g=$mingid
-      for i in $gidlist
-      do
-        if [ $g -eq $i ]; then g=`expr $g + 1` ; fi
-        if [ $g -eq $oldg ]; then g=`expr $g + 1` ; fi
-        if [ $i -ge $maxgid ]; then break; fi
-      done  
-
-      if [ $g -ge $maxgid ]; then
-        echo Error: GID range is full!
-        exit 1
-      fi
-    fi
-  fi
-done
-
-unset gidlist
-
-if [ $createinstall -eq 1 ]; then
-  echo Creating group install with gid $oldg
-  groupadd -g $oldg install || exit 1
-else
-  echo Group install has gid $oldg
-fi
-if [ $creategroup -eq 1 ]; then
-  echo Creating group $gname with gid $g
-  groupadd -g $g $gname || exit 1
-else 
-  echo Group $gname has gid $g
-fi
-
-
-
-useradd -c "${description}" -d ${home} -g ${gname} -G install \
-        -s /bin/bash -u ${u} ${name}  || exit 1
-
-mkdir -p $home || exit 1
-
-yes n|cp -ai -R ${skel}/{[^.],.[^.],..?}* ${home} 2>/dev/null >/dev/null
-
-cd ${home}
-chown --recursive ${u}.${g} .
-
-
-exit 0
--------------------- end $LFS/sbin/add_package_user ------------------------
-
-
-If you use these scripts, you can install a new package like this
-
-install_package 'Foo description' foo foogroup
-
-and the package user foo will be created and you will automatically be su'd to 
-it and put into the package user's home directory. Now just copy the tarball
-from your download directory, untar and install. It's no more work than
-doing it as root.
-
-
-############################################################################
- Pitfalls and Solutions
-############################################################################
- 
-There are some pitfalls when you use this system. The following situations are
-common:
-
-1. A package install script is poorly written and insists on changing
-   ownership/permissions of system directories or its own files.
-   
-2. A package install script has a legitimate reason to change 
-   ownership/permissions of files it installs.
-   
-3. Package A contains a program that is also part of package B. Package B
-   was installed first.
-   
-4. A package tests if the user installing it is root and does not install
-   certain programs otherwise.
-   
-5. A package creates a directory that other packages need to write to.
-
-1-3 usually result in an "Operation not permitted" error during make install.
-Note that this is not actually a flaw of the package user scheme, it's a
-feature. It's the reason why we made the install directories sticky and use
-package users in the first place. We don't want stuff like this to happen
-without our (divine :-) intervention. Fixing these issues is usually easy:
-
-1. Look at the output from "make install". It will contain the offending
-   command such as "install --owner root foo /bin" right before the
-   "Operation not permitted" error. grep through the Makefiles of the package
-   and remove the offending switch (in this case "--owner foo"). 
-   Sometimes you may not want to remove it altogether but may need to change 
-   it to something harmless. For instance "install -m 4755 ..." which tries to 
-   set the setuid bit should be changed to "install -m 755 ...".
-   You can automate these changes with a sed script or use a wrapper script
-   around install (see below) to avoid having to manually change Makefiles.
-   Note that you either have to perform these changes *after* the configure
-   step or you have to modify the source Makefiles (usually Makefile.in or
-   Makefile.am).
-
-2. This is basically like 1 but in this case the package actually has a reason
-   (that you accept) for doing what it does. This is seldom but happens for
-   some packages that install setuid root programs that you want to have
-   setuid root, such as ping. In this case, act like in case 1 and execute
-   the appropriate changes manually as root afterwards,
-   such as chown root.root /bin/ping && chmod 4755 /bin/ping.
-   
-3. In this case you have to decide which package you actually want to provide
-   the program in question. If you want to replace package B's program with
-   that of package A, simply delete the program manually as root.
-   If you don't want package A to overwrite the program with its own,
-   grep through the Makefiles for the name of the program in question (and
-   its manpages). Usually you will find a list like
-   PROGRAMS=foo bar fubar barfu
-   and it is sufficient to remove the program from this list. In very rare
-   cases you may need to remove some "install <programname> <destination>"
-   lines from the Makefile.
-   
-4. This case is usually documented in the INSTALL file of the package and a 
-   make target to install the programs left out, such as "install-root", is 
-   provided. So this is not normally an issue.
-
-5. This case is easy to fix by assigning the directory in question to the 
-   install group and making it group-writeable and sticky. This does not even
-   have to be done as root. The package user who created the directory has the
-   permissions to do it. So you can insert an appropriate line into the 
-   Makefile.
-
-Manually changing Makefiles is annoying, even if it happens only occasionally.
-Sed scripts do help but they have to be custom fitted to every package that
-needs them. There is a better solution, though. While building LFS with the
-package user scheme, I have noticed that although there are a lot of possible
-things a Makefile could contain which would trigger an 
-"Operation not permitted" error, only few of them are actually used.
-So far I have only encountered these problems in connection with mkdir, chgrp,
-chown and install. 
-I have written the following scripts to handle them automatically. If you make
-sure the directory where these scripts are located (in my case /usr/src/lfs)
-is the first in the PATH for every package user, you should be able to install
-most LFS packages without having to fix any Makefiles manually. 
-
-ATTENTION! These wrapper scripts allow "make install" to complete without
-aborting due to "Operation not permitted" errors. However, some of the
-operations that are suppressed this way are legitimate (see 2. above).
-For that reason, the wrapper scripts output lines beginning with "***"
-to stderr that contain the original command that the installation wanted to
-execute. 
-You *must* check these lines and if it was a legitimate operation you have to
-take appropriate action manually or the programs in question will not
-work properly. The following is a list of things you should look for and
-what you have to do:
-
-1. "*** install -m 4xxx -o root" : This wants to make a binary setuid root.
-   The important thing here is "-m 4x". Many install scripts try to use
-   "install -m 755 -o root" or something similar. This can be ignored. The
-   owner (specified with "-o owner") is only important for binaries with mode
-   4xxx (specified with "-m 4xxx").  If you decide that the binary really 
-   should be setuid root (for the LFS base packages this is usually okay)
-   you have to do
-       chown root.root <binaryname>
-       chmod u+s <binaryname>
-
-2. "*** chgrp xxx" : This wants to change the group of a binary. This is
-   usually only done if a binary is made setgid. You will see that in the
-   output of "ls -l" like this
-   rwxr-sr-x   1 util-lin tty          8348 Dec  3  2000 write
-   The "s" in the group field tells you this is a setgid binary.
-   Right now the chgrp wrapper below only intercepts chgrp for xxx=tty
-   because that is the only thing needed for installing LFS. 
-   If such a call has been intercepted and you want the binary to be setgid,
-   you have to do the following:
-   	chgrp xxx <binaryname>
-   	chmod g+s <binaryname>
-
-TIP:
-    It is important that you check the error log religiously when installing
-    a package as a package user, especially if you use the scripts below.
-    
-    To make this easier, install like this
-    
-      make install 3>&1 1>&2 2>&3 | tee install.err
-      
-    This will give you the normal make output (i.e. errors and normal messages)
-    to the screen but in addition to that it will put a copy of all error 
-    messages into install.err. You can "cat install.err" after the installation
-    to examine error messages.
-    Note that "make install | tee install.err" does *not* work. This would
-    copy all normal messages *without* the errors.
-    
-    If you want to redirect screen output (i.e. the complete install log,
-    including errors and non-errors) to a file, do it like this
-
-      { make install 3>&1 1>&2 2>&3 | tee install.err ;} &>install.log
-
-    You should probably create a shell function for this to save you typing.
-
-
-Here are the wrapper scripts:
-
-------------- begin $LFS/usr/src/lfs/wrappers/mkdir --------------------------
-#!/bin/sh
-
-DAISY_CHAIN=""
-
-for p in $(type -ap mkdir) ; do
-  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
-done
-
-if [ ! -n "$DAISY_CHAIN" ]; then
-  echo Cannot find real ${0##*/} command 
-  exit 1
-fi
-
-if [ $UID == 0 ]; then
-  exec $DAISY_CHAIN "$@"
-fi
-
-watchdir=/usr/share/locale
-
-cmdline="$@"
-
-dirs=""
-for((i=$#; $i>0;))
-do
-  a="$1"
-  shift 1; i=$(($i-1))
-  case "$a" in
-    $watchdir/*) dirs="$dirs ""`expr $a : "$watchdir/\(.*\)"`" 
-                 set -- "$@" "$a" 
-                 ;;
-    *) set -- "$@" "$a" ;;
-  esac
-done
-
-$DAISY_CHAIN "$@" || exit $?
-
-test z"$dirs" != z &&
-echo 1>&2 '***' mkdir "$cmdline"
-for dir in $dirs ; do
-  cumuldir=""
-  for d in `echo $dirs | sed 's#/# #g' -` ; do
-    cumuldir=$cumuldir$d/
-    chgrp install $watchdir/$cumuldir
-    chmod g+w,o+t $watchdir/$cumuldir
-  done  
-done
-exit 0
------------- end $LFS/usr/src/lfs/wrappers/mkdir --------------------------
-
------------- begin $LFS/usr/src/lfs/wrappers/chgrp ------------------------
-#!/bin/sh
-
-DAISY_CHAIN=""
-
-for p in $(type -ap chgrp) ; do
-  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
-done
-
-if [ ! -n "$DAISY_CHAIN" ]; then
-  echo Cannot find real ${0##*/} command 
-  exit 1
-fi
-
-if [ $UID == 0 ]; then
-  exec $DAISY_CHAIN "$@"
-fi
-
-if [ "$1" == "tty" ]; then
-  echo 1>&2 '***' chgrp "$@"  
-else
-  $DAISY_CHAIN "$@" || exit $?
-fi
-
-exit 0
------------- end $LFS/usr/src/lfs/wrappers/chgrp --------------------------
-
------------- begin $LFS/usr/src/lfs/wrappers/chown ------------------------
-#!/bin/sh
-
-DAISY_CHAIN=""
-
-for p in $(type -ap chown) ; do
-  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
-done
-
-if [ ! -n "$DAISY_CHAIN" ]; then
-  echo Cannot find real ${0##*/} command 
-  exit 1
-fi
-
-if [ $UID == 0 ]; then
-  exec $DAISY_CHAIN "$@"
-fi
-
-if [ "$1" == "root.root" ]; then
-  echo 1>&2 '***' chown "$@"  
-else
-  $DAISY_CHAIN "$@" || exit $?
-fi
-
-exit 0
--------------- end $LFS/usr/src/lfs/wrappers/chown ------------------------
-
------------- begin $LFS/usr/src/lfs/wrappers/install ----------------------
-#!/bin/sh
-
-localedir=/usr/share/locale
-cmdline="$@"
-manpagesowner=man-pages
-
-DAISY_CHAIN=""
-
-for p in $(type -ap install) ; do
-  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
-done
-
-if [ ! -n "$DAISY_CHAIN" ]; then
-  echo Cannot find real ${0##*/} command 
-  exit 1
-fi
-
-if [ $UID == 0 ]; then
-  exec $DAISY_CHAIN "$@"
-fi
-
-
-	#********** test if we create directories ********************
-if [ \( z"$1" = z"-d" \) -o \( z"$1" = z"-m" -a z"$3" = z"-d" \) ]; then  
-  locdirs=""
-  notify=0
-  havedir=0
-  for((i=$#; $i>0; ))
-  do
-    a="$1"
-    shift 1; i=$(($i-1))
-    case "$a" in
-      -o|-g|--owner|--group) notify=1 
-      			shift 1; i=$(($i-1))
-          		set -- "$@" 
-          ;;
-      $localedir/*) if [ ! -d "$a" ]; then
-      		      locdirs="$locdirs ""`expr $a : "$localedir/\(.*\)"`" 
-                      set -- "$@" "$a"
-                      havedir=1
-                    else
-                      notify=1
-                      set -- "$@"
-                    fi  
-                   ;;
-      */*|/sbin) if [ ! -d "$a" ]; then 
-      	     set -- "$@" "$a" 
-      	     havedir=1
-      	   else
-      	     notify=1
-      	     set -- "$@"
-      	   fi             
-      	   ;;
-      *) set -- "$@" "$a" ;;
-    esac
-  done
-  
-  test $notify -eq 1 -o z"$locdirs" != z && \
-  					echo 1>&2 '***' install "$cmdline"
-
-  test $havedir -eq 0 && exit 0
-
-  $DAISY_CHAIN "$@" || exit $?
-  
-  test z"$locdirs" != z &&
-  for dir in $locdirs ; do
-    cumuldir=""
-    for d in `echo $locdirs | sed 's#/# #g' -` ; do
-      cumuldir=$cumuldir$d/
-      if [ -d $localedir/$cumuldir ]; then
-        chgrp install $localedir/$cumuldir
-        chmod g+w,o+t $localedir/$cumuldir
-      fi  
-    done  
-  done
-
-else  #if "$1" != "-d"  ,i.e. we do not create directories *****************
-  notify=0
-  for((i=$# ; $i>0; ))
-  do
-    a="$1"
-    shift 1; i=$(($i-1))
-    case "$a" in
-     -m)      set -- "$@" "$a" 
-              a="$1"
-              shift 1; i=$(($i-1))
-              case "$a" in
-                4755) notify=1 ; set -- "$@" "755" ;;
-                *) set -- "$@" "$a"  ;;
-              esac
-          ;;
-      -m4755) notify=1 ; set -- "$@" "-m755" ;;
-      -o|-g|--owner|--group)    notify=1 
-      		shift 1; i=$(($i-1))
-          	set -- "$@" 
-          ;;
-      */man/man?/*) 
-                if [ -e "$a" -a ! -O "$a" ]; then
-                  if [ `find "$a" -printf \%u` = $manpagesowner ]; then
-                    notify=1
-                    set -- "$@" not_installed
-                  else
-                    set -- "$@" "$a"
-                  fi  
-                else
-                  set -- "$@" "$a"
-                fi
-          ;;    
-      *) set -- "$@" "$a" ;;
-    esac
-  done
-
-  test $notify -eq 1 && echo 1>&2 '***' install "$cmdline"
-
-  $DAISY_CHAIN "$@" || exit $?
-fi
-
-exit 0
------------ end $LFS/usr/src/lfs/wrappers/install --------------------------
-
-If you improve any of these scripts, I would be grateful if you could mail
-me your changes together with a note saying which package prompted the
-change. Note that these scripts are supposed to have minimal intrusiveness.
-So writing a common case "-m*)" instead of the case "-m4755" is undesirable.
-The scripts should only deal with the problems that have actually been
-encountered, not all possible problems.
-
-#############################################################################
- LFS specifics
-#############################################################################
- 
-For the user name of the package users I always use the name of the package
-without the version number, including dashes and possibly exceeding 8
-characters in length, e.g. "util-linux". 
-Aside from ls -l which chops off the last characters
-of the user name I have not noticed any problems with this. The other programs
-I have tested seem to deal with these user names just fine. 
-If you encounter problems, please report them to me.
-
-Now how do we apply the above to the building of an LFS system ?
-
-##########################################################################
-Pre-chroot phase 
-##########################################################################
-
-We don't use package users in the pre-chroot phase. This does not mean we
-install as root. I suggest building the pre-chroot system as a normal user.
-That way, you can later distinguish files created inside chroot (these
-have uid 0 or the uid of a package user) and remaining files created during 
-the pre-chroot phase (these carry the uid of your normal user account on
-your host system). Building as an ordinary user also protects you against 
-typos that might otherwise cause a package to overwrite files on your host
-system.
-
-The actual commands of the pre-chroot phase don't need be changed but you
-have to do some additional things.
-The first problem is that we need find right after installing glibc inside
-chroot. The best thing to do is to build a static version during the 
-pre-chroot phase like this:
-
-./configure --prefix=$LFS/usr --disable-nls &&
-make LDFLAGS=-static CPPFLAGS=-Dre_max_failures=re_max_f2 &&
-make libexecdir=$LFS/usr/bin install
-
-Another problem is that some programs such as chown can not resolve usernames
-before glibc is installed. Fortunately most programs accept a numeric UID
-or GID. There is one nasty exception, though: su. The most fundamental
-program when using package users doesn't swallow numeric ids :-|
-
-Now how do we become a package user before glibc is installed ? 
-If you guessed that I have a written a script to replace it, you guessed ...
-... wrong :-) I have written a C program to replace it. 
-
-It just happens that sh-utils
-contains an su program which is not used in LFS. It gets installed 
-statically linked during the pre-chroot phase, is never used there (assuming
-a standard LFS build), gets replaced with a dynamically linked version when 
-sh-utils is reinstalled and then is finally replaced by the su from shadow 
-which is the version we will use when the LFS system is finished. So all
-you need to do is to replace the file src/su.c in the sh-utils source tree
-with the following file before compiling your chapter 5 sh-utils.
-Note that if you compile chapter 5 as non-root, you need to issue the command
-`make install-root' after `make install' or sh-utils won't install su.
-
--------- begin $LFS/usr/src/sh-utils/sh-utils-<version>/src/su.c ------------
-#include <stdio.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-#include <grp.h>
-
-#define NUMGIDS 1024
-
-int main(int argc,char* argv[])
-{
-  char* Res;
-  char Buffy[4096];
-  uid_t tuid=-1,uid;
-  gid_t gid;
-  int i;
-  FILE* File;
-  char* command=NULL;
-  char* shell;
-  char* HOME;
-  gid_t gid_list[NUMGIDS];
-  ssize_t NumGids=0;
-
-  if (argc>1) 
-  {
-    if (strcmp(argv[1],"--help")==0) 
-      { fprintf(stdout,"There is no help!\n"); exit(0);}
-    if (strcmp(argv[1],"--version")==0) {fprintf(stdout,"0.6\n"); exit(0); }
-  }
-
-  if ((argc==4) && (strcmp(argv[2],"-c")==0)) command=argv[3]; else
-  if (argc!=2)
-  {
-    fprintf(stdout,"USAGE: su username|uid [-c command]\n");
-    return 1;
-  };
-
-  i=0;
-  while(isdigit(argv[1][i])) ++i;
-  if (argv[1][i]==0) tuid=atol(argv[1]);
-
-  File=fopen("/etc/passwd","rb");
-  if (File==NULL) {perror("/etc/passwd"); return 1;};
-  
-  while(1)
-  {
-    errno=0;
-    Res=fgets(Buffy,1024,File);
-    if (Res==NULL) {
-      if (errno!=0) perror("/etc/passwd"); 
-        else fprintf(stderr,"su: User not found!\n");
-      return 1;
-    };
-    
-    Res=strtok(Buffy,":");
-    if (Res==NULL) continue;
-    strtok(NULL,":");
-    uid=atol(strtok(NULL,":"));
-    gid=atol(strtok(NULL,":"));
-    strtok(NULL,":");
-    HOME=strtok(NULL,":");
-    shell=strtok(NULL,":");
-    if (tuid==uid) {argv[1]=strdup(Buffy); break;}
-    if (strcmp(argv[1],Buffy)==0) break;
-  };
-  HOME=strdup(HOME);
-  shell=strdup(shell);
-  
-  File=fopen("/etc/group","rb");
-  if (File==NULL) {perror("/etc/group"); return 1;};
-  
-  while(1)
-  {
-ContinueReadingEtcGroup:
-    errno=0;
-    Res=fgets(Buffy,1024,File);
-    if (Res==NULL) {
-      if (errno!=0) {perror("/etc/group"); return 1;} else break;
-    };
-    
-    Res=strtok(Buffy,":,\n");
-    if (Res==NULL) continue;
-    strtok(NULL,":,\n");
-    gid_list[NumGids]=atol(strtok(NULL,":,\n"));
-    Res=strtok(NULL,":,\n");
-
-    while(Res!=NULL)
-    {
-      if (strcmp(Res,argv[1])==0) 
-      {
-        ++NumGids;
-        if (NumGids>=NUMGIDS) goto SetNewIdentity; 
-        		 else goto ContinueReadingEtcGroup;
-      };
-      Res=strtok(NULL,":,\n");
-    };
-  };
-
-SetNewIdentity:
-  if (command==NULL) command=shell;
-  setenv("HOME",HOME,1);
-  setgroups(NumGids,gid_list);
-  setgid(gid);
-  setuid(uid);
-  errno=0;
-  i=system(command);
-  if (((i<0) || (i==127)) && (errno!=0)) {perror("/bin/sh"); return 1;};
-  return i;
-};
--------- end $LFS/usr/src/sh-utils/sh-utils-<version>/src/su.c ------------
-
-This su program accepts user names as well as numeric UIDs. It does its own
-name resolution using /etc/passwd so it works even without glibc being
-installed. 
-Note that sh-utils installs the su program with the setuid bit set. 
-If you install the pre-chroot system as an ordinary user (which you should 
-for safety reasons), this will result in a su that doesn't work even when 
-executed by root. Simply remove the setuid bit like this
-
-chmod u-s $LFS/bin/su
-
-and su will work fine once we have entered the chroot environment (where
-we work as root). Note that this allows you to su from root to a package
-user but not the other way around. If you want to be able to su from a package
-user to root you will have to make su setuid root 
-(i.e. chown root.root $LFS/bin/su && chmod u+s $LFS/bin/su). Make sure that
-you don't keep such an su lying around on a system that others have access to.
-The above su does not check for a password, so if you make it setuid root,
-everyone can use it to become root without a password!
-
-
-##########################################################################  
- Chroot phase - preparing the LFS system: 
-##########################################################################
- 
-This is the tricky part. Once we
-have entered chroot, we have to assign install directories to the
-install group and make them group-writeable. However, since glibc is not
-yet installed, we can't use user names, yet. Furthermore, groupadd and useradd
-which are part of the shadow package are not installed, yet.
-This means that we can't create any package users, at least not without
-editing /etc/group and /etc/passwd manually. 
-But don't despair. The following
-scripts make nice replacements for useradd and groupadd as long as shadow
-isn't there. Note that they only accept the exact syntax with which the
-useradd and groupadd commands are used in the add_package_user script.
-I assume you will be using the install_package/add_package_user scripts to
-add package users to the system. Here are the scripts:
-
---------------------- begin $LFS/usr/sbin/useradd ----------------------------  
-#!/bin/sh
-if [ $# -ne 13 -o z$1 != z-c -o z$3 != z-d -o z$5 != z-g -o z$7 != z-G -o z$9 != z-s -o z${11} != z-u ]; then
-echo 1>&2 USAGE: useradd -c description -d home -g maingroup -G addgroup -s shell -u uid login 
-exit 1
-fi
-
-#test if user already exists
-grep "^${13}:.*" /etc/passwd 
-if [ $? -eq 0 ]; then
-  echo 1>&2 $0: User does already exist
-  exit 1
-fi       
-
-g=`grep ^${6}:.\* /etc/group | cut -d : -f 3 -`
-if [ z${g} = z ]; then
-  echo 1>&2 $0: Group ${6} does not exist!
-  exit 1
-fi
-
-grep ^${8}:.\* /etc/group >/dev/null || \
-{
-  echo 1>&2 $0: Group ${8} does not exist!
-  exit 1
-}
-
-
-cp /etc/passwd /tmp/passwd123456
-echo "${13}:x:${12}:$g:$2:$4:/bin/bash" \
-| sort -t : -k3,3n -m /tmp/passwd123456 - > /etc/passwd
-
-
-cp /etc/group /tmp/group123456
-sed  -e 's/^\('"${8}"':[^:]*:[0-9]*:..*\)$/\1,'"${13}"'/' \
-     -e 's/^\('"${8}"':[^:]*:[0-9]*\):$/\1:'"${13}"'/' \
-     						/tmp/group123456 >/etc/group
----------------------- end $LFS/usr/sbin/useradd ----------------------------  
-
---------------------- begin $LFS/usr/sbin/groupadd --------------------------
-#!/bin/sh
-if [ $# -ne 3 -o z$1 != z-g ]; then
-echo 1>&2 USAGE: groupadd -g gid groupname
-exit 1
-fi
-
-#test if group already exists
-grep "^${3}:.*" /etc/group 
-if [ $? -eq 0 ]; then
-  echo 1>&2 $0: Group does already exist
-  exit 1
-fi       
-
-cp /etc/group /tmp/group123456
-echo ${3}:x:${2}: | sort -t : -k3,3n -m /tmp/group123456 - > /etc/group
---------------------- end $LFS/usr/sbin/groupadd ----------------------------
-
-These scripts overcome the problem of the missing shadow utilities. 
-
-With the above scripts and su program we now have everything we need to
-begin our chroot phase. 
-
-###########################################################################
- Tips before you chroot
-###########################################################################
- 
-Whenever add_package_user creates a new package user it copies the files
-from /etc/skel-package (if you create this directory) to the new package
-user's home directory. Symlinks are copied as symlinks.
-A useful symlink to place in /etc/skel-package is one like
-
-.bashrc -> /etc/bashrc_package 
-
-with something like the following:
-
------------------- begin $LFS/etc/bashrc_package --------------------------
-#first load basic configuration to make system work normal
-source /etc/bashrc_basic
-
-export PATH=/usr/src/lfs/wrappers:$PATH
-
-#make prompt reflect that we are a package user. Do it via USER_PROMPT_COMMAND
-#rather than PROMPT_COMMAND because we want to keep root's prompt if we su to root
-export USER_PROMPT_COMMAND='PS1="package \u:"`pwd`"> "'
-
-alias mafobu='make -f /usr/src/lfs/mafobu'
-
-#The following command will put us in the home directory. 
-cd
------------------- end $LFS/etc/bashrc_package ----------------------------
-
------------------- begin $LFS/etc/bashrc_basic ----------------------------
-#This file should be sourced by all users' .bashrc files
-
-if [ $UID -eq 0 ]; then
-  export PATH=/usr/local/sbin:/sbin:/bin:/usr/sbin:/usr/bin
-else
-  export PATH=/usr/local/bin:/bin:/usr/bin
-fi
-
-  #set a red prompt when user is root. If a user wants to override this
-  #s/he should use USER_PROMPT_COMMAND instead of PROMPT_COMMAND in order to 
-  #keep 
-  #root's prompt when su'ed to root. If a user wants to change PS1 directly
-  #s/he should do "unset USER_PROMPT_COMMAND".
-export PROMPT_COMMAND='if [ $UID -eq 0 ]; then \
-  PS1="\[\033[0;31m\]root@\h:"`pwd -P`"# \[\033[0m\]" ; \
-    else eval $USER_PROMPT_COMMAND ; fi'
-  #make PROMPT_COMMAND read-only to protect against careless users
-declare -r PROMPT_COMMAND
-  #set a reasonable default USER_PROMPT_COMMAND
-export USER_PROMPT_COMMAND='PS1="\u@\h:"`pwd`"> "'
-
-  #make keys (del, bs, home, end,...) work normal
-export INPUTRC=/etc/inputrc
-bind -f $INPUTRC
------------------- end $LFS/etc/bashrc_basic ------------------------------
-
-
-
-Another useful file to place in /etc/skel-package is a .project file like
-this:
-
------------------- begin $LFS/etc/skel-package/.project ------------------
-DESCRIPTION:
-  bogus package
-CONTENTS:
-  foo,bar,fubar
-LAST UPDATED:
-  30 Feb 2042
-DOWNLOAD LOCATION:
-  ftp://ftp.gnu.org/gnu/foo/
-WEB SITE:
-  <none>
-INSTALL NOTES:
-GENERAL NOTES:
------------------ end $LFS/etc/skel-package/.project ------------------
-
-Update this file whenever you re/install a package. It is called .project
-so that it is automatically displayed when you issue the command 
-"finger <package>" or "pinky -l <package>".
-
-
-###########################################################################
- Inside the chroot environment
-###########################################################################
-
-After you have chroot'ed do
-
-groupadd -g 10000 install
-
-which will create the install group. Now use 
-
-chown 0.10000 `cat /tmp/installdirs`
-chmod ug=rwx,o=rx `cat /tmp/installdirs`
-
-to assign directories to the install group. Note that we do not make the
-directories sticky, yet. This is because they still contain files belonging
-to root or some unknown user (if you installed pre-chroot as non-root). These
-files must be overwriteable. The file /tmp/installdirs is the following list:
-
------------------ begin $LFS/tmp/installdirs ------------------------------
-/usr/bin
-/usr/etc
-/usr/sbin
-/usr/include
-/usr/lib
-/usr/man/man?
-/usr/doc
-/usr/info
-/usr/local/man/man?
-/usr/local/doc
-/usr/share
-/usr/share/dict
-/usr/share/doc
-/usr/share/info
-/usr/share/locale
-/usr/share/man/man1
-/usr/share/man/man2
-/usr/share/man/man3
-/usr/share/man/man4
-/usr/share/man/man5
-/usr/share/man/man6
-/usr/share/man/man7
-/usr/share/man/man8
-/usr/share/nls
-/usr/share/misc
-/usr/share/terminfo
-/usr/share/zoneinfo
-/usr/share/i18n
-/usr/share/aclocal
-/usr/local/bin
-/usr/local/etc
-/usr/local/include
-/usr/local/lib
-/usr/local/sbin
-/usr/local/share
-/usr/local/share/dict
-/usr/local/share/doc
-/usr/local/share/info
-/usr/local/share/locale
-/usr/local/share/man/man1
-/usr/local/share/man/man2
-/usr/local/share/man/man3
-/usr/local/share/man/man4
-/usr/local/share/man/man5
-/usr/local/share/man/man6
-/usr/local/share/man/man7
-/usr/local/share/man/man8
-/usr/local/share/nls
-/usr/local/share/misc
-/usr/local/share/terminfo
-/usr/local/share/zoneinfo
-/etc
-/sbin
-/bin
-/lib
------------------ end $LFS/tmp/installdirs --------------------------------
-
-Now do
-
-chown 0.10000 /usr/share/info/dir
-chmod ug=rw,o=r /usr/share/info/dir
-
-which makes sure packages can install their info pages. 
-
-
-
-#########################################################################
- Chroot phase -installing the packages 
-#########################################################################
-
-Now we can finally install glibc. Create /dev/null as root by doing
-
-mknod -m 0666 /dev/null c 1 3
-
-then do
-
-install_package "GNU C library" glibc system
-
-which will create the system group and a user glibc and will also su to the new
-glibc package user. Note that the mkdir and install wrapper
-don't work properly during the installation of glibc because they use
-the name "install" rather than the gid. This means we have to do the
-following *after* installing glibc:
-
-find /usr/share/locale/* -type d -user glibc -exec chmod ug=rwx,o=rxt \{\} \;\
-					 -exec chgrp install \{\} \;
-
-
-Now do
-
-exit
-
-to become root and begin installing the rest of the packages. Use the command
-
-install_package <description> <packagename> <group>
-
-to create and become the package user. Then unpack in that user's home 
-directory and use the guidelines below and the book's directions to 
-install each package.
-
-############################################################################
- Group guidelines
-############################################################################
-
-I recommend the following groups for use with package users:
-
-devel: development related stuff, e.g. compilers. This is not restricted to
-       software development. TeX for instance would belong in this group.
-       
-utils: Most software fits into this category, even somewhat essential software 
-       like grep or text editors.
-      
-net: network related stuff such as an ftp daemon or a web browser. This
-     group overlaps with other groups to a large extent. It should be used
-     in preference of the other groups whenever a package is clearly focused
-     towards Internet, LAN, WWW,... A utility like wget for instance would
-     go in net rather than utils. Exceptions from this rule are the groups
-     docs, addons, games and mmedia. If a package fits into one of those 
-     groups, use the respective group instead of net.
-     
-docs: Documentation related packages, such as a tarball with Linux howtos.
-      Note that software to create documentation such as XML processors should
-      probably go in devel and software to view or post-process documentation
-      such as man or groff should probably go in utils.
-      
-system: important system software, such as bash. This group should be used
-        only for really essential packages. Most packages you would put in 
-        this group are better put into "utils". Vi for instance belongs in 
-        utils. 
-        It is unlikely that any package not part of basic LFS belongs in the
-        system group.
-        
-libs: What utils is for executables, libs is for libraries. Libraries that are
-      not strongly related to any of the other categories should go here, such
-      as zlib or libpng.
-      Essential system libraries such as glibc, ncurses or gettext should
-      go in system instead.
-      The libs group is also used for run-time environments such as the
-      Java Virtual Machine, dosemu and wine. Other emulators like MAME for
-      instance should probably go into games instead. 
-     
-games: what do you expect ;-)
-
-mmedia: This is the group for audio and video editors, mp3 players etc.
-
-apps: Applications such as spreadsheets and word processors (not text editors)
-      but also CAD software and graphics software such as Gimp.
-      The apps group is a bit like utils, but apps are usually more user 
-      friendly and more streamlined and focused than utils. 
-      Apps feel less geekish and nerdish than
-      utils. Emacs for instance belongs in utils, not in apps.
-      
-addons: plugins, filters and similar that are meant to be used in conjunction
-       with another package.
-       
-x: software that relates to the X Window System in general and does not fit
-   into any of the other categories, such as the X server itself or window 
-   managers.
-   Most X software should be put into other more specific groups.
-   A game like xmines would go in games for instance and a text editor for
-   X would go in utils.
-   
-kde: Software that relates to KDE and does not fit into
-     any other category. This group should be used with care. 
-     Do *not* use it for all KDE software. K Office for instance belongs in
-     apps. Konqueror belongs in net.
-     
-gnome: Software that relates to GNOME and does not fit into
-       any other category. This group should be used with care. 
-       Do *not* use it for all GNOME software. Gimp for instance belongs 
-       in apps. A GNOME-aware window manager that works with plain X should
-       go in the x group.
-
-The following is a list of the LFS packages with the user.group assignments
-I think are appropriate. The user name in general should be the name of
-the main tarball without extensions and version. The groups try to follow
-the guidelines above but sometimes it is hard to find the "correct" group.
-The list also contains some notes I made when I installed them. 
-If you use the mkdir, chgrp and install wrappers, you should
-not have any trouble.
-
-glibc.system:
-  see above.
-
-MAKEDEV: not installed as a package user
-
-man-pages.docs
-findutils.utils
-mawk.devel:
-	rm /usr/bin/mawk /usr/share/man/man1/mawk.1 
-	as root before `make install'
-ncurses.system
-vim.utils
-ed.utils
-gcc.devel:
-	Before `make install' assign the /usr/lib/gcc-lib and /usr/include/g++
-	to the gcc package user by doing (as root)
-	  chown -R gcc. /usr/lib/gcc-lib /usr/include/g++
-bison.devel
-less.utils
-groff.utils
-man.utils
-perl.utils
-m4.devel
-texinfo.utils
-autoconf.devel
-automake.devel:
-	Creates the directory /usr/share/aclocal. This directory is written to
-	by other packages, so chgrp install and chmod g+w,o+t it.
-
-bash.system:
-	When ./configure is done as a package user (more precisely when done 
-	in a su environment), it will fail to detect /dev/stdin. This will 
-	cause bash to compile an emulation of /dev/std* and /dev/fd/*. 
-	I actually prefer this emulation because it matches the description 
-	in the manpage while the normal behaviour (i.e. to open the 
-	respective device) does not always.  If a normal bash is desired, 
-	use sed to change configure and replace 
-	"test -r /dev/stdin" with "test -e /dev/stdin" (same for /dev/fd). 
-	[ This information is for bash 2.05, I reported the issue so it may
-	be fixed in future versions. ]
-flex.devel
-file.utils
-libtool.devel
-bin86.devel
-binutils.devel
-bzip2.utils
-gettext.system
-kbd.system
-diffutils.utils
-e2fsprogs.utils
-fileutils.system
-grep.utils
-gzip.utils
-lilo.system
-make.devel:
-	make wants to be setgid kmem in order for the -l option to work.
-	If you are not a developer who knows what this option does, you
-	don't need it and should not give make special privileges.
-	[UPDATE] On Linux the -l option seems to work even if make is not
-	setgid kmem.
-
-linux kernel: not installed as package user
-modutils.system:
-	The modutils check if modules are owned by root before using them.
-	This is the reason why the linux kernel should be compiled and
-	installed as root, rather than as a package user.
-
-netkit-base.net
-patch.utils
-procinfo.utils
-procps.utils
-psmisc.utils
-sed.utils
-sh-utils.system
-net-tools.net
-shadow.system:
-	This package installs quite a few setuid root progs. If you're not
-	religious about package users you might want to install this one
-	as root.root to make life easier for yourself.
-	If you do install as package user don't forget to make the
-	binaries in question setuid root manually afterwards.
-	After installing shadow make sure that the useradd and groupadd
-	scripts have been properly replaced. Execute
-	  find / -maxdepth 3 -name groupadd
-	to make sure that you don't have 2 copies (e.g. one in /sbin and
-	one in /usr/sbin)  
-	
-
-sysklogd.system
-	This package has /usr/bin/install hardwired, so install with
-	  make INSTALL=install install
-	to make it use the wrapper.
-
-sysvinit.system:
-	This one is a bit tricky. You have to create /dev/initctl manually
-	as root	*before* doing "make install" because a package user does
-	not have permission to write to /dev. So do (as root!!)
-	  rm -f /dev/initctl
-	  mknod -m 600 /dev/initctl p
-
-tar.utils
-textutils.utils
-util-linux.system:
-	Don't forget to make mount and umount setuid root manually after
-	installing this package. And the write program wants to be
-	setgid tty.
-
-###########################################################################
- Final steps
-###########################################################################
-
-After installing everything, make the install directories sticky:
-
-chmod ug=rwx,o=rxt `cat /tmp/installdirs`
-
-If you installed pre-chroot as a normal user there are now some directories
-owned by that user even though they should be owned by a package user. This
-happens because the package users in question did not/could not recreate
-these directories. The following script will fix that. It works by looking
-for directories not owned by a registered user (-nouser option). The list
-of these directories is processed in a for loop. For each directory find is
-then used to look for all files owned by a registered user and to list those
-users. With "sort -u" (unique) we get a list of registered users that have
-files in the directory in question and wc tells us how many of these users
-there are. If there is only one such user (i.e. all files in the directory
-belong either to an unregistered user or the one registered user we 
-identified) then we assign the directory to this user.
-
------------------ begin $LFS/usr/src/lfs/fixowner -------------------------
-#!/bin/sh   
-#find all directories owned by an unknown user (i.e. the normal user
-#account you installed pre-chroot with, if you installed as a normal
-#user) and assign those that have an unambiguous intended owner (i.e.
-#only files belonging to a single owner aside from the unknown one
-#are found in the directory) to that owner.
-get_dir_owners() 
-{ 
-  owners=`find $1 -not -nouser -printf "%u\n" | sort -u `
-  num=`echo $owners | wc -w | tr -d " "`
-} 
-
-for dir in `find / -path "/proc" -prune -or -type d -nouser -print` 
-do 
-  get_dir_owners $dir 
-  if [ $num == 1 ]; then 
-    chown `echo $owners | tr -d " "`. $dir 
-    chmod u=rwx,go=rx $dir 
-    echo "Assigning $dir to $owners"
-  fi  
-done
------------------ end $LFS/usr/src/lfs/fixowner ---------------------------
-
-Finally you should
-use find to find files that still belong to the user you
-installed pre-chroot with. You can also use find to identify any directories
-that are group-writeable and not sticky. You should also check for setuid
-and setgid programs that don't belong to root. Apply your common sense to
-deal with these files (or send me a mail so I can mention the issue here).
-
-find / -path "/proc/*" -prune -or -perm +u+s -printf "%p: suid %u\n"
-find / -path "/proc/*" -prune -or -perm +g+s -printf "%p: sgid %g\n"
-find / -path "/proc/*" -prune -or \
-       -type d -perm +o+w -not -perm +o+t -printf "%p: world-writeable\n"
-find / -path "/proc/*" -prune -or -type d -perm +g+w -not -perm +o+w \
-                             -not -perm +o+t -printf "%p: group-writeable\n"
-find / -path "/proc/*" -prune -or \
-       -not -type d -not -type l -perm +o+w -printf "%p: world-writeable\n"
-find / -path "/proc/*" -prune -or -path "/dev/*" -prune -or \
-       -not -type d -not -type l -perm +g+w -not -perm +o+w \
-                                           -printf "%p: group-writeable\n"
-find / -path "/proc/*" -prune -or -nouser -printf "%p: unknown user: %u\n"
-find / -path "/proc/*" -prune -or -nogroup -printf "%p: unknown group: %g\n"
-
-
-
-###########################################################################
- Security issues with NFS
-###########################################################################
-
-If you use the network filesystem NFS, there are some things you need to
-look out for when using the package user system described in this hint.
-A fundamental security problem with NFS is that it blindly trusts the uid and 
-gid of the client. If an attacker can get access to the root account on a
-system in your network that is allowed to mount NFS shares from your server,
-or if the attacker can attach his own computer to your network, then this
-attacker can pretend to be anyone. NFS will happily allow the attacker to
-work in the NFS exported directory as any user he wants to be.
-The only exception is the root account. By default NFS exports directories 
-with the root_squash option that maps all incoming requests from uid 0 to 
-anonuid (65534 unless set in /etc/exports) and gid 0 to anongid
-(65534 unless set in /etc/exports). This protects files owned by 
-root.root. On a normal system this includes most files in /bin, /etc, /lib
-and most other directories except /home. If you use the package user scheme,
-however, most of these files are owned by package users. These files are
-not protected by the root_squash option. 
-In order to make NFS exports secure, you have to add the option "all_squash"
-to every entry in /etc/exports that exports a directory that contains 
-files owned by package users. Note that all_squash is always a good idea
-because even systems that don't use package users usually have some programs 
-owned by other users such as daemon or bin and other groups such as tty, 
-because they need to be setuid or setgid.

Added: trunk/more_control_and_pkg_man.txt
===================================================================
--- trunk/more_control_and_pkg_man.txt	2004-11-01 06:57:29 UTC (rev 904)
+++ trunk/more_control_and_pkg_man.txt	2004-11-04 05:13:06 UTC (rev 905)
@@ -0,0 +1,1780 @@
+AUTHOR: Matthias S. Benkmann <article at winterdrache dot de>
+
+DATE: 2004-11-01
+
+LICENSE: Creative Commons Attribution-NoDerivs 2.0 
+         (http://creativecommons.org/licenses/by-nd/2.0/)
+
+SYNOPSIS: More Control and Package Management using Package Users (v1.0)
+
+DESCRIPTION:
+-You want to know which packages your files belong to ?                 
+-You want to deinstall software that doesn't have make uninstall ?      
+-You are bothered by programs installed setuid root behind your back ?  
+-You don't like packages quietly overwriting files from other packages ?
+-You don't like package managers like RPM ?                             
+-YOU WANT TOTAL CONTROL USING ONLY UNIX BUILTINS ?                      
+
+ATTACHMENTS:
+http://www.linuxfromscratch.org/hints/downloads/attachments/more_control_and_pkg_man/more_control_helpers.tar.bz2
+
+PREREQUISITES:
+For use with LFS book 6.0: Brain.
+For use with LFS book later than 6.0: Brain (awake, good working condition).
+
+HINT:
+
+########################################################################### 
+ Contents
+###########################################################################
+
+1. Preface
+2. Overview
+
+- PART 1: General Information -
+
+3. Package Users
+  3.1 Introduction
+  3.2 User Name
+  3.3 Groups
+  3.4 Home Directory
+4. Common Problems
+  4.1 Introduction
+  4.2 General Procedure
+  4.3 Permission Changes
+  4.4 Ownership Changes
+  4.5 Write to Non-Install Directory
+  4.6 Delete or Overwrite File
+  4.7 /sbin/ldconfig
+5. The more_control_helpers Archive
+  5.1 Overview
+  5.2 The Wrappers
+  5.3 add_package_user/install_package
+  5.4 forall_direntries_from
+  5.5 uninstall_package
+  5.6 list_suspicious_files/list_suspicious_files_from
+  5.7 list_package
+  5.8 grep_all_regular_files_for
+  5.9 The etc Directory
+  5.10 Temporary Files
+  
+- PART 2: LFS Specifics -
+
+6. Pre-Chroot Phase (Chapter 5)
+7. Chroot Phase (Chapter 6)
+  7.1 Preparations
+  7.2 Walkthrough: Installing linux-libc-headers
+  7.3 Known Issues with LFS Packages
+8. Sanity Checks
+  8.1 Suspicious Files
+  8.2 References to Temporary Files
+
+- APPENDICES -
+
+A. Security Issues
+  A.1 NFS
+  A.2 Daemons
+B. Package Categories
+C. Acknowledgements and Changelog
+  
+
+########################################################################### 
+ 1. Preface
+###########################################################################
+
+Let's say I have written a program that you would like to use. To make it
+easier for you I come over to install it for you. Would you give me the root
+account and then leave the room ? No ? Then why do you give it to complete
+strangers who you have never seen in your life, to install software packages
+pulled from some Internet server, that come with no warranty and don't even 
+list their contents in the README, although they will happily spread them all 
+over your system ?
+
+It is a mystery why Unix admins who wouldn't even trust their employer with
+more than a normal user account carelessly execute complex and incomprehensible
+installation scripts with full root rights.
+
+Users and groups are the basic security principle in a Unix system. They have
+been used successfully for a long time to monitor who has created a file and 
+to control who is allowed to delete or change it. But this control has only 
+been imposed on the files of ordinary users. What a waste! I suggest to extend
+this control to all system files. 
+
+The general idea is to create package users, i.e. user accounts with restricted
+rights, to build and install software packages, rather than doing these tasks 
+as root. Not only does this give you more control over what build and install 
+scripts may or may not do, it can also serve as a quite useful package 
+management system.
+
+
+#############################################################################
+ 2. Overview
+#############################################################################
+
+This hint is divided into 3 parts. The first part contains general information
+about the package user method. This part is the most important part of the
+hint. Read it thoroughly. The second part explains how to apply the package 
+user method to the building of an LFS system. 
+Finally, part 3 of this hint is the Appendix with information that would not
+fit anywhere else or that is not of general interest.
+
+It is inevitable that part 2 will become outdated with time as the LFS book 
+changes and new versions of the software packages used with LFS are released. 
+I make no attempt to track these changes. 
+When someone reports an issue with a package I will incorporate
+it into the hint, but larger changes that might be required due to changes in
+the LFS build methodology could take a long time to get included. The reason 
+for this (aside from lack of time) is that I consider part 2 as bonus material 
+that helps people get started but is not essential. Part 1 describes the 
+concepts, which are independent of package versions or the LFS book, and you 
+will have to rely on this information whenever part 2 fails. Don't forget 
+that part 2 only deals with the packages used by the LFS book. For all the 
+other packages you install on your system after that even an up-to-date 
+part 2 would offer no aid anyway.
+
+The previous paragraph might sound discouraging, and as you read more from the
+hint it is possible that you get the impression that the package user
+method is complicated, causes lots of difficult problems and is overall too
+much trouble for anyone but a real hardcore admin with programming experience.
+But you would be mistaken. 
+First of all, many things experienced as installation problems when working
+with the package user system are in fact desirable features. 
+If `make install' fails for some package, because it attempts to install a
+file with the same name as a pre-existing file from another package, you
+should not curse the fact that you have to spend additional time to resolve
+this issue. Instead you should be happy that you have been alerted of this
+collision that, had it gone unnoticed, could have messed up your system in
+more or less subtle ways.
+Secondly, the package user system is not an all-or-nothing approach. It
+works on a per-package basis. If a package gives you too much trouble, you
+can always decide to chicken out and finish the installation as root.
+Finally, the more_control_helpers archive provided with this hint contains
+several useful scripts that automate many aspects of software installation
+as a package user and, together with the tips given in this hint, add a lot 
+of value to the package user system. 
+So do not pass judgement until you have read at least the complete part 1,
+including the description of the more_control_helpers.
+
+
+---------------------- PART 1: General Information --------------------------
+
+
+#############################################################################
+ 3. Package Users
+#############################################################################
+
+ 3.1 Introduction
+ ----------------
+
+The basic idea of this scheme is easily explained. Every package belongs to a 
+certain "package user". When you install a package, you build and install
+the package as this package user, causing all files that are installed to be 
+owned by the package user. As a consequence all the usual package management 
+tasks can be comfortably achieved through the use of standard command line 
+utilities. A simple `ls -l <file>' will tell you, for instance, what package 
+<file> belongs to and a `find -user ...' command allows you to perform an 
+operation on all the files belonging to a certain package, e.g. delete them 
+to uninstall the package.
+
+But package management is not all that package users are good for. Because
+package users do not have root-rights, the installation of a package is
+limited in what it can do. One thing that a package user is not allowed to do,
+for example, is to overwrite files from a different package user. Clashes
+between different packages that want to install a binary, library or header 
+file of the same name are more common than you might think. With package users
+you never run the risk of package B's installation destroying files from 
+package A silently without you noticing. Every attempt of doing this during
+package B's installation will cause a "Permission denied" or
+"Operation not permitted" error so that you have the chance of taking 
+appropriate steps.
+Another thing that package users are not allowed to do is install setuid root 
+binaries. The decision to make a binary setuid root is also something that a 
+prudent admin does not want to leave up to the creator of a software package.
+
+Usually package user accounts have no valid password so that only root can su 
+to a package user, which ensures that package users do not open an additional 
+way into the system and undermine security. But you *may* set passwords 
+anyway to allow a co-admin who you want to be able to install and maintain 
+certain software packages to do so without having access to the actual root 
+account. This co-admin could for instance install, delete, change additional 
+libraries which might be necessary for his workgroup. He would be unable, 
+though, to remove or modify libraries which don't belong to him/her, such as 
+libc.
+
+
+ 3.2 User Name
+ -------------
+
+You don't need to drive yourself nuts trying to come up with 8 character
+names for the package users. I always use the name of the package without 
+the version number, including dashes and possibly exceeding 8 characters in 
+length, e.g. "util-linux", and in the several years that I've been using this 
+scheme I have not encountered any problems, nor has anyone else reported 
+trouble. The 8-character limit on user names seems to be a thing of the past.
+
+TIP:
+  You can use bash's programmable completion feature to save yourself some 
+  typing when entering commands that take a user name as an argument, such as
+  su, finger or pinky. The command 
+  
+      complete -o default -o nospace -A user su finger pinky
+      
+  tells bash to tab-complete words as user names for the commands su,
+  finger and pinky.
+  With this in place you can simply type `su linux-li<TAB>' and bash
+  will complete this to `su linux-libc-headers' (assuming that you have a
+  package user named "linux-libc-headers").
+  "-o default" tells bash that if a suitable user name does not exist, the 
+  default completion shall be attempted. 
+  "-o nospace" prevents the addition of a space after the completed word.
+  
+  This is a very useful command to put into root's .bashrc and .bash_profile.
+  
+  BTW, at http://freshmeat.net/projects/bashcompletion/
+  you can find a project that offers sophisticated completions for many
+  other commands.
+
+
+ 3.3 Groups
+ ----------
+
+Every package user belongs to at least 2 groups. One of these groups is
+the "install" group, which all package users (and only package users) belong
+to. All directories that packages are allowed to install stuff in belong to 
+the install group. This includes directories such as /bin and /usr/bin but 
+excludes directories like /root or /. 
+The directories owned by the install group are always group-writable. 
+This would be enough for the package management aspects, but without further 
+preparation this would not give added security or control because every 
+package could replace the files from a different package (the change would 
+be visible in the output from `ls -l', though).
+For this reason all install directories get the sticky attribute. This
+allows users to create new files and delete or modify their own files in
+the directory, but files from other users can not be modified or removed.
+In the rest of this hint, whenever the term "install directory" is used, it
+refers to a directory that belongs to group install, is group-writable and
+sticky. IOW, to turn <dir> into an install directory you would do
+
+    chgrp install <dir> && chmod g+w,o+t <dir>
+
+Although the install group is crucial for the package user system, it is 
+implemented as a supplementary group, rather than as the primary group for
+package users. This has at least 2 advantages. 
+One advantage is that this makes it easy to get a list of all packages 
+installed on the system with the command
+
+    grep install /etc/group
+
+A more important point, however, is that the primary group is the
+one that files created by the package user will belong to. So it will be 
+printed in the output of `ls -l' and is subject to find's "-group" test. 
+This makes it very useful for organizational purposes. 
+Following are some suggestions for how to use the primary group. 
+
+1. group name = user name
+
+   Under this scheme the package user for the bash package would be
+   bash:bash. `ls -l /bin/bash' would show something like this
+   
+   -rwxr-xr-x    1 bash     bash    1731859 Feb 30  2005 /bin/bash
+   
+   An important advantage of this scheme is that the user information is
+   not lost when you make a file setuid root, which requires changing
+   the file's owner. Because of this advantage, this scheme is the one
+   recommended by this hint. However, the hint's instructions will work
+   fine if you choose a different scheme.
+
+2. group name = package category
+
+   Under this scheme, you would have certain package categories, such as
+   games, system, net,... and bash, being a system program, would possibly
+   belong to the system group, so that `ls -l /bin/bash' would show something 
+   like this
+   
+   -rwxr-xr-x    1 bash     system    1731859 Jul  4  1776 /bin/bash
+   
+   This system is nice, but probably not as useful as #1 above, unless you
+   have a real use for this categorization.
+   For a possible categorization see Appendix B at the end of this hint.
+
+3. group name = identifier for a real group of people
+   
+   Under this scheme, the group would correspond to a real group of people in 
+   meatspace, e.g. the group of admins responsible for the package. 
+   If you need something like this you'll know best what it looks like and how
+   to implement it, so no further discussion of this method will be given here. 
+   
+
+ 3.4 Home Directory
+ ------------------
+ 
+Although it is well possible not to have a valid home directory for package
+users or to have just one home directory shared by all package users, that
+would be a wasted opportunity. Having individual home directories for the
+package users offers a nice way to organize tarballs, patches, build scripts,
+notes and all the other per-package information that you accumulate with time.
+
+I suggest to use the home directory /usr/src/<package> for a package user
+called <package> with the contents detailed below. The more_control_helpers 
+archive contains scripts and skeleton files that implement this suggestion.
+
+  .bash_profile: 
+           You will usually want to have the same environment for all package
+           users, so it is a good idea to make .bash_profile a symbolic link
+           to a file in a central location. The more_control_helpers example
+           uses /etc/pkgusr/bash_profile for this purpose.
+           
+  .bashrc: 
+           As for .bash_profile a symlink is a good idea for .bashrc. The
+           more_control_helpers example uses /etc/pkgusr/bashrc as link target.
+           Under normal circumstances package users are not 
+           (and even can not be) used for logging into the system, so there 
+           is little reason to distinguish between login and non-login shells 
+           for package users. Therefore, the example bashrc from 
+           more_control_helpers simply sources .bash_profile.
+           This makes sure that the same environment will be used, regardless
+           of whether `su <package>' or `su - <package>' is used to become
+           the package user.
+           
+  .project: 
+           The contents of this file are printed by the commands
+           `finger -l <user>' and 'pinky -l <user>' so .project is a
+           good place for putting information about a package. You should 
+           keep the contents of the .project files for your package users 
+           up-to-date.
+                       
+  source code:
+           The package user's home directory is the perfect place for storing
+           a package's source code. This includes tarballs for different
+           versions, CVS checkouts, unpacked source trees for building,...
+           
+  build script(s):
+           Package user installations require more careful examination of build 
+           and install messages than installations done as root, because of
+           the package user-specific problems that can occur. Therefore it is
+           unwise to simply copy'n'paste installation instructions from the
+           LFS book. Build scripts allow you to use sophisticated output
+           redirection for logging purposes that is impractical for direct
+           entry on the command line. The build script skeleton included in
+           the more_control_helpers archive demonstrates this.
+                       
+
+############################################################################
+ 4. Common Problems
+############################################################################
+
+ 4.1 Introduction
+ ----------------
+
+Software installation is the crux of the package user system. Because 
+installation scripts are often written under the assumption that they will be 
+executed as root, they sometimes fail when executed by a package user.
+Once this hurdle is passed and a package has been installed, there's usually no 
+difference to a root-installation. A few programs insist that certain 
+security-sensitive files be owned by root and will not execute otherwise,
+but this is the rare exception. 
+This chapter presents some more or less common problems that you will 
+encounter when using package user accounts to install software, together with
+guidelines on how to deal with these issues. 
+Although I've said it before I will say it again: Many of the problems you
+encounter during a package user installation are desirable features of the
+package user system. You want installation to fail rather than have 
+potentially dangerous actions performed behind your back with root rights.
+
+ 
+ 4.2 General Procedure
+ ---------------------
+ 
+When an installation fails it is almost always due to a "Permission denied"
+or "Operation not permitted" error while executing a command during
+`make install'. The first thing you have to do is identify the command that
+is causing the problem. Usually you will find this in the make output right
+before the error message. Once you have identified the culprit, you have to
+decide whether the action that is attempted is illegitimate, partially
+legitimate or completely legitimate. Illegitimate commands can simply be
+removed from the Makefile. The other 2 possibilities are more difficult to 
+deal with. You either have to change the condition that makes the command fail
+or you have to change or sometimes remove the command and make a note if your
+change suppresses a legitimate action.
+
+After you've made changes to solve a certain problem, you reattempt the
+installation and solve any remaining problems until the installation
+succeeds. Once you've reached that point it is time to perform any remaining
+legitimate actions that you've had to disable, such as make certain binaries
+setuid root.
+
+Note that often Makefiles are generated during the configure step, sometimes
+even later in the build process. If you want to apply changes before the
+configure step you will usually have to edit files called "Makefile.in".
+
+ 
+ 4.3 Permission Changes
+ ----------------------
+
+Some unsophisticated build systems that don't use the mkinstalldirs script to 
+create installation target directories are very poorly written. Instead of 
+testing whether a target directory exists, they simply attempt to create 
+it with default permissions. This problem usually manifests as a line such
+as "install -d $(prefix)/bin" in the Makefile. In the common case where 
+prefix=/usr this would attempt to create the /usr/bin directory. If the target
+directory already exists, as in this case, install will attempt to change its
+permissions to the default permissions (or those passed on the command line).
+Of course a package user is not allowed to change the permissions of
+/usr/bin and so the command fails with a message like
+"install: cannot change permissions of `/usr/bin': Operation not permitted"
+This is an example of a completely illegitimate command. Just remove it from
+the Makefile and everything's fine.
+
+ 
+ 4.4 Ownership Changes
+ ---------------------
+
+The most common situation when a package wants to change the ownership of
+files during installation is when it wants to install setuid root binaries.
+A common command to do this would be something like
+"install -c -m 4755 -o root name /usr/bin/name" and the error message would
+look like this:
+"install: cannot change ownership of `name': Operation not permitted"
+The change of ownership is hidden in the "-o root" switch to install, which
+tells it to make the target file owned by root.
+The command is at least partially legitimate, because you probably want the 
+binary to be installed. Whether you actually want it to be setuid root is 
+a different matter. The fact that a binary is commonly installed as setuid
+root doesn't mean that you should make it so. You'll have to ask yourself if
+normal users absolutely need to execute that binary. If you think they can
+live without it you're better off not making it setuid root, because every
+setuid root binary is a potential security hole. In any case you will
+have to edit the Makefile and remove the offending switch, "-o root" in this 
+case, so that the installation can succeed. Note that this will cause the
+binary to be installed setuid <package>, which of course makes no sense at all.
+If you don't intend to make the binary setuid root after the installation, it
+is best to change the "-m 4755" to "-m 755", so that it won't be installed
+setuid at all.
+
+TIP:
+  When you make a binary setuid root after the installation, use
+  `chown root /usr/bin/name' and not `chown root:root /usr/bin/name'.
+  This way you can keep original group of the file (i.e. the group of the 
+  package user) intact. With the user name = group name scheme recommended for
+  package users this makes sure that you can identify the source package of
+  the binary even after making it setuid root.
+  Note that as a security measure chown resets the setuid bit,
+  so you will have to do `chmod u+s /usr/bin/name' after the chown.
+
+ 
+ 4.5 Write to Non-Install Directory
+ ----------------------------------
+
+Sometimes packages want to create files or directories in non-install 
+directories. 3 situations have to be distinguished in this case. The 1st
+possibility is that the target directory should be an install directory.
+An example of this is /usr/share/aclocal. This directory is not among the
+standard system directories created when building an LFS system. It will be
+created by the first package that has files to install there and will be
+owned by the corresponding package user. The next package that wants to write
+in it will fail to install. The remedy is simple. Just make the directory an
+install directory. You don't even need to be root to do it. The package user
+that owns the directory has the rights to make that change.
+
+The 2nd possible reason for a package wanting to write to a non-install
+directory is that the failing command is only partially legitimate, i.e. you
+do want to have installed whatever it is meant to install, but you want it in
+a different location. For example some packages install binaries that are not
+meant to be called directly. The default location for these binaries is
+sometimes called libexec and with prefix=/usr the package will attempt to 
+create /usr/libexec. In cases such as this you often don't have to change 
+any Makefiles. There is either a configure switch to change the directory in
+question or it is just a matter of overriding a Makefile variable as in
+`make libexecdir=/usr/lib install'.
+
+The 3rd possible reason for an attempt to write to a non-install directory is
+that the command in question is illegitimate, i.e. you don't want to have
+installed whatever the package wants to install. As usual with illegitimate
+commands you can edit the Makefile and just remove them. In the case of
+a whole directory whose installation you want to suppress it could be too
+much effort to remove all of the offending commands that want to install
+files there. In this case an approach similar to that from the previous
+paragraph can be more effective. Either through configure switches or 
+overriding of variables you change the directory in question to something
+like <builddir>/foobar, where <builddir> is the directory in which build 
+commands are run (i.e. usually the top of the unpackaged source
+tree). This will cause the package to create the unwanted directory inside
+the build tree, which doesn't cause any permission problems and has the nice
+side effect that it'll be deleted together with the build directory when you
+clean up after the build.
+
+
+ 4.6 Delete or Overwrite File
+ ----------------------------
+
+In a perfect world one package should not mess with another package's files,
+but in the real world conflicts do happen occasionally. While a normal
+sysadmin installing as root won't notice this until it's too late, an admin
+employing the package user system will have to deal with conflicts right away.
+When a package tries to overwrite or delete a file or directory that is owned
+by another package the attempt will fail. It will fail even inside install
+directories because of the sticky bit.
+Although sometimes difficult to implement, the solution to such a conflict is
+easy to describe. You need to either remove (or rename) the old file or 
+directory before installing, or suppress the installation of the new file or 
+directory. The installation of individual binaries is sometimes easy to
+prevent. If you find a line such as "PROGRAMS=foo bar fubar barfu" in the
+Makefile and "foo" is the name of the conflicting binary, just try removing
+it from that list. That may be sufficient to prevent it from being installed.
+
+ 
+ 4.7 /sbin/ldconfig
+ ------------------
+ 
+Packages that install libraries sometimes run /sbin/ldconfig as part of their
+installation so that the dynamic libraries are properly registered on the 
+system. Because a package user is not allowed to overwrite /etc/ld.so.cache
+ldconfig fails. This failure is commonly ignored in Makefiles, but you should
+take note of it anyway, because you need to run ldconfig as root after
+the installation.
+ 
+ 
+############################################################################
+ 5. The more_control_helpers Archive
+############################################################################
+
+ 5.1 Overview
+ ------------
+
+The more_control_helpers archive contains files to help you with building and
+maintaining a system that uses the package user method. One thing that the
+more_control_helpers archive contains are some LFS-specific temporary files 
+that are only needed for the building of your LFS system and will not remain 
+installed in a permanent location. Then there are the previously mentioned 
+example files that demonstrate the suggested use of the package user home 
+directories discussed earlier. Another group of files contained in the archive 
+is a set of scripts that help with package management aspects, such as
+creating new package users and checking which files a particular package has 
+installed. Finally the more_control_helpers archive contains wrapper scripts
+for some commands that handle many of the common problems discussed in the
+previous chapter and make package user installations a lot easier.
+ 
+ 
+ 5.2 The Wrappers
+ ----------------
+ 
+The previous chapter discussed some common problems encountered during
+package user builds and how to solve them. The solution to an installation
+failure usually requires editing of one or more Makefiles. Making such changes
+manually is annoying, even if it happens only occasionally, and whenever you
+reinstall a package you have to make the changes again. Sed scripts and patches
+can help with the latter problem, but they still have to be custom fitted to 
+every package that needs them. There is a better solution, though. While there
+exist countless ways to install files, only very few are commonly used by
+packages. The 5 commands mkdir, chgrp, chown, chmod and install are responsible 
+for many of the common problems that arise during an LFS installation. This
+prompted me to write wrapper scripts for these 5 commands that recognize
+certain problematic patterns and deal with them automatically.
+
+The instructions given in this hint in the LFS-specific part will instruct you
+to install these wrappers in /usr/lib/pkgusr. If you do that and make sure 
+that this directory is the first entry in the PATH of every package user, then
+they will save you a lot of time and effort in dealing with recurring issues.
+Note that if you want to choose a directory other than /usr/lib/pkgusr for
+the wrappers, you need to be careful. Some configure scripts ignore certain
+locations. A subdirectory of /etc would not work, for instance, because /etc
+is one of these locations.  
+
+It is important that you understand the limitations of the wrapper scripts.
+They can fix some problems without user intervention, such as turning
+newly created directories in /usr/share/locale into install directories.
+But other problems by their very nature require manual intervention. When a 
+program tries to install a setuid root binary, for instance, the wrapper 
+scripts will suppress the attempt to change ownership of an installed file to 
+root. While that allows `make install' to complete without error, it is only 
+a partial solution. The wrapper scripts can not (and should not) take away
+your responsibility for deciding whether the program in question should be
+setuid root and to make it so, if necessary. To account for this, the
+wrapper scripts will output warning lines to standard error that start with
+"***" whenever they encounter a situation that needs to be reviewed.
+Following the "***" in the message will be the original command that the
+installation attempted to perform. 
+You *must* check these "***" lines, examine the affected files or directories
+and take appropriate action. Because of this it is imperative that you log
+the messages output during a package installation and check these logs
+religiously. The `build' script contained in the more_control_helpers archive
+demonstrates some useful output redirection tricks to be used for this purpose.
+The following 3 examples shall illustrate what kind of things you will have to
+look for:
+
+Example 1: "*** install -c rsh -o root -m 4775 /usr/bin/rsh"
+   This message is output by the install wrapper during the installation of
+   inetutils. The package wants to install the rsh binary setuid root. The
+   install wrapper removes the "-o root" and changes the "-m 4775" to
+   "-m 755" before passing the command on to the real install program.
+   The important thing here is the "-m 4xxx", because this wants to set the
+   setuid bit. Some install scripts throw in a "-o root" for good measure
+   when installing an otherwise normal binary. In that case it's enough that
+   the install wrapper strips out the "-o root" and you don't have to take
+   further action. But when, as in the case of inetutils, the permissions
+   indicate an attempt to make a binary setuid or setgid, then you will have to
+   investigate. You need to decide if you want rsh to be setuid root and
+   if you decide you do, you need to become root and issue commands like this:
+       
+       chown root /usr/bin/rsh
+       chmod u+s /usr/bin/rsh
+  
+TIP:
+   Be conservative with making binaries setuid. If you're unsure whether you
+   will ever use a program (as non-root), you probably don't want it to be 
+   setuid root. Keep in mind that you can always make the change later when
+   you need it. When you apply this reasoning to rsh, for instance, you'll 
+   probably end up not making it setuid root.
+
+
+Example 2: "*** chgrp tty /usr/bin/write" 
+   This is output by the chgrp wrapper during the util-linux installation.
+   The util-linux package wants to install the write program as setgid tty,
+   so that it is allowed to access other users' terminals. The chgrp wrapper
+   prevents the changing of the group and the chmod wrapper prevents the
+   setting of the setgid bit. You need to decide if you want the
+   program to be setgid and if you decide in favor of this, do as root
+   
+       chgrp tty /usr/bin/write
+       chmod g+s /usr/bin/write
+   
+    
+Example 3: "*** install -d -m 755 /sbin"
+   This is also from the util-linux installation. Util-linux, for no good
+   reason, tries to recreate the /sbin directory. The install wrapper
+   prevents this and you don't have to take any further action.
+
+ 
+ 5.3 add_package_user/install_package
+ ------------------------------------
+  
+Whenever you install a new package on your system, you first have to create
+a new user account, possibly create a new group and if you follow the advice
+from this hint about making productive use of a package user's home directory,
+you will have to set up that one, too. If you were to do all of this manually,
+it would be a lot of work. The add_package_user and install_package scripts
+in the more_control_helpers archive were written to automate this.
+
+The install_package script is the one you will normally use to prepare for
+installing a new package. It takes 3 parameters: the description of the 
+package, the name of the package user account to create and the name of the
+package user's primary group. So if you use the user=group scheme recommended 
+by this hint and are as creative with your package descriptions as I am, then 
+the command you'll use to prepare for installing package "foo" will be
+
+    install_package foo foo foo
+
+This command does 2 things. First it calls the add_package_user script with
+the provided name, group and description plus sensible default values for 
+add_package_user's other parameters. Then, after add_package_user has created 
+the package user account, install_package automatically uses the su-command
+to switch to the newly created account. If the default .bashrc and
+.bash_profile scripts you use for package users contain the command "cd" as do
+the examples in the more_control_helpers archive, you will be put right into
+your package user's home directory so that you can start installing right away.
+
+The add_package_user script is responsible for the actual work of creating
+a new package user account. Given a name, a group name and a description, it
+will create a new user account with the provided primary group and the install
+group as supplementary group. The groups will be created if necessary. 
+add_package_user takes several arguments that determine the numeric ranges from
+which it will pick the new user's UID and the GIDs for groups it needs to
+create. add_package_user does not only create the package user account. It
+will set up a home directory for it, too. You can either specify the directory
+or go with the default, which is /usr/src/<name>, where <name> is the name
+provided for the new account. If the home directory already exists, its
+ownership and that of any existing contents will be changed to the new user.
+If it doesn't exist, it will be created. 
+
+The contents of /etc/pkgusr/skel-package will be copied into the new package
+user's home directory (without overwriting pre-existing files). 
+The more_control_helpers archive contains an example of a useful skel-package
+directory. Note that symlinks are copied as symlinks, so skel-package is the
+perfect place to put .bashrc and .bash_profile symlinks to a central location
+that will ensure that all package user accounts have the same environment.
+This is especially useful to make sure that all package users have the
+wrappers directory in their PATH.
+
+  
+ 5.4 forall_direntries_from
+ --------------------------
+
+The forall_direntries_from script is a very useful tool for common package
+management tasks. It can roughly be described as a shortcut for 
+"find / -user <name> -or -group <name>  <commands>", where <name> is the
+first parameter to forall_direntries_from and <commands> are the remaining
+parameters. However, forall_direntries_from takes care of making sure that
+only relevant filesystems are scanned and shields you from certain unpleasant
+surprises such as "Oops, I forgot that -depth negates -prune and have 
+accidentally wiped out my home directory." or "Oops, I forgot to -prune /proc
+and now I'm getting parity errors on my SCSI bus.". 
+
+IMPORTANT NOTE: By default the forall_direntries_from script will only scan
+the / filesystem and will not traverse other filesystems. If you have
+relevant directories that need to be scanned on other filesystems, you will 
+need to edit the script and add the respective mount point(s) to the
+fs_to_scan list at the beginning of the script. The most likely candidate for
+addition is "/usr".
+
+Application examples:
+
+Example 1: Create a tar.gz archive of all files that belong to <package>, e.g.
+           for installing <package> on another machine without having to 
+           recompile it there.
+
+  forall_direntries_from <package> -fprint0 /tmp/files.lst
+  tar --null -P -czf /tmp/archive.tar.gz --files-from=/tmp/files.lst
+
+
+Example 2: Print out all setuid root binaries installed by <package>.
+           (This only works if you use the user=group scheme.)
+  
+  forall_direntries_from <package> -perm +u+s -print
+
+
+Example 3: List all binaries in /bin and /usr/bin belonging to "me" (i.e. the 
+           package user executing the command) in alphabetical order.
+
+  forall_direntries_from $(whoami) -path "*/bin/*" -printf "%f\n" | sort
+
+
+Example 4: Uninstall <package>.
+          
+  See following section about the uninstall_package script.
+ 
+                                   
+ 5.5 uninstall_package
+ ---------------------
+
+The uninstall_package script is basically a forall_direntries_from
+application example in script form. The command `uninstall_package foo'
+prints out the forall_direntries_from call that you have to use to delete
+all the files of package "foo" (except for those in directories that 
+forall_direntries_from is instructed not to scan) together with some
+explanations. So in order to delete the files from package foo, you would 
+execute `uninstall_package foo' and then copy'n'paste the command it prints
+to the command line. As a safeguard the forall_direntries_from call has an 
+"echo" in front of the "rm" and "rmdir" calls, so if you execute it, the files 
+will not actually be deleted unless you remove both instances of "echo". 
+It is recommended that you execute the command once with the echos and check 
+the output to make sure that only the files you intend to be deleted are in 
+the list. After you've confirmed that, you can use the shell's history to 
+recall the command, edit out the instances of "echo" and remove the files 
+for real.
+
+
+ 5.6 list_suspicious_files/list_suspicious_files_from
+ ----------------------------------------------------
+
+list_suspicious_files looks for filesystem entries that are out of the ordinary
+in some way and prints a categorized list of them. Things that qualify as
+suspicious include setuid and setgid binaries, world-writable files, symlinks 
+that are possibly broken, hard links, install directories with unusual 
+permissions and other stuff. You should run this script after you've finished 
+your new LFS system and in regular intervals after that. Investigate the
+listing closely.
+
+TIP: 
+  When you check the list of setuid and setgid files, don't forget to
+  look at the actual user or group ownership of the file. It's easy to forget
+  that, especially in the setuid case, because we often equate setuid with
+  setuid root since setuid is seldom used with other user accounts.
+
+list_suspicious_files_from takes a user or group name or a UID/GID as an 
+argument and reports suspicious entries only when they are owned by the given 
+user or group. Usually you would not call this script directly but instead
+use list_package (described in the next section), whose output includes that 
+from list_suspicious_files_from.
+
+IMPORTANT NOTE: By default the list_suspicious_files script will only scan
+the / filesystem and will not traverse other filesystems. If you have
+relevant directories that need to be scanned on other filesystems, you will 
+need to edit the script and add the respective mount point(s) to the
+fs_to_scan list at the beginning of the script. The most likely candidate for
+addition is "/usr".
+
+
+ 5.7 list_package
+ ----------------
+
+list_package tells you everything about a package's installed files. In
+general you will want to execute something like 
+
+   list_package $(whoami) >pkg.lst
+   
+right after installing a package and you can forget about the chronically
+inaccurate content listings in the (B)LFS book. 
+The following (shortened) output for util-linux speaks for itself:
+
+PS1> list_package util-linux
+
+EXECUTABLES (in */bin or */sbin)
+  agetty, arch, blockdev, cal, cfdisk, [...] vidmode(->rdev), whereis, write
+
+EXECUTABLES WITH NO MANPAGE (in */bin or */sbin)
+  fsck.cramfs, mkfs.cramfs
+
+MANPAGE SUMMARIES OF EXECUTABLES (in */bin or */sbin)
+  agetty: alternative Linux getty
+  arch: print machine architecture
+  blockdev: call block device ioctls from the command line
+  cal: displays a calendar
+  cfdisk: Curses based disk partition table manipulator for Linux
+  chkdupexe: find duplicate executables
+  col: filter reverse line feeds from input
+  [...]
+  swapon: enable/disable devices and files for paging and swapping
+  tailf: follow the growth of a log file
+  tunelp: set various parameters for the lp device
+  ul: do underlining
+  umount: unmount file systems
+  vidmode: query/set image root device, RAM disk size, or video mode
+  whereis: locate the binary, source, and manual page files for a command
+  write: send a message to another user
+
+EXTRA MANPAGES
+  /usr/share/man/man5/fstab.5
+  /usr/share/man/man5/nfs.5
+  /usr/share/man/man8/sln.8
+
+EXTRA EXECUTABLES (not in */bin or */sbin)
+  /usr/share/misc/getopt/getopt-parse.bash
+  /usr/share/misc/getopt/getopt-parse.tcsh
+  /usr/share/misc/getopt/getopt-test.bash
+  /usr/share/misc/getopt/getopt-test.tcsh
+
+ALL FILES
+  /etc/fdprm
+  /sbin/agetty
+  /sbin/blockdev
+  /sbin/cfdisk
+  /sbin/ctrlaltdel
+  /sbin/elvtune
+  /sbin/fdisk
+  /sbin/fsck.cramfs
+  /sbin/fsck.minix
+  /sbin/hwclock
+  /sbin/losetup
+  /sbin/mkfs
+  /sbin/mkfs.bfs
+  [...]
+  /usr/share/man/man8/rootflags.8
+  /usr/share/man/man8/setfdprm.8
+  /usr/share/man/man8/setsid.8
+  /usr/share/man/man8/sfdisk.8
+  /usr/share/man/man8/sln.8
+  /usr/share/man/man8/swapoff.8
+  /usr/share/man/man8/swapon.8
+  /usr/share/man/man8/tunelp.8
+  /usr/share/man/man8/umount.8
+  /usr/share/man/man8/vidmode.8
+  /usr/share/misc/getopt
+  /usr/share/misc/getopt/getopt-parse.bash
+  /usr/share/misc/getopt/getopt-parse.tcsh
+  /usr/share/misc/getopt/getopt-test.bash
+  /usr/share/misc/getopt/getopt-test.tcsh
+
+SETUID FILES
+  -rwsr-xr-x "/usr/bin/mount"  root:util-linux
+  -rwsr-xr-x "/usr/bin/umount"  root:util-linux
+
+SETGID FILES
+  -rwxr-sr-x "/usr/bin/write"  util-linux:tty
+
+FILES WITH UNUSUAL PERMISSIONS
+  -rwsr-xr-x "/usr/bin/mount"  root:util-linux
+  -rwsr-xr-x "/usr/bin/umount"  root:util-linux
+  -rwxr-sr-x "/usr/bin/write"  util-linux:tty
+
+
+Note: list_package works regardless of the prefix you've installed the package
+      with, so you can for instance configure with --prefix=/opt/package and
+      list_package will work just fine (provided that /opt is among the
+      filesystems configured to be scanned by forall_direntries_from and
+      list_suspicious_files).
+
+Note: list_package only considers manpages actually owned by the package to 
+      list. It will not consider manpages installed by another package. This
+      means that you may see executables identified as not having a manpage
+      although they do have one courtesy of another package 
+      (usually man-pages).
+
+
+ 5.8 grep_all_regular_files_for
+ ------------------------------
+
+This script is not really related to the package user system, but because of
+its similarity to the other scripts I've included it anyway. The sole purpose
+of this script is to identify files that store references to the build 
+environment, specifically the /tools directory. Such references may point out
+problems, since the /tools directory is supposed to be transient.
+Don't forget that results for unstripped binaries and libraries are not 
+reliable, because debugging information often includes references to the
+build environment. These do not cause trouble (unless you're trying to debug
+the objects in question after deleting /tools).
+  
+IMPORTANT NOTE: By default the grep_all_regular_files_for script will only scan
+the / filesystem and will not traverse other filesystems. If you have
+relevant directories that need to be scanned on other filesystems, you will 
+need to edit the script and add the respective mount point(s) to the
+fs_to_scan list at the beginning of the script. The most likely candidate for
+addition is "/usr".  
+  
+  
+ 5.9 The etc Directory
+ ---------------------
+ 
+If you follow the instructions provided in the LFS-specific part of this hint,
+the contents of the etc directory will be installed in /etc/pkgusr. The
+directory contains a bashrc and bash_profile for package users that takes
+care of package user specific details such as putting the wrappers directory
+at the beginning of the PATH and calling cd, so that `su <package>' will
+put you right into the package user's home directory. Also contained in the
+etc directory is a skel-package directory as used by 
+install_package/add_package_user to populate the home directories of newly
+created package users.
+ 
+ 
+ 5.10 Temporary Files 
+ --------------------
+
+3 files in the more_control_helpers archive are only used during the 
+installation of the base LFS system and are not installed permanently.
+The first of them is the installdirs.lst file that contains a list of 
+directories that should be install directories. 
+The second file is sbin/useradd, which is a very primitive shell script that
+adds a new entry to /etc/passwd. It allows us to add package users before
+we have installed shadow, which provides a real useradd.
+Finally there is groupadd, which is like useradd, only for /etc/group.
+Both scripts, useradd as well as groupadd, do very little error checking and
+only support the syntax needed by install_package/add_package_user. So don't
+try anything funky with them.
+
+  
+------------------------ PART 2: LFS Specifics ------------------------------
+
+
+#############################################################################
+ 6. Pre-Chroot Phase (Chapter 5)
+#############################################################################
+
+Build Chapter 5 exactly as explained by the LFS book. There is only one
+little change you have to make. After running `make install' for the coreutils
+package, issue the following command (still from within the coreutils
+build directory):
+
+    cp src/su /tools/bin
+    
+This installs the su binary. Coreutils doesn't install su when working as
+non-root (which we do in Chapter 5), because su needs to be setuid root for
+normal operation and a non-root user cannot install setuid root binaries. 
+But for our purposes (i.e. su'ing from root to a package user) a non-setuid 
+su is enough, so we just copy coreutils' su to /tools/bin without making it
+setuid root.
+    
+When you have reached the end of Chapter 5, before you begin with Chapter 6 
+you will need to install the helper scripts in the /tools directory so that
+they are available once you've entered the chroot environment. Use the
+following commands to install the more_control_helpers in /tools:
+
+    cd /tools &&
+    tar xjf /path/to/more_control_helpers.tar.bz2 &&
+    cd  more_control_helpers &&
+    cp ./sbin/* /tools/bin
+    
+Note that the target directory is "/tools/bin" in the cp command and 
+*not* "/tools/sbin", although the latter location would be more appropriate.
+The reason for this is simply that the LFS instructions do not add 
+"/tools/sbin" to the PATH (and neither do the instructions in this hint).
+
+
+#############################################################################
+ 7. Chroot Phase (Chapter 6)
+#############################################################################
+
+ 7.1 Preparations
+ ----------------
+
+Enter the chroot environment and follow the instructions from the book up to
+but *not* including the installation of the first package (which at the time of
+this writing is linux-libc-headers). Now install the more_control_helpers
+files in their proper locations on the new LFS system:
+
+    cp -a /tools/more_control_helpers/etc /etc/pkgusr &&
+    chown -R 0:0 /etc/pkgusr &&
+    cp -a /tools/more_control_helpers/lib /usr/lib/pkgusr &&
+    chown -R 0:0 /usr/lib/pkgusr &&
+    cp /tools/more_control_helpers/bin/* /usr/bin &&
+    cp /tools/more_control_helpers/sbin/* /usr/sbin &&
+    rm /usr/sbin/{useradd,groupadd}
+
+Note that the useradd and groupadd scripts are not installed on the new LFS 
+system. These scripts are just temporary workarounds we will use as long as 
+the real useradd and groupadd are not available. Therefore they should only 
+be in /tools/bin.
+
+ATTENTION! If you decide to use a different directory than /usr/lib/pkgusr
+for the wrappers, you have to be careful, because at least the glibc
+configure script ignores certain directories when looking for programs. The
+list of ignored directories for glibc includes, among others, everything that 
+starts with "/etc", "/usr/etc" and "/sbin". Wrappers put into a directory that
+matches any of these patterns would be ineffective.
+
+Now it's time to create the install group:
+
+    groupadd -g 9999 install
+
+The GID 9999 has been chosen because the default range used by 
+add_package_user for package user GIDs starts at 10000. Choose whatever number
+you like.
+
+Once the install group has been created you have to turn all the directories
+that packages will install files in into install directories. To make this
+easier I have compiled a list of install directories that can be found in
+the file /tools/more_control_helpers/installdirs.lst. The following command
+uses this list to assign the necessary directories to the install group.
+Note that you will get several error messages because of non-existent
+directories. This is because the list contains some directories not created
+by LFS.
+
+    chown 0:9999 $(cat /tools/more_control_helpers/installdirs.lst)
+
+To be usable by package users, the directories will have to be group-writable
+and should be sticky as has been explained in the beginning of this hint.
+The following command sets the permissions appropriately.
+You will get the same error messages as for the previous command.
+
+    chmod ug=rwx,o=rxt $(cat /tools/more_control_helpers/installdirs.lst)
+
+
+ 7.2 Walkthrough: Installing linux-libc-headers
+ ----------------------------------------------
+
+At this point everything has been set up for creating the first package
+user. At the time of this writing the first package installed in the LFS
+book is Linux-Libc-Headers, so this package will serve as an example for how 
+things are done. The command
+
+     install_package 'Linux Headers' linux-libc-headers linux-libc-headers
+
+will create a package user with user and group name linux-libc-headers.
+If you don't want to use the user=group scheme, change the last argument to
+the desired group name. The description is arbitrary but needs to meet the
+requirements for the description field of an /etc/passwd entry.
+
+The directory /usr/src/linux-libc-headers will be set up as the home directory
+for the package user, automatically populated with the contents of 
+/etc/pkgusr/skel-package. The install_package command also issues the command
+`su linux-libc-headers' to assume the identity of the newly created package
+user. If you're using the bashrc and bash_profile scripts from the
+more_control_helpers archive, you will be put straight into the directory 
+/usr/src/linux-libc-headers and your prompt will look like this
+
+package linux-libc-headers:/usr/src/linux-libc-headers>
+     
+to show you that you're working as package user linux-libc-headers and
+that your current working directory is /usr/src/linux-libc-headers.
+
+Use the command 
+   
+     echo $PATH
+
+to verify that your PATH starts with "/usr/lib/pkgusr", the directory that 
+contains the wrappers, and ends with "/tools/bin".
+
+Now everything is prepared for installing the package according to the
+instructions in the LFS book. Note that at the time of this writing the 
+LFS book tells you to execute a chown command to make sure that the headers 
+are owned by root. This is just because the packager has made a very common 
+mistake when creating the tarball for the headers: He has archived the files 
+with a non-root user/group assignment. When unpacking such a tarball as root, 
+the files end up being owned by some weird user/group combination, which may 
+open a security hole. When you're working as a package user this can not 
+happen and you don't want to chown the headers to root:root, because that 
+would defeat the whole point of installing the headers with a package user.
+This is one of the small points on which you will have to deviate from the 
+standard LFS instructions when using package users. More package user related
+issues with the current LFS book can be found in the next section.
+
+After you've installed the headers, simply issue the command
+
+    exit
+    
+to become root again. Now would be a good time to think about useful
+customizations for /etc/pkgusr/{bash_profile,bashrc} and/or 
+/etc/pkgusr/skel-package, if you've not already customized them.
+Once you're satisfied with your setup, install the rest of the packages.
+The following section will help you with some problems that you will run into.
+
+
+ 7.3 Known Issues with LFS Packages
+ ----------------------------------
+
+This section has details on the package user related problems you will face
+when building your LFS system. You should copy the information from this
+section to the INSTALL NOTES of the relevant .project files for the packages 
+concerned, together with any of your own notes.
+
+NOTE: If you're building by an LFS book later than 6.0 it is recommended that
+      you read this complete chapter before you start building any packages.
+      If your LFS version is 6.0 then it's fine to read this section package
+      by package as you progress with your build.
+
+
+linux-libc-headers:
+    At the time of this writing the LFS book tells you to execute a chown 
+    command to make sure that the headers are owned by root. This is just 
+    because the packager has made a very common mistake when creating the 
+    tarball for the headers: He has archived the files with a non-root 
+    user/group assignment. When unpacking such a tarball as root, the files 
+    end up being owned by some weird user/group combination, which may open 
+    a security hole. When you're working as a package user this can not happen 
+    and you don't want to chown the headers to root:root, because that would 
+    defeat the whole point of installing the headers with a package user.
+    
+    There's another packaging error in the linux-libc-headers archive.
+    The files are stored with incorrect permissions. They are supposed to
+    be world-readable, but they are not. The book's instructions already
+    tell you how to correct this but I point it out, because this error will 
+    resurface a little later.
+
+
+man-pages:
+    If the name you use for the man-pages package user is not exactly 
+    "man-pages", then you will have to change the variable "manpagesowner"
+    right at the beginning of the wrapper script `install'.
+
+    Recent versions of man-pages contain POSIX manpages that the package
+    tries to install in /usr/share/man/man{0,1,3}p. As /usr/share/man is
+    not an install directory and the LFS book does not have instructions to
+    create these directories at the time of this writing, the installation 
+    will fail and the respective man-pages will not be installed.
+    Possible remedies:
+      1. Make /usr/share/man an install directory. 
+         Consequence: All Packages will be able to create new subdirectories
+         in /usr/share/man. I find this undesirable because there are packages
+         that create directories for manpages in foreign languages that I
+         don't want. YMMV.
+      2. Ignore the problem and live without the POSIX manpages. Unless
+         you are a developer (including script writer) who is interested
+         in writing portable programs/scripts this is a good solution.
+      3. Create the directories /usr/share/man/man{0,1,3}p as root
+         prior to installing man-pages. You'll have to either chown them
+         to the man-pages package user or make them install directories.
+         This is my preferred solution.
+
+
+glibc:
+    The packaging error of libc-linux-headers described earlier also affects
+    the glibc build. Because of the error, the headers in /tools/include
+    are not world-readable. Unfortunately the LFS book (as of this writing)
+    does not correct this in Chapter 5 like it does in Chapter 6. For a
+    standard LFS build this is no problem, because glibc is built as root and
+    root can access everything regardless of permissions.
+    The glibc package user, however, does not have permission to access
+    these headers. This will cause several configure tests to fail, because
+    the respective test programs can not be compiled.
+    The end result is the error message "/lib/cpp fails sanity check", which
+    is completely nonsensical as we don't have a /lib/cpp.
+    
+    This is the perfect opportunity to introduce rule #1 of error diagnostics:
+    
+       NEVER TRUST DIAGNOSTIC MESSAGES !
+       
+    There are 2 kinds of diagnostic messages:
+    
+      1. Those that are unnecessary, because once you see which component has
+         failed, the source of the problem is obvious.
+      2. Those that grossly misdiagnose the source of the problem and lead
+         you to draw the wrong conclusions.
+    
+    No, there is no other kind. Trust me ;-)
+    In this case, /lib/cpp has nothing to do with the problem. It doesn't
+    exist and that's fine. The message just wants to trick you into doing
+    something stupid such as create a symlink /lib/cpp -> /tools/bin/cpp.
+    But that would be totally wrong. Before you jump to any premature 
+    conclusions you should always try to get as much *low-level* information 
+    as you can. Diagnostic messages are *high-level* information. They 
+    represent a filtered view of the problem, which is usually of little help.
+    Fortunately the message (the complete one, not the part quoted above) also
+    points at the source for the necessary low-level information. In this 
+    case that is the file config.log (not to be confused with configure.log, 
+    the file created by the build script included in the more_control_helpers 
+    archive).
+    config.log is created by all autoconf-created configures (not just that 
+    of glibc) and it contains, among other things, the test programs used by 
+    configure and messages output while building and running them. Whenever a 
+    configure script fails or gives weird results, check config.log. And 
+    always remember rule #2 of error diagnostics
+    
+       ALWAYS START AT THE FIRST ERROR
+       
+    This seems pretty obvious, but nevertheless people commonly do the exact
+    opposite. It's just too tempting to start at the point of the final 
+    failure and try to work backwards. In this case many people would open 
+    config.log and scroll to the point of the failed /lib/cpp sanity check.
+    After all, that's what caused configure to abort and so that's what needs
+    to be fixed, right?  WRONG! Someone who takes this approach just sees the 
+    error message "/lib/cpp: No such file or directory" and is even more 
+    convinced that a missing /lib/cpp symlink (or program) is the problem.
+    
+    The correct way to approach such a problem is to start at the beginning
+    of config.log, to scroll down to first error message and to check if it
+    is an issue that needs to be fixed (error messages in config.log are
+    not always signs for a problem). If the issue needs to be fixed, then
+    it needs to be fixed first, because all later errors could be rooted in
+    this issue (even if, no, *especially* if you don't believe this is the 
+    case).
+    If we apply this advice to the problem at hand, we quickly get to the first
+    serious error in config.log: 
+
+      "/tools/include/linux/limits.h: Permission denied"
+    
+    A quick check with ls reveals that indeed the directory with the linux
+    headers is not world-readable, which is obviously wrong. The fix is
+    easy. Just make (as root) the header directories /tools/include/{linux,asm} 
+    world-readable with commands similar to those the LFS book presents 
+    in Chapter 6 for the installation of linux-libc-headers.
+    Once this change has been made, glibc's configure succeeds.
+
+TIP:
+    Even when configure completes successfully, you should still check the
+    output carefully to see if there is anything odd. E.g. if you're using
+    the wrappers, you should check that configure outputs the line
+    
+       checking for a BSD-compatible install... /usr/lib/pkgusr/install -c
+    
+    If configure detects a different install, such as /tools/bin/install,
+    something is wrong. Maybe there's a typo in the PATH for the package
+    user, or you've put the wrappers into a directory that is ignored by
+    configure.
+    
+
+    With the wrappers the glibc build and install should work smoothly. 
+    The wrapper script for install makes sure that the /usr/share/locale/* 
+    directories become install directories so that other programs can install 
+    their localized messages. One thing that the wrappers do not take care of, 
+    however, is the file /usr/share/info/dir. Because in the current LFS build
+    order glibc is the first package that installs info files, dir is owned by 
+    and only writable by glibc. In order to allow other packages to install 
+    info pages, execute the following commands as root:
+    
+       chown root:install /usr/share/info/dir &&
+       chmod ug=rw,o=r /usr/share/info/dir
+
+NOTE:
+    glibc wants to install the program pt_chown as setuid root. If you install
+    as a package user, the program will get installed but not given root
+    privileges (because of the install wrapper). 
+    The following info is from the glibc docs:
+          
+       One auxiliary program, `/usr/libexec/pt_chown', is installed setuid
+       `root'.  This program is invoked by the `grantpt' function; it sets the
+       permissions on a pseudoterminal so it can be used by the calling
+       process.  This means programs like `xterm' and `screen' do not have to
+       be setuid to get a pty.  (There may be other reasons why they need
+       privileges.)  If you are using a 2.1 or newer Linux kernel with the
+       `devptsfs' or `devfs' filesystems providing pty slaves, you don't need
+       this program; otherwise you do.  The source for `pt_chown' is in
+       `login/programs/pt_chown.c'.
+                               
+    So unless you're building a system that does not use devpts (which would
+    be quite unusual), this does not need to concern you.
+
+TIP:
+    In case you were wondering if you should create /etc/nsswitch.conf and
+    /etc/ld.so.conf as root or glibc, I recommend to assign all files that 
+    you manually create or manually edit to the root account. That way you can
+    distinguish between those files that can be regenerated automatically and
+    those that can not. Assigning even automatically generated files to
+    root once you make the first manual edit, ensures that a later 
+    reinstallation of a package won't silently do away with your manual tweaks.
+
+
+binutils:
+    The installation of binutils should complete without problems. 
+    It does however cause minor conflicts with autoconf (see later).
+    
+    
+gcc:
+    Because the /usr/lib/libgcc_s.so.1 symlink created at the beginning of
+    Chapter 6 is owned by root, gcc's installation cannot remove it. 
+    So you will have to remove it as root before `make install'.
+    
+    
+coreutils:
+    Because the /bin/cat, /bin/pwd and /bin/stty symlinks are owned by root,
+    coreutils' installation cannot remove them. So you will have to remove 
+    them manually before `make install'.
+
+NOTE:
+    The man-pages package has already installed manpages for the binaries
+    from coreutils. The install wrapper will prevent coreutils from overwriting
+    those. This is done because the manpages from the man-pages package are 
+    of superior quality. It also prevents errors during `make install' that
+    would otherwise occur because the coreutils package user cannot overwrite 
+    manpages owned by another user.
+    If you don't like the above behaviour and would rather have the original 
+    package manpages (despite them being inferior), you can set the variable 
+    manpagesowner at the beginning of the install wrapper to a string that
+    doesn't correspond to a package user name (it must not be empty, though!).
+    If you do this, you will have to resolve manpage conflicts in another way. 
+    The easiest way to handle this is probably to not install the man-pages 
+    package at the beginning of Chapter 6 but at the end, after all the other
+    packages have already installed their manpages. Then you need only deal 
+    with the conflicts once, when installing man-pages.
+
+
+ncurses:
+    The installation of ncurses (like that of other packages that include 
+    libraries) wants to run /sbin/ldconfig to update /etc/ld.so.cache. 
+    This fails because the package user doesn't have permission to replace 
+    /etc/ld.so.cache.
+    Making /etc/ld.so.cache group-writable by the install group doesn't help, 
+    because the permissions would be reset on the next call to /sbin/ldconfig.
+    This error will usually not abort the installation and you can just
+    run /sbin/ldconfig manually as root afterwards.
+
+
+gettext:
+    The gettext installation creates the directory /usr/share/aclocal, which
+    contains macros for autoconf. Other packages want to install 
+    files into this directory, so you should make it writable by the install 
+    group and sticky. You don't need to do this now. You can wait till you 
+    install a package that wants to write to aclocal.
+
+
+inetutils:
+    This package contains some programs that it wants to be setuid root:
+    rsh, rcp, rlogin and ping
+    The install wrapper prevents these programs from being installed
+    setuid root. You must decide which of these programs you want to be 
+    setuid root and manually make them so. Be conservative. Don't make a
+    binary setuid root unless you *know* that ordinary users can't live
+    without it. Every setuid root binary is a potential security hole.
+
+
+iproute2:
+    This package tries to change the permissions of /usr/sbin. The install
+    wrapper takes care of this.
+
+
+perl:
+    Before you do `make install', you will have to 
+    `chown perl /usr/bin/perl' so that the perl package user is allowed to
+    remove the /usr/bin/perl symlink.
+    
+    If you will install add-on packages for perl as their own package users
+    into /usr/lib/perl5/site_perl, then you will need to turn 
+    /usr/lib/perl5/site_perl/ and its subdirectories into 
+    install directories. You don't need to do this now as you'll notice it
+    anyway when installing a perl add-on fails. 
+
+
+autoconf:
+    The autoconf package wants to install its own copy of standards.info,
+    which fails because binutils has already installed this file. You can 
+    either ignore the error or remove the binutils version of standards.info 
+    before `make install'.
+
+
+bash:
+    Before you can `make install' you need to `chown bash /bin/bash' so
+    that the bash installation can replace the /bin/bash symlink.
+    When running the test suite as a package user, the test "run-test" will 
+    fail with the following output:
+
+      33d32
+      < *** chmod g+s /tmp/test.setgid
+      35c34
+      < 1
+      ---
+      > 0
+      64d62
+      < *** chmod u+s /tmp/test.setuid
+      66c64
+      < 1
+      ---
+      > 0
+      154c152
+      < 1
+      ---
+      > 0
+      160c158
+      < 1
+      ---
+      > 0
+    
+    The first 2 failures are caused by the chmod wrapper which prevents the
+    test from setting the setuid and setgid bits and outputs the *** warning.
+    The failures are harmless and will not occur if you remove the wrappers
+    directory from the PATH before running the tests.
+    
+    The last 2 failures are not specific to package users but will occur 
+    whenever the user running the test is not the user who owns the terminal 
+    as is usually the case when you use the `su' command.
+    Simply ignore these failures. They are harmless. If you insist on getting
+    the tests to succeed, you will have to use chown as root to
+    assign ownership of the tty in which you will run the tests to the 
+    user running the tests. To find out the proper terminal, use the command
+    `ls -la /proc/self/fd/1' in the terminal where you will run the tests. 
+    It will output something like
+      lrwx------  1 bash bash 64 Sep 12 21:29 /proc/self/fd/1 -> /dev/pts/2
+    In this example the tty to be chowned would be /dev/pts/2.
+    
+    
+libtool:
+    The libtool installation wants to add files to /usr/share/aclocal, so
+    if you have not made it an install directory, yet, you will have to do it 
+    now (i.e. make the directory group install, group-writable, sticky).
+      
+    
+grub:
+    The commands to create and populate /boot/grub have to be executed as
+    root.
+
+
+procps:
+    The procps installation wants to execute the command `ldconfig'. This will
+    fail for 2 reasons:
+    
+      1) A package user does not have /sbin in its PATH
+      2) Package users are not allowed to overwrite /etc/ld.so.cache
+    
+    To overcome this problem, install with 
+      
+      make ldconfig='' install
+      
+    and issue the command `/sbin/ldconfig' manually as root after installing.
+
+
+shadow:
+    shadow contains its own version of the `groups' command and accompanying
+    manpage. The installation of these conflicts with the coreutils versions.
+    As of this writing the LFS book deals with this problem in
+    the following way:
+    
+      1) coreutils' groups is installed in /usr/bin and shadow's
+         groups is installed in /bin, so it's enough to delete shadow's groups
+         after installation.
+      2) The manpage issue is simply ignored, meaning that the system will
+         end up having the coreutils version of groups but the shadow version
+         of the groups manpage.
+         
+    Number 1 will not cause trouble with package users, unless you
+    are doing things like symlinking /usr/bin and /bin to be the same. And in
+    that case the "trouble" caused, namely that shadow won't be able to
+    overwrite `groups', is actually a good thing, because it prevents you
+    from unknowingly ending up with a different `groups' command than a 
+    standard-LFS user. Issues like this are exactly what the "more control"
+    part of this hint's title is about. The package user system does not
+    allow things like this to happen behind your back.
+    
+    Number 2 is probably not intentional. It's just one of those things that
+    people who don't use the package user system never become aware of and so
+    it has managed to escape the attention of the LFS testers. So once again 
+    the installation failure caused by the package user system, although 
+    annoying, is a desirable feature.
+    
+    To deal with both groups-issues, simply prevent shadow from installing
+    groups and its manpage. Execute the following commands *after* the
+    configure step, because the Makefiles don't exist until then.
+    
+      sed -i 's/groups.1//' man/Makefile
+      sed -i '/^bin_PROGRAMS/s/groups//' src/Makefile
+
+    By default shadow wants to install non-English manpages. This fails
+    because the /usr/share/man directory is not an install directory and
+    therefore package users are not allowed to create new subdirectories in it.
+    To solve this problem, before you `make install', open the file
+    man/Makefile, find the line 
+    
+      SUBDIRS = cs de es fr hu id it ja ko pl pt_BR ru zh_CN zh_TW
+    
+    and remove all the languages that you don't want to install. For those
+    languages that you do want to install, create directories with the
+    respective names in /usr/share/man as root and make them install
+    directories (i.e. group install, group-writable, sticky).
+    
+    At the time of this writing the coreutils patch used in LFS prevents the 
+    installation of the su binary, but not of its manpage. This is probably
+    another buglet in LFS that is exposed by the package user system. 
+    Whatever the reason, you will have to remove the su.1 manpage manually 
+    as root before shadow can be installed:
+    
+      rm /usr/share/man/man1/su.1
+    
+    There is yet another issue with shadow concerning manpages. The shadow
+    package contains a passwd.5 manpage. Installation of this manpage is
+    automatically suppressed by the install wrapper, because it would 
+    overwrite the passwd.5 manpage provided by the man-pages package. As usual
+    the man-pages version is better, so you can simply ignore this issue.
+
+    shadow wants to install the programs su, chage, chfn, chsh, expiry, 
+    gpasswd, newgrp and passwd as setuid root. You will need to decide which 
+    of these programs you want to be setuid root and manually make them so. 
+
+
+sysklogd:
+    sysklogd's Makefile has /usr/bin/install hardwired as the install
+    program, which circumvents the install wrapper. The wrapper is needed 
+    for sysklogd because it tries to make its manpages owned by root 
+    (which obviously a package user is not allowed to do). 
+    Therefore, install with
+    
+      make INSTALL=install install
+
+
+sysvinit:
+    sysvinit's installation wants to create /dev/initctl if it does not exist, 
+    but a package user does not have permission to do that, so create
+    /dev/initctl manually as root before installing:
+    
+        rm -f /dev/initctl
+        mkfifo /dev/initctl
+        chmod 600 /dev/initctl
+                                                  
+
+udev:
+    udev wants to recreate the /dev directory, although it already exists.
+    Since a package user cannot do that, the installation fails. To fix this,
+    kill the line in the Makefile that's responsible:
+    
+      sed -i '/\$(INSTALL) -d \$(DESTDIR)\$(udevdir)/d' Makefile
+    
+    NOTE: udev's Makefile is read-only, but apparently sed doesn't care about
+    this. If you want to edit the Makefile in another way (or if you're using
+    a sed version that doesn't have this, IMHO buggy, behaviour), you will 
+    have to `chmod u+w Makefile' first.
+
+
+util-linux:
+    util-linux wants to install write as setgid tty and u/mount as
+    setuid root. The wrappers catch this, so it doesn't cause the install to
+    fail, but as usual you'll have to decide if you want these programs to
+    have special privileges and take manual action as root if you do.
+
+
+##########################################################################  
+ 8. Sanity Checks 
+##########################################################################
+
+ 8.1 Suspicious Files
+ --------------------
+ 
+You probably ran the `list_package' command for each package and reviewed
+the results which include the suspicious files owned by that package. But even
+if you did that it's still a good idea to run the non-package specific 
+`list_suspicious_files' command once your build is complete. There could be
+something you overlooked the first time, or maybe you created a file as root
+with the wrong permissions. It doesn't hurt to check again and this will also
+give you the opportunity to review any setuid/setgid decisions you made with
+respect to the installed binaries.
+
+TIP: 
+  When you check the list of setuid and setgid files, don't forget to
+  look at the actual user or group ownership of the file. It's easy to forget
+  that, especially in the setuid case, because we often equate setuid with
+  setuid root since setuid is seldom used with other user accounts.
+
+  
+ 8.2 References to Temporary Files
+ ---------------------------------
+
+One big concern when building an LFS system is independence of the new LFS
+system from the files installed in /tools. The /tools directory is intended 
+to be temporary and it should be possible to delete it after building your
+LFS system with no adverse side effects. The `grep_all_regular_files_for'
+script from the more_control_helpers package can help you verify that your
+new LFS system is indeed clean. The command
+
+     grep_all_regular_files_for /tools
+
+will give you a list of all files that contain the string "/tools". Review the
+files in the list to make sure that no dependencies on the temporary files in
+/tools have crept in. But remember that results from binaries and libraries 
+are only meaningful after stripping away the debug information, because
+debug information necessarily includes references to the build environment.
+Of course, if you are a developer who will potentially run gdb on system
+libraries/binaries, your position will be that stripping away debug information
+is the wrong way to do away with /tools references. The other way to deal with
+them is to rebuild packages for which /tools references are reported. The new
+build will not involve any files from /tools and so the new debug information
+will not refer to /tools. Note that the LFS build instructions for glibc
+make glibc compile against /tools/glibc-kernheaders. Unless you copy the
+glibc-kernheaders directory to a location outside of /tools and compile glibc
+against that copy, you won't get rid of the /tools references in glibc's 
+debug information.
+No matter what means you choose to deal with the debug information issue, in 
+the end you should have a system where the above command produces only false 
+positives (such as "perlfaq3.1", which includes the URL
+"http://www.research.att.com/sw/tools/uwin/") and files that legitimately
+refer to /tools (such as a copy of this hint file).
+
+
+----------------------------- APPENDICES ----------------------------------
+
+
+###########################################################################
+ Appendix A: Security Issues
+###########################################################################
+
+ A.1 NFS
+ -------
+
+If you use the network filesystem NFS, there are some things you need to
+look out for when using the package user system. A fundamental security 
+problem with NFS is that it blindly trusts the UID and GID of the client. 
+If an attacker can get access to the root account on a system in your network 
+that is allowed to mount NFS shares from your server, or if the attacker can 
+attach his own computer to your network, then this attacker can pretend to be 
+anyone. NFS will happily allow the attacker to work in the NFS exported 
+directory as any user he wants to be. The only exception is the root account. 
+By default NFS exports directories with the root_squash option that maps all 
+incoming requests from uid 0 to anonuid (65534 unless set in /etc/exports) 
+and gid 0 to anongid (65534 unless set in /etc/exports). This protects files 
+owned by root:root. On a normal system this includes most files in /bin, /etc,
+/lib and most other directories except /home. If you use the package user 
+scheme, however, most of these files are owned by package users. These files 
+are not protected by the root_squash option. In order to make NFS exports 
+secure, you have to add the option "all_squash" to every entry in /etc/exports 
+that exports a directory that contains files owned by package users. Note that 
+all_squash is always a good idea because even systems that don't use package 
+users often have some programs owned by other users or groups, because they 
+need to be setuid or setgid.
+
+
+ A.2 Daemons
+ -----------
+
+It is a common practice to run daemons under special user accounts rather
+than as root as a security measure. If you feel tempted to use a package 
+user account for this purpose, resist the temptation. It would be a very
+stupid idea. Although they are deliberately less powerful than root, package 
+user accounts are still privileged and need to be considered as equivalent to 
+root as far as security is concerned. Do not do anything with a package user 
+that on a system without package users you would not do with the root account.
+
+
+###########################################################################
+ Appendix B: Package Categories
+###########################################################################
+
+Although the user name = group name scheme is recommended by this hint, it is
+not the only possible one. Another scheme that has some appeal is to define
+package categories and to use the group for the purpose of categorizing the
+packages. Following is a suggested set of categories that can serve as a
+guideline for implementing this scheme.
+
+devel: development related stuff, e.g. compilers. This is not restricted to
+       software development. TeX for instance would belong in this group.
+       
+utils: Most software fits into this category, even somewhat essential software 
+       like grep or text editors.
+      
+net: network related stuff such as an ftp daemon or a web browser. This
+     group overlaps with other groups to a large extent. It should be used
+     in preference of the other groups whenever a package is clearly focused
+     towards Internet, LAN, WWW,... A utility like wget for instance would
+     go in net rather than utils. Exceptions from this rule are the groups
+     docs, addons, games and mmedia. If a package fits into one of those 
+     groups, use the respective group instead of net.
+     
+docs: Documentation related packages, such as a tarball with Linux howtos.
+      Note that software to create documentation such as XML processors should
+      probably go in devel and software to view or post-process documentation
+      such as man or groff should probably go in utils.
+      
+system: important system software, such as bash. This group should be used
+        only for really essential packages. Most packages you would put in 
+        this group are better put in "utils". Vi for instance belongs in 
+        utils. 
+        It is unlikely that any package not part of basic LFS belongs in the
+        system group.
+        
+libs: What utils is for executables, libs is for libraries. Libraries that are
+      not strongly related to any of the other categories should go here, such
+      as zlib or libpng.
+      Essential system libraries such as glibc, ncurses or gettext should
+      go in system instead.
+      The libs group is also used for run-time environments such as the
+      Java Virtual Machine, dosemu and wine. Other emulators like MAME for
+      instance should probably go into games instead. 
+     
+games: what do you expect ;-)
+
+mmedia: This is the group for audio and video editors, mp3 players etc.
+
+apps: Applications such as spreadsheets and word processors (not text editors)
+      but also CAD software and graphics software such as Gimp.
+      The apps group is a bit like utils, but apps are usually more user 
+      friendly and more streamlined and feel less nerdish than utils. 
+      
+addons: plugins, filters and similar that are meant to be used in conjunction
+       with another package.
+       
+x: software that relates to the X Window System in general and does not fit
+   into any of the other categories, such as the X server itself or window 
+   managers.
+   Most X software should be put into other more specific groups.
+   A game like xmines would go in games for instance and a text editor for
+   X would go in utils.
+   
+kde: Software that relates to KDE and does not fit into
+     any other category. This group should be used with care. 
+     Do *not* use it for all KDE software. K Office for instance belongs in
+     apps. Konqueror belongs in net.
+     
+gnome: Software that relates to GNOME and does not fit into
+       any other category. This group should be used with care. 
+       Do *not* use it for all GNOME software. Gimp for instance belongs 
+       in apps. A GNOME-aware window manager that works with plain X should
+       go in the x group.
+
+
+###########################################################################
+ Appendix C: Acknowledgements and Changelog
+###########################################################################
+
+ACKNOWLEDGEMENTS:
+  * Tushar Teredesai for suggesting the user=group scheme.
+
+
+CHANGELOG:
+
+2004-11-01
+            -capitalized title
+            -released version 1.0
+            
+2004-10-14
+            -started developing the more_control_helpers utilities
+            
+2004-08-14
+            -started major rewrite (update for new LFS version, new hint 
+             format, textual improvements,...)
+
+2002-04-20
+            -changed LFS VERSION header to be more conservative
+            -added <br> tags to the synopsis for the sake of the hints 
+             index
+            -added group mmedia to the list of suggested groups 
+            -submitted v0.8
+
+2002-03-16  
+            -added note, that on Linux make doesn't need to be setgid kmem
+
+2002-02-18
+            -added section "Security issues with NFS"
+            -submitted v0.7
+
+2002-01-30  -added Changelog
+            -moved "chown 0.10000 `cat /tmp/installdirs`" command up (before
+             glibc package user is created)
+            -add_package_user: create home directory with "mkdir -p"
+                               use $grpfile everywhere instead of /etc/group
+            -improved mammoth sentence in Introduction
+            -added note about possibility to have user name==group name
+            -source bashrc_basic in bashrc_package
+            -minor textual changes
+
+




More information about the hints mailing list