[PC-BSD Commits] r19150 - in pcbsd/current/src-sh/pc-adctl: conf krb ldap nss nssldap pam rc samba scripts

svn at pcbsd.org svn at pcbsd.org
Thu Sep 13 00:43:47 PDT 2012


Author: johnh
Date: 2012-09-13 07:43:46 +0000 (Thu, 13 Sep 2012)
New Revision: 19150

Removed:
   pcbsd/current/src-sh/pc-adctl/pam/tags
Modified:
   pcbsd/current/src-sh/pc-adctl/conf/pc-activedirectory.conf
   pcbsd/current/src-sh/pc-adctl/krb/Makefile
   pcbsd/current/src-sh/pc-adctl/ldap/Makefile
   pcbsd/current/src-sh/pc-adctl/nss/Makefile
   pcbsd/current/src-sh/pc-adctl/nssldap/Makefile
   pcbsd/current/src-sh/pc-adctl/nssldap/nssldapconf.c
   pcbsd/current/src-sh/pc-adctl/pam/Makefile
   pcbsd/current/src-sh/pc-adctl/pam/pam-parser.y
   pcbsd/current/src-sh/pc-adctl/pam/pamconf.c
   pcbsd/current/src-sh/pc-adctl/rc/rc.activedirectory
   pcbsd/current/src-sh/pc-adctl/samba/Makefile
   pcbsd/current/src-sh/pc-adctl/scripts/pc-activedirectory
   pcbsd/current/src-sh/pc-adctl/scripts/pc-adctl
   pcbsd/current/src-sh/pc-adctl/scripts/pc-kerberos
   pcbsd/current/src-sh/pc-adctl/scripts/pc-kinit
   pcbsd/current/src-sh/pc-adctl/scripts/pc-ldap
   pcbsd/current/src-sh/pc-adctl/scripts/pc-nssldap
   pcbsd/current/src-sh/pc-adctl/scripts/pc-nsswitch
   pcbsd/current/src-sh/pc-adctl/scripts/pc-pam
   pcbsd/current/src-sh/pc-adctl/scripts/pc-samba
Log:
Lots of bugfixes. Merged AD code and bugfixes from FreeNAS as well. Still some more bugs to be worked out, but we're getting there.



Modified: pcbsd/current/src-sh/pc-adctl/conf/pc-activedirectory.conf
===================================================================
--- pcbsd/current/src-sh/pc-adctl/conf/pc-activedirectory.conf	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/conf/pc-activedirectory.conf	2012-09-13 07:43:46 UTC (rev 19150)
@@ -33,3 +33,13 @@
 # Allow trusted domains?
 #
 ad_allow_trusted_doms = no
+
+#
+# AD has UNIX extensions?
+#
+ad_unix_extensions = no
+
+#
+# Use verbose logging?
+#
+ad_verbose_logging = no

Modified: pcbsd/current/src-sh/pc-adctl/krb/Makefile
===================================================================
--- pcbsd/current/src-sh/pc-adctl/krb/Makefile	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/krb/Makefile	2012-09-13 07:43:46 UTC (rev 19150)
@@ -10,7 +10,7 @@
 PROGMODE=	0555
 DESTDIR=	/usr/local/bin
 
-PROG=	krbconf
+PROG=	pc-krbconf
 SRCS=	krbconf.c krbconf.h
 
 CFLAGS+= -I. -I${.CURDIR}

Modified: pcbsd/current/src-sh/pc-adctl/ldap/Makefile
===================================================================
--- pcbsd/current/src-sh/pc-adctl/ldap/Makefile	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/ldap/Makefile	2012-09-13 07:43:46 UTC (rev 19150)
@@ -10,7 +10,7 @@
 PROGMODE=	0555
 DESTDIR=	/usr/local/bin
 
-PROG=	ldapconf
+PROG=	pc-ldapconf
 SRCS=	ldapconf.c ldapconf.h
 
 CFLAGS+= -I. -I${.CURDIR}

Modified: pcbsd/current/src-sh/pc-adctl/nss/Makefile
===================================================================
--- pcbsd/current/src-sh/pc-adctl/nss/Makefile	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/nss/Makefile	2012-09-13 07:43:46 UTC (rev 19150)
@@ -10,7 +10,7 @@
 PROGMODE=	0555
 DESTDIR=	/usr/local/bin
 
-PROG=	nssconf
+PROG=	pc-nssconf
 SRCS=	nssconf.c nssconf.h
 
 CFLAGS+= -I. -I${.CURDIR}

Modified: pcbsd/current/src-sh/pc-adctl/nssldap/Makefile
===================================================================
--- pcbsd/current/src-sh/pc-adctl/nssldap/Makefile	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/nssldap/Makefile	2012-09-13 07:43:46 UTC (rev 19150)
@@ -10,7 +10,7 @@
 PROGMODE=	0555
 DESTDIR=	/usr/local/bin
 
-PROG=	nssldapconf
+PROG=	pc-nssldapconf
 SRCS=	nssldapconf.c nssldapconf.h
 
 CFLAGS+= -I. -I${.CURDIR}

Modified: pcbsd/current/src-sh/pc-adctl/nssldap/nssldapconf.c
===================================================================
--- pcbsd/current/src-sh/pc-adctl/nssldap/nssldapconf.c	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/nssldap/nssldapconf.c	2012-09-13 07:43:46 UTC (rev 19150)
@@ -58,7 +58,59 @@
 	return (ptr);
 }
 
+/*
+ * Swiped directly from FreeBSD and modified to fit my needs.
+ */
 char *
+xstrsep(char **stringp, const char *delim)
+{
+	char *s;
+	const char *spanp;
+	int c, sc;
+	char *tok;
+
+	if ((s = *stringp) == NULL)
+		return (NULL);
+
+	for (tok = s;;) {
+		c = *s++;
+		spanp = delim;
+
+		do {
+			if ((sc = *spanp++) == c && *(s - 2) != '\\') {
+				if (c == 0)
+					s = NULL;
+				else
+					s[-1] = 0;
+
+				*stringp = s;
+				return (tok);
+			}
+
+		} while (sc != 0);
+	}
+}
+
+char *
+unescape(char *str)
+{
+	char *src, *dst;
+
+	if (str == NULL)
+		return (NULL);
+
+	src = dst = str;
+	while (*src != 0) {
+		if (*src == '\\' && *(src + 1) != 0 && *(src + 1) == '=')
+			src++;
+		*dst++ = *src++;
+	}
+
+	*dst = 0;
+	return (str);
+}
+
+char *
 clean(char *str)
 {
 	char *ptr;
@@ -127,20 +179,20 @@
 	}
 
 	if (tmp != NULL)
-		nm->name = xstrdup(clean(tmp));
+		nm->name = xstrdup(unescape(clean(tmp)));
 	if (ptr != NULL) {
 		switch (mt) {
 			case 't': {
-				tmp = strsep(&ptr, "=");
+				tmp = xstrsep(&ptr, "=");
 				if (ptr != NULL) {
-					nm->attr = xstrdup(clean(tmp));
-					nm->value = xstrdup(clean(ptr));
+					nm->attr = xstrdup(unescape(clean(tmp)));
+					nm->value = xstrdup(unescape(clean(ptr)));
 				}
 			}
 
 			case 'p':
 			default:
-				nm->value = xstrdup(clean(ptr));
+				nm->value = xstrdup(unescape(clean(ptr)));
 		}
 	}
 

Modified: pcbsd/current/src-sh/pc-adctl/pam/Makefile
===================================================================
--- pcbsd/current/src-sh/pc-adctl/pam/Makefile	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/pam/Makefile	2012-09-13 07:43:46 UTC (rev 19150)
@@ -10,7 +10,7 @@
 PROGMODE=	0555
 DESTDIR=	/usr/local/bin
 
-PROG=	pamconf
+PROG=	pc-pamconf
 SRCS=	pamconf.c pamconf.h
 
 CFLAGS+= -I. -I${.CURDIR}

Modified: pcbsd/current/src-sh/pc-adctl/pam/pam-parser.y
===================================================================
--- pcbsd/current/src-sh/pc-adctl/pam/pam-parser.y	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/pam/pam-parser.y	2012-09-13 07:43:46 UTC (rev 19150)
@@ -193,7 +193,7 @@
 		int i;
 
 		pe->pes_narguments = 0;
