PEP8: fix E303: too many blank lines (2)
[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 wintest, pexpect, time, subprocess
7
8
9 def set_krb5_conf(t):
10     t.putenv("KRB5_CONFIG", '${PREFIX}/private/krb5.conf')
11
12
13 def build_s4(t):
14     '''build samba4'''
15     t.info('Building s4')
16     t.chdir('${SOURCETREE}')
17     t.putenv('CC', 'ccache gcc')
18     t.run_cmd('make reconfigure || ./configure --enable-auto-reconfigure --enable-developer --prefix=${PREFIX} -C')
19     t.run_cmd('make -j')
20     t.run_cmd('rm -rf ${PREFIX}')
21     t.run_cmd('make -j install')
22
23
24 def provision_s4(t, func_level="2008"):
25     '''provision s4 as a DC'''
26     t.info('Provisioning s4')
27     t.chdir('${PREFIX}')
28     t.del_files(["var", "private"])
29     t.run_cmd("rm -f etc/smb.conf")
30     provision = ['bin/samba-tool',
31                'domain',
32                'provision',
33                '--realm=${LCREALM}',
34                '--domain=${DOMAIN}',
35                '--adminpass=${PASSWORD1}',
36                '--server-role=domain controller',
37                '--function-level=%s' % func_level,
38                '-d${DEBUGLEVEL}',
39                '--option=interfaces=${INTERFACE}',
40                '--host-ip=${INTERFACE_IP}',
41                '--option=bind interfaces only=yes',
42                '--option=rndc command=${RNDC} -c${PREFIX}/etc/rndc.conf',
43                '--dns-backend=${NAMESERVER_BACKEND}',
44                '${DNS_FORWARDER}']
45     if t.getvar('USE_NTVFS'):
46         provision.append('${USE_NTVFS}')
47
48     if t.getvar('INTERFACE_IPV6'):
49         provision.append('--host-ip6=${INTERFACE_IPV6}')
50     t.run_cmd(provision)
51     t.run_cmd('bin/samba-tool user add testallowed ${PASSWORD1}')
52     t.run_cmd('bin/samba-tool user add testdenied ${PASSWORD1}')
53     t.run_cmd('bin/samba-tool group addmembers "Allowed RODC Password Replication Group" testallowed')
54
55
56 def start_s4(t):
57     '''startup samba4'''
58     t.info('Starting Samba4')
59     t.chdir("${PREFIX}")
60     t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
61     t.run_cmd(['sbin/samba',
62                '--option', 'panic action=gnome-terminal -e "gdb --pid %d"', '--option', 'max protocol=nt1'])
63     t.port_wait("${INTERFACE_IP}", 139)
64
65
66 def test_smbclient(t):
67     '''test smbclient against localhost'''
68     t.info('Testing smbclient')
69     smbclient = t.getvar("smbclient")
70     t.chdir('${PREFIX}')
71     t.cmd_contains("%s --version" % (smbclient), ["Version 4.1"])
72     t.retry_cmd('%s -L ${INTERFACE_IP} -U%%' % (smbclient), ["netlogon", "sysvol", "IPC Service"])
73     child = t.pexpect_spawn('%s //${INTERFACE_IP}/netlogon -Uadministrator%%${PASSWORD1}' % (smbclient))
74     child.expect("smb:")
75     child.sendline("dir")
76     child.expect("blocks available")
77     child.sendline("mkdir testdir")
78     child.expect("smb:")
79     child.sendline("cd testdir")
80     child.expect('testdir')
81     child.sendline("cd ..")
82     child.sendline("rmdir testdir")
83
84
85 def create_shares(t):
86     '''create some test shares'''
87     t.info("Adding test shares")
88     t.chdir('${PREFIX}')
89     t.write_file("etc/smb.conf", '''
90 [test]
91        path = ${PREFIX}/test
92        read only = no
93 [profiles]
94        path = ${PREFIX}/var/profiles
95        read only = no
96     ''',
97                  mode='a')
98     t.run_cmd("mkdir -p test")
99     t.run_cmd("mkdir -p var/profiles")
100
101
102 def test_dns(t):
103     '''test that DNS is OK'''
104     t.info("Testing DNS")
105     t.cmd_contains("host -t SRV _ldap._tcp.${LCREALM}.",
106                    ['_ldap._tcp.${LCREALM} has SRV record 0 100 389 ${HOSTNAME}.${LCREALM}'])
107     t.cmd_contains("host -t SRV  _kerberos._udp.${LCREALM}.",
108                    ['_kerberos._udp.${LCREALM} has SRV record 0 100 88 ${HOSTNAME}.${LCREALM}'])
109     t.cmd_contains("host -t A ${HOSTNAME}.${LCREALM}",
110                    ['${HOSTNAME}.${LCREALM} has address'])
111
112
113 def test_kerberos(t):
114     '''test that kerberos is OK'''
115     t.info("Testing kerberos")
116     t.run_cmd("kdestroy")
117     t.kinit("administrator@${REALM}", "${PASSWORD1}")
118     # this copes with the differences between MIT and Heimdal klist
119     t.cmd_contains("klist", ["rincipal", "administrator@${REALM}"])
120
121
122 def test_dyndns(t):
123     '''test that dynamic DNS is working'''
124     t.chdir('${PREFIX}')
125     t.run_cmd("sbin/samba_dnsupdate --fail-immediately")
126     if not t.getvar('NAMESERVER_BACKEND') == 'SAMBA_INTERNAL':
127         t.rndc_cmd("flush")
128
129
130 def run_winjoin(t, vm):
131     '''join a windows box to our domain'''
132     t.setwinvars(vm)
133
134     t.run_winjoin(t, "${LCREALM}")
135
136
137 def test_winjoin(t, vm):
138     t.info("Checking the windows join is OK")
139     smbclient = t.getvar("smbclient")
140     t.chdir('${PREFIX}')
141     t.port_wait("${WIN_IP}", 139)
142     t.retry_cmd('%s -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"], retries=100)
143     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
144     t.cmd_contains('%s -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"])
145     t.cmd_contains('%s -L ${WIN_HOSTNAME}.${LCREALM} -k no -Utestallowed@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"])
146     t.cmd_contains('%s -L ${WIN_HOSTNAME}.${LCREALM} -k yes -Utestallowed@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"])
147     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}")
148     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
149     child.expect("The command completed successfully")
150
151
152 def run_dcpromo(t, vm):
153     '''run a dcpromo on windows'''
154     t.setwinvars(vm)
155
156     t.info("Joining a windows VM ${WIN_VM} to the domain as a DC using dcpromo")
157     child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_ip=True, set_noexpire=True)
158     child.sendline("copy /Y con answers.txt")
159     child.sendline('''
160 [DCINSTALL]
161 RebootOnSuccess=Yes
162 RebootOnCompletion=Yes
163 ReplicaOrNewDomain=Replica
164 ReplicaDomainDNSName=${LCREALM}
165 SiteName=Default-First-Site-Name
166 InstallDNS=No
167 ConfirmGc=Yes
168 CreateDNSDelegation=No
169 UserDomain=${LCREALM}
170 UserName=${LCREALM}\\administrator
171 Password=${PASSWORD1}
172 DatabasePath="C:\Windows\NTDS"
173 LogPath="C:\Windows\NTDS"
174 SYSVOLPath="C:\Windows\SYSVOL"
175 SafeModeAdminPassword=${PASSWORD1}
176 \1a
177 ''')
178     child.expect("copied.")
179     child.expect("C:")
180     child.expect("C:")
181     child.sendline("dcpromo /answer:answers.txt")
182     i = child.expect(["You must restart this computer", "failed", "Active Directory Domain Services was not installed", "C:"], timeout=240)
183     if i == 1 or i == 2:
184         child.sendline("echo off")
185         child.sendline("echo START DCPROMO log")
186         child.sendline("more c:\windows\debug\dcpromoui.log")
187         child.sendline("echo END DCPROMO log")
188         child.expect("END DCPROMO")
189         raise Exception("dcpromo failed")
190     t.wait_reboot()
191
192
193 def test_dcpromo(t, vm):
194     '''test that dcpromo worked'''
195     t.info("Checking the dcpromo join is OK")
196     smbclient = t.getvar("smbclient")
197     t.chdir('${PREFIX}')
198     t.port_wait("${WIN_IP}", 139)
199     t.retry_cmd("host -t A ${WIN_HOSTNAME}.${LCREALM}. ${NAMED_INTERFACE_IP}",
200                 ['${WIN_HOSTNAME}.${LCREALM} has address'],
201                 retries=30, delay=10, casefold=True)
202     t.retry_cmd('%s -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"])
203     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
204     t.cmd_contains('%s -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"])
205
206     t.cmd_contains("bin/samba-tool drs kcc ${HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%${PASSWORD1}", ['Consistency check', 'successful'])
207     t.retry_cmd("bin/samba-tool drs kcc ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%${PASSWORD1}", ['Consistency check', 'successful'])
208
209     t.kinit("administrator@${REALM}", "${PASSWORD1}")
210
211     # the first replication will transfer the dnsHostname attribute
212     t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME}.${LCREALM} ${WIN_HOSTNAME} CN=Configuration,${BASEDN} -k yes", ["was successful"])
213
214     for nc in ['${BASEDN}', 'CN=Configuration,${BASEDN}', 'CN=Schema,CN=Configuration,${BASEDN}']:
215         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME}.${LCREALM} ${WIN_HOSTNAME}.${LCREALM} %s -k yes" % nc, ["was successful"])
216         t.cmd_contains("bin/samba-tool drs replicate ${WIN_HOSTNAME}.${LCREALM} ${HOSTNAME}.${LCREALM} %s -k yes" % nc, ["was successful"])
217
218     t.cmd_contains("bin/samba-tool drs showrepl ${HOSTNAME}.${LCREALM} -k yes",
219                    ["INBOUND NEIGHBORS",
220                      "${BASEDN}",
221                      "Last attempt .* was successful",
222                      "CN=Configuration,${BASEDN}",
223                      "Last attempt .* was successful",
224                      "CN=Configuration,${BASEDN}",  # cope with either order
225                      "Last attempt .* was successful",
226                      "OUTBOUND NEIGHBORS",
227                      "${BASEDN}",
228                      "Last success",
229                      "CN=Configuration,${BASEDN}",
230                      "Last success",
231                      "CN=Configuration,${BASEDN}",
232                      "Last success"],
233                    ordered=True,
234                    regex=True)
235
236     t.cmd_contains("bin/samba-tool drs showrepl ${WIN_HOSTNAME}.${LCREALM} -k yes",
237                    ["INBOUND NEIGHBORS",
238                      "${BASEDN}",
239                      "Last attempt .* was successful",
240                      "CN=Configuration,${BASEDN}",
241                      "Last attempt .* was successful",
242                      "CN=Configuration,${BASEDN}",
243                      "Last attempt .* was successful",
244                      "OUTBOUND NEIGHBORS",
245                      "${BASEDN}",
246                      "Last success",
247                      "CN=Configuration,${BASEDN}",
248                      "Last success",
249                      "CN=Configuration,${BASEDN}",
250                      "Last success"],
251                    ordered=True,
252                    regex=True)
253
254     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}", set_time=True)
255     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
256
257     retries = 10
258     i = child.expect(["The command completed successfully", "The network path was not found"])
259     while i == 1 and retries > 0:
260         child.expect("C:")
261         time.sleep(2)
262         child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
263         i = child.expect(["The command completed successfully", "The network path was not found"])
264         retries -= 1
265
266     t.run_net_time(child)
267
268     t.info("Checking if showrepl is happy")
269     child.sendline("repadmin /showrepl")
270     child.expect("${BASEDN}")
271     child.expect("was successful")
272     child.expect("CN=Configuration,${BASEDN}")
273     child.expect("was successful")
274     child.expect("CN=Schema,CN=Configuration,${BASEDN}")
275     child.expect("was successful")
276
277     t.info("Checking if new users propagate to windows")
278     t.retry_cmd('bin/samba-tool user add test2 ${PASSWORD2}', ["created successfully"])
279     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['Sharename', 'Remote IPC'])
280     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['Sharename', 'Remote IPC'])
281
282     t.info("Checking if new users on windows propagate to samba")
283     child.sendline("net user test3 ${PASSWORD3} /add")
284     while True:
285         i = child.expect(["The command completed successfully",
286                           "The directory service was unable to allocate a relative identifier"])
287         if i == 0:
288             break
289         time.sleep(2)
290
291     t.retry_cmd("%s -L ${HOSTNAME}.${LCREALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['Sharename', 'IPC'])
292     t.retry_cmd("%s -L ${HOSTNAME}.${LCREALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['Sharename', 'IPC'])
293
294     t.info("Checking propogation of user deletion")
295     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${LCREALM}%${PASSWORD1}')
296     child.sendline("net user test3 /del")
297     child.expect("The command completed successfully")
298
299     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['LOGON_FAILURE'])
300     t.retry_cmd("%s -L ${HOSTNAME}.${LCREALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['LOGON_FAILURE'])
301     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['LOGON_FAILURE'])
302     t.retry_cmd("%s -L ${HOSTNAME}.${LCREALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['LOGON_FAILURE'])
303     t.vm_poweroff("${WIN_VM}")
304
305
306 def run_dcpromo_rodc(t, vm):
307     '''run a RODC dcpromo to join a windows DC to the samba domain'''
308     t.setwinvars(vm)
309     t.info("Joining a w2k8 box to the domain as a RODC")
310     t.vm_poweroff("${WIN_VM}", checkfail=False)
311     t.vm_restore("${WIN_VM}", "${WIN_SNAPSHOT}")
312     child = t.open_telnet("${WIN_HOSTNAME}", "administrator", "${WIN_PASS}", set_ip=True)
313     child.sendline("copy /Y con answers.txt")
314     child.sendline('''
315 [DCInstall]
316 ReplicaOrNewDomain=ReadOnlyReplica
317 ReplicaDomainDNSName=${LCREALM}
318 PasswordReplicationDenied="BUILTIN\Administrators"
319 PasswordReplicationDenied="BUILTIN\Server Operators"
320 PasswordReplicationDenied="BUILTIN\Backup Operators"
321 PasswordReplicationDenied="BUILTIN\Account Operators"
322 PasswordReplicationDenied="${DOMAIN}\Denied RODC Password Replication Group"
323 PasswordReplicationAllowed="${DOMAIN}\Allowed RODC Password Replication Group"
324 DelegatedAdmin="${DOMAIN}\\Administrator"
325 SiteName=Default-First-Site-Name
326 InstallDNS=No
327 ConfirmGc=Yes
328 CreateDNSDelegation=No
329 UserDomain=${LCREALM}
330 UserName=${LCREALM}\\administrator
331 Password=${PASSWORD1}
332 DatabasePath="C:\Windows\NTDS"
333 LogPath="C:\Windows\NTDS"
334 SYSVOLPath="C:\Windows\SYSVOL"
335 SafeModeAdminPassword=${PASSWORD1}
336 RebootOnCompletion=No
337 \1a
338 ''')
339     child.expect("copied.")
340     child.sendline("dcpromo /answer:answers.txt")
341     i = child.expect(["You must restart this computer", "failed", "could not be located in this domain"], timeout=120)
342     if i != 0:
343         child.sendline("echo off")
344         child.sendline("echo START DCPROMO log")
345         child.sendline("more c:\windows\debug\dcpromoui.log")
346         child.sendline("echo END DCPROMO log")
347         child.expect("END DCPROMO")
348         raise Exception("dcpromo failed")
349     child.sendline("shutdown -r -t 0")
350     t.wait_reboot()
351
352
353 def test_dcpromo_rodc(t, vm):
354     '''test the RODC dcpromo worked'''
355     t.info("Checking the w2k8 RODC join is OK")
356     smbclient = t.getvar("smbclient")
357     t.chdir('${PREFIX}')
358     t.port_wait("${WIN_IP}", 139)
359     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}", set_time=True)
360     child.sendline("ipconfig /registerdns")
361     t.retry_cmd('%s -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"])
362     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
363     t.cmd_contains('%s -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"])
364     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
365     child.expect("The command completed successfully")
366
367     t.info("Checking if showrepl is happy")
368     child.sendline("repadmin /showrepl")
369     child.expect("${BASEDN}")
370     child.expect("was successful")
371     child.expect("CN=Configuration,${BASEDN}")
372     child.expect("was successful")
373     child.expect("CN=Configuration,${BASEDN}")
374     child.expect("was successful")
375
376     for nc in ['${BASEDN}', 'CN=Configuration,${BASEDN}', 'CN=Schema,CN=Configuration,${BASEDN}']:
377         t.cmd_contains("bin/samba-tool drs replicate --add-ref ${WIN_HOSTNAME}.${LCREALM} ${HOSTNAME}.${LCREALM} %s" % nc, ["was successful"])
378
379     t.cmd_contains("bin/samba-tool drs showrepl ${HOSTNAME}.${LCREALM}",
380                    ["INBOUND NEIGHBORS",
381                      "OUTBOUND NEIGHBORS",
382                      "${BASEDN}",
383                      "Last attempt.*was successful",
384                      "CN=Configuration,${BASEDN}",
385                      "Last attempt.*was successful",
386                      "CN=Configuration,${BASEDN}",
387                      "Last attempt.*was successful"],
388                    ordered=True,
389                    regex=True)
390
391     t.info("Checking if new users are available on windows")
392     t.run_cmd('bin/samba-tool user add test2 ${PASSWORD2}')
393     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['Sharename', 'Remote IPC'])
394     t.retry_cmd("bin/samba-tool drs replicate ${WIN_HOSTNAME}.${LCREALM} ${HOSTNAME}.${LCREALM} ${BASEDN}", ["was successful"])
395     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['Sharename', 'Remote IPC'])
396     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${LCREALM}%${PASSWORD1}')
397     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['LOGON_FAILURE'])
398     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['LOGON_FAILURE'])
399     t.vm_poweroff("${WIN_VM}")
400
401
402 def prep_join_as_dc(t, vm):
403     '''start VM and shutdown Samba in preperation to join a windows domain as a DC'''
404     t.info("Starting VMs for joining ${WIN_VM} as a second DC using samba-tool domain join DC")
405     t.chdir('${PREFIX}')
406     t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
407     if not t.getvar('NAMESERVER_BACKEND') == 'SAMBA_INTERNAL':
408         t.rndc_cmd('flush')
409     t.run_cmd("rm -rf etc/smb.conf private")
410     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
411     t.get_ipconfig(child)
412
413
414 def join_as_dc(t, vm):
415     '''join a windows domain as a DC'''
416     t.setwinvars(vm)
417     t.info("Joining ${WIN_VM} as a second DC using samba-tool domain join DC")
418     t.port_wait("${WIN_IP}", 389)
419     t.retry_cmd("host -t SRV _ldap._tcp.${WIN_REALM} ${WIN_IP}", ['has SRV record'])
420
421     t.retry_cmd("bin/samba-tool drs showrepl ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator%${WIN_PASS}", ['INBOUND NEIGHBORS'])
422     t.run_cmd('bin/samba-tool domain join ${WIN_REALM} DC -Uadministrator%${WIN_PASS} -d${DEBUGLEVEL} --option=interfaces=${INTERFACE}')
423     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
424
425
426 def test_join_as_dc(t, vm):
427     '''test the join of a windows domain as a DC'''
428     t.info("Checking the DC join is OK")
429     smbclient = t.getvar("smbclient")
430     t.chdir('${PREFIX}')
431     t.retry_cmd('%s -L ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%%${WIN_PASS}' % (smbclient), ["C$", "IPC$", "Sharename"])
432     t.cmd_contains("host -t A ${HOSTNAME}.${WIN_REALM}.", ['has address'])
433     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
434
435     t.info("Forcing kcc runs, and replication")
436     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
437     t.run_cmd('bin/samba-tool drs kcc ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
438
439     t.kinit("administrator@${WIN_REALM}", "${WIN_PASS}")
440     for nc in ['${WIN_BASEDN}', 'CN=Configuration,${WIN_BASEDN}', 'CN=Schema,CN=Configuration,${WIN_BASEDN}']:
441         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME}.${WIN_REALM} ${WIN_HOSTNAME}.${WIN_REALM} %s -k yes" % nc, ["was successful"])
442         t.cmd_contains("bin/samba-tool drs replicate ${WIN_HOSTNAME}.${WIN_REALM} ${HOSTNAME}.${WIN_REALM} %s -k yes" % nc, ["was successful"])
443
444     child.sendline("ipconfig /flushdns")
445     child.expect("Successfully flushed")
446
447     retries = 10
448     i = 1
449     while i == 1 and retries > 0:
450         child.sendline("net use t: \\\\${HOSTNAME}.${WIN_REALM}\\test")
451         i = child.expect(["The command completed successfully", "The network path was not found"])
452         child.expect("C:")
453         if i == 1:
454             time.sleep(2)
455         retries -= 1
456
457     t.info("Checking if showrepl is happy")
458     child.sendline("repadmin /showrepl")
459     child.expect("${WIN_BASEDN}")
460     child.expect("was successful")
461     child.expect("CN=Configuration,${WIN_BASEDN}")
462     child.expect("was successful")
463     child.expect("CN=Configuration,${WIN_BASEDN}")
464     child.expect("was successful")
465
466     t.info("Checking if new users propagate to windows")
467     t.retry_cmd('bin/samba-tool user add test2 ${PASSWORD2}', ["created successfully"])
468     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${WIN_REALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['Sharename', 'Remote IPC'])
469     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${WIN_REALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['Sharename', 'Remote IPC'])
470
471     t.info("Checking if new users on windows propagate to samba")
472     child.sendline("net user test3 ${PASSWORD3} /add")
473     child.expect("The command completed successfully")
474     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['Sharename', 'IPC'])
475     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['Sharename', 'IPC'])
476
477     t.info("Checking propogation of user deletion")
478     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${WIN_REALM}%${WIN_PASS}')
479     child.sendline("net user test3 /del")
480     child.expect("The command completed successfully")
481
482     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${WIN_REALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['LOGON_FAILURE'])
483     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['LOGON_FAILURE'])
484     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${WIN_REALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['LOGON_FAILURE'])
485     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['LOGON_FAILURE'])
486
487     t.run_cmd('bin/samba-tool domain demote -Uadministrator@${WIN_REALM}%${WIN_PASS}')
488
489     t.vm_poweroff("${WIN_VM}")
490
491
492 def join_as_rodc(t, vm):
493     '''join a windows domain as a RODC'''
494     t.setwinvars(vm)
495     t.info("Joining ${WIN_VM} as a RODC using samba-tool domain join DC")
496     t.port_wait("${WIN_IP}", 389)
497     t.retry_cmd("host -t SRV _ldap._tcp.${WIN_REALM} ${WIN_IP}", ['has SRV record'])
498     t.retry_cmd("bin/samba-tool drs showrepl ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator%${WIN_PASS}", ['INBOUND NEIGHBORS'])
499     t.run_cmd('bin/samba-tool domain join ${WIN_REALM} RODC -Uadministrator%${WIN_PASS} -d${DEBUGLEVEL} --option=interfaces=${INTERFACE}')
500     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
501
502
503 def test_join_as_rodc(t, vm):
504     '''test a windows domain RODC join'''
505     t.info("Checking the RODC join is OK")
506     smbclient = t.getvar("smbclient")
507     t.chdir('${PREFIX}')
508     t.retry_cmd('%s -L ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%%${WIN_PASS}' % (smbclient), ["C$", "IPC$", "Sharename"])
509     t.cmd_contains("host -t A ${HOSTNAME}.${WIN_REALM}.", ['has address'])
510     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
511
512     t.info("Forcing kcc runs, and replication")
513     t.run_cmd('bin/samba-tool drs kcc ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
514     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
515
516     t.kinit("administrator@${WIN_REALM}", "${WIN_PASS}")
517     for nc in ['${WIN_BASEDN}', 'CN=Configuration,${WIN_BASEDN}', 'CN=Schema,CN=Configuration,${WIN_BASEDN}']:
518         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME}.${WIN_REALM} ${WIN_HOSTNAME}.${WIN_REALM} %s -k yes" % nc, ["was successful"])
519
520     retries = 10
521     i = 1
522     while i == 1 and retries > 0:
523         child.sendline("net use t: \\\\${HOSTNAME}.${WIN_REALM}\\test")
524         i = child.expect(["The command completed successfully", "The network path was not found"])
525         child.expect("C:")
526         if i == 1:
527             time.sleep(2)
528         retries -= 1
529
530     t.info("Checking if showrepl is happy")
531     child.sendline("repadmin /showrepl")
532     child.expect("DSA invocationID")
533
534     t.cmd_contains("bin/samba-tool drs showrepl ${WIN_HOSTNAME}.${WIN_REALM} -k yes",
535                    ["INBOUND NEIGHBORS",
536                      "OUTBOUND NEIGHBORS",
537                      "${WIN_BASEDN}",
538                      "Last attempt .* was successful",
539                      "CN=Configuration,${WIN_BASEDN}",
540                      "Last attempt .* was successful",
541                      "CN=Configuration,${WIN_BASEDN}",
542                      "Last attempt .* was successful"],
543                    ordered=True,
544                    regex=True)
545
546     t.info("Checking if new users on windows propagate to samba")
547     child.sendline("net user test3 ${PASSWORD3} /add")
548     child.expect("The command completed successfully")
549     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['Sharename', 'IPC'])
550     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['Sharename', 'IPC'])
551
552     # should this work?
553     t.info("Checking if new users propagate to windows")
554     t.cmd_contains('bin/samba-tool user add test2 ${PASSWORD2}', ['No RID Set DN'])
555
556     t.info("Checking propogation of user deletion")
557     child.sendline("net user test3 /del")
558     child.expect("The command completed successfully")
559
560     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['LOGON_FAILURE'])
561     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['LOGON_FAILURE'])
562     t.vm_poweroff("${WIN_VM}")
563
564
565 def test_howto(t):
566     '''test the Samba4 howto'''
567
568     t.setvar("SAMBA_VERSION", "Version 4")
569     t.setvar("smbclient", "bin/smbclient4")
570     t.check_prerequesites()
571
572     # we don't need fsync safety in these tests
573     t.putenv('TDB_NO_FSYNC', '1')
574
575     if not t.skip("configure_bind"):
576         t.configure_bind(kerberos_support=True, include='${PREFIX}/private/named.conf')
577     if not t.skip("stop_bind"):
578         t.stop_bind()
579
580     if not t.skip("stop_vms"):
581         t.stop_vms()
582
583     if not t.skip("build"):
584         build_s4(t)
585
586     if not t.skip("provision"):
587         provision_s4(t)
588
589     set_krb5_conf(t)
590
591     if not t.skip("create-shares"):
592         create_shares(t)
593
594     if not t.skip("starts4"):
595         start_s4(t)
596     if not t.skip("smbclient"):
597         test_smbclient(t)
598
599     if not t.skip("configure_bind2"):
600         t.configure_bind(kerberos_support=True, include='${PREFIX}/private/named.conf')
601     if not t.skip("start_bind"):
602         t.start_bind()
603
604     if not t.skip("dns"):
605         test_dns(t)
606     if not t.skip("kerberos"):
607         test_kerberos(t)
608     if not t.skip("dyndns"):
609         test_dyndns(t)
610
611     if t.have_vm('WINDOWS7') and not t.skip("windows7"):
612         t.start_winvm("WINDOWS7")
613         t.test_remote_smbclient("WINDOWS7")
614         run_winjoin(t, "WINDOWS7")
615         test_winjoin(t, "WINDOWS7")
616         t.vm_poweroff("${WIN_VM}")
617
618     if t.have_vm('WINXP') and not t.skip("winxp"):
619         t.start_winvm("WINXP")
620         run_winjoin(t, "WINXP")
621         test_winjoin(t, "WINXP")
622         t.test_remote_smbclient("WINXP", "administrator", "${PASSWORD1}")
623         t.vm_poweroff("${WIN_VM}")
624
625     if t.have_vm('W2K3C') and not t.skip("win2k3_member"):
626         t.start_winvm("W2K3C")
627         run_winjoin(t, "W2K3C")
628         test_winjoin(t, "W2K3C")
629         t.test_remote_smbclient("W2K3C", "administrator", "${PASSWORD1}")
630         t.vm_poweroff("${WIN_VM}")
631
632     if t.have_vm('W2K8R2C') and not t.skip("dcpromo_rodc"):
633         t.info("Testing w2k8r2 RODC dcpromo")
634         t.start_winvm("W2K8R2C")
635         t.test_remote_smbclient('W2K8R2C')
636         run_dcpromo_rodc(t, "W2K8R2C")
637         test_dcpromo_rodc(t, "W2K8R2C")
638
639     if t.have_vm('W2K8R2B') and not t.skip("dcpromo_w2k8r2"):
640         t.info("Testing w2k8r2 dcpromo")
641         t.start_winvm("W2K8R2B")
642         t.test_remote_smbclient('W2K8R2B')
643         run_dcpromo(t, "W2K8R2B")
644         test_dcpromo(t, "W2K8R2B")
645
646     if t.have_vm('W2K8B') and not t.skip("dcpromo_w2k8"):
647         t.info("Testing w2k8 dcpromo")
648         t.start_winvm("W2K8B")
649         t.test_remote_smbclient('W2K8B')
650         run_dcpromo(t, "W2K8B")
651         test_dcpromo(t, "W2K8B")
652
653     if t.have_vm('W2K3B') and not t.skip("dcpromo_w2k3"):
654         t.info("Testing w2k3 dcpromo")
655         t.info("Changing to 2003 functional level")
656         provision_s4(t, func_level='2003')
657         create_shares(t)
658         start_s4(t)
659         test_smbclient(t)
660         t.restart_bind(kerberos_support=True, include='${PREFIX}/private/named.conf')
661         test_dns(t)
662         test_kerberos(t)
663         test_dyndns(t)
664         t.start_winvm("W2K3B")
665         t.test_remote_smbclient('W2K3B')
666         run_dcpromo(t, "W2K3B")
667         test_dcpromo(t, "W2K3B")
668
669     if t.have_vm('W2K8R2A') and not t.skip("join_w2k8r2"):
670         t.start_winvm("W2K8R2A")
671         prep_join_as_dc(t, "W2K8R2A")
672         t.run_dcpromo_as_first_dc("W2K8R2A", func_level='2008r2')
673         join_as_dc(t, "W2K8R2A")
674         create_shares(t)
675         start_s4(t)
676         test_dyndns(t)
677         test_join_as_dc(t, "W2K8R2A")
678
679     if t.have_vm('W2K8R2A') and not t.skip("join_rodc"):
680         t.start_winvm("W2K8R2A")
681         prep_join_as_dc(t, "W2K8R2A")
682         t.run_dcpromo_as_first_dc("W2K8R2A", func_level='2008r2')
683         join_as_rodc(t, "W2K8R2A")
684         create_shares(t)
685         start_s4(t)
686         test_dyndns(t)
687         test_join_as_rodc(t, "W2K8R2A")
688
689     if t.have_vm('W2K3A') and not t.skip("join_w2k3"):
690         t.start_winvm("W2K3A")
691         prep_join_as_dc(t, "W2K3A")
692         t.run_dcpromo_as_first_dc("W2K3A", func_level='2003')
693         join_as_dc(t, "W2K3A")
694         create_shares(t)
695         start_s4(t)
696         test_dyndns(t)
697         test_join_as_dc(t, "W2K3A")
698
699     t.info("Howto test: All OK")
700
701
702 def test_cleanup(t):
703     '''cleanup after tests'''
704     t.info("Cleaning up ...")
705     t.restore_resolv_conf()
706     if getattr(t, 'bind_child', False):
707         t.bind_child.kill()
708
709
710 if __name__ == '__main__':
711     t = wintest.wintest()
712
713     t.setup("test-s4-howto.py", "source4")
714
715     try:
716         test_howto(t)
717     except:
718         if not t.opts.nocleanup:
719             test_cleanup(t)
720         raise
721
722     if not t.opts.nocleanup:
723         test_cleanup(t)
724     t.info("S4 howto test: All OK")