#!/bin/bash
#
# Like what you see? Join us!
# https://www.univention.com/about-us/careers/vacancies/
#
# Copyright 2004-2024 Univention GmbH
#
# https://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <https://www.gnu.org/licenses/>.

. /usr/share/univention-lib/ucr.sh

CONFIGBASENAME="connector"

usage() {
	echo ""
	echo "This is univention-adsearch"
	echo ""
	echo "Univention-adsearch uses the settings of \"univention-ad-connector\" to ldap-search an Active-Directory Server."
	echo ""
	echo "Usage:"
	echo "univention-adsearch [-c configbase] filter <attributes>"
	echo ""
	echo "The default configbase is \"connector\"."
	echo ""
	echo "Extend help:"
	echo "univention-adsearch --help, for a detailed ldbsearch help message"
}


## check for option -U to avoid letting --simple-bind-dn taking precedence
optspec=":-:c:d:U:A:P:h"
while getopts "$optspec" option; do
	case "${option}" in
		c) CONFIGBASENAME="${OPTARG}"; shift 2;;
		d) debug=true; shift;;
		U|A|P) credentials_given=true;;
		h) usage; exit 0;;
		-)
			case "${OPTARG}" in
				authentication-file|authentication-file=*)
					credentials_given=true;;
				machine-pass|machine-pass=*)
					credentials_given=true;;
				password|password=*)
					credentials_given=true;;
				simple-bind-dn|simple-bind-dn=*)
					credentials_given=true;;
				user|user=*)
					credentials_given=true;;
			esac;;
	esac
done

eval "$(univention-config-registry shell "$CONFIGBASENAME/ad/ldap/.*")"

binddn_env="${CONFIGBASENAME//-/_}_ad_ldap_binddn"
binddn_ucr="${CONFIGBASENAME//-/_}/ad/ldap/binddn"
bindpw_env="${CONFIGBASENAME//-/_}_ad_ldap_bindpw"
bindpw_ucr="${CONFIGBASENAME//-/_}/ad/ldap/bindpw"
host_env="${CONFIGBASENAME//-/_}_ad_ldap_host"
port_env="${CONFIGBASENAME//-/_}_ad_ldap_port"
base_env="${CONFIGBASENAME//-/_}_ad_ldap_base"
cert_env="${CONFIGBASENAME//-/_}_ad_ldap_certificate"
ldaps_ucr="${CONFIGBASENAME//-/_}/ad/ldap/ldaps"
kerberos_ucr="${CONFIGBASENAME//-/_}/ad/ldap/kerberos"


cleanup() {
	if [ -n "$authentication_file" ]; then
		rm -f "$authentication_file"
	fi
}


options=()
if ! [ "$credentials_given" = 'true' ]; then
	if ! is_ucr_true "$kerberos_ucr"; then
		if [ -n "${!binddn_env}" ]; then
			options+=("--simple-bind-dn=${!binddn_env}")
		else
			echo "UCR variable $binddn_ucr not set and no ldbsearch credential options given"
			exit 1
		fi
		if [ -r "${!bindpw_env}" ]; then
			trap cleanup EXIT
			authentication_file=$(mktemp)
			chmod 600 "$authentication_file"
			cat > "$authentication_file" <<-%EOF
			password = $(<"${!bindpw_env}")
			%EOF
			options+=("--authentication-file=$authentication_file")
		else
			echo "File ${!bindpw_env} not found given in UCR variable $bindpw_ucr"
			exit 1
		fi
	else
		if [ -z "${!binddn_env}" ]; then
			echo "UCR variable $binddn_ucr not set"
			exit 1
		fi
		if [ -z "${!bindpw_env}" ]; then
			echo "UCR variable $bindpw_ucr not set"
			exit 1
		elif ! [ -r "${!bindpw_env}" ]; then
			echo "File ${!bindpw_env} not found given in UCR variable $bindpw_ucr"
			exit 1
		fi
		kdestroy
		kinit --no-addresses --password-file="${!bindpw_env}" "${!binddn_env}"
		options+=("--use-kerberos=required")
	fi
fi


if is_ucr_true "$ldaps_ucr"; then
	protocol='ldaps'
	options+=("--option" "tls cafile = ${!cert_env}")
	options+=("--option" "tls crlfile = /etc/univention/ssl/ucsCA/crl/crl.pem") ## we could add a cert from the AD domain into our CRL
else
	protocol='ldap'
fi


ldap_server_name="${!host_env}"
if [ -n "${!port_env}" ]; then
	ldap_server_name="${ldap_server_name}:${!port_env}"
fi
if [ -n "${!base_env}" ]; then
	options+=("--basedn=${!base_env}")
fi


ldbsearch --show-deleted -H "$protocol://$ldap_server_name" "${options[@]}" "$@"
rc=$?

if [ "$debug" = 'true' ]; then
	echo "### Output of: ldbsearch --show-deleted -H $protocol://$ldap_server_name ${options[@]} $@"
fi

exit $rc
