#!/bin/bash
# 
# This script is used for Administration of RSBAC ACLs
#
#
# Make sure we're really running bash.
#
[ -z "$BASH" ] && { echo "This menu requires bash" 1>&2; exit 1; }

#
# Cache function definitions, turn off posix compliance
#
set -h +o posix

# set this to rsbac bin dir, if not in path (trailing / is mandatory!)
#
#if test -z "$RSBACPATH" ; then RSBACPATH=./ ; fi

# set this to initial dir on script startup
LASTDIR='.'

# which dialog tool to use - dialog or kdialog or xdialog...
if test -z $DIALOG
then DIALOG=${RSBACPATH}dialog
fi
if ! $DIALOG --clear
then
  echo $DIALOG menu program required! >&2
  exit
fi
if ! $DIALOG --help 2>&1 | grep -q "help-button"
then
  echo "Newer dialog menu version >= 0.9a-20020309a with '--help-button' option" >&2
  echo "required, please use dialog from admin tools contrib dir or set" >&2
  echo "\$DIALOG to another dialog program, e.g. with rsbac_settings_menu!" >&2
  exit
fi

# The dir for tmp files
if test -z "$TMPDIR" ; then TMPDIR=/tmp ; fi

# This must be a unique temporary filename
if ! TMPFILE=`mktemp -q $TMPDIR/rsbac_dialog.XXXXXX`
then
  TMPFILE=$TMPDIR/rsbac_dialog.$$
  if test -e $TMPFILE
  then rm $TMPFILE
  fi
fi
if ! TMPFILETWO=`mktemp -q $TMPDIR/rsbac_dialog.XXXXXX`
then
  TMPFILETWO=$TMPDIR/rsbac_dialog.$$.2
  if test -e $TMPFILETWO
  then rm $TMPFILETWO
  fi
fi

# test for LINES and COLUMNS (should be exported e.g. in /etc/profile)
if test -z "$LINES" ; then LINES=25 ; fi
if test -z "$COLUMNS" ; then COLUMNS=80 ; fi
export LINES
export COLUMNS
declare -i BL=$LINES-4
declare -i BC=$COLUMNS-4
declare -i MAXWIDTH=$BC-26
declare -i MAXLINES=$LINES-10
gl () {
  if test $1 -gt $MAXLINES
  then echo $MAXLINES
  else echo $1
  fi
}

if test -z "$BACKTITLE"
  then BACKTITLE="RSBAC Administration Tools v1.2.2" ; fi
TITLE="`whoami`@`hostname`: RSBAC ACL Administration"
HELPTITLE="`whoami`@`hostname`: RSBAC ACL Administration Help"
ERRTITLE="RSBAC ACL Administration - ERROR"

## no changes below this line!

NO_USER=65533
ALL_USERS=65532
GETMODE=real
GETSWITCH=

show_help () {
  case "$RSBACLANG" in
    DE)
      show_help_german "$1"
      ;;
    RU)
      show_help_russian "$1"
      ;;
    *)
      show_help_english "$1"
      ;;
  esac
}

show_help_english () {
 {
  echo "$1"
  echo ""
  case "$1" in
      FD)
        echo File/Dir/Fifo/Symlink ACLs
        ;;
      DEV)
        echo Device ACLs
        ;;
      USER)
        echo User ACLs
        ;;
      PROCESS)
        echo Process ACLs
        ;;
      IPC)
        echo Inter Process Communication ACLs
        ;;
      SCD)
        echo System Control Data ACLs
        ;;
      NETDEV)
        echo Network Devices
        ;;
      NETTEMP_NT)
        echo Network Templates - ACL for template accesses.
        ;;
      NETTEMP)
        echo Network Templates - ACL for network object accesses.
        ;;
      NETOBJ)
        echo Network objects
        ;;
      :DEFAULT:)
        echo "$TARGET default ACL, the top parent object for all inheritance."
        ;;

    'File/Dir/Fifo/Symlink List')
      echo "Choose object from a list."
      ;;

    'Device List')
      echo "Choose object from a list."
      ;;

    'SCD List')
      echo "Choose object from a list."
      ;;

    'Network Device List')
      echo "Choose object from a list."
      ;;

    'Network Template List')
      echo "Choose object from a list."
      ;;

    "File/Dir/Fifo/Symlink" | "Device" | "SCD")
      echo "Enter object name."
      ;;

    "User" | "Process" | "IPC")
      echo "Enter object name."
      ;;

    "Follow")
      echo "Follow a symbolic link."
      ;;

    "Choose Target")
      echo "Choose target type."
      ;;

    'Add ACL Entry')
      echo "Add an ACL entry for this object."
      ;;

    "Remove Entry")
      echo "Remove an ACL entry from this object."
      ;;

    "Change TTL")
      echo "Change time-to-live for an ACL entry of this object. After this"
      echo "time the entry will be removed."
      ;;

    "Name / Rights")
      echo "Switch between subject names and rights to be shown in menu."
      ;;

    'Who has here')
      echo "Show which subjects have which effective rights to this object."
      ;;

    'Change Mask')
      echo "Change the inheritance mask of this object."
      echo ""
      echo "The mask specifies, which rights can be inherited from the object at the"
      echo "next higher level, e.g. the parent directory."
      echo ""
      echo "The highest level parent is the :DEFAULT: object."
      ;;

    GROUP* | ROLE* | USER*)
      echo "Rights in this ACL entry."
      ;;

    "Clear ACL")
      echo "Remove all ACL entries for this object."
      ;;

    'Groups')
      echo "Go to groups menu."
      ;;

    'Roles')
      echo "Go to RC roles menu."
      ;;

    'FD attr')
      echo "Go to File/Dir/Fifo/Symlink attribute menu."
      ;;

    'DEV attr')
      echo "Go to Device attribute menu."
      ;;

    'IPC attr')
      echo "Go to IPC attribute menu."
      ;;

    'SCD attr')
      echo "Go to SCD attribute menu."
      ;;

    'USER attr')
      echo "Go to User attribute menu."
      ;;

    'PROCESS attr')
      echo "Go to Process attribute menu."
      ;;

    'NETTEMP attr')
      echo "Go to Network Template attribute menu."
      ;;

    Quit)
        echo "Quit this menu."
      ;;

    *)
        echo "No help for $1 available!"
  esac
 } > $TMPFILE
  $DIALOG --title "$HELPTITLE" \
          --backtitle "$BACKTITLE" \
          --textbox $TMPFILE $BL $BC
