#!/bin/bash
# meta: proxy=True
# meta: preconfig=../../DPM-config
##############################################################################
# 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.
##############################################################################
#
# AUTHORS: Dimitar Shiyachki <Dimitar.Shiyachki@cern.ch>
#
##############################################################################

SCRIPTDIR="$(dirname "$(readlink -f ${BASH_SOURCE})")"
source "${SCRIPTDIR}/../../Macros"

PROXY_NEEDED

TEST_DIR=d`date +%s%N`
TEST_SUBDIR=sd`date +%s%N`
TEMP_FILE=/tmp/_dpm_test_temp`date +%s%N`
TEST_FILE=/tmp/tf`date +%s%N`

if [ -z "$X509_USER_PROXY" ]; then
  export X509_USER_PROXY=`voms-proxy-info -p`
fi

processOutput ()
{
   L_COMMAND_NAME=$1
   L_COMMAND_RET=$2
   L_CHECK_FOR=$3
   L_ERROR_MSG=$4
   L_OUTPUT_FILE=$5
   L_ERROR_MSG_2=$6

   if [ $L_COMMAND_RET -ne 0 ]; then
      echo -n "   $L_COMMAND_NAME exited with error."
      if grep -q "$L_ERROR_MSG" "$L_OUTPUT_FILE" || \
         ( [ -n "$L_ERROR_MSG_2" ] && grep -q "$L_ERROR_MSG_2" "$L_OUTPUT_FILE" ); then
         if [ "x$L_CHECK_FOR" == "xFOR_ALLOW" ]; then
            echo "Access was denied. FAIL."
            cleanup
            TEST_FAILED " Access was denied. FAIL."
         else
            echo " Access was denied. OK."
         fi
      else
         echo "Unexpected error message. FAIL."
	 cat $L_OUTPUT_FILE 
         cleanup
         TEST_FAILED "Unexpected error message. FAIL."
      fi
   else
      if [ "x$L_CHECK_FOR" == "xFOR_ALLOW" ]; then
         echo "   $L_COMMAND_NAME exited with no error. Access was allowed. OK."
      else
         echo "   $L_COMMAND_NAME exited with no error. FAIL."
         cleanup
         TEST_FAILED "   $L_COMMAND_NAME exited with no error. FAIL."
      fi
   fi
}

checkServices ()
{
   echo
   echo " * Checking DPNS access"
   dpns-ls $TEST_DIR >$TEMP_FILE 2>&1
   processOutput "dpns-ls" $? "$1" "Permission denied" "$TEMP_FILE"

   echo
   echo " * Checking SRMv1 access"
   lcg-cp -v -b -D srmv2 srm://$DPM_HOST:8446/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/bash_copy_1 \
                         $TEST_FILE >$TEMP_FILE 2>&1
   processOutput "lcg-cp" $? "$1" "Could not get user mapping" "$TEMP_FILE"

   echo
   echo " * Checking SRMv2 access"
   lcg-cp -v -b -D srmv2 srm://$DPM_HOST:8446/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/bash_copy_1 \
                         $TEST_FILE >$TEMP_FILE 2>&1
   processOutput "lcg-cp" $? "$1" "Could not get user mapping" "$TEMP_FILE"

   echo
   echo " * Checking RFIO access"
   rfcp $DPNS_HOME/$TEST_DIR/bash_copy_1 $TEST_FILE >$TEMP_FILE 2>&1
   processOutput "rfcp" $? "$1" "Permission denied" "$TEMP_FILE"

   echo
   echo " * Checking DPM-GSIFTP access"
   globus-url-copy $GSI_TURL file://$TEST_FILE >$TEMP_FILE 2>&1
   processOutput "globus-url-copy" $? "$1" "Could not get virtual id" "$TEMP_FILE"
}

