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