##############################################################################
# Copyright (c) Members of the EGEE Collaboration. 2004.
# See http://www.eu-egee.org/partners/ for details on the copyright
# holders.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS
# OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##############################################################################
#
# NAME :        config_users
#
# DESCRIPTION : This function configures the users.
#
# AUTHORS :     Robert.Harakaly@cern.ch
#
# NOTES :       Creates the Pool Users.
#
#               Takes the users, groups and ids from a configuration file (USERS_CONF).
#               File format:
#               UserId:User:GroupId:Group:VO:Tag:
#
# YAIM MODULE:  glite-yaim-core
#
##############################################################################

config_users_check() {

  if [ "x$CONFIG_USERS" = "xyes" ]; then
    requires $1 USERS_CONF VOS
    return $?
  fi

  return 0
}

config_users() {

  if [ "x$CONFIG_USERS" = "xyes" ]; then
  ####@ Takes the users, groups and ids from a configuration file: ${USERS_CONF}

    ####@ Check whether USERS_CONF exists
    if [ ! -e $USERS_CONF ]; then
      yaimlog INFO "USERS_CONF file $USERS_CONF doesn't exist."
      yestr ${YEX_NOSUCHFILE}
      yaimlog ERROR "${YERRORSTR}"
      exit ${YEX_NOSUCHFILE}
    fi

    check_users_conf_format
    grid_accounts=
    newline='
'
    ####@ Check if pool accounts for VOs are defined in $USERS_CONF file.
    for vo in $VOS; do 
      # Take the groups of all entries belonging to the VO and without a 
      # specific tag. The most numerous result is taken into account.
      # UserId:User:GroupId:Group:VO:Flag:
      #   $1    $2    $3      $4  $5  $6
      v=$(awk -F: '$6=="" && $5 == tolower(vo){print $4}' vo=$vo ${USERS_CONF} \
        	| sort | uniq -c | sort -n -k 1,1 | tail -1 | awk '{print $2}')
      if [ -z $v ]; then
        yaimlog WARNING "VO $vo doesn't have pool accounts defined in $USERS_CONF"
      fi
    done

    ####@ Generate a list of missing users
    PASSWD=`mktemp /root/yaim.XXXXXX`
    MISSING=`mktemp /root/yaim.XXXXXX`
    getent passwd | sort -t: -k1,1 > $PASSWD
    sort -t: -k2,2 $USERS_CONF | join -v 2 -t: -1 1 -2 2 $PASSWD - > $MISSING
    rm -f $PASSWD

    ####@ Adds all users/groups for each VO in ${VOS}
    while IFS=: read id user gids groups virtorg tag other; do

      # Skip blank lines
      if [ "x$id" = "x" ]; then
        yaimlog DEBUG "Skipping blank line in ${USERS_CONF}."
        continue
      fi
      # Skip user if VO not supported
      if ! ( [ "$virtorg" ] && echo $VOS | grep -w "$virtorg" >/dev/null ); then
        yaimlog DEBUG "Skipping user ${user}, VO (${virtorg} not supported.)"
        continue
      fi
      # Specify user home if defined by the sys admin
      unset useradd_args
      home_dir=`get_vo_param ${virtorg} USER_HOME_PREFIX`
      if [ "x${home_dir}" != "x" ]; then
        yaimlog DEBUG "USER_HOME_PREFIX is specified for VO ${virtorg}" 
        useradd_args="-d `eval echo "\${home_dir}"`/$user"    
      else
        if [ "x${USER_HOME_PREFIX}" != "x" ]; then
          yaimlog DEBUG "USER_HOME_PREFIX is specified for all the VOs"
          useradd_args="-d `eval echo "\${USER_HOME_PREFIX}"`/$user"
        fi
      fi

      # Add group
      gids=`echo $gids | sed -e 's/,/ /g'`
      groups=`echo $groups | sed -e 's/,/ /g'`
      initialgroup=`echo $groups | cut -d " " -f 1`
      additionalgroups=`echo $groups | cut -d " " -f 2- -s`
      SED="s/ $initialgroup / /g;s/ - / /g;s/  */ /g;s/^ //;s/ $//;s/ /,/g"
      additionalgroups=`echo " $additionalgroups " | sed "$SED"`
      [ -z "$additionalgroups" ] || additionalgroups="-G $additionalgroups"

      for group in $groups; do

       gid=` echo $gids | cut -d " " -f 1`
       gids=`echo $gids | cut -d " " -f 2- -s`
       if [ -z "$gid" ]; then
           yaimlog ABORT "User '$user' has group '$group' without GID defined !"
           yaimlog ABORT "Please, specify a GID for group '$group', user '$user'"
           yestr ${YEX_GROUPERR}
           yaimlog ERROR "${YERRORSTR}"
           exit ${YEX_GROUPERR}
       fi

       if [ "x$group" = "x-" ] && [ "x$gid" != "x-" ]; then
	   yaimlog ABORT "User '$user' has group '-'. GID must be '-' !"
           yaimlog ABORT "Please, specify GID '-' for group '-', user '$user'"
           yestr ${YEX_GROUPERR}
           yaimlog ERROR "${YERRORSTR}"
           exit ${YEX_GROUPERR}
       fi

       if [ "x$group" != "x-" ] && [ "x$gid" = "x-" ]; then
	   yaimlog ABORT "User '$user' has group '$group' with GID '-' !"
           yaimlog ABORT "Please, specify a GID for group '$group', user '$user'"
           yestr ${YEX_GROUPERR}
           yaimlog ERROR "${YERRORSTR}"
           exit ${YEX_GROUPERR}
       fi

       if [ "x$group" = "x-" ]; then
	   yaimlog DEBUG "No secondary groups configured for user '$user'."
	   continue
       fi

       if ! (getent group $group >/dev/null || groupadd -g $gid $group); then
           yaimlog ABORT  "Group '$group' with gid '$gid' for user '$user' failed to be created !"
           yestr ${YEX_GROUPERR}
           yaimlog ERROR "${YERRORSTR}"
           exit ${YEX_GROUPERR}
       else
         yaimlog DEBUG "Group '$group' with gid '$gid' for user '$user' succesfully created."
       fi

      done # Add group

      useradd -m -p "*NP*" -c "mapped user for group $initialgroup" \
         -u $id -g $initialgroup $additionalgroups ${useradd_args} $user
      ret=$?
      if [ $ret -ne 0 ]; then
        yaimlog ABORT "useradd command for $user with uid '$id' failed."
        if [ $ret -ne 9 ]; then
          userdel $user > /dev/null 2>&1
          yaimlog ABORT "ran userdel for $user to try to cleanup."
        fi
        yestr ${YEX_USERERR}
        yaimlog ERROR "${YERRORSTR}"
        exit ${YEX_USERERR}
      fi 
    
      ####@ Disables cron for pool users, grid users shall not be able to submit at or cron jobs.
      for deny in /etc/at.deny /etc/cron.deny; do
        tmp=$deny.$$
        touch $deny
        (grep -v "^$user\$" $deny; echo "$user") > $tmp && mv $tmp $deny
      done

    done < ${MISSING} # Add user
    rm -f ${MISSING}
    unset MISSING

    # Some things we need to do on every reconfiguration
    while IFS=: read id user gids groups virtorg tag other; do

      # Skip blank lines
      if [ "x$id" = "x" ]; then
        yaimlog DEBUG "Skipping blank line in ${USERS_CONF}."
        continue
      fi
      # Skip user if VO not supported
      if ! ( [ "$virtorg" ] && echo $VOS | grep -w "$virtorg" >/dev/null ); then
        yaimlog DEBUG "Skipping user ${user} since its VO (${virtorg}) is not supported."
        continue
      fi
      grid_accounts="$grid_accounts$newline$user"

    done < $USERS_CONF

  else 
    ####@ User configuration is disabled 
    yaimlog INFO "User configuration is disabled. YAIM won't configure the users in ${USERS_CONF}"
    yaimlog INFO "Please, be aware the users must exist in the system for succesful configuration"
  fi


  ####@ Cleanup grid accounts 
  (
    cga=/etc/cleanup-grid-accounts.conf
    cga_tmp=$cga.$$

    [ -r $cga ] || exit

    (
	sed '/YAIM/,$d' $cga
	echo "# next lines added by YAIM on `date`"
	echo "ACCOUNTS='$grid_accounts$newline'"
    ) > $cga_tmp

    mv $cga_tmp $cga
  )

  ####@ On a CE and WN it creates the cleanup-grid-accounts cron job.
  let minute="$RANDOM%60"
  let h="$RANDOM%6"
  f=/var/log/cleanup-grid-accounts.log

  if ( echo " ${NODE_TYPE_LIST} " | egrep -q "CE" ); then
    ####@ cron job
    cron_job cleanup-grid-accounts root "$minute $h * * * /usr/sbin/cleanup-grid-accounts.sh -v -F >> $f 2>&1"

    ####@ log rotate
    cat <<EOF > /etc/logrotate.d/cleanup-grid-accounts
$f {
    compress
    daily
    rotate 30
    missingok
}
EOF

  elif ( echo "${NODE_TYPE_LIST}" | grep 'WN' > /dev/null ); then
    ####@ cron job
    cron_job cleanup-grid-accounts root "$minute $h * * * /usr/sbin/cleanup-grid-accounts.sh -v >> $f 2>&1"

    ####@ log rotate
    cat <<EOF > /etc/logrotate.d/cleanup-grid-accounts
$f {
    compress
    daily
    rotate 30
    missingok
}
EOF

  fi # cleanup-grid-accounts

  return 0

}
