##@cooked comments # -*- coding: utf-8 mode: sh -*- vim:sw=4:sts=4:et:ai:si:sta:fenc=utf-8
## Gestion du service slapd (démarrage/arrêt), et de sa configuration
##@cooked nocomments
##@require base
##@require sysinfos
uprovide ldap
urequire base sysinfos

function get_default_ldapconfdir_prefix() {
    # Calculer et afficher la valeur par défaut de LDAPCONFDIR, ou une chaine
    # vide si l'on n'a pas pu le détecter automatiquement.
    if check_sysinfos -s linux; then
        if check_sysinfos -d debianlike; then
            [ -d /etc/ldap ] && echo /etc/ldap
        elif check_sysinfos -d redhatlike; then
            [ -d /etc/openldap ] && echo /etc/openldap
        elif check_sysinfos -d gentoo; then
            [ -d /etc/openldap ] && echo /etc/openldap
        fi
    elif check_sysinfos -s darwin; then
        [ -d /etc/openldap ] && echo /etc/openldap
    fi
}

function get_default_ldapowner_prefix() {
    # Calculer et afficher la valeur par défaut de LDAPOWNER, ou une chaine
    # vide si l'on n'a pas pu le détecter automatiquement.
    if check_sysinfos -s linux; then
        if check_sysinfos -d debianlike; then
            echo openldap:openldap
        elif check_sysinfos -d redhatlike; then
            echo ldap:ldap
        elif check_sysinfos -d gentoo; then
            echo ldap:ldap
        fi
    elif check_sysinfos -s darwin; then
        echo root:wheel
    fi
}

__ldap_prefixes=
function __compute_ldap_prefixes() {
    [ -n "$__ldap_prefixes" ] && return
    LDAPCONFDIR="${LDAPCONFDIR:-$(get_default_ldapconfdir_prefix)}"
    LDAPOWNER="${LDAPOWNER:-$(get_default_ldapowner_prefix)}"
    __ldap_prefixes=1
}

LDAP_PREFIXES=(LDAPCONFDIR LDAPOWNER)
UTOOLS_PREFIXES=("${UTOOLS_PREFIXES[@]}" "${LDAP_PREFIXES[@]}")

function compute_ldap_prefixes() {
    __compute_ldap_prefixes
}

function recompute_ldap_prefixes() {
    local v
    for v in "${LDAP_PREFIXES[@]}"; do
        eval "$v="
    done
    __ldap_prefixes=
    __compute_ldap_prefixes
}

function get_LDAPCONFDIR_prefix() {
    __compute_ldap_prefixes
    echo "$LDAPCONFDIR"
}

function get_LDAPOWNER_prefix() {
    __compute_ldap_prefixes
    echo "$LDAPOWNER"
}

function split_ldapuri() {
    # spliter le ldapuri $1 en $2(=proto), $3(=host) et $4(=port)
    local ldapuri="$1" protoname="${2:-proto}" hostname="${3:-host}" portname="${4:-port}"
    local tmp
    if [ -z "$ldapuri" ]; then
        _setv "$protoname" ""
        _setv "$hostname" ""
        _setv "$portname" ""
        return 0
    fi
    tmp="$ldapuri"
    if [ "${tmp#ldap://}" != "$tmp" ]; then
        _setv "$protoname" ldap
        tmp="${tmp#ldap://}"
    elif [ "${tmp#ldaps://}" != "$tmp" ]; then
        _setv "$protoname" ldaps
        tmp="${tmp#ldaps://}"
    elif [ "${tmp#ldapi://}" != "$tmp" ]; then
        _setv "$protoname" ldapi
        tmp="${tmp#ldapi://}"
    else
        _setv "$protoname" ""
        _setv "$hostname" ""
        _setv "$portname" ""
        eerror "invalid ldapuri: $ldapuri"
        return 1
    fi
    tmp="${tmp%%/*}"
    local tmphost="${tmp%%:*}"
    _setv "$hostname" "$tmphost"
    tmp="${tmp#$tmphost}"
    _setv "$portname" "${tmp#:}"
    return 0
}

function get_suffixes() {
    # obtenir les suffixes de connexion du serveur avec l'uri $1, un par ligne
    # retourner 1 si la valeur n'a pas pu être obtenue
    local ncs
    ncs="$(ldapsearch -x ${1:+-H "$1"} -b "" -LLL -s base namingContexts)" || return 1
    <<<"$ncs" grep namingContexts: | sed 's/namingContexts: //'
}

function get_anysuffix() {
    # obtenir le *premier* suffixe du serveur avec l'uri $1
    # retourner 1 si la valeur n'a pas pu être obtenue
    local suffix
    suffix="$(get_suffixes "$1")" || return 1
    <<<"$suffix" head -n1
}

