aboutsummaryrefslogtreecommitdiff
path: root/templates
diff options
context:
space:
mode:
authorLebedev Vadim <abraham1901@gmail.com>2013-03-18 18:55:58 +0400
committerAdam Jahn <ajjahn@gmail.com>2013-03-19 21:14:30 -0400
commit32f1dc699c77ae665d8c8e39d8d9c2c3fb497df9 (patch)
tree6b2edbb451b76b18c3bbc3a49d591e91e24e2b06 /templates
parentd612151695cb9121d4aebcdb8a39c0ee87f7c612 (diff)
downloadpuppet-samba-32f1dc699c77ae665d8c8e39d8d9c2c3fb497df9.tar.gz
puppet-samba-32f1dc699c77ae665d8c8e39d8d9c2c3fb497df9.tar.bz2
Add implementation join Samba server into Active Directory
Conflicts: manifests/server/share.pp
Diffstat (limited to 'templates')
-rw-r--r--templates/configure_active_directory.erb142
-rw-r--r--templates/verify_active_directory.erb107
2 files changed, 249 insertions, 0 deletions
diff --git a/templates/configure_active_directory.erb b/templates/configure_active_directory.erb
new file mode 100644
index 0000000..35ba86f
--- /dev/null
+++ b/templates/configure_active_directory.erb
@@ -0,0 +1,142 @@
+#!/bin/bash
+
+# This script can cause a host to join or leave
+# the Windows Active Directory domain
+
+# variables
+#
+# specify a timeout for domain operations
+seconds=300
+#
+# post_join_delay seems to be necessary after joing domain
+post_join_delay=30
+#
+
+PROG=$(basename $0)
+
+function usage () {
+ cat >&2 <<- EOF
+ Usage: $PROG -[hjl]
+ -h help
+ -j join the domain
+ -l leave the domain
+ Return code indicates success (0) or failure.
+ EOF
+}
+
+# kinit and klist path depend on krb5 release
+export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/kerberos/bin
+
+NET=$(which net)
+if ! [ -x "$NET" ]; then
+ echo "ERROR: net command is missing or not executable." >&2
+ exit 1
+fi
+
+EXPECT=$(which expect)
+if ! [ -x "$EXPECT" ]; then
+ echo "ERROR: cannot run expect" >&2
+ exit 1
+fi
+
+if [ $# -eq 0 ]; then
+ usage
+ exit 2
+fi
+
+while getopts "hjlq" option
+do
+ case $option in
+ h ) usage; exit 0;;
+ j ) action="join";;
+ l ) action="leave";;
+ * ) usage; exit 2;;
+ esac
+done
+
+password="<%= scope.lookupvar('samba::server::ads::winbind_pass') -%>"
+
+# short hostname from facter
+my_hostname="<%= hostname -%>"
+
+# what account do we use for net ads commands?
+winbind_acct="<%= scope.lookupvar('samba::server::ads::winbind_acct') -%>"
+
+# which realm will we be joining?
+my_realm="<%= scope.lookupvar('samba::server::ads::realm') -%>"
+
+# where should we create computer accounts?
+target_ou="<%= scope.lookupvar('samba::server::ads::target_ou') -%>"
+
+echo "Please do not kill me; I may be slow" >&2
+
+#TODO, need write time check check_kdc_time
+#if ! /bin/check_kdc_time; then
+# echo "ERROR: time offset too large to manipulate domain" >&2
+# exit 1
+#else
+# echo "INFO: time offset seems ok" >&2
+#fi
+
+if [ "$action" = "leave" ]; then
+ logger -st $PROG "Leaving AD domain"
+ $NET ads $action -U ${winbind_acct}%${password} | grep Deleted && success=true || success=false
+ kdestroy
+ rm -f /etc/krb5.keytab
+ if [ $success = "true" ]; then
+ logger -st $PROG "Left AD domain"
+ else
+ logger -st $PROG "Failed to leave AD domain"
+ fi
+fi
+
+ad_settle() {
+ (
+ echo -n "Waiting $post_join_delay seconds"
+ for x in $(seq 1 $post_join_delay); do
+ echo -n "."
+ sleep 1
+ done
+ echo
+ ) >&2
+}
+
+# ldapmodify _does_ use the env var for sasl bind
+export KRB5CCNAME=$(umask 0077; mktemp -q winbind_cache.XXXXXXXX)
+
+if [ "$action" = "join" ]; then
+ logger -st $PROG "Joining AD domain" >&2
+ $NET ads $action -U ${winbind_acct}%${password} createcomputer="${target_ou}"\
+ | grep Joined && success=true || success=false
+
+if [ $success = "false" ]; then
+ echo ERROR: failed to join domain >&2
+ exit 2
+fi
+
+max_attempts=5
+for attempt in $(seq 1 $max_attempts); do
+ echo "$attempt of $max_attempts:"
+ ad_settle
+ echo "Getting TGT for ${winbind_acct}@${my_realm}" >&2
+ $EXPECT -c "spawn -noecho kinit -c $KRB5CCNAME ${winbind_acct}@${my_realm};
+ expect :;
+ send ${password}\n;
+ expect eof"
+ klist -c $KRB5CCNAME &> /dev/null && break
+done
+
+if [ $(wbinfo -u|wc -l) != 0 ]; then
+ success=true
+else
+ echo "ERROR: return user list from AD is empty" >&2
+ success=false
+fi
+
+# get rid of cred cache
+kdestroy -c $KRB5CCNAME &> /dev/null
+rm -f $KRB5CCNAME &> /dev/null || :
+
+fi
+
+[ "$success" = "true" ] && exit 0 || exit 1
diff --git a/templates/verify_active_directory.erb b/templates/verify_active_directory.erb
new file mode 100644
index 0000000..5a2a506
--- /dev/null
+++ b/templates/verify_active_directory.erb
@@ -0,0 +1,107 @@
+#!/bin/bash
+
+PROG=$(basename $0)
+export EXPIRATION=90
+
+# kinit and klist path depend on krb5 release
+export PATH=/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/kerberos/bin
+
+EXPECT=$(which expect)
+if ! [ -x "$EXPECT" ]; then
+ echo "ERROR: cannot run expect" >&2
+ exit 1
+fi
+
+#TODO
+#if ! check_kdc_time; then
+# {
+# echo "===================================="
+# echo "WARNING: time offset seems too large"
+# echo "===================================="
+# } >&2
+#fi
+
+password="<%= scope.lookupvar('samba::server::ads::winbind_pass') -%>"
+
+# short hostname from facter
+my_hostname="<%= hostname -%>"
+
+winbind_acct="<%= scope.lookupvar('samba::server::ads::winbind_acct') -%>"
+
+default_realm=$(grep -i '^[[:space:]]*realm.*=' /etc/samba/smb.conf | sed 's/ //g' | sed 's/realm=//g')
+
+# if we're still here, let's try the testjoin
+do_testjoin() {
+ echo "Running net ads testjoin with EXPIRATION=$EXPIRATION" >&2
+ _cmd="net ads testjoin -P"
+ if [[ -n "$1" ]]; then
+ _cmd="${_cmd} $@"
+ fi
+ output=$(${_cmd} 2>&1)
+ grep -q 'Join is OK' <<< $output
+ _rc=$?
+ if [ ${_rc} -ne 0 ]; then
+ logger -st $PROG "Error: net ads testjoin -P failed: $output"
+ fi
+ return ${_rc}
+}
+do_testjoin
+if [ $? -ne 0 ]; then
+ # get verbose failure info
+ do_testjoin -d3
+fi
+
+
+# if we're still here, we need to:
+# - get a TGT that enables us to query the attribute 'useraccountcontrol'
+# - confirm that AD trusts us for GSSAPI delegation
+
+export KRB5CCNAME=$(umask 0077; mktemp -q winbind_cache.XXXXXXXX)
+
+get_tgt() {
+ (
+ $EXPECT -c "spawn -noecho kinit -c $KRB5CCNAME ${winbind_acct}@${default_realm};
+ expect :;
+ send ${password}\n;
+ expect eof"
+ ) &> /dev/null
+ klist -c $KRB5CCNAME &> /dev/null
+ return $?
+}
+
+# try this several times.
+max_attempts=5
+# assume non-zero for has_tgt
+has_tgt=1
+for attempt in $(seq 1 $max_attempts); do
+ # If we just joined the domain, it takes a small amount of time
+ # for AD to sort things out amongst the DC's, and it
+ # depends in part on DNS performance.
+ if get_tgt; then
+ has_tgt=0
+ break
+ fi
+ echo "." >&2
+ sleep 3
+done
+
+success=true
+
+if [ $has_tgt -ne 0 ]; then
+ logger -st $PROG "ERROR: failed to get TGT from AD"
+ success=false
+else
+ if [ $(wbinfo -u|wc -l) != 0 ]; then
+ success=true
+ else
+ echo "ERROR: return user list from AD is empty" >&2
+ success=false
+ fi
+
+ # get rid of cred cache
+ kdestroy -c $KRB5CCNAME &> /dev/null
+fi
+
+[[ $success == "false" ]] && exit 1
+
+exit 0