#!/bin/sh
#
# Copyright 2011-2021 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/>.

eval "$(univention-config-registry shell)"

usage () {
	echo "$(basename "$0") [-h] [-u|-c] [-f]"
	echo "    -c   check only computer objects"
	echo "    -u   check only user objects"
	echo "    -h   prints this helptext"
	echo "    -f   perform changes"
	echo "         (default is dry-run)"
	exit $1
}

FORCE=""
ONLYUSER=""
ONLYCOMPUTER=""
while [ -n "$1" ]
do
        case "$1" in
        -h|--help)
                usage 0
                ;;
        -c)
                ONLYCOMPUTER="1"
                shift
                ;;
        -u)
                ONLYUSER="1"
				shift
                ;;
        -f)
                FORCE="1"
				shift
                ;;
        --)
                shift
                break
                ;;
        -*)
                usage 2 >&2
                ;;
        *)
                break
                ;;
        esac
done


OLDIFS="$IFS"
IFS='
'

if [ -z "$ONLYUSER" ] ; then
	# TEST COMPUTERS
	gidNumberList="$(ldapsearch -LLLx -ZZ -D "$ldap_hostdn" -y /etc/machine.secret "(&(objectClass=univentionHost)(gidNumber=*))" gidNumber | ldapsearch-wrapper | sed -ne "s,^gidNumber: ,,p" | sort -u)"
	for gidNumber in $gidNumberList ; do
	 	grpDn="$(ldapsearch -xLLL -ZZ -D "$ldap_hostdn" -y /etc/machine.secret "(&(objectClass=univentionGroup)(gidNumber=${gidNumber}))" dn | ldapsearch-wrapper | sed -ne 's,dn: ,,p')"
	 	for dn in $(ldapsearch -LLLx -ZZ -D "$ldap_hostdn" -y /etc/machine.secret "(&(objectClass=univentionHost)(gidNumber=${gidNumber}))" dn | ldapsearch-wrapper | sed -ne "s,^dn: ,,p") ; do
	 		if [ -z "$(ldapsearch -xLLL -ZZ -D "$ldap_hostdn" -y /etc/machine.secret "(&(objectClass=univentionGroup)(gidNumber=${gidNumber})(uniqueMember=${dn}))" dn)" ] ; then
	 			echo "*** $dn is missing in group with gidNumber $gidNumber ($grpDn)"
	 			if [ -n "$FORCE" ] ; then
	 				ldapmodify -x -D "cn=admin,$ldap_base" -w "$(cat /etc/ldap.secret)" <<EOF
dn: $grpDn
changetype: modify
add: uniqueMember
uniqueMember: $dn
EOF
	 		    fi
	 		fi
	 		hostuid="$(ldapsearch -xLLL -ZZ -D "$ldap_hostdn" -y /etc/machine.secret -b "$dn" uid | ldapsearch-wrapper | sed -ne 's,^uid: ,,p')"
	 		if [ -z "$(ldapsearch -xLLL -ZZ -D "$ldap_hostdn" -y /etc/machine.secret "(&(objectClass=univentionGroup)(gidNumber=${gidNumber})(memberUid=${hostuid}))" dn)" ] ; then
	 			echo "*** $hostuid is missing in group with gidNumber $gidNumber ($grpDn)"
	 			if [ -n "$FORCE" ] ; then
	 				ldapmodify -x -D "cn=admin,$ldap_base" -w "$(cat /etc/ldap.secret)" <<EOF
dn: $grpDn
changetype: modify
add: memberUid
memberUid: $hostuid
EOF
	 		    fi
	 		fi
	 	done
	done
fi

if [ -z "$ONLYCOMPUTER" ] ; then
	# TEST USERS
	gidNumberList="$(ldapsearch -LLLx -ZZ -D "$ldap_hostdn" -y /etc/machine.secret "(&(objectClass=posixAccount)(uid=*)(!(uid=*$))(gidNumber=*))" gidNumber | ldapsearch-wrapper | sed -ne "s,^gidNumber: ,,p" | sort -u)"
	for gidNumber in $gidNumberList ; do
	 	grpDn="$(ldapsearch -xLLL -ZZ -D "$ldap_hostdn" -y /etc/machine.secret "(&(objectClass=univentionGroup)(gidNumber=${gidNumber}))" dn | ldapsearch-wrapper | sed -ne 's,dn: ,,p')"
	 	for dn in $(ldapsearch -LLLx "(&(objectClass=posixAccount)(uid=*)(!(uid=*$))(gidNumber=${gidNumber}))" dn | ldapsearch-wrapper | sed -ne "s,^dn: ,,p") ; do
	 		if [ -z "$(ldapsearch -xLLL -ZZ -D "$ldap_hostdn" -y /etc/machine.secret "(&(objectClass=univentionGroup)(gidNumber=${gidNumber})(uniqueMember=${dn}))" dn)" ] ; then
	 			echo "*** $dn is missing in group with gidNumber $gidNumber ($grpDn)"
	 			if [ -n "$FORCE" ] ; then
	 				ldapmodify -x -D "cn=admin,$ldap_base" -w "$(cat /etc/ldap.secret)" <<EOF
dn: $grpDn
changetype: modify
add: uniqueMember
uniqueMember: $dn
EOF
	 		    fi
	 		fi
	 		useruid="$(ldapsearch -xLLL -ZZ -D "$ldap_hostdn" -y /etc/machine.secret -b "$dn" uid | ldapsearch-wrapper | sed -ne 's,^uid: ,,p')"
	 		if [ -z "$(ldapsearch -xLLL -ZZ -D "$ldap_hostdn" -y /etc/machine.secret "(&(objectClass=univentionGroup)(gidNumber=${gidNumber})(memberUid=${useruid}))" dn)" ] ; then
	 			echo "*** $useruid is missing in group with gidNumber $gidNumber ($grpDn)"
	 			if [ -n "$FORCE" ] ; then
	 				ldapmodify -x -D "cn=admin,$ldap_base" -w "$(cat /etc/ldap.secret)" <<EOF
dn: $grpDn
changetype: modify
add: memberUid
memberUid: $useruid
EOF
	 		    fi
	 		fi
	 	done
	done
fi

exit 0
