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