-		pe->pes_arguments = xalloc(PAM_ENTRY_ARGMAX);
+		pe->pes_arguments = xalloc(sizeof(pe->pes_arguments) * PAM_ENTRY_ARGMAX);
 		for (i = 0;i < PAM_ENTRY_ARGMAX;i++) {
 			pe->pes_arguments[i] = NULL;
 		}

Modified: pcbsd/current/src-sh/pc-adctl/pam/pamconf.c
===================================================================
--- pcbsd/current/src-sh/pc-adctl/pam/pamconf.c	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/pam/pamconf.c	2012-09-13 07:43:46 UTC (rev 19150)
@@ -76,6 +76,7 @@
 new_pam_entry(int facility)
 {
 	struct pam_entry *pe = xalloc(sizeof(*pe));
+
 	pe->pes_arguments = NULL;
 	pe->pes_narguments = 0;
 	pe->facility = facility;
@@ -153,7 +154,7 @@
 			break;
 	}
 
-	free(pe);
+	xfree(&pe);
 }
 
 void

Modified: pcbsd/current/src-sh/pc-adctl/rc/rc.activedirectory
===================================================================
--- pcbsd/current/src-sh/pc-adctl/rc/rc.activedirectory	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/rc/rc.activedirectory	2012-09-13 07:43:46 UTC (rev 19150)
@@ -30,52 +30,498 @@
 #	Active Directory config
 #
 : ${AD_CONF:="/usr/local/etc/pc-activedirectory.conf"}
+: ${AD_NET_CONF:="/usr/local/etc/pc-activedirectory-net.conf"}
 
 
 #
 #	Active Directory Functions
 #
-__get_SRV_record()
+
+__onoff()
 {
+	local ret="${1}"
+
+	if [ -z "${ret}" ]
+	then
+		echo "0"
+		return 0
+	fi
+
+	ret="$(echo "${ret}" | tr A-Z a-z)"
+	case "${ret}" in
+		on) ret=1 ;;
+		yes) ret=1 ;;
+		1) ret=1 ;;
+		off) ret=0 ;;
+		no) ret=0 ;;
+		0) ret=0 ;;
+		*) ret=1 ;;
+	esac
+
+	echo "${ret}"
+	return 0
+}
+
+
+__proto()
+{
+	local proto="${1}"
+	local default="${2}"
+
+	if [ -z "${default}" ]
+	then
+		default="tcp"
+	fi
+
+	if [ -z "${proto}" ]
+	then
+		proto="${default}"
+	fi
+
+	proto="$(echo ${proto}|tr A-Z a-z)"
+	if [ "${proto}" != "tcp" -a "${proto}" != "udp" ]
+	then
+		proto="${default}"
+	fi
+
+	echo "${proto}"
+}
+
+__get_SRV_records()
+{
 	local host="${1}"
-	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+	local proto=$(__proto "${2}" tcp)
+	
+	AD_log "__get_SRV_records: host=${host}"
 
-	dig -t srv +short "${host}" | sort -n +0 +1 > "${tmpfile}"
+	if [ -z "${host}" ]
+	then
+		return 1
+	fi
 
+	AD_log "__get_SRV_records: dig -t srv +short +nocomments ${host}"
+	dig -t srv +short +nocomments "${host}" | egrep -v '^[[:space:]]*;;' | sort -n +0 +1
+
+	return $?
+}
+
+__get_SRV_host()
+{
+	local tmpfile="${1}"
+	local proto=$(__proto "${2}" tcp)
+
+	if [ -z "${tmpfile}" -o ! -s "${tmpfile}" ]
+	then
+		return 1
+	fi
+
 	exec 3<&0
 	exec 0<"${tmpfile}"
 	while read -r line
 	do
 		local host=$(echo "${line}"|awk '{ print $4 }'|sed 's/\.$//')
 		local port=$(echo "${line}"|awk '{ print $3 }')
+		local nc_timeout=15
+		local nc_args=
 
-		__do_AD_query "${host}" "${port}" "" "" "" "base" "" "" >/dev/null 2>&1
+		AD_log "__get_SRV_host: trying ${host}:${port}"
+
+		if [ "${proto}" = "tcp" ]
+		then
+			nc_args="-z -d -w ${nc_timeout}"
+
+		elif [ "${proto}" = "udp" ]
+		then
+			nc_args="-z -d -w ${nc_timeout} -u"
+		fi
+		
+		#
+		# UDP will always return that it was able to connect.
+		# Is there a better way to do this?
+		#
+		/usr/bin/nc ${nc_args} "${host}" "${port}" >/dev/null 2>&1
 		if [ "$?" = "0" ]
 		then
 			exec 0<&3
 			echo "${host}:${port}"
-			rm "${tmpfile}"
+
+			AD_log "__get_SRV_host: Okay"
 			return 0
 		fi
+
+		AD_log "__get_SRV_host: Fail"
 	done
 	exec 0<&3
-	rm "${tmpfile}"
 
 	return 1
 }
 
+__get_SRV_record()
+{
+	local host="${1}"
+	local proto=$(__proto "${2}" tcp)
+	local res
+
+	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+
+	if [ -z "${proto}" ]
+	then
+		
+		proto="tcp"
+	fi
+
+	AD_log "__get_SRV_record: host=${host}"
+	__get_SRV_records "${host}" > "${tmpfile}"
+
+	__get_SRV_host "${tmpfile}"
+	res=$?
+
+	rm "${tmpfile}"
+	return ${res}
+}
+
+AD_locate_domain_controllers_by_guid()
+{
+	local domain="${1}"
+	local guid="${2}"
+	local record
+
+	AD_log "AD_locate_domain_controllers_by_guid: domain=${domain}, guid=${guid}"
+
+	if [ -z "${domain}" -o -z "${guid}" ]
+	then
+		return 1
+	fi	
+
+	record="_ldap._tcp.${guid}.domains._msdcs.${domain}"
+
+	AD_log "AD_locate_domain_controllers_by_guid: record=${record}"
+	__get_SRV_records "${record}"
+
+	return $?
+}
+
+AD_get_domain_controller_by_guid()
+{
+	local domain="${1}"
+	local guid="${2}"
+	local record
+	local res
+
+	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+
+	AD_locate_domain_controllers_by_guid "${domain}" "${guid}" > "${tmpfile}"
+	__get_SRV_host "${tmpfile}"
+	res=$?
+
+	rm "${tmpfile}"
+	return ${res}
+}
+
+AD_locate_domain_controllers()
+{
+	local domain="${1}"
+	local site="${2}"
+	local record
+
+	AD_log "AD_locate_domain_controllers: domain=${domain}, site=${site}"
+
+	if [ -z "${domain}" ]
+	then
+		return 1
+	fi
+
+	if [ -z "${site}" ]
+	then
+		record="_ldap._tcp.dc._msdcs.${domain}"
+	else
+		record="_ldap._tcp.${site}._sites.dc._msdcs.${domain}"
+	fi
+
+	AD_log "AD_locate_domain_controllers: record=${record}"
+	__get_SRV_records "${record}"
+
+	return $?
+}
+
 AD_get_domain_controller()
 {
-	__get_SRV_record "_ldap._tcp.${1}"
+	local domain="${1}"
+	local site="${2}"
+	local record
+	local res
+
+	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+
+	AD_locate_domain_controllers "${domain}" "${site}" > "${tmpfile}"
+	__get_SRV_host "${tmpfile}"
+	res=$?
+
+	rm "${tmpfile}"
 	return $?
 }
 
-AD_get_global_catalog()
+AD_locate_primary_domain_controllers()
 {
-	__get_SRV_record "_gc._tcp.${1}"
+	local domain="${1}"
+	local record
+
+	AD_log "AD_locate_primary_domain_controllers: domain=${domain}"
+
+	if [ -z "${domain}" ]
+	then
+		return 1
+	fi
+
+	record="_ldap._tcp.pdc._msdcs.${domain}"
+
+	AD_log "AD_locate_primary_domain_controllers: record=${record}"
+	__get_SRV_records "${record}"
+
 	return $?
 }
 
