#!/bin/bash

# Upper-case any string passed in as a parameter, print to stdout.
upcase() {
	echo "$@" | tr '[a-z]' '[A-Z]'
}

# Convert any domain name passed in as a parameter to a distinguished name.
domain2dn() {
	echo "$@" | sed -e 's|^|DC=|g' -e 's|\.|,DC=|g'
}

# Look up the host named in the SRV record for $1 in the AD domain.
srv() {
	dig $1.$adrealm srv ${2:+@$2} | grep -v ^\; | grep -i "IN SRV" | awk '{print $NF}' | sed 's,\.$,,'
}

# Concatenate the contents of multiple lines of text into one.
concatenate() {
	local data=
	while read line ; do
		data="${data}${data:+${1:- }}$line"
	done
	echo "$data"
}

# Echo a string and run it.
echorun() {
	echo "[" "$@" "]"
	if $dryrun ; then
		true
	else
		"$@"
	fi
}

# Print the help message AND exit.
help() {
	echo Usage: `basename $0` OPTIONS
	echo Recognized options:
	echo -e "\t-d DOMAIN"
	echo -e "\t--domain DOMAIN"
	echo -e "\t--domain=DOMAIN"
	echo -e "\t\tSpecify the Active Directory domain name."
	echo -e "\t-u Administrator[%password]"
	echo -e "\t--user Administrator[%password]"
	echo -e "\t--user=Administrator[%password]"
	echo -e "\t\tSpecify the user who will join the system to the network."
	echo -e "\t--dry-run"
	echo -e "\t\tPrint the commands which would be run, but don't run them."
	echo -e "\t--nostart"
	echo -e "\t\tRun commands but don't start any services."
	echo -e "\t-v"
	echo -e "\t--verbose"
	echo -e "\t\tPrint discovered information."
	exit 1
}

# Guess at what our AD domain is named.  Assume it won't be "localdomain".
if hostname | grep -q '\.' ; then
	# The FQDN should have at least three parts (right?), the host part,
	# and a domain name which itself contains a ".".
	if test -n "`hostname | cut -f3 -d.`" ; then
		localdomain=`hostname | cut -f2- -d.`
		if test "$localdomain" != "localdomain" ; then
			defaultrealm="$localdomain"
		fi
	fi
fi

# Parse command-line arguments.
user=Administrator
domain=$defaultrealm
verbose=false
dryrun=false
start=true
if test $# -eq 0 ; then
	help
fi
while test -n "$1" ; do
case "$1" in
	--user=*)
		user=`echo "$1" | cut -f2- -d=`
		;;
	--user|-u)
		shift
		user="$1"
		;;
	--domain=*)
		domain=`echo "$1" | cut -f2- -d=`
		;;
	--domain|-d)
		shift
		domain="$1"
		;;
	--dry-run)
		dryrun=true
		;;
	--verbose|-v)
		verbose=true
		;;
	--help|-h)
		help
		;;
	--nostart)
		start=false
		;;
	*)
		echo Unrecognized option: $1
		help
		;;
esac
shift
done

adrealm=${domain}
krb5realm=`upcase $adrealm`
ntdomain=`upcase $adrealm | cut -f1 -d.`
servers=`srv _kerberos._tcp.default-first-site-name._sites | concatenate ,`
basedn=`domain2dn "$adrealm"`

if test -z "$servers" ; then
	echo ERROR: could not locate domain controllers for domain \"$adrealm\".
	echo Please ensure that your DNS includes SRV records which can be used to locate
	echo servers for the Active Directory domain and try again.
	exit 1
fi
if $verbose ; then
	echo "[" Active Directory Realm Name: $adrealm "]"
	echo "[" Kerberos Realm Name: $krb5realm "]"
	echo "[" NT Domain Name: $ntdomain "]"
	echo "[" Domain Controllers: $servers "]"
	echo "[" LDAP Base Distinguished Name: $basedn "]"
fi
echorun /usr/sbin/authconfig --kickstart --nostart \
	--enablekrb5 \
	--krb5realm=$krb5realm \
	--krb5kdc=$servers \
	--enablekrb5kdcdns \
	--enablekrb5realmdns \
	--smbworkgroup=$ntdomain \
	--smbservers=$servers \
	--enablewinbind \
	--smbsecurity=ads \
	--smbrealm=$krb5realm \
	--winbindtemplateshell=/bin/bash \
	--enablewinbindusedefaultdomain \
	--ldapserver="$servers" \
	--ldapbasedn="$basedn" \
	--enablecache
test -x /usr/sbin/ntpdate && echorun /usr/sbin/ntpdate `echo "$servers" | cut -f1 -d,`
echorun /usr/bin/net join ${user:+-U "$user"}
if $start ; then
	if runlevel 2> /dev/null > /dev/null ; then
		if test $? -eq 0 ; then
			echorun /usr/sbin/authconfig --kickstart
		fi
	fi
fi

