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