#  sleep 1
}

show_help_german () {
 {
  echo "$1"
  echo ""
  case "$1" in
      FD)
        echo File/Dir/Fifo/Symlink ACLs
        ;;
      DEV)
        echo Device ACLs
        ;;
      USER)
        echo User ACLs
        ;;
      PROCESS)
        echo Process ACLs
        ;;
      IPC)
        echo Inter Process Communication ACLs
        ;;
      SCD)
        echo System Control Data ACLs
        ;;
      NETDEV)
        echo Network Devices
        ;;
      NETTEMP_NT)
        echo Netzwerk-Templates - ACL fr Templatezugriffe.
        ;;
      NETTEMP)
        echo Netzwerk-Templates - ACL fr Netzwerk-Objekt-Zugriffe.
        ;;
      NETOBJ)
        echo Netzwerkobjekte
        ;;
      :DEFAULT:)
        echo "$TARGET default ACL, das oberste Eltern-Objekt fr alle Vererbungen."
        ;;

    'File/Dir/Fifo/Symlink List')
      echo "Whle Objekt aus einer Liste."
      ;;

    'Device List')
      echo "Whle Objekt aus einer Liste."
      ;;

    'SCD List')
      echo "Whle Objekt aus einer Liste."
      ;;

    'Network Device List')
      echo "Whle Objekt aus einer Liste."
      ;;

    'Network Template List')
      echo "Whle Objekt aus einer Liste."
      ;;

    "File/Dir/Fifo/Symlink" | "Device" | "SCD")
      echo "Objektnamen eingeben."
      ;;

    "User" | "Process" | "IPC")
      echo "Objektnamen eingeben."
      ;;

    "Follow")
      echo "Symbolischem Link folgen."
      ;;

    "Choose Target")
      echo "Ziel-Typ whlen."
      ;;

    'Add ACL Entry')
      echo "ACL-Eintrag fr dieses Objekt hinzufgen."
      ;;

    "Remove Entry")
      echo "ACL-Eintrag von diesem Objekt entfernen."
      ;;

    "Change TTL")
      echo "Lebenszeit eines ACL-Eintrags ndern. Nach dieser Zeitspanne"
      echo "wird der Eintrag automatisch entfernt."
      ;;

    "Name / Rights")
      echo "Umschalten zwischen Subjekt-Namen- und Rechteanzeige im Men."
      ;;

    'Who has here')
      echo "Anzeigen, welche Subjekte welche effektiven Rechte auf dieses"
      echo "Objekt haben."
      ;;

    'Change Mask')
      echo "Vererbungsmaske dieses Objekts ndern."
      echo ""
      echo "Die Maske legt fest, welche Rechte von der nchsthheren"
      echo "Objektebene geerbt werden knnen, z.B. dem Elternverzeichnis."
      echo ""
      echo "Das oberste Elternobjekt ist das :DEFAULT:-Objekt."
      ;;

    GROUP* | ROLE* | USER*)
      echo "Rechte in diesem ACL-Eintrag."
      ;;

    "Clear ACL")
      echo "Entferne alle ACL-Eintrge fr dieses Objekt."
      ;;

    'Groups')
      echo "Gehe zum Gruppenmen."
      ;;

    'Roles')
      echo "Gehe zum RC-Rollenmen."
      ;;

    'FD attr')
      echo "Gehe zum File/Dir/Fifo/Symlink-Attributmen."
      ;;

    'DEV attr')
      echo "Gehe zum Device-Attributmen."
      ;;

    'IPC attr')
      echo "Gehe zum IPC-Attributmen."
      ;;

    'SCD attr')
      echo "Gehe zum SCD-Attributmen."
      ;;

    'USER attr')
      echo "Gehe zum User-Attributmen."
      ;;

    'PROCESS attr')
      echo "Gehe zum Proze-Attributmen."
      ;;

    'NETTEMP attr')
      echo "Gehe zum Netzwerk-Template-Attributmen."
      ;;

    Quit)
        echo "Beende dieses Men."
      ;;

    *)
        echo "Keine Hilfe fr $1 verfgbar!"
  esac
 } > $TMPFILE
  $DIALOG --title "$HELPTITLE" \
          --backtitle "$BACKTITLE" \
          --textbox $TMPFILE $BL $BC
#  sleep 1
}

