#!/bin/sh
#
# $FreeBSD$
#

# PROVIDE: ix-activedirectory
# REQUIRE: ix-pre-samba ix-kinit
# BEFORE: samba_server

. /etc/rc.freenas

: ${NSS_LDAP_CONF:="/usr/local/etc/nss_ldap.conf"}
: ${LDAP_CONF:="/usr/local/etc/openldap/ldap.conf"}

get_basename()
{
	local domainname="${1}" 

	base=$(echo "${domainname}" | awk '{
		n = split($0, parts, ".");
		if (n > 0) {
			base = sprintf("dc=%s", parts[1]);
			for (i=2;i <= n;i++) {
				base = sprintf("%s,dc=%s", base, parts[i]);
			}
			printf("%s", base);
		}
	}')

	echo "${base}"
}

generate_ldap_conf()
{
	local ldapconf="${LDAP_CONF}"
	local dcname="$(AD_get ad_dcname)"
	local domainname="$(AD_get ad_domainname)"
	local basedn="$(get_basename "${domainname}")"

	echo "HOST ${dcname}" > "${ldapconf}"
	echo "BASE ${basedn}" >> "${ldapconf}"
}

generate_nss_ldap_conf()
{
	local nssconf="${NSS_LDAP_CONF}"
	local secret="${NSS_LDAP_SECRET}"
	local dcname="$(AD_get ad_dcname)"
	local domainname="$(AD_get ad_domainname)"
	local bindname="$(AD_get ad_bindname)"
	local bindpw="$(AD_get ad_bindpw)"
	local base="$(get_basename "${domainname}")"

	[ -z "${dcname}" -o -z "${base}" ] && return 1 

	cat <<-EOF > "${nssconf}"
	host ${dcname}
	base ${base}
	uri ldap://${dcname}/
	rootbinddn ${bindname}@${domainname}
	scope sub
	ssl no
	ldap_version 3
	timelimit 30
	bind_timelimit 30
	bind_policy soft
	pam_ldap_attribute uid
	nss_base_passwd ${base}?sub
	nss_base_shadow ${base}?sub
	nss_base_group ${base}?sub? &(objectCategory=group)(gidnumber=*)
	nss_map_objectclass posixAccount user
	nss_map_objectclass shadowAccount user
	nss_map_objectclass posixGroup group
	nss_map_attribute gecos cn
	nss_map_attribute homeDirectory unixHomeDirectory
	nss_map_attribute uniqueMember member
	pam_filter objectClass=user
	pam_member_attribute member
	pam_password ad

EOF
	printf "${bindpw}" > "${secret}"
	chmod 600 "${secret}"

	ln -sf ${nssconf} "$(dirname ${nssconf})/ldap.conf" 2>/dev/null
	ln -sf ${secret} "$(dirname ${secret})/ldap.secret"

	return 0
}


get_trusted()
{
	${FREENAS_SQLITE_CMD} ${FREENAS_CONFIG} "
	SELECT
		ad_allow_trusted_doms

	FROM
		directoryservice_activedirectory

	ORDER BY
		-directoryservice_activedirectory.id

	LIMIT 1;
	"
}

get_cifs_homedir()
{
	${FREENAS_SQLITE_CMD} ${FREENAS_CONFIG} "
	SELECT
		cifs_path

	FROM
		sharing_cifs_share

	WHERE
		cifs_home = 1

	ORDER BY
		-sharing_cifs_share.id

	LIMIT 1;
	"
}

has_unix_extensions()
{
	local ad_unix=$(${FREENAS_SQLITE_CMD} ${FREENAS_CONFIG} "
	SELECT
		ad_unix_extensions

	FROM
		directoryservice_activedirectory

	ORDER BY
		-id

	LIMIT 1;
	")

	if [ "${ad_unix}" = "1" ]
	then
		return 0
	fi

	return 1
}


setup_homedirs()
{
	local trusted=$(get_trusted)
	local cifs_home="$(get_cifs_homedir)"

	if [ -n "${cifs_home}" ]
	then
		ln -sfh "$cifs_home" "/home"

		if [ "${trusted}" = "1" ]
		then
			local partitions="$(AD_query_partitions)"
			for p in ${partitions}
			do
				mkdir -p "/home/${p}"
			done

		else
			local workgroup=$(AD_get ad_netbiosname)
			local homedir="/home/${workgroup}"

			mkdir -p "${homedir}"
			/usr/local/bin/winacl -a reset -p "${homedir}"
		fi

	elif [ ! -d "/home" ]
	then
		mkdir /home
	fi
}

activedirectory_start()
{
	if dirsrv_enabled activedirectory
	then
		AD_init

		/usr/local/libexec/nas/generate_ldap_conf.py

		AD_log "activedirectory_start: trying to join domain"
		if ! AD_join_domain
		then
			/etc/directoryservice/ActiveDirectory/ctl stop
			return 1
		fi

		setup_homedirs
		create_cache_filesystem
		mkdir -p ${FREENAS_CACHEDIR}/.samba
	fi
	
	return 0
}

activedirectory_status()
{
	local res=1

	if dirsrv_enabled activedirectory
	then
		AD_init

		AD_log "activedirectory_status: checking status"
		AD_status_domain >/dev/null
		res=$?
	fi

	return ${res}
}

activedirectory_stop()
{
	AD_init

        /usr/local/www/freenasUI/tools/cachetool.py expire

	AD_log "activedirectory_stop: leaving domain"
	AD_disable_machine_account	
}


name="ix-activedirectory"
start_cmd='activedirectory_start'
status_cmd='activedirectory_status'
stop_cmd='activedirectory_stop'
            
load_rc_config $name
run_rc_command "$1"
