#!/bin/bash

set -e

echo "Indiquez le suffixe (ex.: dc=dauphine,dc=fr):"
echo -n "-> "
read SUFFIX
echo

if ldapsearch -H ldapi:// -Y EXTERNAL -b cn=config olcSuffix=$SUFFIX 2>/dev/null | grep -q '^result: [1-9]'; then
	echo "ERROR: le suffixe $SUFFIX existe déjà" >&2
	exit 1
fi

if [ -d "/var/lib/ldap/$SUFFIX" ]; then
	echo "ERROR: le répertoire de donnée '/var/lib/ldap/$SUFFIX' existe déjà" >&2
	exit 1
fi

echo "Indiquez le mot de passe de l'administrateur (uid=admin,ou=people,$SUFFIX):"
echo -n "-> "
read PASSWORD
echo

echo "Donnez le nom de l'organisation:"
echo -n "-> "
read ORGANIZATION
echo

echo "Indiquez le code de l'établissement, préfixé par son origine, ex.:"
echo " - {UAI}0350936C pour désigner l'université de Rennes 1"
echo " - {SIRET}18004312700067 pour désigner l'AMUE"
echo " - {CNRS}MOY1400 pour désigner la délégation régionale de Toulouse du CNRS"
echo -n "-> "
read CODEETB
echo

echo Récapitulatif:
echo "Suffixe: $SUFFIX"
echo "Mot de passe admin: $PASSWORD"
echo "Nom de l'établissment: $ORGANIZATION"
echo "Code UAI de l'établissemen: $CODEETB"
echo
echo "Voulez-vous créer cet annuaire? (oui/non)"
echo -n "-> "
read OK
echo

if [ "x$OK" != "xoui" ]; then
	exit 0
fi

DC=`echo $SUFFIX | sed 's/dc=\([^,]*\).*/\1/'`
DBDIR=/var/lib/ldap/$SUFFIX
DBACCESSLOGDIR=/var/lib/ldap/$SUFFIX/accesslog/

mkdir -p "$DBDIR" "$DBACCESSLOGDIR"
chown openldap.openldap "$DBDIR" "$DBACCESSLOGDIR"

LDIF=`tempfile --prefix=create-branch --suffix=.ldif`
cat <<EOF >$LDIF
# LDAPVI syntax
add olcDatabase={1}mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcDatabase: {1}mdb
olcSuffix: $SUFFIX
olcDbDirectory: /var/lib/ldap/$SUFFIX/
olcRootDN: uid=admin,ou=people,$SUFFIX
olcRootPW: $PASSWORD
olcLastMod: TRUE
olcAddContentACL: FALSE
olcMonitoring: TRUE
olcSyncUseSubentry: FALSE
olcMaxDerefDepth: 0
olcLimits: {0}dn.exact="uid=admin,ou=people,$SUFFIX" size.soft=unlimited  size.hard=unlimited  time.soft=unlimited  time.hard=unlimited
olcLimits: {1}dn.exact="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" size.soft=unlimited  size.hard=unlimited  time.soft=unlimited  time.hard=unlimited
olcReadOnly: FALSE
olcAccess: {0}to * 
  by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
  by group=cn=admin,ou=groupes,$SUFFIX manage
  by * break
# *FIXME apply more thinking to ACLs*

# Create accesslog DIT
add olcDatabase={1}mdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcMdbConfig
olcSuffix: cn=accesslog,$SUFFIX
olcDbDirectory: /var/lib/ldap/$SUFFIX/accesslog/
olcAccess: {0}to * 
  by dn.exact=gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth manage
  by group=cn=admin,ou=groupes,$SUFFIX manage
  by * break

add olcOverlay={0}syncprov,olcDatabase={1}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcSyncProvConfig
olcOverlay: {0}syncprov
olcSpCheckpoint: 100 10
olcSpSessionlog: 100

# Log all writes to the db
add olcOverlay={1}accesslog,olcDatabase={2}mdb,cn=config
objectClass: olcAccesslogConfig
objectClass: olcOverlayConfig
objectClass: olcConfig
objectClass: top
olcOverlay: {1}accesslog
olcAccessLogDB: cn=accesslog,$SUFFIX
olcAccessLogOps: writes
# log are conserved one year and purged every day
olcAccessLogPurge: 365+00:00 1+00:00
# Keep a copy of everything
olcAccessLogOld: objectClass=*

add olcOverlay={2}refint,olcDatabase={2}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcRefintConfig
olcOverlay: {2}refint
olcRefintAttribute: member 
  eduPersonOrgDN 
  eduPersonOrgUnitDN
  owner
  eduPersonPrimaryOrgUnitDN
  supannGroupeAdminDN
  supannGroupeLecteurDN
  supannParrainDN