checkDirectoryAccess ()
{
   L_CHECK_TYPE=$1
   L_LCG_CP_FILENAME=$2
   L_RFIO_CP_FILENAME=$3
   L_DPNS_DIRECTORY=$4

   echo
   echo " * Copying new file using lcg-cp(gridftp)"
   lcg-cp -v -b -D srmv2 /bin/bash \
          srm://$DPM_HOST:8446/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/$L_LCG_CP_FILENAME \
          >$TEMP_FILE 2>&1
   processOutput "lcg-cp" $? $L_CHECK_TYPE "Could not get user mapping" "$TEMP_FILE" "Permission denied"

   echo
   echo " * Copying new file using rfcp"
   rfcp /bin/bash $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/$L_RFIO_CP_FILENAME >$TEMP_FILE 2>&1
   processOutput "rfcp" $? $L_CHECK_TYPE "Permission denied" "$TEMP_FILE"

   echo
   echo " * Creating subdirectory with dpns-mkdir"
   dpns-mkdir $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/L_DPNS_DIRECTORY >$TEMP_FILE 2>&1
   processOutput "dpns-mkdir" $? $L_CHECK_TYPE "Permission denied" "$TEMP_FILE"
}

cleanup ()
{
   echo; echo "Cleaning up..."
   if [ -f "$X509_USER_PROXY_ORIGINAL" ]; then
      X509_USER_PROXY=$X509_USER_PROXY_ORIGINAL
   fi

   rm -f $TEST_FILE

   DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chmod 775 $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR"
   DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chmod 775 $DPNS_HOME/$TEST_DIR/bash_copy_1"
   DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chown $EXECUTING_UID $DPNS_HOME/$TEST_DIR/bash_copy_1"
   DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $OWNER_GID \
                                                         --group $PRIMARY_FQAN --status 0"
   DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $SECOND_GID \
                                                       --group $SECONDARY_FQAN --status 0"

   lcg-del --nolfc -v -b -D srmv2 \
      srm://$DPM_HOST:$SRMV2_PORT/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/bash_copy_1
   lcg-del --nolfc -v -b -D srmv2 \
      srm://$DPM_HOST:$SRMV2_PORT/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/bash_copy_1
   lcg-del --nolfc -v -b -D srmv2 \
      srm://$DPM_HOST:$SRMV2_PORT/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/bash_copy_2
   lcg-del --nolfc -v -b -D srmv2 \
      srm://$DPM_HOST:$SRMV2_PORT/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/lcg-cp-file-temp \
      >/dev/null 2>&1
   lcg-del --nolfc -v -b -D srmv2 \
      srm://$DPM_HOST:$SRMV2_PORT/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/rf-cp-file-temp \
      >/dev/null 2>&1

   dpns-rm -r $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/dpns-dir-temp >/dev/null 2>&1
   dpns-rm -r $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/subdir_test >/dev/null 2>&1
   dpns-rm -r $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR
   dpns-rm -r $DPNS_HOME/$TEST_DIR

   rm -f /tmp/temp_copy_1
   rm -f $TEMP_FILE
}

echo "Creating directory $TEST_DIR"
dpns-mkdir -p $TEST_DIR

echo "Copying a file in $TEST_DIR"
lcg-cp -v -b -D srmv2 file:/bin/bash srm://$DPM_HOST:$SRMV2_PORT/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/bash_copy_1

