# start 65ucsschool

@!@
# -*- coding: utf-8 -*-
import re
import os
from univention.lib.misc import custom_groupname

aclset = """
# Primary und Back Directory Nodes duerfen die Einträge aller OUs lesen und schreiben
access to dn.regex="^(.+,)?ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$"
	by group/univentionGroup/uniqueMember.expand="cn=DC Backup Hosts,cn=groups,@%@ldap/base@%@" write
	by * +0 break

"""

def replace_ucr_variables(template):
	variable_token = re.compile('@[$]@')
	replacements = {
		'STAFF2EDU': '# ' if configRegistry.is_true('ucsschool/ldap/replicate_staff_to_edu', False) else '',
		'DISTRICT': 'ou=[^,]+,' if configRegistry.is_true('ucsschool/ldap/district/enable', False) else '',
		'PUPILS': configRegistry.get('ucsschool/ldap/default/container/pupils', 'schueler'),
		'TEACHERS': configRegistry.get('ucsschool/ldap/default/container/teachers', 'lehrer'),
		'LEGAL-GUARDIAN': configRegistry.get('ucsschool/ldap/default/container/legal_guardians', 'sorgeberechtigte'),
		'STAFF': configRegistry.get('ucsschool/ldap/default/container/staff', 'mitarbeiter'),
		'TEACHERS-STAFF': configRegistry.get('ucsschool/ldap/default/container/teachers-and-staff', 'lehrer und mitarbeiter'),
		'ADMINS': configRegistry.get('ucsschool/ldap/default/container/admins', 'admins'),
		'GRPADMINS': configRegistry.get('ucsschool/ldap/default/groupprefix/admins', 'admins-'),
		'EXAM': configRegistry.get('ucsschool/ldap/default/container/exam', 'examusers'),
		'DOMAIN_ADMINS': custom_groupname('Domain Admins'),
		'SCHOOLOUATTRS': '@top,@organizationalUnit,@ucsschoolOrganizationalUnit,@univentionObject,@univentionPolicyReference',  # FIXME: extended attributes which adds object classes doesn't work
		# FIXME: the following rules aren't enough but we need to support extended attributes/options
		'CONTAINERATTRS': 'cn,objectClass,!univentionShare,!univentionShareNFS,!univentionShareSamba,!SambaSamAccount',
		'USERATTRS': 'cn,objectClass,!univentionShare,!univentionShareNFS,!univentionShareSamba,!posixGroup',
		'GROUPATTRS': 'cn,objectClass,description,!univentionShare,!univentionShareNFS,!univentionShareSamba,!posixAccount,!SambaSamAccount',
		'DHCPSERVICEATTRS': 'cn,!posixGroup,!posixAccount,!SambaSamAccount,!univentionShare,!univentionShareNFS,!univentionShareSamba',
		'DHCPATTRS': 'cn,!posixGroup,!posixAccount,!SambaSamAccount,!univentionShare,!univentionShareNFS,!univentionShareSamba',
		'MSGPO_MSPRINT_CONTAINER': '@univentionObject,@organizationalRole',
		'MSWMI_FILTER': '@univentionObject,@organizationalRole'
	}

	# enable objectclasses only if corresponding LDAP schema is present (Bug #41725)
	if os.path.exists('/var/lib/univention-ldap/local-schema/mswmi.schema'):
		replacements['MSWMI_FILTER'] += ',@msWMISom'
	if os.path.exists('/var/lib/univention-ldap/local-schema/msgpo.schema'):
		replacements['MSGPO_MSPRINT_CONTAINER'] += ',@msGPOContainer'
	if os.path.exists('/var/lib/univention-ldap/local-schema/msprintconnectionpolicy.schema'):
		replacements['MSGPO_MSPRINT_CONTAINER'] += ',@msPrintConnectionPolicy'

	while True:
		i = variable_token.finditer(template)
		try:
			start = next(i)
			end = next(i)
			name = template[start.end():end.start()]

			template = template[:start.start()] + replacements.get(name, '') + template[end.end():]
		except StopIteration:
			break

	return template