+AD_get_primary_domain_controller()
+{
+	local domain="${1}"
+	local res
+
+	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+
+	AD_locate_primary_domain_controllers "${domain}" > "${tmpfile}"
+	__get_SRV_host "${tmpfile}"
+	res=$?
+
+	rm "${tmpfile}"
+	return ${res}
+}
+
+AD_locate_ldap_servers()
+{
+	local domain="${1}"
+	local site="${2}"
+	local record
+
+	AD_log "AD_locate_ldap_servers: domain=${domain}, site=${site}"
+
+	if [ -z "${domain}" ]
+	then
+		return 1
+	fi
+
+	if [ -z "${site}" ]
+	then
+		record="_ldap._tcp.${domain}"
+	else
+		record="_ldap._tcp.${site}._sites.${domain}"
+	fi
+
+	AD_log "AD_locate_ldap_servers: record=${record}"
+	__get_SRV_records "${record}"
+
+	return $?
+}
+
+AD_get_ldap_server()
+{
+	local domain="${1}"
+	local site="${2}"
+	local record
+	local res
+
+	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+
+	AD_locate_ldap_servers "${domain}" "${site}" > "${tmpfile}"
+	__get_SRV_host "${tmpfile}"
+	res=$?
+
+	rm "${tmpfile}"
+	return ${res}
+}
+
+AD_locate_forest_global_catalog_servers()
+{
+	local forest="${1}"
+	local site="${2}"
+	local record
+
+	AD_log "AD_locate_forest_global_catalog_servers: forest=${forest}, site=${site}"
+
+	if [ -z "${domain}" ]
+	then
+		return 1
+	fi
+
+	if [ -z "${site}" ]
+	then
+		record="_ldap._tcp.gc._msdcs.${forest}"
+	else
+		record="_ldap._tcp.${site}._sites.gc._msdcs.${forest}"
+	fi
+
+	AD_log "AD_locate_forest_global_catalog_servers: record=${record}"
+	__get_SRV_records "${record}"
+
+	return $?
+}
+
+AD_get_forest_global_catalog_server()
+{
+	local forest="${1}"
+	local site="${2}"
+	local res
+
+	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+
+	AD_locate_forest_global_catalog_servers "${forest}" "${site}" > "${tmpfile}"
+	__get_SRV_host "${tmpfile}"
+	res=$?
+
+	rm "${tmpfile}"
+	return ${res}
+}
+
+AD_locate_domain_global_catalog_servers()
+{
+	local domain="${1}"
+	local site="${2}"
+
+	AD_log "AD_locate_domain_global_catalog_servers: domain=${domain}, site=${site}"
+
+	if [ -z "${domain}" ]
+	then
+		return 1
+	fi
+
+	if [ -z "${site}" ]
+	then
+		record="_gc._tcp.${domain}"
+	else
+		record="_gc._tcp.${site}._sites.${domain}"
+	fi
+
+	AD_log "AD_locate_global_catalogservers: record=${record}"
+	__get_SRV_records "${record}"
+
+	return $?
+}
+
+AD_get_domain_global_catalog_server()
+{
+	local domain="${1}"
+	local site="${2}"
+	local res
+
+	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+
+	AD_locate_domain_global_catalog_servers "${domain}" "${site}" > "${tmpfile}"
+	__get_SRV_host "${tmpfile}"
+	res=$?
+
+	rm "${tmpfile}"
+	return ${res}
+}
+
+AD_locate_kerberos_servers()
+{
+	local domain="${1}"
+	local proto="${2}"
+	local site="${3}"
+	local record
+
+	AD_log "AD_locate_kerberos_servers: domain=${domain}, proto=${proto}, site=${site}"
+
+	if [ -z "${proto}" ]
+	then
+		proto="udp"
+	fi
+
+	proto="$(echo ${proto}|tr A-Z a-z)"
+	if [ "${proto}" != "tcp" -a "${proto}" != "udp" ]
+	then
+		proto="udp"
+	fi
+
+	if [ -z "${site}" ]
+	then
+		record="_kerberos._${proto}.${domain}"
+	else
+		record="_kerberos._${proto}.${site}._sites.${domain}"
+	fi
+
+	AD_log "AD_locate_kerberos_servers: record=${record}"
+	__get_SRV_records "${record}"
+
+	return $?
+}
+
+AD_get_kerberos_server()
+{
+	local domain="${1}"
+	local proto="${2}"
+	local site="${3}"
+	local res
+
+	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+
+	AD_locate_kerberos_servers "${domain}" "${proto}" "${site}" > "${tmpfile}"
+	__get_SRV_host "${tmpfile}"
+	res=$?
+
+	rm "${tmpfile}"
+	return ${res}
+}
+
+AD_locate_kpasswd_servers()
+{
+	local domain="${1}"
+	local proto="${2}"
+	local site="${3}"
+	local record
+
+	AD_log "AD_locate_kpasswd_servers: domain=${domain}, proto=${proto}, site=${site}"
+
+	if [ -z "${proto}" ]
+	then
+		proto="udp"
+	fi
+
+	proto="$(echo ${proto}|tr A-Z a-z)"
+	if [ "${proto}" != "tcp" -a "${proto}" != "udp" ]
+	then
+		proto="udp"
+	fi
+
+	if [ -z "${site}" ]
+	then
+		record="_kpasswd._${proto}.${domain}"
+	else
+		record="_kpasswd._${proto}.${site}._sites.${domain}"
+	fi
+
+	AD_log "AD_locate_kpasswd_servers: record=${record}"
+	__get_SRV_records "${record}"
+
+	return $?
+}
+
+AD_get_kpasswd_server()
+{
+	local domain="${1}"
+	local proto="${2}"
+	local site="${3}"
+	local res
+
+	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+
+	AD_locate_kpasswd_servers "${domain}" "${proto}" "${site}" > "${tmpfile}"
+	__get_SRV_host "${tmpfile}"
+	res=$?
+
+	rm "${tmpfile}"
+	return ${res}
+}
+
 __do_AD_query()
 {
 	local dcname="${1}"
@@ -127,6 +573,8 @@
 	: ${basedn:="$(AD_get basedn)"}
 	: ${filter:='(objectclass=*)'}
 
+	AD_log "AD_query: basedn = ${basedn}, filter = ${filter}, attributes = ${attributes}"
+
 	local dcname="$(AD_get dcname)"
 	local dcport="$(AD_get dcport)"
 	local binddn="$(AD_get binddn)"
@@ -142,6 +590,8 @@
 	local config="$(AD_query_rootDSE|egrep '^configurationNamingContext'|cut -f2- -d:|xargs)"
 	local basedn="CN=Partitions,${config}"
 
+	AD_log "AD_query_partitions: config = ${config}, basedn = ${basedn}"
+
 	AD_query "${basedn}" "" netbiosname|grep '^nETBIOSName'|cut -f2- -d:|xargs
 }
 
@@ -155,6 +605,8 @@
 
     	: ${filter:='(objectclass=*)'}
 
+	AD_log "AD_query_global_catalog: filter = ${filter}, attributes = ${attributes}"
+
 	local gchost="$(AD_get gchost)"
 	local gcport="$(AD_get gcport)"
 	local binddn="$(AD_get binddn)"
@@ -186,6 +638,8 @@
 
 	: ${filter:='(objectclass=*)'}
 
+	AD_log "AD_query_rootDSE: filter = ${filter}, attributes = ${attributes}"
+
 	local dcname="$(AD_get dcname)"
 	local dcport="$(AD_get dcport)"
 	local binddn="$(AD_get binddn)"
@@ -209,14 +663,14 @@
 	rm "${tmpfile}"
 }
 
-__AD_escape()
+__escape()
 {
-	printf "${1}" | sed -Ee 's|\\|\\\\|g' -Ee 's|[^a-zA-Z0-9]|\\&|g'
+	[ -n "${1}" ] && printf "${1}" | sed -Ee 's|\\|\\\\|g' -Ee 's|[^a-zA-Z0-9]|\\&|g'
 }
 
-__AD_unescape()
+__unescape()
 {
-	printf "${1}" | sed -Ee 's|\\([^a-zA-Z0-9])|\1|g' -Ee 's|\\\\|\\|g'
+	[ -n "${1}" ] && printf "${1}" | sed -Ee 's|\\([^a-zA-Z0-9])|\1|g' -Ee 's|\\\\|\\|g'
 }
 
 __do_AD_get()
@@ -224,9 +678,9 @@
 	local prefix="${1}"
 	local name="${2}"
 	local var=\$$(printf "${prefix}${name}")