show_help_russian () {
 {
  echo "$1"
  echo ""
  case "$1" in
      FD)
        echo File/Dir/Fifo/Symlink ACLs
        ;;
      DEV)
        echo Device ACLs
        ;;
      USER)
        echo User ACLs
        ;;
      PROCESS)
        echo Process ACLs
        ;;
      IPC)
        echo Inter Process Communication ACLs
        ;;
      SCD)
        echo System Control Data ACLs
        ;;
      NETDEV)
        echo Network Devices
        ;;
      NETTEMP_NT)
        echo Network Templates - ACL for template accesses.
        ;;
      NETTEMP)
        echo Network Templates - ACL for network object accesses.
        ;;
      NETOBJ)
        echo Network objects
        ;;
      :DEFAULT:)
        echo "$TARGET default ACL, the top parent object for all inheritance."
        ;;

    'File/Dir/Fifo/Symlink List')
      echo "Choose object from a list."
      ;;

    'Device List')
      echo "Choose object from a list."
      ;;

    'SCD List')
      echo "Choose object from a list."
      ;;

    'Network Device List')
      echo "Choose object from a list."
      ;;

    'Network Template List')
      echo "Choose object from a list."
      ;;

    "File/Dir/Fifo/Symlink" | "Device" | "SCD")
      echo "Enter object name."
      ;;

    "User" | "Process" | "IPC")
      echo "Enter object name."
      ;;

    "Follow")
      echo "Follow a symbolic link."
      ;;

    "Choose Target")
      echo "Choose target type."
      ;;

    'Add ACL Entry')
      echo "Add an ACL entry for this object."
      ;;

    "Remove Entry")
      echo "Remove an ACL entry from this object."
      ;;

    "Change TTL")
      echo "Change time-to-live for an ACL entry of this object. After this"
      echo "time the entry will be removed."
      ;;

    "Name / Rights")
      echo "Switch between subject names and rights to be shown in menu."
      ;;

    'Who has here')
      echo "Show which subjects have which effective rights to this object."
      ;;

    'Change Mask')
      echo "Change the inheritance mask of this object."
      echo ""
      echo "The mask specifies, which rights can be inherited from the object at the"
      echo "next higher level, e.g. the parent directory."
      echo ""
      echo "The highest level parent is the :DEFAULT: object."
      ;;

    GROUP* | ROLE* | USER*)
      echo "Rights in this ACL entry."
      ;;

    "Clear ACL")
      echo "Remove all ACL entries for this object."
      ;;

    'Groups')
      echo "Go to groups menu."
      ;;

    'Roles')
      echo "Go to RC roles menu."
      ;;

    'FD attr')
      echo "Go to File/Dir/Fifo/Symlink attribute menu."
      ;;

    'DEV attr')
      echo "Go to Device attribute menu."
      ;;

    'IPC attr')
      echo "Go to IPC attribute menu."
      ;;

    'SCD attr')
      echo "Go to SCD attribute menu."
      ;;

    'USER attr')
      echo "Go to User attribute menu."
      ;;

    'PROCESS attr')
      echo "Go to Process attribute menu."
      ;;

    'NETTEMP attr')
      echo "Go to Network Template attribute menu."
      ;;

    Quit)
        echo "Quit this menu."
      ;;

    *)
        echo "No help for $1 available!"
  esac
 } > $TMPFILE
  $DIALOG --title "$HELPTITLE" \
          --backtitle "$BACKTITLE" \
          --textbox $TMPFILE $BL $BC
#  sleep 1
}

get_attributes () {
 case $TARGET in
  "FD")
    ALLREQ=`$RSBACPATH""attr_get_file_dir -n FD`
    if test -n "$OBJECT"
    then
      if test "$OBJECT" = ":DEFAULT:"
        then TYPE=FD
      elif test -L "$OBJECT"
        then TYPE=SYMLINK
             SYMLINK="`ls -l \"$OBJECT\"|cut -d '>' -f 2|cut -c 2-`"
             SUBTYPE="SYMLINK"
      elif test -f "$OBJECT"
        then TYPE=FILE ; SUBTYPE=FILE
      elif test -b "$OBJECT"
        then TYPE=FILE ; SUBTYPE=BLOCK
      elif test -c "$OBJECT"
        then TYPE=FILE ; SUBTYPE=CHAR
      elif test -p "$OBJECT"
        then TYPE=FIFO ; SUBTYPE=FIFO
      elif test -d "$OBJECT"
        then TYPE=DIR ; SUBTYPE=DIR
             LASTDIR=`( cd "$OBJECT" && pwd ) || echo "$OBJECT"`
             OBJECT=$LASTDIR
             if test -n "$RSBACLOGFILE"
             then
               echo "cd `pwd`" >>"$RSBACLOGFILE"
             fi
      else TYPE=NONE
      fi
    else
      TYPE=NONE
    fi
    ;;

  "DEV")
    ALLREQ=`$RSBACPATH""attr_get_file_dir -n DEV`
    if test "$OBJECT" = ":DEFAULT:"
    then
      TYPE=DEV ; SUBTYPE=BLOCK
    elif test -L "$OBJECT"
      then TYPE=NONE
           SYMLINK="`ls -l \"$OBJECT\"|cut -d '>' -f 2|cut -c 2-`"
           SUBTYPE="SYMLINK"
    elif test -b "$OBJECT"
    then
      TYPE=DEV ; SUBTYPE=BLOCK
    elif test -c "$OBJECT"
    then
      TYPE=DEV ; SUBTYPE=CHAR
    elif test -d "$OBJECT"
    then
      TYPE=NONE ; SUBTYPE=DIR
      LASTDIR=`( cd "$OBJECT" && pwd ) || echo "$OBJECT"`
      OBJECT=$LASTDIR
    else
      TYPE=NONE ; SUBTYPE=NONE
    fi
    ;;
  NETDEV)
    ALLREQ=`$RSBACPATH""attr_get_net -n $TARGET`
    if test "$OBJECT" != "" 
    then TYPE=$TARGET ; SUBTYPE=$TARGET
    else TYPE=NONE
    fi
    ;;
  NETTEMP_NT)
    ALLREQ=`$RSBACPATH""attr_get_net -n NETTEMP`
    if test "$OBJECT" != "" 
    then TYPE=$TARGET ; SUBTYPE=$TARGET
    else TYPE=NONE
    fi
    ;;
  NET*)
    ALLREQ=`$RSBACPATH""attr_get_net -n NETOBJ`
    if test "$OBJECT" != "" 
    then TYPE=$TARGET ; SUBTYPE=$TARGET
    else TYPE=NONE
    fi
    ;;
  *)
    ALLREQ=`$RSBACPATH""attr_get_file_dir -n $TARGET`
    if test "$OBJECT" != "" 
    then TYPE=$TARGET ; SUBTYPE=$TARGET
    else TYPE=NONE
    fi
    ;;
 esac
}


onoff () {
   if test "$1" = "$2"
     then echo on
   else echo off
   fi
}

onoffb () {
   if test "$1" = "1"
     then echo on
   else echo off
   fi
}

list_item () {
   if test -L "$1"
   then echo $1 "SYMLINK->`ls -l \"$1\"|cut -d '>' -f 2|cut -c 2-`"
   elif test -d "$1"
   then echo $1 DIR
   elif test -f "$1" -o -b "$1" -o -c "$1"
   then echo $1 FILE
   elif test -p "$1"
   then echo $1 FIFO
   elif test "$1" = ":DEFAULT:"
   then echo $1 FILE
   else echo $1 NONE
   fi
}

list_dev_item () {
   if test -L "$1"
   then echo $1 "SYMLINK->`ls -l \"$1\"|cut -d '>' -f 2|cut -c 2-`"
   elif test -b "$1"
   then echo $1 BLOCK
   elif test -c "$1"
   then echo $1 CHAR
   elif test -d "$1"
   then echo $1 DIR
   elif test "$1" = ":DEFAULT:"
   then echo $1 DEV
   else echo $1 NONE
   fi
}