GSI_TURL=$(lcg-gt -v -b -D srmv2 srm://$DPM_HOST:$SRMV2_PORT/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/bash_copy_1 gsiftp| head -1)
echo "GSIFTP TURL is $GSI_TURL"

echo
echo -n "Looking up owning user id: "
OWNER_GID=$(dpns-ls -l $DPNS_HOME/$TEST_DIR | \
            grep bash_copy_1 | \
            sed -e 's/[rwxd-]*\s*[0-9]*\s*[0-9]*\s*\([0-9]*\)\s*.*/\1/')
echo $OWNER_GID

echo -n "Getting the subject corresponding to the owner group id (PRIMARY_FQAN): "
PRIMARY_FQAN=$(dpns-listgrpmap --gid $OWNER_GID | \
               sed -e 's/\s*[0-9]*\s*//')
echo $PRIMARY_FQAN

SECONDARY_FQAN=$(voms-proxy-info -all | grep "^attribute : /$VO" | \
                 sed -e 's/\/Role=NULL//' | sed -e 's/\/Capability=NULL//' \
                 | sed -e 's/attribute : \///' | tail -1)

SECOND_GID=$(dpns-listgrpmap --group $SECONDARY_FQAN | \
             sed -e 's/\s*\([0-9]*\).*/\1/')

echo "Secondary FQAN: $SECONDARY_FQAN. Corresponding GID is: $SECOND_GID"

echo
echo "Scenario 1: Banning primary FQAN with LOCAL_BAN and checking access"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $OWNER_GID \
                                              --group $PRIMARY_FQAN --status LOCAL_BAN"
checkServices "FOR_DENY"

echo
echo "Scenario 2: Banning primary FQAN with ARGUS_BAN and checking access"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $OWNER_GID \
                                              --group $PRIMARY_FQAN --status ARGUS_BAN"
checkServices "FOR_DENY"

echo
echo "Scenario 3: Banning primary FQAN with LOCAL_BAN|ARGUS_BAN and checking access"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $OWNER_GID \
                                  --group $PRIMARY_FQAN --status 'ARGUS_BAN|LOCAL_BAN'"
checkServices "FOR_DENY"

echo
echo "Scenario 4: Unbanning primary FQAN and rechecking access"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $OWNER_GID \
                                              --group $PRIMARY_FQAN --status 0"
checkServices "FOR_ALLOW"

echo
echo "Scenario 5: Banning a secondary FQAN and rechecking access"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $SECOND_GID \
                                 --group $SECONDARY_FQAN --status 'ARGUS_BAN|LOCAL_BAN'"
checkServices "FOR_ALLOW"

echo
echo "Scenario 6: Secondary FQAN which is needed for directory write access is banned"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $SECOND_GID \
                                 --group $SECONDARY_FQAN --status 'ARGUS_BAN|LOCAL_BAN'"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-mkdir $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chgrp $SECOND_GID $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR"
checkDirectoryAccess "FOR_DENY" bash_copy_1 bash_copy_2 subdir_test

echo
echo "Scenario 7: Secondary FQAN which is needed for read access for a root-owned directory with mode 770 is banned"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $SECOND_GID \
                                 --group $SECONDARY_FQAN --status 'ARGUS_BAN|LOCAL_BAN'"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chmod 770 $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chgrp $SECOND_GID $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR"

echo
echo " * Listing directory contents with dpns-ls"
dpns-ls $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR >$TEMP_FILE 2>&1
processOutput "dpns-ls" $? "FOR_DENY" "Permission denied" "$TEMP_FILE"

EXECUTING_DN=$(voms-proxy-info -subject | sed -e 's/\/CN=proxy//')
EXECUTING_UID=$(dpns-listusrmap --user "$EXECUTING_DN" | cut -c1-8 | sed -e 's/ //g')

echo "Executing DN is: $EXECUTING_DN"
echo "Executing UID is: $EXECUTING_UID"

echo
echo "Scenario 8: Secondary FQAN corresponding to directory group owner banned, owner access allowed, mode 770"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-modifygrpmap --gid $SECOND_GID \
                                 --group $SECONDARY_FQAN --status 'ARGUS_BAN|LOCAL_BAN'"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chown $EXECUTING_UID $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR"
checkDirectoryAccess "FOR_ALLOW" bash_copy_1 bash_copy_2 subdir_test

echo
echo "Scenario 9: Primary FQAN corresponding to directory group owner banned, owner access allowed, mode 775"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chmod 775 $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR"
echo
X509_USER_PROXY_ORIGINAL=$X509_USER_PROXY
echo $PROXYPASSWD | voms-proxy-init -voms $VO:/$SECONDARY_FQAN -out /tmp/temporary-proxy -pwstdin
X509_USER_PROXY=/tmp/temporary-proxy
checkDirectoryAccess "FOR_DENY" lcg-cp-file-temp rf-cp-file-temp dpns-dir-temp
X509_USER_PROXY=$X509_USER_PROXY_ORIGINAL
unset X509_USER_PROXY_ORIGINAL
lcg-del --nolfc -v -b -D srmv2 \
   srm://$DPM_HOST:$SRMV2_PORT/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/lcg-cp-file-temp >/dev/null 2>&1
lcg-del --nolfc -v -b -D srmv2 \
   srm://$DPM_HOST:$SRMV2_PORT/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/rf-cp-file-temp >/dev/null 2>&1
dpns-rm -r $DPNS_HOME/$TEST_DIR/$TEST_SUBDIR/dpns-dir-temp >/dev/null 2>&1

echo
echo "Scenario 10: Secondary FQAN corresponding to file group owner banned, file owned by root with mode 770"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chmod 770 $DPNS_HOME/$TEST_DIR/bash_copy_1"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chown root $DPNS_HOME/$TEST_DIR/bash_copy_1"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chgrp $SECOND_GID $DPNS_HOME/$TEST_DIR/bash_copy_1"

echo
echo " * Check file read access via dpm-gsiftp"
lcg-cp -v -b -D srmv2 \
   srm://$DPM_HOST:8446/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/bash_copy_1 \
   /tmp/temp_copy_1 >$TEMP_FILE 2>&1
processOutput "lcg-cp" $? "FOR_DENY" "Could not get user mapping" "$TEMP_FILE" "Permission denied"

echo
echo " * Copying file read access via RFIO"
rfcp $DPNS_HOME/$TEST_DIR/bash_copy_1 /tmp/temp_copy_1 >$TEMP_FILE 2>&1
processOutput "rfcp" $? "FOR_DENY" "Permission denied" "$TEMP_FILE"

echo
echo "Scenario 11: Primary FQAN corresponding to file group owner banned, file owned by executor with mode 775"
echo
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chmod 775 $DPNS_HOME/$TEST_DIR/bash_copy_1"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chown $EXECUTING_UID $DPNS_HOME/$TEST_DIR/bash_copy_1"
DPM_HOST_EXEC "export DPNS_HOST=localhost; export PATH=$PATH:/opt/lcg/bin; dpns-chgrp $SECOND_GID $DPNS_HOME/$TEST_DIR/bash_copy_1"
X509_USER_PROXY_ORIGINAL=$X509_USER_PROXY
echo $PROXYPASSWD | voms-proxy-init -voms $VO:/$SECONDARY_FQAN -out /tmp/temporary-proxy -pwstdin
X509_USER_PROXY=/tmp/temporary-proxy
echo
echo " * Check file read access via dpm-gsiftp"
lcg-cp -v -b -D srmv2 \
   srm://$DPM_HOST:8446/srm/managerv2\?SFN=$DPNS_HOME/$TEST_DIR/bash_copy_1 \
   /tmp/temp_copy_1 >$TEMP_FILE 2>&1
processOutput "lcg-cp" $? "FOR_DENY" "Could not get user mapping" "$TEMP_FILE" "Permission denied"
echo
echo " * Copying file read access via RFIO"
rfcp $DPNS_HOME/$TEST_DIR/bash_copy_1 /tmp/temp_copy_1 >$TEMP_FILE 2>&1
processOutput "rfcp" $? "FOR_DENY" "Permission denied" "$TEMP_FILE"
X509_USER_PROXY=$X509_USER_PROXY_ORIGINAL
unset X509_USER_PROXY_ORIGINAL

cleanup
echo
echo "OVERALL RESULT:"

TEST_PASSED

