Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
none
none
titleSave in a file AccountChecker.sh and chmod +x AccountChecker.sh
#! /bin/sh
################################################################################
DESCRIPTION="
This shell script will check whether a user account identified by
a SAML2 NameID exists at a given Identity Provider.

For that it will do an attribute query using a provided NameID.
If the Identity Provider then returns at least one of the personal
attributes that can be configured below, the script assumes that
the account still exists.

In order to execute the script, it must be copied to a host where
a Shibboleth Service Provider (SP) 2.x is installed because it requires
the resolvertest binary that comes bundled with the SP.

Using the -v options the script will produce verbose output.
If you see this description you either have used the -h option
standing for help or you have used an illegal option.

If you are wondering why you have to enter your password, this is because
the scrip has to execute the resolvertest binary as root in order to allow
it access to the (hopefully) read protected private key that is used by
the Service Provider.

The script can be executed with a NameID or a file as an argument.
If the value that is provided to the script does not consist of the tripel
'SP!IdP!NameID', the entityID of the default application of this SP is used
as well as a default IdP that can be configured in this script.

When called with the -i option the script returns the following status codes:
    0     If account probably doesn't exist anymore
    1     If account still exists
  255     If an error occured

If the script is called with a file as argument (-f), it assumes that each line
of the file consists either of a NameID or the tripel 'SP!IdP!NameID'. It then
will check each NameID and create a comma separated copy of the given file with
the suffix '.result.csv'. This new file contains an additonal column where
the numbers stand for the above-mentioned status codes.

Version: 20090715
Authors: lukas.haemmerle@switch.ch
"
################################################################################

### CONFIG SECTION START ###
# Path to Service Provider's resolvertest binary
RESOLVERTEST=`which resolvertest`

# NameID format to use
FORMAT=urn:oasis:names:tc:SAML:2.0:nameid-format:persistent

# Default IdP to use if IdP is not provided as argument
IDP=https://default.idp.example.org/idp/shibboleth

# Personal attributes to check as proof of account's existence
# The following values should correspond to the IDs or aliases of attribute
# definitions in Shibboleth's attribute-map.xml file
ATTRIBUTES=( eppn
uniqueID Shib-SwissEP-UniqueID
mail Shib-InetOrgPerson-mail
givenName Shib-InetOrgPerson-givenName
surname Shib-Person-surname
Shib-SwissEP-DateOfBirth dateOfBirth
employeeNumber Shib-InetOrgPerson-employeeNumber)
### CONFIG SECTION END ###

################################################################################

#-------------------------------------------------------------------------------
# Checks whether attributes are returned for NameID
parseNameID(){
	TLINE=$1

	# Parse complete NameID
	NAMEIDP1=`echo "$TLINE" | cut -d! -f1`
	NAMEIDP2=`echo "$TLINE" | cut -d! -f2`
	NAMEIDP3=`echo "$TLINE" | cut -d! -f3`

	# Check if we got the full NameID
	if [ "$NAMEIDP1" != "$NAMEIDP3" ] ; then
		ID=$NAMEIDP3
		IDP=$NAMEIDP1
	else
		ID=$NAMEIDP1
	fi

	if [ $VERBOSE -eq 1 -a $ID ] ; then
		echo -n "Checking NameID: $ID"
		echo " against Identity Provider: $IDP"
	fi

	(CheckNameID "$ID" "$IDP")
	return $?
}

#-------------------------------------------------------------------------------

# Checks whether attributes are returned for NameID
CheckNameID(){
	TID=$1
	TIDP=$2

	RESULT="`\
sudo $RESOLVERTEST \
-saml2 \
-f $FORMAT \
-n $TID \
-i $TIDP \
`"

	ERRORS="`echo \"$RESULT\" | grep ERROR`"

	if [ "$ERRORS" != "" -a "$NAMEID" != "" ] ; then
		echo "Erorr occured:"
		echo "$ERRORS"
		return 255
	elif [ "$ERRORS" != "" ] ; then
		return 255
	fi


	for name in ${ATTRIBUTES[@]}
	do
		FOUND="`echo \"$RESULT\" | grep \"ID: $name\"`"
		if [ "$FOUND" != "" ] ; then
			if [ $VERBOSE -eq 1 ] ; then
				echo -n "Found personal attribute with $FOUND "
				echo " -> User account with NameID $TID still exists";
			fi
		return 1
	fi
	done

	if [ $VERBOSE -eq 1 ] ; then
		echo -n "No personal attributes found for user account with NameID $TID"
		echo " -> User account probably doesn't exist anymore"
	fi
	return 0
}

#-------------------------------------------------------------------------------

# Init some variables
VERBOSE=0;

# Parse arguments
while getopts hvf:i: c
do
	case $c in
		v) VERBOSE=1;;
		f) FILE=$OPTARG;;
		i) NAMEID=$OPTARG;;
		h)
		echo "$0 [-h] [-v] -i persistentID"
		echo "$0 [-h] [-v] -f file"
		echo "$0 -h
		echo "$DESCRIPTION"
		exit 255;;
		[?])
		echo "$0 [-h] [-v] -i persistentID"
		echo "$0 [-h] [-v] -f file"
		echo "$0 -h
		echo "$DESCRIPTION"
		exit 255;;
	esac
done

if [ "$FILE" == "" -a "$NAMEID" == "" ] ; then
	echo "You must provide at least the options -i or -f"
	exit 255
fi

if [ "$FILE" != "" -a "$NAMEID" != "" ] ; then
	echo "You can only use -i or -f as options!"
	exit 255
fi

# Parse file
if [ "$FILE" != "" ] ; then
	if [ ! -f $FILE  ] ; then
		echo "File $FILE doesn't exist!"
		exit 255
	fi

	if [ $VERBOSE -eq 1 -a $FILE ] ; then
		echo "Parsing file: $FILE"
	fi

	RESULTFILE="$FILE.result.csv"
	echo "#NAMEID,#RESULT" > $RESULTFILE
	while read LINE ;do
		(parseNameID "$LINE")
		echo "$LINE,$?" >> $RESULTFILE
	done < $FILE
	exit 0;

elif [ "$NAMEID" != "" ] ; then
	# Parse single NameID
	(parseNameID "$NAMEID")
	exit $?

else
	echo "Something unexpected happened  :-("
	exit 255
fi

#-------------------------------------------------------------------------------

...