get_vname () {
  if test "$TYPE" = "NONE"
    then echo " "
         return
  fi
  if test -z "$2"
    then echo "N/A"
         return
  fi

  case $1 in
    onoff)
      case $2 in
        1) echo On
          ;;
        *) echo Off
          ;;
      esac 
      ;;
    *) echo ERROR!
      ;;
  esac
}

full_name () {
  if test "$1" = ""
  then echo " "
  else echo `$RSBACPATH""attr_get_user $1 full_name`
  fi
}

get_uid () {
  if test "$1" = ""
  then echo " "
  else echo `$RSBACPATH""attr_get_user $1 user_nr`
  fi
}

get_name () {
  if test "$1" = ""
  then echo " "
  else echo `$RSBACPATH""attr_get_user $1 user_name`
  fi
}

split_subj () {
  echo $1|tr '_' ' '
}

gen_tlist () {
  if test "$TYPE" != "NONE"
  then
    if $RSBACPATH""acl_tlist -s $TYPE "$OBJECT" > $TMPFILE
    then
      TMP=`cat $TMPFILE | sort | tr ' ' '_'`
      if test "$SHOW" = Rights
      then
        for i in $TMP
        do
          echo $i `$RSBACPATH""acl_rights -sd --\`split_subj $i\` $TYPE "$OBJECT"`
        done
      else
        for i in $TMP
        do
          TMP2=`echo $i|cut -d '_' -f 2`
          case $i in
            GROUP_*)
              if $RSBACPATH""acl_group -s get_group_entry $TMP2 >$TMPFILE 2>/dev/null
              then TMP3=`cat $TMPFILE | tr ' ' '_'`
              else TMP3='(private)'
              fi
              echo $i $TMP3
              ;;
            ROLE_*)
              if $RSBACPATH""rc_get_item ROLE $TMP2 name > $TMPFILE 2>/dev/null
              then
                echo $i `cat $TMPFILE | tr ' ' '_'`
              else
                echo $i '(unknown)'
              fi
              ;;
            USER_*)
              echo $i `$RSBACPATH""attr_get_user $TMP2 user_name`
              ;;
            *)
              ;;
          esac
        done
      fi
    fi
  fi
}

gen_subj_list () {
  if test "$TYPE" != "NONE"
  then
    case $1 in
      GROUP)
        TMP=`$RSBACPATH""acl_group -gsn list_groups`
        for i in $TMP
        do
          TMP2=`$RSBACPATH""acl_group -s get_group_entry $i|tr ' ' '_'`
          echo $i $TMP2
        done
        ;;
      ROLE)
        rc_get_item list_roles
        ;;
      USER)
        ${RSBACPATH}attr_get_user -bl
        ;;
      *)
        echo ERROR !
        ;;
    esac
  fi
}

gen_right_list () {
    ALLREQUESTS=`$RSBACPATH""acl_rights -N $TARGET $OBJECT`
    TMP=`${RSBACPATH}acl_rights -sdp --\`split_subj $1\` $TYPE $OBJECT`
    for i in $ALLREQUESTS
    do
      if echo $TMP | grep -q $i
      then
        echo $i on on
      else
        echo $i off off
      fi
    done
}

check_rights () {
  if $RSBACPATH""acl_rights -sd --`split_subj $1` $TYPE $OBJECT > $TMPFILE 2>$TMPFILETWO
  then
    RIGHTBITS=`cat $TMPFILE`
    if $DIALOG --title "Rights for $1 to $TYPE $OBJECT" \
              --backtitle "$BACKTITLE" \
              --checklist "Bits: $RIGHTBITS" $BL $BC $MAXLINES \
                `gen_right_list $1` \
                '--------------' '-----------------' off \
                UA 'Unset ALL' off \
                A  'Set ALL' off \
                R  'Set Read Requests' off \
                W  'Set Write Requests' off \
                SY 'Set System R.' off \
                SE 'Set Security R.' off \
                S  'Set ACL Special R.' off \
      2>$TMPFILE
    then TMP=`cat $TMPFILE|tr -d '"'`
         if $RSBACPATH""acl_grant -s `split_subj $1` $TMP $TYPE "$OBJECT" &>$TMPFILE
         then
           if test -n "$RSBACLOGFILE"
           then
             echo $RSBACPATH""acl_grant -s `split_subj $1` $TMP $TYPE \"$OBJECT\" >>"$RSBACLOGFILE"
           fi
         else
             $DIALOG --title "$ERRTITLE" \
                    --backtitle "$BACKTITLE" \
                    --msgbox "`head -n 1 $TMPFILE`" $BL $BC
             continue
         fi
    fi
  else
    $DIALOG --title "$ERRTITLE" \
           --backtitle "$BACKTITLE" \
           --msgbox "`head -n 1 $TMPFILETWO`" $BL $BC
  fi
  rm $TMPFILETWO
}

show_mask () {
  if test "$TYPE" != "NONE"
  then
    if test "$OBJECT" = ":DEFAULT:"
    then
        echo '(none)'
    else
        $RSBACPATH""acl_mask $TYPE "$OBJECT" | cut -d ':' -f 2 | cut -c2-
    fi
  else
    echo '(none)'
  fi
}

gen_mask_right_list () {
    TMP=`${RSBACPATH}acl_mask -p $TYPE "$OBJECT" | grep -v 000`
    for i in $ALLREQ
    do
      if echo $TMP | grep -q $i
      then
        echo $i on on
      else
        echo $i off off
      fi
    done
}

