changeset 1:d6bef198ae71

add work by Matthias S. Benkmann which is the inspiration for this project.
author Robert McIntyre <rlm@mit.edu>
date Tue, 08 Jan 2013 11:45:01 +0000
parents 0b7a589f6e9a
children a75581c89dde
files org/pkg.org previous-work/more_control_and_pkg_man.txt previous-work/more_control_helpers/README previous-work/more_control_helpers/bin/forall_direntries_from previous-work/more_control_helpers/bin/grep_all_regular_files_for previous-work/more_control_helpers/bin/list_package previous-work/more_control_helpers/bin/list_suspicious_files previous-work/more_control_helpers/bin/list_suspicious_files_from previous-work/more_control_helpers/bin/uninstall_package previous-work/more_control_helpers/etc/bash_profile previous-work/more_control_helpers/etc/bashrc previous-work/more_control_helpers/etc/build previous-work/more_control_helpers/etc/skel-package/.bash_profile previous-work/more_control_helpers/etc/skel-package/.bashrc previous-work/more_control_helpers/etc/skel-package/.project previous-work/more_control_helpers/etc/skel-package/build previous-work/more_control_helpers/etc/skel-package/build.conf previous-work/more_control_helpers/installdirs.lst previous-work/more_control_helpers/lib/chgrp previous-work/more_control_helpers/lib/chmod previous-work/more_control_helpers/lib/chown previous-work/more_control_helpers/lib/install previous-work/more_control_helpers/lib/ldconfig.c previous-work/more_control_helpers/lib/mkdir previous-work/more_control_helpers/sbin/add_package_user previous-work/more_control_helpers/sbin/groupadd previous-work/more_control_helpers/sbin/install_package previous-work/more_control_helpers/sbin/useradd
diffstat 28 files changed, 3711 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
     1.1 --- a/org/pkg.org	Tue Jan 08 10:59:30 2013 +0000
     1.2 +++ b/org/pkg.org	Tue Jan 08 11:45:01 2013 +0000
     1.3 @@ -0,0 +1,56 @@
     1.4 +The point of this system to to 
     1.5 +
     1.6 +1. Determine the provenence of every file on my system.
     1.7 +2. Always have an "undo" button.
     1.8 +
     1.9 +These criteria have evolved from my frustrations
    1.10 +with my previous LFS system.
    1.11 +
    1.12 +
    1.13 +User expreience:
    1.14 +
    1.15 +Suppose I want to install emacs.
    1.16 +
    1.17 +here's a sample terminal session
    1.18 +
    1.19 +$ pkg emacs "a text editor"
    1.20 +   > creating user emacs.
    1.21 +   > cd /pkg/emacs
    1.22 +
    1.23 +$ wget http://emacs.com/emacs.tar.bz2
    1.24 +   > downloaded emacs.tar.bz2
    1.25 +   
    1.26 +$ unp emacs.tar.bz2; cd emacs; configure; 
    1.27 +     make install;
    1.28 +   > install stuff.. 
    1.29 +   
    1.30 +$ hg st
    1.31 +   > a bunch of files are added
    1.32 +
    1.33 +1. Say I don't want emacs after all.
    1.34 +$ hg purge; hg revert --all
    1.35 +
    1.36 +2. Complete emacs instilation
    1.37 +   > hg addr; hg commit -m "emacs." 
    1.38 +
    1.39 +(this commits as the emacs user)
    1.40 +
    1.41 +3. can examine provenance of information
    1.42 +$ pkg-examine emacs
    1.43 +   > package emacs owns the following files:
    1.44 +   >  emacs
    1.45 +   >  man/emacs 
    1.46 +   > ....
    1.47 +
    1.48 +4. see all the commits that the "emacs" user made.
    1.49 +$ pkg-history emacs
    1.50 +  > <filtered mercurial log>
    1.51 +
    1.52 +5. remove a package in its entirety
    1.53 +$ pkg-remove emacs
    1.54 +  > removed
    1.55 +  > <list of files>
    1.56 + 
    1.57 +
    1.58 +
    1.59 +
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/previous-work/more_control_and_pkg_man.txt	Tue Jan 08 11:45:01 2013 +0000
     2.3 @@ -0,0 +1,1916 @@
     2.4 + 
     2.5 +AUTHOR: Matthias S. Benkmann <article at winterdrache dot de>
     2.6 +
     2.7 +DATE: 2007-10-20
     2.8 +
     2.9 +LICENSE: Creative Commons Attribution-Share Alike 3.0
    2.10 +         (http://creativecommons.org/licenses/by-sa/3.0/)
    2.11 +
    2.12 +SYNOPSIS: More Control and Package Management using Package Users (v1.4)
    2.13 +
    2.14 +DESCRIPTION:
    2.15 +-You want to know which packages your files belong to ?                 
    2.16 +-You want to deinstall software that doesn't have make uninstall ?      
    2.17 +-You are bothered by programs installed setuid root behind your back ?  
    2.18 +-You don't like packages quietly overwriting files from other packages ?
    2.19 +-You don't like package managers like RPM ?                             
    2.20 +-YOU WANT TOTAL CONTROL USING ONLY UNIX BUILTINS ?                      
    2.21 +
    2.22 +ATTACHMENTS:
    2.23 +http://www.linuxfromscratch.org/hints/downloads/attachments/more_control_and_pkg_man/more_control_helpers.tar.bz2
    2.24 +
    2.25 +PREREQUISITES:
    2.26 +For use with LFS book 6.2: Brain.
    2.27 +For use with LFS book later than 6.2: Brain (awake, good working condition).
    2.28 +
    2.29 +HINT:
    2.30 +
    2.31 +########################################################################### 
    2.32 + Contents
    2.33 +###########################################################################
    2.34 +
    2.35 +1. Preface
    2.36 +2. Overview
    2.37 +
    2.38 +- PART 1: General Information -
    2.39 +
    2.40 +3. Package Users
    2.41 +  3.1 Introduction
    2.42 +  3.2 User Name
    2.43 +  3.3 Groups
    2.44 +  3.4 Home Directory
    2.45 +4. Common Problems
    2.46 +  4.1 Introduction
    2.47 +  4.2 General Procedure
    2.48 +  4.3 Permission Changes
    2.49 +  4.4 Ownership Changes
    2.50 +  4.5 Write to Non-Install Directory
    2.51 +  4.6 Delete or Overwrite File
    2.52 +  4.7 /sbin/ldconfig
    2.53 +  4.8 What Commands to Run as a Package User
    2.54 +5. The more_control_helpers Archive
    2.55 +  5.1 Overview
    2.56 +  5.2 The Wrappers
    2.57 +  5.3 add_package_user/install_package
    2.58 +  5.4 forall_direntries_from
    2.59 +  5.5 uninstall_package
    2.60 +  5.6 list_suspicious_files/list_suspicious_files_from
    2.61 +  5.7 list_package
    2.62 +  5.8 grep_all_regular_files_for
    2.63 +  5.9 The etc Directory
    2.64 +  5.10 Temporary Files
    2.65 +  
    2.66 +- PART 2: LFS Specifics -
    2.67 +
    2.68 +6. Pre-Chroot Phase (Chapter 5)
    2.69 +7. Chroot Phase (Chapter 6)
    2.70 +  7.1 Preparations
    2.71 +  7.2 Walkthrough: Installing linux-libc-headers
    2.72 +  7.3 Known Issues with LFS Packages
    2.73 +8. Sanity Checks
    2.74 +  8.1 Suspicious Files
    2.75 +  8.2 References to Temporary Files
    2.76 +
    2.77 +- APPENDICES -
    2.78 +
    2.79 +A. Security Issues
    2.80 +  A.1 NFS
    2.81 +  A.2 Daemons
    2.82 +B. Package Categories
    2.83 +C. Acknowledgements and Changelog
    2.84 +  
    2.85 +
    2.86 +########################################################################### 
    2.87 + 1. Preface
    2.88 +###########################################################################
    2.89 +
    2.90 +Let's say I have written a program that you would like to use. To make it
    2.91 +easier for you I come over to install it for you. Would you give me the root
    2.92 +account and then leave the room ? No ? Then why do you give it to complete
    2.93 +strangers who you have never seen in your life, to install software packages
    2.94 +pulled from some Internet server, that come with no warranty and don't even 
    2.95 +list their contents in the README, although they will happily spread them all 
    2.96 +over your system ?
    2.97 +
    2.98 +It is a mystery why Unix admins who wouldn't even trust their employer with
    2.99 +more than a normal user account carelessly execute complex and incomprehensible
   2.100 +installation scripts with full root rights.
   2.101 +
   2.102 +Users and groups are the basic security principle in a Unix system. They have
   2.103 +been used successfully for a long time to monitor who has created a file and 
   2.104 +to control who is allowed to delete or change it. But this control has only 
   2.105 +been imposed on the files of ordinary users. What a waste! I suggest to extend
   2.106 +this control to all system files. 
   2.107 +
   2.108 +The general idea is to create package users, i.e. user accounts with restricted
   2.109 +rights, to build and install software packages, rather than doing these tasks 
   2.110 +as root. Not only does this give you more control over what build and install 
   2.111 +scripts may or may not do, it can also serve as a quite useful package 
   2.112 +management system.
   2.113 +
   2.114 +
   2.115 +#############################################################################
   2.116 + 2. Overview
   2.117 +#############################################################################
   2.118 +
   2.119 +This hint is divided into 3 parts. The first part contains general information
   2.120 +about the package user method. This part is the most important part of the
   2.121 +hint. Read it thoroughly. The second part explains how to apply the package 
   2.122 +user method to the building of an LFS system. 
   2.123 +Finally, part 3 of this hint is the Appendix with information that would not
   2.124 +fit anywhere else or that is not of general interest.
   2.125 +
   2.126 +It is inevitable that part 2 will become outdated with time as the LFS book 
   2.127 +changes and new versions of the software packages used with LFS are released. 
   2.128 +I make no attempt to track these changes. 
   2.129 +When someone reports an issue with a package I will incorporate
   2.130 +it into the hint, but larger changes that might be required due to changes in
   2.131 +the LFS build methodology could take a long time to get included. The reason 
   2.132 +for this (aside from lack of time) is that I consider part 2 as bonus material 
   2.133 +that helps people get started but is not essential. Part 1 describes the 
   2.134 +concepts, which are independent of package versions or the LFS book, and you 
   2.135 +will have to rely on this information whenever part 2 fails. Don't forget 
   2.136 +that part 2 only deals with the packages used by the LFS book. For all the 
   2.137 +other packages you install on your system after that even an up-to-date 
   2.138 +part 2 would offer no aid anyway.
   2.139 +
   2.140 +The previous paragraph might sound discouraging, and as you read more from the
   2.141 +hint it is possible that you get the impression that the package user
   2.142 +method is complicated, causes lots of difficult problems and is overall too
   2.143 +much trouble for anyone but a real hardcore admin with programming experience.
   2.144 +But you would be mistaken. 
   2.145 +First of all, many things experienced as installation problems when working
   2.146 +with the package user system are in fact desirable features. 
   2.147 +If `make install' fails for some package, because it attempts to install a
   2.148 +file with the same name as a pre-existing file from another package, you
   2.149 +should not curse the fact that you have to spend additional time to resolve
   2.150 +this issue. Instead you should be happy that you have been alerted of this
   2.151 +collision that, had it gone unnoticed, could have messed up your system in
   2.152 +more or less subtle ways.
   2.153 +Secondly, the package user system is not an all-or-nothing approach. It
   2.154 +works on a per-package basis. If a package gives you too much trouble, you
   2.155 +can always decide to chicken out and finish the installation as root.
   2.156 +Finally, the more_control_helpers archive provided with this hint contains
   2.157 +several useful scripts that automate many aspects of software installation
   2.158 +as a package user and, together with the tips given in this hint, add a lot 
   2.159 +of value to the package user system. 
   2.160 +So do not pass judgement until you have read at least the complete part 1,
   2.161 +including the description of the more_control_helpers.
   2.162 +
   2.163 +
   2.164 +---------------------- PART 1: General Information --------------------------
   2.165 +
   2.166 +
   2.167 +#############################################################################
   2.168 + 3. Package Users
   2.169 +#############################################################################
   2.170 +
   2.171 + 3.1 Introduction
   2.172 + ----------------
   2.173 +
   2.174 +The basic idea of this scheme is easily explained. Every package belongs to a 
   2.175 +certain "package user". When you install a package, you build and install
   2.176 +the package as this package user, causing all files that are installed to be 
   2.177 +owned by the package user. As a consequence all the usual package management 
   2.178 +tasks can be comfortably achieved through the use of standard command line 
   2.179 +utilities. A simple `ls -l <file>' will tell you, for instance, what package 
   2.180 +<file> belongs to and a `find -user ...' command allows you to perform an 
   2.181 +operation on all the files belonging to a certain package, e.g. delete them 
   2.182 +to uninstall the package.
   2.183 +
   2.184 +But package management is not all that package users are good for. Because
   2.185 +package users do not have root-rights, the installation of a package is
   2.186 +limited in what it can do. One thing that a package user is not allowed to do,
   2.187 +for example, is to overwrite files from a different package user. Clashes
   2.188 +between different packages that want to install a binary, library or header 
   2.189 +file of the same name are more common than you might think. With package users
   2.190 +you never run the risk of package B's installation destroying files from 
   2.191 +package A silently without you noticing. Every attempt of doing this during
   2.192 +package B's installation will cause a "Permission denied" or
   2.193 +"Operation not permitted" error so that you have the chance of taking 
   2.194 +appropriate steps.
   2.195 +Another thing that package users are not allowed to do is install setuid root 
   2.196 +binaries. The decision to make a binary setuid root is also something that a 
   2.197 +prudent admin does not want to leave up to the creator of a software package.
   2.198 +
   2.199 +Usually package user accounts have no valid password so that only root can su 
   2.200 +to a package user, which ensures that package users do not open an additional 
   2.201 +way into the system and undermine security. But you *may* set passwords 
   2.202 +anyway to allow a co-admin who you want to be able to install and maintain 
   2.203 +certain software packages to do so without having access to the actual root 
   2.204 +account. This co-admin could for instance install, delete, change additional 
   2.205 +libraries which might be necessary for his workgroup. He would be unable, 
   2.206 +though, to remove or modify libraries which don't belong to him/her, such as 
   2.207 +libc.
   2.208 +
   2.209 +
   2.210 + 3.2 User Name
   2.211 + -------------
   2.212 +
   2.213 +You don't need to drive yourself nuts trying to come up with 8 character
   2.214 +names for the package users. I always use the name of the package without 
   2.215 +the version number, including dashes and possibly exceeding 8 characters in 
   2.216 +length, e.g. "util-linux", and in the several years that I've been using this 
   2.217 +scheme I have not encountered any problems, nor has anyone else reported 
   2.218 +trouble. The 8-character limit on user names seems to be a thing of the past.
   2.219 +
   2.220 +TIP:
   2.221 +  You can use bash's programmable completion feature to save yourself some 
   2.222 +  typing when entering commands that take a user name as an argument, such as
   2.223 +  su, finger or pinky. The command 
   2.224 +  
   2.225 +      complete -o default -o nospace -A user su finger pinky
   2.226 +      
   2.227 +  tells bash to tab-complete words as user names for the commands su,
   2.228 +  finger and pinky.
   2.229 +  With this in place you can simply type `su linux-li<TAB>' and bash
   2.230 +  will complete this to `su linux-libc-headers' (assuming that you have a
   2.231 +  package user named "linux-libc-headers").
   2.232 +  "-o default" tells bash that if a suitable user name does not exist, the 
   2.233 +  default completion shall be attempted. 
   2.234 +  "-o nospace" prevents the addition of a space after the completed word.
   2.235 +  
   2.236 +  This is a very useful command to put into root's .bashrc and .bash_profile.
   2.237 +  
   2.238 +  BTW, at http://freshmeat.net/projects/bashcompletion/
   2.239 +  you can find a project that offers sophisticated completions for many
   2.240 +  other commands.
   2.241 +  
   2.242 +  Or switch to zsh (http://freshmeat.net/projects/zsh/). It's more powerful
   2.243 +  and less buggy than bash.
   2.244 +
   2.245 +
   2.246 + 3.3 Groups
   2.247 + ----------
   2.248 +
   2.249 +Every package user belongs to at least 2 groups. One of these groups is
   2.250 +the "install" group, which all package users (and only package users) belong
   2.251 +to. All directories that packages are allowed to install stuff in belong to 
   2.252 +the install group. This includes directories such as /bin and /usr/bin but 
   2.253 +excludes directories like /root or /. 
   2.254 +The directories owned by the install group are always group-writable. 
   2.255 +This would be enough for the package management aspects, but without further 
   2.256 +preparation this would not give added security or control because every 
   2.257 +package could replace the files from a different package (the change would 
   2.258 +be visible in the output from `ls -l', though).
   2.259 +For this reason all install directories get the sticky attribute. This
   2.260 +allows users to create new files and delete or modify their own files in
   2.261 +the directory, but files from other users can not be modified or removed.
   2.262 +In the rest of this hint, whenever the term "install directory" is used, it
   2.263 +refers to a directory that belongs to group install, is group-writable and
   2.264 +sticky. IOW, to turn <dir> into an install directory you would do
   2.265 +
   2.266 +    chgrp install <dir> && chmod g+w,o+t <dir>
   2.267 +
   2.268 +Although the install group is crucial for the package user system, it is 
   2.269 +implemented as a supplementary group, rather than as the primary group for
   2.270 +package users. This has at least 2 advantages. 
   2.271 +One advantage is that this makes it easy to get a list of all packages 
   2.272 +installed on the system with the command
   2.273 +
   2.274 +    grep install /etc/group
   2.275 +
   2.276 +A more important point, however, is that the primary group is the
   2.277 +one that files created by the package user will belong to. So it will be 
   2.278 +printed in the output of `ls -l' and is subject to find's "-group" test. 
   2.279 +This makes it very useful for organizational purposes. 
   2.280 +Following are some suggestions for how to use the primary group. 
   2.281 +
   2.282 +1. group name = user name
   2.283 +
   2.284 +   Under this scheme the package user for the bash package would be
   2.285 +   bash:bash. `ls -l /bin/bash' would show something like this
   2.286 +   
   2.287 +   -rwxr-xr-x    1 bash     bash    1731859 Feb 30  2005 /bin/bash
   2.288 +   
   2.289 +   An important advantage of this scheme is that the user information is
   2.290 +   not lost when you make a file setuid root, which requires changing
   2.291 +   the file's owner. Because of this advantage, this scheme is the one
   2.292 +   recommended by this hint. However, the hint's instructions will work
   2.293 +   fine if you choose a different scheme.
   2.294 +
   2.295 +2. group name = package category
   2.296 +
   2.297 +   Under this scheme, you would have certain package categories, such as
   2.298 +   games, system, net,... and bash, being a system program, would possibly
   2.299 +   belong to the system group, so that `ls -l /bin/bash' would show something 
   2.300 +   like this
   2.301 +   
   2.302 +   -rwxr-xr-x    1 bash     system    1731859 Jul  4  1776 /bin/bash
   2.303 +   
   2.304 +   This system is nice, but probably not as useful as #1 above, unless you
   2.305 +   have a real use for this categorization.
   2.306 +   For a possible categorization see Appendix B at the end of this hint.
   2.307 +
   2.308 +3. group name = identifier for a real group of people
   2.309 +   
   2.310 +   Under this scheme, the group would correspond to a real group of people in 
   2.311 +   meatspace, e.g. the group of admins responsible for the package. 
   2.312 +   If you need something like this you'll know best what it looks like and how
   2.313 +   to implement it, so no further discussion of this method will be given here. 
   2.314 +   
   2.315 +
   2.316 + 3.4 Home Directory
   2.317 + ------------------
   2.318 + 
   2.319 +Although it is well possible not to have a valid home directory for package
   2.320 +users or to have just one home directory shared by all package users, that
   2.321 +would be a wasted opportunity. Having individual home directories for the
   2.322 +package users offers a nice way to organize tarballs, patches, build scripts,
   2.323 +notes and all the other per-package information that you accumulate with time.
   2.324 +
   2.325 +I suggest to use the home directory /usr/src/<package> for a package user
   2.326 +called <package> with the contents detailed below. The more_control_helpers 
   2.327 +archive contains scripts and skeleton files that implement this suggestion.
   2.328 +
   2.329 +  .bash_profile: 
   2.330 +           You will usually want to have the same environment for all package
   2.331 +           users, so it is a good idea to make .bash_profile a symbolic link
   2.332 +           to a file in a central location. The more_control_helpers example
   2.333 +           uses /etc/pkgusr/bash_profile for this purpose.
   2.334 +           
   2.335 +  .bashrc: 
   2.336 +           As for .bash_profile a symlink is a good idea for .bashrc. The
   2.337 +           more_control_helpers example uses /etc/pkgusr/bashrc as link target.
   2.338 +           Under normal circumstances package users are not 
   2.339 +           (and even can not be) used for logging into the system, so there 
   2.340 +           is little reason to distinguish between login and non-login shells 
   2.341 +           for package users. Therefore, the example bashrc from 
   2.342 +           more_control_helpers simply sources .bash_profile.
   2.343 +           This makes sure that the same environment will be used, regardless
   2.344 +           of whether `su <package>' or `su - <package>' is used to become
   2.345 +           the package user.
   2.346 +           
   2.347 +  .project: 
   2.348 +           The contents of this file are printed by the commands
   2.349 +           `finger -l <user>' and 'pinky -l <user>' so .project is a
   2.350 +           good place for putting information about a package. You should 
   2.351 +           keep the contents of the .project files for your package users 
   2.352 +           up-to-date.
   2.353 +                       
   2.354 +  source code:
   2.355 +           The package user's home directory is the perfect place for storing
   2.356 +           a package's source code. This includes tarballs for different
   2.357 +           versions, CVS checkouts, unpacked source trees for building,...
   2.358 +           
   2.359 +  build script(s):
   2.360 +           Package user installations require more careful examination of build 
   2.361 +           and install messages than installations done as root, because of
   2.362 +           the package user-specific problems that can occur. Therefore it is
   2.363 +           unwise to simply copy'n'paste installation instructions from the
   2.364 +           LFS book. Build scripts allow you to use sophisticated output
   2.365 +           redirection for logging purposes that is impractical for direct
   2.366 +           entry on the command line. The build script skeleton included in
   2.367 +           the more_control_helpers archive demonstrates this.
   2.368 +                       
   2.369 +
   2.370 +############################################################################
   2.371 + 4. Common Problems
   2.372 +############################################################################
   2.373 +
   2.374 + 4.1 Introduction
   2.375 + ----------------
   2.376 +
   2.377 +Software installation is the crux of the package user system. Because 
   2.378 +installation scripts are often written under the assumption that they will be 
   2.379 +executed as root, they sometimes fail when executed by a package user.
   2.380 +Once this hurdle is passed and a package has been installed, there's usually no 
   2.381 +difference to a root-installation. A few programs insist that certain 
   2.382 +security-sensitive files be owned by root and will not execute otherwise,
   2.383 +but this is the rare exception. 
   2.384 +This chapter presents some more or less common problems that you will 
   2.385 +encounter when using package user accounts to install software, together with
   2.386 +guidelines on how to deal with these issues. 
   2.387 +Although I've said it before I will say it again: Many of the problems you
   2.388 +encounter during a package user installation are desirable features of the
   2.389 +package user system. You want installation to fail rather than have 
   2.390 +potentially dangerous actions performed behind your back with root rights.
   2.391 +
   2.392 + 
   2.393 + 4.2 General Procedure
   2.394 + ---------------------
   2.395 + 
   2.396 +When an installation fails it is almost always due to a "Permission denied"
   2.397 +or "Operation not permitted" error while executing a command during
   2.398 +`make install'. The first thing you have to do is identify the command that
   2.399 +is causing the problem. Usually you will find this in the make output right
   2.400 +before the error message. Once you have identified the culprit, you have to
   2.401 +decide whether the action that is attempted is illegitimate, partially
   2.402 +legitimate or completely legitimate. Illegitimate commands can simply be
   2.403 +removed from the Makefile. The other 2 possibilities are more difficult to 
   2.404 +deal with. You either have to change the condition that makes the command fail
   2.405 +or you have to change or sometimes remove the command and make a note if your
   2.406 +change suppresses a legitimate action.
   2.407 +
   2.408 +After you've made changes to solve a certain problem, you reattempt the
   2.409 +installation and solve any remaining problems until the installation
   2.410 +succeeds. Once you've reached that point it is time to perform any remaining
   2.411 +legitimate actions that you've had to disable, such as make certain binaries
   2.412 +setuid root.
   2.413 +
   2.414 +Note that often Makefiles are generated during the configure step, sometimes
   2.415 +even later in the build process. If you want to apply changes before the
   2.416 +configure step you will usually have to edit files called "Makefile.in".
   2.417 +
   2.418 + 
   2.419 + 4.3 Permission Changes
   2.420 + ----------------------
   2.421 +
   2.422 +Some unsophisticated build systems that don't use the mkinstalldirs script to 
   2.423 +create installation target directories are very poorly written. Instead of 
   2.424 +testing whether a target directory exists, they simply attempt to create 
   2.425 +it with default permissions. This problem usually manifests as a line such
   2.426 +as "install -d $(prefix)/bin" in the Makefile. In the common case where 
   2.427 +prefix=/usr this would attempt to create the /usr/bin directory. If the target
   2.428 +directory already exists, as in this case, install will attempt to change its
   2.429 +permissions to the default permissions (or those passed on the command line).
   2.430 +Of course a package user is not allowed to change the permissions of
   2.431 +/usr/bin and so the command fails with a message like
   2.432 +"install: cannot change permissions of `/usr/bin': Operation not permitted"
   2.433 +This is an example of a completely illegitimate command. Just remove it from
   2.434 +the Makefile and everything's fine.
   2.435 +
   2.436 + 
   2.437 + 4.4 Ownership Changes
   2.438 + ---------------------
   2.439 +
   2.440 +The most common situation when a package wants to change the ownership of
   2.441 +files during installation is when it wants to install setuid root binaries.
   2.442 +A common command to do this would be something like
   2.443 +"install -c -m 4755 -o root name /usr/bin/name" and the error message would
   2.444 +look like this:
   2.445 +"install: cannot change ownership of `name': Operation not permitted"
   2.446 +The change of ownership is hidden in the "-o root" switch to install, which
   2.447 +tells it to make the target file owned by root.
   2.448 +The command is at least partially legitimate, because you probably want the 
   2.449 +binary to be installed. Whether you actually want it to be setuid root is 
   2.450 +a different matter. The fact that a binary is commonly installed as setuid
   2.451 +root doesn't mean that you should make it so. You'll have to ask yourself if
   2.452 +normal users absolutely need to execute that binary. If you think they can
   2.453 +live without it you're better off not making it setuid root, because every
   2.454 +setuid root binary is a potential security hole. In any case you will
   2.455 +have to edit the Makefile and remove the offending switch, "-o root" in this 
   2.456 +case, so that the installation can succeed. Note that this will cause the
   2.457 +binary to be installed setuid <package>, which of course makes no sense at all.
   2.458 +If you don't intend to make the binary setuid root after the installation, it
   2.459 +is best to change the "-m 4755" to "-m 755", so that it won't be installed
   2.460 +setuid at all.
   2.461 +
   2.462 +TIP:
   2.463 +  When you make a binary setuid root after the installation, use
   2.464 +  `chown root /usr/bin/name' and not `chown root:root /usr/bin/name'.
   2.465 +  This way you can keep original group of the file (i.e. the group of the 
   2.466 +  package user) intact. With the user name = group name scheme recommended for
   2.467 +  package users this makes sure that you can identify the source package of
   2.468 +  the binary even after making it setuid root.
   2.469 +  Note that as a security measure chown resets the setuid bit,
   2.470 +  so you will have to do `chmod u+s /usr/bin/name' after the chown.
   2.471 +
   2.472 + 
   2.473 + 4.5 Write to Non-Install Directory
   2.474 + ----------------------------------
   2.475 +
   2.476 +Sometimes packages want to create files or directories in non-install 
   2.477 +directories. 3 situations have to be distinguished in this case. The 1st
   2.478 +possibility is that the target directory should be an install directory.
   2.479 +An example of this is /usr/share/aclocal. This directory is not among the
   2.480 +standard system directories created when building an LFS system. It will be
   2.481 +created by the first package that has files to install there and will be
   2.482 +owned by the corresponding package user. The next package that wants to write
   2.483 +in it will fail to install. The remedy is simple. Just make the directory an
   2.484 +install directory. You don't even need to be root to do it. The package user
   2.485 +that owns the directory has the rights to make that change.
   2.486 +
   2.487 +The 2nd possible reason for a package wanting to write to a non-install
   2.488 +directory is that the failing command is only partially legitimate, i.e. you
   2.489 +do want to have installed whatever it is meant to install, but you want it in
   2.490 +a different location. For example some packages install binaries that are not
   2.491 +meant to be called directly. The default location for these binaries is
   2.492 +sometimes called libexec and with prefix=/usr the package will attempt to 
   2.493 +create /usr/libexec. In cases such as this you often don't have to change 
   2.494 +any Makefiles. There is either a configure switch to change the directory in
   2.495 +question or it is just a matter of overriding a Makefile variable as in
   2.496 +`make libexecdir=/usr/lib install'.
   2.497 +
   2.498 +The 3rd possible reason for an attempt to write to a non-install directory is
   2.499 +that the command in question is illegitimate, i.e. you don't want to have
   2.500 +installed whatever the package wants to install. As usual with illegitimate
   2.501 +commands you can edit the Makefile and just remove them. In the case of
   2.502 +a whole directory whose installation you want to suppress it could be too
   2.503 +much effort to remove all of the offending commands that want to install
   2.504 +files there. In this case an approach similar to that from the previous
   2.505 +paragraph can be more effective. Either through configure switches or 
   2.506 +overriding of variables you change the directory in question to something
   2.507 +like <builddir>/foobar, where <builddir> is the directory in which build 
   2.508 +commands are run (i.e. usually the top of the unpackaged source
   2.509 +tree). This will cause the package to create the unwanted directory inside
   2.510 +the build tree, which doesn't cause any permission problems and has the nice
   2.511 +side effect that it'll be deleted together with the build directory when you
   2.512 +clean up after the build.
   2.513 +
   2.514 +
   2.515 + 4.6 Delete or Overwrite File
   2.516 + ----------------------------
   2.517 +
   2.518 +In a perfect world one package should not mess with another package's files,
   2.519 +but in the real world conflicts do happen occasionally. While a normal
   2.520 +sysadmin installing as root won't notice this until it's too late, an admin
   2.521 +employing the package user system will have to deal with conflicts right away.
   2.522 +When a package tries to overwrite or delete a file or directory that is owned
   2.523 +by another package the attempt will fail. It will fail even inside install
   2.524 +directories because of the sticky bit.
   2.525 +Although sometimes difficult to implement, the solution to such a conflict is
   2.526 +easy to describe. You need to either remove (or rename) the old file or 
   2.527 +directory before installing, or suppress the installation of the new file or 
   2.528 +directory. The installation of individual binaries is sometimes easy to
   2.529 +prevent. If you find a line such as "PROGRAMS=foo bar fubar barfu" in the
   2.530 +Makefile and "foo" is the name of the conflicting binary, just try removing
   2.531 +it from that list. That may be sufficient to prevent it from being installed.
   2.532 +
   2.533 + 
   2.534 + 4.7 /sbin/ldconfig
   2.535 + ------------------
   2.536 + 
   2.537 +Packages that install libraries sometimes run /sbin/ldconfig as part of their
   2.538 +installation so that the dynamic libraries are properly registered on the 
   2.539 +system. Because a package user is not allowed to overwrite /etc/ld.so.cache
   2.540 +ldconfig fails. This failure is commonly ignored in Makefiles, but you should
   2.541 +take note of it anyway, because you need to run ldconfig as root after
   2.542 +the installation. Alternatively, the more_control_helpers contain a wrapper 
   2.543 +program that calls /sbin/ldconfig and can be made setuid root.
   2.544 +
   2.545 +
   2.546 + 4.8 What Commands to Run as a Package User  
   2.547 + ------------------------------------------
   2.548 +
   2.549 +A common problem that new users of this hint have is to decide which commands
   2.550 +to run as a package user and which commands to run as root. The general rule
   2.551 +is that the only commands to run as a package user are those for building,
   2.552 +installing, removing and modifying the files that belong to *that* package 
   2.553 +user's package. Everything else should be run as root as usual. 
   2.554 +Some things you CAN/SHOULD NOT DO as a package user include
   2.555 +
   2.556 +    - starting daemons
   2.557 +    - running udevstart
   2.558 +    - stripping /lib/*
   2.559 +
   2.560 + 
   2.561 +############################################################################
   2.562 + 5. The more_control_helpers Archive
   2.563 +############################################################################
   2.564 +
   2.565 + 5.1 Overview
   2.566 + ------------
   2.567 +
   2.568 +The more_control_helpers archive contains files to help you with building and
   2.569 +maintaining a system that uses the package user method. One thing that the
   2.570 +more_control_helpers archive contains are some LFS-specific temporary files 
   2.571 +that are only needed for the building of your LFS system and will not remain 
   2.572 +installed in a permanent location. Then there are the previously mentioned 
   2.573 +example files that demonstrate the suggested use of the package user home 
   2.574 +directories discussed earlier. Another group of files contained in the archive 
   2.575 +is a set of scripts that help with package management aspects, such as
   2.576 +creating new package users and checking which files a particular package has 
   2.577 +installed. Finally the more_control_helpers archive contains wrapper scripts
   2.578 +for some commands that handle many of the common problems discussed in the
   2.579 +previous chapter and make package user installations a lot easier.
   2.580 + 
   2.581 + 
   2.582 + 5.2 The Wrappers
   2.583 + ----------------
   2.584 + 
   2.585 +The previous chapter discussed some common problems encountered during
   2.586 +package user builds and how to solve them. The solution to an installation
   2.587 +failure usually requires editing of one or more Makefiles. Making such changes
   2.588 +manually is annoying, even if it happens only occasionally, and whenever you
   2.589 +reinstall a package you have to make the changes again. Sed scripts and patches
   2.590 +can help with the latter problem, but they still have to be custom fitted to 
   2.591 +every package that needs them. There is a better solution, though. While there
   2.592 +exist countless ways to install files, only very few are commonly used by
   2.593 +packages. The 5 commands mkdir, chgrp, chown, chmod and install are responsible 
   2.594 +for most of the problems that arise during an LFS installation. This
   2.595 +prompted me to write wrapper scripts for these 5 commands that recognize
   2.596 +certain problematic patterns and deal with them automatically.
   2.597 +
   2.598 +The instructions given in this hint in the LFS-specific part will instruct you
   2.599 +to install these wrappers in /usr/lib/pkgusr. If you do that and make sure 
   2.600 +that this directory is the first entry in the PATH of every package user, then
   2.601 +they will save you a lot of time and effort in dealing with recurring issues.
   2.602 +Note that if you want to choose a directory other than /usr/lib/pkgusr for
   2.603 +the wrappers, you need to be careful. Some configure scripts ignore certain
   2.604 +locations. A subdirectory of /etc would not work, for instance, because /etc
   2.605 +is one of these locations.  
   2.606 +
   2.607 +It is important that you understand the limitations of the wrapper scripts.
   2.608 +They can fix some problems without user intervention, such as turning
   2.609 +newly created directories in /usr/share/locale into install directories.
   2.610 +But other problems by their very nature require manual intervention. When a 
   2.611 +program tries to install a setuid root binary, for instance, the wrapper 
   2.612 +scripts will suppress the attempt to change ownership of an installed file to 
   2.613 +root. While that allows `make install' to complete without error, it is only 
   2.614 +a partial solution. The wrapper scripts can not (and should not) take away
   2.615 +your responsibility for deciding whether the program in question should be
   2.616 +setuid root and to make it so, if necessary. To account for this, the
   2.617 +wrapper scripts will output warning lines to standard error that start with
   2.618 +"***" whenever they encounter a situation that needs to be reviewed.
   2.619 +Following the "***" in the message will be the original command that the
   2.620 +installation attempted to perform. 
   2.621 +You *must* check these "***" lines, examine the affected files or directories
   2.622 +and take appropriate action. Because of this it is imperative that you log
   2.623 +the messages output during a package installation and check these logs
   2.624 +religiously. The `build' script contained in the more_control_helpers archive
   2.625 +demonstrates some useful output redirection tricks to be used for this purpose.
   2.626 +The following 3 examples shall illustrate what kind of things you will have to
   2.627 +look for:
   2.628 +
   2.629 +Example 1: "*** install -c rsh -o root -m 4775 /usr/bin/rsh"
   2.630 +   This message is output by the install wrapper during the installation of
   2.631 +   inetutils. The package wants to install the rsh binary setuid root. The
   2.632 +   install wrapper removes the "-o root" and changes the "-m 4775" to
   2.633 +   "-m 755" before passing the command on to the real install program.
   2.634 +   The important thing here is the "-m 4xxx", because this wants to set the
   2.635 +   setuid bit. Some install scripts throw in a "-o root" for good measure
   2.636 +   when installing an otherwise normal binary. In that case it's enough that
   2.637 +   the install wrapper strips out the "-o root" and you don't have to take
   2.638 +   further action. But when, as in the case of inetutils, the permissions
   2.639 +   indicate an attempt to make a binary setuid or setgid, then you will have to
   2.640 +   investigate. You need to decide if you want rsh to be setuid root and
   2.641 +   if you decide you do, you need to become root and issue commands like this:
   2.642 +       
   2.643 +       chown root /usr/bin/rsh
   2.644 +       chmod u+s /usr/bin/rsh
   2.645 +  
   2.646 +TIP:
   2.647 +   Be conservative with making binaries setuid. If you're unsure whether you
   2.648 +   will ever use a program (as non-root), you probably don't want it to be 
   2.649 +   setuid root. Keep in mind that you can always make the change later when
   2.650 +   you need it. When you apply this reasoning to rsh, for instance, you'll 
   2.651 +   probably end up not making it setuid root.
   2.652 +
   2.653 +
   2.654 +Example 2: "*** chgrp tty /usr/bin/write" 
   2.655 +   This is output by the chgrp wrapper during the util-linux installation.
   2.656 +   The util-linux package wants to install the write program as setgid tty,
   2.657 +   so that it is allowed to access other users' terminals. The chgrp wrapper
   2.658 +   prevents the changing of the group and the chmod wrapper prevents the
   2.659 +   setting of the setgid bit. You need to decide if you want the
   2.660 +   program to be setgid and if you decide in favor of this, do as root
   2.661 +   
   2.662 +       chgrp tty /usr/bin/write
   2.663 +       chmod g+s /usr/bin/write
   2.664 +   
   2.665 +    
   2.666 +Example 3: "*** install -d -m 755 /sbin"
   2.667 +   This is also from the util-linux installation. Util-linux, for no good
   2.668 +   reason, tries to recreate the /sbin directory. The install wrapper
   2.669 +   prevents this and you don't have to take any further action.
   2.670 +
   2.671 + 
   2.672 + 5.3 add_package_user/install_package
   2.673 + ------------------------------------
   2.674 +  
   2.675 +Whenever you install a new package on your system, you first have to create
   2.676 +a new user account, possibly create a new group and if you follow the advice
   2.677 +from this hint about making productive use of a package user's home directory,
   2.678 +you will have to set up that one, too. If you were to do all of this manually,
   2.679 +it would be a lot of work. The add_package_user and install_package scripts
   2.680 +in the more_control_helpers archive were written to automate this.
   2.681 +
   2.682 +The install_package script is the one you will normally use to prepare for
   2.683 +installing a new package. It takes 3 parameters: the description of the 
   2.684 +package, the name of the package user account to create and the name of the
   2.685 +package user's primary group. So if you use the user=group scheme recommended 
   2.686 +by this hint and are as creative with your package descriptions as I am, then 
   2.687 +the command you'll use to prepare for installing package "foo" will be
   2.688 +
   2.689 +    install_package foo foo foo
   2.690 +
   2.691 +This command does 2 things. First it calls the add_package_user script with
   2.692 +the provided name, group and description plus sensible default values for 
   2.693 +add_package_user's other parameters. Then, after add_package_user has created 
   2.694 +the package user account, install_package automatically uses the su-command
   2.695 +to switch to the newly created account. If the default .bashrc and
   2.696 +.bash_profile scripts you use for package users contain the command "cd" as do
   2.697 +the examples in the more_control_helpers archive, you will be put right into
   2.698 +your package user's home directory so that you can start installing right away.
   2.699 +
   2.700 +TIP:
   2.701 +  The install_package script can be called with a single argument that will
   2.702 +  be used as user name, group name and description. So instead of the above
   2.703 +  command a simple `install_package foo' would have sufficed.
   2.704 +
   2.705 +The add_package_user script is responsible for the actual work of creating
   2.706 +a new package user account. Given a name, a group name and a description, it
   2.707 +will create a new user account with the provided primary group and the install
   2.708 +group as supplementary group. The groups will be created if necessary. 
   2.709 +add_package_user takes several arguments that determine the numeric ranges from
   2.710 +which it will pick the new user's UID and the GIDs for groups it needs to
   2.711 +create. add_package_user does not only create the package user account. It
   2.712 +will set up a home directory for it, too. You can either specify the directory
   2.713 +or go with the default, which is /usr/src/<name>, where <name> is the name
   2.714 +provided for the new account. If the home directory already exists, its
   2.715 +ownership and that of any existing contents will be changed to the new user.
   2.716 +If it doesn't exist, it will be created. 
   2.717 +
   2.718 +The contents of /etc/pkgusr/skel-package will be copied into the new package
   2.719 +user's home directory (without overwriting pre-existing files). 
   2.720 +The more_control_helpers archive contains an example of a useful skel-package
   2.721 +directory. Note that symlinks are copied as symlinks, so skel-package is the
   2.722 +perfect place to put .bashrc and .bash_profile symlinks to a central location
   2.723 +that will ensure that all package user accounts have the same environment.
   2.724 +This is especially useful to make sure that all package users have the
   2.725 +wrappers directory in their PATH.
   2.726 +
   2.727 +  
   2.728 + 5.4 forall_direntries_from
   2.729 + --------------------------
   2.730 +
   2.731 +The forall_direntries_from script is a very useful tool for common package
   2.732 +management tasks. It can roughly be described as a shortcut for 
   2.733 +"find / -user <name> -or -group <name>  <commands>", where <name> is the
   2.734 +first parameter to forall_direntries_from and <commands> are the remaining
   2.735 +parameters. However, forall_direntries_from takes care of making sure that
   2.736 +only relevant filesystems are scanned and shields you from certain unpleasant
   2.737 +surprises such as "Oops, I forgot that -depth negates -prune and have 
   2.738 +accidentally wiped out my home directory." or "Oops, I forgot to -prune /proc
   2.739 +and now I'm getting parity errors on my SCSI bus.". 
   2.740 +
   2.741 +IMPORTANT NOTE: By default the forall_direntries_from script will only scan
   2.742 +the / filesystem and will not traverse other filesystems. If you have
   2.743 +relevant directories that need to be scanned on other filesystems, you will 
   2.744 +need to edit the script and add the respective mount point(s) to the
   2.745 +fs_to_scan list at the beginning of the script. The most likely candidate for
   2.746 +addition is "/usr".
   2.747 +
   2.748 +Application examples:
   2.749 +
   2.750 +Example 1: Create a tar.gz archive of all files that belong to <package>, e.g.
   2.751 +           for installing <package> on another machine without having to 
   2.752 +           recompile it there.
   2.753 +
   2.754 +  forall_direntries_from <package> -fprint0 /tmp/files.lst
   2.755 +  tar --null -P -czf /tmp/archive.tar.gz --files-from=/tmp/files.lst
   2.756 +
   2.757 +
   2.758 +Example 2: Print out all setuid root binaries installed by <package>.
   2.759 +           (This only works if you use the user=group scheme.)
   2.760 +  
   2.761 +  forall_direntries_from <package> -perm +u+s -print
   2.762 +
   2.763 +
   2.764 +Example 3: List all binaries in /bin and /usr/bin belonging to "me" (i.e. the 
   2.765 +           package user executing the command) in alphabetical order.
   2.766 +
   2.767 +  forall_direntries_from $(whoami) -path "*/bin/*" -printf "%f\n" | sort
   2.768 +
   2.769 +
   2.770 +Example 4: Uninstall <package>.
   2.771 +          
   2.772 +  See following section about the uninstall_package script.
   2.773 + 
   2.774 +                                   
   2.775 + 5.5 uninstall_package
   2.776 + ---------------------
   2.777 +
   2.778 +The uninstall_package script is basically a forall_direntries_from
   2.779 +application example in script form. The command `uninstall_package foo'
   2.780 +prints out the forall_direntries_from call that you have to use to delete
   2.781 +all the files of package "foo" (except for those in directories that 
   2.782 +forall_direntries_from is instructed not to scan) together with some
   2.783 +explanations. So in order to delete the files from package foo, you would 
   2.784 +execute `uninstall_package foo' and then copy'n'paste the command it prints
   2.785 +to the command line. As a safeguard the forall_direntries_from call has an 
   2.786 +"echo" in front of the "rm" and "rmdir" calls, so if you execute it, the files 
   2.787 +will not actually be deleted unless you remove both instances of "echo". 
   2.788 +It is recommended that you execute the command once with the echos and check 
   2.789 +the output to make sure that only the files you intend to be deleted are in 
   2.790 +the list. After you've confirmed that, you can use the shell's history to 
   2.791 +recall the command, edit out the instances of "echo" and remove the files 
   2.792 +for real.
   2.793 +
   2.794 +
   2.795 + 5.6 list_suspicious_files/list_suspicious_files_from
   2.796 + ----------------------------------------------------
   2.797 +
   2.798 +list_suspicious_files looks for filesystem entries that are out of the ordinary
   2.799 +in some way and prints a categorized list of them. Things that qualify as
   2.800 +suspicious include setuid and setgid binaries, world-writable files, symlinks 
   2.801 +that are possibly broken, hard links, install directories with unusual 
   2.802 +permissions and other stuff. You should run this script after you've finished 
   2.803 +your new LFS system and in regular intervals after that. Investigate the
   2.804 +listing closely.
   2.805 +
   2.806 +TIP: 
   2.807 +  When you check the list of setuid and setgid files, don't forget to
   2.808 +  look at the actual user or group ownership of the file. It's easy to forget
   2.809 +  that, especially in the setuid case, because we often equate setuid with
   2.810 +  setuid root since setuid is seldom used with other user accounts.
   2.811 +
   2.812 +list_suspicious_files_from takes a user or group name or a UID/GID as an 
   2.813 +argument and reports suspicious entries only when they are owned by the given 
   2.814 +user or group. Usually you would not call this script directly but instead
   2.815 +use list_package (described in the next section), whose output includes that 
   2.816 +from list_suspicious_files_from.
   2.817 +
   2.818 +IMPORTANT NOTE: By default the list_suspicious_files script will only scan
   2.819 +the / filesystem and will not traverse other filesystems. If you have
   2.820 +relevant directories that need to be scanned on other filesystems, you will 
   2.821 +need to edit the script and add the respective mount point(s) to the
   2.822 +fs_to_scan list at the beginning of the script. The most likely candidate for
   2.823 +addition is "/usr".
   2.824 +
   2.825 +
   2.826 + 5.7 list_package
   2.827 + ----------------
   2.828 +
   2.829 +list_package tells you everything about a package's installed files. In
   2.830 +general you will want to execute something like 
   2.831 +
   2.832 +   list_package $(whoami) >pkg.lst
   2.833 +   
   2.834 +right after installing a package and you can forget about the chronically
   2.835 +inaccurate content listings in the (B)LFS book. 
   2.836 +The following (shortened) output for util-linux speaks for itself:
   2.837 +
   2.838 +PS1> list_package util-linux
   2.839 +
   2.840 +EXECUTABLES (in */bin or */sbin)
   2.841 +  agetty, arch, blockdev, cal, cfdisk, [...] vidmode(->rdev), whereis, write
   2.842 +
   2.843 +EXECUTABLES WITH NO MANPAGE (in */bin or */sbin)
   2.844 +  fsck.cramfs, mkfs.cramfs
   2.845 +
   2.846 +MANPAGE SUMMARIES OF EXECUTABLES (in */bin or */sbin)
   2.847 +  agetty: alternative Linux getty
   2.848 +  arch: print machine architecture
   2.849 +  blockdev: call block device ioctls from the command line
   2.850 +  cal: displays a calendar
   2.851 +  cfdisk: Curses based disk partition table manipulator for Linux
   2.852 +  chkdupexe: find duplicate executables
   2.853 +  col: filter reverse line feeds from input
   2.854 +  [...]
   2.855 +  swapon: enable/disable devices and files for paging and swapping
   2.856 +  tailf: follow the growth of a log file
   2.857 +  tunelp: set various parameters for the lp device
   2.858 +  ul: do underlining
   2.859 +  umount: unmount file systems
   2.860 +  vidmode: query/set image root device, RAM disk size, or video mode
   2.861 +  whereis: locate the binary, source, and manual page files for a command
   2.862 +  write: send a message to another user
   2.863 +
   2.864 +EXTRA MANPAGES
   2.865 +  /usr/share/man/man5/fstab.5
   2.866 +  /usr/share/man/man5/nfs.5
   2.867 +  /usr/share/man/man8/sln.8
   2.868 +
   2.869 +EXTRA EXECUTABLES (not in */bin or */sbin)
   2.870 +  /usr/share/misc/getopt/getopt-parse.bash
   2.871 +  /usr/share/misc/getopt/getopt-parse.tcsh
   2.872 +  /usr/share/misc/getopt/getopt-test.bash
   2.873 +  /usr/share/misc/getopt/getopt-test.tcsh
   2.874 +
   2.875 +ALL FILES
   2.876 +  /etc/fdprm
   2.877 +  /sbin/agetty
   2.878 +  /sbin/blockdev
   2.879 +  /sbin/cfdisk
   2.880 +  /sbin/ctrlaltdel
   2.881 +  /sbin/elvtune
   2.882 +  /sbin/fdisk
   2.883 +  /sbin/fsck.cramfs
   2.884 +  /sbin/fsck.minix
   2.885 +  /sbin/hwclock
   2.886 +  /sbin/losetup
   2.887 +  /sbin/mkfs
   2.888 +  /sbin/mkfs.bfs
   2.889 +  [...]
   2.890 +  /usr/share/man/man8/rootflags.8
   2.891 +  /usr/share/man/man8/setfdprm.8
   2.892 +  /usr/share/man/man8/setsid.8
   2.893 +  /usr/share/man/man8/sfdisk.8
   2.894 +  /usr/share/man/man8/sln.8
   2.895 +  /usr/share/man/man8/swapoff.8
   2.896 +  /usr/share/man/man8/swapon.8
   2.897 +  /usr/share/man/man8/tunelp.8
   2.898 +  /usr/share/man/man8/umount.8
   2.899 +  /usr/share/man/man8/vidmode.8
   2.900 +  /usr/share/misc/getopt
   2.901 +  /usr/share/misc/getopt/getopt-parse.bash
   2.902 +  /usr/share/misc/getopt/getopt-parse.tcsh
   2.903 +  /usr/share/misc/getopt/getopt-test.bash
   2.904 +  /usr/share/misc/getopt/getopt-test.tcsh
   2.905 +
   2.906 +SETUID FILES
   2.907 +  -rwsr-xr-x "/usr/bin/mount"  root:util-linux
   2.908 +  -rwsr-xr-x "/usr/bin/umount"  root:util-linux
   2.909 +
   2.910 +SETGID FILES
   2.911 +  -rwxr-sr-x "/usr/bin/write"  util-linux:tty
   2.912 +
   2.913 +FILES WITH UNUSUAL PERMISSIONS
   2.914 +  -rwsr-xr-x "/usr/bin/mount"  root:util-linux
   2.915 +  -rwsr-xr-x "/usr/bin/umount"  root:util-linux
   2.916 +  -rwxr-sr-x "/usr/bin/write"  util-linux:tty
   2.917 +
   2.918 +
   2.919 +Note: list_package works regardless of the prefix you've installed the package
   2.920 +      with, so you can for instance configure with --prefix=/opt/package and
   2.921 +      list_package will work just fine (provided that /opt is on a
   2.922 +      filesystem configured to be scanned by forall_direntries_from and
   2.923 +      list_suspicious_files).
   2.924 +
   2.925 +Note: list_package only considers manpages actually owned by the package to 
   2.926 +      list. It will not consider manpages installed by another package. This
   2.927 +      means that you may see executables identified as not having a manpage
   2.928 +      although they do have one courtesy of another package 
   2.929 +      (usually man-pages).
   2.930 +
   2.931 +
   2.932 + 5.8 grep_all_regular_files_for
   2.933 + ------------------------------
   2.934 +
   2.935 +This script is not really related to the package user system, but because of
   2.936 +its similarity to the other scripts I've included it anyway. The sole purpose
   2.937 +of this script is to identify files that store references to the build 
   2.938 +environment, specifically the /tools directory. Such references may point out
   2.939 +problems, since the /tools directory is supposed to be transient.
   2.940 +Don't forget that results for unstripped binaries and libraries are not 
   2.941 +reliable, because debugging information often includes references to the
   2.942 +build environment. These do not cause trouble (unless you're trying to debug
   2.943 +the objects in question after deleting /tools).
   2.944 +  
   2.945 +IMPORTANT NOTE: By default the grep_all_regular_files_for script will only scan
   2.946 +the / filesystem and will not traverse other filesystems. If you have
   2.947 +relevant directories that need to be scanned on other filesystems, you will 
   2.948 +need to edit the script and add the respective mount point(s) to the
   2.949 +fs_to_scan list at the beginning of the script. The most likely candidate for
   2.950 +addition is "/usr".  
   2.951 +  
   2.952 +  
   2.953 + 5.9 The etc Directory
   2.954 + ---------------------
   2.955 + 
   2.956 +If you follow the instructions provided in the LFS-specific part of this hint,
   2.957 +the contents of the etc directory will be installed in /etc/pkgusr. The
   2.958 +directory contains a bashrc and bash_profile for package users that takes
   2.959 +care of package user specific details such as putting the wrappers directory
   2.960 +at the beginning of the PATH and calling cd, so that `su <package>' will
   2.961 +put you right into the package user's home directory. Also contained in the
   2.962 +etc directory is a skel-package directory as used by 
   2.963 +install_package/add_package_user to populate the home directories of newly
   2.964 +created package users.
   2.965 + 
   2.966 + 
   2.967 + 5.10 ldconfig.c
   2.968 + --------------------
   2.969 +
   2.970 +A lot of packages contain libraries. Having to manually call /sbin/ldconfig
   2.971 +as root after installing these packages can become annoying. It would be
   2.972 +much easier if one could grant package users permission to use /sbin/ldconfig.
   2.973 +Making ldconfig setuid root would be a simple and effective solution, but
   2.974 +there are some pitfalls. First of all it is imperative that ordinary users
   2.975 +be prohibited from executing ldconfig with elevated privileges. Otherwise
   2.976 +an ordinary user can overwrite and possibly read arbitrary files on the 
   2.977 +system. This can be prevented by making ldconfig owned by group install and
   2.978 +removing the o+x bit from the file mode. While this setup is no less secure
   2.979 +than running `make install' as root, one reason why we're using package users
   2.980 +is because we don't feel safe doing that. To protect against the (admittedly
   2.981 +very theoretical) danger of a malicious package user, the more_control_helpers
   2.982 +provide ldconfig.c. The only thing this program does is to call 
   2.983 +`/sbin/ldconfig -v' with an empty environment. Because it doesn't evaluate
   2.984 +any user input and doesn't pass any user-provided data to ldconfig, it can
   2.985 +safely be made setuid root. 
   2.986 +
   2.987 +
   2.988 + 5.11 Temporary Files 
   2.989 + --------------------
   2.990 +
   2.991 +3 files in the more_control_helpers archive are only used during the 
   2.992 +installation of the base LFS system and are not installed permanently.
   2.993 +The first of them is the installdirs.lst file that contains a list of 
   2.994 +directories that should be install directories. 
   2.995 +The second file is sbin/useradd, which is a very primitive shell script that
   2.996 +adds a new entry to /etc/passwd. It allows us to add package users before
   2.997 +we have installed shadow, which provides a real useradd.
   2.998 +Finally there is groupadd, which is like useradd, only for /etc/group.
   2.999 +Both scripts, useradd as well as groupadd, do very little error checking and
  2.1000 +only support the syntax needed by install_package/add_package_user. So don't
  2.1001 +try anything funky with them.
  2.1002 +
  2.1003 +  
  2.1004 +------------------------ PART 2: LFS Specifics ------------------------------
  2.1005 +
  2.1006 +
  2.1007 +#############################################################################
  2.1008 + 6. Pre-Chroot Phase (Chapter 5)
  2.1009 +#############################################################################
  2.1010 +
  2.1011 +Build Chapter 5 explained by the LFS book with the following changes:
  2.1012 +
  2.1013 +coreutils:
  2.1014 +  After running `make install' for the coreutils
  2.1015 +  package, issue the following command (still from within the coreutils
  2.1016 +  build directory):
  2.1017 +
  2.1018 +    cp src/su /tools/bin
  2.1019 +    
  2.1020 +  This installs the su binary. Coreutils doesn't install su when working as
  2.1021 +  non-root (which we do in Chapter 5), because su needs to be setuid root for
  2.1022 +  normal operation and a non-root user cannot install setuid root binaries. 
  2.1023 +  But for our purposes (i.e. su'ing from root to a package user) a non-setuid 
  2.1024 +  su is enough, so we just copy coreutils' su to /tools/bin without making it
  2.1025 +  setuid root.
  2.1026 +  
  2.1027 +more_control_helpers:
  2.1028 +  When you have reached the end of Chapter 5, before you begin with Chapter 6 
  2.1029 +  you will need to install the helper scripts in the /tools directory so that
  2.1030 +  they are available once you've entered the chroot environment. Use the
  2.1031 +  following commands to install the more_control_helpers in /tools:
  2.1032 +
  2.1033 +    cd /tools &&
  2.1034 +    tar xjf /path/to/more_control_helpers.tar.bz2 &&
  2.1035 +    cd  more_control_helpers &&
  2.1036 +    cp ./sbin/* /tools/bin
  2.1037 +    
  2.1038 +  Note that the target directory is "/tools/bin" in the cp command and 
  2.1039 +  *not* "/tools/sbin", although the latter location would be more appropriate.
  2.1040 +  The reason for this is simply that the LFS instructions do not add 
  2.1041 +  "/tools/sbin" to the PATH (and neither do the instructions in this hint).
  2.1042 +
  2.1043 +
  2.1044 +#############################################################################
  2.1045 + 7. Chroot Phase (Chapter 6)
  2.1046 +#############################################################################
  2.1047 +
  2.1048 + 7.1 Preparations
  2.1049 + ----------------
  2.1050 +
  2.1051 +Enter the chroot environment and follow the instructions from the book up to
  2.1052 +but *not* including the installation of the first package (which at the time of
  2.1053 +this writing is linux-libc-headers). Now install the more_control_helpers
  2.1054 +files in their proper locations on the new LFS system:
  2.1055 +
  2.1056 +    cp -a /tools/more_control_helpers/etc /etc/pkgusr &&
  2.1057 +    chown -R 0:0 /etc/pkgusr &&
  2.1058 +    cp -a /tools/more_control_helpers/lib /usr/lib/pkgusr &&
  2.1059 +    chown -R 0:0 /usr/lib/pkgusr &&
  2.1060 +    cp /tools/more_control_helpers/bin/* /usr/bin &&
  2.1061 +    cp /tools/more_control_helpers/sbin/* /usr/sbin &&
  2.1062 +    rm /usr/sbin/{useradd,groupadd}
  2.1063 +
  2.1064 +Note that the useradd and groupadd scripts are not installed on the new LFS 
  2.1065 +system. These scripts are just temporary workarounds we will use as long as 
  2.1066 +the real useradd and groupadd are not available. Therefore they should only 
  2.1067 +be in /tools/bin.
  2.1068 +
  2.1069 +ATTENTION! If you decide to use a different directory than /usr/lib/pkgusr
  2.1070 +for the wrappers, you have to be careful, because at least the glibc
  2.1071 +configure script ignores certain directories when looking for programs. The
  2.1072 +list of ignored directories for glibc includes, among others, everything that 
  2.1073 +starts with "/etc", "/usr/etc" and "/sbin". Wrappers put into a directory that
  2.1074 +matches any of these patterns would be ineffective.
  2.1075 +
  2.1076 +Now it's time to create the install group:
  2.1077 +
  2.1078 +    groupadd -g 9999 install
  2.1079 +
  2.1080 +The GID 9999 has been chosen because the default range used by 
  2.1081 +add_package_user for package user GIDs starts at 10000. Choose whatever number
  2.1082 +you like.
  2.1083 +
  2.1084 +Once the install group has been created you have to turn all the directories
  2.1085 +that packages will install files in into install directories. To make this
  2.1086 +easier I have compiled a list of install directories that can be found in
  2.1087 +the file /tools/more_control_helpers/installdirs.lst. The following command
  2.1088 +uses this list to assign the necessary directories to the install group.
  2.1089 +Note that you will get several error messages because of non-existent
  2.1090 +directories. This is because the list contains some directories not created
  2.1091 +by LFS.
  2.1092 +
  2.1093 +    chown 0:9999 $(cat /tools/more_control_helpers/installdirs.lst)
  2.1094 +
  2.1095 +To be usable by package users, the directories will have to be group-writable
  2.1096 +and should be sticky as has been explained in the beginning of this hint.
  2.1097 +The following command sets the permissions appropriately.
  2.1098 +You will get the same error messages as for the previous command.
  2.1099 +
  2.1100 +    chmod ug=rwx,o=rxt $(cat /tools/more_control_helpers/installdirs.lst)
  2.1101 +
  2.1102 +
  2.1103 + 7.2 Walkthrough: Installing linux-libc-headers
  2.1104 + ----------------------------------------------
  2.1105 +
  2.1106 +At this point everything has been set up for creating the first package
  2.1107 +user. At the time of this writing the first package installed in the LFS
  2.1108 +book is Linux-Libc-Headers, so this package will serve as an example for how 
  2.1109 +things are done. The command
  2.1110 +
  2.1111 +     install_package 'Linux Headers' linux-libc-headers linux-libc-headers
  2.1112 +
  2.1113 +will create a package user with user and group name linux-libc-headers.
  2.1114 +If you don't want to use the user=group scheme, change the last argument to
  2.1115 +the desired group name. The description is arbitrary but needs to meet the
  2.1116 +requirements for the description field of an /etc/passwd entry.
  2.1117 +
  2.1118 +TIP:
  2.1119 +  Remember that you can call install_package with just one argument, if you
  2.1120 +  want user name, group name and description to be the same.
  2.1121 +
  2.1122 +The directory /usr/src/linux-libc-headers will be set up as the home directory
  2.1123 +for the package user, automatically populated with the contents of 
  2.1124 +/etc/pkgusr/skel-package. The install_package command also issues the command
  2.1125 +`su - linux-libc-headers' to assume the identity of the newly created package
  2.1126 +user. If you're using the bashrc and bash_profile scripts from the
  2.1127 +more_control_helpers archive, you will be put straight into the directory 
  2.1128 +/usr/src/linux-libc-headers and your prompt will look like this
  2.1129 +
  2.1130 +package linux-libc-headers:/usr/src/linux-libc-headers>
  2.1131 +     
  2.1132 +to show you that you're working as package user linux-libc-headers and
  2.1133 +that your current working directory is /usr/src/linux-libc-headers.
  2.1134 +
  2.1135 +Use the command 
  2.1136 +   
  2.1137 +     echo $PATH
  2.1138 +
  2.1139 +to verify that your PATH starts with "/usr/lib/pkgusr", the directory that 
  2.1140 +contains the wrappers, and ends with "/tools/bin".
  2.1141 +
  2.1142 +Now everything is prepared for installing the package according to the
  2.1143 +instructions in the LFS book. Note that at the time of this writing the 
  2.1144 +LFS book tells you to execute a chown command to make sure that the headers 
  2.1145 +are owned by root. This is just because the packager has made a very common 
  2.1146 +mistake when creating the tarball for the headers: He has archived the files 
  2.1147 +with a non-root user/group assignment. When unpacking such a tarball as root, 
  2.1148 +the files end up being owned by some weird user/group combination, which may 
  2.1149 +open a security hole. When you're working as a package user this can not 
  2.1150 +happen and you don't want to chown the headers to root:root, because that 
  2.1151 +would defeat the whole point of installing the headers with a package user.
  2.1152 +This is one of the small points on which you will have to deviate from the 
  2.1153 +standard LFS instructions when using package users. More package user related
  2.1154 +issues with the current LFS book can be found in the next section.
  2.1155 +
  2.1156 +After you've installed the headers, simply issue the command
  2.1157 +
  2.1158 +    exit
  2.1159 +    
  2.1160 +to become root again. Now would be a good time to think about useful
  2.1161 +customizations for /etc/pkgusr/{bash_profile,bashrc} and/or 
  2.1162 +/etc/pkgusr/skel-package, if you've not already customized them.
  2.1163 +Once you're satisfied with your setup, install the rest of the packages.
  2.1164 +The following section will help you with some problems that you will run into.
  2.1165 +
  2.1166 +
  2.1167 + 7.3 Known Issues with LFS Packages
  2.1168 + ----------------------------------
  2.1169 +
  2.1170 +This section has details on the package user related problems you will face
  2.1171 +when building your LFS system. You should copy the information from this
  2.1172 +section to the INSTALL NOTES of the relevant .project files for the packages 
  2.1173 +concerned, together with any of your own notes.
  2.1174 +
  2.1175 +NOTE: If you're building by an LFS book later than 6.2 it is recommended that
  2.1176 +      you read this complete chapter before you start building any packages.
  2.1177 +      If your LFS version is 6.2 then it's fine to read this section package
  2.1178 +      by package as you progress with your build.
  2.1179 +
  2.1180 +
  2.1181 +linux-libc-headers:
  2.1182 +    At the time of this writing the LFS book tells you to execute a chown 
  2.1183 +    command to make sure that the headers are owned by root. This is just 
  2.1184 +    because the packager has made a very common mistake when creating the 
  2.1185 +    tarball for the headers: He has archived the files with a non-root 
  2.1186 +    user/group assignment. When unpacking such a tarball as root, the files 
  2.1187 +    end up being owned by some weird user/group combination, which may open 
  2.1188 +    a security hole. When you're working as a package user this can not happen 
  2.1189 +    and you don't want to chown the headers to root:root, because that would 
  2.1190 +    defeat the whole point of installing the headers with a package user.
  2.1191 +    
  2.1192 +    There used to be another packaging error in the linux-libc-headers. 
  2.1193 +    Version 2.6.12.0 (current as of this writing) doesn't have it anymore,
  2.1194 +    but older versions used to contain files with permissions set incorrectly. 
  2.1195 +    All headers are supposed to be world-readable, but they weren't. More about
  2.1196 +    this later in the glibc notes.
  2.1197 +
  2.1198 +
  2.1199 +man-pages:
  2.1200 +    If the name you use for the man-pages package user is not exactly 
  2.1201 +    "man-pages", then you will have to change the variable "manpagesowner"
  2.1202 +    right at the beginning of the wrapper script `install'.
  2.1203 +
  2.1204 +    Recent versions of man-pages contain POSIX manpages that the package
  2.1205 +    tries to install in /usr/share/man/man{0,1,3}p. There's also a manpage
  2.1206 +    that man-pages wants to install to /usr/share/man/man9.
  2.1207 +    As /usr/share/man is
  2.1208 +    not an install directory and the LFS book does not have instructions to
  2.1209 +    create these directories at the time of this writing, the installation 
  2.1210 +    will fail and the respective man-pages will not be installed.
  2.1211 +    Possible remedies:
  2.1212 +      1. Make /usr/share/man an install directory. 
  2.1213 +         Consequence: All Packages will be able to create new subdirectories
  2.1214 +         in /usr/share/man. I find this undesirable because there are packages
  2.1215 +         that create directories for manpages in foreign languages that I
  2.1216 +         don't want. YMMV.
  2.1217 +      2. Ignore the problem and live without the POSIX manpages. Unless
  2.1218 +         you are a developer (including script writer) who is interested
  2.1219 +         in writing portable programs/scripts this is a good solution.
  2.1220 +      3. Create the directories /usr/share/man/man{0,1,3}p and man9 as root
  2.1221 +         prior to installing man-pages. You'll have to either chown them
  2.1222 +         to the man-pages package user or make them install directories.
  2.1223 +         This is my preferred solution.
  2.1224 +
  2.1225 +
  2.1226 +glibc:
  2.1227 +    It is kind of unfortunate that the packaging error of libc-linux-headers 
  2.1228 +    concerning the permissions doesn't exist in the current version. It 
  2.1229 +    provided for a great learning experience. I've kept the following section
  2.1230 +    in the hint for this reason even though it doesn't apply anymore. Please
  2.1231 +    take the time to read it.
  2.1232 +    
  2.1233 +--------------------- old stuff start ----------------------------------------
  2.1234 +    Because of the error, the headers in /tools/include
  2.1235 +    are not world-readable. Unfortunately the LFS book (as of this writing)
  2.1236 +    does not correct this in Chapter 5 like it does in Chapter 6. For a
  2.1237 +    standard LFS build this is no problem, because glibc is built as root and
  2.1238 +    root can access everything regardless of permissions.
  2.1239 +    The glibc package user, however, does not have permission to access
  2.1240 +    these headers. This will cause several configure tests to fail, because
  2.1241 +    the respective test programs can not be compiled.
  2.1242 +    The end result is the error message "/lib/cpp fails sanity check", which
  2.1243 +    is completely nonsensical as we don't have a /lib/cpp.
  2.1244 +    
  2.1245 +    This is the perfect opportunity to introduce rule #1 of error diagnostics:
  2.1246 +    
  2.1247 +       NEVER TRUST DIAGNOSTIC MESSAGES !
  2.1248 +       
  2.1249 +    There are 2 kinds of diagnostic messages:
  2.1250 +    
  2.1251 +      1. Those that are unnecessary, because once you see which component has
  2.1252 +         failed, the source of the problem is obvious.
  2.1253 +      2. Those that grossly misdiagnose the source of the problem and lead
  2.1254 +         you to draw the wrong conclusions.
  2.1255 +    
  2.1256 +    No, there is no other kind. Trust me ;-)
  2.1257 +    In this case, /lib/cpp has nothing to do with the problem. It doesn't
  2.1258 +    exist and that's fine. The message just wants to trick you into doing
  2.1259 +    something stupid such as create a symlink /lib/cpp -> /tools/bin/cpp.
  2.1260 +    But that would be totally wrong. Before you jump to any premature 
  2.1261 +    conclusions you should always try to get as much *low-level* information 
  2.1262 +    as you can. Diagnostic messages are *high-level* information. They 
  2.1263 +    represent a filtered view of the problem, which is usually of little help.
  2.1264 +    Fortunately the message (the complete one, not the part quoted above) also
  2.1265 +    points at the source for the necessary low-level information. In this 
  2.1266 +    case that is the file config.log (not to be confused with configure.log, 
  2.1267 +    the file created by the build script included in the more_control_helpers 
  2.1268 +    archive).
  2.1269 +    config.log is created by all autoconf-created configures (not just that 
  2.1270 +    of glibc) and it contains, among other things, the test programs used by 
  2.1271 +    configure and messages output while building and running them. Whenever a 
  2.1272 +    configure script fails or gives weird results, check config.log. And 
  2.1273 +    always remember rule #2 of error diagnostics
  2.1274 +    
  2.1275 +       ALWAYS START AT THE FIRST ERROR
  2.1276 +       
  2.1277 +    This seems pretty obvious, but nevertheless people commonly do the exact
  2.1278 +    opposite. It's just too tempting to start at the point of the final 
  2.1279 +    failure and try to work backwards. In this case many people would open 
  2.1280 +    config.log and scroll to the point of the failed /lib/cpp sanity check.
  2.1281 +    After all, that's what caused configure to abort and so that's what needs
  2.1282 +    to be fixed, right?  WRONG! Someone who takes this approach just sees the 
  2.1283 +    error message "/lib/cpp: No such file or directory" and is even more 
  2.1284 +    convinced that a missing /lib/cpp symlink (or program) is the problem.
  2.1285 +    
  2.1286 +    The correct way to approach such a problem is to start at the beginning
  2.1287 +    of config.log, to scroll down to first error message and to check if it
  2.1288 +    is an issue that needs to be fixed (error messages in config.log are
  2.1289 +    not always signs for a problem). If the issue needs to be fixed, then
  2.1290 +    it needs to be fixed first, because all later errors could be rooted in
  2.1291 +    this issue (even if, no, *especially* if you don't believe this is the 
  2.1292 +    case).
  2.1293 +    If we apply this advice to the problem at hand, we quickly get to the first
  2.1294 +    serious error in config.log: 
  2.1295 +
  2.1296 +      "/tools/include/linux/limits.h: Permission denied"
  2.1297 +    
  2.1298 +    A quick check with ls reveals that indeed the directory with the linux
  2.1299 +    headers is not world-readable, which is obviously wrong. The fix is
  2.1300 +    easy. Just make (as root) the header directories /tools/include/{linux,asm} 
  2.1301 +    world-readable with commands similar to those the LFS book presents 
  2.1302 +    in Chapter 6 for the installation of linux-libc-headers.
  2.1303 +    Once this change has been made, glibc's configure succeeds.
  2.1304 +--------------------- old stuff end -----------------------------------------    
  2.1305 +
  2.1306 +TIP:
  2.1307 +    Even when configure completes successfully, you should still check the
  2.1308 +    output carefully to see if there is anything odd. E.g. if you're using
  2.1309 +    the wrappers, you should check that configure outputs the line
  2.1310 +    
  2.1311 +       checking for a BSD-compatible install... /usr/lib/pkgusr/install -c
  2.1312 +    
  2.1313 +    If configure detects a different install, such as /tools/bin/install,
  2.1314 +    something is wrong. Maybe there's a typo in the PATH for the package
  2.1315 +    user, or you've put the wrappers into a directory that is ignored by
  2.1316 +    configure.
  2.1317 +    
  2.1318 +
  2.1319 +    With the wrappers the glibc build and install should work smoothly. 
  2.1320 +    The wrapper script for install makes sure that the /usr/share/locale/* 
  2.1321 +    directories become install directories so that other programs can install 
  2.1322 +    their localized messages. 
  2.1323 +    One thing that the wrappers do not take care of, 
  2.1324 +    however, is the file /usr/share/info/dir. Because in the current LFS build
  2.1325 +    order glibc is the first package that installs info files, dir is owned by 
  2.1326 +    and only writable by glibc. In order to allow other packages to install 
  2.1327 +    info pages, execute the following commands as root:
  2.1328 +    
  2.1329 +       chown root:install /usr/share/info/dir &&
  2.1330 +       chmod ug=rw,o=r /usr/share/info/dir
  2.1331 +
  2.1332 +NOTE:
  2.1333 +    glibc wants to install the program pt_chown as setuid root. If you install
  2.1334 +    as a package user, the program will get installed but not given root
  2.1335 +    privileges (because of the install wrapper). 
  2.1336 +    The following info is from the glibc docs:
  2.1337 +          
  2.1338 +       One auxiliary program, `/usr/libexec/pt_chown', is installed setuid
  2.1339 +       `root'.  This program is invoked by the `grantpt' function; it sets the
  2.1340 +       permissions on a pseudoterminal so it can be used by the calling
  2.1341 +       process.  This means programs like `xterm' and `screen' do not have to
  2.1342 +       be setuid to get a pty.  (There may be other reasons why they need
  2.1343 +       privileges.)  If you are using a 2.1 or newer Linux kernel with the
  2.1344 +       `devptsfs' or `devfs' filesystems providing pty slaves, you don't need
  2.1345 +       this program; otherwise you do.  The source for `pt_chown' is in
  2.1346 +       `login/programs/pt_chown.c'.
  2.1347 +                               
  2.1348 +    So unless you're building a system that does not use devpts (which would
  2.1349 +    be quite unusual), this does not need to concern you.
  2.1350 +
  2.1351 +TIP:
  2.1352 +    In case you were wondering if you should create /etc/nsswitch.conf and
  2.1353 +    /etc/ld.so.conf as root or glibc, I recommend to assign all files that 
  2.1354 +    you manually create or manually edit to the root account. That way you can
  2.1355 +    distinguish between those files that can be regenerated automatically and
  2.1356 +    those that can not. Assigning even automatically generated files to
  2.1357 +    root once you make the first manual edit, ensures that a later 
  2.1358 +    reinstallation of a package won't silently do away with your manual tweaks.
  2.1359 +
  2.1360 +ldconfig:
  2.1361 +    Now that glibc has installed /sbin/ldconfig you can activate the ldconfig
  2.1362 +    wrapper if you want to. Perform the following steps as root 
  2.1363 +    AFTER re-adjusting the toolchain, 
  2.1364 +    just before starting with binutils:
  2.1365 +    
  2.1366 +       cd /usr/lib/pkgusr
  2.1367 +       gcc -O2 -W -Wall -o ldconfig ldconfig.c
  2.1368 +       chown root:install ldconfig
  2.1369 +       chmod u=rwxs,g=rxs,o= ldconfig
  2.1370 +  
  2.1371 +    These instructions make the ldconfig wrapper setuid root and setgid install
  2.1372 +    and prevent non-root users not in the install group from executing it. 
  2.1373 +    The setuid root is required so that it can replace /etc/ld.so.cache. 
  2.1374 +    The setgid install is not strictly required, but without it 
  2.1375 +    /etc/ld.so.cache will end up with the group of the last package user that 
  2.1376 +    touched it. If you use the user name=group name scheme this will cause the 
  2.1377 +    more_control_helpers scripts to believe that /etc/ld.so.cache belongs to 
  2.1378 +    the package in question which can be confusing.
  2.1379 +
  2.1380 +binutils:
  2.1381 +    Have you make /usr/share/info/dir group-writable as explained above in
  2.1382 +    the glibc notes? If you've missed that part, go back and do it now.
  2.1383 +    The installation of binutils should complete without problems. 
  2.1384 +    It does however cause minor conflicts with autoconf (see later).
  2.1385 +    
  2.1386 +NOTE:
  2.1387 +    At the time of this writing the version of bash used in the LFS book has
  2.1388 +    a bug that causes the list_package script to spit out errors and to list
  2.1389 +    all manpages of binutils (and other packages) as Broken. This bug is 
  2.1390 +    already fixed by the bash patch used by the book but the patch is not
  2.1391 +    applied in chapter 5. Since the manpage summary functionality of 
  2.1392 +    list_package requires man which is not installed until after bash is
  2.1393 +    rebuilt, this doesn't really matter, because while patching the
  2.1394 +    chapter 5 bash would get rid of the error messages, it wouldn't result
  2.1395 +    in usable manpage summaries.
  2.1396 +    
  2.1397 +    
  2.1398 +gcc:
  2.1399 +    Because the /usr/lib/libgcc_s.so* symlinks created at the beginning of
  2.1400 +    Chapter 6 is owned by root, gcc's installation cannot remove it. 
  2.1401 +    So you will have to remove it as root before `make install'.
  2.1402 +    Alternatively use
  2.1403 +    
  2.1404 +       chown -h gcc: /usr/lib/libgcc*
  2.1405 +       
  2.1406 +    to change ownership of the files in question after creating the gcc
  2.1407 +    package user. Note the -h option which has to be used to change 
  2.1408 +    ownership of the symlinks themselves rather than their target files.
  2.1409 +
  2.1410 +db:
  2.1411 +    It should be obvious that you don't want to change the ownership of the
  2.1412 +    installed files.
  2.1413 +    
  2.1414 +    
  2.1415 +coreutils:
  2.1416 +    Because the /bin/cat, /bin/pwd and /bin/stty symlinks are owned by root,
  2.1417 +    coreutils' installation cannot remove them. So you will have to remove 
  2.1418 +    them manually before `make install'. Alternatively use the command
  2.1419 +    
  2.1420 +       chown -h coreutils: /bin/{cat,pwd,stty}
  2.1421 +       
  2.1422 +    after creating the coreutils package user. Note the -h switch that makes
  2.1423 +    chown change the ownership of the symlinks themselves rather than their 
  2.1424 +    target files.
  2.1425 +    
  2.1426 +    The chapter 6 instructions move the coreutils binaries to /bin, including
  2.1427 +    the mv binary itself. You need to make sure that hashing is turned off
  2.1428 +    for this to work. The LFS book does this by putting `set +h' into the
  2.1429 +    LFS user's .bashrc. If you're following this hint, you're likely using
  2.1430 +    build scripts, so you need to put this command into the build script
  2.1431 +    before the mv commands.
  2.1432 +
  2.1433 +NOTE:
  2.1434 +    The man-pages package has already installed manpages for the binaries
  2.1435 +    from coreutils. The install wrapper will prevent coreutils from overwriting
  2.1436 +    those. This is done because the manpages from the man-pages package are 
  2.1437 +    of superior quality (although not necessarily uptodate). 
  2.1438 +    It also prevents errors during `make install' that
  2.1439 +    would otherwise occur because the coreutils package user cannot overwrite 
  2.1440 +    manpages owned by another user.
  2.1441 +    If you don't like the above behaviour and would rather have the original 
  2.1442 +    package manpages (because they are uptodate), you can set the variable 
  2.1443 +    manpagesowner at the beginning of the install wrapper to a string that
  2.1444 +    doesn't correspond to a package user name (it must not be empty, though!).
  2.1445 +    If you do this, you will have to resolve manpage conflicts in another way. 
  2.1446 +    The easiest way to handle this is probably to not install the man-pages 
  2.1447 +    package at the beginning of Chapter 6 but at the end, after all the other
  2.1448 +    packages have already installed their manpages. Then you need only deal 
  2.1449 +    with the conflicts once, when installing man-pages.
  2.1450 +
  2.1451 +
  2.1452 +ncurses:
  2.1453 +    The installation of ncurses (like that of other packages that include 
  2.1454 +    libraries) wants to run /sbin/ldconfig to update /etc/ld.so.cache. 
  2.1455 +    This fails because the package user doesn't have permission to replace 
  2.1456 +    /etc/ld.so.cache.
  2.1457 +    Making /etc/ld.so.cache group-writable by the install group doesn't help, 
  2.1458 +    because the permissions would be reset on the next call to /sbin/ldconfig.
  2.1459 +    This error will usually not abort the installation and you can just
  2.1460 +    run /sbin/ldconfig manually as root afterwards.
  2.1461 +    Alternatively you can use the ldconfig wrapper as described earlier.
  2.1462 +
  2.1463 +
  2.1464 +aclocal directory:
  2.1465 +    At the time of this writing the directory /usr/share/aclocal is
  2.1466 +    created during the bison installation. This directory contains
  2.1467 +    macros for autoconf. Other packages want to install 
  2.1468 +    files into this directory, so you should make it writable by the install 
  2.1469 +    group and sticky. 
  2.1470 +
  2.1471 +
  2.1472 +perl:
  2.1473 +    Before you do `make install', you will have to 
  2.1474 +    `chown -h perl: /usr/bin/perl' so that the perl package user is allowed to
  2.1475 +    remove the /usr/bin/perl symlink.
  2.1476 +    
  2.1477 +    If you will install add-on packages for perl as their own package users
  2.1478 +    into /usr/lib/perl5/site_perl, then you will need to turn 
  2.1479 +    /usr/lib/perl5/site_perl/ and its subdirectories into 
  2.1480 +    install directories. You don't need to do this now as you'll notice it
  2.1481 +    anyway when installing a perl add-on fails. 
  2.1482 +
  2.1483 +
  2.1484 +autoconf:
  2.1485 +    The autoconf package wants to install its own copy of standards.info,
  2.1486 +    which fails because binutils has already installed this file. You can 
  2.1487 +    either ignore the error or remove the binutils version of standards.info 
  2.1488 +    before `make install'.
  2.1489 +
  2.1490 +
  2.1491 +bash:
  2.1492 +  configure:
  2.1493 +    The bash configure script tests for the presence of the special devices
  2.1494 +    /dev/std* and /dev/fd/*. Unfortunately at the time of this writing the
  2.1495 +    test for /dev/fd/* is buggy (the test for /dev/stdin used to be broke, too
  2.1496 +    in bash-2.x, but has been fixed since). It ends up testing read access to 
  2.1497 +    standard input, 
  2.1498 +    which is the (pseudo)terminal you're building your system in. 
  2.1499 +    Unfortunately su doesn't change ownership of the terminal device, so when
  2.1500 +    you're su'd to a package user account, the terminal still belongs to the
  2.1501 +    login user. As the package user doesn't have read access to the device,
  2.1502 +    the tests fail.
  2.1503 +    
  2.1504 +    There is a simple way to get around this. Simply run ./configure like this
  2.1505 +    
  2.1506 +      ./configure ....  </dev/null
  2.1507 +    
  2.1508 +    The trick here is to redirect standard input (note, that this is a '<' not
  2.1509 +    a '>' !) to refer to /dev/null. Unlike the terminal device, /dev/null is
  2.1510 +    world-readable and world-writable, so the tests succeed as they should.
  2.1511 +    If you don't like this trick, you can also chown the terminal device in
  2.1512 +    question (see `ls -la /dev/fd/0') to the package user before building
  2.1513 +    bash.
  2.1514 +    
  2.1515 +  make check:
  2.1516 +    When running the test suite as a package user, the test "run-test" will 
  2.1517 +    fail with the output like this:
  2.1518 +
  2.1519 +      33d32
  2.1520 +      < *** chmod g+s /tmp/test.setgid
  2.1521 +      35c34
  2.1522 +      < 1
  2.1523 +      ---
  2.1524 +      > 0
  2.1525 +      64d62
  2.1526 +      < *** chmod u+s /tmp/test.setuid
  2.1527 +      66c64
  2.1528 +      < 1
  2.1529 +      ---
  2.1530 +      > 0
  2.1531 +      154c152
  2.1532 +      < 1
  2.1533 +      ---
  2.1534 +      > 0
  2.1535 +      160c158
  2.1536 +      < 1
  2.1537 +      ---
  2.1538 +      > 0
  2.1539 +    
  2.1540 +    The first 2 failures are caused by the chmod wrapper which prevents the
  2.1541 +    test from setting the setuid and setgid bits and outputs the *** warning.
  2.1542 +    The failures are harmless. You can get rid of them by removing the wrappers
  2.1543 +    directory from the PATH before running the tests.
  2.1544 +    
  2.1545 +    The last 2 failures are not specific to package users but will occur 
  2.1546 +    whenever you run the tests su'd to another user. The reasons are the same
  2.1547 +    as for the configure problem described earlier. The same solutions apply.
  2.1548 +    Either use chown (if you chowned before configure you're already 
  2.1549 +    done, of course) or run make check like this
  2.1550 +       
  2.1551 +      make check </dev/null
  2.1552 +    
  2.1553 +  make install:
  2.1554 +    Before you can `make install' you need to `chown -h bash: /bin/bash' as
  2.1555 +    root so that the bash installation can replace the /bin/bash symlink that
  2.1556 +    you manually created at the beginning of chapter 6.
  2.1557 +
  2.1558 +
  2.1559 +pkgconfig directory:
  2.1560 +    At the time of this writing the directory /usr/lib/pkgconfig is
  2.1561 +    created during the e2fsprogs installation. This directory contains
  2.1562 +    build information used by the pkg-config tool. Other packages want to 
  2.1563 +    install files into this directory, so you should make it writable by the
  2.1564 +    install group and sticky. 
  2.1565 +
  2.1566 +
  2.1567 +grub:
  2.1568 +    The commands to create and populate /boot/grub have to be executed as
  2.1569 +    root.
  2.1570 +    
  2.1571 +    
  2.1572 +grep:
  2.1573 +    Before you can `make install' you need to `chown -h grep: /bin/grep' as
  2.1574 +    root so that the grep installation can replace the /bin/grep symlink that
  2.1575 +    you manually created at the beginning of chapter 6.
  2.1576 +    
  2.1577 +
  2.1578 +inetutils:
  2.1579 +    This package contains some programs that it wants to be setuid root:
  2.1580 +    rsh, rcp, rlogin and ping
  2.1581 +    The install wrapper prevents these programs from being installed
  2.1582 +    setuid root. You must decide which of these programs you want to be 
  2.1583 +    setuid root and manually make them so. Be conservative. Don't make a
  2.1584 +    binary setuid root unless you *know* that ordinary users can't live
  2.1585 +    without it. Every setuid root binary is a potential security hole.
  2.1586 +
  2.1587 +
  2.1588 +iproute2:
  2.1589 +    This package tries to change the permissions of /usr/sbin and some man
  2.1590 +    directories. The install wrappers take care of this.
  2.1591 +
  2.1592 +
  2.1593 +man-db:
  2.1594 +    Even after installing man-db you won't get manpage summaries from
  2.1595 +    list_package, because the way list_package calls man it needs col
  2.1596 +    to work and col is from util-linux. You may however install util-linux
  2.1597 +    right away. The alphabetical sort is the only reason it is at the end
  2.1598 +    of Chapter 6.
  2.1599 +
  2.1600 +
  2.1601 +shadow:
  2.1602 +    By default shadow wants to install non-English manpages. This fails
  2.1603 +    because the /usr/share/man directory is not an install directory and
  2.1604 +    therefore package users are not allowed to create new subdirectories in it.
  2.1605 +    To solve this problem, before you `make install', open the file
  2.1606 +    man/Makefile, find the line 
  2.1607 +    
  2.1608 +      SUBDIRS = cs de es fr hu id it ja ko pl pt_BR ru zh_CN zh_TW
  2.1609 +    
  2.1610 +    and remove all the languages that you don't want to install. For those
  2.1611 +    languages that you do want to install, create directories with the
  2.1612 +    respective names in /usr/share/man as root and make them install
  2.1613 +    directories (i.e. group install, group-writable, sticky).
  2.1614 +    
  2.1615 +    There is yet another issue with shadow concerning manpages. The shadow
  2.1616 +    package contains a passwd.5 and a getspnam.3 manpage. 
  2.1617 +    Installation of these manpages is
  2.1618 +    automatically suppressed by the install wrapper, because it would 
  2.1619 +    overwrite the manpages provided by the man-pages package. As usual
  2.1620 +    the man-pages version is better, so you can simply ignore this issue.
  2.1621 +
  2.1622 +    shadow wants to install the programs su, chage, chfn, chsh, expiry, 
  2.1623 +    gpasswd, newgrp and passwd as setuid root. You will need to decide which 
  2.1624 +    of these programs you want to be setuid root and manually make them so. 
  2.1625 +
  2.1626 +
  2.1627 +sysklogd:
  2.1628 +    sysklogd's Makefile has /usr/bin/install hardwired as the install
  2.1629 +    program, which circumvents the install wrapper. The wrapper is needed 
  2.1630 +    for sysklogd because it tries to make its manpages owned by root 
  2.1631 +    (which obviously a package user is not allowed to do). 
  2.1632 +    Therefore, install with
  2.1633 +    
  2.1634 +      make INSTALL=install install
  2.1635 +
  2.1636 +
  2.1637 +udev:
  2.1638 +    udev wants to install files into the directory /usr/lib/pkgconfig. If
  2.1639 +    you've followed the instructions given further above you've already made
  2.1640 +    this an install directory. If you haven't, do so now or the udev 
  2.1641 +    installation will fail.
  2.1642 +    
  2.1643 +    The LFS instructions for installing udev tell you to execute the command
  2.1644 +      
  2.1645 +      mknod -m0666 /lib/udev/devices/null c 1 3
  2.1646 +      
  2.1647 +    Because a package user is not allowed to create device nodes, execute this
  2.1648 +    command as root.
  2.1649 +    
  2.1650 +
  2.1651 +util-linux:
  2.1652 +    util-linux wants to install write as setgid tty and u/mount as
  2.1653 +    setuid root. The wrappers catch this, so it doesn't cause the install to
  2.1654 +    fail, but as usual you'll have to decide if you want these programs to
  2.1655 +    have special privileges and take manual action as root if you do.
  2.1656 +
  2.1657 +
  2.1658 +##########################################################################  
  2.1659 + 8. Sanity Checks 
  2.1660 +##########################################################################
  2.1661 +
  2.1662 + 8.1 Suspicious Files
  2.1663 + --------------------
  2.1664 + 
  2.1665 +You probably ran the `list_package' command for each package and reviewed
  2.1666 +the results which include the suspicious files owned by that package. But even
  2.1667 +if you did that it's still a good idea to run the non-package specific 
  2.1668 +`list_suspicious_files' command once your build is complete. There could be
  2.1669 +something you overlooked the first time, or maybe you created a file as root
  2.1670 +with the wrong permissions. It doesn't hurt to check again and this will also
  2.1671 +give you the opportunity to review any setuid/setgid decisions you made with
  2.1672 +respect to the installed binaries.
  2.1673 +
  2.1674 +TIP: 
  2.1675 +  When you check the list of setuid and setgid files, don't forget to
  2.1676 +  look at the actual user or group ownership of the file. It's easy to forget
  2.1677 +  that, especially in the setuid case, because we often equate setuid with
  2.1678 +  setuid root since setuid is seldom used with other user accounts.
  2.1679 +
  2.1680 +  
  2.1681 + 8.2 References to Temporary Files
  2.1682 + ---------------------------------
  2.1683 +
  2.1684 +One big concern when building an LFS system is independence of the new LFS
  2.1685 +system from the files installed in /tools. The /tools directory is intended 
  2.1686 +to be temporary and it should be possible to delete it after building your
  2.1687 +LFS system with no adverse side effects. The `grep_all_regular_files_for'
  2.1688 +script from the more_control_helpers package can help you verify that your
  2.1689 +new LFS system is indeed clean. The command
  2.1690 +
  2.1691 +     grep_all_regular_files_for /tools
  2.1692 +
  2.1693 +will give you a list of all files that contain the string "/tools". Review the
  2.1694 +files in the list to make sure that no dependencies on the temporary files in
  2.1695 +/tools have crept in. But remember that results from binaries and libraries 
  2.1696 +are only meaningful after stripping away the debug information, because
  2.1697 +debug information necessarily includes references to the build environment.
  2.1698 +Of course, if you are a developer who will potentially run gdb on system
  2.1699 +libraries/binaries, your position will be that stripping away debug information
  2.1700 +is the wrong way to do away with /tools references. The other way to deal with
  2.1701 +them is to rebuild packages for which /tools references are reported. The new
  2.1702 +build will not involve any files from /tools and so the new debug information
  2.1703 +will not refer to /tools. Note that the LFS build instructions for glibc
  2.1704 +make glibc compile against /tools/glibc-kernheaders. Unless you copy the
  2.1705 +glibc-kernheaders directory to a location outside of /tools and compile glibc
  2.1706 +against that copy, you won't get rid of the /tools references in glibc's 
  2.1707 +debug information.
  2.1708 +No matter what means you choose to deal with the debug information issue, in 
  2.1709 +the end you should have a system where the above command produces only false 
  2.1710 +positives (such as "perlfaq3.1", which includes the URL
  2.1711 +"http://www.research.att.com/sw/tools/uwin/") and files that legitimately
  2.1712 +refer to /tools (such as a copy of this hint file).
  2.1713 +
  2.1714 +
  2.1715 +----------------------------- APPENDICES ----------------------------------
  2.1716 +
  2.1717 +
  2.1718 +###########################################################################
  2.1719 + Appendix A: Security Issues
  2.1720 +###########################################################################
  2.1721 +
  2.1722 + A.1 NFS
  2.1723 + -------
  2.1724 +
  2.1725 +If you use the network filesystem NFS, there are some things you need to
  2.1726 +look out for when using the package user system. A fundamental security 
  2.1727 +problem with NFS is that it blindly trusts the UID and GID of the client. 
  2.1728 +If an attacker can get access to the root account on a system in your network 
  2.1729 +that is allowed to mount NFS shares from your server, or if the attacker can 
  2.1730 +attach his own computer to your network, then this attacker can pretend to be 
  2.1731 +anyone. NFS will happily allow the attacker to work in the NFS exported 
  2.1732 +directory as any user he wants to be. The only exception is the root account. 
  2.1733 +By default NFS exports directories with the root_squash option that maps all 
  2.1734 +incoming requests from uid 0 to anonuid (65534 unless set in /etc/exports) 
  2.1735 +and gid 0 to anongid (65534 unless set in /etc/exports). This protects files 
  2.1736 +owned by root:root. On a normal system this includes most files in /bin, /etc,
  2.1737 +/lib and most other directories except /home. If you use the package user 
  2.1738 +scheme, however, most of these files are owned by package users. These files 
  2.1739 +are not protected by the root_squash option. In order to make NFS exports 
  2.1740 +secure, you have to add the option "all_squash" to every entry in /etc/exports 
  2.1741 +that exports a directory that contains files owned by package users. Note that 
  2.1742 +all_squash is always a good idea because even systems that don't use package 
  2.1743 +users often have some programs owned by other users or groups, because they 
  2.1744 +need to be setuid or setgid.
  2.1745 +
  2.1746 +
  2.1747 + A.2 Daemons
  2.1748 + -----------
  2.1749 +
  2.1750 +It is a common practice to run daemons under special user accounts rather
  2.1751 +than as root as a security measure. If you feel tempted to use a package 
  2.1752 +user account for this purpose, resist the temptation. It would be a very
  2.1753 +stupid idea. Although they are deliberately less powerful than root, package 
  2.1754 +user accounts are still privileged and need to be considered as equivalent to 
  2.1755 +root as far as security is concerned. Do not do anything with a package user 
  2.1756 +that on a system without package users you would not do with the root account.
  2.1757 +
  2.1758 +
  2.1759 +###########################################################################
  2.1760 + Appendix B: Package Categories
  2.1761 +###########################################################################
  2.1762 +
  2.1763 +Although the user name = group name scheme is recommended by this hint, it is
  2.1764 +not the only possible one. Another scheme that has some appeal is to define
  2.1765 +package categories and to use the group for the purpose of categorizing the
  2.1766 +packages. Following is a suggested set of categories that can serve as a
  2.1767 +guideline for implementing this scheme.
  2.1768 +
  2.1769 +devel: development related stuff, e.g. compilers. This is not restricted to
  2.1770 +       software development. TeX for instance would belong in this group.
  2.1771 +       
  2.1772 +utils: Most software fits into this category, even somewhat essential software 
  2.1773 +       like grep or text editors.
  2.1774 +      
  2.1775 +net: network related stuff such as an ftp daemon or a web browser. This
  2.1776 +     group overlaps with other groups to a large extent. It should be used
  2.1777 +     in preference of the other groups whenever a package is clearly focused
  2.1778 +     towards Internet, LAN, WWW,... A utility like wget for instance would
  2.1779 +     go in net rather than utils. Exceptions from this rule are the groups
  2.1780 +     docs, addons, games and mmedia. If a package fits into one of those 
  2.1781 +     groups, use the respective group instead of net.
  2.1782 +     
  2.1783 +docs: Documentation related packages, such as a tarball with Linux howtos.
  2.1784 +      Note that software to create documentation such as XML processors should
  2.1785 +      probably go in devel and software to view or post-process documentation
  2.1786 +      such as man or groff should probably go in utils.
  2.1787 +      
  2.1788 +system: important system software, such as bash. This group should be used
  2.1789 +        only for really essential packages. Most packages you would put in 
  2.1790 +        this group are better put in "utils". Vi for instance belongs in 
  2.1791 +        utils. 
  2.1792 +        It is unlikely that any package not part of basic LFS belongs in the
  2.1793 +        system group.
  2.1794 +        
  2.1795 +libs: What utils is for executables, libs is for libraries. Libraries that are
  2.1796 +      not strongly related to any of the other categories should go here, such
  2.1797 +      as zlib or libpng.
  2.1798 +      Essential system libraries such as glibc, ncurses or gettext should
  2.1799 +      go in system instead.
  2.1800 +      The libs group is also used for run-time environments such as the
  2.1801 +      Java Virtual Machine, dosemu and wine. Other emulators like MAME for
  2.1802 +      instance should probably go into games instead. 
  2.1803 +     
  2.1804 +games: what do you expect ;-)
  2.1805 +
  2.1806 +mmedia: This is the group for audio and video editors, mp3 players etc.
  2.1807 +
  2.1808 +apps: Applications such as spreadsheets and word processors (not text editors)
  2.1809 +      but also CAD software and graphics software such as Gimp.
  2.1810 +      The apps group is a bit like utils, but apps are usually more user 
  2.1811 +      friendly and more streamlined and feel less nerdish than utils. 
  2.1812 +      
  2.1813 +addons: plugins, filters and similar that are meant to be used in conjunction
  2.1814 +       with another package.
  2.1815 +       
  2.1816 +x: software that relates to the X Window System in general and does not fit
  2.1817 +   into any of the other categories, such as the X server itself or window 
  2.1818 +   managers.
  2.1819 +   Most X software should be put into other more specific groups.
  2.1820 +   A game like xmines would go in games for instance and a text editor for
  2.1821 +   X would go in utils.
  2.1822 +   
  2.1823 +kde: Software that relates to KDE and does not fit into
  2.1824 +     any other category. This group should be used with care. 
  2.1825 +     Do *not* use it for all KDE software. K Office for instance belongs in
  2.1826 +     apps. Konqueror belongs in net.
  2.1827 +     
  2.1828 +gnome: Software that relates to GNOME and does not fit into
  2.1829 +       any other category. This group should be used with care. 
  2.1830 +       Do *not* use it for all GNOME software. Gimp for instance belongs 
  2.1831 +       in apps. A GNOME-aware window manager that works with plain X should
  2.1832 +       go in the x group.
  2.1833 +
  2.1834 +
  2.1835 +###########################################################################
  2.1836 + Appendix C: Acknowledgements and Changelog
  2.1837 +###########################################################################
  2.1838 +
  2.1839 +ACKNOWLEDGEMENTS:
  2.1840 +  * Matthias Benkmann for writing the original version of this hint
  2.1841 +  * Tushar Teredesai for suggesting the user=group scheme.
  2.1842 +  * Markus Laire for reporting the 2005-01-01 build bug
  2.1843 +
  2.1844 +CHANGELOG:
  2.1845 +
  2.1846 +2007-10-20 Matthias Benkmann
  2.1847 +           -relicensed under CC-BY-SA (previously CC-BY-ND).
  2.1848 +           -added name tags to changelog entries in preparation for having the
  2.1849 +            hint continued by different authors.
  2.1850 +           -added workaround to list_package for bug in man-db that causes
  2.1851 +            some manpages to show up as "Weird manpage" in the summary.
  2.1852 +           -chmod wrapper now prevents shadow from installing files setuid 
  2.1853 +            shadow.
  2.1854 +           -added a wrapper to solve ldconfig issue.
  2.1855 +           -install_package now works when called with just a single argument. 
  2.1856 +            That argument is used for user name, group name and description.
  2.1857 +           -bash_profile of more_control_helpers now has /sbin and /usr/sbin 
  2.1858 +            in the PATH to match the PATH used by root when building.
  2.1859 +           -install_package does su - <name> now (i.e. start a login shell).
  2.1860 +           -build script now handles unpacking of tarballs and allows calling 
  2.1861 +            the different stages individually.
  2.1862 +           -useradd uses the -s provided shell and no longer hardwires bash.
  2.1863 +           -chapter 6 bash notes now properly address the configure and 
  2.1864 +            make check issues.
  2.1865 +
  2.1866 +2007-03-21 Matthias Benkmann
  2.1867 +           -changed forall_direntries_from to avoid warning message from find
  2.1868 +            when -depth is used.
  2.1869 +           -added 4.8 What Commands to Run as a Package User  
  2.1870 +
  2.1871 +2005-12-22 Matthias Benkmann
  2.1872 +           -added advice on how to cope with the moving mv problem to
  2.1873 +            coreutils note.
  2.1874 +
  2.1875 +2005-11-13 Matthias Benkmann
  2.1876 +           -fixed list_suspicious_files and list_package to work with
  2.1877 +            recent more POSIX-conforming versions of GNU find
  2.1878 +           -released version 1.2 
  2.1879 +
  2.1880 +2005-01-01 Matthias Benkmann
  2.1881 +            -fixed bug in skel-package/build script that caused it to report
  2.1882 +             all steps as successful, even if they failed 
  2.1883 +            -released version 1.1
  2.1884 +
  2.1885 +2004-11-01 Matthias Benkmann
  2.1886 +            -capitalized title
  2.1887 +            -released version 1.0
  2.1888 +            
  2.1889 +2004-10-14 Matthias Benkmann
  2.1890 +            -started developing the more_control_helpers utilities
  2.1891 +            
  2.1892 +2004-08-14 Matthias Benkmann
  2.1893 +            -started major rewrite (update for new LFS version, new hint 
  2.1894 +             format, textual improvements,...)
  2.1895 +
  2.1896 +2002-04-20 Matthias Benkmann
  2.1897 +            -changed LFS VERSION header to be more conservative
  2.1898 +            -added <br> tags to the synopsis for the sake of the hints 
  2.1899 +             index
  2.1900 +            -added group mmedia to the list of suggested groups 
  2.1901 +            -submitted v0.8
  2.1902 +
  2.1903 +2002-03-16 Matthias Benkmann  
  2.1904 +            -added note, that on Linux make doesn't need to be setgid kmem
  2.1905 +
  2.1906 +2002-02-18 Matthias Benkmann
  2.1907 +            -added section "Security issues with NFS"
  2.1908 +            -submitted v0.7
  2.1909 +
  2.1910 +2002-01-30 Matthias Benkmann
  2.1911 +            -added Changelog
  2.1912 +            -moved "chown 0.10000 `cat /tmp/installdirs`" command up (before
  2.1913 +             glibc package user is created)
  2.1914 +            -add_package_user: create home directory with "mkdir -p"
  2.1915 +                               use $grpfile everywhere instead of /etc/group
  2.1916 +            -improved mammoth sentence in Introduction
  2.1917 +            -added note about possibility to have user name==group name
  2.1918 +            -source bashrc_basic in bashrc_package
  2.1919 +            -minor textual changes
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/previous-work/more_control_helpers/README	Tue Jan 08 11:45:01 2013 +0000
     3.3 @@ -0,0 +1,4 @@
     3.4 +These files are part of the hint
     3.5 +"More control and package management using package users (v1.4)"
     3.6 +You should be able to find it at
     3.7 +http://www.linuxfromscratch.org/hints/downloads/files/more_control_and_pkg_man.txt
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/previous-work/more_control_helpers/bin/forall_direntries_from	Tue Jan 08 11:45:01 2013 +0000
     4.3 @@ -0,0 +1,101 @@
     4.4 +#!/bin/bash
     4.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
     4.6 +# You may do everything with this code except misrepresent its origin.
     4.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
     4.8 +
     4.9 +#The following list should contain the mount points of all filesystems
    4.10 +#that are to be scanned as a space-separated list within parentheses. 
    4.11 +#/ will usually be in this list and if you have /usr
    4.12 +#on a separate partition, it will also be in this list. Other non-special
    4.13 +#filesystems where package users could own files should also be put in this
    4.14 +#list.
    4.15 +#Mount points whose filesystems are special, such as procfs or sysfs must
    4.16 +#not be in this list. While a simple find on those special filesystems should 
    4.17 +#be harmless, operations such as "-exec grep something" are NOT SAFE and may 
    4.18 +#have HARMFUL SIDE-EFFECTS, especially when performed as root. 
    4.19 +fs_to_scan=(/)
    4.20 +
    4.21 +#Files with a path prefix found in the following list are ignored.
    4.22 +#This list will usually contain the parent directory of your package users'
    4.23 +#home directories, because normally you don't want to scan those. You can
    4.24 +#also add other directories that will never contain package user files, such
    4.25 +#as /home. This reduces scan time.
    4.26 +#NOTE: The LFS-6.0 book uses a ramfs mounted on /dev and with that setup
    4.27 +#/dev does not need to be in the prune list. But since there is no requirement
    4.28 +#that /dev have its on filesystem it's better to prune it explicitly.
    4.29 +prune_prefixes=(/home /usr/src /dev /tools) #NO TRAILING SLASHES!!!!
    4.30 +
    4.31 +if [ $# -lt 1 -o "$1" = "--help" ]; then
    4.32 +  echo 1>&2
    4.33 +  echo 1>&2 'USAGE: '"${0##*/}"' <user_or_group_name> [<find-commands>]'
    4.34 +  echo 1>&2
    4.35 +  echo 1>&2 '  If <find-commands> contains no action other than -prune, -print will be'
    4.36 +  echo 1>&2 '    executed for all matching files.'
    4.37 +  echo 1>&2 '  Entries will be matched if group and/or user equals <user_or_group_name>'
    4.38 +  echo 1>&2 '    (numeric UID/GID allowed).'
    4.39 +  echo 1>&2 '  All matching entries will be acted on, including device special files, so'
    4.40 +  echo 1>&2 '    you should be extra careful with the <find-commands> you provide!'
    4.41 +  echo 1>&2
    4.42 +  exit 1
    4.43 +fi
    4.44 +
    4.45 +#suppress ugly debug output from shell
    4.46 +trap ':' SIGPIPE
    4.47 +
    4.48 +ugname="$1"
    4.49 +shift 1  #remove user_or_group_name from argument list
    4.50 +
    4.51 +# Recent versions of find issue a warning if "-depth" is listed after a
    4.52 +# non-option argument. To prevent this warning if -depth is passed to
    4.53 +# this script, we pick up the "-depth" argument here to move it to the
    4.54 +# front later on.
    4.55 +depth=""
    4.56 +if [ "_$1" = "_-depth" ]; then
    4.57 +  depth=-depth
    4.58 +  shift 1
    4.59 +fi
    4.60 +
    4.61 +ugmatcher=(-false)
    4.62 +#test if find accepts ugname as a user, and append to ugmatcher if it does
    4.63 +if find / -maxdepth 0 -user "$ugname" >/dev/null 2>&1 ; then
    4.64 +  ugmatcher[${#ugmatcher[@]}]="-or"
    4.65 +  ugmatcher[${#ugmatcher[@]}]="-user"
    4.66 +  ugmatcher[${#ugmatcher[@]}]="$ugname"
    4.67 +fi
    4.68 +#test if find accepts ugname as a group, and append to ugmatcher if it does
    4.69 +if find / -maxdepth 0 -group "$ugname" >/dev/null 2>&1 ; then
    4.70 +  ugmatcher[${#ugmatcher[@]}]="-or"
    4.71 +  ugmatcher[${#ugmatcher[@]}]="-group"
    4.72 +  ugmatcher[${#ugmatcher[@]}]="$ugname"
    4.73 +fi
    4.74 +
    4.75 +#if find accepted ugname as neither user nor group, then exit
    4.76 +if [ "${#ugmatcher[@]}" = 1 ]; then
    4.77 +  echo 1>&2 'find does not accept `'"$ugname'"' as group or user name'
    4.78 +  exit 1
    4.79 +fi
    4.80 +
    4.81 +#construct find commands that match the prune_prefixes. Each prefix will be
    4.82 +#matched as -path <prefix> -or -path <prefix>/*
    4.83 +#so that the directory itself and all subdirectories are matched.
    4.84 +y=(\( -false)
    4.85 +for ((i=0; $i<${#prune_prefixes[@]}; i=$i+1)) 
    4.86 +do
    4.87 +  y[${#y[@]}]='-or'
    4.88 +  y[${#y[@]}]=-path
    4.89 +  y[${#y[@]}]="${prune_prefixes[$i]}"
    4.90 +  y[${#y[@]}]='-or'
    4.91 +  y[${#y[@]}]=-path
    4.92 +  y[${#y[@]}]="${prune_prefixes[$i]}/*"
    4.93 +done
    4.94 +y[${#y[@]}]=')'
    4.95 +
    4.96 +#In the following find command, the part
    4.97 +# -not ( ( "${y[@]}" -prune ) -or "${y[@]}" )
    4.98 +#is responsible for preventing the files that match prune_prefixes from
    4.99 +#being processed. The 2nd "${y[@]}" may seem redundant, but it isn't, because
   4.100 +#-prune has no effect and is always false when -depth is used.
   4.101 +#The -true before "$@" ensures that -depth can be passed as only parameter.
   4.102 +find "${fs_to_scan[@]}" $depth -xdev -noleaf \
   4.103 +     -not \( \( "${y[@]}" -prune \) -or "${y[@]}" \) \
   4.104 +     -and \( "${ugmatcher[@]}" \) -and \( -true "$@" \)
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/previous-work/more_control_helpers/bin/grep_all_regular_files_for	Tue Jan 08 11:45:01 2013 +0000
     5.3 @@ -0,0 +1,74 @@
     5.4 +#!/bin/bash
     5.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
     5.6 +# You may do everything with this code except misrepresent its origin.
     5.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
     5.8 +
     5.9 +#The following list should contain the mount points of all filesystems
    5.10 +#that are to be scanned as a space-separated list within parentheses. 
    5.11 +#/ will usually be in this list and if you have /usr
    5.12 +#on a separate partition, it will also be in this list. 
    5.13 +#Mount points whose filesystems are special, such as procfs or sysfs must
    5.14 +#not be in this list. While a simple find on those special filesystems should 
    5.15 +#be harmless, operations such as "-exec grep something" are NOT SAFE and may 
    5.16 +#have HARMFUL SIDE-EFFECTS, especially when performed as root. 
    5.17 +fs_to_scan=(/)
    5.18 +
    5.19 +#Files with a path prefix found in the following list are ignored. As the
    5.20 +#main function of this script is to help you find files that contain
    5.21 +#hardwired paths to /tools or other unwanted references to
    5.22 +#your build system, you will usually prune any directories that don't contain
    5.23 +#files of interest, such as /tools (whose files naturally refer to /tools)
    5.24 +#and your package users' home directories (which may also test positive if
    5.25 +#you have unpacked and configured sources lying around).
    5.26 +#NOTE: The LFS-6.0 book uses a ramfs mounted on /dev and with that setup
    5.27 +#/dev does not need to be in the prune list. But since there is no requirement
    5.28 +#that /dev have its on filesystem it's better to prune it explicitly.
    5.29 +prune_prefixes=(/home /usr/src /dev /tools) #NO TRAILING SLASHES!!!
    5.30 +
    5.31 +if [ $# -lt 1 -o "$1" = "--help" ]; then
    5.32 +  echo 1>&2 
    5.33 +  echo 1>&2 'USAGE: '"${0##*/}"' <grep-commands>'
    5.34 +  echo 1>&2 
    5.35 +  echo 1>&2 '  grep -l <grep-commands> -- <file>'
    5.36 +  echo 1>&2 '  will be executed for each *regular file* <file>'
    5.37 +  echo 1>&2 '  ATTENTION! If you override the -l switch with a switch that makes grep'
    5.38 +  echo 1>&2 '  output all individual matches rather than just the matching files,'
    5.39 +  echo 1>&2 '  then DO NOT redirect output to a file that is in a directory that will be'
    5.40 +  echo 1>&2 '  scanned, or you risk creating an endless loop that will cause your'
    5.41 +  echo 1>&2 '  output file to grow till your disk is full.'
    5.42 +  echo 1>&2 
    5.43 +  exit 1
    5.44 +fi
    5.45 +
    5.46 +#suppress ugly debug output from shell
    5.47 +trap ':' SIGPIPE
    5.48 +
    5.49 +#construct find commands that match the prune_prefixes. Each prefix will be
    5.50 +#matched as -path <prefix> -or -path <prefix>/*
    5.51 +#so that the directory itself and all subdirectories are matched.
    5.52 +y=(\( -false)
    5.53 +for ((i=0; $i<${#prune_prefixes[@]}; i=$i+1)) 
    5.54 +do
    5.55 +  y[${#y[@]}]='-or'
    5.56 +  y[${#y[@]}]=-path
    5.57 +  y[${#y[@]}]="${prune_prefixes[$i]}"
    5.58 +  y[${#y[@]}]='-or'
    5.59 +  y[${#y[@]}]=-path
    5.60 +  y[${#y[@]}]="${prune_prefixes[$i]}/*"
    5.61 +done
    5.62 +y[${#y[@]}]=')'
    5.63 +
    5.64 +cmd_pre=(-type f -exec grep -l)
    5.65 +cmd_post=(-- {} \;)
    5.66 +
    5.67 +#In the following find command, the part
    5.68 +# -not ( ( "${y[@]}" -prune ) -or "${y[@]}" )
    5.69 +#is responsible for preventing the files that match prune_prefixes from
    5.70 +#being processed. The 2nd "${y[@]}" may seem redundant, but it isn't, because
    5.71 +#-prune has no effect and is always false when -depth is used (which someone
    5.72 +#might do in the future).
    5.73 +#The -true before "$@" ensures that -depth can be passed as 1st parameter
    5.74 +#of $cmd_pre (should someone change it in the future).
    5.75 +find "${fs_to_scan[@]}" -xdev -noleaf \
    5.76 +     -not \( \( "${y[@]}" -prune \) -or "${y[@]}" \) \
    5.77 +     -and \( -true "${cmd_pre[@]}" "$@" "${cmd_post[@]}" \)
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/previous-work/more_control_helpers/bin/list_package	Tue Jan 08 11:45:01 2013 +0000
     6.3 @@ -0,0 +1,291 @@
     6.4 +#!/bin/bash
     6.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
     6.6 +# You may do everything with this code except misrepresent its origin.
     6.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
     6.8 +
     6.9 +if [ $# -lt 1 -o \( $# -gt 1 -a "z$1" != "z:man" -a "z$1" != "z:mani" -a "z$1" != "z:lib" \) -o "$1" = "--help" ]; then
    6.10 +  echo 1>&2
    6.11 +  echo 1>&2 'USAGE: '"${0##*/}"' <user_or_group_name>'
    6.12 +  echo 1>&2
    6.13 +  echo 1>&2 '  Entries will be matched if group and/or user equals <user_or_group_name>'
    6.14 +  echo 1>&2 '    (numeric UID/GID allowed).'
    6.15 +  echo 1>&2 '  This script uses `forall_direntries_from'"'"' and `list_suspicious_files_from'"'."
    6.16 +  echo 1>&2
    6.17 +  echo 1>&2 '  NOTE: Several minutes may pass before you see the first output.'
    6.18 +  echo 1>&2 '  You should probably redirect output to a file for later reference.'
    6.19 +  echo 1>&2
    6.20 +  echo 1>&2 '  WARNING! This program is for listing files from package users only!'
    6.21 +  echo 1>&2 '           Do NOT use it to list files from untrusted users!'
    6.22 +  echo 1>&2 '           An untrusted user could set up a manipulated manpage to exploit'
    6.23 +  echo 1>&2 '           a bug in man when it is used to extract the summary!'
    6.24 +  exit 1
    6.25 +fi
    6.26 +
    6.27 +# KNOWN BUGS:
    6.28 +#  - when extracting summaries from manpages, candidate manpages are considered
    6.29 +#    in alphabetic order rather than the order used by the man command.
    6.30 +#    The problem with this is that section 8, which contains manpages for
    6.31 +#    admin commands, will be considered after lower-numbered sections.
    6.32 +#    In the rare case that an admin command has the same name as a topic from
    6.33 +#    a lower-numbered manpage installed by the same package, the summary will
    6.34 +#    be taken from the wrong manpage.
    6.35 +#    An example for such a clash are the faillog.5 and faillog.8 manpages from
    6.36 +#    the shadow package.
    6.37 +#    Because this problem is difficult to fix, rare and easily spotted (since
    6.38 +#    the manpage that should have provided the summary will be listed under
    6.39 +#    EXTRA MANPAGES) I won't fix it.
    6.40 +
    6.41 +ugname="$1"
    6.42 +
    6.43 +#suppress ugly debug output from shell
    6.44 +trap ':' SIGPIPE
    6.45 +
    6.46 +if [ $# -gt 1 ]; then
    6.47 +  name="${2##*/}"
    6.48 +  case "$1" in
    6.49 +    :man) 
    6.50 +      name=${name%.gz}
    6.51 +      name=${name%.bz2}
    6.52 +      name=${name%.*}
    6.53 +      echo $'command\2'"$name"$'\2man\2'"$2" ;;
    6.54 +    :mani) 
    6.55 +      name=${name%.gz}
    6.56 +      name=${name%.bz2}
    6.57 +      name=${name%.*}
    6.58 +      echo $'command\2'"$name"$'\2mani\2'"$2" ;;
    6.59 +    :lib) 
    6.60 +      name=${name%.a}
    6.61 +      name=${name%%.so*}
    6.62 +      echo "lib $name" 
    6.63 +      ;;
    6.64 +  esac
    6.65 +  exit 0
    6.66 +fi
    6.67 +
    6.68 +sanitize() { tr -c '[:print:]' '?' ; }
    6.69 +
    6.70 +# $1: <commandname>
    6.71 +# $2: command\2<commandname>\2cmd\2(-><linktarget>)
    6.72 +# $3: command\2<commandname>\2man[i]\2<manpage_path>  or  <empty>
    6.73 +expand_command()
    6.74 +{
    6.75 +  sep=$'\2'
    6.76 +  cmdname="$1"
    6.77 +  cmdline="$2"
    6.78 +  manline="$3"
    6.79 +  linktarget="${cmdline##*${sep}}"
    6.80 +  
    6.81 +  if [ -z "$manline" ]; then
    6.82 +    description='No manpage'
    6.83 +    #the "l" at the beginning is just to make it sort after "lib"
    6.84 +    echo -n "lmanlessbin $cmdname" | sanitize
    6.85 +    echo 
    6.86 +    
    6.87 +  else # if [ ! -z "$manline" ]; then
    6.88 +    manpage=${manline##*${sep}}
    6.89 +    manpagedir=${manpage%/*}
    6.90 +    wsc='[[:space:],]\+'
    6.91 +    # The cd $manpagedir is a workaround for a bug in man-db that causes it
    6.92 +    # to attempt to resolve paths relative to cwd.
    6.93 +    # The `t l;d;:l;n;b l' in the sed command is voodoo magic to make sed
    6.94 +    # output only the first match but to keep eating up all input. I use this
    6.95 +    # instead of  `| head -n 1', because head breaks the pipe after doing
    6.96 +    # its 1 line output, which (if it happens before sed has processed the
    6.97 +    # complete input) freaks out man and causes it to emit a totally
    6.98 +    # silly error message including "No such file or directory", which is
    6.99 +    # annoying when you do testing without suppressing man's errors.
   6.100 +    # The $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' removes the backspace-based 
   6.101 +    # as well as ESC-based formatting from man's output. 
   6.102 +    description="$( { cd "$manpagedir/.." 2>/dev/null ;
   6.103 +                      COLUMNS=300 man "$manpage" 2>/dev/null || 
   6.104 +                                      echo " $name - Broken manpage" ; } | 
   6.105 +       sed $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' |
   6.106 +       sed -n "/^NAME/,/^[A-Z]/s/^.*${wsc}${cmdname}${wsc}.*-\+${wsc}\(.*\)/\1/p;t l;d;:l;n;b l" )"
   6.107 +    if [ -z "$description" ]; then
   6.108 +      description="$( cd "$manpagedir/.." 2>/dev/null ;
   6.109 +                      COLUMNS=300 man "$manpage" 2>/dev/null |
   6.110 +        sed $'s/.\b\\(.\\)/\\1/g;s/\x1b[^m]\\+m//g' |
   6.111 +        sed -n "s/^.*${wsc}..*${wsc}.*-\+${wsc}\(.*\)/\1/p;t l;d;:l;n;b l" )"
   6.112 +    fi
   6.113 +    test -z "$description" && description="Weird manpage"
   6.114 +  fi
   6.115 +
   6.116 +  echo -n "binexe $cmdname" | sanitize
   6.117 +  test "$linktarget" != '(->)' && echo -n "$linktarget" | sanitize
   6.118 +  echo 
   6.119 +  #the "lx" in "lxdescription" is just to make sure it sorts after "lmanlessbin"
   6.120 +  echo -n "lxdescription $cmdname: $description" | sanitize  
   6.121 +  echo 
   6.122 +}
   6.123 +
   6.124 +# NOTE: The -path and -lname stuff at the beginning of the following is
   6.125 +# there to make sure that none of the lines output by find contains
   6.126 +# a) \n or \r, because that would mess up post-processing the output 
   6.127 +#    line-by-line.
   6.128 +# b) \x7f, because this character triggers one of the nastier bash-bugs
   6.129 +#    wrt string handling
   6.130 +# c) \2, because I use this as separator within the lines
   6.131 +#    (Why \2 and not \0 or \1 ? Because bash can't cope with \0 at all and has
   6.132 +#    bugs related to \1.)
   6.133 +#
   6.134 +# Because of this, having the final section called "ALL FILES" is technically
   6.135 +# a lie, because files with a path containing one of the abovementioned
   6.136 +# characters will not appear in output.
   6.137 +# However, a) no sane package contains such files
   6.138 +#          b) they will be listed in the output from list_suspicious_files
   6.139 +cmd=(\( -path $'*\n*' -or -path $'*\r*' -or -path $'*\x7f*' 
   6.140 +        -or -path $'*\2*'
   6.141 +        -or -lname $'*\n*' -or -lname $'*\r*' -or -lname $'*\x7f*' 
   6.142 +        -or -lname $'*\2*' 
   6.143 +     \) 
   6.144 +     -or
   6.145 +     \(
   6.146 +       \( -printf "zall %p\n" \) ,
   6.147 +       \(
   6.148 +         \( -type f -or -xtype f \) -and
   6.149 +         \(
   6.150 +           \( -perm -u+x \( -path "*/bin/*" -or -path "*/sbin/*" \) -printf 'command\2%f\2cmd\2(->%l)\n' \)
   6.151 +       -or \( -path "*/man/man*/*" -exec "$0" ":man" {} \; \)
   6.152 +       -or \( -path "*/man/*/man*/*" -exec "$0" ":mani" {} \; \)
   6.153 +       -or \( \( -name "lib*.so" -or -name "lib*.a" -or -name "lib*.so.*" \) -path "*/lib/*" -exec "$0" ":lib" {} \; \)
   6.154 +       -or \( -type f -perm -u+x -not \( \( -name "lib*.so" -or -name "lib*.a" -or -name "lib*.so.*" \) -path "*/lib/*" \)  -printf "nobinexe %p\n" \)
   6.155 +         \)
   6.156 +       \)  
   6.157 +     \)
   6.158 +    )
   6.159 +
   6.160 +forall_direntries_from "$ugname" "${cmd[@]}" | sort -u |
   6.161 +{
   6.162 +  sep=$'\2'
   6.163 +  hold=''
   6.164 +  for((;;)) 
   6.165 +  do
   6.166 +    if [ -z "$hold" ]; then
   6.167 +      read -r line || break
   6.168 +    else
   6.169 +      line="$hold"
   6.170 +      hold=''
   6.171 +    fi
   6.172 +    
   6.173 +    case "z$line" in
   6.174 +      zcommand${sep}*${sep}cmd${sep}*) 
   6.175 +        cmdname=${line#command${sep}}
   6.176 +        cmdname=${cmdname%%${sep}*}
   6.177 +        read -r hold
   6.178 +        case "z$hold" in
   6.179 +          zcommand${sep}${cmdname}${sep}man${sep}*|zcommand${sep}${cmdname}${sep}mani${sep}*) 
   6.180 +            expand_command "$cmdname" "$line" "$hold"
   6.181 +            hold=''
   6.182 +          ;;
   6.183 +          
   6.184 +          z*) 
   6.185 +            expand_command "$cmdname" "$line" ""
   6.186 +          ;;
   6.187 +        esac
   6.188 +        ;;
   6.189 +
   6.190 +      zcommand${sep}*${sep}man${sep}*|command${sep}*${sep}mani${sep}*) 
   6.191 +         
   6.192 +        echo -n "manextra ${line##*${sep}}" | sanitize
   6.193 +        echo
   6.194 +        ;;
   6.195 +
   6.196 +      z*) 
   6.197 +        echo -n "$line" | sanitize
   6.198 +        echo
   6.199 +        ;;
   6.200 +    esac
   6.201 +    
   6.202 +  done
   6.203 +} | sort |  #no -u here, bc. the above processing may equalize different files
   6.204 +{
   6.205 +# (1) binexe: Executables (in *bin/)
   6.206 +# (2) lib: Libraries (in *lib/*)
   6.207 +# (3) lmanlessbin: Executables (in *bin/) without manpages
   6.208 +# (4) lxdescription: Summaries for executables (in *bin/)
   6.209 +# (5) manextra: Extra manpages
   6.210 +#     full paths, no perms
   6.211 +# (6) nobinexe: Executables not in *bin/ (excluding *lib/*.so and *lib/*.so.*)
   6.212 +#     full paths, no perms
   6.213 +# (7) zall: All files
   6.214 +#     full paths, no perms
   6.215 +
   6.216 +  curstate=''
   6.217 +  while read -r line
   6.218 +  do
   6.219 +    newstate="${line%% *}"
   6.220 +    if [ "$newstate" != "$curstate" ]; then
   6.221 +      curstate="$newstate"
   6.222 +      case "$curstate" in
   6.223 +        binexe)
   6.224 +          echo 'EXECUTABLES (in */bin or */sbin)'
   6.225 +          echo -n "  ${line#binexe }"
   6.226 +          ;;
   6.227 +        lib)
   6.228 +          echo
   6.229 +          echo
   6.230 +          echo 'LIBRARIES (lib*.a or lib*.so)'
   6.231 +          echo -n "  ${line#lib }"
   6.232 +          ;;
   6.233 +        lmanlessbin)
   6.234 +          echo
   6.235 +          echo
   6.236 +          echo 'EXECUTABLES WITH NO MANPAGE (in */bin or */sbin)'
   6.237 +          echo -n "  ${line#lmanlessbin }"
   6.238 +          ;;
   6.239 +        lxdescription)
   6.240 +          echo
   6.241 +          echo
   6.242 +          echo 'MANPAGE SUMMARIES OF EXECUTABLES (in */bin or */sbin)'
   6.243 +          echo "  ${line#lxdescription }"
   6.244 +          ;;
   6.245 +        manextra)
   6.246 +          echo
   6.247 +          echo 'EXTRA MANPAGES'
   6.248 +          echo "  ${line#manextra }"
   6.249 +          ;;
   6.250 +        nobinexe)
   6.251 +          echo
   6.252 +          echo 'EXTRA EXECUTABLES (not in */bin or */sbin)'
   6.253 +          echo "  ${line#nobinexe }"
   6.254 +          ;;
   6.255 +        zall)
   6.256 +          echo
   6.257 +          echo 'ALL FILES'
   6.258 +          echo "  ${line#zall }"
   6.259 +          ;;
   6.260 +        *) 
   6.261 +          echo
   6.262 +          echo
   6.263 +          echo 'UNEXPECTED LINE'
   6.264 +          echo "  $line"
   6.265 +          ;;
   6.266 +        
   6.267 +      esac
   6.268 +    else
   6.269 +      case "$curstate" in
   6.270 +        binexe) echo -n ", ${line#binexe }" 
   6.271 +          ;;
   6.272 +        lib) echo -n ", ${line#lib }" 
   6.273 +          ;;
   6.274 +        lmanlessbin) echo -n ", ${line#lmanlessbin }" 
   6.275 +          ;;
   6.276 +        lxdescription) echo "  ${line#lxdescription }" 
   6.277 +          ;;
   6.278 +        manextra) echo "  ${line#manextra }" 
   6.279 +          ;;
   6.280 +        nobinexe) echo "  ${line#nobinexe }" 
   6.281 +          ;;
   6.282 +        zall) echo "  ${line#zall }" 
   6.283 +          ;;
   6.284 +        *) 
   6.285 +          echo
   6.286 +          echo 'UNEXPECTED LINE'
   6.287 +          echo "  $line"
   6.288 +          ;;
   6.289 +      esac
   6.290 +    fi
   6.291 +  done
   6.292 +} 
   6.293 +
   6.294 +list_suspicious_files_from "$ugname"
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/previous-work/more_control_helpers/bin/list_suspicious_files	Tue Jan 08 11:45:01 2013 +0000
     7.3 @@ -0,0 +1,218 @@
     7.4 +#!/bin/bash
     7.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
     7.6 +# You may do everything with this code except misrepresent its origin.
     7.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
     7.8 +
     7.9 +#The following list should contain the mount points of all filesystems
    7.10 +#that are to be scanned as a space-separated list within parentheses. 
    7.11 +#/ will usually be in this list and if you have /usr
    7.12 +#on a separate partition, it will also be in this list. Other non-special
    7.13 +#filesystems where suspicious files could be located should also be put in 
    7.14 +#this list.
    7.15 +#Mount points whose filesystems are special, such as procfs or sysfs should
    7.16 +#not be in this list. 
    7.17 +fs_to_scan=(/)
    7.18 +
    7.19 +#Files with a path prefix found in the following list are ignored.
    7.20 +#DO !!!!NOT!!! PUT /usr/src OR WHATEVER THE HOME DIRECTORY prefix is for your
    7.21 +#package users into this list!!! You DO want to scan those directories in
    7.22 +#order to spot e.g. world-writable tarballs and other abominations that
    7.23 +#may have crept in.
    7.24 +#Ideally, this list should be empty.
    7.25 +prune_prefixes=() #NO TRAILING SLASHES!!!
    7.26 +
    7.27 +#If the following variable is set to "yes", then files that contain
    7.28 +#control characters or other non-printable characters (except for space)
    7.29 +#will be reported as suspicious. 
    7.30 +#This test slows down the search considerably!
    7.31 +enable_illchars=yes
    7.32 +
    7.33 +
    7.34 +#suppress ugly debug output from shell
    7.35 +trap ':' SIGPIPE
    7.36 +
    7.37 +#"-false" as 1st argument is used when called by list_suspicious_files_from
    7.38 +if [ $# -ge 1 -a "$1" != "-false" ]; then
    7.39 +  echo 1>&2 
    7.40 +  echo 1>&2 "USAGE: ${0##*/}"
    7.41 +  echo 1>&2 
    7.42 +  echo 1>&2 '  Outputs a categorized list of files and directories with properties'
    7.43 +  echo 1>&2 '  that could mean trouble and should be investigated.'
    7.44 +  echo 1>&2
    7.45 +  exit 1
    7.46 +fi
    7.47 +
    7.48 +
    7.49 +usergroupmatch=(-true)
    7.50 +if [ "$1" = "-false" ]; then
    7.51 +  usergroupmatch=(\( "$@" \))
    7.52 +fi
    7.53 +
    7.54 +#construct find commands that match the prune_prefixes. Each prefix will be
    7.55 +#matched as -path <prefix> -or -path <prefix>/*
    7.56 +#so that the directory itself and all subdirectories are matched.
    7.57 +y=(\( -false)
    7.58 +for ((i=0; $i<${#prune_prefixes[@]}; i=$i+1)) 
    7.59 +do
    7.60 +  y[${#y[@]}]='-or'
    7.61 +  y[${#y[@]}]=-path
    7.62 +  y[${#y[@]}]="${prune_prefixes[$i]}"
    7.63 +  y[${#y[@]}]='-or'
    7.64 +  y[${#y[@]}]=-path
    7.65 +  y[${#y[@]}]="${prune_prefixes[$i]}/*"
    7.66 +done
    7.67 +y[${#y[@]}]=')'
    7.68 +
    7.69 +illchars=( $'\x1'  $'\x2'  $'\x3'  $'\x4'  $'\x5'  $'\x6'  $'\x7'  $'\x8'  
    7.70 +  $'\x9'  $'\xA'  $'\xB'  $'\xC'  $'\xD'  $'\xE'  $'\xF'  $'\x10'  $'\x11' 
    7.71 +  $'\x12'  $'\x13'  $'\x14'  $'\x15'  $'\x16'  $'\x17'  $'\x18'  $'\x19'  
    7.72 +  $'\x1A'  $'\x1B'  $'\x1C'  $'\x1D'  $'\x1E'  $'\x1F'  $'\x7f' $'\x80' 
    7.73 +  $'\x81'  $'\x82'  $'\x83'  $'\x84'  $'\x85'  $'\x86'  $'\x87'  $'\x88'  
    7.74 +  $'\x89'  $'\x8A'  $'\x8B'  $'\x8C'  $'\x8D'  $'\x8E'  $'\x8F'  $'\x90'  
    7.75 +  $'\x91'  $'\x92'  $'\x93'  $'\x94'  $'\x95'  $'\x96'  $'\x97'  $'\x98'  
    7.76 +  $'\x99'  $'\x9A'  $'\x9B'  $'\x9C'  $'\x9D'  $'\x9E'  $'\x9F' ) 
    7.77 +
    7.78 +
    7.79 +if [ "$enable_illchars" = yes ]; then
    7.80 +
    7.81 +  illname=(\( -false)
    7.82 +  for ((i=0; $i<${#illchars[@]}; i=$i+1)) 
    7.83 +  do
    7.84 +    #handle bash \x7f error
    7.85 +    if [ "*${illchars[$i]}*" = "**" ]; then
    7.86 +      illchars[$i]=$'\x80'  #'
    7.87 +    fi
    7.88 +    illname[${#illname[@]}]='-or'
    7.89 +    illname[${#illname[@]}]=-name
    7.90 +    illname[${#illname[@]}]="*${illchars[$i]}*"
    7.91 +  done
    7.92 +  illname[${#illname[@]}]=')'
    7.93 +
    7.94 +  illlink=(\( -false)
    7.95 +  for ((i=0; $i<${#illchars[@]}; i=$i+1)) 
    7.96 +  do
    7.97 +    illlink[${#illlink[@]}]='-or'
    7.98 +    illlink[${#illlink[@]}]=-lname
    7.99 +    illlink[${#illlink[@]}]="*${illchars[$i]}*"
   7.100 +  done
   7.101 +  illlink[${#illlink[@]}]=')'
   7.102 +else #if [ "$enable_illchars" = no ]
   7.103 +  illlink=(-false)
   7.104 +  illname=(-false)
   7.105 +fi
   7.106 +
   7.107 +# $1=section heading
   7.108 +# $2=inode message
   7.109 +report()
   7.110 +{
   7.111 +  echo -printf "increment_code_here"
   7.112 +  echo -printf 
   7.113 +  echo "1 ${1}\\n" | sed 's/ /\\040/g'
   7.114 +  echo -printf "insert_code_here"
   7.115 +  
   7.116 +  if [ -n "$2" ]; then
   7.117 +    echo -printf 
   7.118 +    echo "2 %i 1 ${2}\\n" | sed 's/ /\\040/g'
   7.119 +    echo -printf "insert_code_here"
   7.120 +    echo -printf 
   7.121 +    echo "2 %i 2 " | sed 's/ /\\040/g'
   7.122 +  else
   7.123 +    echo -printf "2\\040" 
   7.124 +  fi
   7.125 +  
   7.126 +  echo -exec ls -T 0 -ladQ {} \;
   7.127 +}
   7.128 +
   7.129 +
   7.130 +filegoodperm=(\( -perm 644 -or -perm 755 -or -perm 555 -or -perm 444 -or -perm 600 -or -perm 700 -or -perm 640 \))
   7.131 +dirgoodperm=(\( -perm 755 -or -perm 555 -or -perm 700 -or -perm 750 \))
   7.132 +
   7.133 +good=( \( 
   7.134 +          -not \( -not -type d -links +1 \)
   7.135 +          -not -nouser -not -nogroup 
   7.136 +          -not \( "${illname[@]}" \) 
   7.137 +          -not \( "${illlink[@]}" \) 
   7.138 +       \) 
   7.139 +       -and
   7.140 +\(
   7.141 +      \( -type f -not -group install "${filegoodperm[@]}" \) 
   7.142 +  -or \( -type d -not -group install "${dirgoodperm[@]}" \)
   7.143 +  -or \( -type d -group install \( -perm 1775 \) \)
   7.144 +  -or \( -type d -group root -user root -path "/tmp" \( -perm 1777 \) \)
   7.145 +  -or \( -type d -group root -user root -path "/var/tmp" \( -perm 1777 \) \)
   7.146 +  -or \( -not -type d -not -type f -not -type l -path "/dev/*" \)
   7.147 +  -or \( -type l \( -xtype b -or -xtype c -or -xtype d -or -xtype p -or -xtype f \) \)
   7.148 +\)
   7.149 +)
   7.150 +
   7.151 +bad=(
   7.152 +    \( "${illname[@]}" $(report  "NON-PRINTABLE CHAR IN NAME")  \)
   7.153 + OP \( "${illlink[@]}" $(report  "NON-PRINTABLE-CHAR IN LINK-TARGET")  \)
   7.154 + OP \( -type f -perm -4000 $(report  "SETUID FILES")  \)
   7.155 + OP \( -type f -perm -2000 $(report  "SETGID FILES")  \)
   7.156 + OP \( -type f -perm -1000 $(report  "STICKY FILES")  \)
   7.157 + OP \( -type d -perm -2000 $(report  "GROUP-KEEPING DIRECTORIES")  \)
   7.158 + OP \( -type d -not -group install -perm -1000  $(report  "STICKY DIRECTORIES")  \)
   7.159 + OP \( -type f -perm -g+w  $(report  "GROUP-WRITABLE FILES")  \)
   7.160 + OP \( -type f -perm -o+w  $(report  "WORLD-WRITABLE FILES")  \)
   7.161 + OP \( -type d -perm -g+w  $(report  "GROUP-WRITABLE DIRECTORIES")  \)
   7.162 + OP \( -type d -perm -o+w  $(report  "WORLD-WRITABLE DIRECTORIES")  \)
   7.163 + OP \( -not \( -type f -or -type l -or -type d \) -not -path "/dev/*"  $(report  "SPECIAL FILES OUTSIDE /dev")  \)
   7.164 + OP \( -type d -group install -not -perm 1755  $(report  "INSTALL DIRECTORIES WITH UNUSUAL PERMISSIONS")  \)
   7.165 + OP \( -type f -group install $(report  "FILES ASSIGNED TO GROUP INSTALL")  \)
   7.166 + OP \( -type l -not \( -xtype b -or -xtype c -or -xtype d -or -xtype p -or -xtype f \) $(report  "SYMLINKS POSSIBLY BROKEN OR LOOP")  \)
   7.167 + OP \( -not -type d -links +1 $(report "HARDLINKED FILES" "Inode %i is shared by %n files, including") \)
   7.168 + OP \( -nouser  $(report  "THINGS HAVING UID WITH NO ASSIGNED USER NAME")  \)
   7.169 + OP \( -nogroup  $(report  "THINGS HAVING GID WITH NO ASSIGNED GROUP NAME")  \)
   7.170 + OP \( -type f -not -group install -not "${filegoodperm[@]}"  $(report  "FILES WITH UNUSUAL PERMISSIONS")  \)
   7.171 + OP \( -type d -not -group install -not "${dirgoodperm[@]}"  $(report  "DIRECTORIES WITH UNUSUAL PERMISSIONS")  \)
   7.172 +)
   7.173 +
   7.174 +#insert unique codes for the messages
   7.175 +code=100
   7.176 +for ((i=0; $i<${#bad[@]}; i=$i+1)) 
   7.177 +do
   7.178 +  if [ "${bad[$i]}" = "increment_code_here" ]; then
   7.179 +    code=$(($code + 1))
   7.180 +    bad[$i]=$code
   7.181 +  elif [ "${bad[$i]}" = "insert_code_here" ]; then
   7.182 +    bad[$i]=$code
   7.183 +  fi
   7.184 +done
   7.185 +
   7.186 +allbad=()  #all bad matches are reported
   7.187 +onebad=()  #only the first bad match is reported
   7.188 +for ((i=0; $i<${#bad[@]}; i=$i+1)) 
   7.189 +do
   7.190 +  if [ "${bad[$i]}" = "OP" ]; then
   7.191 +    allbad[$i]=","
   7.192 +    onebad[$i]="-or"
   7.193 +  else
   7.194 +    allbad[$i]="${bad[$i]}"
   7.195 +    onebad[$i]="${bad[$i]}"
   7.196 +  fi
   7.197 +done
   7.198 +
   7.199 +#Add a default case to onebad.
   7.200 +#This should never be hit, because the explicit cases should catch all
   7.201 +#files, but just in case I've missed something, this will catch it.
   7.202 +onebad=("${onebad[@]}" -or  $(report  "WEIRD SHIT") )
   7.203 +
   7.204 +#make allbad always return false
   7.205 +allbad=("${allbad[@]}" , -false)
   7.206 +
   7.207 +cmd=( "${usergroupmatch[@]}" -and
   7.208 +     \( \( "${good[@]}" \) -or \( "${allbad[@]}" \) -or \( "${onebad[@]}" \) \)
   7.209 +    )
   7.210 +
   7.211 +#In the following find command, the part
   7.212 +# -not ( ( "${y[@]}" -prune ) -or "${y[@]}" )
   7.213 +#is responsible for preventing the files that match prune_prefixes from
   7.214 +#being processed. The 2nd "${y[@]}" may seem redundant, but it isn't, because
   7.215 +#-prune has no effect and is always false when -depth is used.
   7.216 +find "${fs_to_scan[@]}" -xdev -noleaf \
   7.217 +     -not \( \( "${y[@]}" -prune \) -or "${y[@]}" \) \
   7.218 +     -and \( "${cmd[@]}" \) | 
   7.219 +sed 's/^\(...2\) \([0-9]\+ 2 \)\?\([^ ]\+\) \+[^ ]\+ \+\([^ ]\+\) \+\([^ ]\+\) \+[^"]\+\(".\+\)/\1 \2\3 \6  \4:\5/' |
   7.220 +sort -u | 
   7.221 +sed 's/^...1 /\'$'\n''/;s/^...2 [0-9]\+ 1 /\'$'\n''  /;s/^...2 [0-9]\+ 2 /    /;s/^...2 /  /'
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/previous-work/more_control_helpers/bin/list_suspicious_files_from	Tue Jan 08 11:45:01 2013 +0000
     8.3 @@ -0,0 +1,41 @@
     8.4 +#!/bin/bash
     8.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
     8.6 +# You may do everything with this code except misrepresent its origin.
     8.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
     8.8 +
     8.9 +if [ $# != 1 -o "$1" = "--help" ]; then
    8.10 +  echo 1>&2
    8.11 +  echo 1>&2 'USAGE: '"${0##*/}"' <user_or_group>'
    8.12 +  echo 1>&2
    8.13 +  echo 1>&2 '  Outputs a categorized list of files and directories with properties'
    8.14 +  echo 1>&2 '  that could mean trouble and should be investigated.'
    8.15 +  echo 1>&2 '  Suspicious objects will be reported only if group and/or user equals'
    8.16 +  echo 1>&2 '  <user_or_group> (numeric UID/GID allowed).'
    8.17 +  echo 1>&2 '  This script calls `'"${0%_*}'"' for the real work.'
    8.18 +  echo 1>&2
    8.19 +  exit 1
    8.20 +fi
    8.21 +
    8.22 +ugname="$1"
    8.23 +
    8.24 +ugmatcher=(-false)
    8.25 +#test if find accepts ugname as a user, and append to ugmatcher if it does
    8.26 +if find / -maxdepth 0 -user "$ugname" >/dev/null 2>&1 ; then
    8.27 +  ugmatcher[${#ugmatcher[@]}]="-or"
    8.28 +  ugmatcher[${#ugmatcher[@]}]="-user"
    8.29 +  ugmatcher[${#ugmatcher[@]}]="$ugname"
    8.30 +fi
    8.31 +#test if find accepts ugname as a group, and append to ugmatcher if it does
    8.32 +if find / -maxdepth 0 -group "$ugname" >/dev/null 2>&1 ; then
    8.33 +  ugmatcher[${#ugmatcher[@]}]="-or"
    8.34 +  ugmatcher[${#ugmatcher[@]}]="-group"
    8.35 +  ugmatcher[${#ugmatcher[@]}]="$ugname"
    8.36 +fi
    8.37 +
    8.38 +#if find accepted ugname as neither user nor group, then exit
    8.39 +if [ "${#ugmatcher[@]}" = 1 ]; then
    8.40 +  echo 1>&2 'find does not accept `'"$ugname'"' as group or user name'
    8.41 +  exit 1
    8.42 +fi
    8.43 +
    8.44 +"${0%_*}" "${ugmatcher[@]}"
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/previous-work/more_control_helpers/bin/uninstall_package	Tue Jan 08 11:45:01 2013 +0000
     9.3 @@ -0,0 +1,31 @@
     9.4 +#!/bin/sh
     9.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
     9.6 +# You may do everything with this code except misrepresent its origin.
     9.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
     9.8 +
     9.9 +if [ $# != 1 -o "$1" = '--help' ]; then
    9.10 +  echo 1>&2 'USAGE: uninstall_package <package-name>'
    9.11 +  exit 1
    9.12 +fi
    9.13 +echo
    9.14 +echo '# If package '"$1"' has setuid root binaries, then you need to be'
    9.15 +echo '# root for the following to work.'
    9.16 +echo '# Otherwise, you can do it as user '"$1"'.'
    9.17 +echo
    9.18 +echo 'forall_direntries_from "'"$1"'" -depth \( -type d -exec echo rmdir {} \; \) -or \( -not -type d -exec echo rm -f {} \; \)'
    9.19 +echo
    9.20 +echo '# After successfully deleting all files, you may want to remove the'
    9.21 +echo '# package user '"$1"'. But remember that if you do that you need to'
    9.22 +echo '# remove or change ownership of '"$(eval echo ~"$1")"'. Unless you are'
    9.23 +echo '# certain that you will never re-install '"$1"', it is probably better to'
    9.24 +echo '# just keep the package user '"$1"' and its home directory around.'
    9.25 +echo '# Anyway, if you want to delete the account, you can use the following'
    9.26 +echo '# command:'
    9.27 +echo 
    9.28 +echo 'userdel "'"$1"'"'
    9.29 +echo
    9.30 +echo '# If your /etc/login.defs has USERGROUPS_ENAB set to "yes" (the default),'
    9.31 +echo '# then userdel will automatically delete the package user'"'"'s group if'
    9.32 +echo '# its name is identical to the user name. Otherwise, if you want to delete'
    9.33 +echo '# the package user'"'"'s group, you will need to use the `groupdel'"'"' command.'
    9.34 +echo
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/previous-work/more_control_helpers/etc/bash_profile	Tue Jan 08 11:45:01 2013 +0000
    10.3 @@ -0,0 +1,10 @@
    10.4 +# The wrappers directory must be the first entry in the PATH.
    10.5 +# The /tools/bin directory must be the last entry in the PATH and can be 
    10.6 +#   removed at the end of Chapter 6.
    10.7 +export PATH=/usr/lib/pkgusr:/bin:/usr/bin:/sbin:/usr/sbin:/tools/bin
    10.8 +
    10.9 +# Make prompt reflect that we are a package user.
   10.10 +export PROMPT_COMMAND='PS1="package \u:"`pwd`"> "'
   10.11 +
   10.12 +# Go to the home directory whenever we su to a package user.
   10.13 +cd
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/previous-work/more_control_helpers/etc/bashrc	Tue Jan 08 11:45:01 2013 +0000
    11.3 @@ -0,0 +1,3 @@
    11.4 +#Use the same environment regardless of whether we use 
    11.5 +#`su <package>' or 'su - <package>' to become the package user.
    11.6 +source ~/.bash_profile
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/previous-work/more_control_helpers/etc/build	Tue Jan 08 11:45:01 2013 +0000
    12.3 @@ -0,0 +1,178 @@
    12.4 +#!/bin/bash
    12.5 +# Copyright (c) 2000-2006 Matthias S. Benkmann <article AT winterdrache DOT de>
    12.6 +# You may do everything with this code except misrepresent its origin.
    12.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    12.8 +
    12.9 +# This script will build a package based on the commands in $HOME/build.conf
   12.10 +# It can be called with the following parameters that
   12.11 +# will cause it to execute the respective *_commands() functions. If it is
   12.12 +# called with no parameter, that is equivalent to
   12.13 +# build unpack patch configure make check install clean
   12.14 +#
   12.15 +# It will create 8 log files in the $HOME directory:
   12.16 +#   configure.log: All messages output during configure
   12.17 +#   configure.err: Just the errors output during configure
   12.18 +#   check.log: All messages output during checking
   12.19 +#   check.err: Just the errors output during checking
   12.20 +#   make.log: All messages output during make
   12.21 +#   make.err: Just the errors output during make
   12.22 +#   install.log: All messages output during make install
   12.23 +#   install.err: Just the errors output during make install
   12.24 +#
   12.25 +# After running the script you should check the *.err files to see
   12.26 +# if any problems have occurred. If that is the case, use the corresponding
   12.27 +# *.log files to see the error messages in context.
   12.28 +
   12.29 +build_script="$(readlink -f "$0")"
   12.30 +
   12.31 +cd  # go HOME
   12.32 +
   12.33 +source "$HOME"/build.conf
   12.34 +
   12.35 +if [ "_$(whoami)" != _root ]; then
   12.36 +  export PACKAGE_OWNER="$(whoami)"
   12.37 +fi
   12.38 +
   12.39 +
   12.40 + # This function auto-extracts tarballs based on PATTERNS (see build.conf) inside
   12.41 + # the directory $HOME/xxxbuild and
   12.42 + # cds into the fist directory created by the first tarball. This is also
   12.43 + # stored in the variable $srcdir.
   12.44 +unpack_commands()
   12.45 +{ :
   12.46 +  export srcdir=""
   12.47 +  rm -rf "$HOME/xxxbuild"
   12.48 +  mkdir -p "$HOME/xxxbuild" 
   12.49 +  cd "$HOME/xxxbuild" || return 1
   12.50 +  
   12.51 +  for p in $PATTERNS ; do
   12.52 +    for archive in "$HOME"/*"$p"* ; do
   12.53 +      dir=""
   12.54 +      if [ -f "$archive" ]; then
   12.55 +        case z"$archive" in
   12.56 +          z*.tar.bz2) dir=$(tar tjf "$archive" | grep / | head -n 1) ; tar xjf "$archive"  ;;
   12.57 +          z*.tar.gz)  dir=$(tar tzf "$archive" | grep / | head -n 1) ; tar xzf "$archive"  ;;
   12.58 +        esac
   12.59 +      fi
   12.60 +      dir=${dir##./}
   12.61 +      test -z "$dir" && echo 1>&2 "Error extracting $archive"
   12.62 +      test -z "$srcdir" && srcdir=${dir%%/*}
   12.63 +    done
   12.64 +  done
   12.65 +  
   12.66 +  test -z "$srcdir" && { echo 1>&2 "Source directory not found" ; return 1 ; }
   12.67 +  ln -s "$srcdir" yyysrc
   12.68 +}
   12.69 +
   12.70 +clean_commands()
   12.71 +{
   12.72 +  rm -rf "$HOME/xxxbuild"
   12.73 +}
   12.74 +
   12.75 +test_pipe()
   12.76 +{
   12.77 +  for i in "${PIPESTATUS[@]}" 
   12.78 +  do
   12.79 +    test $i != 0 && { echo FAILED! ; exit 1 ; }
   12.80 +  done
   12.81 +  echo successful!
   12.82 +  return 0
   12.83 +}
   12.84 +
   12.85 +if [ $# -eq 0 ]; then
   12.86 +  set -- unpack patch configure make check root_pre_install install root_post_install clean
   12.87 +fi
   12.88 +
   12.89 +while [ -n "$1" ]; do
   12.90 +  case "_$1" in
   12.91 +    _all)
   12.92 +        shift 1
   12.93 +        set -- dummy unpack patch configure make check root_pre_install install root_post_install clean "$@"
   12.94 +        ;;
   12.95 +        
   12.96 +    _unpack)
   12.97 +        echo -n Unpacking...
   12.98 +
   12.99 +        unpack_commands # no logging for unpack necessary 
  12.100 +        test_pipe
  12.101 +        ;;
  12.102 +   
  12.103 +    _patch)
  12.104 +        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
  12.105 +        patch_commands # no logging for patch necessary 
  12.106 +        #test_pipe
  12.107 +        ;;
  12.108 +
  12.109 +    _configure)
  12.110 +        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
  12.111 +        echo -n Configuring...
  12.112 +
  12.113 +        { configure_commands 3>&1 1>&2 2>&3 | tee "$HOME/configure.err" ;} &>"$HOME/configure.log"
  12.114 +        test_pipe
  12.115 +        # NOTE: Simply using && instead of test_pipe would not work, because &&
  12.116 +        # only tests the exit status of the last command in the pipe, which is tee.
  12.117 +        ;;
  12.118 +
  12.119 +    _make)
  12.120 +        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
  12.121 +        echo -n Building...
  12.122 +
  12.123 +        { make_commands 3>&1 1>&2 2>&3 | tee "$HOME/make.err" ;} &>"$HOME/make.log"
  12.124 +        test_pipe
  12.125 +        ;;
  12.126 +
  12.127 +    _check)
  12.128 +        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
  12.129 +        echo -n Checking...
  12.130 +
  12.131 +        { check_commands 3>&1 1>&2 2>&3 | tee "$HOME/check.err" ;} &>"$HOME/check.log"
  12.132 +        test_pipe
  12.133 +        ;;
  12.134 +    
  12.135 +    _root_pre_install)
  12.136 +        if type root_pre_install_commands &>/dev/null ; then
  12.137 +          if [ _$(whoami) != _root ]; then
  12.138 +            su --preserve-environment root -c "HOME='$HOME' '$build_script' root_pre_install" || exit 1
  12.139 +          else  
  12.140 +            echo -n "Preparing for install(root)..."
  12.141 +  
  12.142 +            { root_pre_install_commands 3>&1 1>&2 2>&3 | tee "$HOME/preinstall.err" ;} &>"$HOME/preinstall.log"
  12.143 +            test_pipe
  12.144 +          fi  
  12.145 +        fi
  12.146 +        ;;
  12.147 +        
  12.148 +    _install)
  12.149 +        cd "$HOME/xxxbuild/yyysrc" && srcdir="$(pwd)" || exit 1
  12.150 +        echo -n Installing...
  12.151 +
  12.152 +        { install_commands 3>&1 1>&2 2>&3 | tee "$HOME/install.err" ;} &>"$HOME/install.log"
  12.153 +        test_pipe
  12.154 +        ;;
  12.155 +    
  12.156 +    _root_post_install)
  12.157 +        if type root_post_install_commands &>/dev/null ; then
  12.158 +          if [ _$(whoami) != _root ]; then
  12.159 +            su --preserve-environment root -c "HOME='$HOME' '$build_script' root_post_install" || exit 1
  12.160 +          else  
  12.161 +            echo -n "Finishing install(root)..."
  12.162 +  
  12.163 +            { root_post_install_commands 3>&1 1>&2 2>&3 | tee "$HOME/postinstall.err" ;} &>"$HOME/postinstall.log"
  12.164 +            test_pipe
  12.165 +          fi  
  12.166 +        fi  
  12.167 +        ;;
  12.168 +        
  12.169 +    _clean)
  12.170 +        cd "$HOME"
  12.171 +        echo -n Cleaning...
  12.172 +        clean_commands
  12.173 +        echo done!
  12.174 +        ;;
  12.175 +    *)
  12.176 +        echo 1>&2 "Unknown command '$1'"
  12.177 +        exit 1
  12.178 +        ;;
  12.179 +  esac       
  12.180 +  shift 1
  12.181 +done
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/previous-work/more_control_helpers/etc/skel-package/.bash_profile	Tue Jan 08 11:45:01 2013 +0000
    13.3 @@ -0,0 +1,1 @@
    13.4 +/etc/pkgusr/bash_profile
    13.5 \ No newline at end of file
    14.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.2 +++ b/previous-work/more_control_helpers/etc/skel-package/.bashrc	Tue Jan 08 11:45:01 2013 +0000
    14.3 @@ -0,0 +1,1 @@
    14.4 +/etc/pkgusr/bashrc
    14.5 \ No newline at end of file
    15.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.2 +++ b/previous-work/more_control_helpers/etc/skel-package/.project	Tue Jan 08 11:45:01 2013 +0000
    15.3 @@ -0,0 +1,14 @@
    15.4 +DESCRIPTION:
    15.5 +  bogus package
    15.6 +CONTENTS:
    15.7 +  see pkg.lst
    15.8 +LAST UPDATED:
    15.9 +  30 Feb 2007
   15.10 +DOWNLOAD LOCATION:
   15.11 +  ftp://ftp.gnu.org/gnu/foo/
   15.12 +WEB SITE:
   15.13 +  <none>
   15.14 +INSTALL NOTES:
   15.15 +  <none>
   15.16 +GENERAL NOTES:
   15.17 +  <none>
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/previous-work/more_control_helpers/etc/skel-package/build	Tue Jan 08 11:45:01 2013 +0000
    16.3 @@ -0,0 +1,1 @@
    16.4 +/etc/pkgusr/build
    16.5 \ No newline at end of file
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/previous-work/more_control_helpers/etc/skel-package/build.conf	Tue Jan 08 11:45:01 2013 +0000
    17.3 @@ -0,0 +1,53 @@
    17.4 +#
    17.5 +# Build instructions for <PACKAGE>
    17.6 +#
    17.7 +# This file is sourced by the /etc/pkguser/build script.
    17.8 +
    17.9 +# Note: the ":;" before the "}" in *_commands() is a no-op that makes sure 
   17.10 +# that the function remains syntactically valid, even if you remove its
   17.11 +# contents (e.g. remove the "configure" line, because there's nothing to 
   17.12 +# configure for the package).
   17.13 +
   17.14 +# ATTENTION! All functions are called with $HOME/xxxbuild/yyysrc as current
   17.15 +# working directory (except for clean_commands which has $HOME as cwd
   17.16 +# and unpack_commands which starts in $HOME when the
   17.17 +# script is called). This directory is created by unpack_commands.
   17.18 +# This means that a cd in configure_commands will NOT
   17.19 +# carry over into make_commands, so if you're building in a different
   17.20 +# directory than the one with the extracted source, then a cd has to be 
   17.21 +# inserted at the beginning of EVERY function.
   17.22 +
   17.23 +# The unpack_commands() function in the build script will automatically extract
   17.24 +# .tar.gz and .tar.bz2 archives that match any of the space-separated
   17.25 +# patterns in this list.
   17.26 +# If a package has multiple archives, use patterns that make sure the
   17.27 +# archives are extracted in the correct order, because the archive
   17.28 +# extracted first will be the one in whose directory the build commands
   17.29 +# will be executed. Example for bash: "bash-3.1.tar doc-3.1.tar"
   17.30 +PATTERNS='4.3.2.tar'
   17.31 +
   17.32 +patch_commands()
   17.33 +{ :
   17.34 +  #patch -Np1 -i "$HOME"/package.patch
   17.35 +}
   17.36 +
   17.37 +configure_commands()
   17.38 +{ :
   17.39 +  "$srcdir"/configure --prefix=/usr --sysconfdir=/etc --disable-nls
   17.40 +}
   17.41 +
   17.42 +make_commands()
   17.43 +{ :
   17.44 +  make
   17.45 +}
   17.46 +
   17.47 +check_commands()
   17.48 +{ :
   17.49 +  #make check
   17.50 +}
   17.51 +
   17.52 +install_commands()
   17.53 +{ :
   17.54 +  make install
   17.55 +}
   17.56 +
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/previous-work/more_control_helpers/installdirs.lst	Tue Jan 08 11:45:01 2013 +0000
    18.3 @@ -0,0 +1,86 @@
    18.4 +/usr/bin
    18.5 +/usr/sbin
    18.6 +/usr/include
    18.7 +/usr/lib
    18.8 +/usr/man/man1
    18.9 +/usr/man/man2
   18.10 +/usr/man/man3
   18.11 +/usr/man/man4
   18.12 +/usr/man/man5
   18.13 +/usr/man/man6
   18.14 +/usr/man/man7
   18.15 +/usr/man/man8
   18.16 +/usr/doc
   18.17 +/usr/info
   18.18 +/usr/local/man/man1
   18.19 +/usr/local/man/man2
   18.20 +/usr/local/man/man3
   18.21 +/usr/local/man/man4
   18.22 +/usr/local/man/man5
   18.23 +/usr/local/man/man6
   18.24 +/usr/local/man/man7
   18.25 +/usr/local/man/man8
   18.26 +/usr/local/doc
   18.27 +/usr/local/info
   18.28 +/usr/share
   18.29 +/usr/share/dict
   18.30 +/usr/share/doc
   18.31 +/usr/share/info
   18.32 +/usr/share/locale
   18.33 +/usr/share/man/man1
   18.34 +/usr/share/man/man2
   18.35 +/usr/share/man/man3
   18.36 +/usr/share/man/man4
   18.37 +/usr/share/man/man5
   18.38 +/usr/share/man/man6
   18.39 +/usr/share/man/man7
   18.40 +/usr/share/man/man8
   18.41 +/usr/share/nls
   18.42 +/usr/share/misc
   18.43 +/usr/share/terminfo
   18.44 +/usr/share/zoneinfo
   18.45 +/usr/share/i18n
   18.46 +/usr/share/aclocal
   18.47 +/usr/local/bin
   18.48 +/usr/local/etc
   18.49 +/usr/local/include
   18.50 +/usr/local/lib
   18.51 +/usr/local/sbin
   18.52 +/usr/local/share
   18.53 +/usr/local/share/dict
   18.54 +/usr/local/share/doc
   18.55 +/usr/local/share/info
   18.56 +/usr/local/share/locale
   18.57 +/usr/local/share/man/man1
   18.58 +/usr/local/share/man/man2
   18.59 +/usr/local/share/man/man3
   18.60 +/usr/local/share/man/man4
   18.61 +/usr/local/share/man/man5
   18.62 +/usr/local/share/man/man6
   18.63 +/usr/local/share/man/man7
   18.64 +/usr/local/share/man/man8
   18.65 +/usr/local/share/nls
   18.66 +/usr/local/share/misc
   18.67 +/usr/local/share/terminfo
   18.68 +/usr/local/share/zoneinfo
   18.69 +/opt
   18.70 +/opt/doc
   18.71 +/opt/info
   18.72 +/opt/bin
   18.73 +/opt/include
   18.74 +/opt/lib
   18.75 +/opt/man/man1
   18.76 +/opt/man/man2
   18.77 +/opt/man/man3
   18.78 +/opt/man/man4
   18.79 +/opt/man/man5
   18.80 +/opt/man/man6
   18.81 +/opt/man/man7
   18.82 +/opt/man/man8
   18.83 +/var/lib
   18.84 +/var/opt
   18.85 +/etc
   18.86 +/etc/opt
   18.87 +/sbin
   18.88 +/bin
   18.89 +/lib
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/previous-work/more_control_helpers/lib/chgrp	Tue Jan 08 11:45:01 2013 +0000
    19.3 @@ -0,0 +1,27 @@
    19.4 +#!/bin/bash
    19.5 +# Copyright (c) 2000,2004 Matthias S. Benkmann <article AT winterdrache DOT de>
    19.6 +# You may do everything with this code except misrepresent its origin.
    19.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    19.8 +
    19.9 +DAISY_CHAIN=""
   19.10 +
   19.11 +for p in $(type -ap chgrp) ; do
   19.12 +  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
   19.13 +done
   19.14 +
   19.15 +if [ ! -n "$DAISY_CHAIN" ]; then
   19.16 +  echo Cannot find real ${0##*/} command 
   19.17 +  exit 1
   19.18 +fi
   19.19 +
   19.20 +if [ $UID == 0 ]; then
   19.21 +  exec $DAISY_CHAIN "$@"
   19.22 +fi
   19.23 +
   19.24 +if [ "$1" == "tty" ]; then
   19.25 +  echo 1>&2 '***' chgrp "$@"  
   19.26 +else
   19.27 +  $DAISY_CHAIN "$@" || exit $?
   19.28 +fi
   19.29 +
   19.30 +exit 0
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/previous-work/more_control_helpers/lib/chmod	Tue Jan 08 11:45:01 2013 +0000
    20.3 @@ -0,0 +1,45 @@
    20.4 +#!/bin/bash
    20.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
    20.6 +# You may do everything with this code except misrepresent its origin.
    20.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    20.8 +
    20.9 +DAISY_CHAIN=""
   20.10 +
   20.11 +for p in $(type -ap chmod) ; do
   20.12 +  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
   20.13 +done
   20.14 +
   20.15 +if [ ! -n "$DAISY_CHAIN" ]; then
   20.16 +  echo Cannot find real ${0##*/} command 
   20.17 +  exit 1
   20.18 +fi
   20.19 +
   20.20 +if [ $UID == 0 ]; then
   20.21 +  exec $DAISY_CHAIN "$@"
   20.22 +fi
   20.23 +
   20.24 +report=0
   20.25 +doit=1
   20.26 +reportmsg="*** chmod $@"
   20.27 +
   20.28 +set -- "$@" eND_ofLisT
   20.29 +while true ; do
   20.30 +  arg="$1"
   20.31 +  shift 1
   20.32 +  case "_$arg" in
   20.33 +    _eND_ofLisT) break ;;
   20.34 +    _g+s|_u+s) report=1; doit=0  ;;
   20.35 +    _4755) arg=755 ; report=1; doit=1 ;;
   20.36 +    _4555) arg=555 ; report=1; doit=1 ;;
   20.37 +    *) ;;
   20.38 +  esac
   20.39 +  set -- "$@" "$arg"
   20.40 +done
   20.41 +
   20.42 +if [ "$report" = 1 ]; then echo 1>&2 "$reportmsg" ; fi
   20.43 +
   20.44 +if [ "$doit" = 1 ]; then  
   20.45 +  exec $DAISY_CHAIN "$@"
   20.46 +fi
   20.47 +
   20.48 +exit 0
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/previous-work/more_control_helpers/lib/chown	Tue Jan 08 11:45:01 2013 +0000
    21.3 @@ -0,0 +1,30 @@
    21.4 +#!/bin/bash
    21.5 +# Copyright (c) 2000,2004 Matthias S. Benkmann <article AT winterdrache DOT de>
    21.6 +# You may do everything with this code except misrepresent its origin.
    21.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    21.8 +
    21.9 +DAISY_CHAIN=""
   21.10 +
   21.11 +for p in $(type -ap chown) ; do
   21.12 +  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
   21.13 +done
   21.14 +
   21.15 +if [ ! -n "$DAISY_CHAIN" ]; then
   21.16 +  echo Cannot find real ${0##*/} command 
   21.17 +  exit 1
   21.18 +fi
   21.19 +
   21.20 +if [ $UID == 0 ]; then
   21.21 +  exec $DAISY_CHAIN "$@"
   21.22 +fi
   21.23 +
   21.24 +# Package users can't chown anything at all, so
   21.25 +# having the script test for specific parameters
   21.26 +# is pointless.
   21.27 +#if [ "$1" == "root.root" ]; then
   21.28 +  echo 1>&2 '***' chown "$@"  
   21.29 +#else
   21.30 +#  $DAISY_CHAIN "$@" || exit $?
   21.31 +#fi
   21.32 +
   21.33 +exit 0
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/previous-work/more_control_helpers/lib/install	Tue Jan 08 11:45:01 2013 +0000
    22.3 @@ -0,0 +1,127 @@
    22.4 +#!/bin/bash
    22.5 +# Copyright (c) 2000,2004 Matthias S. Benkmann <article AT winterdrache DOT de>
    22.6 +# You may do everything with this code except misrepresent its origin.
    22.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    22.8 +
    22.9 +manpagesowner=man-pages
   22.10 +localedir=/usr/share/locale
   22.11 +cmdline="$@"
   22.12 +
   22.13 +DAISY_CHAIN=""
   22.14 +
   22.15 +for p in $(type -ap install) ; do
   22.16 +  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
   22.17 +done
   22.18 +
   22.19 +if [ ! -n "$DAISY_CHAIN" ]; then
   22.20 +  echo Cannot find real ${0##*/} command 
   22.21 +  exit 1
   22.22 +fi
   22.23 +
   22.24 +if [ $UID == 0 ]; then
   22.25 +  exec $DAISY_CHAIN "$@"
   22.26 +fi
   22.27 +
   22.28 +#kill unused -c parameter if we get it
   22.29 +if [ z"$1" = z"-c" ]; then shift 1 ; fi
   22.30 +
   22.31 +	#********** test if we create directories ********************
   22.32 +if [ \( z"$1" = z"-d" \) -o \( z"$1" = z"-m" -a z"$3" = z"-d" \) ]; then  
   22.33 +  locdirs=""
   22.34 +  notify=0
   22.35 +  havedir=0
   22.36 +  for((i=$#; $i>0; ))
   22.37 +  do
   22.38 +    a="$1"
   22.39 +    shift 1; i=$(($i-1))
   22.40 +    case "$a" in
   22.41 +      -o|-g|--owner|--group) notify=1 
   22.42 +      			shift 1; i=$(($i-1))
   22.43 +          		set -- "$@" 
   22.44 +          ;;
   22.45 +      $localedir/*) if [ ! -d "$a" ]; then
   22.46 +      		      locdirs="$locdirs ""`expr $a : "$localedir/\(.*\)"`" 
   22.47 +                      set -- "$@" "$a"
   22.48 +                      havedir=1
   22.49 +                    else
   22.50 +                      notify=1
   22.51 +                      set -- "$@"
   22.52 +                    fi  
   22.53 +                   ;;
   22.54 +      */*|/sbin) if [ ! -d "$a" ]; then 
   22.55 +      	     set -- "$@" "$a" 
   22.56 +      	     havedir=1
   22.57 +      	   else
   22.58 +      	     notify=1
   22.59 +      	     set -- "$@"
   22.60 +      	   fi             
   22.61 +      	   ;;
   22.62 +      *) set -- "$@" "$a" ;;
   22.63 +    esac
   22.64 +  done
   22.65 +  
   22.66 +  test $notify -eq 1 -o z"$locdirs" != z && \
   22.67 +  					echo 1>&2 '***' install "$cmdline"
   22.68 +
   22.69 +  test $havedir -eq 0 && exit 0
   22.70 +
   22.71 +  $DAISY_CHAIN "$@" || exit $?
   22.72 +  
   22.73 +  test z"$locdirs" != z &&
   22.74 +  for dir in $locdirs ; do
   22.75 +    cumuldir=""
   22.76 +    for d in `echo $locdirs | sed 's#/# #g' -` ; do
   22.77 +      cumuldir=$cumuldir$d/
   22.78 +      if [ -d $localedir/$cumuldir ]; then
   22.79 +        chgrp install $localedir/$cumuldir
   22.80 +        chmod g+w,o+t $localedir/$cumuldir
   22.81 +      fi  
   22.82 +    done  
   22.83 +  done
   22.84 +
   22.85 +else  #if "$1" != "-d"  ,i.e. we do not create directories *****************
   22.86 +  notify=0
   22.87 +  for((i=$# ; $i>0; ))
   22.88 +  do
   22.89 +    a="$1"
   22.90 +    shift 1; i=$(($i-1))
   22.91 +    case "$a" in
   22.92 +     -m)      set -- "$@" "$a" 
   22.93 +              a="$1"
   22.94 +              shift 1; i=$(($i-1))
   22.95 +              case "$a" in
   22.96 +                4755) notify=1 ; set -- "$@" "755" ;;
   22.97 +                4775) notify=1 ; set -- "$@" "755" ;;
   22.98 +                4711) notify=1 ; set -- "$@" "711" ;;
   22.99 +                *) set -- "$@" "$a"  ;;
  22.100 +              esac
  22.101 +          ;;
  22.102 +      -m4755) notify=1 ; set -- "$@" "-m755" ;;
  22.103 +      -m4775) notify=1 ; set -- "$@" "-m755" ;;
  22.104 +      -m4711) notify=1 ; set -- "$@" "-m711" ;;
  22.105 +      -o|-g|--owner|--group)    notify=1 
  22.106 +      		shift 1; i=$(($i-1))
  22.107 +          	set -- "$@" 
  22.108 +          ;;
  22.109 +      */man/man?/*) 
  22.110 +                if [ -e "$a" -a ! -O "$a" ]; then
  22.111 +                  if [ `find "$a" -printf \%u` = $manpagesowner ]; then
  22.112 +                    notify=1
  22.113 +                    set -- "$@" not_installed
  22.114 +                  else
  22.115 +                    set -- "$@" "$a"
  22.116 +                  fi  
  22.117 +                else
  22.118 +                  set -- "$@" "$a"
  22.119 +                fi
  22.120 +          ;;    
  22.121 +      *) set -- "$@" "$a" ;;
  22.122 +    esac
  22.123 +  done
  22.124 +
  22.125 +  test $notify -eq 1 && echo 1>&2 '***' install "$cmdline"
  22.126 +
  22.127 +  $DAISY_CHAIN "$@" || exit $?
  22.128 +fi
  22.129 +
  22.130 +exit 0
    23.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.2 +++ b/previous-work/more_control_helpers/lib/ldconfig.c	Tue Jan 08 11:45:01 2013 +0000
    23.3 @@ -0,0 +1,8 @@
    23.4 +#include <unistd.h>
    23.5 +
    23.6 +int main()
    23.7 +{
    23.8 +  char* const argv[] = {"/sbin/ldconfig", "-v", NULL, NULL};
    23.9 +  char* const env[] = {NULL, NULL};
   23.10 +  return execve(argv[0], argv, env);
   23.11 +}
    24.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.2 +++ b/previous-work/more_control_helpers/lib/mkdir	Tue Jan 08 11:45:01 2013 +0000
    24.3 @@ -0,0 +1,50 @@
    24.4 +#!/bin/bash
    24.5 +# Copyright (c) 2000 Matthias S. Benkmann <article AT winterdrache DOT de>
    24.6 +# You may do everything with this code except misrepresent its origin.
    24.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    24.8 +
    24.9 +watchdir=/usr/share/locale
   24.10 +
   24.11 +DAISY_CHAIN=""
   24.12 +
   24.13 +for p in $(type -ap mkdir) ; do
   24.14 +  if [ ! $p -ef $0 ]; then DAISY_CHAIN=$p ; break ; fi
   24.15 +done
   24.16 +
   24.17 +if [ ! -n "$DAISY_CHAIN" ]; then
   24.18 +  echo Cannot find real ${0##*/} command 
   24.19 +  exit 1
   24.20 +fi
   24.21 +
   24.22 +if [ $UID == 0 ]; then
   24.23 +  exec $DAISY_CHAIN "$@"
   24.24 +fi
   24.25 +
   24.26 +cmdline="$@"
   24.27 +
   24.28 +dirs=""
   24.29 +for((i=$#; $i>0;))
   24.30 +do
   24.31 +  a="$1"
   24.32 +  shift 1; i=$(($i-1))
   24.33 +  case "$a" in
   24.34 +    $watchdir/*) dirs="$dirs ""`expr $a : "$watchdir/\(.*\)"`" 
   24.35 +                 set -- "$@" "$a" 
   24.36 +                 ;;
   24.37 +    *) set -- "$@" "$a" ;;
   24.38 +  esac
   24.39 +done
   24.40 +
   24.41 +$DAISY_CHAIN "$@" || exit $?
   24.42 +
   24.43 +test z"$dirs" != z &&
   24.44 +echo 1>&2 '***' mkdir "$cmdline"
   24.45 +for dir in $dirs ; do
   24.46 +  cumuldir=""
   24.47 +  for d in `echo $dirs | sed 's#/# #g' -` ; do
   24.48 +    cumuldir=$cumuldir$d/
   24.49 +    chgrp install $watchdir/$cumuldir
   24.50 +    test -k $watchdir/$cumuldir || chmod g+w,o+t $watchdir/$cumuldir
   24.51 +  done  
   24.52 +done
   24.53 +exit 0
    25.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.2 +++ b/previous-work/more_control_helpers/sbin/add_package_user	Tue Jan 08 11:45:01 2013 +0000
    25.3 @@ -0,0 +1,239 @@
    25.4 +#!/bin/bash
    25.5 +# Copyright (c) 2004 Matthias S. Benkmann <article AT winterdrache DOT de>
    25.6 +# You may do everything with this code except misrepresent its origin.
    25.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    25.8 +
    25.9 +#Package user home directories will be located under this directory
   25.10 +homebase=/usr/src
   25.11 +
   25.12 +#Contents of following directory are copied into home directory when creating 
   25.13 +#a new package user (existing files will not be overwritten)
   25.14 +skel=/etc/pkgusr/skel-package
   25.15 +
   25.16 +if [ $# -lt 7 ]; then
   25.17 +  echo 1>&2 'USAGE: '
   25.18 +  echo 1>&2 'add_package_user <description> <name> <minuid> <maxuid> \'
   25.19 +  echo 1>&2 '                              <group> <mingid> <maxgid> [-d <home>]'
   25.20 +  echo 1>&2
   25.21 +  echo 1>&2 'If a user account called <name> exists, a message will be printed and'
   25.22 +  echo 1>&2 'everything will be left as-is. If a user account called <name> does not'
   25.23 +  echo 1>&2 'exist, one will be created.'
   25.24 +  echo 1>&2 'The account'"'"'s primary group will be <group> and the /etc/passwd'
   25.25 +  echo 1>&2 'description field will be set to <description>. If a group called <group>'
   25.26 +  echo 1>&2 'does not already exist, one will be created.'
   25.27 +  echo 1>&2 'The new account will get the "install" group as a supplementary group. If'
   25.28 +  echo 1>&2 'a group named "install" does not exist, one will be created.'
   25.29 +  echo 1>&2
   25.30 +  echo 1>&2 '<description> needs to be a valid string for the /etc/passwd description'
   25.31 +  echo 1>&2 '  field. This means, among other things, that it must not contain ":".'
   25.32 +  echo 1>&2 '  Don'"'"'t forget to properly quote <description> if it contains spaces or'
   25.33 +  echo 1>&2 '  other characters interpreted by the shell!'
   25.34 +  echo 1>&2
   25.35 +  echo 1>&2 '<minuid>(incl.) and <maxuid>(excl.) determine the numeric range from which'
   25.36 +  echo 1>&2 '  the new account'"'"'s UID will be picked in the following way:'
   25.37 +  echo 1>&2
   25.38 +  echo 1>&2 '  1. If the range contains no unused UID => Exit with error.'
   25.39 +  echo 1>&2 '  2. If <maxuid>-1 is still unused, find the greatest UID from the range'
   25.40 +  echo 1>&2 '     that is used and pick the number after that.'
   25.41 +  echo 1>&2 '  3. If <maxuid>-1 is in use, pick the first unused number from the range.'
   25.42 +  echo 1>&2
   25.43 +  echo 1>&2 '<mingid>(incl.) and <maxgid>(excl.) determine the numeric range from which'
   25.44 +  echo 1>&2 '  to pick the GID for group <group> and/or group "install", if it needs to be'
   25.45 +  echo 1>&2 '  created. The process for picking the GID is the same as that for the UID.'
   25.46 +  echo 1>&2 ''
   25.47 +  echo 1>&2 '<home> specifies the new user'"'"'s home directory. If it is not provided,'
   25.48 +  echo 1>&2 '  it will default to '"$homebase/<name> ."
   25.49 +  echo 1>&2 '  If the home directory does not exist yet it will be created, otherwise'
   25.50 +  echo 1>&2 '  the existing directory will be recursively chown'"'"'ed to the new user.'
   25.51 +  echo 1>&2 '  The home directory will be populated with a copy of the contents of'
   25.52 +  echo 1>&2 "  $skel, but pre-existing files in the home directory"
   25.53 +  echo 1>&2 '  will not be overwritten. Note that symlinks will be copied as symlinks!'
   25.54 +  echo 1>&2 ''
   25.55 +  exit 1
   25.56 +fi
   25.57 +
   25.58 +grpfile=/etc/group
   25.59 +passwd=/etc/passwd
   25.60 +
   25.61 +
   25.62 +
   25.63 +description=$1
   25.64 +name=$2
   25.65 +minuid=$3
   25.66 +maxuid=$4
   25.67 +gname=$5
   25.68 +mingid=$6
   25.69 +maxgid=$7
   25.70 +home=$homebase/$name
   25.71 +
   25.72 +set -- "$@" _eNd_OF_lisT_
   25.73 +while [ "$1" != "_eNd_OF_lisT_" ]; do
   25.74 +  case "$1" in
   25.75 +    -d) shift 1
   25.76 +        if [ "$1" = "_eNd_OF_lisT_" ]; then
   25.77 +          echo 1>&2 "-d directory name missing!"
   25.78 +          exit 1
   25.79 +        fi
   25.80 +        home="$1"
   25.81 +        shift 1
   25.82 +        ;;
   25.83 +    *) temp="$1" 
   25.84 +       shift 1
   25.85 +       set -- "$@" "$temp"
   25.86 +       ;;
   25.87 +  esac     
   25.88 +done
   25.89 +shift 1 #throw away _eNd_OF_lisT_
   25.90 +
   25.91 +if [ $UID -ne 0 ]; then echo Please run this script as root. ; exit 1; fi
   25.92 +
   25.93 +#test if user already exists
   25.94 +grep "^$name:.*" $passwd
   25.95 +if [ $? -eq 0 ]; then 
   25.96 +  echo 'Package user does already exist! Do su '$name' to do maintenance work.'
   25.97 +  exit 1
   25.98 +fi 
   25.99 +
  25.100 +#test if minuid, maxuid, mingid and maxgid are integers, otherwise error
  25.101 +error=0
  25.102 +expr ${minuid} + 1 2>/dev/null 1>&2 || error=1
  25.103 +expr ${maxuid} + 1 2>/dev/null 1>&2 || error=1
  25.104 +expr ${mingid} + 1 2>/dev/null 1>&2 || error=1
  25.105 +expr ${maxgid} + 1 2>/dev/null 1>&2 || error=1
  25.106 +
  25.107 +if [ $error -eq 1 ]; then
  25.108 +  echo Error: Illegal numeric value!
  25.109 +  exit 1
  25.110 +fi
  25.111 +
  25.112 +if [ $minuid -ge $maxuid ]; then
  25.113 +  echo 'Error: minuid must be less than maxuid !' 
  25.114 +  exit 1
  25.115 +fi
  25.116 +
  25.117 +if [ $mingid -ge $maxgid ]; then
  25.118 +  echo 'Error: mingid must be less than maxgid !' 
  25.119 +  exit 1
  25.120 +fi
  25.121 +
  25.122 +
  25.123 +uidlist=`cut -d : -f 3 $passwd | sort -n`
  25.124 +
  25.125 +#find last used UID within range
  25.126 +u=0
  25.127 +for i in $uidlist
  25.128 +do
  25.129 +  if [ $i -ge $maxuid ]; then break; fi
  25.130 +  if [ $i -ge $minuid ]; then u=$i; fi 
  25.131 +done
  25.132 +
  25.133 +#if no UID from the range is used, pick the first, otherwise pick the one
  25.134 +#immediately following the last UID in use.
  25.135 +if [ $u -eq 0 ]; then u=$minuid; else u=`expr $u + 1`; fi
  25.136 +
  25.137 +#if the UID determined above is >= maxuid (i.e. illegal)
  25.138 +#then we look for the first unused uid in the range.
  25.139 +if [ $u -ge $maxuid ]; then
  25.140 +  u=$minuid
  25.141 +  for i in $uidlist
  25.142 +  do
  25.143 +    if [ $u -eq $i ]; then u=`expr $u + 1` ; fi
  25.144 +    if [ $i -ge $maxuid ]; then break; fi
  25.145 +  done  
  25.146 +
  25.147 +  if [ $u -ge $maxuid ]; then
  25.148 +    echo Error: UID range is full!
  25.149 +    exit 1
  25.150 +  fi
  25.151 +fi
  25.152 +
  25.153 +echo Will create user $name with uid: $u
  25.154 +
  25.155 +unset uidlist
  25.156 +
  25.157 +#############################################################################
  25.158 +#                                 group
  25.159 +#############################################################################
  25.160 +
  25.161 +#execute the following for gname and "install" to get gids for those 2 groups
  25.162 +
  25.163 +g=0
  25.164 +creategroup=0
  25.165 +for group in install $gname
  25.166 +do
  25.167 +  oldg=$g #save gid from previous run
  25.168 +  createinstall=$creategroup
  25.169 +  creategroup=0
  25.170 + 
  25.171 +  #test if group already exists and extract gid if so
  25.172 +  g=`grep ^${group}:.\* $grpfile | cut -d : -f 3 -`
  25.173 +
  25.174 +  #if group does not exist, then check range for a free gid
  25.175 +  if [ z$g = z ]; then 
  25.176 +    creategroup=1
  25.177 +    
  25.178 +    gidlist=`cut -d : -f 3 $grpfile | sort -n`
  25.179 +
  25.180 +    #find last used GID within range
  25.181 +    g=0
  25.182 +    for i in $gidlist
  25.183 +    do
  25.184 +      if [ $i -ge $maxgid ]; then break; fi
  25.185 +      if [ $i -ge $mingid ]; then g=$i; fi
  25.186 +    done
  25.187 +
  25.188 +    #if no GID from the range is used, pick the first, otherwise pick the one
  25.189 +    #immediately following the last GID in use.
  25.190 +    if [ $g -eq 0 ]; then g=$mingid; else g=`expr $g + 1`; fi
  25.191 +    
  25.192 +    #don't reuse gid from previous run 
  25.193 +    if [ $g -eq $oldg ]; then g=`expr $g + 1`; fi
  25.194 +
  25.195 +    #if the GID determined above is >= maxgid (i.e. illegal)
  25.196 +    #then we look for the first unused gid in the range.
  25.197 +    if [ $g -ge $maxgid ]; then
  25.198 +      g=$mingid
  25.199 +      for i in $gidlist
  25.200 +      do
  25.201 +        if [ $g -eq $i ]; then g=`expr $g + 1` ; fi
  25.202 +        if [ $g -eq $oldg ]; then g=`expr $g + 1` ; fi
  25.203 +        if [ $i -ge $maxgid ]; then break; fi
  25.204 +      done  
  25.205 +
  25.206 +      if [ $g -ge $maxgid ]; then
  25.207 +        echo Error: GID range is full!
  25.208 +        exit 1
  25.209 +      fi
  25.210 +    fi
  25.211 +  fi
  25.212 +done
  25.213 +
  25.214 +unset gidlist
  25.215 +
  25.216 +if [ $createinstall -eq 1 ]; then
  25.217 +  echo Creating group install with gid $oldg
  25.218 +  groupadd -g $oldg install || exit 1
  25.219 +else
  25.220 +  echo Group install has gid $oldg
  25.221 +fi
  25.222 +if [ $creategroup -eq 1 ]; then
  25.223 +  echo Creating group $gname with gid $g
  25.224 +  groupadd -g $g $gname || exit 1
  25.225 +else 
  25.226 +  echo Group $gname has gid $g
  25.227 +fi
  25.228 +
  25.229 +
  25.230 +
  25.231 +useradd -c "${description}" -d ${home} -g ${gname} -G install \
  25.232 +        -s /bin/bash -u ${u} ${name}  || exit 1
  25.233 +
  25.234 +mkdir -p $home || exit 1
  25.235 +
  25.236 +yes n|cp -ai -R ${skel}/{[^.],.[^.],..?}* ${home} 2>/dev/null >/dev/null
  25.237 +
  25.238 +cd ${home}
  25.239 +chown --recursive ${u}:${g} .
  25.240 +
  25.241 +
  25.242 +exit 0
    26.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.2 +++ b/previous-work/more_control_helpers/sbin/groupadd	Tue Jan 08 11:45:01 2013 +0000
    26.3 @@ -0,0 +1,26 @@
    26.4 +#!/bin/bash
    26.5 +# Copyright (c) 2000,2004 Matthias S. Benkmann <article AT winterdrache DOT de>
    26.6 +# You may do everything with this code except misrepresent its origin.
    26.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    26.8 +
    26.9 +#
   26.10 +# This is a primitive script to serve as groupadd until the real groupadd
   26.11 +# has been installed. It has little error checking, so don't pass it anything
   26.12 +# stupid or it'll mess up your /etc/group file.
   26.13 +#
   26.14 +
   26.15 +if [ $# -ne 3 -o z$1 != z-g ]; then
   26.16 +echo 1>&2 USAGE: groupadd -g gid groupname
   26.17 +exit 1
   26.18 +fi
   26.19 +
   26.20 +#test if group already exists
   26.21 +grep "^${3}:.*" /etc/group 
   26.22 +if [ $? -eq 0 ]; then
   26.23 +  echo 1>&2 $0: Group does already exist
   26.24 +  exit 1
   26.25 +fi       
   26.26 +
   26.27 +cp /etc/group /tmp/group123456
   26.28 +echo ${3}:x:${2}: | sort -t : -k3,3n -m /tmp/group123456 - > /etc/group
   26.29 +
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/previous-work/more_control_helpers/sbin/install_package	Tue Jan 08 11:45:01 2013 +0000
    27.3 @@ -0,0 +1,35 @@
    27.4 +#!/bin/bash
    27.5 +# Copyright (c) 2000,2004 Matthias S. Benkmann <article AT winterdrache DOT de>
    27.6 +# You may do everything with this code except misrepresent its origin.
    27.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    27.8 +
    27.9 +if [ $# -eq 1 ]; then
   27.10 +  set -- "$1" "$1" "$1"
   27.11 +fi
   27.12 +
   27.13 +if [ $# -ne 3 ]; then
   27.14 +  echo 1>&2
   27.15 +  echo 1>&2 'USAGE 1: install_package <description> <name> <group>'
   27.16 +  echo 1>&2 'USAGE 2: install_package <name>'
   27.17 +  echo 1>&2
   27.18 +  echo 1>&2 'Creates a new package user called <name> with primary group <group>'
   27.19 +  echo 1>&2 'and description <description>.'
   27.20 +  echo 1>&2 'If the user account has been created successfully, `su - <name>'"'"' will be'
   27.21 +  echo 1>&2 'executed so that you can start working with the new account right away.'
   27.22 +  echo 1>&2
   27.23 +  echo 1>&2 '<description> needs to be a valid string for the /etc/passwd description'
   27.24 +  echo 1>&2 '  field. This means, among other things, that it must not contain ":".'
   27.25 +  echo 1>&2 '  Don'"'"'t forget to properly quote <description> if it contains spaces or'
   27.26 +  echo 1>&2 '  other characters interpreted by the shell!'
   27.27 +  echo 1>&2
   27.28 +  echo 1>&2 'This script leaves the actual creation of the new account to the'
   27.29 +  echo 1>&2 'add_package_user script. Check out its documentation for details.'
   27.30 +  echo 1>&2
   27.31 +  echo 1>&2 'When called with just one argument, that argument will be used as'
   27.32 +  echo 1>&2 '<name>, <description> and <group>'
   27.33 +  exit 1
   27.34 +fi
   27.35 +
   27.36 +if [ $UID -ne 0 ]; then echo Please run this script as root. ; exit 1; fi
   27.37 +add_package_user "${1}" $2 10000 20000 $3 10000 20000 || exit 1
   27.38 +su - $2
    28.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.2 +++ b/previous-work/more_control_helpers/sbin/useradd	Tue Jan 08 11:45:01 2013 +0000
    28.3 @@ -0,0 +1,45 @@
    28.4 +#!/bin/bash
    28.5 +# Copyright (c) 2000,2004 Matthias S. Benkmann <article AT winterdrache DOT de>
    28.6 +# You may do everything with this code except misrepresent its origin.
    28.7 +# PROVIDED `AS IS' WITH ABSOLUTELY NO WARRANTY OF ANY KIND!
    28.8 +
    28.9 +#
   28.10 +# This is a primitive script to serve as useradd until the real useradd
   28.11 +# has been installed. It has little error checking, so don't pass it anything
   28.12 +# stupid or it'll mess up your /etc/passwd and/or /etc/group file.
   28.13 +#
   28.14 +
   28.15 +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
   28.16 +echo 1>&2 USAGE: useradd -c description -d home -g maingroup -G addgroup -s shell -u uid login 
   28.17 +exit 1
   28.18 +fi
   28.19 +
   28.20 +#test if user already exists
   28.21 +grep "^${13}:.*" /etc/passwd 
   28.22 +if [ $? -eq 0 ]; then
   28.23 +  echo 1>&2 $0: User does already exist
   28.24 +  exit 1
   28.25 +fi       
   28.26 +
   28.27 +g=`grep ^${6}:.\* /etc/group | cut -d : -f 3 -`
   28.28 +if [ z${g} = z ]; then
   28.29 +  echo 1>&2 $0: Group ${6} does not exist!
   28.30 +  exit 1
   28.31 +fi
   28.32 +
   28.33 +grep ^${8}:.\* /etc/group >/dev/null || \
   28.34 +{
   28.35 +  echo 1>&2 $0: Group ${8} does not exist!
   28.36 +  exit 1
   28.37 +}
   28.38 +
   28.39 +
   28.40 +cp /etc/passwd /tmp/passwd123456
   28.41 +echo "${13}:x:${12}:$g:$2:$4:${10}" \
   28.42 +| sort -t : -k3,3n -m /tmp/passwd123456 - > /etc/passwd
   28.43 +
   28.44 +
   28.45 +cp /etc/group /tmp/group123456
   28.46 +sed  -e 's/^\('"${8}"':[^:]*:[0-9]*:..*\)$/\1,'"${13}"'/' \
   28.47 +     -e 's/^\('"${8}"':[^:]*:[0-9]*\):$/\1:'"${13}"'/' \
   28.48 +     						/tmp/group123456 >/etc/group