-	local val=$(eval "printf ${var}")
+	local val=$(eval "printf ${var} 2>/dev/null")
 
-	__AD_unescape "${val}"
+	__unescape "${val}"
 }
 
 AD_get()
@@ -236,7 +690,15 @@
 
 	for v in ${vars}
 	do
-		__do_AD_get "${prefix}" "${v}"
+		local var=\$$(printf "${v}")
+		local val=$(eval "printf ${var} 2>/dev/null")
+
+		if [ -n "${val}" ]
+		then
+			echo "${val}"
+		else
+			__do_AD_get "${prefix}" "${v}" 2>/dev/null
+		fi
 	done
 }
 
@@ -244,7 +706,7 @@
 {
 	local prefix="${1}"
 	local var="${2}"
-	local val=$(__AD_escape "${3}")
+	local val=$(__escape "${3}")
 	local pair="${var}=${val}"
 
 	eval "${prefix}${pair}"
@@ -256,7 +718,7 @@
 	local val="${2}"
 	local prefix="__ad_"
 
-	__do_AD_set "${prefix}" "${var}" "${val}"
+	__do_AD_set "${prefix}" "${var}" "${val}" 2>/dev/null
 }
 
 AD_save()
@@ -304,42 +766,145 @@
 {
 	local adminname="${1}"
 	local adminpw="${2}"
+	local res
 
 	: ${adminname:="$(AD_get adminname)"}
 	: ${adminpw:="$(AD_get adminpw)"}
 
+	AD_log "AD_join_domain: net ads join -U ${adminname}"
+
 	/usr/local/bin/net ads join -U "${adminname}%${adminpw}"
-	return $?
+	res=$?
+
+	local ok="Failed"
+	if [ "${res}" = "0" ]
+	then
+		ok="Successful"
+	fi
+
+	AD_log "AD_join_domain: ${ok}"
+	return ${res}
 }
 
 AD_status_domain()
 {
 	local adminname="${1}"
 	local adminpw="${2}"
+	local res
 
 	: ${adminname:="$(AD_get adminname)"}
 	: ${adminpw:="$(AD_get adminpw)"}
 
+	AD_log "AD_status_domain: net ads status -U ${adminname}"
+
 	/usr/local/bin/net ads status -U "${adminname}%${adminpw}"
-	return $?
+	res=$?
+
+	local ok="Not okay"
+	if [ "${res}" = "0" ]
+	then
+		ok="Okay"
+	fi
+
+	AD_log "AD_status_domain: ${ok}"
+	return ${res}
 }
 
 AD_leave_domain()
 {
 	local adminname="${1}"
 	local adminpw="${2}"
+	local res
 
 	: ${adminname:="$(AD_get adminname)"}
 	: ${adminpw:="$(AD_get adminpw)"}
 
+	AD_log "AD_leave_domain: net ads leave -U ${adminname}"
+
 	/usr/local/bin/net ads leave -U "${adminname}%${adminpw}"
-	return $?
+	res=$?
+
+	local ok="Failed"
+	if [ "${res}" = "0" ]
+	then
+		ok="Successful"
+	fi
+
+	AD_log "AD_leave_domain: ${ok}"
+	return ${res}
 }
 
+AD_verbose_logging()
+{
+	local verbose=$(AD_get verbose_logging)
+	local on=$(__onoff ${verbose})
+	local ret=1
+
+	if [ "${on}" = "1" ]
+	then
+		ret=0
+	fi
+
+	return ${ret}
+}
+
+AD_UNIX_extensions()
+{
+	local ad_unix=$(AD_get unix_extensions)
+	local on=$(__onoff ${ad_unix})
+	local ret=1
+
+	if [ "${on}" = "1" ]
+	then
+		ret=0
+	fi
+
+	return ${ret}
+}
+
+AD_log()
+{
+	local args="$*"
+
+	if AD_verbose_logging
+	then
+		logger -t "ActiveDirectory" ${args} >/dev/null 2>&1
+	fi
+}
+
+AD_generate_config()
+{
+	local vars="\
+		adminname \
+		domainname \
+		basedn \
+		binddn \
+		dcname \
+		dcport \
+		dc \
+		gchost \
+		gcport \
+		gc \
+		krbhost \
+		kpwdhost \
+	"
+
+	: > "${AD_NET_CONF}"
+	for var in ${vars}
+	do
+		local val="$(AD_get ${var})"
+		echo "${var}=\"${val}\"" >> "${AD_NET_CONF}"
+	done
+
+	/bin/chmod 600 "${AD_NET_CONF}"
+}
+
 AD_init()
 {
 	local adconf="${AD_CONF}"
  	local tmpfile="$(mktemp -q /var/tmp/.adfooXXXXXX)"
+	local config_exists=0
+	local verbose=0
 
 	egrep -v '^[[:space:]]+$|^$|^#|^[[:space:]]+#' < "${adconf}" > "${tmpfile}"
 
@@ -347,7 +912,7 @@
 	exec 0<"${tmpfile}"
 	while read -r line
 	do
-		var=$(echo ${line}|cut -f1 -d=|xargs|cut -f2 -d_)
+		var=$(echo ${line}|cut -f1 -d=|xargs|cut -f2- -d_)
 		val=$(echo ${line}|cut -f2- -d=|xargs)
 
 		AD_set "${var}" "${val}"
@@ -355,17 +920,68 @@
 	exec 0<&3
 	rm -f "${tmpfile}"
 
+	if [ -f "${AD_NET_CONF}" ]
+	then
+		AD_log "AD_init: net config exists, loading values from ${AD_NET_CONF}"
+		. "${AD_NET_CONF}"
+		config_exists=1
+	fi
+
+	if [ "${config_exists}" = "1" ]
+	then
+		return 0
+	fi
+
 	local adminname=$(AD_get adminname)
 	local domainname=$(AD_get domainname)
-	AD_set binddn "${adminname}@$(echo ${domainname}|tr a-z A-Z)"
 
-	local dc=$(AD_get_domain_controller "${domainname}")
+	local binddn=$(AD_get binddn)
+	if [ -z "${binddn}" ]
+	then
+		AD_set binddn "${adminname}@$(echo ${domainname}|tr a-z A-Z)"
+	fi
+	AD_log "AD_init: binddn = $(AD_get binddn)"
+
+	
+	local dc=$(AD_get dc)
+	if [ -z "${dc}" ]
+	then
+		dc=$(AD_get_domain_controller "${domainname}")
+	fi
+
 	AD_set dcname "$(echo "${dc}"|cut -f1 -d:)"
 	AD_set dcport "$(echo "${dc}"|cut -f2 -d:)"
+	AD_log "AD_init: dcname = $(AD_get dcname), dcport = $(AD_get dcport)"
 
-	AD_set basedn "$(AD_query_rootDSE|egrep '^defaultNamingContext'|cut -f2- -d:|xargs)"
+	local basedn=$(AD_get basedn)
+	if [ -z "${basedn}" ]
+	then
+		AD_set basedn "$(AD_query_rootDSE|egrep '^defaultNamingContext'|cut -f2- -d:|xargs)"
+	fi
+	AD_log "AD_init: basedn = $(AD_get basedn)"
 
-	local gc=$(AD_get_global_catalog "${domainname}")
+	local gc=$(AD_get gc)
+	if [ -z "${gc}" ]
+	then
+		gc=$(AD_get_domain_global_catalog_server "${domainname}")
+	fi
+
 	AD_set gchost "$(echo "${gc}"|cut -f1 -d:)"
 	AD_set gcport "$(echo "${gc}"|cut -f2 -d:)"
+	AD_log "AD_init: gchost = $(AD_get gchost), gcport = $(AD_get gcport)"
+
+	local krbhost=$(AD_get krbhost)
+	if [ -z "${krbhost}" ]
+	then
+		AD_set krbhost "$(AD_get_kerberos_server ${domainname})"
+	fi
+         
+	local kpwdhost=$(AD_get kpwdhost)
+	if [ -z "${kpwdhost}" ]
+	then
+		AD_set kpwdhost "$(AD_get_kpasswd_server ${domainname})"
+	fi
+
+	AD_generate_config
+	return 0
 }