check_mask_rights () {
  RIGHTBITS=`$RSBACPATH""acl_mask $TYPE $OBJECT`
  if $DIALOG --title "Inheritance Mask for $TYPE $OBJECT" \
            --backtitle "$BACKTITLE" \
            --checklist "$RIGHTBITS" $BL $BC $MAXLINES \
              `gen_mask_right_list` \
              '--------------' '-----------------' off \
              UA 'Unset ALL' off \
              A  'Set ALL' off \
              R  'Set Read Requests' off \
              W  'Set Write Requests' off \
              SY 'Set System R.' off \
              SE 'Set Security R.' off \
              S  'Set ACL Special R.' off \
    2>$TMPFILE
  then TMP=`cat $TMPFILE|tr -d '"'`
       if $RSBACPATH""acl_mask -s $TMP $TYPE $OBJECT &>$TMPFILE
       then
         if test -n "$RSBACLOGFILE"
         then
           echo $RSBACPATH""acl_mask -s $TMP $TYPE $OBJECT >>"$RSBACLOGFILE"
         fi
       else
           $DIALOG --title "$ERRTITLE" \
                  --backtitle "$BACKTITLE" \
                  --msgbox "`head -n 1 $TMPFILE`" $BL $BC
           continue
       fi
  fi
}

gen_menu_choose_items () {
  case $TARGET in
      FD)
        case $1 in
          1)
            echo File/Dir/Fifo/Symlink List
          ;;
          2)
            echo Choose from `name_print "$LASTDIR"`
          ;;
          3)
            echo File/Dir/Fifo/Symlink
          ;;
          4)
            echo `name_print "$OBJECT / $SUBTYPE"`
          ;;
          *)
          ;;
        esac
        ;;
      DEV)
        case $1 in
          1)
            echo Device List
          ;;
          2)
            echo Choose from `name_print "$LASTDIR"`
          ;;
          3)
            echo Device
          ;;
          4)
            echo `name_print "$OBJECT / $SUBTYPE"`
          ;;
          *)
          ;;
        esac
        ;;
      USER)
        case $1 in
          1)
            echo User
          ;;
          2)
            echo :DEFAULT: only
          ;;
          3)
            echo User
          ;;
          4)
            echo `name_print "$OBJECT"`
          ;;
          *)
          ;;
        esac
        ;;
      PROCESS)
        case $1 in
          1)
            echo Process
          ;;
          2)
            echo :DEFAULT: only
          ;;
          3)
            echo Process
          ;;
          4)
            echo `name_print "$OBJECT"`
          ;;
          *)
          ;;
        esac
        ;;
      IPC)
        case $1 in
          1)
            echo IPC
          ;;
          2)
            echo :DEFAULT: only
          ;;
          3)
            echo IPC
          ;;
          4)
            echo `name_print "$OBJECT"`
          ;;
          *)
          ;;
        esac
        ;;
      SCD)
        case $1 in
          1)
            echo SCD List
          ;;
          2)
            echo Choose from list
          ;;
          3)
            echo SCD
          ;;
          4)
            echo `name_print "$OBJECT"`
          ;;
          *)
          ;;
        esac
        ;;
      NETDEV)
        case $1 in
          1)
            echo Network Device List
          ;;
          2)
            echo Choose from list
          ;;
          3)
            echo Network Device
          ;;
          4)
            echo `name_print "$OBJECT"`
          ;;
          *)
          ;;
        esac
        ;;
      NETTEMP | NETTEMP_NT)
        case $1 in
          1)
            echo Network Template List
          ;;
          2)
            echo Choose from list
          ;;
          3)
            echo Network Template
          ;;
          4)
            echo `name_print "$OBJECT"`
          ;;
          *)
          ;;
        esac
        ;;
      NETOBJ)
        case $1 in
          1)
            echo Network Object List
          ;;
          2)
            echo Choose from list
          ;;
          3)
            echo Network Object
          ;;
          4)
            echo `name_print "$OBJECT"`
          ;;
          *)
          ;;
        esac
        ;;
      *)
        ;;
  esac
}

get_target_name () {
  case $1 in
      FD)
        echo File/Dir/Fifo/Symlink
        ;;
      DEV)
        echo Device
        ;;
      USER)
        echo User
        ;;
      PROCESS)
        echo Process
        ;;
      IPC)
        echo Inter Process Communication
        ;;
      SCD)
        echo System Control Data
        ;;
      NETDEV)
        echo Network Device
        ;;
      NETTEMP_NT)
        echo Network Template for template accesses
        ;;
      NETTEMP)
        echo Network Template for netobj accesses
        ;;
      NETOBJ)
        echo Network Object
        ;;
      *)
        echo " "
        ;;
  esac
}

choose_target () {
    while $DIALOG --title "$TITLE" \
              --backtitle "$BACKTITLE" \
              --help-button --default-item "$TARGET" \
              --menu "$1" $BL $BC 10 \
              FD "`get_target_name FD`" \
              DEV "`get_target_name DEV`" \
              USER "`get_target_name USER`" \
              PROCESS "`get_target_name PROCESS`" \
              IPC "`get_target_name IPC`" \
              SCD "`get_target_name SCD`" \
              NETDEV "`get_target_name NETDEV`" \
              NETTEMP_NT "`get_target_name NETTEMP_NT`" \
              NETTEMP "`get_target_name NETTEMP`" \
              NETOBJ "`get_target_name NETOBJ`" \
           2>$TMPFILE
    do
       TARGET=`cat $TMPFILE`
       case $TARGET in
         HELP*)
           show_help "${TARGET:5}"
           TARGET="${TARGET:5}"
           ;;
         FD)
           TYPE=NONE
           OBJECT=":DEFAULT:"
           break
           ;;
         DEV)
           TYPE=$TARGET
           LASTDIR=/dev
           OBJECT=":DEFAULT:"
           break
           ;;
         IPC|SCD|USER|PROCESS|NETDEV|NETTEMP_NT|NETOBJ)
           TYPE=$TARGET
           OBJECT=":DEFAULT:"
           break
           ;;
         NETTEMP)
           TYPE=$TARGET
           OBJECT=
           break
           ;;
       esac
    done
}

