#!/bin/sh -f

. alterator-openldap-functions


# find_dn dc=my,dc=domain,dc=com
# => /etc/openldap/slapd-my.domain.com.conf
# or
# find_dn
# => /etc/openldap/slapd-my1.domain.com.conf
# => /etc/openldap/slapd-my2.domain.com.conf
# => /etc/openldap/slapd-my1....
find_dn()
{
    local dn=
    [ "$#" -ge 1 ] && dn="$1" && shift

    for conf in $(read_slapd_conf include|egrep -i "slapd-[.a-z0-9_-]+\.conf[[:blank:]]*$") ;do
        if [ -z "$dn" ] ;then
            local suffix="$(read_config "$conf" suffix)"
            [ -z "$suffix" ] || echo "$suffix $conf"
        else
            read_config "$conf" suffix|egrep -qw "^$dn$" && echo "$conf"
        fi
    done
}


# to_realm my.domain.ru
# => MY.DOMAIN.RU
to_realm()
{
    echo "$1"|tr '[[:lower:]]' '[[:upper:]]'
}

check_dn_name()
{
    # please fix regexp
    echo "$1"|egrep -qi "^dc=[a-z][a-z0-9_-]*(,dc=[a-z][a-z0-9_-]*)*$" ||
    fatal "$0: check_dn_name: invalid suffix dn '$name'" 
    
    [ -n "$(find_dn "$1")" ] && fatal "check_dn_name: basedn '$1' already exists"
}

