PEP8: fix E302: expected 2 blank lines, found 1
[samba.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
354 def test_dcpromo_rodc(t, vm):
355     '''test the RODC dcpromo worked'''
356     t.info("Checking the w2k8 RODC join is OK")
357     smbclient = t.getvar("smbclient")
358     t.chdir('${PREFIX}')
359     t.port_wait("${WIN_IP}", 139)
360     child = t.open_telnet("${WIN_HOSTNAME}", "${DOMAIN}\\administrator", "${PASSWORD1}", set_time=True)
361     child.sendline("ipconfig /registerdns")
362     t.retry_cmd('%s -L ${WIN_HOSTNAME}.${LCREALM} -Uadministrator@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"])
363     t.cmd_contains("host -t A ${WIN_HOSTNAME}.${LCREALM}.", ['has address'])
364     t.cmd_contains('%s -L ${WIN_HOSTNAME}.${LCREALM} -Utestallowed@${LCREALM}%%${PASSWORD1}' % (smbclient), ["C$", "IPC$", "Sharename"])
365     child.sendline("net use t: \\\\${HOSTNAME}.${LCREALM}\\test")
366     child.expect("The command completed successfully")
367
368     t.info("Checking if showrepl is happy")
369     child.sendline("repadmin /showrepl")
370     child.expect("${BASEDN}")
371     child.expect("was successful")
372     child.expect("CN=Configuration,${BASEDN}")
373     child.expect("was successful")
374     child.expect("CN=Configuration,${BASEDN}")
375     child.expect("was successful")
376
377     for nc in ['${BASEDN}', 'CN=Configuration,${BASEDN}', 'CN=Schema,CN=Configuration,${BASEDN}']:
378         t.cmd_contains("bin/samba-tool drs replicate --add-ref ${WIN_HOSTNAME}.${LCREALM} ${HOSTNAME}.${LCREALM} %s" % nc, ["was successful"])
379
380     t.cmd_contains("bin/samba-tool drs showrepl ${HOSTNAME}.${LCREALM}",
381                    ["INBOUND NEIGHBORS",
382                      "OUTBOUND NEIGHBORS",
383                      "${BASEDN}",
384                      "Last attempt.*was successful",
385                      "CN=Configuration,${BASEDN}",
386                      "Last attempt.*was successful",
387                      "CN=Configuration,${BASEDN}",
388                      "Last attempt.*was successful"],
389                    ordered=True,
390                    regex=True)
391
392     t.info("Checking if new users are available on windows")
393     t.run_cmd('bin/samba-tool user add test2 ${PASSWORD2}')
394     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['Sharename', 'Remote IPC'])
395     t.retry_cmd("bin/samba-tool drs replicate ${WIN_HOSTNAME}.${LCREALM} ${HOSTNAME}.${LCREALM} ${BASEDN}", ["was successful"])
396     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['Sharename', 'Remote IPC'])
397     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${LCREALM}%${PASSWORD1}')
398     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['LOGON_FAILURE'])
399     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${LCREALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['LOGON_FAILURE'])
400     t.vm_poweroff("${WIN_VM}")
401
402
403 def prep_join_as_dc(t, vm):
404     '''start VM and shutdown Samba in preperation to join a windows domain as a DC'''
405     t.info("Starting VMs for joining ${WIN_VM} as a second DC using samba-tool domain join DC")
406     t.chdir('${PREFIX}')
407     t.run_cmd('killall -9 -q samba smbd nmbd winbindd', checkfail=False)
408     if not t.getvar('NAMESERVER_BACKEND') == 'SAMBA_INTERNAL':
409         t.rndc_cmd('flush')
410     t.run_cmd("rm -rf etc/smb.conf private")
411     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
412     t.get_ipconfig(child)
413
414
415 def join_as_dc(t, vm):
416     '''join a windows domain as a DC'''
417     t.setwinvars(vm)
418     t.info("Joining ${WIN_VM} as a second DC using samba-tool domain join DC")
419     t.port_wait("${WIN_IP}", 389)
420     t.retry_cmd("host -t SRV _ldap._tcp.${WIN_REALM} ${WIN_IP}", ['has SRV record'])
421
422     t.retry_cmd("bin/samba-tool drs showrepl ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator%${WIN_PASS}", ['INBOUND NEIGHBORS'])
423     t.run_cmd('bin/samba-tool domain join ${WIN_REALM} DC -Uadministrator%${WIN_PASS} -d${DEBUGLEVEL} --option=interfaces=${INTERFACE}')
424     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
425
426
427 def test_join_as_dc(t, vm):
428     '''test the join of a windows domain as a DC'''
429     t.info("Checking the DC join is OK")
430     smbclient = t.getvar("smbclient")
431     t.chdir('${PREFIX}')
432     t.retry_cmd('%s -L ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%%${WIN_PASS}' % (smbclient), ["C$", "IPC$", "Sharename"])
433     t.cmd_contains("host -t A ${HOSTNAME}.${WIN_REALM}.", ['has address'])
434     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
435
436     t.info("Forcing kcc runs, and replication")
437     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
438     t.run_cmd('bin/samba-tool drs kcc ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
439
440     t.kinit("administrator@${WIN_REALM}", "${WIN_PASS}")
441     for nc in ['${WIN_BASEDN}', 'CN=Configuration,${WIN_BASEDN}', 'CN=Schema,CN=Configuration,${WIN_BASEDN}']:
442         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME}.${WIN_REALM} ${WIN_HOSTNAME}.${WIN_REALM} %s -k yes" % nc, ["was successful"])
443         t.cmd_contains("bin/samba-tool drs replicate ${WIN_HOSTNAME}.${WIN_REALM} ${HOSTNAME}.${WIN_REALM} %s -k yes" % nc, ["was successful"])
444
445     child.sendline("ipconfig /flushdns")
446     child.expect("Successfully flushed")
447
448     retries = 10
449     i = 1
450     while i == 1 and retries > 0:
451         child.sendline("net use t: \\\\${HOSTNAME}.${WIN_REALM}\\test")
452         i = child.expect(["The command completed successfully", "The network path was not found"])
453         child.expect("C:")
454         if i == 1:
455             time.sleep(2)
456         retries -= 1
457
458     t.info("Checking if showrepl is happy")
459     child.sendline("repadmin /showrepl")
460     child.expect("${WIN_BASEDN}")
461     child.expect("was successful")
462     child.expect("CN=Configuration,${WIN_BASEDN}")
463     child.expect("was successful")
464     child.expect("CN=Configuration,${WIN_BASEDN}")
465     child.expect("was successful")
466
467     t.info("Checking if new users propagate to windows")
468     t.retry_cmd('bin/samba-tool user add test2 ${PASSWORD2}', ["created successfully"])
469     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${WIN_REALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['Sharename', 'Remote IPC'])
470     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${WIN_REALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['Sharename', 'Remote IPC'])
471
472     t.info("Checking if new users on windows propagate to samba")
473     child.sendline("net user test3 ${PASSWORD3} /add")
474     child.expect("The command completed successfully")
475     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['Sharename', 'IPC'])
476     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['Sharename', 'IPC'])
477
478     t.info("Checking propogation of user deletion")
479     t.run_cmd('bin/samba-tool user delete test2 -Uadministrator@${WIN_REALM}%${WIN_PASS}')
480     child.sendline("net user test3 /del")
481     child.expect("The command completed successfully")
482
483     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${WIN_REALM} -Utest2%%${PASSWORD2} -k no" % (smbclient), ['LOGON_FAILURE'])
484     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['LOGON_FAILURE'])
485     t.retry_cmd("%s -L ${WIN_HOSTNAME}.${WIN_REALM} -Utest2%%${PASSWORD2} -k yes" % (smbclient), ['LOGON_FAILURE'])
486     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['LOGON_FAILURE'])
487
488     t.run_cmd('bin/samba-tool domain demote -Uadministrator@${WIN_REALM}%${WIN_PASS}')
489
490     t.vm_poweroff("${WIN_VM}")
491
492
493 def join_as_rodc(t, vm):
494     '''join a windows domain as a RODC'''
495     t.setwinvars(vm)
496     t.info("Joining ${WIN_VM} as a RODC using samba-tool domain join DC")
497     t.port_wait("${WIN_IP}", 389)
498     t.retry_cmd("host -t SRV _ldap._tcp.${WIN_REALM} ${WIN_IP}", ['has SRV record'])
499     t.retry_cmd("bin/samba-tool drs showrepl ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator%${WIN_PASS}", ['INBOUND NEIGHBORS'])
500     t.run_cmd('bin/samba-tool domain join ${WIN_REALM} RODC -Uadministrator%${WIN_PASS} -d${DEBUGLEVEL} --option=interfaces=${INTERFACE}')
501     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
502
503
504 def test_join_as_rodc(t, vm):
505     '''test a windows domain RODC join'''
506     t.info("Checking the RODC join is OK")
507     smbclient = t.getvar("smbclient")
508     t.chdir('${PREFIX}')
509     t.retry_cmd('%s -L ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%%${WIN_PASS}' % (smbclient), ["C$", "IPC$", "Sharename"])
510     t.cmd_contains("host -t A ${HOSTNAME}.${WIN_REALM}.", ['has address'])
511     child = t.open_telnet("${WIN_HOSTNAME}", "${WIN_DOMAIN}\\administrator", "${WIN_PASS}", set_time=True)
512
513     t.info("Forcing kcc runs, and replication")
514     t.run_cmd('bin/samba-tool drs kcc ${HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
515     t.run_cmd('bin/samba-tool drs kcc ${WIN_HOSTNAME}.${WIN_REALM} -Uadministrator@${WIN_REALM}%${WIN_PASS}')
516
517     t.kinit("administrator@${WIN_REALM}", "${WIN_PASS}")
518     for nc in ['${WIN_BASEDN}', 'CN=Configuration,${WIN_BASEDN}', 'CN=Schema,CN=Configuration,${WIN_BASEDN}']:
519         t.cmd_contains("bin/samba-tool drs replicate ${HOSTNAME}.${WIN_REALM} ${WIN_HOSTNAME}.${WIN_REALM} %s -k yes" % nc, ["was successful"])
520
521     retries = 10
522     i = 1
523     while i == 1 and retries > 0:
524         child.sendline("net use t: \\\\${HOSTNAME}.${WIN_REALM}\\test")
525         i = child.expect(["The command completed successfully", "The network path was not found"])
526         child.expect("C:")
527         if i == 1:
528             time.sleep(2)
529         retries -= 1
530
531     t.info("Checking if showrepl is happy")
532     child.sendline("repadmin /showrepl")
533     child.expect("DSA invocationID")
534
535     t.cmd_contains("bin/samba-tool drs showrepl ${WIN_HOSTNAME}.${WIN_REALM} -k yes",
536                    ["INBOUND NEIGHBORS",
537                      "OUTBOUND NEIGHBORS",
538                      "${WIN_BASEDN}",
539                      "Last attempt .* was successful",
540                      "CN=Configuration,${WIN_BASEDN}",
541                      "Last attempt .* was successful",
542                      "CN=Configuration,${WIN_BASEDN}",
543                      "Last attempt .* was successful"],
544                    ordered=True,
545                    regex=True)
546
547     t.info("Checking if new users on windows propagate to samba")
548     child.sendline("net user test3 ${PASSWORD3} /add")
549     child.expect("The command completed successfully")
550     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['Sharename', 'IPC'])
551     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['Sharename', 'IPC'])
552
553     # should this work?
554     t.info("Checking if new users propagate to windows")
555     t.cmd_contains('bin/samba-tool user add test2 ${PASSWORD2}', ['No RID Set DN'])
556
557     t.info("Checking propogation of user deletion")
558     child.sendline("net user test3 /del")
559     child.expect("The command completed successfully")
560
561     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k no" % (smbclient), ['LOGON_FAILURE'])
562     t.retry_cmd("%s -L ${HOSTNAME}.${WIN_REALM} -Utest3%%${PASSWORD3} -k yes" % (smbclient), ['LOGON_FAILURE'])
563     t.vm_poweroff("${WIN_VM}")
564
565
566 def test_howto(t):
567     '''test the Samba4 howto'''
568
569     t.setvar("SAMBA_VERSION", "Version 4")
570     t.setvar("smbclient", "bin/smbclient4")
571     t.check_prerequesites()
572
573     # we don't need fsync safety in these tests
574     t.putenv('TDB_NO_FSYNC', '1')
575
576     if not t.skip("configure_bind"):
577         t.configure_bind(kerberos_support=True, include='${PREFIX}/private/named.conf')
578     if not t.skip("stop_bind"):
579         t.stop_bind()
580
581     if not t.skip("stop_vms"):
582         t.stop_vms()
583
584     if not t.skip("build"):
585         build_s4(t)
586
587     if not t.skip("provision"):
588         provision_s4(t)
589
590     set_krb5_conf(t)
591
592     if not t.skip("create-shares"):
593         create_shares(t)
594
595     if not t.skip("starts4"):
596         start_s4(t)
597     if not t.skip("smbclient"):
598         test_smbclient(t)
599
600     if not t.skip("configure_bind2"):
601         t.configure_bind(kerberos_support=True, include='${PREFIX}/private/named.conf')
602     if not t.skip("start_bind"):
603         t.start_bind()
604
605     if not t.skip("dns"):
606         test_dns(t)
607     if not t.skip("kerberos"):
608         test_kerberos(t)
609     if not t.skip("dyndns"):
610         test_dyndns(t)
611
612     if t.have_vm('WINDOWS7') and not t.skip("windows7"):
613         t.start_winvm("WINDOWS7")
614         t.test_remote_smbclient("WINDOWS7")
615         run_winjoin(t, "WINDOWS7")
616         test_winjoin(t, "WINDOWS7")
617         t.vm_poweroff("${WIN_VM}")
618
619     if t.have_vm('WINXP') and not t.skip("winxp"):
620         t.start_winvm("WINXP")
621         run_winjoin(t, "WINXP")
622         test_winjoin(t, "WINXP")
623         t.test_remote_smbclient("WINXP", "administrator", "${PASSWORD1}")
624         t.vm_poweroff("${WIN_VM}")
625
626     if t.have_vm('W2K3C') and not t.skip("win2k3_member"):
627         t.start_winvm("W2K3C")
628         run_winjoin(t, "W2K3C")
629         test_winjoin(t, "W2K3C")
630         t.test_remote_smbclient("W2K3C", "administrator", "${PASSWORD1}")
631         t.vm_poweroff("${WIN_VM}")
632
633     if t.have_vm('W2K8R2C') and not t.skip("dcpromo_rodc"):
634         t.info("Testing w2k8r2 RODC dcpromo")
635         t.start_winvm("W2K8R2C")
636         t.test_remote_smbclient('W2K8R2C')
637         run_dcpromo_rodc(t, "W2K8R2C")
638         test_dcpromo_rodc(t, "W2K8R2C")
639
640     if t.have_vm('W2K8R2B') and not t.skip("dcpromo_w2k8r2"):
641         t.info("Testing w2k8r2 dcpromo")
642         t.start_winvm("W2K8R2B")
643         t.test_remote_smbclient('W2K8R2B')
644         run_dcpromo(t, "W2K8R2B")
645         test_dcpromo(t, "W2K8R2B")
646
647     if t.have_vm('W2K8B') and not t.skip("dcpromo_w2k8"):
648         t.info("Testing w2k8 dcpromo")
649         t.start_winvm("W2K8B")
650         t.test_remote_smbclient('W2K8B')
651         run_dcpromo(t, "W2K8B")
652         test_dcpromo(t, "W2K8B")
653
654     if t.have_vm('W2K3B') and not t.skip("dcpromo_w2k3"):
655         t.info("Testing w2k3 dcpromo")
656         t.info("Changing to 2003 functional level")
657         provision_s4(t, func_level='2003')
658         create_shares(t)
659         start_s4(t)
660         test_smbclient(t)
661         t.restart_bind(kerberos_support=True, include='${PREFIX}/private/named.conf')
662         test_dns(t)
663         test_kerberos(t)
664         test_dyndns(t)
665         t.start_winvm("W2K3B")
666         t.test_remote_smbclient('W2K3B')
667         run_dcpromo(t, "W2K3B")
668         test_dcpromo(t, "W2K3B")
669
670     if t.have_vm('W2K8R2A') and not t.skip("join_w2k8r2"):
671         t.start_winvm("W2K8R2A")
672         prep_join_as_dc(t, "W2K8R2A")
673         t.run_dcpromo_as_first_dc("W2K8R2A", func_level='2008r2')
674         join_as_dc(t, "W2K8R2A")
675         create_shares(t)
676         start_s4(t)
677         test_dyndns(t)
678         test_join_as_dc(t, "W2K8R2A")
679
680     if t.have_vm('W2K8R2A') and not t.skip("join_rodc"):
681         t.start_winvm("W2K8R2A")
682         prep_join_as_dc(t, "W2K8R2A")
683         t.run_dcpromo_as_first_dc("W2K8R2A", func_level='2008r2')
684         join_as_rodc(t, "W2K8R2A")
685         create_shares(t)
686         start_s4(t)
687         test_dyndns(t)
688         test_join_as_rodc(t, "W2K8R2A")
689
690     if t.have_vm('W2K3A') and not t.skip("join_w2k3"):
691         t.start_winvm("W2K3A")
692         prep_join_as_dc(t, "W2K3A")
693         t.run_dcpromo_as_first_dc("W2K3A", func_level='2003')
694         join_as_dc(t, "W2K3A")
695         create_shares(t)
696         start_s4(t)
697         test_dyndns(t)
698         test_join_as_dc(t, "W2K3A")
699
700     t.info("Howto test: All OK")
701
702
703 def test_cleanup(t):
704     '''cleanup after tests'''
705     t.info("Cleaning up ...")
706     t.restore_resolv_conf()
707     if getattr(t, 'bind_child', False):
708         t.bind_child.kill()
709
710
711 if __name__ == '__main__':
712     t = wintest.wintest()
713
714     t.setup("test-s4-howto.py", "source4")
715
716     try:
717         test_howto(t)
718     except:
719         if not t.opts.nocleanup:
720             test_cleanup(t)
721         raise
722
723     if not t.opts.nocleanup:
724         test_cleanup(t)
725     t.info("S4 howto test: All OK")