#! /bin/bash
###############  Copyright 2003 Trimble Navigation Limited #############
# $Id: mergePasswds,v 1.13 2003/08/05 18:09:11 tom Exp $
# $Source: /home/CVS/fireballTop/fireballFS/root/usr/local/fireball/mergePasswds,v $
########################################################################
#
# mergePasswds
#
# Shell script to create the system password file by merging account
# data from several sources.
#
# A Fireball firmware release comes with a generic password file that
# contains several system accounts (like root, netrx, mail, etc.).
# These are not under user control.  Other portions of the fireball
# system require that the user create and manage system accounts, with
# passwords.  For example, the ftp utility needs separate passwords for
# the accounts adminFTP and netrsFTP.  [Note, only the ftp passwords
# exist at the moment, but this might change if we allow user-defined
# ssh accounts, etc.]  Since the user defined accounts are part of the
# configuration, they must be maintained in /etc/sysconfig, They can't
# be wiped out by firmware upgrades but they should be wiped out if the
# user does a ResetToDefaults operation.  But the generic account 
# information has to survive such operations.  Futhermore, /etc/passwd
# is the path that is hard-wired into many programs, so that has to
# be the path to the file, even though /etc/ is not writeable.  To
# handle all of these requirements and constraints, we have to implement
# the following:
#
#   /etc/passwd is a symlink to /etc/syconfig/passwd, which is in a
#   writeable directory.
#
#   /etc/syconfig/passwd is dynamically generated at various times
#   by combining data from several sources:
#
#   /usr/local/fireball/defaults/sysconfig/passwd
#       This is a default file containing the generic accounts.
#       It is part of each firmware release.
#
#   /etc/sysconfig/ftppasswd
#       This is a configuration file containing only the account
#       definitions used by the FTP daemon.
#
#   /etc/sysconfig/...
#       There may be other user defined accounts at some later time,
#       such as for ssh logins, etc.
#
# MergePasswds takes the contents of the user configuration password
# file(s) and merges the information with the base account information,
# putting the results into /etc/sysconfig/passwd.  It must do this
# whenever any of the contributing files may have changed:
#
# - When the user enters a new password for any user configurable
#   accounts.
#
# - When the user generated account information might have been changed,
#   as by applying a new configuration file containing ftppasswd.
#   This is usually refered to as a "clone" operation.
#
# - When new firmware is installed, since the base password file may
#   have changed.
#
# A case could be made for including this condition:
#
# - When the system is reset to its default configuration which wipes
#   out everything in /etc/sysconfig and restores everything to the 
#   default settings.  
#
# But that should install the base account data in
# /etc/sysconfig/passwd, ignoring any other accounts.  That is probably
# what is desired, but this could change if some default merging becomes
# necessary with later modifications.
#
# As it currently stands, this script is invoked 
#   By the GUI when ftp passwords are changed.  
#   By the Ramdisk file system whenever the system firmware is upgraded.
#   By the Ramdisk file system whenever a clone operation is performed.
#
# The script takes the source files and combines them into a new
# composite passwd file.  The new file is created in /tmp.  It is 
# installed into /etc/sysconfig only if necessary, this is, only when
# actual changes are detected.  
########################################################################


PATH=/bin:/usr/bin/

# The script code below uses the utility programs diff and grep.
# These exist on the PATH when running in a normal compact flash
# file system, but there are problems with these programs when run in
# the diagnostic ramdisk system.  Thus, we define shell variables
# containing the proper explicit path for each of these and use the
# variables to invoke them below.
#
#   diff doesn't exist in the ramdisk, and has to be called from the
#        compact flash system. 
#        When running from CF     : /usr/bin/diff.
#        When running from Ramdisk: /mnt/usr/bin/diff
#
#   grep exists in ramdisk, but is defective (busybox) and leads to
#        many duplicate lines.  So we have to use the compact flash
#        version, which isn't a link to busybox.
#        When running from CF     : /bin/grep.
#        When running from Ramdisk: /mnt/bin/grep

# Assume we are running from normal compact flash file system
DIFF=/usr/bin/diff
GREP=/bin/grep
# Have to rewrite these if running on Ramdisk.  Detect this by the
# missing /usr/bin/diff file.
if [[ ! -f $DIFF ]]
then
  DIFF=/mnt/$DIFF
  GREP=/mnt/$GREP
fi

# This is the target for the final password file.
PASSWD_FILE=/etc/sysconfig/passwd

# Determine the location of the generic account information.  The
# location varies depending on which file system we are running in.
# We first check under the path that would be present for normal 
# runtime CompactFlash systems.  If that file doesn't exist, we assume
# we are running under the Ramdisk filesystem for installations or
# cloning operations, and the file is found under /mnt/...
# If that fails then we don't have a base file and have to give up.
PASSWD_BASE=/usr/local/fireball/defaults/sysconfig/passwd 
if [[ ! -f $PASSWD_BASE ]]
then
  PASSWD_BASE=/mnt/$PASSWD_BASE
  if [[ ! -f $PASSWD_BASE ]]
  then
    Error="Can't find a base passwd file!" 
    echo "mergePasswds: $Error" 1>&2
    exit 1
  fi
fi


# In a subshell, filter the base passwd file to remove any lines that 
# should be coming in from the user configuration area.  Then append the
# user configuration lines.  Direct the entire stdout of the subshell to
# the new file in /tmp/passwd.
(
  # Emit all lines in passwd that don't match these patterns.
  # We drop any accounts expected to be supplied by the
  # ftppasswd file.  
  # The obsolete account "netrxFTP" is also dropped.
  $GREP -v -e '^netrxFTP:' -e '^adminFTP:' -e '^netrsFTP:' $PASSWD_BASE

  # Append the user configurable data, if it exists.
  # As a security measure, we only transfer any account lines that are
  # expected to be in this file.  That prevents a backdoor method of
  # installing unusual accounts using the Config File mechanism.
  if [[ -f /etc/sysconfig/ftppasswd ]]
  then
    $GREP -e '^netrsFTP:' -e '^adminFTP:' /etc/sysconfig/ftppasswd
  fi

  # Append other data sources here.  None at present time.

) > /tmp/passwd

#cat /tmp/passwd

# If the new file differs from the old one, then install the new
# one.  Diff returns 0 if the files are identical and 1 if 
# differences were found.  
# Diff returns a 2 if problems were found, so if the $PASSWD_FILE
# doesn't currently exist we'll create it.
if ! $DIFF -q /tmp/passwd $PASSWD_FILE > /dev/null
then
  # Difference found or base didn't exist.
  # Copy the new password file into place.
  #logger -t mergePasswds "Updating /etc/passwd with new user accounts."
  cp /tmp/passwd $PASSWD_FILE
#else
  # No differences found.  No update needed.
  #logger -t mergePasswds "No update needed."
fi

exit 0
# end of script mergePasswds
