make the error logged when winbindd fails to access the dc during startup more scary...
[samba.git] / ctdb / config / events.d / 50.samba
1 #!/bin/sh
2 # ctdb event script for Samba
3
4 PATH=/bin:/usr/bin:$PATH
5
6 . $CTDB_BASE/functions
7 loadconfig ctdb
8 loadconfig samba
9
10 detect_init_style
11
12 case $CTDB_INIT_STYLE in
13         suse)
14                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-smb}
15                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-nmb}
16                 CTDB_SERVICE_WINBIND=${CTDB_SERVICE_WINBIND:-winbind}
17                 ;;
18         debian)
19                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-samba}
20                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-""}
21                 CTDB_SERVICE_WINBIND=${CTDB_SERVICE_WINBIND:-winbind}
22                 ;;
23         redhat)
24                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-smb}
25                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-""}
26                 CTDB_SERVICE_WINBIND=${CTDB_SERVICE_WINBIND:-winbind}
27                 ;;
28         *)
29                 # should not happen, but for now use redhat style as default:
30                 CTDB_SERVICE_SMB=${CTDB_SERVICE_SMB:-smb}
31                 CTDB_SERVICE_NMB=${CTDB_SERVICE_NMB:-""}
32                 CTDB_SERVICE_WINBIND=${CTDB_SERVICE_WINBIND:-winbind}
33                 ;;
34 esac
35
36 cmd="$1"
37 shift
38
39 [ "$CTDB_MANAGES_SAMBA" = "yes" ] || [ "$CTDB_MANAGES_WINBIND" = "yes" ] || exit 0
40
41
42 # set default samba cleanup period - in minutes
43 [ -z "$SAMBA_CLEANUP_PERIOD" ] && {
44     SAMBA_CLEANUP_PERIOD=10
45 }
46
47 # we keep a cached copy of smb.conf here
48 smbconf_cache="$CTDB_BASE/state/samba/smb.conf.cache"
49
50
51 #############################################
52 # update the smb.conf cache in the foreground
53 testparm_foreground_update() {
54     mkdir -p "$CTDB_BASE/state/samba" || exit 1
55     testparm -s 2> /dev/null | egrep -v 'registry.shares.=|include.=' > "$smbconf_cache"
56 }
57
58 #############################################
59 # update the smb.conf cache in the background
60 testparm_background_update() {
61     # if the cache doesn't exist, then update in the foreground
62     [ -f $smbconf_cache ] || {
63         testparm_foreground_update
64     }
65     # otherwise do a background update
66     (
67         tmpfile="${smbconf_cache}.$$"
68         testparm -s > $tmpfile 2> /dev/null &
69         # remember the pid of the teamparm process
70         pid="$!"
71         # give it 10 seconds to run
72         timeleft=10
73         while [ $timeleft -gt 0 ]; do
74             timeleft=$(($timeleft - 1))
75             # see if the process still exists
76             /bin/kill -0 $pid > /dev/null 2>&1 || {
77                 # it doesn't exist, grab its exit status
78                 wait $pid
79                 [ $? = 0 ] || {
80                     echo "50.samba: smb.conf background update exited with status $?"
81                     rm -f "${tmpfile}"
82                     exit 1
83                 }               
84                 # put the new smb.conf contents in the cache (atomic rename)
85                 # make sure we remove references to the registry while doing 
86                 # this to ensure that running testparm on the cache does
87                 # not use the registry
88                 egrep -v 'registry.shares.=|include.=' < "$tmpfile" > "${tmpfile}.2"
89                 rm -f "$tmpfile"
90                 mv -f "${tmpfile}.2" "$smbconf_cache" || {
91                     echo "50.samba: failed to update background cache"
92                     rm -f "${tmpfile}.2"
93                     exit 1
94                 }
95                 exit 0
96             }
97             # keep waiting for testparm to finish
98             sleep 1
99         done
100         # it took more than 10 seconds - kill it off
101         rm -f "${tmpfile}"
102         /bin/kill -9 "$pid" > /dev/null 2>&1
103         echo "50.samba: timed out updating smbconf cache in background"
104         exit 1
105     ) &
106 }
107
108 ##################################################
109 # show the testparm output using a cached smb.conf 
110 # to avoid registry access
111 testparm_cat() {
112     [ -f $smbconf_cache ] || {
113         testparm_foreground_update
114     }
115     testparm -s "$smbconf_cache" "$@" 2>/dev/null
116 }
117
118 # function to see if ctdb manages winbind
119 check_ctdb_manages_winbind() {
120   [ -z "$CTDB_MANAGES_WINBIND" ] && {
121     secmode=`testparm_cat --parameter-name=security`
122     case $secmode in
123         ADS|DOMAIN)
124             CTDB_MANAGES_WINBIND="yes";
125             ;;
126         *)
127             CTDB_MANAGES_WINBIND="no";
128             ;;
129     esac
130   }
131 }
132
133 ###########################
134 # periodic cleanup function
135 periodic_cleanup() {
136     # running smbstatus scrubs any dead entries from the connections
137     # and sessionid database
138     # echo "Running periodic cleanup of samba databases"
139     smbstatus -np > /dev/null 2>&1 &
140 }
141
142 case $cmd in 
143      startup)
144         # create the state directory for samba
145         /bin/mkdir -p $CTDB_BASE/state/samba
146
147         # make sure samba is not already started
148         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
149                 service "$CTDB_SERVICE_SMB" stop > /dev/null 2>&1
150                 service "$CTDB_SERVICE_NMB" stop > /dev/null 2>&1
151                 killall -0 -q smbd && {
152                     sleep 1
153                     # make absolutely sure samba is dead
154                     killall -q -9 smbd
155                 }
156
157                 killall -0 -q nmbd && {
158                     sleep 1
159                     # make absolutely sure samba is dead
160                     killall -q -9 nmbd
161                 }
162         }
163
164         # restart the winbind service
165         check_ctdb_manages_winbind
166         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
167                 service "$CTDB_SERVICE_WINBIND" stop > /dev/null 2>&1
168                 killall -0 -q winbindd && {
169                     sleep 1
170                     # make absolutely sure winbindd is dead
171                     killall -q -9 winbindd
172                 }
173                 service "$CTDB_SERVICE_WINBIND" start
174                 sleep 1
175                 wbinfo -t || {
176                         echo "ERROR: wbinfo -t returned error during startup. Aborting startup event."
177                         echo "ERROR: This may mean that winbindd can not access the domaincontroller and thus can not authenticate users."
178                         exit 1
179                 }
180         }
181
182         # start Samba service. Start it reniced, as under very heavy load 
183         # the number of smbd processes will mean that it leaves few cycles for
184         # anything else
185         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
186                 nice_service "$CTDB_SERVICE_NMB" start
187                 nice_service "$CTDB_SERVICE_SMB" start
188         }
189         ;;
190         
191      takeip)
192         # nothing special for Samba
193         ;;
194
195      releaseip)
196         # nothing special for Samba
197         ;;
198
199      recovered)
200         # nothing special for Samba
201         exit 0
202         ;;
203
204      shutdown)
205         # shutdown Samba when ctdb goes down
206         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
207                 service "$CTDB_SERVICE_SMB" stop
208                 service "$CTDB_SERVICE_NMB" stop
209         }
210
211         # stop the winbind service
212         check_ctdb_manages_winbind
213         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
214                 service "$CTDB_SERVICE_WINBIND" stop
215         }
216         ;;
217
218      monitor)
219         # Create a dummy file to track when we need to do periodic cleanup
220         # of samba databases
221         [ -f $CTDB_BASE/state/samba/periodic_cleanup ] || {
222                 touch $CTDB_BASE/state/samba/periodic_cleanup
223         }
224         [ `/usr/bin/find $CTDB_BASE/state/samba/periodic_cleanup -mmin +$SAMBA_CLEANUP_PERIOD | wc -l` -eq 1 ] && {
225                 # Cleanup the databases
226                 periodic_cleanup
227                 touch $CTDB_BASE/state/samba/periodic_cleanup
228         }
229
230         [ "$CTDB_MANAGES_SAMBA" = "yes" ] && {
231                 [ "$CTDB_SAMBA_SKIP_SHARE_CHECK" = "yes" ] || {
232                         testparm_background_update
233
234                         testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && {
235                             testparm_foreground_update
236                             testparm_cat | egrep '^WARNING|^ERROR|^Unknown' && {
237                                 echo "ERROR: testparm shows smb.conf is not clean"
238                                 exit 1
239                             }
240                         }
241
242                         smb_dirs=`testparm_cat | egrep '^[[:space:]]*path = ' | cut -d= -f2`
243                         ctdb_check_directories_probe "Samba" $smb_dirs || {
244                             testparm_foreground_update
245                             smb_dirs=`testparm_cat | egrep '^[[:space:]]*path = ' | cut -d= -f2`
246                             ctdb_check_directories "Samba" $smb_dirs
247                         }
248                 }
249
250                 smb_ports="$CTDB_SAMBA_CHECK_PORTS"
251                 [ -z "$smb_ports" ] && {
252                         smb_ports=`testparm_cat --parameter-name="smb ports"`
253                 }
254                 ctdb_check_tcp_ports "Samba" $smb_ports
255         }
256
257         # check winbind is OK
258         check_ctdb_manages_winbind
259         [ "$CTDB_MANAGES_WINBIND" = "yes" ] && {
260                 ctdb_check_command "winbind" "wbinfo -p"
261         }
262         ;;
263
264 esac
265
266 # ignore unknown commands
267 exit 0