create_dn()
{
    local dn="$1"
    local domain=$(dn_2_host "$dn")
    local realm="$(to_realm "$domain")"
    local basedir=${SLAPD_CONF%/*}	
    local template="$basedir/slapd-template.conf"
    local new_dn_conf="$basedir/slapd-$domain.conf"
    local passwd=$(pwgen -n 16 -1)

    #copy template into slapd-domain.conf
    cp "$template" "$new_dn_conf"
    chmod 640 "$new_dn_conf"
    chown root:ldap "$new_dn_conf"

    #fix dc=. base, password
    sed -i -e "s/dc=template/$dn/g" $new_dn_conf
    sed -i -e "s/template/$domain/g" $new_dn_conf
    sed -i -e "s/REALM/$realm/g" $new_dn_conf
    sed -i -e "s/secret/$passwd/g" $new_dn_conf

    echo "include $new_dn_conf" >>  "$SLAPD_CONF"

    export DN_CONF="$new_dn_conf"
    base_rootdn_rootpw
    ldap-init 

    /etc/init.d/slapd restart >/dev/null   
}

delete_dn()
{
    local dn="$1"
    local domain=$(dn_2_host "$dn")
    local basedir="${SLAPD_CONF%/*}"
    local dn_conf="$(find_dn "$dn")"
    [ -f "$dn_conf" ] || fatal "delete_dn: no such file '$dn_conf'" 
    local dn_base_file="$(read_config "$dn_conf" directory)"

    rm -f -- "$dn_conf"
    rm -rf -- "$dn_base_file"
    dn_conf="$(quote_sed_regexp $dn_conf)"
    sed -r -i -e "/^include[[:blank:]]+$dn_conf[[:blank:]]*$/ d" "$SLAPD_CONF"

    /etc/init.d/slapd restart >/dev/null 2>&1
}

rename_dn()
{
    local old="$1" ; shift
    local new="$1" ; shift
    local oldhost="$(dn_2_host "$old")"
    local newhost="$(dn_2_host "$new")"
    local databasedir=""
    local oldname=""
    local newname=""


    TMPFILE="$(mktemp -t "$oldhost.XXXXXXXXXX")" || fatal "can't create tempfile"
   
    #slapcating old database
    /etc/init.d/slapd stop && slapcat -b "$old" -l "$TMPFILE"
   
    #substitution dc=old to dc=new
    sed -r -i -e "s/$(quote_sed_regexp $old)/$(quote_sed_regexp $new)/g" "$TMPFILE"
    # changing 'dc: '
    oldname="$(quote_sed_regexp "$(echo "$oldhost"|cut -f1 -d'.')")"
    newname="$(quote_sed_regexp "$(echo "$newhost"|cut -f1 -d'.')")"
    sed -r -i -e "s/dc:[[:space:]]$oldname/dc: $newname/" "$TMPFILE"

    #substitution cn=OLDDOMAIN to cn=NEWDOMAIN (KDC)
    oldname="$(to_realm $oldhost)"
    newname="$(to_realm $newhost)"
    sed -r -i -e "s/cn=$oldname/cn=$newname/g" "$TMPFILE"
    #substitution @OLDDOMAIN to @NEWDOMAIN (KDC)
    sed -r -i -e "s/@$oldname/@$newname/g" "$TMPFILE"

    #substitution olddomain to newdomain
    sed -r -i -e "s/$oldhost/$newhost/g" "$TMPFILE"
   
    #fixing main slapd conf
    sed -r -i -e "s/^include[[:space:]]+$(quote_sed_regexp "/etc/openldap/slapd-$oldhost.conf")$/include $(quote_sed_regexp "/etc/openldap/slapd-$newhost.conf")/" "$MAIN_SLAPD_CONF"

    #moving old to new
    mv "/etc/openldap/slapd-$oldhost.conf" "/etc/openldap/slapd-$newhost.conf"
   
    #changing dc=old to dc=new
    sed -r -i -e "s/$(quote_sed_regexp $old)/$(quote_sed_regexp $new)/g" "/etc/openldap/slapd-$newhost.conf"
   
    #database dir with OLD directory value
    databasedir="$(read_config "/etc/openldap/slapd-$newhost.conf" directory)"
   
    #removing old database dir with database
    rm -rf "$databasedir" || fatal "can't remove old database dir"
   
    #changing directory value
    sed -r -i -e "s/^directory[[:space:]].+/directory $(quote_sed_regexp "/var/lib/ldap/bases/$newhost")/" "/etc/openldap/slapd-$newhost.conf" 
   
    #database dir with NEW directory value
    databasedir="$(read_config "/etc/openldap/slapd-$newhost.conf" directory)"
   
    #adding changed ldif
    mkdir -p "$databasedir"
    chmod 700 "$databasedir"
    slapadd -c -b "$new" -l "$TMPFILE"
    chown -R ldap:ldap "$databasedir"
   
    /etc/init.d/slapd start
    rm -f "$TMPFILE" >&2
}

action="$1" ; shift
[ $# -eq 1 ] && object="$1" && shift
[ $# -eq 2 ] && old="$1" && new="$2"


case $action in
    create)
        [ -z "$object" ] && fatal "basedn not set" 
        check_dn_name $object 
        create_dn $object
    ;;
    delete)
        [ -z "$object" ] && fatal "object not set" 
        delete_dn $object	
    ;;
    find)
        [ -z "$object" ] && fatal "object not set"
        find_dn "$object"
    ;;
    list)
        find_dn
    ;;
    master)
    master_conf="/etc/alterator/openldap/master.conf"
    if [ -n "$object" ] ;then
        cfile="$(find_dn "$object")"
        [ -z "$cfile" ] || ln -sf "$cfile" "$master_conf"
    else
        if [ -h "$master_conf" ] ;then
            cfile=$(readlink "$master_conf")
            [ -s "$cfile" ] && echo "$(read_config "$cfile" suffix) $cfile"
        fi
    fi
    ;; 
#    rename)
#        [ -z "$old" -o -z "$new" ] && fatal "old domain or new domain not set" 
#        rename_dn "$old" "$new"
#    ;;
    *)
    echo "usage"
    echo "$0 find dc=my,dc=domain,dc=ru"
    echo "or"
    echo "$0 create dc=my,dc=domain,dc=ru"
    echo "or"
    echo "$0 delete dc=my,dc=domain,dc=ru"
    echo "or"
    echo "$0 list"
    echo "or"
    echo "$0 master [dc=my,dc=domain,dc=ru]"
#    echo "or"
#    echo "$0 rename dc=myold,dc=domain,dc=ru dc=mynew,dc=domain,dc=ru"
    ;;
esac