declare -i MAXNAMELEN=$BC-34
name_print () {
  if test ${#1} -gt $MAXNAMELEN
  then
    declare -i START=${#1}-$MAXNAMELEN
    echo "$1" | cut -c$START-${#1}
  else
    echo "$1"
  fi
}

gen_follow_symlink () {
    case $1 in
      1)
        if test "$TYPE" = "SYMLINK" -o "$SUBTYPE" = "SYMLINK"
        then
          echo 'Follow'
        fi
        ;;
      2)
        if test "$TYPE" = "SYMLINK" -o "$SUBTYPE" = "SYMLINK"
        then
          echo "`name_print \"$SYMLINK\"`"
        fi
        ;;
    esac
}

###################### Menu #################

if test -n "$RSBACLOGFILE"
then
  {
    echo ""
    echo "# $0 start `date`"
    echo "cd `pwd`"
  } >>"$RSBACLOGFILE"
fi

case $1 in
  FD|FILE|DIR|FIFO|SYMLINK)
    TARGET=FD
    TYPE=NONE
    if test -n "$2"
    then OBJECT="$2"
    else OBJECT=":DEFAULT:"
    fi
    ;;
  DEV|SCD)
    TARGET=$1
    TYPE=$1
    LASTDIR=/dev
    if test -n "$2"
    then OBJECT="$2"
    else OBJECT=":DEFAULT:"
    fi
    ;;
  IPC|USER|PROCESS)
    TARGET=$1
    TYPE=$1
    if test -n "$2"
    then OBJECT="$2"
    else OBJECT=":DEFAULT:"
    fi
    OBJECT=":DEFAULT:"
    ;;
  NETDEV|NETTEMP_NT|NETOBJ)
    TARGET=$1
    TYPE=$1
    if test -n "$2"
    then OBJECT="$2"
    else OBJECT=":DEFAULT:"
    fi
    ;;
  NETTEMP)
    TARGET=$1
    TYPE=$1
    if test -n "$2"
    then OBJECT="$2"
    else OBJECT=
    fi
    ;;
  "-h" | "--help")
    echo Use: $0 '[target-type [object-name [Rights|Name]]]'
    exit
    ;;
   *)
    choose_target
    if test -z "$TARGET"
    then
      test -e $TMPFILE && rm $TMPFILE
      test -e $TMPFILETWO && rm $TMPFILETWO
      exit
    fi
    ;;
esac

get_attributes "$OBJECT"

if test "$3" = "Rights" -o "$3" = "rights"
then SHOW=Rights
else SHOW=Name
fi