function get_dcsuffix() {
    # obtenir le *premier* suffixe du serveur avec l'uri $1 qui se termine par
    # dc=TLD où TLD est une valeur quelconque. A priori, c'est un suffixe d'une
    # base de donnée non administrative.
    # retourner 1 si la valeur n'a pas pu être obtenue
    local suffix
    suffix="$(get_suffixes "$1" | awk '/(^|,)[dD][cC]=[^,]+/ { print }')" || return 1
    <<<"$suffix" head -n1
}

function get_suffix() {
    # obtenir le *premier* suffixe du serveur avec l'uri $1 qui se termine si
    # possible par dc=TLD où TLD est une valeur quelconque. Dans le cas normal,
    # le suffixe affiché est celui d'une base non administrative.
    # retourner 1 si la valeur n'a pas pu être obtenue
    local suffixes suffix
    suffixes="$(get_suffixes "$1")" || return 1
    suffix="$(<<<"$suffixes" awk '/(^|,)[dD][cC]=[^,]+/ { print }')"
    [ -n "$suffix" ] || suffix="$suffixes"
    <<<"$suffix" head -n1
}

function reldn() {
    local dn="$(strlower "$1")"
    local suffix="$(strlower "${2:-$SUFFIX}")"

    # exprimer le dn $1 relativement au suffixe $2(=$SUFFIX)
    if [ -z "$suffix" ]; then
        echo "$1"
    elif [ -z "$dn" -o "$dn" == "$suffix" ]; then
        echo ""
    elif [ "${dn%,$suffix}" != "$dn" ]; then
        # absolu, enlever $suffix
        echo "${1:$((${#dn} - ${#suffix}))}"
    else
        # relatif
        echo "$1"
    fi
}

function _absdn() {
    local dn="$(strlower "$1")"
    local suffix="$(strlower "$2")"

    # obtenir le dn absolu correspondant au dn $1, le dn de base étant $2
    if [ -z "$suffix" ]; then
        echo "$1"
    elif [ -z "$dn" -o "$dn" == "$suffix" ]; then
        echo "$2"
    elif [ "${dn%,$suffix}" != "$dn" ]; then
        # absolu
        echo "$1"
    else
        # relatif, ajouter $suffix
        echo "$1,$2"
    fi
}

function absdn() {
    # obtenir le dn absolu correspondant au dn $1, le dn de base étant
    # $2(=$SUFFIX)
    _absdn "$1" "${2:-$SUFFIX}"
}

function subof() {
    # tester si le dn absolu $1 est $2 ou un enfant de $2
    local dn="$(strlower "$1")"
    local par="$(strlower "$2")"
    [ "$dn" == "$par" -o "${dn%,$par}" != "$dn" ]
}

function rabsdn() {
    # comme absdn, mais tient compte de la valeur de $3(=$SEARCHBASE)
    # Si le dn commence par "~/", le dn est relatif à $2(=$SUFFIX)
    # Si le dn commence par "/", le dn est absolu
    # Sinon, le dn est relatif à $3
    local dn="$1" suffix="${2:-$SUFFIX}" searchbase="${3:-$SEARCHBASE}"

    # corriger les expansions éventuelles du shell
    if [ "$dn" == "$HOME" ]; then
        dn="~"
    elif [ "${dn#$HOME}" != "$dn" ]; then
        dn="~${dn#$HOME}"
    fi
    # calculer le dn absolu
    if [ "${dn#/}" != "$dn" ]; then
        echo "${dn#/}"
    elif [ "$dn" == "~" ]; then
        echo "$suffix"
    elif [ "${dn#\~/}" != "$dn" ]; then
        _absdn "${dn#\~/}" "$suffix"
    else
        _absdn "$dn" "$searchbase"
    fi
}

function pdn() {
    # corriger pour *affichage* un dn *absolu*. pour la racine "", afficher
    # '/'. pour $2(=$SUFFIX), afficher '~'. sinon, afficher le dn relativement à
    # $2
    local suffix="${2:-$SUFFIX}"
    if [ -z "$1" ]; then
        echo "/"
    elif [ "$1" == "$suffix" ]; then
        echo "~"
    elif [ "${1%,$suffix}" != "$1" ]; then
        echo "$(reldn "$1")"
    else
        echo "/$1"
    fi
}

function filter_slapdconf() {
    # Traiter un fichier de configuration slapd.conf en fusionnant les lignes
    # qui sont découpées. Ceci permet de faire des traitements sur le contenu.
    # Ce filtre s'utilisera normalement avec filter_conf, e.g.:
    #     <slapd.conf filter_slapdconf | filter_conf >result.conf
    awk '
BEGIN { line = ""; valid = 0; }
/^[ \t]/ { line = line $0; next; }
{ if (valid) print line; line = $0; valid = 1; }
END { if (valid) print line; }
'
}