Modified: pcbsd/current/src-sh/pc-adctl/samba/Makefile
===================================================================
--- pcbsd/current/src-sh/pc-adctl/samba/Makefile	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/samba/Makefile	2012-09-13 07:43:46 UTC (rev 19150)
@@ -10,7 +10,7 @@
 PROGMODE=	0555
 DESTDIR=	/usr/local/bin
 
-PROG=	sambaconf
+PROG=	pc-sambaconf
 SRCS=	sambaconf.c sambaconf.h
 
 CFLAGS+= -I. -I${.CURDIR}

Modified: pcbsd/current/src-sh/pc-adctl/scripts/pc-activedirectory
===================================================================
--- pcbsd/current/src-sh/pc-adctl/scripts/pc-activedirectory	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/scripts/pc-activedirectory	2012-09-13 07:43:46 UTC (rev 19150)
@@ -14,6 +14,8 @@
 	if checkyesno activedirectory_enable 2>/dev/null
 	then
 		AD_init
+
+		AD_log "activedirectory_start: trying to join domain"
 		if ! AD_join_domain; then
 			return 1
 		fi
@@ -25,12 +27,16 @@
 activedirectory_status()
 {
 	AD_init
+
+	AD_log "activedirectory_status: checking status"
 	AD_status_domain >/dev/null
 }
 
 activedirectory_stop()
 {
 	AD_init
+
+	AD_log "activedirectory_stop: leaving domain"
 	AD_leave_domain
 }
 

Modified: pcbsd/current/src-sh/pc-adctl/scripts/pc-adctl
===================================================================
--- pcbsd/current/src-sh/pc-adctl/scripts/pc-adctl	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/scripts/pc-adctl	2012-09-13 07:43:46 UTC (rev 19150)
@@ -7,6 +7,21 @@
 
 . /usr/local/etc/rc.activedirectory
 
+adctl_cmd()
+{
+	local args="$*"
+
+	if [ -n "${args}" ]
+	then
+		logger -t ActiveDirectory "${args}"
+		${args}
+		return $?
+	fi
+
+	return 0
+}
+
+
 adctl_assert()
 {
 	local args="$*"
@@ -23,25 +38,27 @@
 {
 	if checkyesno activedirectory_enable 2>/dev/null
 	then
-		adctl_assert service pc-kerberos start
-		adctl_assert service pc-nsswitch start
-		adctl_assert service pc-pam start
+		adctl_cmd service pc-kerberos start
+		adctl_cmd service pc-nsswitch start
+		adctl_cmd service pc-pam start
 
 		service samba status
 		if [ "$?" = "0" ]
 		then
-			adctl_assert service samba stop
-			adctl_assert service pc-samba start
-			adctl_assert service samba start
+			adctl_cmd service samba stop
+			adctl_cmd service pc-samba start
+			adctl_cmd service samba start
 		else
-			adctl_assert service pc-samba start
-			adctl_assert service samba start
+			adctl_cmd service pc-samba start
+			adctl_cmd service samba start
 		fi
 
-		adctl_assert service pc-kinit start
-		adctl_assert service pc-kinit status
-		adctl_assert service pc-activedirectory start
-		adctl_assert service pc-activedirectory status
+		adctl_cmd service pc-kinit start
+		adctl_cmd service pc-kinit status
+		adctl_cmd service pc-nssldap start
+		adctl_cmd service pc-activedirectory start
+		adctl_cmd service pc-activedirectory status
+		adctl_cmd service samba restart
 	fi
 	
 	return 0
@@ -62,15 +79,16 @@
 		service pc-pam stop
 		service pc-samba stop
 		service pc-kinit stop
+		adctl_cmd service pc-nssldap stop
 		service pc-activedirectory stop
 
 		service samba status
 		if [ "$?" = "0" ]
 		then
-			adctl_assert service samba stop
-			adctl_assert service samba start
+			adctl_cmd service samba stop
+			adctl_cmd service samba start
 		else
-			adctl_assert service samba start
+			adctl_cmd service samba start
 		fi
 	fi
 }

Modified: pcbsd/current/src-sh/pc-adctl/scripts/pc-kerberos
===================================================================
--- pcbsd/current/src-sh/pc-adctl/scripts/pc-kerberos	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/scripts/pc-kerberos	2012-09-13 07:43:46 UTC (rev 19150)
@@ -9,7 +9,7 @@
 . /usr/local/etc/rc.activedirectory
 
 : ${PATH_KRB5_CONFIG:="/etc/krb5.conf"}
-: ${KRBCONF:="/usr/local/bin/krbconf"}
+: ${KRBCONF:="/usr/local/bin/pc-krbconf"}
 
 esc()
 {
@@ -18,31 +18,32 @@
 
 generate_krb5_conf()
 {
+	AD_init
+
 	local cmd="${KRBCONF}"
 	if [ -f "${PATH_KRB5_CONFIG}" ]
 	then
 		cmd="${KRBCONF} -f ${PATH_KRB5_CONFIG}"
 	fi
 
-	local _dcname="${1}"
-	local _domainname="${2}"
-	local _netbiosname="${3}"
-	local _adminname="${4}"
-	local _adminpw="${5}"
+	local krbhost=$(AD_get krbhost)
+	local kpwdhost=$(AD_get kpwdhost)
+	local domainname=$(AD_get domainname)
 
-	local _kdc=$(echo ${_dcname} | tr A-Z a-z)
-	local _upper_realm=$(echo ${_domainname} | tr a-z A-Z)
-	local _lower_realm=$(echo ${_domainname} | tr A-Z a-z)
-	local _admin_server=${_kdc}
-	local _domain=$(echo ${_domainname} | tr A-Z a-z)
+	AD_log "generate_krb5_conf: krbhost=${krbhost}, kpwdhost=${kpwdhost}, " \
+		"domainname=${domainname}"
 
+	local kdc="$(echo "${krbhost}" | tr A-Z a-z)"
+	local upper_realm="$(echo "${domainname}" | tr a-z A-Z)"
+	local lower_realm="$(echo "${domainname}" | tr A-Z a-z)"
+	local admin_server="${kdc}"
+	local domain="$(echo "${domainname}" | tr A-Z a-z)"
+
 	local tmp=$(mktemp /tmp/krb5.XXXXXX)
 
 	cp "${PATH_KRB5_CONFIG}" "${PATH_KRB5_CONFIG}.orig" >/dev/null 2>&1
 	${cmd} \
 		-c -m "^appdefaults.pam.forwardable=true" \
-		-c -m "^appdefaults.pam.krb4_convert=false" \
-		-c -m "^appdefaults.pam.debug=false" \
 		-c -m "^appdefaults.pam.ticket_lifetime=36000" \
 		-c -m "^appdefaults.pam.renew_lifetime=36000" \
 		\
@@ -51,18 +52,19 @@
 		-c -m "^libdefaults.ticket_lifetime=24h" \
 		-c -m "^libdefaults.clockskew=300" \
 		-c -m "^libdefaults.forwardable=yes" \
-		-c -m "^libdefaults.default_realm=${_upper_realm}" \
+		-c -m "^libdefaults.default_realm=${upper_realm}" \
 		\
 		-c -m "^logging.default=SYSLOG:INFO:LOCAL7" \
 		\
-		-c -m "^realms.$(esc ${_upper_realm}).kdc=${_kdc}" \
-		-c -m "^realms.$(esc ${_upper_realm}).admin_server=${_admin_server}" \
-		-c -m "^realms.$(esc ${_upper_realm}).default_domain=${_domain}" \
+		-c -m "^realms.$(esc ${upper_realm}).kdc=${kdc}" \
+		-c -m "^realms.$(esc ${upper_realm}).admin_server=${admin_server}" \
+		-c -m "^realms.$(esc ${upper_realm}).default_domain=${domain}" \
+		-c -m "^realms.$(esc ${upper_realm}).kpasswd_server=${kpwdhost}" \
 		\
-		-c -m "^domain_realm.$(esc ${_lower_realm})=${_upper_realm}" \
-		-c -m "^domain_realm.$(esc .${_lower_realm})=${_upper_realm}" \
-		-c -m "^domain_realm.$(esc ${_upper_realm})=${_upper_realm}" \
-		-c -m "^domain_realm.$(esc .${_upper_realm})=${_upper_realm}" \
+		-c -m "^domain_realm.$(esc ${lower_realm})=${upper_realm}" \
+		-c -m "^domain_realm.$(esc .${lower_realm})=${upper_realm}" \
+		-c -m "^domain_realm.$(esc ${upper_realm})=${upper_realm}" \
+		-c -m "^domain_realm.$(esc .${upper_realm})=${upper_realm}" \
 		\
 		-o "${tmp}"
 
@@ -72,6 +74,11 @@
 		return $?
 	fi
 
+	for line in $(verify_krb5_conf 2>&1)
+	do
+		AD_log "generate_krb5_conf: ${line}"
+	done
+
 	return 0
 }
 
@@ -79,16 +86,7 @@
 {
 	if checkyesno activedirectory_enable 2>/dev/null
 	then
-		AD_init
-
-		dcname=$(AD_get dcname)
-		domainname=$(AD_get domainname)
-		netbiosname=$(AD_get netbiosname)
-		adminname=$(AD_get adminname)
-		adminpw=$(AD_get adminpw)
-
-		generate_krb5_conf "${dcname}" "${domainname}" \
-			"${netbiosname}" "${adminname}" "${adminpw}"
+		generate_krb5_conf
 	fi
 }
 

Modified: pcbsd/current/src-sh/pc-adctl/scripts/pc-kinit
===================================================================
--- pcbsd/current/src-sh/pc-adctl/scripts/pc-kinit	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/scripts/pc-kinit	2012-09-13 07:43:46 UTC (rev 19150)
@@ -13,9 +13,9 @@
 
 kerberos_start()
 {
-	local ec pwfile
+	local re=1
+	local pwfile
 
-	ec=1
 	if checkyesno activedirectory_enable 2>/dev/null
 	then
 		AD_init
@@ -26,24 +26,35 @@
 
 		if [ -n "${adminname}" -a -n "${domainname}" -a -n "${adminpw}" ]
 		then
+			domainname=$(echo "${domainname}" | tr a-z A-Z)
+
 			pwfile=$(mktemp /tmp/tmp.XXXXXXXX)
 			printf "${adminpw}" > ${pwfile}
-			domainname=$(echo "${domainname}" | tr a-z A-Z)
+
+			AD_log "kerberos_start: kinit --password-file=${pwfile} " \
+			    "${adminname}@${domainname}"
 			kinit --password-file="${pwfile}" \
 			    "${adminname}@${domainname}"
-			ec=$?
+			res=$?
+
+			local ok="Failed"
+			if [ "${res}" = "0" ]
+			then
+				ok="Successful"
+			fi
+
+			AD_log "kerberos_start: ${ok}"
 			rm -f "${pwfile}"
-
 			sleep 10
 		fi
 	fi
 
-	return ${ec}
+	return ${res}
 }
 
 kerberos_status()
 {
-	local ec=1
+	local res=1
 
 	if checkyesno activedirectory_enable 2>/dev/null
 	then
@@ -56,17 +67,36 @@
 		if [ -n "${adminname}" -a -n "${domainname}" -a -n "${adminpw}" ]
 		then
 			domainname=$(echo "${domainname}"|tr a-z A-Z)
+
+			AD_log "kerberos_status: klist -l | grep -q ^${adminname}@${domainname}"
 			klist -l | grep -q "^${adminname}@${domainname}"
-			ec=$?
+			res=$?
+
+			local ok="Failed"
+			if [ "${res}" = "0" ]
+			then
+				ok="Successful"
+			fi
+
+			AD_log "kerberos_status: ${ok}"
 		fi
 	fi
 
-	return ${ec}
+	return ${res}
 }
 
 kerberos_stop()
 {
+	AD_log "kerberos_stop: kdestroy"
+
 	kdestroy
+	local ok="Failed"
+	if [ "${res}" = "0" ]
+	then
+		ok="Successful"
+	fi
+
+	AD_log "kerberos_stop: ${ok}"
 }
 
 name="pc-kinit"

Modified: pcbsd/current/src-sh/pc-adctl/scripts/pc-ldap
===================================================================
--- pcbsd/current/src-sh/pc-adctl/scripts/pc-ldap	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/scripts/pc-ldap	2012-09-13 07:43:46 UTC (rev 19150)
@@ -10,7 +10,7 @@
 . /usr/local/etc/rc.ldap
     
 : ${OPENLDAP_CONF:="/usr/local/etc/openldap/ldap.conf"}
-: ${LDAPCONF:="/usr/local/bin/ldapconf"}
+: ${LDAPCONF:="/usr/local/bin/pc-ldapconf"}
 
 
 backup_openldap_conf()

Modified: pcbsd/current/src-sh/pc-adctl/scripts/pc-nssldap
===================================================================
--- pcbsd/current/src-sh/pc-adctl/scripts/pc-nssldap	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/scripts/pc-nssldap	2012-09-13 07:43:46 UTC (rev 19150)
@@ -12,9 +12,32 @@
     
 : ${NSS_LDAP_CONF:="/usr/local/etc/nss_ldap.conf"}
 : ${NSS_LDAP_SECRET:="/usr/local/etc/nss_ldap.secret"}
-: ${NSSLDAPCONF:="/usr/local/bin/nssldapconf"}
+: ${NSSLDAPCONF:="/usr/local/bin/pc-nssldapconf"}
 
+escape()
+{
+	[ -n "${1}" ] && printf "${1}" | sed -Ee 's|=|\\=|g'
+}
 
+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}"
+}
+
+
 backup_nss_ldap_conf()
 {
 	local conf="${NSS_LDAP_CONF}"
@@ -66,7 +89,7 @@
 	return 0
 }
 
