aboutsummaryrefslogtreecommitdiff
path: root/templates/configure_active_directory.erb
blob: c860c780ddef61447a0e13146d28374db73b3372 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/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
    if [ "${target_ou}" != "" ]; then
    	ou_parameter="createcomputer=\"${target_ou}\""
    else
        ou_parameter=""
    fi

    logger -st $PROG "Joining AD domain" >&2
    $NET ads $action -U "${winbind_acct}%${password}" ${ou_parameter} \
	| 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