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