-generate_nss_ldap_conf()
+generate_LDAP_nss_ldap_conf()
 {
 	local tmp
 	local conf="${NSS_LDAP_CONF}"
@@ -237,13 +260,86 @@
 	fi
 }
 
+generate_AD_nss_ldap_conf()
+{
+	local tmp
+	local conf="${NSS_LDAP_CONF}"
+	local secret="${NSS_LDAP_SECRET}"
+
+	local dcname="$(AD_get dcname)"
+	local domainname="$(AD_get domainname)"
+	local adminname="$(AD_get adminname)"
+	local adminpw="$(AD_get adminpw)"
+	local base="$(get_basename "${domainname}")"
+
+	base=$(escape "${base}")
+
+	[ -z "${dcname}" -o -z "${base}" ] && return 1
+
+	local cmd="${NSSLDAPCONF}"
+	if [ -f "${conf}" ]
+	then
+		cmd="${NSSLDAPCONF} -f ${conf}"
+	fi
+
+	tmp=$(mktemp /tmp/tmp.XXXXXX)
+
+	${cmd} \
+		-c -m "^host=${dcname}" \
+		-c -m "^base=${base}" \
+		-c -m "^uri=ldap://${dcname}" \
+		-c -m "^rootbinddn=${adminname}@${domainname}" \
+		-c -m "^scope=sub" \
+		-c -m "^ssl=no" \
+		-c -m "^ldap_version=3" \
+		-c -m "^timelimit=30" \
+		-c -m "^bind_timelimit=30" \
+		-c -m "^bind_policy=soft" \
+		-c -m "^pam_ldap_attribute=uid" \
+		-c -m "^nss_base_passwd=${base}?sub" \
+		-c -m "^nss_base_shadow=${base}?sub"  \
+		-c -t "^nss_base_group=${base}?sub?=&(objectCategory=group)(gidnumber=*)" \
+		-c -t "^nss_map_objectclass=posixAccount=user" \
+		-c -t "^nss_map_objectclass=shadowAccount=user" \
+		-c -t "^nss_map_objectclass=posixGroup=group" \
+		-c -t "^nss_map_attribute=gecos=cn" \
+		-c -t "^nss_map_attribute=homeDirectory=unixHomeDirectory" \
+		-c -t "^nss_map_attribute=uniqueMember=member" \
+		-c -t "^pam_filter=objectClass=user" \
+		-c -m "^pam_member_attribute=member" \
+		-c -m "^pam_password=ad" \
+		-o "${tmp}"
+	if [ "$?" != "0" ]
+	then
+		return 1
+	fi
+	if ! safe_save "${tmp}" "${conf}"
+	then
+		return 1
+	fi
+
+	printf "${rootbindpw}" > "${secret}"
+	chmod 600 "${secret}"
+
+	ln -sf ${conf} "$(dirname ${conf})/ldap.conf"
+	ln -sf ${secret} "$(dirname ${secret})/ldap.secret"
+
+	return 0
+}
+
 nssldap_start()
 {
 	if checkyesno ldapclient_enable 2>/dev/null
 	then
 		ldap_init
 		backup_nss_ldap_conf
-		generate_nss_ldap_conf
+		generate_LDAP_nss_ldap_conf
+
+	elif checkyesno activedirectory_enable 2>/dev/null
+	then
+		AD_init
+		backup_nss_ldap_conf
+		generate_AD_nss_ldap_conf
 	fi
 }
 
