#!/bin/sh
# Based on
# <URL: https://fedorahosted.org/sssd/wiki/Configuring%20sssd%20to%20authenticate%20with%20a%20Windows%202008%20Domain%20Server >

set -e

# See if we can find an Active Directory LDAP server.
lookup_ad_server() {
    dnsdomain="$1"
    adserver=$(host -N 2 -t SRV _ldap._tcp.$dnsdomain | egrep -v 'NXDOMAIN|^;' | awk '{print $NF}' | head -1)
    if [ "$adserver" ] ; then
	echo $adserver | sed 's/\.$//'
    fi
}

lookup_ad_realm() {
    ldapuri="$1"
    realm=$(ldapsearch -LLL -x -H $ldapuri. -b '' -s base ldapServiceName | grep ldapServiceName: | cut -d@ -f2)
    echo $realm
}

find_dns_domain() {
    if [ "$1" ] ; then
	domain=$1
    else
	domain="$(hostname -d 2>/dev/null || true)"
	# If hostname is not FQDN, look in DNS setup instead, to
	# increase the chance of the automatic setup to work.
	if [ -z "$domain" ] || [ "(null)" = "$domain" ] || [ "localdomain" = "$domain" ]; then
	    domain=$(grep search /etc/resolv.conf |awk '{print $2}')
	fi
    fi
    echo $domain
}

ldap_is_active_directory() {
    ldapuri="$1"
    # OpenLDAP do not have defaultNamingContext in the root LDAP
    # object, while Active Directory do.
    if ldapsearch -LLL -H "$ldapuri" -x -b '' -s base 2>/dev/null | \
	grep -q defaultNamingContext ; then
	true
    else
	false
    fi
}

lookup_ldap_base() {
    ldapuri="$1"
    defaultcontext="$(ldapsearch -LLL -H "$ldapuri" -x -b '' -s base defaultNamingContext  2>/dev/null | awk '/^defaultNamingContext: / { print $2}')"
    if [ -z "$defaultcontext" ] ; then
	:
    else
	echo $defaultcontext
    fi
}

setup_smbconf() {
    adserver="$1"
    realm="$2"
    workgroup="$3"
    cat > /etc/samba/smb.conf <<EOF
[global]
   workgroup = $workgroup
   client signing = yes
   client use spnego = yes
   kerberos method = secrets and keytab
   log file = /var/log/samba/%m.log
   password server = $adserver
   realm = $realm
   security = ads
EOF
}
bindir=$(dirname $0)

# Make sure the packages we need are installed
apt-get install -qy host ldap-utils samba-common

dnsdomain=$(find_dns_domain "$1")

adserver=$(lookup_ad_server $dnsdomain)

if [ -z "$adserver" ] ; then
    echo "error: Unable to find AD server using SRV records in $dnsdomain"
    exit 1
fi

ldapuri=ldap://$adserver

if ! ldap_is_active_directory $ldapuri ; then
    echo "error: Detected LDAP server $ldapuri is not an Active Directory server"
    exit 1
fi

realm=$(lookup_ad_realm $ldapuri)

if [ -z "$realm" ] ; then
    echo "error: Unable to find Kerberos realm using AD server $ldapuri"
    exit 1
fi
ldapbase="$(lookup_ldap_base "$ldapuri")"

echo "********************************************"
echo "Setting up AD client using"
echo "  $adserver as AD server,"
echo "  $realm as Kerberos realm and"
echo "  $ldapbase as LDAP base"
echo "********************************************"

cat <<EOF | debconf-set-selections
nslcd   nslcd/ldap-uris string  ldap://$adserver/
nslcd   nslcd/ldap-base string  $ldapbase
EOF

# Set up roaming profile and AD connection for PAM and NSS (using sssd)
$bindir/setup-roaming


cat > /etc/krb5.conf <<EOF
[logging]
 default = FILE:/var/log/krb5libs.log

[libdefaults]
 default_realm = $realm
 dns_lookup_realm = true
 dns_lookup_kdc = true
 ticket_lifetime = 24h
 renew_lifetime = 7d
 rdns = false
 forwardable = yes

# You may also want either of:
# allow_weak_crypto = true
# default_tkt_enctypes = arcfour-hmac

[realms]
# Define only if DNS lookups are not working
# $realm = {
#  kdc = server.ad.example.com
#  admin_server = server.ad.example.com
# }

[domain_realm]
# Define only if DNS lookups are not working
# .ad.example.com = $realm
# ad.example.com = $realm
EOF

# Create dummy file to get "net ads lookup" working
setup_smbconf "$adserver" "$realm" "UNKNOWN"
workgroup="$(net ads lookup|awk '/Pre-Win2k Domain:/ { print $3}')"
setup_smbconf "$adserver" "$realm" "$workgroup"
echo
echo "Log in as domain administrator to register machine in Active Directory"
echo
printf "AD username to use [Administrator]: "
read adminaduser
if [ -z "$adminaduser" ] ; then
    adminaduser=Administrator
fi
net ads join -U $adminaduser

invoke-rc.d sssd restart
