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