olcRefintNothing: $SUFFIX

add olcOverlay={3}constraint,olcDatabase={2}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcConstraintConfig
olcOverlay: {3}constraint
# un seul cn pour les utilisateurs
olcConstraintAttribute: cn count 1 restrict="ldap:///ou=people,$SUFFIX??sub?(objectClass=*)" 
#olcConstraintAttribute: cn regex "^[-A-Z' ]*$" restrict="ldap:///ou=people,$SUFFIX??sub?(objectClass=*)" 
olcConstraintAttribute: cn regex "^[-A-Za-z0-9 ]*$" restrict="ldap:///ou=groups,$SUFFIX??sub?(objectClass=*)" 
olcConstraintAttribute: cn regex "^[-A-Za-z0-9 ]*$" restrict="ldap:///$SUFFIX??base?(objectClass=*)" 
olcConstraintAttribute: dc regex "^[a-z0-9-]*$" 
olcConstraintAttribute: displayName,sn,givenName set "(this/givenName + [ ] + this/sn) & this/displayName" restrict="ldap:///ou=people,$SUFFIX??sub?(objectClass=*)" 
olcConstraintAttribute: eduOrgHomePageURI,eduOrgSuperiorURI,eduOrgWhitePagesURI regex "^https?://.*$" 
olcConstraintAttribute: eduPersonAffiliation regex "^(student|faculty|staff|employee|member|affiliate|alum|library-walk-in|researcher|retired|emeritus|teacher|registered-reader)$" 
olcConstraintAttribute: eduPersonPrincipalName regex "^.*@.*$" 
olcConstraintAttribute: mail count 1
olcConstraintAttribute: mail,supannMailPerso,supannAutreMail 
  regex "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$" 
# olcConstraintAttribute: mailForwardingAddress 
  regex "^([A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}|[a-z0-9]+)$" # mail ou uid
olcConstraintAttribute: supannAliasLogin regex "^[[:alnum:]]+$" 
olcConstraintAttribute: supannCodeEntiteParent,supannEntiteAffectation uri  ldap:///ou=structures,$SUFFIX?supannCodeEntite?sub?(objectClass=supannEntite)
olcConstraintAttribute: supannCodeINE count 1
olcConstraintAttribute: supannEmpId count 1
# FIXME: syntex regex pas bonne
olcConstraintAttribute: supannCivilite regex "^(M.|Mme|Mlle)$" 
olcConstraintAttribute: supannTypeEntite,supannEtuCursusAnnee regex "^\{SUPANN\}[A-Z][0-9]+$" 
# attribut issu d'une nomenclature
olcConstraintAttribute: supannEtablissement,
 supannEtuDiplome,
 supannEtuElementPedagogique,
 supannEtuEtape,
 supannEtuRegimeInscription,
 supannEtuSecteurDisciplinaire,
 supannEtuTypeDiplome,
  regex "^\{[^}]+\}.*$" 
olcConstraintAttribute: supannEtuAnneeInscription regex "^[0-9][0-9][0-9][0-9]$" 

add olcOverlay={4}unique,olcDatabase={2}mdb,cn=config
objectClass: olcOverlayConfig
objectClass: olcUniqueConfig
olcOverlay: {4}unique
olcUniqueURI: ldap://?supannAutreMail?sub

add $SUFFIX
objectClass: organization
objectClass: dcObject
objectClass: eduOrg
objectClass: supannOrg
dc: $DC
o: $ORGANIZATION
supannEtablissement: $CODEETB

add ou=people,$SUFFIX
objectClass: organizationalUnit
ou: people

add uid=admin,ou=people,$SUFFIX
objectClass: inetOrgPerson
objectClass: eduPerson
objectClass: supannPerson
uid: admin
cn: Administrateur annuaire
displayName: Administrateur annuaire
givenName: Administrateur
sn: annuaire
supannListeRouge: TRUE
userPassword: $PASSWORD
supannEtablissement: $CODEETB

add ou=structures,$SUFFIX
objectClass: organizationalUnit
ou: structures

add ou=groups,$SUFFIX
objectClass: organizationalUnit
ou: groups

add cn=admin,ou=groups,$SUFFIX
objectClass: groupOfNames
objectClass: supannGroupe
cn: admin
description: Groupe des administrateurs de l'annuaire
member: uid=admin,ou=people,$SUFFIX
EOF
echo -n Chargement de la définition du nouvelle annuaire dans $LDIF..
ldapvi --profile config --ldapmodify --ldapvi --add $LDIF
echo " FAIT"