@@ -252,6 +348,10 @@
 	if  checkyesno ldapclient_enable 2>/dev/null
 	then
 		restore_nss_ldap_conf
+
+	elif checkyesno activedirectory_enable 2>/dev/null
+	then
+		restore_nss_ldap_conf
 	fi
 }
 

Modified: pcbsd/current/src-sh/pc-adctl/scripts/pc-nsswitch
===================================================================
--- pcbsd/current/src-sh/pc-adctl/scripts/pc-nsswitch	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/scripts/pc-nsswitch	2012-09-13 07:43:46 UTC (rev 19150)
@@ -11,7 +11,7 @@
 . /usr/local/etc/rc.activedirectory
 
 : ${PATH_NS_CONF:="/etc/nsswitch.conf"}
-: ${NSSCONF:="/usr/local/bin/nssconf"}
+: ${NSSCONF:="/usr/local/bin/pc-nssconf"}
 
 nsswitch_conf_start()
 {
@@ -24,6 +24,13 @@
 		conftype='winbind'
 		doconf=1
 
+		AD_init
+
+		if AD_UNIX_extensions
+		then
+			conftype='ldap'
+		fi
+
 	elif checkyesno ldapclient_enable 2>/dev/null
 	then
 		conftype='ldap'
@@ -67,6 +74,13 @@
 		conftype='winbind'
 		doconf=1
 
+		AD_init
+
+		if AD_UNIX_extensions
+		then
+			conftype='ldap'
+		fi
+
 	elif checkyesno ldapclient_enable 2>/dev/null
 	then
 		conftype='ldap'

Modified: pcbsd/current/src-sh/pc-adctl/scripts/pc-pam
===================================================================
--- pcbsd/current/src-sh/pc-adctl/scripts/pc-pam	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/scripts/pc-pam	2012-09-13 07:43:46 UTC (rev 19150)
@@ -11,180 +11,210 @@
 . /usr/local/etc/rc.ldap
 . /usr/local/etc/rc.activedirectory
 
-: ${DEFAULT_PAM_SERVICES:="ftp login passwd sshd su telnetd"}
-: ${PAMDIR:="/etc/pam.d"}
-: ${PAMCONF:="/usr/local/bin/pamconf"}
 
+: ${DEFAULT_PAM_SERVICES:="ALL"}
+: ${PAMDIRS:="/etc/pam.d /usr/local/etc/pam.d"}
+: ${PAMCONF:="/usr/local/bin/pc-pamconf"}
+
 : ${activedirectory_pam_services:="${DEFAULT_PAM_SERVICES}"}
 : ${ldapclient_pam_services:="${DEFAULT_PAM_SERVICES}"}
 
-pam_start()
+
+in_pam_services()
 {
-	local auth
-	local account
-	local session
-	local password
-	local doconf=0
+	local res=1
+	local service="${1}"
+	local services="${2}"
 
-	if checkyesno activedirectory_enable 2>/dev/null
+	if [ "${services}" = "NONE" ]
 	then
-		doconf=1
-		auth="+2auth:sufficient:/usr/local/lib/pam_winbind.so:silent:try_first_pass:krb5_auth:krb5_ccache_type=FILE"
-		account="+2account:sufficient:/usr/local/lib/pam_winbind.so:krb5_auth:krb5_ccache_type=FILE"
-		session="+session:required:/usr/local/lib/pam_mkhomedir.so"
-		password="+0password:sufficient:/usr/local/lib/pam_winbind.so:try_first_pass:krb5_auth krb5_ccache_type=FILE"
+		return 1
 
-	elif checkyesno ldapclient_enable 2>/dev/null
+	elif [ "${services}" = "ALL" ]
 	then
-		doconf=1
-		auth="+2auth:sufficient:/usr/local/lib/pam_ldap.so:silent:no_warn:try_first_pass"
-		account="+2account:sufficient:/usr/local/lib/pam_ldap.so:ignore_authinfo_unavail"
-		session="+session:required:/usr/local/lib/pam_mkhomedir.so"
-		password="+0password:sufficient:/usr/local/lib/pam_ldap.so:try_first_pass"
+		return 0
+
+	else
+		for s in ${services}
+		do
+			if [ "${s}" = "${service}" ]
+			then
+				res=0
+				break
+			fi
+		done
 	fi
 
-	if [ "${doconf}" = "1" ]
-	then
-		local tmpdir=$(mktemp -d /tmp/pam.XXXXXX)
-		local errors=0
+	return ${res}
+}
 
-		for s in ${activedirectory_pam_services}
+do_pam_conf()
+{
+	local auth="${1}"
+	local account="${2}"
+	local session="${3}"
+	local password="${4}"
+	local services="${5}"
+
+	local fail=0
+	local tmpdirs=""
+
+	for pam_dir in ${PAMDIRS}
+	do
+		local tmpdir="$(mktemp -d /tmp/pam.XXXXXX)"
+		local pam_files="$(ls "${pam_dir}" | grep -v README)"
+
+		tmpdirs="${tmpdirs} ${tmpdir}:${pam_dir}"
+
+		for s in ${pam_files}
 		do
-			local tmp="${tmpdir}/${s}"
-			local sfile="${PAMDIR}/${s}"
+			local pam_file="${pam_dir}/${s}"
+			local tmp_file="${tmpdir}/${s}"
 
-			cp "${sfile}" "${tmpdir}/${s}.orig"
-			${PAMCONF} -f "${sfile}" \
+			if in_pam_services "${s}" "${services}"
+			then
+				${PAMCONF} -f "${pam_file}" \
 				-m "${auth}" \
 				-m "${account}" \
 				-m "${session}" \
 				-m "${password}" \
-				-o "${tmp}"
+				-o "${tmp_file}"
 
-				if [ "$?" != "0" -o ! -s "${tmp}" ]
+				if [ "$?" != "0" ]
 				then
-					errors=1
-					break
+					touch "${tmp_file}.FAIL"
 				fi
+			fi	
 		done
+	done
 
-		if [ "${errors}" = "0" ]
+	for d in ${tmpdirs}
+	do
+		local tmp="$(echo "${d}" | cut -f1 -d:)"
+
+		if "${tmp}/*.FAIL" >/dev/null 2>&1
 		then
-			for s in $(ls ${tmpdir}|grep -v '.orig')
-			do
-				local sfile="${PAMDIR}/${s}"
-
-				mv "${tmpdir}/${s}" "${sfile}"
-				if [ "$?" != "0" ]
-				then
-					errors=1
-					break
-				fi
-			done
+			fail=1
+			break
 		fi
+	done
 
-		if [ "${errors}" = "1" ]
-		then
-			for s in $(ls ${tmpdir}/*.orig)
-			do
-				local sfile="${PAMDIR}/$(echo ${s}|sed 's/.orig//')"
-				local orig="${tmpdir}/${s}"
+	if [ "${fail}" = "1" ]
+	then
+		for d in ${tmpdirs}
+		do
+			local tmp="$(echo "${d}" | cut -f1 -d:)"
+			rm -rf "${tmp}"	
+		done
 
-				mv ${orig} ${sfile}
-			done
+		return 1
+	else
+		for d in ${tmpdirs}
+		do
+			local src="$(echo "${d}" | cut -f1 -d:)"
+			local dst="$(echo "${d}" | cut -f2 -d:)"
 
-			rm -rf "${tmpdir}" >/dev/null 2>&1
-			return 1
-		fi
+			mv ${src}/* ${dst}/
+			rm -rf "${src}"
+		done
 
-		rm -rf "${tmpdir}" >/dev/null 2>&1
 		return 0
 	fi
 
 	return 0
 }
 
-pam_stop()
+pam_start()
 {
 	local auth
 	local account
 	local session
 	local password
+	local services
 	local doconf=0
 
 	if checkyesno activedirectory_enable 2>/dev/null
 	then
+		AD_init
+
+		local pam_winbind="/usr/local/lib/pam_winbind.so"
+		local pam_krb5="pam_krb5.so"
+
+		local pam_mod="${pam_winbind}"
+		if AD_UNIX_extensions
+		then
+			pam_mod="${pam_krb5}"
+		fi
+
 		doconf=1
-		auth='-auth:sufficient:/usr/local/lib/pam_winbind.so'
-		account='-account:sufficient:/usr/local/lib/pam_winbind.so'
-		session='-session:required:/usr/local/lib/pam_mkhomedir.so'
-		password='-password:sufficient:/usr/local/lib/pam_winbind.so'
+		auth="+2auth:sufficient:${pam_mod}:silent:try_first_pass:krb5_auth:krb5_ccache_type=FILE"
+		account="+2account:sufficient:${pam_mod}:krb5_auth:krb5_ccache_type=FILE"
+		session="+session:required:/usr/local/lib/pam_mkhomedir.so"
+		password="+0password:sufficient:${pam_mod}:try_first_pass:krb5_auth:krb5_ccache_type=FILE"
+		services="${activedirectory_pam_services}"
 
 	elif checkyesno ldapclient_enable 2>/dev/null
 	then
 		doconf=1
-		auth='-auth:sufficient:/usr/local/lib/pam_ldap.so'
-		account='-account:sufficient:/usr/local/lib/pam_ldap.so'
-		session='-session:required:/usr/local/lib/pam_mkhomedir.so'
-		password='-password:sufficient:/usr/local/lib/pam_ldap.so'
+		auth="+2auth:sufficient:/usr/local/lib/pam_ldap.so:silent:no_warn:try_first_pass"
+		account="+2account:sufficient:/usr/local/lib/pam_ldap.so:ignore_authinfo_unavail"
+		session="+session:required:/usr/local/lib/pam_mkhomedir.so"
+		password="+0password:sufficient:/usr/local/lib/pam_ldap.so:try_first_pass"
+		services="${ldap_pam_services}"
 	fi
 
 	if [ "${doconf}" = "1" ]
 	then
-		local tmpdir=$(mktemp -d /tmp/pam.XXXXXX)
-		local errors=0
+		do_pam_conf "${auth}" "${account}" "${session}" "${password}" "${services}"
+		return $?
+	fi
 
-		for s in ${activedirectory_pam_services}
-		do
-			local tmp="${tmpdir}/${s}"
-			local sfile="${PAMDIR}/${s}"
+	return 0
+}
 
-			cp "${sfile}" "${tmpdir}/${s}.orig"
-			${PAMCONF} -f "${sfile}" \
-				-m "${auth}" \
-				-m "${account}" \
-				-m "${session}" \
-				-m "${password}" \
-				-o "${tmp}"
+pam_stop()
+{
+	local auth
+	local account
+	local session
+	local password
+	local services
+	local doconf=0
 
-				if [ "$?" != "0" -o ! -s "${tmp}" ]
-				then
-					errors=1
-					break
-				fi
-		done
+	if checkyesno activedirectory_enable 2>/dev/null
+	then
+		AD_init
 
-		if [ "${errors}" = "0" ]
+		local pam_winbind="/usr/local/lib/pam_winbind.so"
+		local pam_krb5="pam_krb5.so"
+
+		local pam_mod="${pam_winbind}"
+		if AD_UNIX_extensions
 		then
-			for s in $(ls ${tmpdir}|grep -v '.orig')
-			do
-				local sfile="${PAMDIR}/${s}"
-
-				mv "${tmpdir}/${s}" "${sfile}"
-				if [ "$?" != "0" ]
-				then
-					errors=1
-					break
-				fi
-			done
+			pam_mod="${pam_krb5}"
 		fi
 
-		if [ "${errors}" = "1" ]
-		then
-			for s in $(ls ${tmpdir}/*.orig)
-			do
-				local sfile="${PAMDIR}/$(echo ${s}|sed 's/.orig//')"
-				local orig="${tmpdir}/${s}"
+		doconf=1
+		auth="-auth:sufficient:${pam_mod}"
+		account="-account:sufficient:${pam_mod}"
+		session="-session:required:/usr/local/lib/pam_mkhomedir.so"
+		password="-password:sufficient:${pam_mod}"
+		services="${activedirectory_pam_services}"
 
-				mv ${orig} ${sfile}
-			done
+	elif checkyesno ldapclient_enable 2>/dev/null
+	then
+		doconf=1
+		auth='-auth:sufficient:/usr/local/lib/pam_ldap.so'
+		account='-account:sufficient:/usr/local/lib/pam_ldap.so'
+		session='-session:required:/usr/local/lib/pam_mkhomedir.so'
+		password='-password:sufficient:/usr/local/lib/pam_ldap.so'
+		services="${ldap_pam_services}"
+	fi
 
-			rm -rf "${tmpdir}" >/dev/null 2>&1
-			return 1
-		fi
-
-		rm -rf "${tmpdir}" >/dev/null 2>&1
-		return 0
+	if [ "${doconf}" = "1" ]
+	then
+		do_pam_conf "${auth}" "${account}" "${session}" "${password}" "${services}"
+		return $?
 	fi
 
 	return 0

Modified: pcbsd/current/src-sh/pc-adctl/scripts/pc-samba
===================================================================
--- pcbsd/current/src-sh/pc-adctl/scripts/pc-samba	2012-09-12 22:11:56 UTC (rev 19149)
+++ pcbsd/current/src-sh/pc-adctl/scripts/pc-samba	2012-09-13 07:43:46 UTC (rev 19150)
@@ -12,7 +12,7 @@
 . /usr/local/etc/rc.activedirectory
 
 : ${SMB_CONF:="/usr/local/etc/smb.conf"}
-: ${SAMBACONF:="/usr/local/bin/sambaconf"}
+: ${SAMBACONF:="/usr/local/bin/pc-sambaconf"}
 
 
 ad_smbconf_start()
@@ -26,14 +26,29 @@
 	if checkyesno activedirectory_enable 2>/dev/null
 	then
 		local tmp=$(mktemp /tmp/samba.XXXXXX)
+		local backend
+		local range
 
 		AD_init
-		local td=$(AD_get ad_allow_trusted_doms)
-		if [ -z "${td}" ]
+
+		local trusted=$(AD_get ad_allow_trusted_doms)
+		if [ -z "${trusted}" ]
 		then
-			td="no"
+			trusted="no"
 		fi
 
+		local default=$(AD_get use_default_domain)
+		if [ -z "${default}" ]
+		then
+			default="yes"
+		fi
+
+		if ! AD_UNIX_extensions
+		then
+			backend="-w -m '+global:idmap config $(AD_get workgroup): backend=rid'"
+			range="-w -m '+global:idmap config $(AD_get workgroup): range=20000-20000000'"
+		fi
+
 		cp "${SMB_CONF}" "${SMB_CONF}.orig"
 		${cmd} \
 			-w -m "+global:security=ADS" \
@@ -53,16 +68,16 @@
 			-w -m "+global:dos filemode=yes" \
 			-w -m "+global:idmap uid=10000-19999" \
 			-w -m "+global:idmap gid=10000-19999" \
-			-w -m "+global:idmap config $(AD_get workgroup): backend=rid" \
-			-w -m "+global:idmap config $(AD_get workgroup): range=20000-20000000" \
+			${backend} \
+			${range} \
 			-w -m "+global:winbind cache time=10" \
 			-w -m "+global:winbind offline logon=yes" \
 			-w -m "+global:winbind enum users=yes" \
 			-w -m "+global:winbind enum groups=yes" \
 			-w -m "+global:winbind nested groups=yes" \
-			-w -m "+global:winbind use default domain=yes" \
+			-w -m "+global:winbind use default domain=${default}" \
 			-w -m "+global:winbind refresh tickets=yes" \
-			-w -m "+global:allow trusted domains=${td}" \
+			-w -m "+global:allow trusted domains=${trusted}" \
 			-w -m "+global:template shell=/bin/sh" \
 			-w -m "+global: template homedir=/home/%U" \
 			-o "${tmp}"



More information about the Commits mailing list