while true ; do \
  if ! \
  $DIALOG --title "$TITLE" \
         --backtitle "$BACKTITLE" \
         --help-button --default-item "$SELECTED" \
         --menu "Main Menu" $BL $BC $MAXLINES \
                "`gen_menu_choose_items 1`" "`gen_menu_choose_items 2`" \
                "`gen_menu_choose_items 3`" "`gen_menu_choose_items 4`" \
                `gen_follow_symlink 1` `gen_follow_symlink 2` \
                "Choose Target" "$TARGET" \
                "-------------" "" \
                "Add ACL Entry" "Add group, role or user entry" \
                "Remove Entry" "" \
                "Change TTL" "Change time-to-live for an entry" \
                "Name / Rights" "$SHOW" \
                "Who has here" "" \
                "Change Mask" "`show_mask`" \
                "-------------" "" \
                `gen_tlist` \
                "-------------" "" \
                "Clear ACL" "" \
                "Groups" "Go to ACL groups menu" \
                "Roles" "Go to RC roles menu" \
                "$TARGET attr" "Go to $TARGET general attributes" \
                "Quit" "" \
         2>$TMPFILE
   then
     rm $TMPFILE
     test -e $TMPFILETWO && rm $TMPFILETWO
     exit
  fi

  SELECTED=`cat $TMPFILE`
  case $SELECTED in
    HELP*)
      show_help "${SELECTED:5}"
      SELECTED="${SELECTED:5}"
      ;;
    'File/Dir/Fifo/Symlink List')
        if test ! -d $LASTDIR
        then LASTDIR='/'
        fi
        TMP=`ls -1ad "$LASTDIR"/* "$LASTDIR"/.*`
        while $DIALOG --title "$TITLE" \
                     --backtitle "$BACKTITLE" \
                     --default-item "$OBJECT" \
                     --menu "File/Dir/Fifo Name (choose cancel for $OBJECT)" $BL $BC $MAXLINES \
                         ':DEFAULT:' "Default ACL" \
                         `for i in $TMP ; do list_item "$i" ; done` \
           2>$TMPFILE
        do OBJECT=`cat $TMPFILE`
           get_attributes
           TMP=`ls -1ad "$LASTDIR"/* "$LASTDIR"/.*|tr '*' ' '`
           if test $TYPE != "DIR"
           then break
           fi
        done
      ;;

    'Device List')
        if test ! -d $LASTDIR
        then LASTDIR='/dev'
        fi
        TMP=`ls -1ad "$LASTDIR"/* "$LASTDIR"/.*`
        if $DIALOG --title "$TITLE" \
                  --backtitle "$BACKTITLE" \
                  --default-item "$OBJECT" \
                  --menu "Device Name (choose cancel for $OBJECT)" $BL $BC $MAXLINES \
                         ':DEFAULT:' "Default ACL" \
                         `for i in $TMP ; do list_dev_item "$i" ; done` \
           2>$TMPFILE
        then OBJECT=`cat $TMPFILE`
           get_attributes
           TMP=`ls -1ad "$LASTDIR"/* "$LASTDIR"/.*`
           if test ! -d "$OBJECT"
           then break
           fi
        fi
      ;;

    'SCD List')
        TMP=`$RSBACPATH""acl_rights -n`
        if $DIALOG --title "$TITLE" \
                  --backtitle "$BACKTITLE" \
                  --default-item "$OBJECT" \
                  --menu "Device Name" $BL $BC $MAXLINES \
                         ':DEFAULT:' "Default ACL" \
                         `for i in $TMP ; do echo "$i" "-" ; done` \
           2>$TMPFILE
        then OBJECT=`cat $TMPFILE`
           get_attributes
        fi
      ;;

    'Network Device List')
        TMP=`cat /proc/net/dev|grep ':'|cut -d ':' -f 1`
        if $DIALOG --title "$TITLE" \
                  --backtitle "$BACKTITLE" \
                  --default-item "$OBJECT" \
                  --menu "Network Device Name" $BL $BC $MAXLINES \
                         ':DEFAULT:' "Default ACL" \
                         `for i in $TMP ; do echo $i "-" ; done` \
           2>$TMPFILE
        then OBJECT=`cat $TMPFILE`
           get_attributes
        fi
      ;;

    'Network Template List')
        if $DIALOG --title "$TITLE" \
                  --backtitle "$BACKTITLE" \
                  --default-item "$OBJECT" \
                  --menu "Network Template Number" $BL $BC $MAXLINES \
                         ':DEFAULT:' "Default ACL" \
                         `$RSBACPATH""net_temp list_temp_names` \
           2>$TMPFILE
        then OBJECT=`cat $TMPFILE`
           get_attributes
        fi
      ;;

    'Network Object List')
      ;;

    "File/Dir/Fifo/Symlink" | "Device" | "SCD" | "Network Device" | "Network Template" \
      | "Network Object")
        if $DIALOG --title "$TITLE" \
                  --backtitle "$BACKTITLE" \
                  --inputbox "Enter `get_target_name $TARGET`" $BL $BC "$OBJECT" \
           2>$TMPFILE
        then OBJECT=`cat $TMPFILE`
             get_attributes
        fi
      ;;

    "User" | "Process" | "IPC")
        OBJECT=:DEFAULT:
        get_attributes
      ;;

    "Follow")
        OBJECT="$SYMLINK"
        get_attributes
      ;;

    "Choose Target")
      choose_target
      ;;

    'Add ACL Entry')
        if test "$TYPE" != "NONE"
        then \
          while $DIALOG --title "$TITLE" \
                    --backtitle "$BACKTITLE" \
                    --default-item "$STYPE" \
                    --menu "Choose new entry's subject type" $BL $BC 3 \
                                GROUP "ACL group" \
                                ROLE "RC role" \
                                USER "Normal user" \
             2>$TMPFILE
          do STYPE=`cat $TMPFILE`
               if $DIALOG --title "$TITLE" \
                         --backtitle "$BACKTITLE" \
                         --default-item "$SUBJ" \
                         --menu "Choose $STYPE" $BL $BC $MAXLINES \
                                     `gen_subj_list $STYPE` \
                  2>$TMPFILE
               then SUBJ=`cat $TMPFILE`
                     if $RSBACPATH""acl_grant $STYPE $SUBJ $TYPE "$OBJECT" &>$TMPFILE
                     then 
                       if test -n "$RSBACLOGFILE"
                       then
                         echo $RSBACPATH""acl_grant $STYPE $SUBJ $TYPE \"$OBJECT\" >>"$RSBACLOGFILE"
                       fi
                       check_rights ${STYPE}_${SUBJ}
                     else
                       $DIALOG --title "$ERRTITLE" \
                              --backtitle "$BACKTITLE" \
                              --msgbox "`head -n 1 $TMPFILE`" $BL $BC
                     fi
                     break
               fi
          done
        else
                 $DIALOG --title "$ERRTITLE" \
                        --backtitle "$BACKTITLE" \
                        --msgbox "Add ACL Entry: No object specified!" 5 $BC
        fi
      ;;

    "Remove Entry")
        if test "$TYPE" != "NONE"
        then \
          while $DIALOG --title "$TITLE" \
                    --backtitle "$BACKTITLE" \
                    --default-item "$TMP" \
                    --menu "Choose entry to delete" $BL $BC $MAXLINES \
                    `gen_tlist` \
             2>$TMPFILE
          do TMP=`cat $TMPFILE`
             if $RSBACPATH""acl_grant -m `split_subj $TMP` $TYPE "$OBJECT" &>$TMPFILE
             then
               if test -n "$RSBACLOGFILE"
               then
                 echo $RSBACPATH""acl_grant -m `split_subj $TMP` $TYPE \"$OBJECT\" >>"$RSBACLOGFILE"
               fi
             else
               $DIALOG --title "$ERRTITLE" \
                       --backtitle "$BACKTITLE" \
                       --msgbox "`head -n 1 $TMPFILE`" $BL $BC
             fi
          done
        else
                 $DIALOG --title "$ERRTITLE" \
                        --backtitle "$BACKTITLE" \
                        --msgbox "Remove Entry: No object specified!" 5 $BC
        fi
      ;;

    "Change TTL")
        if test "$TYPE" != "NONE"
        then \
          while $DIALOG --title "$TITLE" \
                    --backtitle "$BACKTITLE" \
                    --default-item "$TMP" \
                    --menu "Choose entry to set time-to-live" $BL $BC $MAXLINES \
                    `gen_tlist` \
             2>$TMPFILE
          do TMP=`cat $TMPFILE`
            TTL=`echo $TMP|cut -d ':' -f 2|cut -d 's' -f 1`
            if test "$TTL" = "$TMP" -o -z "$TTL"
            then TTL=0
            fi
            if $DIALOG --title "$TITLE" \
                       --backtitle "$BACKTITLE" \
                       --inputbox "Enter TTL in seconds for $TMP (0 for unlimited)" $BL $BC "$TTL" \
              2>$TMPFILE
            then TTL=`cat $TMPFILE`
              if $RSBACPATH""acl_grant -t $TTL `split_subj $TMP` $TYPE "$OBJECT" &>$TMPFILE
              then
                if test -n "$RSBACLOGFILE"
                then
                  echo $RSBACPATH""acl_grant -t $TTL `split_subj $TMP` $TYPE \"$OBJECT\" >>"$RSBACLOGFILE"
                fi
              else
                $DIALOG --title "$ERRTITLE" \
                        --backtitle "$BACKTITLE" \
                        --msgbox "`head -n 1 $TMPFILE`" $BL $BC
              fi
            fi
          done
        else
                 $DIALOG --title "$ERRTITLE" \
                        --backtitle "$BACKTITLE" \
                        --msgbox "Change TTL: No object specified!" 5 $BC
        fi
      ;;

    "Name / Rights")
        if test "$SHOW" = Rights
        then SHOW=Name
        else SHOW=Rights
        fi
      ;;

    'Who has here')
        if test "$TYPE" != "NONE"
        then \
          while $DIALOG --title "$TITLE" \
                    --backtitle "$BACKTITLE" \
                    --default-item "$STYPE" \
                    --menu "Who has rights to $TYPE $OBJECT: Choose subject type" $BL $BC 4 \
                                ALL "All types" \
                                GROUP "ACL group" \
                                ROLE "RC role" \
                                USER "Normal user" \
             2>$TMPFILE
          do
            STYPE=`cat $TMPFILE`
            case $STYPE in
              GROUP)
                TMP=`$RSBACPATH""acl_group -gsn list_groups`
                for i in $TMP
                do
                  TMP2=`$RSBACPATH""acl_rights -sg $i $TYPE $OBJECT`
                  echo GROUP_${i} $TMP2
                done > $TMPFILETWO
                ;;
              ROLE)
                TMP=`rc_get_item list_role_nr`
                for i in $TMP
                do
                  TMP2=`$RSBACPATH""acl_rights -sl $i $TYPE $OBJECT`
                  echo ROLE_${i} $TMP2
                done > $TMPFILETWO
                ;;
              USER)
                TMP=`${RSBACPATH}attr_get_user -nl|sort -n`
                for i in $TMP
                do
                  TMP2=`$RSBACPATH""acl_rights -su $i $TYPE $OBJECT`
                  echo USER_${i} $TMP2
                done > $TMPFILETWO
                ;;
              ALL)
                TMP=`$RSBACPATH""acl_group -gsn list_groups`
                for i in $TMP
                do
                  TMP2=`$RSBACPATH""acl_rights -sg $i $TYPE $OBJECT`
                  echo GROUP_${i} $TMP2
                done > $TMPFILETWO
                TMP=`rc_get_item list_role_nr`
                for i in $TMP
                do
                  TMP2=`$RSBACPATH""acl_rights -sl $i $TYPE $OBJECT`
                  echo ROLE_${i} $TMP2
                done >> $TMPFILETWO
                TMP=`${RSBACPATH}attr_get_user -nl|sort -n`
                for i in $TMP
                do
                  TMP2=`$RSBACPATH""acl_rights -su $i $TYPE $OBJECT`
                  echo USER_${i} $TMP2
                done >> $TMPFILETWO
                ;;
            esac
            while $DIALOG --title "$TITLE" \
                      --backtitle "$BACKTITLE" \
                      --default-item "$SUBJ" \
                      --menu "Who has rights to $TYPE $OBJECT" $BL $BC $MAXLINES \
                             `cat $TMPFILETWO | grep -v "000000000000000000000000000000000000000000000000000"` \
                  2>$TMPFILE
            do SUBJ=`cat $TMPFILE`
               TMP=`echo $SUBJ|cut -d '_' -f 2`
               case $SUBJ in
                 GROUP_*)
                   if $RSBACPATH""acl_group -s get_group_entry $TMP >$TMPFILE 2>/dev/null
                   then TMP="$SUBJ / `cat $TMPFILE | tr ' ' '_'`"
                   else TMP="$SUBJ / '(private)'"
                   fi
                   ;;
                 ROLE_*)
                   if $RSBACPATH""rc_get_item ROLE $TMP name > $TMPFILE 2>/dev/null
                   then
                     TMP="$SUBJ / `cat $TMPFILE | tr ' ' '_'`"
                   else
                     TMP="$SUBJ / '(unknown)'"
                   fi
                   ;;
                 USER_*)
                   TMP="$SUBJ / `$RSBACPATH""attr_get_user $TMP user_name`"
                   ;;
               esac
               echo "$TMP" rights to $TYPE $OBJECT >$TMPFILE
               echo --------------------------------------- >>$TMPFILE
               if $RSBACPATH""acl_rights -sp --`split_subj $SUBJ` $TYPE $OBJECT >>$TMPFILE
               then 
                 $DIALOG --title "$TITLE" \
                        --backtitle "$BACKTITLE" \
                        --textbox $TMPFILE $BL $BC
               fi
            done
            rm $TMPFILETWO
          done
        else
                 $DIALOG --title "$ERRTITLE" \
                        --backtitle "$BACKTITLE" \
                        --msgbox "Who has here: No object specified!" 5 $BC
        fi
      ;;

    'Change Mask')
      check_mask_rights
      ;;

    GROUP* | ROLE* | USER*)
      check_rights $SELECTED
      ;;

    "Clear ACL")
      if test "$TYPE" != "NONE"
      then
        if $DIALOG --title "$TITLE" \
                  --backtitle "$BACKTITLE" \
                  --yesno "Remove all ACL entries for $TYPE $OBJECT?" 6 $BC \
           2>$TMPFILE
        then
          TMP=`$RSBACPATH""acl_tlist -s $TYPE "$OBJECT" | tr ' ' '_'`
          for i in $TMP
          do
            $RSBACPATH""acl_grant -m `split_subj $i` $TYPE "$OBJECT"
            if test -n "$RSBACLOGFILE"
            then
              echo $RSBACPATH""acl_grant -m `split_subj $i` $TYPE \"$OBJECT\" >>"$RSBACLOGFILE"
            fi
          done
        fi
      fi
      ;;

    'Groups')
      $RSBACPATH""rsbac_acl_group_menu
      ;;

    'Roles')
      $RSBACPATH""rsbac_rc_role_menu
      ;;

    'FD attr')
      $RSBACPATH""rsbac_fd_menu "$OBJECT"
      ;;

    'DEV attr')
      $RSBACPATH""rsbac_dev_menu "$OBJECT"
      ;;

    'IPC attr')
      $RSBACPATH""rsbac_ipc_menu
      ;;

    'SCD attr')
      $RSBACPATH""rsbac_scd_menu "$OBJECT"
      ;;

    'USER attr')
      $RSBACPATH""rsbac_user_menu
      ;;

    'PROCESS attr')
      $RSBACPATH""rsbac_process_menu
      ;;

    'NETDEV attr')
      $RSBACPATH""rsbac_netdev_menu $OBJECT
      ;;

    'NETTEMP attr'|'NETTEMP_NT attr')
      $RSBACPATH""rsbac_nettemp_menu $OBJECT
      get_attributes "$OBJECT"
      ;;

    'NETOBJ attr')
      $RSBACPATH""rsbac_netobj_menu $OBJECT
      ;;

    Quit)
        rm $TMPFILE
        test -e $TMPFILETWO && rm $TMPFILETWO
        exit
      ;;

    *)
        $DIALOG --title "$ERRTITLE" \
               --backtitle "$BACKTITLE" \
               --msgbox "Main Menu: Selection Error!" 5 $BC
  esac
# sleep 2
done
