#!/bin/sh

REMOVE=""

# Do not use package or force currently
opts=$(getopt -o "pfr" -l "package,force,remove" -- "$@")
eval set -- "$opts"

while [ $# -gt 0 ]; do
    case $1 in
        --package) shift;;
        --force) shift;;
        --remove) REMOVE="true"; shift;;
        --) shift; break;;
        *) ;;
    esac
done


pam_profile_get () {
  local PROFILE="$1"
  local FIELDNAME="$2"
  awk -v FIELDNAME=$FIELDNAME '
    BEGIN{fieldname=""}
    function ltrim(s) { sub(/^[ \t\r\n]+/, "", s); return s }
    function rtrim(s) { sub(/[ \t\r\n]+$/, "", s); return s }
    function trim(s) { return rtrim(ltrim(s)); }
    /^[A-Za-z\-]+:/ { split($0, f, ":"); fieldname = f[1]; p[fieldname]=trim(f[2]); }
    /^[^A-Za-z\-]+/ {
        # FIXME:
        # Expected only single module configured per profile primary or additional
        # Assume the previous field has empty value
        p[fieldname] = $0
    }
    END {
        print p[FIELDNAME]
      }' $PROFILE
}

pam_profiles_sorted () 
{
  local PROFILE_NAME

  for PROFILE in /usr/share/pam-configs/*
  do
    # Skip the profile on remove
    if [ -n "$REMOVE" ]; then
      PROFILE_NAME=$(basename $PROFILE)
      test "$PROFILE_NAME" = "$DPKG_MAINTSCRIPT_PACKAGE" && continue
    fi
    printf "%05d %s\n" "$(pam_profile_get $PROFILE Priority)" $PROFILE
  done | sort -r | cut -d " " -f 2
}

pam_profiles_get_all () 
{
  local COMMON="$1"
  local COMMONTYPE="$2"

  if [ $COMMON = Session-NonInteractive ]
  then
    COMMONORIG=$COMMON
    COMMON=Session
  fi
  local COMMONID="$(echo $COMMON | tr '[:upper:]' '[:lower:]')"
  local PROFILE
  local RES=""
  local MOD

  for PROFILE in $(pam_profiles_sorted)
  do
    test "$(pam_profile_get $PROFILE Default)" = yes || continue
    test "$COMMONORIG" = Session-NonInteractive -a "$(pam_profile_get $PROFILE Session-Interactive-Only)" = yes && continue
    test "$(pam_profile_get $PROFILE $COMMON-Type)" = "$COMMONTYPE" || continue
    MOD="$(pam_profile_get $PROFILE $COMMON-Initial)"
    if [ -z "$MOD" ]
    then
      MOD="$(pam_profile_get $PROFILE $COMMON)"
      if [ -z "$MOD" ]
      then
        # Compatibility with old versions
        MOD="$(pam_profile_get $PROFILE $COMMON-Final)"
      fi
    fi
    if [ -n "$MOD" ]
    then
      RES="$RES
$COMMONID$MOD"
    fi
  done

  local MOD_CNT
  MOD_CNT=$(/bin/echo -e "$RES" | grep -c "=end")
  /bin/echo -e "$RES" | sed "/^$/d" | while read module; do
    /bin/echo -e "$module" | sed -e s/"=end"/"=$MOD_CNT"/
    test "$MOD_CNT" = 0 && continue
    MOD_CNT=$(expr $MOD_CNT - 1)
  done
}

replace () {
  local NEEDLE="$1"
  local REPLACEMENT="$2"
  local LINE
  while IFS= read -r LINE; do
    if [ "$LINE" = "$NEEDLE" ]
    then
      LINE=$REPLACEMENT
    fi
    echo "$LINE"
  done
}

umask 022

for COMMON in Auth Account Password Session Session-NonInteractive
do
  COMMONID=$(echo $COMMON | tr '[:upper:]' '[:lower:]')
  COMMONVAR=$COMMONID
  TEMPLATEFILE=/usr/share/pam/common-$COMMONID

  if [ $COMMONID = session-noninteractive ]
  then
    COMMONID=session
    COMMONVAR=session_nonint
  fi

  echo ==== $COMMON Primary
  PRIMARY=$(pam_profiles_get_all $COMMON Primary)
  if [ -z "$PRIMARY" ]
  then
    PRIMARY="$COMMONID\t[default=1]\t\t\tpam_permit.so"
  fi
  echo "$PRIMARY"

  echo ==== $COMMON Additional
  ADDITIONAL=$(pam_profiles_get_all $COMMON Additional)
  echo "$ADDITIONAL"

  echo @@@@ $TEMPLATEFILE
  cat $TEMPLATEFILE | replace "\$${COMMONVAR}_primary" "$PRIMARY" | replace "\$${COMMONVAR}_additional" "$ADDITIONAL" > /etc/pam.d/$(basename $TEMPLATEFILE)
done
