
# TODO: use optional SSH tunnelling for LDAP access.

LDAPUSER=cn=schemareader,ou=Users,o=Example 
LDAPPASS=xxxxxx
LDAPADMIN=cn=admin,ou=Users,o=Example

# Fetches the schema from the requested host.
%-schema.ldif: Makefile
	ldapsearch -H "ldaps://$*/" -D $(LDAPUSER) -w $(LDAPPASS) -b cn=schema -s base attributeTypes objectClasses >$@
	grep -q '^result: 0 Success' $@
	
# Sorts the schema by declaration type and OID, removes comments etc.
%-schema-ordered.ldif: %-schema.ldif
	../helpers/ldif-normalise < $< > $@

# Combines all master schema files to one big one, and convert from LDIF
# modification format to LDIF result format.
# The script ../../scripts/ldif-edir2dirsrv.sh makes a similar conversion.
master-schema.ldif: $(wildcard master/*.ldif)
	echo 'dn: cn=schema' >$@
	sed '/^\(attribute[tT]ypes\)*\(object[cC]lasses\)*: /,/^$$/!d' $^ | \
	sed '/^ *\(#.*\)*$$/d' >>$@

%-oid-list.txt: %-schema-ordered.ldif
	cut -d' ' -f3 -s $< >$@

%-name-list.txt: %-schema-ordered.ldif
	grep -o "NAME '[^']*'" $< | cut -d"'" -f2 >$@

# Fetches only attributes and classes that are (re)defined in our master
# schema.  This is needed for synthesising the appropriate "delete:"s.
# The rule depends on the feature (which even I find esoteric) that there
# cannot be a beginning of a word and an end of a word at the same place.
%-schema-selected.ldif: %-schema-ordered.ldif master-oid-list.txt master-name-list.txt
	egrep "^dn:|\\<1.3.6.1.4.1.16161.4|NAME '(`cat master-name-list.txt | tr \\\\012 '|'`)'|\\<(`cat master-oid-list.txt | tr \\\\012 '|'`)\\>" $< >$@

# Forms a schema modification list from the existing situation and the
# target situation (master schema).
# Basically, this forms a delete for all schema elements that exist in
# both the master schema and the downloaded schema, and an add for all
# schema elements in the master schema.
%-updates.txt: %-schema-selected.ldif master-schema-ordered.ldif
	( sed 's/^/d /' $<; sed 's/^/a /' master-schema-ordered.ldif ) >$@

# Arranges the updates thus:
# 1. adds and deletes for the same name (or OID) are combined into a change.
# 2. remaining (non-paired) adds are placed first, then changes, then deletes.
# 3. deletes of classes are placed before deletes of attributes.
%-updates-combined.txt: %-updates.txt combine-updates.awk
	sort -f -k6,6 -k4,4 -k1,1 $< | awk -f combine-updates.awk | \
	sed 's/^d object/d 1object/' | sort | sed 's/^d 1object/d object/' >$@

# read in the updates in lined format and transform them into LDIF.
%-update.ldif: %-updates-combined.txt fix-impossible-updates.sed convert-updates-into-ldif.sed
	sed -f fix-impossible-updates.sed $< | \
	sed -f convert-updates-into-ldif.sed >$@

# Copies the schema modification LDIF on the requested host and reads it
# in with ldapmodify.
%-update: %-update.ldif
	ldapmodify -v -H "ldaps://$*/" -D $(LDAPADMIN) -W -c -S err.ldif -f $<

