65fb5ae9c18cefe99c03803c51b4276f113103c7
[sfrench/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     t.putenv("KRB5_CONFIG", '${PREFIX}/private/krb5.conf')
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, set_ip=True)
123     child.sendline("netdom join ${WIN_HOSTNAME} /Domain:${LCREALM} /PasswordD:${PASSWORD1} /UserD:administrator")
124     child.expect("The command completed successfully")
125     child.expect("C:")
126     child.sendline("shutdown /r -t 0")
127     t.port_wait("${WIN_HOSTNAME}", 139, wait_for_fail=True)
128     t.port_wait("${WIN_HOSTNAME}", 139)
129     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_USER}", "${WIN_PASS}", set_time=True, set_ip=True)
130     child.expect("C:")
131     child.sendline("ipconfig /registerdns")
132     child.expect("Registration of the DNS resource records for all adapters of this computer has been initiated. Any errors will be reported in the Event Viewer")
133     child.expect("C:")
134
135 def test_winjoin(t, vm):
136     t.setwinvars(vm)
137     t.info("Checking the windows join is OK")
138     t.chdir('${PREFIX}')
139     t.port_wait("${WIN_HOSTNAME}", 139)
140     t.retry_cmd('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"], retries=100)
141     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
142     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
143     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -k no -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
144     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -k yes -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
145     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}")
146     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
147     child.expect("The command completed successfully")
148     t.vm_poweroff("${WIN_VM}")
149
150
151 def run_dcpromo(t, vm):
152     '''run a dcpromo on windows'''
153     t.setwinvars(vm)
154
155     t.info("Joining a windows VM ${WIN_VM} to the domain as a DC using dcpromo")
156     t.vm_poweroff("${WIN_VM}", checkfail=False)
157     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
158     t.ping_wait("${WIN_HOSTNAME}")
159     child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_ip=True)
160     child.sendline("copy /Y con answers.txt")
161     child.sendline('''
162 [DCINSTALL]
163 RebootOnSuccess=Yes
164 RebootOnCompletion=Yes
165 ReplicaOrNewDomain=Replica
166 ReplicaDomainDNSName=${LCREALM}
167 SiteName=Default-First-Site-Name
168 InstallDNS=No
169 ConfirmGc=Yes
170 CreateDNSDelegation=No
171 UserDomain=${LCREALM}
172 UserName=${LCREALM}\\administrator
173 Password=${PASSWORD1}
174 DatabasePath="C:\Windows\NTDS"
175 LogPath="C:\Windows\NTDS"
176 SYSVOLPath="C:\Windows\SYSVOL"
177 SafeModeAdminPassword=${PASSWORD1}
178 \1a
179 ''')
180     child.expect("copied.")
181     child.expect("C:")
182     child.expect("C:")
183     child.sendline("dcpromo /answer:answers.txt")
184     i = child.expect(["You must restart this computer", "failed", "C:"], timeout=120)
185     if i == 1:
186         raise Exception("dcpromo failed")
187     t.port_wait("${WIN_HOSTNAME}", 139, wait_for_fail=True)
188     t.port_wait("${WIN_HOSTNAME}", 139)
189
190
191 def test_dcpromo(t, vm):
192     t.setwinvars(vm)
193     t.info("Checking the dcpromo join is OK")
194     t.chdir('${PREFIX}')
195     t.port_wait("${WIN_HOSTNAME}", 139)
196     t.retry_cmd('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
197     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
198     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
199
200     t.cmd_contains("bin/samba-tool drs kcc ${HOSTNAME} -Uadministrator@${LCREALM}%${PASSWORD1}", ['Consistency check', 'successful'])
201     t.cmd_contains("bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${LCREALM}%${PASSWORD1}", ['Consistency check', 'successful'])
202
203     t.kinit("administrator@${REALM}", "${PASSWORD1}")
204     for nc in [ '${BASEDN}', 'CN=Configuration,${BASEDN}', 'CN=Schema,CN=Configuration,${BASEDN}' ]:
205         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME} ${WIN_HOSTNAME} %s -k yes" % nc, ["was successful"])
206         t.cmd_contains("bin/samba-tool drs replicate ${WIN_HOSTNAME} ${HOSTNAME} %s -k yes" % nc, ["was successful"])
207
208     t.cmd_contains("bin/samba-tool drs showrepl ${HOSTNAME} -k yes",
209                  [ "INBOUND NEIGHBORS",
210                    "${BASEDN}",
211                    "Last attempt .* was successful",
212                    "CN=Configuration,${BASEDN}",
213                    "Last attempt .* was successful",
214                    "CN=Configuration,${BASEDN}", # cope with either order
215                    "Last attempt .* was successful",
216                    "OUTBOUND NEIGHBORS",
217                    "${BASEDN}",
218                    "Last success",
219                    "CN=Configuration,${BASEDN}",
220                    "Last success",
221                    "CN=Configuration,${BASEDN}",
222                    "Last success"],
223                    ordered=True,
224                    regex=True)
225
226     t.cmd_contains("bin/samba-tool drs showrepl ${WIN_HOSTNAME} -k yes",
227                  [ "INBOUND NEIGHBORS",
228                    "${BASEDN}",
229                    "Last attempt .* was successful",
230                    "CN=Configuration,${BASEDN}",
231                    "Last attempt .* was successful",
232                    "CN=Configuration,${BASEDN}",
233                    "Last attempt .* was successful",
234                    "OUTBOUND NEIGHBORS",
235                    "${BASEDN}",
236                    "Last success",
237                    "CN=Configuration,${BASEDN}",
238                    "Last success",
239                    "CN=Configuration,${BASEDN}",
240                    "Last success" ],
241                    ordered=True,
242                    regex=True)
243
244     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}", set_time=True)
245     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
246     child.expect("The command completed successfully")
247
248     t.run_net_time(child)
249
250     t.info("Checking if showrepl is happy")
251     child.sendline("repadmin /showrepl")
252     child.expect("${BASEDN}")
253     child.expect("was successful")
254     child.expect("CN=Configuration,${BASEDN}")
255     child.expect("was successful")
256     child.expect("CN=Schema,CN=Configuration,${BASEDN}")
257     child.expect("was successful")
258
259     t.info("Checking if new users propogate to windows")
260     t.run_cmd('bin/samba-tool newuser test2 ${PASSWORD2}')
261     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['Sharename', 'Remote IPC'])
262     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['Sharename', 'Remote IPC'])
263
264     t.info("Checking if new users on windows propogate to samba")
265     child.sendline("net user test3 ${PASSWORD3} /add")
266     while True:
267         i = child.expect(["The command completed successfully",
268                           "The directory service was unable to allocate a relative identifier"])
269         if i == 0:
270             break
271         time.sleep(2)
272
273     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['Sharename', 'IPC'])
274     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['Sharename', 'IPC'])
275
276     t.info("Checking propogation of user deletion")
277     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${LCREALM}%${PASSWORD1}')
278     child.sendline("net user test3 /del")
279     child.expect("The command completed successfully")
280
281     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['LOGON_FAILURE'])
282     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['LOGON_FAILURE'])
283     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['LOGON_FAILURE'])
284     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['LOGON_FAILURE'])
285     t.vm_poweroff("${WIN_VM}")
286
287
288 def run_dcpromo_rodc(t, vm):
289     t.setwinvars(vm)
290     t.info("Joining a w2k8 box to the domain as a RODC")
291     t.vm_poweroff("${WIN_VM}", checkfail=False)
292     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
293     t.ping_wait("${WIN_HOSTNAME}")
294     child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_ip=True)
295     child.sendline("copy /Y con answers.txt")
296     child.sendline('''
297 [DCInstall]
298 ReplicaOrNewDomain=ReadOnlyReplica
299 ReplicaDomainDNSName=${LCREALM}
300 PasswordReplicationDenied="BUILTIN\Administrators"
301 PasswordReplicationDenied="BUILTIN\Server Operators"
302 PasswordReplicationDenied="BUILTIN\Backup Operators"
303 PasswordReplicationDenied="BUILTIN\Account Operators"
304 PasswordReplicationDenied="${DOMAIN}\Denied RODC Password Replication Group"
305 PasswordReplicationAllowed="${DOMAIN}\Allowed RODC Password Replication Group"
306 DelegatedAdmin="${DOMAIN}\\Administrator"
307 SiteName=Default-First-Site-Name
308 InstallDNS=No
309 ConfirmGc=Yes
310 CreateDNSDelegation=No
311 UserDomain=${LCREALM}
312 UserName=${LCREALM}\\administrator
313 Password=${PASSWORD1}
314 DatabasePath="C:\Windows\NTDS"
315 LogPath="C:\Windows\NTDS"
316 SYSVOLPath="C:\Windows\SYSVOL"
317 SafeModeAdminPassword=${PASSWORD1}
318 RebootOnCompletion=No
319 \1a
320 ''')
321     child.expect("copied.")
322     child.sendline("dcpromo /answer:answers.txt")
323     i = child.expect(["You must restart this computer", "failed"], timeout=120)
324     if i != 0:
325         raise Exception("dcpromo failed")
326     child.sendline("shutdown -r -t 0")
327     t.port_wait("${WIN_HOSTNAME}", 139, wait_for_fail=True)
328     t.port_wait("${WIN_HOSTNAME}", 139)
329
330
331
332 def test_dcpromo_rodc(t, vm):
333     t.setwinvars(vm)
334     t.info("Checking the w2k8 RODC join is OK")
335     t.chdir('${PREFIX}')
336     t.port_wait("${WIN_HOSTNAME}", 139)
337     t.retry_cmd('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
338     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
339     t.cmd_contains('bin/smbclient -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%${PASSWORD1}', ["C$", "IPC$", "Sharename"])
340     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}", set_time=True)
341     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
342     child.expect("The command completed successfully")
343
344     t.info("Checking if showrepl is happy")
345     child.sendline("repadmin /showrepl")
346     child.expect("${BASEDN}")
347     child.expect("was successful")
348     child.expect("CN=Configuration,${BASEDN}")
349     child.expect("was successful")
350     child.expect("CN=Configuration,${BASEDN}")
351     child.expect("was successful")
352
353     t.info("Checking if new users are available on windows")
354     t.run_cmd('bin/samba-tool newuser test2 ${PASSWORD2}')
355     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['Sharename', 'Remote IPC'])
356     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['Sharename', 'Remote IPC'])
357     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${LCREALM}%${PASSWORD1}')
358     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2}", ['LOGON_FAILURE'])
359     t.vm_poweroff("${WIN_VM}")
360
361
362 def join_as_dc(t, vm):
363     t.setwinvars(vm)
364     t.info("Joining ${WIN_VM} as a second DC using samba-tool join DC")
365     t.chdir('${PREFIX}')
366     t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
367     t.vm_poweroff("${WIN_VM}", checkfail=False)
368     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
369     t.run_cmd('${RNDC} flush')
370     t.run_cmd("rm -rf etc private")
371     t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True, set_ip=True)
372     t.retry_cmd("bin/samba-tool drs showrepl ${WIN_HOSTNAME} -Uadministrator%${WIN_PASS}", ['INBOUND NEIGHBORS'] )
373     t.run_cmd('bin/samba-tool join ${WIN_REALM} DC -Uadministrator%${WIN_PASS} -d${DEBUGLEVEL}')
374     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
375
376
377 def test_join_as_dc(t, vm):
378     t.setwinvars(vm)
379     t.info("Checking the DC join is OK")
380     t.chdir('${PREFIX}')
381     t.retry_cmd('bin/smbclient -L ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}', ["C$", "IPC$", "Sharename"])
382     t.cmd_contains("host -t A ${HOSTNAME}.${WIN_REALM}.", ['has address'])
383     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
384
385     t.info("Forcing kcc runs, and replication")
386     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
387     t.run_cmd('bin/samba-tool drs kcc ${HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
388
389     t.kinit("administrator@${WIN_REALM}", "${WIN_PASS}")
390     for nc in [ '${WIN_BASEDN}', 'CN=Configuration,${WIN_BASEDN}', 'CN=Schema,CN=Configuration,${WIN_BASEDN}' ]:
391         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME} ${WIN_HOSTNAME} %s -k yes" % nc, ["was successful"])
392         t.cmd_contains("bin/samba-tool drs replicate ${WIN_HOSTNAME} ${HOSTNAME} %s -k yes" % nc, ["was successful"])
393
394     child.sendline("net use t: \\\\${HOSTNAME}.${WIN_REALM}\\test")
395     child.expect("The command completed successfully")
396
397     t.info("Checking if showrepl is happy")
398     child.sendline("repadmin /showrepl")
399     child.expect("${WIN_BASEDN}")
400     child.expect("was successful")
401     child.expect("CN=Configuration,${WIN_BASEDN}")
402     child.expect("was successful")
403     child.expect("CN=Configuration,${WIN_BASEDN}")
404     child.expect("was successful")
405
406     t.info("Checking if new users propogate to windows")
407     t.run_cmd('bin/samba-tool newuser test2 ${PASSWORD2}')
408     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['Sharename', 'Remote IPC'])
409     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['Sharename', 'Remote IPC'])
410
411     t.info("Checking if new users on windows propogate to samba")
412     child.sendline("net user test3 ${PASSWORD3} /add")
413     child.expect("The command completed successfully")
414     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['Sharename', 'IPC'])
415     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['Sharename', 'IPC'])
416
417     t.info("Checking propogation of user deletion")
418     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${WIN_REALM}%${WIN_PASS}')
419     child.sendline("net user test3 /del")
420     child.expect("The command completed successfully")
421
422     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k no", ['LOGON_FAILURE'])
423     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['LOGON_FAILURE'])
424     t.retry_cmd("bin/smbclient -L ${WIN_HOSTNAME} -Utest2%${PASSWORD2} -k yes", ['LOGON_FAILURE'])
425     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['LOGON_FAILURE'])
426     t.vm_poweroff("${WIN_VM}")
427
428
429 def join_as_rodc(t, vm):
430     t.setwinvars(vm)
431     t.info("Joining ${WIN_VM} as a RODC using samba-tool join DC")
432     t.chdir('${PREFIX}')
433     t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
434     t.vm_poweroff("${WIN_VM}", checkfail=False)
435     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
436     t.run_cmd('${RNDC} flush')
437     t.run_cmd("rm -rf etc private")
438     t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True, set_ip=True)
439     t.retry_cmd("bin/samba-tool drs showrepl ${WIN_HOSTNAME} -Uadministrator%${WIN_PASS}", ['INBOUND NEIGHBORS'] )
440     t.run_cmd('bin/samba-tool join ${WIN_REALM} RODC -Uadministrator%${WIN_PASS} -d${DEBUGLEVEL}')
441     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
442
443
444 def test_join_as_rodc(t, vm):
445     t.setwinvars(vm)
446     t.info("Checking the RODC join is OK")
447     t.chdir('${PREFIX}')
448     t.retry_cmd('bin/smbclient -L ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}', ["C$", "IPC$", "Sharename"])
449     t.cmd_contains("host -t A ${HOSTNAME}.${WIN_REALM}.", ['has address'])
450     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
451
452     t.info("Forcing kcc runs, and replication")
453     t.run_cmd('bin/samba-tool drs kcc ${HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
454     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
455
456     t.kinit("administrator@${WIN_REALM}", "${WIN_PASS}")
457     for nc in [ '${WIN_BASEDN}', 'CN=Configuration,${WIN_BASEDN}', 'CN=Schema,CN=Configuration,${WIN_BASEDN}' ]:
458         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME} ${WIN_HOSTNAME} %s -k yes" % nc, ["was successful"])
459
460     child.sendline("net use t: \\\\${HOSTNAME}.${WIN_REALM}\\test")
461     child.expect("The command completed successfully")
462
463     t.info("Checking if showrepl is happy")
464     child.sendline("repadmin /showrepl")
465     child.expect("DSA invocationID")
466
467     t.cmd_contains("bin/samba-tool drs showrepl ${WIN_HOSTNAME}.${WIN_REALM} -k yes",
468                  [ "INBOUND NEIGHBORS",
469                    "OUTBOUND NEIGHBORS",
470                    "${WIN_BASEDN}",
471                    "Last attempt .* was successful",
472                    "CN=Configuration,${WIN_BASEDN}",
473                    "Last attempt .* was successful",
474                    "CN=Configuration,${WIN_BASEDN}",
475                    "Last attempt .* was successful" ],
476                    ordered=True,
477                    regex=True)
478
479     t.info("Checking if new users on windows propogate to samba")
480     child.sendline("net user test3 ${PASSWORD3} /add")
481     child.expect("The command completed successfully")
482     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['Sharename', 'IPC'])
483     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['Sharename', 'IPC'])
484
485     # should this work?
486     t.info("Checking if new users propogate to windows")
487     t.cmd_contains('bin/samba-tool newuser test2 ${PASSWORD2}', ['No RID Set DN'])
488
489     t.info("Checking propogation of user deletion")
490     child.sendline("net user test3 /del")
491     child.expect("The command completed successfully")
492
493     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k no", ['LOGON_FAILURE'])
494     t.retry_cmd("bin/smbclient -L ${HOSTNAME} -Utest3%${PASSWORD3} -k yes", ['LOGON_FAILURE'])
495     t.vm_poweroff("${WIN_VM}")
496
497
498 def test_howto(t):
499     '''test the Samba4 howto'''
500
501     check_prerequesites(t)
502
503     # we don't need fsync safety in these tests
504     t.putenv('TDB_NO_FSYNC', '1')
505
506     if not t.skip("build"):
507         build_s4(t)
508
509     if not t.skip("provision"):
510         provision_s4(t)
511
512     if not t.skip("create-shares"):
513         create_shares(t)
514
515     if not t.skip("starts4"):
516         start_s4(t, interfaces='${INTERFACES}')
517     if not t.skip("smbclient"):
518         test_smbclient(t)
519     if not t.skip("startbind"):
520         restart_bind(t)
521     if not t.skip("dns"):
522         test_dns(t)
523     if not t.skip("kerberos"):
524         test_kerberos(t)
525     if not t.skip("dyndns"):
526         test_dyndns(t)
527
528     if t.have_var('WINDOWS7_VM') and not t.skip("windows7"):
529         run_winjoin(t, "WINDOWS7")
530         test_winjoin(t, "WINDOWS7")
531
532     if t.have_var('WINXP_VM') and not t.skip("winxp"):
533         run_winjoin(t, "WINXP")
534         test_winjoin(t, "WINXP")
535
536     if t.have_var('W2K8R2C_VM') and not t.skip("dcpromo_rodc"):
537         t.info("Testing w2k8r2 RODC dcpromo")
538         run_dcpromo_rodc(t, "W2K8R2C")
539         test_dcpromo_rodc(t, "W2K8R2C")
540
541     if t.have_var('W2K8R2B_VM') and not t.skip("dcpromo_w2k8r2"):
542         t.info("Testing w2k8r2 dcpromo")
543         run_dcpromo(t, "W2K8R2B")
544         test_dcpromo(t, "W2K8R2B")
545
546     if t.have_var('W2K8B_VM') and not t.skip("dcpromo_w2k8"):
547         t.info("Testing w2k8 dcpromo")
548         run_dcpromo(t, "W2K8B")
549         test_dcpromo(t, "W2K8B")
550
551     if t.have_var('W2K3B_VM') and not t.skip("dcpromo_w2k3"):
552         t.info("Testing w2k3 dcpromo")
553         t.info("Changing to 2003 functional level")
554         provision_s4(t, func_level='2003', interfaces='${INTERFACES}')
555         create_shares(t)
556         start_s4(t, interfaces='${INTERFACES}')
557         test_smbclient(t)
558         restart_bind(t)
559         test_dns(t)
560         test_kerberos(t)
561         test_dyndns(t)
562         run_dcpromo(t, "W2K3B")
563         test_dcpromo(t, "W2K3B")
564
565     if t.have_var('W2K8R2A_VM') and not t.skip("join_w2k8r2"):
566         join_as_dc(t, "W2K8R2A")
567         create_shares(t)
568         start_s4(t, interfaces='${INTERFACES}')
569         test_dyndns(t)
570         test_join_as_dc(t, "W2K8R2A")
571
572     if t.have_var('W2K8R2A_VM') and not t.skip("join_rodc"):
573         join_as_rodc(t, "W2K8R2A")
574         create_shares(t)
575         start_s4(t, interfaces='${INTERFACES}')
576         test_dyndns(t)
577         test_join_as_rodc(t, "W2K8R2A")
578
579     if t.have_var('W2K3A_VM') and not t.skip("join_w2k3"):
580         join_as_dc(t, "W2K3A")
581         create_shares(t)
582         start_s4(t, interfaces='${INTERFACES}')
583         test_dyndns(t)
584         test_join_as_dc(t, "W2K3A")
585
586     t.info("Howto test: All OK")
587
588
589 if __name__ == '__main__':
590     parser = optparse.OptionParser("test-howto.py")
591     parser.add_option("--conf", type='string', default='', help='config file')
592     parser.add_option("--skip", type='string', default='', help='list of steps to skip (comma separated)')
593     parser.add_option("--list", action='store_true', default=False, help='list the available steps')
594     parser.add_option("--rebase", action='store_true', default=False, help='do a git pull --rebase')
595     parser.add_option("--clean", action='store_true', default=False, help='clean the tree')
596     parser.add_option("--prefix", type='string', default=None, help='override install prefix')
597     parser.add_option("--sourcetree", type='string', default=None, help='override sourcetree location')
598
599     opts, args = parser.parse_args()
600
601     if not opts.conf:
602         print("Please specify a config file with --conf")
603         sys.exit(1)
604
605     t = wintest.wintest()
606     t.load_config(opts.conf)
607     t.set_skip(opts.skip)
608
609     if opts.list:
610         t.list_steps_mode()
611
612     if opts.prefix:
613         t.setvar('PREFIX', opts.prefix)
614
615     if opts.sourcetree:
616         t.setvar('SOURCETREE', opts.sourcetree)
617
618     if opts.rebase:
619         t.info('rebasing')
620         t.chdir('${SOURCETREE}')
621         t.run_cmd('git pull --rebase')
622
623     if opts.clean:
624         t.info('rebasing')
625         t.chdir('${SOURCETREE}/source4')
626         t.run_cmd('rm -rf bin')
627
628     test_howto(t)