402519fad6c9c50a1802f23090a8aae033146484
[samba.git] / source4 / scripting / devel / wintest / test-howto.py
1 #!/usr/bin/env python
2
3 '''automated testing of the steps of the Samba4 HOWTO'''
4
5 import sys, os
6 import optparse
7 import wintest
8
9 vars = {}
10
11 def check_prerequesites(t):
12     t.info("Checking prerequesites")
13     t.setvar('HOSTNAME', t.cmd_output("hostname -s").strip())
14     if os.getuid() != 0:
15         raise Exception("You must run this script as root")
16     t.cmd_contains("grep 127.0.0.1 /etc/resolv.conf", ["nameserver 127.0.0.1"])
17
18
19 def build_s4(t):
20     '''build samba4'''
21     t.info('Building s4')
22     t.chdir('${SOURCETREE}/source4')
23     t.putenv('CC', 'ccache gcc')
24     t.run_cmd('make reconfigure || ./configure --enable-auto-reconfigure --enable-developer --prefix=${PREFIX} -C')
25     t.run_cmd('make -j')
26     t.run_cmd('rm -rf ${PREFIX}')
27     t.run_cmd('make -j install')
28
29 def provision_s4(t, func_level="2008", interfaces=None):
30     '''provision s4 as a DC'''
31     t.info('Provisioning s4')
32     t.chdir('${PREFIX}')
33     t.run_cmd("rm -rf etc private")
34     t.run_cmd("find var -type f | xargs rm -f")
35     options=' --function-level=%s -d${DEBUGLEVEL}' % func_level
36     if interfaces:
37         options += ' --option=interfaces=%s' % interfaces
38     t.run_cmd('sbin/provision --realm=${LCREALM} --domain=${DOMAIN} --adminpass=${PASSWORD1} --server-role="domain controller"' + options)
39     t.run_cmd('bin/samba-tool newuser testallowed ${PASSWORD1}')
40     t.run_cmd('bin/samba-tool newuser testdenied ${PASSWORD1}')
41     t.run_cmd('bin/samba-tool group addmembers "Allowed RODC Password Replication Group" testallowed')
42
43 def start_s4(t, interfaces=None):
44     t.info('Starting Samba4')
45     t.chdir("${PREFIX}")
46     t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
47     t.run_cmd(['sbin/samba',
48              '--option', 'panic action=gnome-terminal -e "gdb --pid %PID%"',
49              '--option', 'interfaces=%s' % interfaces])
50     t.port_wait("localhost", 139)
51
52 def test_smbclient(t):
53     t.info('Testing smbclient')
54     t.chdir('${PREFIX}')
55     t.cmd_contains("bin/smbclient --version", ["Version 4.0"])
56     t.retry_cmd('bin/smbclient -L localhost -U%', ["netlogon", "sysvol", "IPC Service"])
57     child = t.pexpect_spawn('bin/smbclient //localhost/netlogon -Uadministrator%${PASSWORD1}')
58     child.expect("smb:")
59     child.sendline("dir")
60     child.expect("blocks available")
61     child.sendline("mkdir testdir")
62     child.expect("smb:")
63     child.sendline("cd testdir")
64     child.expect('testdir')
65     child.sendline("cd ..")
66     child.sendline("rmdir testdir")
67
68 def create_shares(t):
69     t.info("Adding test shares")
70     t.chdir('${PREFIX}')
71     f = open("etc/smb.conf", mode='a')
72     f.write(t.substitute('''
73 [test]
74        path = ${PREFIX}/test
75        read only = no
76 [profiles]
77        path = ${PREFIX}/var/profiles
78        read only = no
79     '''))
80     f.close()
81     t.run_cmd("mkdir -p test")
82     t.run_cmd("mkdir -p var/profiles")
83
84
85 def restart_bind(t):
86     t.info("Restarting bind9")
87     t.putenv('KEYTAB_FILE', '${PREFIX}/private/dns.keytab')
88     t.putenv('KRB5_KTNAME', '${PREFIX}/private/dns.keytab')
89     t.run_cmd('killall -9 -q named', checkfail=False)
90     t.port_wait("localhost", 53, wait_for_fail=True)
91     t.run_cmd("${BIND9}")
92     t.port_wait("localhost", 53)
93     t.run_cmd("${RNDC} flush")
94     t.run_cmd("${RNDC} freeze")
95     t.run_cmd("${RNDC} thaw")
96
97 def test_dns(t):
98     t.info("Testing DNS")
99     t.cmd_contains("host -t SRV _ldap._tcp.${LCREALM}.",
100                  ['_ldap._tcp.${LCREALM} has SRV record 0 100 389 ${HOSTNAME}.${LCREALM}'])
101     t.cmd_contains("host -t SRV  _kerberos._udp.${LCREALM}.",
102                  ['_kerberos._udp.${LCREALM} has SRV record 0 100 88 ${HOSTNAME}.${LCREALM}'])
103     t.cmd_contains("host -t A ${HOSTNAME}.${LCREALM}",
104                  ['${HOSTNAME}.${LCREALM} has address'])
105
106 def test_kerberos(t):
107     t.info("Testing kerberos")
108     t.run_cmd("kdestroy")
109     t.kinit("administrator@${REALM}", "${PASSWORD1}")
110     t.cmd_contains("klist -e", ["Ticket cache", "Default principal", "Valid starting"])
111
112
113 def test_dyndns(t):
114     t.chdir('${PREFIX}')
115     t.run_cmd("sbin/samba_dnsupdate --fail-immediately")
116     t.run_cmd("${RNDC} flush")
117
118
119 def run_winjoin(t, vm):
120     t.setwinvars(vm)
121
122     t.info("Joining a windows box to the domain")
123     t.vm_poweroff("${WIN_VM}", checkfail=False)
124     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
125     t.ping_wait("${WIN_HOSTNAME}")
126     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_USER}", "${WIN_PASS}", set_time=True)
127     child.sendline("netdom join ${WIN_HOSTNAME} /Domain:${LCREALM} /PasswordD:${PASSWORD1} /UserD:administrator")
128     child.expect("The command completed successfully")
129     child.sendline("shutdown /r -t 0")
130     t.port_wait("${WIN_HOSTNAME}", 139, wait_for_fail=True)
131     t.port_wait("${WIN_HOSTNAME}", 139)
132
133
134 def test_winjoin(t, vm):
135     t.setwinvars(vm)
136     t.info("Checking the windows join is OK")
137     t.chdir('${PREFIX}')
138     t.port_wait("${WIN_HOSTNAME}", 139)
139     t.retry_cmd('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
140     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
141     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
142     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -k no -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
143     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -k yes -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
144     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}")
145     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
146     child.expect("The command completed successfully")
147     t.vm_poweroff("${WIN_VM}")
148
149
150 def run_dcpromo(t, vm):
151     '''run a dcpromo on windows'''
152     t.setwinvars(vm)
153     
154     t.info("Joining a windows VM ${WIN_VM} to the domain as a DC using dcpromo")
155     t.vm_poweroff("${WIN_VM}", checkfail=False)
156     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
157     t.ping_wait("${WIN_HOSTNAME}")
158     child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}")
159     child.sendline("copy /Y con answers.txt")
160     child.sendline('''
161 [DCINSTALL]
162 RebootOnSuccess=Yes
163 RebootOnCompletion=Yes
164 ReplicaOrNewDomain=Replica
165 ReplicaDomainDNSName=${LCREALM}
166 SiteName=Default-First-Site-Name
167 InstallDNS=No
168 ConfirmGc=Yes
169 CreateDNSDelegation=No
170 UserDomain=${LCREALM}
171 UserName=${LCREALM}\\administrator
172 Password=${PASSWORD1}
173 DatabasePath="C:\Windows\NTDS"
174 LogPath="C:\Windows\NTDS"
175 SYSVOLPath="C:\Windows\SYSVOL"
176 SafeModeAdminPassword=${PASSWORD1}
177 \1a
178 ''')
179     child.expect("copied.")
180     child.expect("C:")
181     child.expect("C:")
182     child.sendline("dcpromo /answer:answers.txt")
183     i = child.expect(["You must restart this computer", "failed", "C:"], timeout=120)
184     if i == 1:
185         raise Exception("dcpromo failed")
186     t.port_wait("${WIN_HOSTNAME}", 139, wait_for_fail=True)
187     t.port_wait("${WIN_HOSTNAME}", 139)
188
189
190 def test_dcpromo(t, vm):
191     t.setwinvars(vm)
192     t.info("Checking the dcpromo join is OK")
193     t.chdir('${PREFIX}')
194     t.port_wait("${WIN_HOSTNAME}", 139)
195     t.retry_cmd('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
196     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
197     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
198
199     t.cmd_contains("bin/samba-tool drs kcc ${HOSTNAME} -Uadministrator@${LCREALM}%${PASSWORD1}", ['Consistency check', 'successful'])
200     t.cmd_contains("bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${LCREALM}%${PASSWORD1}", ['Consistency check', 'successful'])
201
202     t.kinit("administrator@${REALM}", "${PASSWORD1}")
203     for nc in [ '${BASEDN}', 'CN=Configuration,${BASEDN}', 'CN=Schema,CN=Configuration,${BASEDN}' ]:
204         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME} ${WIN_HOSTNAME} %s -k yes" % nc, ["was successful"])
205         t.cmd_contains("bin/samba-tool drs replicate ${WIN_HOSTNAME} ${HOSTNAME} %s -k yes" % nc, ["was successful"])
206
207     t.cmd_contains("bin/samba-tool drs showrepl ${HOSTNAME} -k yes",
208                  [ "INBOUND NEIGHBORS",
209                    "${BASEDN}",
210                    "Last attempt .* was successful",
211                    "CN=Configuration,${BASEDN}",
212                    "Last attempt .* was successful",
213                    "CN=Configuration,${BASEDN}", # cope with either order
214                    "Last attempt .* was successful",
215                    "OUTBOUND NEIGHBORS",
216                    "${BASEDN}",
217                    "Last success",
218                    "CN=Configuration,${BASEDN}",
219                    "Last success",
220                    "CN=Configuration,${BASEDN}",
221                    "Last success"],
222                    ordered=True,
223                    regex=True)
224
225     t.cmd_contains("bin/samba-tool drs showrepl ${WIN_HOSTNAME} -k yes",
226                  [ "INBOUND NEIGHBORS",
227                    "${BASEDN}",
228                    "Last attempt .* was successful",
229                    "CN=Configuration,${BASEDN}",
230                    "Last attempt .* was successful",
231                    "CN=Configuration,${BASEDN}",
232                    "Last attempt .* was successful",
233                    "OUTBOUND NEIGHBORS",
234                    "${BASEDN}",
235                    "Last success",
236                    "CN=Configuration,${BASEDN}",
237                    "Last success",
238                    "CN=Configuration,${BASEDN}",
239                    "Last success" ],
240                    ordered=True,
241                    regex=True)
242
243     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}", set_time=True)
244     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
245     child.expect("The command completed successfully")
246
247     t.run_net_time(child)
248
249     t.info("Checking if showrepl is happy")
250     child.sendline("repadmin /showrepl")
251     child.expect("${BASEDN}")
252     child.expect("was successful")
253     child.expect("CN=Configuration,${BASEDN}")
254     child.expect("was successful")
255     child.expect("CN=Schema,CN=Configuration,${BASEDN}")
256     child.expect("was successful")
257
258     t.info("Checking if new users propogate to windows")
259     t.run_cmd('bin/samba-tool newuser test2 ${PASSWORD2}')
260     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['Sharename', 'Remote IPC'])
261     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['Sharename', 'Remote IPC'])
262
263     t.info("Checking if new users on windows propogate to samba")
264     child.sendline("net user test3 ${PASSWORD3} /add")
265     while True:
266         i = child.expect(["The command completed successfully",
267                           "The directory service was unable to allocate a relative identifier"])
268         if i == 0:
269             break
270         time.sleep(2)
271
272     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['Sharename', 'IPC'])
273     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['Sharename', 'IPC'])
274
275     t.info("Checking propogation of user deletion")
276     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${LCREALM}%${PASSWORD1}')
277     child.sendline("net user test3 /del")
278     child.expect("The command completed successfully")
279
280     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['LOGON_FAILURE'])
281     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['LOGON_FAILURE'])
282     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['LOGON_FAILURE'])
283     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['LOGON_FAILURE'])
284     t.vm_poweroff("${WIN_VM}")
285
286
287 def run_dcpromo_rodc(t, vm):
288     t.setwinvars(vm)
289     t.info("Joining a w2k8 box to the domain as a RODC")
290     t.vm_poweroff("${WIN_VM}", checkfail=False)
291     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
292     t.ping_wait("${WIN_HOSTNAME}")
293     child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}")
294     child.sendline("copy /Y con answers.txt")
295     child.sendline('''
296 [DCInstall]
297 ReplicaOrNewDomain=ReadOnlyReplica
298 ReplicaDomainDNSName=${LCREALM}
299 PasswordReplicationDenied="BUILTIN\Administrators"
300 PasswordReplicationDenied="BUILTIN\Server Operators"
301 PasswordReplicationDenied="BUILTIN\Backup Operators"
302 PasswordReplicationDenied="BUILTIN\Account Operators"
303 PasswordReplicationDenied="${DOMAIN}\Denied RODC Password Replication Group"
304 PasswordReplicationAllowed="${DOMAIN}\Allowed RODC Password Replication Group"
305 DelegatedAdmin="${DOMAIN}\\Administrator"
306 SiteName=Default-First-Site-Name
307 InstallDNS=No
308 ConfirmGc=Yes
309 CreateDNSDelegation=No
310 UserDomain=${LCREALM}
311 UserName=${LCREALM}\\administrator
312 Password=${PASSWORD1}
313 DatabasePath="C:\Windows\NTDS"
314 LogPath="C:\Windows\NTDS"
315 SYSVOLPath="C:\Windows\SYSVOL"
316 SafeModeAdminPassword=${PASSWORD1}
317 RebootOnCompletion=No
318 \1a
319 ''')
320     child.expect("copied.")
321     child.sendline("dcpromo /answer:answers.txt")
322     i = child.expect(["You must restart this computer", "failed"], timeout=120)
323     if i != 0:
324         raise Exception("dcpromo failed")
325     child.sendline("shutdown -r -t 0")
326     t.port_wait("${WIN_HOSTNAME}", 139, wait_for_fail=True)
327     t.port_wait("${WIN_HOSTNAME}", 139)
328
329
330
331 def test_dcpromo_rodc(t, vm):
332     t.setwinvars(vm)
333     t.info("Checking the w2k8 RODC join is OK")
334     t.chdir('${PREFIX}')
335     t.port_wait("${WIN_HOSTNAME}", 139)
336     t.retry_cmd('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
337     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
338     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
339     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}", set_time=True)
340     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
341     child.expect("The command completed successfully")
342
343     t.info("Checking if showrepl is happy")
344     child.sendline("repadmin /showrepl")
345     child.expect("${BASEDN}")
346     child.expect("was successful")
347     child.expect("CN=Configuration,${BASEDN}")
348     child.expect("was successful")
349     child.expect("CN=Configuration,${BASEDN}")
350     child.expect("was successful")
351
352     t.info("Checking if new users are available on windows")
353     t.run_cmd('bin/samba-tool newuser test2 ${PASSWORD2}')
354     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['Sharename', 'Remote IPC'])
355     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['Sharename', 'Remote IPC'])
356     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${LCREALM}%${PASSWORD1}')
357     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2}", ['LOGON_FAILURE'])
358     t.vm_poweroff("${WIN_VM}")
359
360
361 def join_as_dc(t, vm):
362     t.setwinvars(vm)
363     t.info("Joining ${WIN_VM} as a second DC using samba-tool join DC")
364     t.chdir('${PREFIX}')
365     t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
366     t.vm_poweroff("${WIN_VM}", checkfail=False)
367     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
368     t.run_cmd('${RNDC} flush')
369     t.run_cmd("rm -rf etc private")
370     t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
371     t.retry_cmd("bin/samba-tool drs showrepl ${WIN_HOSTNAME} -Uadministrator%${WIN_PASS}", ['INBOUND NEIGHBORS'] )
372     t.run_cmd('bin/samba-tool join ${WIN_REALM} DC -Uadministrator%${WIN_PASS} -d${DEBUGLEVEL}')
373     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
374
375
376 def test_join_as_dc(t, vm):
377     t.setwinvars(vm)
378     t.info("Checking the DC join is OK")
379     t.chdir('${PREFIX}')
380     t.retry_cmd('bin/smbclient -L ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}', ["C$", "IPC$", "Sharename"])
381     t.cmd_contains("host -t A ${HOSTNAME}.${WIN_REALM}.", ['has address'])
382     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
383
384     t.info("Forcing kcc runs, and replication")
385     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
386     t.run_cmd('bin/samba-tool drs kcc ${HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
387
388     t.kinit("administrator@${WIN_REALM}", "${WIN_PASS}")
389     for nc in [ '${WIN_BASEDN}', 'CN=Configuration,${WIN_BASEDN}', 'CN=Schema,CN=Configuration,${WIN_BASEDN}' ]:
390         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME} ${WIN_HOSTNAME} %s -k yes" % nc, ["was successful"])
391         t.cmd_contains("bin/samba-tool drs replicate ${WIN_HOSTNAME} ${HOSTNAME} %s -k yes" % nc, ["was successful"])
392
393     child.sendline("net use t: \\\\${HOSTNAME}.${WIN_REALM}\\test")
394     child.expect("The command completed successfully")
395
396     t.info("Checking if showrepl is happy")
397     child.sendline("repadmin /showrepl")
398     child.expect("${WIN_BASEDN}")
399     child.expect("was successful")
400     child.expect("CN=Configuration,${WIN_BASEDN}")
401     child.expect("was successful")
402     child.expect("CN=Configuration,${WIN_BASEDN}")
403     child.expect("was successful")
404
405     t.info("Checking if new users propogate to windows")
406     t.run_cmd('bin/samba-tool newuser test2 ${PASSWORD2}')
407     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['Sharename', 'Remote IPC'])
408     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['Sharename', 'Remote IPC'])
409
410     t.info("Checking if new users on windows propogate to samba")
411     child.sendline("net user test3 ${PASSWORD3} /add")
412     child.expect("The command completed successfully")
413     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['Sharename', 'IPC'])
414     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['Sharename', 'IPC'])
415
416     t.info("Checking propogation of user deletion")
417     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${WIN_REALM}%${WIN_PASS}')
418     child.sendline("net user test3 /del")
419     child.expect("The command completed successfully")
420
421     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['LOGON_FAILURE'])
422     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['LOGON_FAILURE'])
423     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['LOGON_FAILURE'])
424     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['LOGON_FAILURE'])
425     t.vm_poweroff("${WIN_VM}")
426
427
428 def join_as_rodc(t, vm):
429     t.setwinvars(vm)
430     t.info("Joining ${WIN_VM} as a RODC using samba-tool join DC")
431     t.chdir('${PREFIX}')
432     t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
433     t.vm_poweroff("${WIN_VM}", checkfail=False)
434     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
435     t.run_cmd('${RNDC} flush')
436     t.run_cmd("rm -rf etc private")
437     t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
438     t.retry_cmd("bin/samba-tool drs showrepl ${WIN_HOSTNAME} -Uadministrator%${WIN_PASS}", ['INBOUND NEIGHBORS'] )
439     t.run_cmd('bin/samba-tool join ${WIN_REALM} RODC -Uadministrator%${WIN_PASS} -d${DEBUGLEVEL}')
440     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
441
442
443 def test_join_as_rodc(t, vm):
444     t.setwinvars(vm)
445     t.info("Checking the RODC join is OK")
446     t.chdir('${PREFIX}')
447     t.retry_cmd('bin/smbclient -L ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}', ["C$", "IPC$", "Sharename"])
448     t.cmd_contains("host -t A ${HOSTNAME}.${WIN_REALM}.", ['has address'])
449     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
450
451     t.info("Forcing kcc runs, and replication")
452     t.run_cmd('bin/samba-tool drs kcc ${HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
453     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
454
455     t.kinit("administrator@${WIN_REALM}", "${WIN_PASS}")
456     for nc in [ '${WIN_BASEDN}', 'CN=Configuration,${WIN_BASEDN}', 'CN=Schema,CN=Configuration,${WIN_BASEDN}' ]:
457         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME} ${WIN_HOSTNAME} %s -k yes" % nc, ["was successful"])
458
459     child.sendline("net use t: \\\\${HOSTNAME}.${WIN_REALM}\\test")
460     child.expect("The command completed successfully")
461
462     t.info("Checking if showrepl is happy")
463     child.sendline("repadmin /showrepl")
464     child.expect("DSA invocationID")
465
466     t.cmd_contains("bin/samba-tool drs showrepl ${WIN_HOSTNAME}.${WIN_REALM} -k yes",
467                  [ "INBOUND NEIGHBORS",
468                    "OUTBOUND NEIGHBORS",
469                    "${WIN_BASEDN}",
470                    "Last attempt .* was successful",
471                    "CN=Configuration,${WIN_BASEDN}",
472                    "Last attempt .* was successful",
473                    "CN=Configuration,${WIN_BASEDN}",
474                    "Last attempt .* was successful" ],
475                    ordered=True,
476                    regex=True)
477
478     t.info("Checking if new users on windows propogate to samba")
479     child.sendline("net user test3 ${PASSWORD3} /add")
480     child.expect("The command completed successfully")
481     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['Sharename', 'IPC'])
482     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['Sharename', 'IPC'])
483
484     # should this work?
485     t.info("Checking if new users propogate to windows")
486     t.cmd_contains('bin/samba-tool newuser test2 ${PASSWORD2}', ['No RID Set DN'])
487
488     t.info("Checking propogation of user deletion")
489     child.sendline("net user test3 /del")
490     child.expect("The command completed successfully")
491
492     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['LOGON_FAILURE'])
493     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['LOGON_FAILURE'])
494     t.vm_poweroff("${WIN_VM}")
495
496
497 def test_howto(t):
498     '''test the Samba4 howto'''
499
500     check_prerequesites(t)
501
502     # we don't need fsync safety in these tests
503     t.putenv('TDB_NO_FSYNC', '1')
504
505     if not t.skip("build"):
506         build_s4(t)
507
508     if not t.skip("provision"):
509         provision_s4(t)
510
511     if not t.skip("create-shares"):
512         create_shares(t)
513
514     if not t.skip("starts4"):
515         start_s4(t, interfaces='${INTERFACES}')
516     if not t.skip("smbclient"):
517         test_smbclient(t)
518     if not t.skip("startbind"):
519         restart_bind(t)
520     if not t.skip("dns"):
521         test_dns(t)
522     if not t.skip("kerberos"):
523         test_kerberos(t)
524     if not t.skip("dyndns"):
525         test_dyndns(t)
526     
527     if t.have_var('WINDOWS7_VM') and not t.skip("windows7"):
528         run_winjoin(t, "WINDOWS7")
529         test_winjoin(t, "WINDOWS7")
530
531     if t.have_var('WINXP_VM') and not t.skip("winxp"):
532         run_winjoin(t, "WINXP")
533         test_winjoin(t, "WINXP")
534     
535     if t.have_var('W2K8R2C_VM') and not t.skip("dcpromo_rodc"):
536         t.info("Testing w2k8r2 RODC dcpromo")
537         run_dcpromo_rodc(t, "W2K8R2C")
538         test_dcpromo_rodc(t, "W2K8R2C")
539
540     if t.have_var('W2K8R2B_VM') and not t.skip("dcpromo_w2k8r2"):
541         t.info("Testing w2k8r2 dcpromo")
542         run_dcpromo(t, "W2K8R2B")
543         test_dcpromo(t, "W2K8R2B")
544
545     if t.have_var('W2K8B_VM') and not t.skip("dcpromo_w2k8"):
546         t.info("Testing w2k8 dcpromo")
547         run_dcpromo(t, "W2K8B")
548         test_dcpromo(t, "W2K8B")
549
550     if t.have_var('W2K3B_VM') and not t.skip("dcpromo_w2k3"):
551         t.info("Testing w2k3 dcpromo")
552         t.info("Changing to 2003 functional level")
553         provision_s4(t, func_level='2003', interfaces='${INTERFACES}')
554         create_shares(t)
555         start_s4(t, interfaces='${INTERFACES}')
556         test_smbclient(t)
557         restart_bind(t)
558         test_dns(t)
559         test_kerberos(t)
560         test_dyndns(t)
561         run_dcpromo(t, "W2K3B")
562         test_dcpromo(t, "W2K3B")
563     
564     if t.have_var('W2K8R2A_VM') and not t.skip("join_w2k8r2"):
565         join_as_dc(t, "W2K8R2A")
566         create_shares(t)
567         start_s4(t, interfaces='${INTERFACES}')
568         test_dyndns(t)
569         test_join_as_dc(t, "W2K8R2A")
570
571     if t.have_var('W2K8R2A_VM') and not t.skip("join_rodc"):
572         join_as_rodc(t, "W2K8R2A")
573         create_shares(t)
574         start_s4(t, interfaces='${INTERFACES}')
575         test_dyndns(t)
576         test_join_as_rodc(t, "W2K8R2A")
577     
578     if t.have_var('W2K3A_VM') and not t.skip("join_w2k3"):
579         join_as_dc(t, "W2K3A")
580         create_shares(t)
581         start_s4(t, interfaces='${INTERFACES}')
582         test_dyndns(t)
583         test_join_as_dc(t, "W2K3A")
584
585     t.info("Howto test: All OK")
586
587
588 if __name__ == '__main__':
589     parser = optparse.OptionParser("test-howto.py")
590     parser.add_option("--conf", type='string', default='', help='config file')
591     parser.add_option("--skip", type='string', default='', help='list of steps to skip (comma separated)')
592     parser.add_option("--list", action='store_true', default=False, help='list the available steps')
593     parser.add_option("--rebase", action='store_true', default=False, help='do a git pull --rebase')
594     parser.add_option("--clean", action='store_true', default=False, help='clean the tree')
595
596     opts, args = parser.parse_args()
597
598     if not opts.conf:
599         t.info("Please specify a config file with --conf")
600         sys.exit(1)
601
602     t = wintest.wintest()
603     t.load_config(opts.conf)
604     t.set_skip(opts.skip)
605     if opts.list:
606         t.list_steps_mode()
607
608     if opts.rebase:
609         t.info('rebasing')
610         t.chdir('${SOURCETREE}')
611         t.run_cmd('git pull --rebase')
612
613     if opts.clean:
614         t.info('rebasing')
615         t.chdir('${SOURCETREE}/source4')
616         t.run_cmd('rm -rf bin')
617
618     test_howto(t)