aclset += """

# prevent unauthorized access to user password data as described in Bug #50669

access to filter="(|(objectClass=ucsschoolAdministrator)(&(univentionObjectType=users/user)(!(objectClass=ucsschoolType))))" attrs=sambaNTPassword,userPassword,krb5Key,sambaPasswordHistory,pwhistory
	by self +0 break
	by group/univentionGroup/uniqueMember="cn=@$@DOMAIN_ADMINS@$@,cn=groups,@%@ldap/base@%@" +0 break
	by set="user/objectClass & ([ucsschoolAdministrator] | [ucsschoolTeacher] | [ucsschoolStaff] | [ucsschoolStudent] | [ucsschoolLegalGuardian])" none
	by * +0 break

access to filter="(|(objectClass=ucsschoolStaff)(objectClass=ucsschoolTeacher))" attrs=sambaNTPassword,userPassword,krb5Key,sambaPasswordHistory,pwhistory
	by self +0 break
	by group/univentionGroup/uniqueMember="cn=@$@DOMAIN_ADMINS@$@,cn=groups,@%@ldap/base@%@" +0 break
	by set="user/objectClass & [ucsschoolAdministrator]" +0 break
	by set="user/objectClass & ([ucsschoolTeacher] | [ucsschoolStaff] | [ucsschoolStudent] | [ucsschoolLegalGuardian])" none
	by * +0 break

access to filter="objectClass=ucsschoolStudent" attrs=sambaNTPassword,userPassword,krb5Key,sambaPasswordHistory,pwhistory
	by self +0 break
	by group/univentionGroup/uniqueMember="cn=@$@DOMAIN_ADMINS@$@,cn=groups,@%@ldap/base@%@" +0 break
	by set="user/objectClass & ([ucsschoolAdministrator] | [ucsschoolTeacher])" +0 break
	by set="user/objectClass & ([ucsschoolStudent] | [ucsschoolStaff] | [ucsschoolLegalGuardian])" none
	by * +0 break

# Replica Directory Nodes need write access to the members of the group Domain Computers
access to dn.exact="cn=Domain Computers,cn=groups,@%@ldap/base@%@" attrs="uniqueMember,memberUid"
	by group/univentionGroup/uniqueMember="cn=DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by * +0 break

# Replica Directory Nodes can read and write policy containers for MS GPOs and msPrintConnectionPolicy objects (part 1)
access to dn.base="cn=policies,cn=system,@%@ldap/base@%@" attrs=children
	by group/univentionGroup/uniqueMember="cn=DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by * +0 break

# Replica Directory Nodes can read and write policy containers for MS GPOs and msPrintConnectionPolicy objects (part 2)
access to dn.children="cn=policies,cn=system,@%@ldap/base@%@" filter="(|(objectClass=msGPOContainer)(objectClass=organizationalRole)(objectClass=msPrintConnectionPolicy))" attrs=entry,children,@$@MSGPO_MSPRINT_CONTAINER@$@
	by group/univentionGroup/uniqueMember="cn=DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by * +0 break

# Replica Directory Nodes can read and write policy containers for MS WMI filter objects (part 1)
access to dn.base="cn=WMIPolicy,cn=system,@%@ldap/base@%@" attrs=children
	by group/univentionGroup/uniqueMember="cn=DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by * +0 break

# Replica Directory Nodes can read and write policy containers for MS WMI filter objects (part 2)
access to dn.children="cn=WMIPolicy,cn=system,@%@ldap/base@%@" filter="(|(objectClass=msWMISom)(objectClass=organizationalRole))" attrs=entry,@$@MSWMI_FILTER@$@
	by group/univentionGroup/uniqueMember="cn=DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by * +0 break

# Lehrer, Mitarbeiter und OU-Admins duerfen Schueler-Passwoerter aendern
access to filter="objectClass=ucsschoolStudent" attrs=krb5KeyVersionNumber,krb5KDCFlags,krb5Key,krb5PasswordEnd,sambaAcctFlags,sambaPwdLastSet,sambaLMPassword,sambaNTPassword,shadowLastChange,shadowMax,userPassword,pwhistory,sambaPwdCanChange,sambaPwdMustChange,sambaPasswordHistory,sambaBadPasswordCount,pwdAccountLockedTime,sambaBadPasswordTime
	by set="this/ucsschoolSchool & ([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" write
	by * +0 break

# Lehrer, Mitarbeiter und OU-Admins duerfen Raum-Gruppen anlegen und bearbeiten
access to dn.regex="^cn=raeume,cn=groups,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=children,entry
	by set.expand="[$1] & ([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" write
	by * +0 break

access to dn.regex="^cn=([^,]+),cn=raeume,cn=groups,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" filter="(objectClass=univentionGroup)" attrs=entry,@$@GROUPATTRS@$@
	by set.expand="[$2] & ([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" write
	by * +0 break

# Rechner duerfen ihr Passwort aendern
# TODO: are the following attributes missing here?: 'sambaBadPasswordCount', 'krb5PasswordEnd', 'shadowMax', 'sambaAcctFlags', 'sambaPasswordHistory'
access to dn.regex="cn=.*,cn=server,cn=computers,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=userPassword,krb5Key,krb5KDCFlags,sambaNTPassword,sambaLMPassword,shadowLastChange,sambaPwdLastSet,pwhistory,krb5KeyVersionNumber,sambaPwdCanChange,sambaPwdMustChange
	by self write
	by * +0 break

# OU-Admins duerfen Passwoerter von Schülern, Lehrern, Sorgeberechtigten und Mitarbeitern (mit Position ausserhalb der OU) aendern
access to filter="(&(|(objectClass=ucsschoolTeacher)(objectClass=ucsschoolLegalGuardian)(objectClass=ucsschoolStudent)(objectClass=ucsschoolStaff))(!(objectClass=ucsschoolAdministrator)))" attrs=krb5KeyVersionNumber,krb5KDCFlags,krb5Key,krb5PasswordEnd,sambaAcctFlags,sambaPwdLastSet,sambaLMPassword,sambaNTPassword,shadowLastChange,shadowMax,userPassword,pwhistory,sambaPwdCanChange,sambaPwdMustChange,sambaPasswordHistory,sambaBadPasswordCount,pwdAccountLockedTime,sambaBadPasswordTime
	by set="this/ucsschoolSchool & ([ldap:///@%@ldap/base@%@?entryDN?sub?%28%26%28objectClass%3DucsschoolAdministratorGroup%29%28uniqueMember%3D]+user/entryDN+[%29%29])/ucsschoolSchool" write
	by * +0 break

# Lehrer, Mitarbeiter und OU-Admins duerfen Arbeitsgruppen anlegen und aendern
access to dn.regex="^(cn=@$@TEACHERS@$@,|cn=@$@PUPILS@$@,|)cn=groups,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=children,entry
	by group/univentionGroup/uniqueMember.expand="cn=@$@GRPADMINS@$@$2,cn=ouadmins,cn=groups,@%@ldap/base@%@" write
	by set.expand="[$2] & ([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" write
	by * +0 break

access to dn.regex="^cn=([^,]+),(cn=@$@TEACHERS@$@,|cn=@$@PUPILS@$@,|)cn=groups,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" filter="(objectClass=univentionGroup)" attrs=entry,@$@GROUPATTRS@$@
	by group/univentionGroup/uniqueMember.expand="cn=@$@GRPADMINS@$@$3,cn=ouadmins,cn=groups,@%@ldap/base@%@" write
	by set.expand="[$3] & ([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" write
	by * +0 break

# Replica Directory Nodes muessen das temporäre Objekt mailPrimaryAddress erstellen duerfen. Siehe Bug #52215
access to dn.regex="^cn=([^,]+),cn=mailPrimaryAddress,cn=temporary,cn=univention,@%@ldap/base@%@$$" filter="objectClass=lock" attrs="entry,@univentionObject,@lock"
	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by * +0 break

access to dn.regex="^cn=mailPrimaryAddress,cn=temporary,cn=univention,@%@ldap/base@%@$$" attrs=children,entry
	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by * +0 break

# Lehrer, Mitarbeiter und OU-Admins muessen einige temporaere Objekte schreiben duerfen
# da keine regulaeren Ausdruecke auf Gruppenmitgliedschaften moeglich sind wird dies allen Lehrern erlaubt
access to dn.regex="^cn=([^,]+),cn=(mailPrimaryAddress|groupName|sid|gid|gidNumber|mac|uidNumber),cn=temporary,cn=univention,@%@ldap/base@%@$$" filter="objectClass=lock" attrs="entry,@univentionObject,@lock"
	by set="([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" write
	by * +0 break

access to dn.regex="^cn=(mailPrimaryAddress|groupName|sid|gid|gidNumber|mac|uidNumber),cn=temporary,cn=univention,@%@ldap/base@%@$$" attrs=children,entry
	by set="([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" write
	by * +0 break

access to dn.base="cn=gidNumber,cn=temporary,cn=univention,@%@ldap/base@%@" attrs=univentionLastUsedValue
	by set="([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" write
	by * +0 break

access to dn.base="cn=uidNumber,cn=temporary,cn=univention,@%@ldap/base@%@" attrs=univentionLastUsedValue
	by set="([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" write
	by * +0 break

# OU-Admins duerfen MAC-Adressen im Rechner- und DHCP-Objekt aendern
# OU-Admins duerfen die ucsschool Rollen in Rechner-Objekten ihrer OU ändern
access to dn.regex="^cn=([^,]+),cn=computers,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=macAddress,ucsschoolRole
	by group/univentionGroup/uniqueMember.expand="cn=@$@GRPADMINS@$@$2,cn=ouadmins,cn=groups,@%@ldap/base@%@" write
	by * +0 break

access to dn.regex="^cn=([^,]+),cn=dhcp,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=entry,children,objectClass,@univentionObject,@univentionPolicyReference,@$@DHCPSERVICEATTRS@$@
	by group/univentionGroup/uniqueMember.expand="cn=@$@GRPADMINS@$@$2,cn=ouadmins,cn=groups,@%@ldap/base@%@" write
	by * +0 break
access to dn.regex="^cn=([^,]+),cn=([^,]+),cn=dhcp,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=entry,objectClass,@univentionObject,@univentionPolicyReference,@$@DHCPATTRS@$@
	by group/univentionGroup/uniqueMember.expand="cn=@$@GRPADMINS@$@$3,cn=ouadmins,cn=groups,@%@ldap/base@%@" write
	by * +0 break

access to dn.regex="^zoneName=[^,]+,cn=dns,@%@ldap/base@%@$$" attrs=sOARecord
	by set="user/objectClass & [ucsschoolAdministrator]" write
	by * +0 break

# Replica Directory Nodes and Managed Nodes of management group are not allowed to replicate pupils, teachers and legal
# guardians
access to dn.regex="^.+,cn=(@$@TEACHERS@$@|@$@PUPILS@$@|@$@LEGAL-GUARDIAN@$@),cn=users,ou=[^,]+,@$@DISTRICT@$@@%@ldap/base@%@$$"
	by group/univentionGroup/uniqueMember="cn=DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" none
	by group/univentionGroup/uniqueMember="cn=Member-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" none
	by * +0 break

access to filter="(|(objectClass=ucsschoolStudent)(objectClass=ucsschoolLegalGuardian)(&(objectClass=ucsschoolTeacher)(!(objectClass=ucsschoolStaff))))"
	by group/univentionGroup/uniqueMember="cn=DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" none
	by group/univentionGroup/uniqueMember="cn=Member-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" none
	by * +0 break

# Replica Directory Nodes and Managed Nodes of educational group are not allowed to replicate staff users
# the following 2 ACLs may be deactivated via the UCR variable "ucsschool/ldap/replicate_staff_to_edu"
@$@STAFF2EDU@$@access to dn.regex="^.+,cn=@$@STAFF@$@,cn=users,ou=[^,]+,@$@DISTRICT@$@@%@ldap/base@%@$$"
@$@STAFF2EDU@$@	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" none
@$@STAFF2EDU@$@	by group/univentionGroup/uniqueMember="cn=Member-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" none
@$@STAFF2EDU@$@	by * +0 break

@$@STAFF2EDU@$@access to filter="(&(objectClass=ucsschoolStaff)(!(objectClass=ucsschoolTeacher))(!(objectClass=ucsschoolAdministrator)))"
@$@STAFF2EDU@$@	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" none
@$@STAFF2EDU@$@	by group/univentionGroup/uniqueMember="cn=Member-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" none
@$@STAFF2EDU@$@	by * +0 break

# Alle Replica Directory Nodes muessen alle Benutzercontainer, Gruppen und GPO links jeder Schule lesen koennen
access to dn.regex="^ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" filter="objectClass=ucsschoolOrganizationalUnit" attrs=entry,children,@$@SCHOOLOUATTRS@$@,@msGPO
	by group/univentionGroup/uniqueMember.expand="cn=OU$1-DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember.expand="cn=OU$1-DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by dn.regex="^cn=.*,cn=server,cn=computers,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" +rscxd
	by * +rscxd break

access to dn.regex="^cn=(users|groups|@$@EXAM@$@),ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=entry,children,@$@CONTAINERATTRS@$@
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by dn.regex="^cn=.*,cn=server,cn=computers,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" +rscxd
	by * +rscxd break

access to dn.regex="^([^,]+),cn=groups,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=entry,@$@GROUPATTRS@$@
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by dn.regex="^cn=.*,cn=server,cn=computers,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" +rscxd
	by * +rscxd break

access to dn.regex="^cn=(@$@PUPILS@$@|@$@TEACHERS@$@|@$@LEGAL-GUARDIAN@$@|@$@TEACHERS-STAFF@$@|@$@STAFF@$@|@$@ADMINS@$@),cn=users,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=entry,children,@$@CONTAINERATTRS@$@
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by dn.regex="^cn=.*,cn=server,cn=computers,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" +rscxd
	by * +rscxd break

# Replica Directory Nodes muessen die Benutzer ihrer Schule lesen und schreiben duerfen
access to dn.regex="^uid=([^,]+),cn=(@$@PUPILS@$@|@$@TEACHERS@$@|@$@LEGAL-GUARDIAN@$@|@$@TEACHERS-STAFF@$@|@$@STAFF@$@|@$@ADMINS@$@),cn=users,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=entry,@$@USERATTRS@$@
	by set="([cn=OU]+this/ucsschoolSchool+[-DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@])/uniqueMember & user" write
	by set="([cn=OU]+this/ucsschoolSchool+[-DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@])/uniqueMember & user" write
	by * +0 break
access to dn.regex="^uid=([^,]+),cn=@$@EXAM@$@,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=entry,@$@USERATTRS@$@
	by set="([cn=OU]+this/ucsschoolSchool+[-DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@])/uniqueMember & user" write
	by * +0 break

# Students dürfen PWHashes von anderen Usern der gleichen Schule nicht lesen
access to attrs=krb5Key,sambaLMPassword,sambaNTPassword,userPassword,pwhistory
	by set="this/ucsschoolSchool & ([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolStudent%29%29])/ucsschoolSchool" none
	by * +0 break

# Schuluser dürfen andere Schuluser auslesen, sofern sie zur eigenen Schule gehören
access to dn.regex="^(.+,)?ou=[^,]+,@%@ldap/base@%@$$"
	by set="this/ucsschoolSchool & user/ucsschoolSchool" read break
	by * +0 break


# Schul-Replica-Directory-Nodes duerfen nur Eintraege ihrer OU lesen und schreiben (Passwortaenderungen etc.)
# Lehrer und Managed Nodes duerfen sie lesen, ou-eigene bekommen Standard-ACLs, ou-fremde Server/user duerfen nichts
access to dn.regex="^(.+,)?ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$"
	by group/univentionGroup/uniqueMember="cn=@$@DOMAIN_ADMINS@$@,cn=groups,@%@ldap/base@%@" +0 break
	by set.expand="[ldap:///ou=$2,@%@ldap/base@%@?ou?base?%28%21%28objectClass%3DucsschoolOrganizationalUnit%29%29]/ou" +0 break
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionLDAPACL/univentionLDAPAccessWrite.expand="ou=$2,@$@DISTRICT@$@@%@ldap/base@%@" write
	by set.expand="[$2] & ([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" +rscxd continue
	by group/univentionGroup/uniqueMember="cn=DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" +0 stop
	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" +0 stop
	by set.expand="([ldap:///]+user/entryDN+[?entryDN?base?%28%7C%28objectClass%3DucsschoolTeacher%29%28objectClass%3DucsschoolAdministrator%29%28objectClass%3DucsschoolStaff%29%29])/ucsschoolSchool" +0 stop
	by dn.regex="^.*,ou=$2,@$@DISTRICT@$@@%@ldap/base@%@$$" +rscxd break
	by dn.regex="^.*,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" +0 stop
	by * +0 break

# Replica Directory Nodes duerfen Klassen-Gruppen bearbeiten (AUSNAHME! Wird fuer Lehrerzuordnung in UMC benoetigt!)
access to dn.regex="^cn=klassen,cn=@$@PUPILS@$@,cn=groups,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" attrs=children,entry
	by group/univentionGroup/uniqueMember.expand="cn=OU$1-DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember.expand="cn=OU$1-DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by * +0 break

access to dn.regex="^cn=([^,]+),cn=klassen,cn=@$@PUPILS@$@,cn=groups,ou=([^,]+),@$@DISTRICT@$@@%@ldap/base@%@$$" filter="(objectClass=univentionGroup)" attrs=entry,@$@GROUPATTRS@$@
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by group/univentionGroup/uniqueMember.expand="cn=OU$2-DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" write
	by * +0 break

# Schoolservers are allowed to replicate passwords of all global objects
# Previously, schoolservers had no access to the password attributes of "global" users, which lead to replication failures, failed.ldifs etc.
# Access to those is denied by an ACL in 70univention-ldap-server_acl-master-end, which gives access to password attributes to all DCs which lie under cn=dc,cn=cumputers,$base
# which does not include school replicas.
# The new ACL may seem like it gives too much access - e.g access to other schools users passwordattributes (which is of course unwanted), but it doesn't.
# The ACLs which seperates the schools matches before this one. ACL evaluation is stopped before reaching this new ACL.
access to attrs=userPassword,krb5Key,krb5KDCFlags,sambaNTPassword,sambaLMPassword,sambaPwdLastSet,pwhistory,krb5KeyVersionNumber,univentionWindowsReinstall,sambaPwdCanChange,sambaPwdMustChange,sambaPasswordHistory,sambaClearTextPassword,sambaPreviousClearTextPassword
	by group/univentionGroup/uniqueMember="cn=DC-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" +rscxd
	by group/univentionGroup/uniqueMember="cn=Member-Verwaltungsnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" +rscxd
	by group/univentionGroup/uniqueMember="cn=DC-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" +rscxd
	by group/univentionGroup/uniqueMember="cn=Member-Edukativnetz,cn=ucsschool,cn=groups,@%@ldap/base@%@" +rscxd
	by * +0 break
"""

if configRegistry.get('server/role') in ('domaincontroller_master', 'domaincontroller_backup'):
	print(replace_ucr_variables(aclset))
else:
	print('# no ACL required on Replica Directory Node')
@!@

# end 65ucsschool
