selftest: Avoid system krb5.conf in testenv provisioning
[sfrench/samba-autobuild/.git] / selftest / target / Samba4.pm
1 #!/usr/bin/perl
2 # Bootstrap Samba and run a number of tests against it.
3 # Copyright (C) 2005-2007 Jelmer Vernooij <jelmer@samba.org>
4 # Published under the GNU GPL, v3 or later.
5
6 package Samba4;
7
8 use strict;
9 use Cwd qw(abs_path);
10 use FindBin qw($RealBin);
11 use POSIX;
12 use SocketWrapper;
13 use target::Samba;
14 use target::Samba3;
15
16 sub new($$$$$) {
17         my ($classname, $bindir, $ldap, $srcdir, $server_maxtime) = @_;
18
19         my $self = {
20                 vars => {},
21                 ldap => $ldap,
22                 bindir => $bindir,
23                 srcdir => $srcdir,
24                 server_maxtime => $server_maxtime,
25                 target3 => new Samba3($bindir, $srcdir, $server_maxtime)
26         };
27         bless $self;
28         return $self;
29 }
30
31 sub scriptdir_path($$) {
32         my ($self, $path) = @_;
33         return "$self->{srcdir}/source4/scripting/$path";
34 }
35
36 sub openldap_start($$$) {
37 }
38
39 sub slapd_start($$)
40 {
41         my $count = 0;
42         my ($self, $env_vars, $STDIN_READER) = @_;
43         my $ldbsearch = Samba::bindir_path($self, "ldbsearch");
44
45         my $uri = $env_vars->{LDAP_URI};
46
47         if (system("$ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") == 0) {
48             print "A SLAPD is still listening to $uri before we started the LDAP backend.  Aborting!";
49             return 1;
50         }
51         # running slapd in the background means it stays in the same process group, so it can be
52         # killed by timelimit
53         my $pid = fork();
54         if ($pid == 0) {
55                 open STDOUT, ">$env_vars->{LDAPDIR}/logs";
56                 open STDERR, '>&STDOUT';
57                 close($env_vars->{STDIN_PIPE});
58                 open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
59
60                 if ($self->{ldap} eq "fedora-ds") {
61                         exec("$ENV{FEDORA_DS_ROOT}/sbin/ns-slapd", "-D", $env_vars->{FEDORA_DS_DIR}, "-d0", "-i", $env_vars->{FEDORA_DS_PIDFILE});
62                 } elsif ($self->{ldap} eq "openldap") {
63                         exec($ENV{OPENLDAP_SLAPD}, "-dnone", "-F", $env_vars->{SLAPD_CONF_D}, "-h", $uri);
64                 }
65                 die("Unable to start slapd: $!");
66         }
67         $env_vars->{SLAPD_PID} = $pid;
68         sleep(1);
69         while (system("$ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") != 0) {
70                 $count++;
71                 if ($count > 40) {
72                         $self->slapd_stop($env_vars);
73                         return 0;
74                 }
75                 sleep(1);
76         }
77         return 1;
78 }
79
80 sub slapd_stop($$)
81 {
82         my ($self, $envvars) = @_;
83         kill 9, $envvars->{SLAPD_PID};
84         return 1;
85 }
86
87 sub check_or_start($$$)
88 {
89         my ($self, $env_vars, $process_model) = @_;
90         my $STDIN_READER;
91
92         return 0 if $self->check_env($env_vars);
93
94         # use a pipe for stdin in the child processes. This allows
95         # those processes to monitor the pipe for EOF to ensure they
96         # exit when the test script exits
97         pipe($STDIN_READER, $env_vars->{STDIN_PIPE});
98
99         # Start slapd before samba, but with the fifo on stdin
100         if (defined($self->{ldap})) {
101                 unless($self->slapd_start($env_vars, $STDIN_READER)) {
102                         warn("couldn't start slapd (main run)");
103                         return undef;
104                 }
105         }
106
107         print "STARTING SAMBA...";
108         my $pid = fork();
109         if ($pid == 0) {
110                 # we want out from samba to go to the log file, but also
111                 # to the users terminal when running 'make test' on the command
112                 # line. This puts it on stderr on the terminal
113                 open STDOUT, "| tee $env_vars->{SAMBA_TEST_LOG} 1>&2";
114                 open STDERR, '>&STDOUT';
115
116                 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
117
118                 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
119                 $ENV{SELFTEST_WINBINDD_SOCKET_DIR} = $env_vars->{SELFTEST_WINBINDD_SOCKET_DIR};
120                 $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
121
122                 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
123                 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
124                 $ENV{NSS_WRAPPER_HOSTS} = $env_vars->{NSS_WRAPPER_HOSTS};
125                 $ENV{NSS_WRAPPER_MODULE_SO_PATH} = $env_vars->{NSS_WRAPPER_MODULE_SO_PATH};
126                 $ENV{NSS_WRAPPER_MODULE_FN_PREFIX} = $env_vars->{NSS_WRAPPER_MODULE_FN_PREFIX};
127
128                 if (defined($env_vars->{RESOLV_WRAPPER_CONF})) {
129                         $ENV{RESOLV_WRAPPER_CONF} = $env_vars->{RESOLV_WRAPPER_CONF};
130                 } else {
131                         $ENV{RESOLV_WRAPPER_HOSTS} = $env_vars->{RESOLV_WRAPPER_HOSTS};
132                 }
133
134                 $ENV{UID_WRAPPER} = "1";
135
136                 $ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "samba");
137                 my @preargs = ();
138                 my @optargs = ();
139                 if (defined($ENV{SAMBA_OPTIONS})) {
140                         @optargs = split(/ /, $ENV{SAMBA_OPTIONS});
141                 }
142                 if(defined($ENV{SAMBA_VALGRIND})) {
143                         @preargs = split(/ /,$ENV{SAMBA_VALGRIND});
144                 }
145
146                 close($env_vars->{STDIN_PIPE});
147                 open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
148
149                 exec(@preargs, Samba::bindir_path($self, "samba"), "-M", $process_model, "-i", "--maximum-runtime=$self->{server_maxtime}", $env_vars->{CONFIGURATION}, @optargs) or die("Unable to start samba: $!");
150         }
151         $env_vars->{SAMBA_PID} = $pid;
152         print "DONE\n";
153
154         close($STDIN_READER);
155
156         return $pid;
157 }
158
159 sub wait_for_start($$)
160 {
161         my ($self, $testenv_vars) = @_;
162         my $ret;
163         # give time for nbt server to register its names
164         print "delaying for nbt name registration\n";
165         sleep 2;
166
167         # This will return quickly when things are up, but be slow if we
168         # need to wait for (eg) SSL init
169         my $nmblookup =  Samba::bindir_path($self, "nmblookup4");
170         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
171         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
172         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
173         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
174         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
175         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
176         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
177         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
178         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
179         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
180         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
181         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
182
183         # Ensure we have the first RID Set before we start tests.  This makes the tests more reliable.
184         if ($testenv_vars->{SERVER_ROLE} eq "domain controller" and not ($testenv_vars->{NETBIOSNAME} eq "RODC")) {
185             # Add hosts file for name lookups
186             $ENV{NSS_WRAPPER_HOSTS} = $testenv_vars->{NSS_WRAPPER_HOSTS};
187                 if (defined($testenv_vars->{RESOLV_WRAPPER_CONF})) {
188                         $ENV{RESOLV_WRAPPER_CONF} = $testenv_vars->{RESOLV_WRAPPER_CONF};
189                 } else {
190                         $ENV{RESOLV_WRAPPER_HOSTS} = $testenv_vars->{RESOLV_WRAPPER_HOSTS};
191                 }
192
193             print "waiting for working LDAP and a RID Set to be allocated\n";
194             my $ldbsearch = Samba::bindir_path($self, "ldbsearch");
195             my $count = 0;
196             my $base_dn = "DC=".join(",DC=", split(/\./, $testenv_vars->{REALM}));
197             my $rid_set_dn = "cn=RID Set,cn=$testenv_vars->{NETBIOSNAME},ou=domain controllers,$base_dn";
198             sleep(1);
199             while (system("$ldbsearch -H ldap://$testenv_vars->{SERVER} -U$testenv_vars->{USERNAME}%$testenv_vars->{PASSWORD} -s base -b \"$rid_set_dn\" rIDAllocationPool > /dev/null") != 0) {
200                 $count++;
201                 if ($count > 40) {
202                     $ret = 1;
203                     last;
204                 }
205                 sleep(1);
206             }
207         }
208         print $self->getlog_env($testenv_vars);
209
210         return $ret
211 }
212
213 sub write_ldb_file($$$)
214 {
215         my ($self, $file, $ldif) = @_;
216
217         my $ldbadd =  Samba::bindir_path($self, "ldbadd");
218         open(LDIF, "|$ldbadd -H $file >/dev/null");
219         print LDIF $ldif;
220         return(close(LDIF));
221 }
222
223 sub add_wins_config($$)
224 {
225         my ($self, $privatedir) = @_;
226
227         return $self->write_ldb_file("$privatedir/wins_config.ldb", "
228 dn: name=TORTURE_11,CN=PARTNERS
229 objectClass: wreplPartner
230 name: TORTURE_11
231 address: 127.0.0.11
232 pullInterval: 0
233 pushChangeCount: 0
234 type: 0x3
235 ");
236 }
237
238 sub mk_fedora_ds($$)
239 {
240         my ($self, $ctx) = @_;
241
242         #Make the subdirectory be as fedora DS would expect
243         my $fedora_ds_dir = "$ctx->{ldapdir}/slapd-$ctx->{ldap_instance}";
244
245         my $pidfile = "$fedora_ds_dir/logs/slapd-$ctx->{ldap_instance}.pid";
246
247         return ($fedora_ds_dir, $pidfile);
248 }
249
250 sub mk_openldap($$)
251 {
252         my ($self, $ctx) = @_;
253
254         my $slapd_conf_d = "$ctx->{ldapdir}/slapd.d";
255         my $pidfile = "$ctx->{ldapdir}/slapd.pid";
256
257         return ($slapd_conf_d, $pidfile);
258 }
259
260 sub mk_keyblobs($$)
261 {
262         my ($self, $tlsdir) = @_;
263
264         #TLS and PKINIT crypto blobs
265         my $dhfile = "$tlsdir/dhparms.pem";
266         my $cafile = "$tlsdir/ca.pem";
267         my $certfile = "$tlsdir/cert.pem";
268         my $reqkdc = "$tlsdir/req-kdc.der";
269         my $kdccertfile = "$tlsdir/kdc.pem";
270         my $keyfile = "$tlsdir/key.pem";
271         my $adminkeyfile = "$tlsdir/adminkey.pem";
272         my $reqadmin = "$tlsdir/req-admin.der";
273         my $admincertfile = "$tlsdir/admincert.pem";
274         my $admincertupnfile = "$tlsdir/admincertupn.pem";
275
276         mkdir($tlsdir, 0700);
277         my $oldumask = umask;
278         umask 0077;
279
280         #This is specified here to avoid draining entropy on every run
281         open(DHFILE, ">$dhfile");
282         print DHFILE <<EOF;
283 -----BEGIN DH PARAMETERS-----
284 MGYCYQC/eWD2xkb7uELmqLi+ygPMKyVcpHUo2yCluwnbPutEueuxrG/Cys8j8wLO
285 svCN/jYNyR2NszOmg7ZWcOC/4z/4pWDVPUZr8qrkhj5MRKJc52MncfaDglvEdJrv
286 YX70obsCAQI=
287 -----END DH PARAMETERS-----
288 EOF
289         close(DHFILE);
290
291         #Likewise, we pregenerate the key material.  This allows the
292         #other certificates to be pre-generated
293         open(KEYFILE, ">$keyfile");
294         print KEYFILE <<EOF;
295 -----BEGIN RSA PRIVATE KEY-----
296 MIICXQIBAAKBgQDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpc
297 ol3+S9/6I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H
298 6H+pPqVIRLOmrWImai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQAB
299 AoGAAqDLzFRR/BF1kpsiUfL4WFvTarCe9duhwj7ORc6fs785qAXuwUYAJ0Uvzmy6
300 HqoGv3t3RfmeHDmjcpPHsbOKnsOQn2MgmthidQlPBMWtQMff5zdoYNUFiPS0XQBq
301 szNW4PRjaA9KkLQVTwnzdXGkBSkn/nGxkaVu7OR3vJOBoo0CQQDO4upypesnbe6p
302 9/xqfZ2uim8IwV1fLlFClV7WlCaER8tsQF4lEi0XSzRdXGUD/dilpY88Nb+xok/X
303 8Z8OvgAXAkEA+pcLsx1gN7kxnARxv54jdzQjC31uesJgMKQXjJ0h75aUZwTNHmZQ
304 vPxi6u62YiObrN5oivkixwFNncT9MxTxVQJBAMaWUm2SjlLe10UX4Zdm1MEB6OsC
305 kVoX37CGKO7YbtBzCfTzJGt5Mwc1DSLA2cYnGJqIfSFShptALlwedot0HikCQAJu
306 jNKEKnbf+TdGY8Q0SKvTebOW2Aeg80YFkaTvsXCdyXrmdQcifw4WdO9KucJiDhSz
307 Y9hVapz7ykEJtFtWjLECQQDIlfc63I5ZpXfg4/nN4IJXUW6AmPVOYIA5215itgki
308 cSlMYli1H9MEXH0pQMGv5Qyd0OYIx2DDg96mZ+aFvqSG
309 -----END RSA PRIVATE KEY-----
310 EOF
311         close(KEYFILE);
312
313         open(ADMINKEYFILE, ">$adminkeyfile");
314
315         print ADMINKEYFILE <<EOF;
316 -----BEGIN RSA PRIVATE KEY-----
317 MIICXQIBAAKBgQD0+OL7TQBj0RejbIH1+g5GeRaWaM9xF43uE5y7jUHEsi5owhZF
318 5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMFxB6esnXhl0Jpip1JkUMM
319 XLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xdl3JRlwIDAQAB
320 AoGAP8mjCP628Ebc2eACQzOWjgEvwYCPK4qPmYOf1zJkArzG2t5XAGJ5WGrENRuB
321 cm3XFh1lpmaADl982UdW3gul4gXUy6w4XjKK4vVfhyHj0kZ/LgaXUK9BAGhroJ2L
322 osIOUsaC6jdx9EwSRctwdlF3wWJ8NK0g28AkvIk+FlolW4ECQQD7w5ouCDnf58CN
323 u4nARx4xv5XJXekBvOomkCQAmuOsdOb6b9wn3mm2E3au9fueITjb3soMR31AF6O4
324 eAY126rXAkEA+RgHzybzZEP8jCuznMqoN2fq/Vrs6+W3M8/G9mzGEMgLLpaf2Jiz
325 I9tLZ0+OFk9tkRaoCHPfUOCrVWJZ7Y53QQJBAMhoA6rw0WDyUcyApD5yXg6rusf4
326 ASpo/tqDkqUIpoL464Qe1tjFqtBM3gSXuhs9xsz+o0bzATirmJ+WqxrkKTECQHt2
327 OLCpKqwAspU7N+w32kaUADoRLisCEdrhWklbwpQgwsIVsCaoEOpt0CLloJRYTANE
328 yoZeAErTALjyZYZEPcECQQDlUi0N8DFxQ/lOwWyR3Hailft+mPqoPCa8QHlQZnlG
329 +cfgNl57YHMTZFwgUVFRdJNpjH/WdZ5QxDcIVli0q+Ko
330 -----END RSA PRIVATE KEY-----
331 EOF
332
333         #generated with
334         # hxtool issue-certificate --self-signed --issue-ca \
335         # --ca-private-key="FILE:$KEYFILE" \
336         # --subject="CN=CA,DC=samba,DC=example,DC=com" \
337         # --certificate="FILE:$CAFILE" --lifetime="25 years"
338
339         open(CAFILE, ">$cafile");
340         print CAFILE <<EOF;
341 -----BEGIN CERTIFICATE-----
342 MIICcTCCAdqgAwIBAgIUaBPmjnPVqyFqR5foICmLmikJTzgwCwYJKoZIhvcNAQEFMFIxEzAR
343 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
344 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTIyMzEyWhgPMjAzMzAyMjQx
345 MjIzMTJaMFIxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
346 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMIGfMA0GCSqGSIb3DQEBAQUA
347 A4GNADCBiQKBgQDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpcol3+S9/6
348 I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H6H+pPqVIRLOmrWIm
349 ai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
350 AaYwHQYDVR0OBBYEFMLZufegDKLZs0VOyFXYK1L6M8oyMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
351 KoZIhvcNAQEFBQADgYEAAZJbCAAkaqgFJ0xgNovn8Ydd0KswQPjicwiODPgw9ZPoD2HiOUVO
352 yYDRg/dhFF9y656OpcHk4N7qZ2sl3RlHkzDu+dseETW+CnKvQIoXNyeARRJSsSlwrwcoD4JR
353 HTLk2sGigsWwrJ2N99sG/cqSJLJ1MFwLrs6koweBnYU0f/g=
354 -----END CERTIFICATE-----
355 EOF
356
357         #generated with GNUTLS internally in Samba.
358
359         open(CERTFILE, ">$certfile");
360         print CERTFILE <<EOF;
361 -----BEGIN CERTIFICATE-----
362 MIICYTCCAcygAwIBAgIE5M7SRDALBgkqhkiG9w0BAQUwZTEdMBsGA1UEChMUU2Ft
363 YmEgQWRtaW5pc3RyYXRpb24xNDAyBgNVBAsTK1NhbWJhIC0gdGVtcG9yYXJ5IGF1
364 dG9nZW5lcmF0ZWQgY2VydGlmaWNhdGUxDjAMBgNVBAMTBVNhbWJhMB4XDTA2MDgw
365 NDA0MzY1MloXDTA4MDcwNDA0MzY1MlowZTEdMBsGA1UEChMUU2FtYmEgQWRtaW5p
366 c3RyYXRpb24xNDAyBgNVBAsTK1NhbWJhIC0gdGVtcG9yYXJ5IGF1dG9nZW5lcmF0
367 ZWQgY2VydGlmaWNhdGUxDjAMBgNVBAMTBVNhbWJhMIGcMAsGCSqGSIb3DQEBAQOB
368 jAAwgYgCgYDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpcol3+
369 S9/6I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H6H+p
370 PqVIRLOmrWImai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQABoyUw
371 IzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGCSqGSIb3DQEB
372 BQOBgQAmkN6XxvDnoMkGcWLCTwzxGfNNSVcYr7TtL2aJh285Xw9zaxcm/SAZBFyG
373 LYOChvh6hPU7joMdDwGfbiLrBnMag+BtGlmPLWwp/Kt1wNmrRhduyTQFhN3PP6fz
374 nBr9vVny2FewB2gHmelaPS//tXdxivSXKz3NFqqXLDJjq7P8wA==
375 -----END CERTIFICATE-----
376 EOF
377         close(CERTFILE);
378
379         #KDC certificate
380         # hxtool request-create \
381         # --subject="CN=krbtgt,CN=users,DC=samba,DC=example,DC=com" \
382         # --key="FILE:$KEYFILE" $KDCREQ
383
384         # hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
385         # --type="pkinit-kdc" \
386         # --pk-init-principal="krbtgt/SAMBA.EXAMPLE.COM@SAMBA.EXAMPLE.COM" \
387         # --req="PKCS10:$KDCREQ" --certificate="FILE:$KDCCERTFILE" \
388         # --lifetime="25 years"
389
390         open(KDCCERTFILE, ">$kdccertfile");
391         print KDCCERTFILE <<EOF;
392 -----BEGIN CERTIFICATE-----
393 MIIDDDCCAnWgAwIBAgIUI2Tzj+JnMzMcdeabcNo30rovzFAwCwYJKoZIhvcNAQEFMFIxEzAR
394 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
395 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTMxOTIzWhgPMjAzMzAyMjQx
396 MzE5MjNaMGYxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
397 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMQ8wDQYDVQQDDAZrcmJ0
398 Z3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMqDqkDAIdQwDUN8cOZaFl934XQL70nF
399 yq+nD2KL0SfcTW5+WlyiXf5L3/oj+5pOYkdmt74MXd1PNv9Q5mjRl6bw34jPOSCgaQVp+Ne5
400 PcEvlQ9jb8fof6k+pUhEs6atYiZqLfn1jKgqEXKjftjoc95TxBxn67atL2B5qkhZ966jAgMB
401 AAGjgcgwgcUwDgYDVR0PAQH/BAQDAgWgMBIGA1UdJQQLMAkGBysGAQUCAwUwVAYDVR0RBE0w
402 S6BJBgYrBgEFAgKgPzA9oBMbEVNBTUJBLkVYQU1QTEUuQ09NoSYwJKADAgEBoR0wGxsGa3Ji
403 dGd0GxFTQU1CQS5FWEFNUExFLkNPTTAfBgNVHSMEGDAWgBTC2bn3oAyi2bNFTshV2CtS+jPK
404 MjAdBgNVHQ4EFgQUwtm596AMotmzRU7IVdgrUvozyjIwCQYDVR0TBAIwADANBgkqhkiG9w0B
405 AQUFAAOBgQBmrVD5MCmZjfHp1nEnHqTIh8r7lSmVtDx4s9MMjxm9oNrzbKXynvdhwQYFVarc
406 ge4yRRDXtSebErOl71zVJI9CVeQQpwcH+tA85oGA7oeFtO/S7ls581RUU6tGgyxV4veD+lJv
407 KPH5LevUtgD+q9H4LU4Sq5N3iFwBaeryB0g2wg==
408 -----END CERTIFICATE-----
409 EOF
410
411         # hxtool request-create \
412         # --subject="CN=Administrator,CN=users,DC=samba,DC=example,DC=com" \
413         # --key="FILE:$ADMINKEYFILE" $ADMINREQFILE
414
415         # hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
416         # --type="pkinit-client" \
417         # --pk-init-principal="administrator@SAMBA.EXAMPLE.COM" \
418         # --req="PKCS10:$ADMINREQFILE" --certificate="FILE:$ADMINCERTFILE" \
419         # --lifetime="25 years"
420         
421         open(ADMINCERTFILE, ">$admincertfile");
422         print ADMINCERTFILE <<EOF;
423 -----BEGIN CERTIFICATE-----
424 MIIDHTCCAoagAwIBAgIUUggzW4lLRkMKe1DAR2NKatkMDYwwCwYJKoZIhvcNAQELMFIxEzAR
425 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
426 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDkwNzI3MDMzMjE1WhgPMjAzNDA3MjIw
427 MzMyMTVaMG0xEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
428 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMRYwFAYDVQQDDA1BZG1p
429 bmlzdHJhdG9yMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0+OL7TQBj0RejbIH1+g5G
430 eRaWaM9xF43uE5y7jUHEsi5owhZF5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMF
431 xB6esnXhl0Jpip1JkUMMXLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xd
432 l3JRlwIDAQABo4HSMIHPMA4GA1UdDwEB/wQEAwIFoDAoBgNVHSUEITAfBgcrBgEFAgMEBggr
433 BgEFBQcDAgYKKwYBBAGCNxQCAjBIBgNVHREEQTA/oD0GBisGAQUCAqAzMDGgExsRU0FNQkEu
434 RVhBTVBMRS5DT02hGjAYoAMCAQGhETAPGw1BZG1pbmlzdHJhdG9yMB8GA1UdIwQYMBaAFMLZ
435 ufegDKLZs0VOyFXYK1L6M8oyMB0GA1UdDgQWBBQg81bLyfCA88C2B/BDjXlGuaFaxjAJBgNV
436 HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4GBAEf/OSHUDJaGdtWGNuJeqcVYVMwrfBAc0OSwVhz1
437 7/xqKHWo8wIMPkYRtaRHKLNDsF8GkhQPCpVsa6mX/Nt7YQnNvwd+1SBP5E8GvwWw9ZzLJvma
438 nk2n89emuayLpVtp00PymrDLRBcNaRjFReQU8f0o509kiVPHduAp3jOiy13l
439 -----END CERTIFICATE-----
440 EOF
441         close(ADMINCERTFILE);
442
443         # hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
444         # --type="pkinit-client" \
445         # --ms-upn="administrator@samba.example.com" \
446         # --req="PKCS10:$ADMINREQFILE" --certificate="FILE:$ADMINCERTUPNFILE" \
447         # --lifetime="25 years"
448         
449         open(ADMINCERTUPNFILE, ">$admincertupnfile");
450         print ADMINCERTUPNFILE <<EOF;
451 -----BEGIN CERTIFICATE-----
452 MIIDDzCCAnigAwIBAgIUUp3CJMuNaEaAdPKp3QdNIwG7a4wwCwYJKoZIhvcNAQELMFIxEzAR
453 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
454 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDkwNzI3MDMzMzA1WhgPMjAzNDA3MjIw
455 MzMzMDVaMG0xEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
456 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMRYwFAYDVQQDDA1BZG1p
457 bmlzdHJhdG9yMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0+OL7TQBj0RejbIH1+g5G
458 eRaWaM9xF43uE5y7jUHEsi5owhZF5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMF
459 xB6esnXhl0Jpip1JkUMMXLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xd
460 l3JRlwIDAQABo4HEMIHBMA4GA1UdDwEB/wQEAwIFoDAoBgNVHSUEITAfBgcrBgEFAgMEBggr
461 BgEFBQcDAgYKKwYBBAGCNxQCAjA6BgNVHREEMzAxoC8GCisGAQQBgjcUAgOgIQwfYWRtaW5p
462 c3RyYXRvckBzYW1iYS5leGFtcGxlLmNvbTAfBgNVHSMEGDAWgBTC2bn3oAyi2bNFTshV2CtS
463 +jPKMjAdBgNVHQ4EFgQUIPNWy8nwgPPAtgfwQ415RrmhWsYwCQYDVR0TBAIwADANBgkqhkiG
464 9w0BAQsFAAOBgQBk42+egeUB3Ji2PC55fbt3FNKxvmm2xUUFkV9POK/YR9rajKOwk5jtYSeS
465 Zd7J9s//rNFNa7waklFkDaY56+QWTFtdvxfE+KoHaqt6X8u6pqi7p3M4wDKQox+9Dx8yWFyq
466 Wfz/8alZ5aMezCQzXJyIaJsCLeKABosSwHcpAFmxlQ==
467 -----END CERTIFICATE-----
468 EOF
469
470         umask $oldumask;
471 }
472
473 sub setup_namespaces($$:$$)
474 {
475         my ($self, $localenv, $upn_array, $spn_array) = @_;
476
477         @{$upn_array} = [] unless defined($upn_array);
478         my $upn_args = "";
479         foreach my $upn (@{$upn_array}) {
480                 $upn_args .= " --add-upn-suffix=$upn";
481         }
482
483         @{$spn_array} = [] unless defined($spn_array);
484         my $spn_args = "";
485         foreach my $spn (@{$spn_array}) {
486                 $spn_args .= " --add-spn-suffix=$spn";
487         }
488
489         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
490
491         my $cmd_env = "";
492         $cmd_env .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$localenv->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
493         if (defined($localenv->{RESOLV_WRAPPER_CONF})) {
494                 $cmd_env .= "RESOLV_WRAPPER_CONF=\"$localenv->{RESOLV_WRAPPER_CONF}\" ";
495         } else {
496                 $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$localenv->{RESOLV_WRAPPER_HOSTS}\" ";
497         }
498         $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\"";
499
500         my $cmd_config = " $localenv->{CONFIGURATION}";
501
502         my $namespaces = $cmd_env;
503         $namespaces .= " $samba_tool domain trust namespaces $upn_args $spn_args";
504         $namespaces .= $cmd_config;
505         unless (system($namespaces) == 0) {
506                 warn("Failed to add namespaces \n$namespaces");
507                 return;
508         }
509
510         return;
511 }
512
513 sub setup_trust($$$$$)
514 {
515         my ($self, $localenv, $remoteenv, $type, $extra_args) = @_;
516
517         $localenv->{TRUST_SERVER} = $remoteenv->{SERVER};
518         $localenv->{TRUST_SERVER_IP} = $remoteenv->{SERVER_IP};
519         $localenv->{TRUST_SERVER_IPV6} = $remoteenv->{SERVER_IPV6};
520         $localenv->{TRUST_NETBIOSNAME} = $remoteenv->{NETBIOSNAME};
521         $localenv->{TRUST_USERNAME} = $remoteenv->{USERNAME};
522         $localenv->{TRUST_PASSWORD} = $remoteenv->{PASSWORD};
523         $localenv->{TRUST_DOMAIN} = $remoteenv->{DOMAIN};
524         $localenv->{TRUST_REALM} = $remoteenv->{REALM};
525
526         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
527         # setup the trust
528         my $cmd_env = "";
529         $cmd_env .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$localenv->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
530         if (defined($localenv->{RESOLV_WRAPPER_CONF})) {
531                 $cmd_env .= "RESOLV_WRAPPER_CONF=\"$localenv->{RESOLV_WRAPPER_CONF}\" ";
532         } else {
533                 $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$localenv->{RESOLV_WRAPPER_HOSTS}\" ";
534         }
535         $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\"";
536
537         my $cmd_config = " $localenv->{CONFIGURATION}";
538         my $cmd_creds = $cmd_config;
539         $cmd_creds .= " -U$localenv->{TRUST_DOMAIN}\\\\$localenv->{TRUST_USERNAME}\%$localenv->{TRUST_PASSWORD}";
540
541         my $create = $cmd_env;
542         $create .= " $samba_tool domain trust create --type=${type} $localenv->{TRUST_REALM}";
543         $create .= " $extra_args";
544         $create .= $cmd_creds;
545         unless (system($create) == 0) {
546                 warn("Failed to create trust \n$create");
547                 return undef;
548         }
549
550         return $localenv
551 }
552
553 sub provision_raw_prepare($$$$$$$$$$$)
554 {
555         my ($self, $prefix, $server_role, $hostname,
556             $domain, $realm, $functional_level,
557             $password, $kdc_ipv4, $kdc_ipv6) = @_;
558         my $ctx;
559         my $netbiosname = uc($hostname);
560
561         unless(-d $prefix or mkdir($prefix, 0777)) {
562                 warn("Unable to create $prefix");
563                 return undef;
564         }
565         my $prefix_abs = abs_path($prefix);
566
567         die ("prefix=''") if $prefix_abs eq "";
568         die ("prefix='/'") if $prefix_abs eq "/";
569
570         unless (system("rm -rf $prefix_abs/*") == 0) {
571                 warn("Unable to clean up");
572         }
573
574         
575         my $swiface = Samba::get_interface($hostname);
576
577         $ctx->{prefix} = $prefix;
578         $ctx->{prefix_abs} = $prefix_abs;
579
580         $ctx->{server_role} = $server_role;
581         $ctx->{hostname} = $hostname;
582         $ctx->{netbiosname} = $netbiosname;
583         $ctx->{swiface} = $swiface;
584         $ctx->{password} = $password;
585         $ctx->{kdc_ipv4} = $kdc_ipv4;
586         $ctx->{kdc_ipv6} = $kdc_ipv6;
587
588 #
589 # Set smbd log level here.
590 #
591         $ctx->{server_loglevel} =$ENV{SERVER_LOG_LEVEL} || 1;
592         $ctx->{username} = "Administrator";
593         $ctx->{domain} = $domain;
594         $ctx->{realm} = uc($realm);
595         $ctx->{dnsname} = lc($realm);
596
597         $ctx->{functional_level} = $functional_level;
598
599         my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `whoami`);
600         chomp $unix_name;
601         $ctx->{unix_name} = $unix_name;
602         $ctx->{unix_uid} = $>;
603         my @mygid = split(" ", $();
604         $ctx->{unix_gid} = $mygid[0];
605         $ctx->{unix_gids_str} = $);
606         @{$ctx->{unix_gids}} = split(" ", $ctx->{unix_gids_str});
607
608         $ctx->{etcdir} = "$prefix_abs/etc";
609         $ctx->{piddir} = "$prefix_abs/pid";
610         $ctx->{smb_conf} = "$ctx->{etcdir}/smb.conf";
611         $ctx->{krb5_conf} = "$ctx->{etcdir}/krb5.conf";
612         $ctx->{privatedir} = "$prefix_abs/private";
613         $ctx->{ncalrpcdir} = "$prefix_abs/ncalrpc";
614         $ctx->{lockdir} = "$prefix_abs/lockdir";
615         $ctx->{logdir} = "$prefix_abs/logs";
616         $ctx->{statedir} = "$prefix_abs/statedir";
617         $ctx->{cachedir} = "$prefix_abs/cachedir";
618         $ctx->{winbindd_socket_dir} = "$prefix_abs/winbindd_socket";
619         $ctx->{winbindd_privileged_socket_dir} = "$prefix_abs/winbindd_privileged_socket";
620         $ctx->{ntp_signd_socket_dir} = "$prefix_abs/ntp_signd_socket";
621         $ctx->{nsswrap_passwd} = "$ctx->{etcdir}/passwd";
622         $ctx->{nsswrap_group} = "$ctx->{etcdir}/group";
623         $ctx->{nsswrap_hosts} = "$ENV{SELFTEST_PREFIX}/hosts";
624         if ($ENV{SAMBA_DNS_FAKING}) {
625                 $ctx->{dns_host_file} = "$ENV{SELFTEST_PREFIX}/dns_host_file";
626                 $ctx->{samba_dnsupdate} = "$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate -s $ctx->{smb_conf} --all-interfaces --use-file=$ctx->{dns_host_file}";
627         } else {
628                 $ctx->{resolv_conf} = "$ctx->{etcdir}/resolv.conf";
629                 $ctx->{samba_dnsupdate} = "$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate -s $ctx->{smb_conf}";
630         }
631
632         $ctx->{tlsdir} = "$ctx->{privatedir}/tls";
633
634         $ctx->{ipv4} = "127.0.0.$swiface";
635         $ctx->{ipv6} = sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface);
636         $ctx->{interfaces} = "$ctx->{ipv4}/8 $ctx->{ipv6}/64";
637
638         push(@{$ctx->{directories}}, $ctx->{privatedir});
639         push(@{$ctx->{directories}}, $ctx->{etcdir});
640         push(@{$ctx->{directories}}, $ctx->{piddir});
641         push(@{$ctx->{directories}}, $ctx->{lockdir});
642         push(@{$ctx->{directories}}, $ctx->{logdir});
643         push(@{$ctx->{directories}}, $ctx->{statedir});
644         push(@{$ctx->{directories}}, $ctx->{cachedir});
645
646         $ctx->{smb_conf_extra_options} = "";
647
648         my @provision_options = ();
649         push (@provision_options, "KRB5_CONFIG=\"$ctx->{krb5_config}\"");
650         push (@provision_options, "NSS_WRAPPER_PASSWD=\"$ctx->{nsswrap_passwd}\"");
651         push (@provision_options, "NSS_WRAPPER_GROUP=\"$ctx->{nsswrap_group}\"");
652         push (@provision_options, "NSS_WRAPPER_HOSTS=\"$ctx->{nsswrap_hosts}\"");
653         if (defined($ctx->{resolv_conf})) {
654                 push (@provision_options, "RESOLV_WRAPPER_CONF=\"$ctx->{resolv_conf}\"");
655         } else {
656                 push (@provision_options, "RESOLV_WRAPPER_HOSTS=\"$ctx->{dns_host_file}\"");
657         }
658         if (defined($ENV{GDB_PROVISION})) {
659                 push (@provision_options, "gdb --args");
660                 if (!defined($ENV{PYTHON})) {
661                     push (@provision_options, "env");
662                     push (@provision_options, "python");
663                 }
664         }
665         if (defined($ENV{VALGRIND_PROVISION})) {
666                 push (@provision_options, "valgrind");
667                 if (!defined($ENV{PYTHON})) {
668                     push (@provision_options, "env");
669                     push (@provision_options, "python");
670                 }
671         }
672         if (defined($ENV{PYTHON})) {
673                 push (@provision_options, $ENV{PYTHON});
674         }
675         push (@provision_options, Samba::bindir_path($self, "samba-tool"));
676         push (@provision_options, "domain");
677         push (@provision_options, "provision");
678         push (@provision_options, "--configfile=$ctx->{smb_conf}");
679         push (@provision_options, "--host-name=$ctx->{hostname}");
680         push (@provision_options, "--host-ip=$ctx->{ipv4}");
681         push (@provision_options, "--quiet");
682         push (@provision_options, "--domain=$ctx->{domain}");
683         push (@provision_options, "--realm=$ctx->{realm}");
684         push (@provision_options, "--adminpass=$ctx->{password}");
685         push (@provision_options, "--krbtgtpass=krbtgt$ctx->{password}");
686         push (@provision_options, "--machinepass=machine$ctx->{password}");
687         push (@provision_options, "--root=$ctx->{unix_name}");
688         push (@provision_options, "--server-role=\"$ctx->{server_role}\"");
689         push (@provision_options, "--function-level=\"$ctx->{functional_level}\"");
690
691         @{$ctx->{provision_options}} = @provision_options;
692
693         return $ctx;
694 }
695
696 #
697 # Step1 creates the basic configuration
698 #
699 sub provision_raw_step1($$)
700 {
701         my ($self, $ctx) = @_;
702
703         mkdir($_, 0777) foreach (@{$ctx->{directories}});
704
705         ##
706         ## lockdir and piddir must be 0755
707         ##
708         chmod 0755, $ctx->{lockdir};
709         chmod 0755, $ctx->{piddir};
710
711         unless (open(CONFFILE, ">$ctx->{smb_conf}")) {
712                 warn("can't open $ctx->{smb_conf}$?");
713                 return undef;
714         }
715         print CONFFILE "
716 [global]
717         netbios name = $ctx->{netbiosname}
718         posix:eadb = $ctx->{statedir}/eadb.tdb
719         workgroup = $ctx->{domain}
720         realm = $ctx->{realm}
721         private dir = $ctx->{privatedir}
722         pid directory = $ctx->{piddir}
723         ncalrpc dir = $ctx->{ncalrpcdir}
724         lock dir = $ctx->{lockdir}
725         state directory = $ctx->{statedir}
726         cache directory = $ctx->{cachedir}
727         winbindd socket directory = $ctx->{winbindd_socket_dir}
728         winbindd privileged socket directory = $ctx->{winbindd_privileged_socket_dir}
729         ntp signd socket directory = $ctx->{ntp_signd_socket_dir}
730         winbind separator = /
731         interfaces = $ctx->{interfaces}
732         tls dh params file = $ctx->{tlsdir}/dhparms.pem
733         panic action = $RealBin/gdb_backtrace \%d
734         wins support = yes
735         server role = $ctx->{server_role}
736         server services = +echo +smb -s3fs
737         dcerpc endpoint servers = +winreg +srvsvc
738         notify:inotify = false
739         ldb:nosync = true
740 #We don't want to pass our self-tests if the PAC code is wrong
741         gensec:require_pac = true
742         log file = $ctx->{logdir}/log.\%m
743         log level = $ctx->{server_loglevel}
744         lanman auth = Yes
745         rndc command = true
746         dns update command = $ctx->{samba_dnsupdate}
747         spn update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_spnupdate -s $ctx->{smb_conf}
748         dreplsrv:periodic_startup_interval = 0
749         dsdb:schema update allowed = yes
750
751         vfs objects = dfs_samba4 acl_xattr fake_acls xattr_tdb streams_depot
752
753         # remove this again, when our smb2 client library
754         # supports signin on compound related requests
755         server signing = on
756
757         idmap_ldb:use rfc2307=yes
758         winbind enum users = yes
759         winbind enum groups = yes
760 ";
761
762         print CONFFILE "
763
764         # Begin extra options
765         $ctx->{smb_conf_extra_options}
766         # End extra options
767 ";
768         close(CONFFILE);
769
770         $self->mk_keyblobs($ctx->{tlsdir});
771
772         #Default the KDC IP to the server's IP
773         if (not defined($ctx->{kdc_ipv4})) {
774                 $ctx->{kdc_ipv4} = $ctx->{ipv4};
775         }
776         if (not defined($ctx->{kdc_ipv6})) {
777                 $ctx->{kdc_ipv6} = $ctx->{ipv6};
778         }
779
780         Samba::mk_krb5_conf($ctx);
781
782         open(PWD, ">$ctx->{nsswrap_passwd}");
783         if ($ctx->{unix_uid} != 0) {
784                 print PWD "root:x:0:0:root gecos:$ctx->{prefix_abs}:/bin/false\n";
785         }
786         print PWD "$ctx->{unix_name}:x:$ctx->{unix_uid}:65531:$ctx->{unix_name} gecos:$ctx->{prefix_abs}:/bin/false\n";
787         print PWD "nobody:x:65534:65533:nobody gecos:$ctx->{prefix_abs}:/bin/false
788 pdbtest:x:65533:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
789 pdbtest2:x:65532:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
790 pdbtest3:x:65531:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
791 pdbtest4:x:65530:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
792 ";
793         close(PWD);
794         my $uid_rfc2307test = 65533;
795
796         open(GRP, ">$ctx->{nsswrap_group}");
797         if ($ctx->{unix_gid} != 0) {
798                 print GRP "root:x:0:\n";
799         }
800         print GRP "$ctx->{unix_name}:x:$ctx->{unix_gid}:\n";
801         print GRP "wheel:x:10:
802 users:x:65531:
803 nobody:x:65533:
804 nogroup:x:65534:nobody
805 ";
806         close(GRP);
807         my $gid_rfc2307test = 65532;
808
809         my $hostname = lc($ctx->{hostname});
810         open(HOSTS, ">>$ctx->{nsswrap_hosts}");
811         if ($hostname eq "localdc") {
812                 print HOSTS "$ctx->{ipv4} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n";
813                 print HOSTS "$ctx->{ipv6} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n";
814         } else {
815                 print HOSTS "$ctx->{ipv4} ${hostname}.$ctx->{dnsname} ${hostname}\n";
816                 print HOSTS "$ctx->{ipv6} ${hostname}.$ctx->{dnsname} ${hostname}\n";
817         }
818         close(HOSTS);
819
820         if (defined($ctx->{resolv_conf})) {
821                 open(RESOLV_CONF, ">$ctx->{resolv_conf}");
822                 print RESOLV_CONF "nameserver $ctx->{kdc_ipv4}\n";
823                 print RESOLV_CONF "nameserver $ctx->{kdc_ipv6}\n";
824                 close(RESOLV_CONF);
825         }
826
827         my $configuration = "--configfile=$ctx->{smb_conf}";
828
829 #Ensure the config file is valid before we start
830         my $testparm = Samba::bindir_path($self, "samba-tool") . " testparm";
831         if (system("$testparm $configuration -v --suppress-prompt >/dev/null 2>&1") != 0) {
832                 system("$testparm -v --suppress-prompt $configuration >&2");
833                 warn("Failed to create a valid smb.conf configuration $testparm!");
834                 return undef;
835         }
836         unless (system("($testparm $configuration -v --suppress-prompt --parameter-name=\"netbios name\" --section-name=global 2> /dev/null | grep -i \"^$ctx->{netbiosname}\" ) >/dev/null 2>&1") == 0) {
837                 warn("Failed to create a valid smb.conf configuration! $testparm $configuration -v --suppress-prompt --parameter-name=\"netbios name\" --section-name=global");
838                 return undef;
839         }
840
841         my $ret = {
842                 KRB5_CONFIG => $ctx->{krb5_conf},
843                 PIDDIR => $ctx->{piddir},
844                 SERVER => $ctx->{hostname},
845                 SERVER_IP => $ctx->{ipv4},
846                 SERVER_IPV6 => $ctx->{ipv6},
847                 NETBIOSNAME => $ctx->{netbiosname},
848                 DOMAIN => $ctx->{domain},
849                 USERNAME => $ctx->{username},
850                 REALM => $ctx->{realm},
851                 PASSWORD => $ctx->{password},
852                 LDAPDIR => $ctx->{ldapdir},
853                 LDAP_INSTANCE => $ctx->{ldap_instance},
854                 SELFTEST_WINBINDD_SOCKET_DIR => $ctx->{winbindd_socket_dir},
855                 NCALRPCDIR => $ctx->{ncalrpcdir},
856                 LOCKDIR => $ctx->{lockdir},
857                 STATEDIR => $ctx->{statedir},
858                 CACHEDIR => $ctx->{cachedir},
859                 PRIVATEDIR => $ctx->{privatedir},
860                 SERVERCONFFILE => $ctx->{smb_conf},
861                 CONFIGURATION => $configuration,
862                 SOCKET_WRAPPER_DEFAULT_IFACE => $ctx->{swiface},
863                 NSS_WRAPPER_PASSWD => $ctx->{nsswrap_passwd},
864                 NSS_WRAPPER_GROUP => $ctx->{nsswrap_group},
865                 NSS_WRAPPER_HOSTS => $ctx->{nsswrap_hosts},
866                 SAMBA_TEST_FIFO => "$ctx->{prefix}/samba_test.fifo",
867                 SAMBA_TEST_LOG => "$ctx->{prefix}/samba_test.log",
868                 SAMBA_TEST_LOG_POS => 0,
869                 NSS_WRAPPER_MODULE_SO_PATH => Samba::nss_wrapper_winbind_so_path($self),
870                 NSS_WRAPPER_MODULE_FN_PREFIX => "winbind",
871                 LOCAL_PATH => $ctx->{share},
872                 UID_RFC2307TEST => $uid_rfc2307test,
873                 GID_RFC2307TEST => $gid_rfc2307test,
874                 SERVER_ROLE => $ctx->{server_role}
875         };
876
877         if (defined($ctx->{resolv_conf})) {
878                 $ret->{RESOLV_WRAPPER_CONF} = $ctx->{resolv_conf};
879         } else {
880                 $ret->{RESOLV_WRAPPER_HOSTS} = $ctx->{dns_host_file};
881         }
882
883         return $ret;
884 }
885
886 #
887 # Step2 runs the provision script
888 #
889 sub provision_raw_step2($$$)
890 {
891         my ($self, $ctx, $ret) = @_;
892
893         my $provision_cmd = join(" ", @{$ctx->{provision_options}});
894         unless (system($provision_cmd) == 0) {
895                 warn("Unable to provision: \n$provision_cmd\n");
896                 return undef;
897         }
898
899         my $testallowed_account = "testallowed";
900         my $samba_tool_cmd = "";
901         $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
902         $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
903             . " user add --configfile=$ctx->{smb_conf} $testallowed_account $ctx->{password}";
904         unless (system($samba_tool_cmd) == 0) {
905                 warn("Unable to add testallowed user: \n$samba_tool_cmd\n");
906                 return undef;
907         }
908
909         my $ldbmodify = "";
910         $ldbmodify .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
911         $ldbmodify .= Samba::bindir_path($self, "ldbmodify");
912         my $base_dn = "DC=".join(",DC=", split(/\./, $ctx->{realm}));
913
914         if ($ctx->{server_role} ne "domain controller") {
915                 $base_dn = "DC=$ctx->{netbiosname}";
916         }
917
918         my $user_dn = "cn=$testallowed_account,cn=users,$base_dn";
919         $testallowed_account = "testallowed account";
920         open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
921         print LDIF "dn: $user_dn
922 changetype: modify
923 replace: samAccountName
924 samAccountName: $testallowed_account
925 -
926 ";
927         close(LDIF);
928
929         open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
930         print LDIF "dn: $user_dn
931 changetype: modify
932 replace: userPrincipalName
933 userPrincipalName: testallowed upn\@$ctx->{realm}
934 replace: servicePrincipalName
935 servicePrincipalName: host/testallowed
936 -           
937 ";
938         close(LDIF);
939
940         $samba_tool_cmd = "";
941         $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
942         $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
943             . " user add --configfile=$ctx->{smb_conf} testdenied $ctx->{password}";
944         unless (system($samba_tool_cmd) == 0) {
945                 warn("Unable to add testdenied user: \n$samba_tool_cmd\n");
946                 return undef;
947         }
948
949         my $user_dn = "cn=testdenied,cn=users,$base_dn";
950         open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
951         print LDIF "dn: $user_dn
952 changetype: modify
953 replace: userPrincipalName
954 userPrincipalName: testdenied_upn\@$ctx->{realm}.upn
955 -           
956 ";
957         close(LDIF);
958
959         $samba_tool_cmd = "";
960         $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
961         $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
962             . " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account'";
963         unless (system($samba_tool_cmd) == 0) {
964                 warn("Unable to add '$testallowed_account' user to 'Allowed RODC Password Replication Group': \n$samba_tool_cmd\n");
965                 return undef;
966         }
967
968         return $ret;
969 }
970
971 sub provision($$$$$$$$$$)
972 {
973         my ($self, $prefix, $server_role, $hostname,
974             $domain, $realm, $functional_level,
975             $password, $kdc_ipv4, $kdc_ipv6, $extra_smbconf_options, $extra_smbconf_shares,
976             $extra_provision_options) = @_;
977
978         my $ctx = $self->provision_raw_prepare($prefix, $server_role,
979                                                $hostname,
980                                                $domain, $realm, $functional_level,
981                                                $password, $kdc_ipv4, $kdc_ipv6);
982
983         if (defined($extra_provision_options)) {
984                 push (@{$ctx->{provision_options}}, @{$extra_provision_options});
985         } else {
986                 push (@{$ctx->{provision_options}}, "--use-ntvfs");
987         }
988
989         $ctx->{share} = "$ctx->{prefix_abs}/share";
990         push(@{$ctx->{directories}}, "$ctx->{share}");
991         push(@{$ctx->{directories}}, "$ctx->{share}/test1");
992         push(@{$ctx->{directories}}, "$ctx->{share}/test2");
993
994         # precreate directories for printer drivers
995         push(@{$ctx->{directories}}, "$ctx->{share}/W32X86");
996         push(@{$ctx->{directories}}, "$ctx->{share}/x64");
997         push(@{$ctx->{directories}}, "$ctx->{share}/WIN40");
998
999         my $msdfs = "no";
1000         $msdfs = "yes" if ($server_role eq "domain controller");
1001         $ctx->{smb_conf_extra_options} = "
1002
1003         max xmit = 32K
1004         server max protocol = SMB2
1005         host msdfs = $msdfs
1006         lanman auth = yes
1007         allow nt4 crypto = yes
1008
1009         # fruit:copyfile is a global option
1010         fruit:copyfile = yes
1011
1012         $extra_smbconf_options
1013
1014 [tmp]
1015         path = $ctx->{share}
1016         read only = no
1017         posix:sharedelay = 100000
1018         posix:oplocktimeout = 3
1019         posix:writetimeupdatedelay = 500000
1020
1021 [xcopy_share]
1022         path = $ctx->{share}
1023         read only = no
1024         posix:sharedelay = 100000
1025         posix:oplocktimeout = 3
1026         posix:writetimeupdatedelay = 500000
1027         create mask = 777
1028         force create mode = 777
1029
1030 [posix_share]
1031         path = $ctx->{share}
1032         read only = no
1033         create mask = 0777
1034         force create mode = 0
1035         directory mask = 0777
1036         force directory mode = 0
1037
1038 [test1]
1039         path = $ctx->{share}/test1
1040         read only = no
1041         posix:sharedelay = 100000
1042         posix:oplocktimeout = 3
1043         posix:writetimeupdatedelay = 500000
1044
1045 [test2]
1046         path = $ctx->{share}/test2
1047         read only = no
1048         posix:sharedelay = 100000
1049         posix:oplocktimeout = 3
1050         posix:writetimeupdatedelay = 500000
1051
1052 [cifs]
1053         path = $ctx->{share}/_ignore_cifs_
1054         read only = no
1055         ntvfs handler = cifs
1056         cifs:server = $ctx->{netbiosname}
1057         cifs:share = tmp
1058         cifs:use-s4u2proxy = yes
1059         # There is no username specified here, instead the client is expected
1060         # to log in with kerberos, and the serverwill use delegated credentials.
1061         # Or the server tries s4u2self/s4u2proxy to impersonate the client
1062
1063 [simple]
1064         path = $ctx->{share}
1065         read only = no
1066         ntvfs handler = simple
1067
1068 [sysvol]
1069         path = $ctx->{statedir}/sysvol
1070         read only = no
1071
1072 [netlogon]
1073         path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1074         read only = no
1075
1076 [cifsposix]
1077         copy = simple
1078         ntvfs handler = cifsposix
1079
1080 [vfs_fruit]
1081         path = $ctx->{share}
1082         vfs objects = catia fruit streams_xattr acl_xattr
1083         ea support = yes
1084         fruit:ressource = file
1085         fruit:metadata = netatalk
1086         fruit:locking = netatalk
1087         fruit:encoding = native
1088
1089 $extra_smbconf_shares
1090 ";
1091
1092         if (defined($self->{ldap})) {
1093                 $ctx->{ldapdir} = "$ctx->{privatedir}/ldap";
1094                 push(@{$ctx->{directories}}, "$ctx->{ldapdir}");
1095
1096                 my $ldap_uri= "$ctx->{ldapdir}/ldapi";
1097                 $ldap_uri =~ s|/|%2F|g;
1098                 $ldap_uri = "ldapi://$ldap_uri";
1099                 $ctx->{ldap_uri} = $ldap_uri;
1100
1101                 $ctx->{ldap_instance} = lc($ctx->{netbiosname});
1102         }
1103
1104         my $ret = $self->provision_raw_step1($ctx);
1105         unless (defined $ret) {
1106                 return undef;
1107         }
1108
1109         if (defined($self->{ldap})) {
1110                 $ret->{LDAP_URI} = $ctx->{ldap_uri};
1111                 push (@{$ctx->{provision_options}}, "--ldap-backend-type=" . $self->{ldap});
1112                 push (@{$ctx->{provision_options}}, "--ldap-backend-nosync");
1113                 if ($self->{ldap} eq "openldap") {
1114                         push (@{$ctx->{provision_options}}, "--slapd-path=" . $ENV{OPENLDAP_SLAPD});
1115                         ($ret->{SLAPD_CONF_D}, $ret->{OPENLDAP_PIDFILE}) = $self->mk_openldap($ctx) or die("Unable to create openldap directories");
1116
1117                 } elsif ($self->{ldap} eq "fedora-ds") {
1118                         push (@{$ctx->{provision_options}}, "--slapd-path=" . "$ENV{FEDORA_DS_ROOT}/sbin/ns-slapd");
1119                         push (@{$ctx->{provision_options}}, "--setup-ds-path=" . "$ENV{FEDORA_DS_ROOT}/sbin/setup-ds.pl");
1120                         ($ret->{FEDORA_DS_DIR}, $ret->{FEDORA_DS_PIDFILE}) = $self->mk_fedora_ds($ctx) or die("Unable to create fedora ds directories");
1121                 }
1122
1123         }
1124
1125         return $self->provision_raw_step2($ctx, $ret);
1126 }
1127
1128 sub provision_s4member($$$)
1129 {
1130         my ($self, $prefix, $dcvars) = @_;
1131         print "PROVISIONING MEMBER...";
1132         my $extra_smb_conf = "
1133         passdb backend = samba_dsdb
1134 winbindd:use external pipes = true
1135
1136 rpc_server:default = external
1137 rpc_server:svcctl = embedded
1138 rpc_server:srvsvc = embedded
1139 rpc_server:eventlog = embedded
1140 rpc_server:ntsvcs = embedded
1141 rpc_server:winreg = embedded
1142 rpc_server:spoolss = embedded
1143 rpc_daemon:spoolssd = embedded
1144 rpc_server:tcpip = no
1145 ";
1146         my $ret = $self->provision($prefix,
1147                                    "member server",
1148                                    "s4member",
1149                                    "SAMBADOMAIN",
1150                                    "samba.example.com",
1151                                    "2008",
1152                                    "locMEMpass3",
1153                                    $dcvars->{SERVER_IP},
1154                                    $dcvars->{SERVER_IPV6},
1155                                    $extra_smb_conf, "", undef);
1156         unless ($ret) {
1157                 return undef;
1158         }
1159
1160         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
1161         my $cmd = "";
1162         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1163         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1164                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1165         } else {
1166                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1167         }
1168         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1169         $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} member";
1170         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1171         $cmd .= " --machinepass=machine$ret->{PASSWORD}";
1172
1173         unless (system($cmd) == 0) {
1174                 warn("Join failed\n$cmd");
1175                 return undef;
1176         }
1177
1178         $ret->{MEMBER_SERVER} = $ret->{SERVER};
1179         $ret->{MEMBER_SERVER_IP} = $ret->{SERVER_IP};
1180         $ret->{MEMBER_SERVER_IPV6} = $ret->{SERVER_IPV6};
1181         $ret->{MEMBER_NETBIOSNAME} = $ret->{NETBIOSNAME};
1182         $ret->{MEMBER_USERNAME} = $ret->{USERNAME};
1183         $ret->{MEMBER_PASSWORD} = $ret->{PASSWORD};
1184
1185         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1186         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1187         $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1188         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1189         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1190         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1191
1192         return $ret;
1193 }
1194
1195 sub provision_rpc_proxy($$$)
1196 {
1197         my ($self, $prefix, $dcvars) = @_;
1198         print "PROVISIONING RPC PROXY...";
1199
1200         my $extra_smbconf_options = "
1201         passdb backend = samba_dsdb
1202
1203         # rpc_proxy
1204         dcerpc_remote:binding = ncacn_ip_tcp:$dcvars->{SERVER}
1205         dcerpc endpoint servers = epmapper, remote
1206         dcerpc_remote:interfaces = rpcecho
1207
1208 [cifs_to_dc]
1209         path = /tmp/_ignore_cifs_to_dc_/_none_
1210         read only = no
1211         ntvfs handler = cifs
1212         cifs:server = $dcvars->{SERVER}
1213         cifs:share = cifs
1214         cifs:use-s4u2proxy = yes
1215         # There is no username specified here, instead the client is expected
1216         # to log in with kerberos, and the serverwill use delegated credentials.
1217         # Or the server tries s4u2self/s4u2proxy to impersonate the client
1218
1219 ";
1220
1221         my $ret = $self->provision($prefix,
1222                                    "member server",
1223                                    "localrpcproxy",
1224                                    "SAMBADOMAIN",
1225                                    "samba.example.com",
1226                                    "2008",
1227                                    "locRPCproxypass4",
1228                                    $dcvars->{SERVER_IP},
1229                                    $dcvars->{SERVER_IPV6},
1230                                    $extra_smbconf_options, "", undef);
1231
1232         unless ($ret) {
1233                 return undef;
1234         }
1235
1236         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
1237
1238         # The joind runs in the context of the rpc_proxy/member for now
1239         my $cmd = "";
1240         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1241         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1242                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1243         } else {
1244                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1245         }
1246         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1247         $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} member";
1248         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1249         $cmd .= " --machinepass=machine$ret->{PASSWORD}";
1250
1251         unless (system($cmd) == 0) {
1252                 warn("Join failed\n$cmd");
1253                 return undef;
1254         }
1255
1256         # Setting up delegation runs in the context of the DC for now
1257         $cmd = "";
1258         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1259         $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
1260         $cmd .= "$samba_tool delegation for-any-protocol '$ret->{NETBIOSNAME}\$' on";
1261         $cmd .= " $dcvars->{CONFIGURATION}";
1262         print $cmd;
1263
1264         unless (system($cmd) == 0) {
1265                 warn("Delegation failed\n$cmd");
1266                 return undef;
1267         }
1268
1269         # Setting up delegation runs in the context of the DC for now
1270         $cmd = "";
1271         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1272         $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
1273         $cmd .= "$samba_tool delegation add-service '$ret->{NETBIOSNAME}\$' cifs/$dcvars->{SERVER}";
1274         $cmd .= " $dcvars->{CONFIGURATION}";
1275
1276         unless (system($cmd) == 0) {
1277                 warn("Delegation failed\n$cmd");
1278                 return undef;
1279         }
1280
1281         $ret->{RPC_PROXY_SERVER} = $ret->{SERVER};
1282         $ret->{RPC_PROXY_SERVER_IP} = $ret->{SERVER_IP};
1283         $ret->{RPC_PROXY_SERVER_IPV6} = $ret->{SERVER_IPV6};
1284         $ret->{RPC_PROXY_NETBIOSNAME} = $ret->{NETBIOSNAME};
1285         $ret->{RPC_PROXY_USERNAME} = $ret->{USERNAME};
1286         $ret->{RPC_PROXY_PASSWORD} = $ret->{PASSWORD};
1287
1288         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1289         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1290         $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1291         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1292         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1293         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1294
1295         return $ret;
1296 }
1297
1298 sub provision_promoted_dc($$$)
1299 {
1300         my ($self, $prefix, $dcvars) = @_;
1301         print "PROVISIONING PROMOTED DC...";
1302
1303         # We do this so that we don't run the provision.  That's the job of 'samba-tool domain dcpromo'.
1304         my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1305                                                "promotedvdc",
1306                                                "SAMBADOMAIN",
1307                                                "samba.example.com",
1308                                                "2008",
1309                                                $dcvars->{PASSWORD},
1310                                                $dcvars->{SERVER_IP},
1311                                                $dcvars->{SERVER_IPV6});
1312
1313         push (@{$ctx->{provision_options}}, "--use-ntvfs");
1314
1315         $ctx->{smb_conf_extra_options} = "
1316         max xmit = 32K
1317         server max protocol = SMB2
1318
1319 [sysvol]
1320         path = $ctx->{statedir}/sysvol
1321         read only = yes
1322
1323 [netlogon]
1324         path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1325         read only = no
1326
1327 ";
1328
1329         my $ret = $self->provision_raw_step1($ctx);
1330         unless ($ret) {
1331                 return undef;
1332         }
1333
1334         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
1335         my $cmd = "";
1336         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1337         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1338                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1339         } else {
1340                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1341         }
1342         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1343         $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} MEMBER --realm=$dcvars->{REALM}";
1344         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1345         $cmd .= " --machinepass=machine$ret->{PASSWORD}";
1346
1347         unless (system($cmd) == 0) {
1348                 warn("Join failed\n$cmd");
1349                 return undef;
1350         }
1351
1352         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
1353         my $cmd = "";
1354         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1355         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1356         $cmd .= "$samba_tool domain dcpromo $ret->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
1357         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1358         $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs --dns-backend=BIND9_DLZ";
1359
1360         unless (system($cmd) == 0) {
1361                 warn("Join failed\n$cmd");
1362                 return undef;
1363         }
1364
1365         $ret->{PROMOTED_DC_SERVER} = $ret->{SERVER};
1366         $ret->{PROMOTED_DC_SERVER_IP} = $ret->{SERVER_IP};
1367         $ret->{PROMOTED_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1368         $ret->{PROMOTED_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1369
1370         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1371         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1372         $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1373         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1374         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1375         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1376
1377         return $ret;
1378 }
1379
1380 sub provision_vampire_dc($$$)
1381 {
1382         my ($self, $prefix, $dcvars) = @_;
1383         print "PROVISIONING VAMPIRE DC...";
1384
1385         # We do this so that we don't run the provision.  That's the job of 'net vampire'.
1386         my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1387                                                "localvampiredc",
1388                                                "SAMBADOMAIN",
1389                                                "samba.example.com",
1390                                                "2008",
1391                                                $dcvars->{PASSWORD},
1392                                                $dcvars->{SERVER_IP},
1393                                                $dcvars->{SERVER_IPV6});
1394
1395         push (@{$ctx->{provision_options}}, "--use-ntvfs");
1396
1397         $ctx->{smb_conf_extra_options} = "
1398         max xmit = 32K
1399         server max protocol = SMB2
1400
1401 [sysvol]
1402         path = $ctx->{statedir}/sysvol
1403         read only = yes
1404
1405 [netlogon]
1406         path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1407         read only = no
1408
1409 ";
1410
1411         my $ret = $self->provision_raw_step1($ctx);
1412         unless ($ret) {
1413                 return undef;
1414         }
1415
1416         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
1417         my $cmd = "";
1418         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1419         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1420                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1421         } else {
1422                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1423         }
1424         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1425         $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
1426         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD} --domain-critical-only";
1427         $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs";
1428
1429         unless (system($cmd) == 0) {
1430                 warn("Join failed\n$cmd");
1431                 return undef;
1432         }
1433
1434         $ret->{VAMPIRE_DC_SERVER} = $ret->{SERVER};
1435         $ret->{VAMPIRE_DC_SERVER_IP} = $ret->{SERVER_IP};
1436         $ret->{VAMPIRE_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1437         $ret->{VAMPIRE_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1438
1439         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1440         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1441         $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1442         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1443         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1444         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1445         $ret->{DC_REALM} = $dcvars->{DC_REALM};
1446
1447         return $ret;
1448 }
1449
1450 sub provision_subdom_dc($$$)
1451 {
1452         my ($self, $prefix, $dcvars) = @_;
1453         print "PROVISIONING SUBDOMAIN DC...";
1454
1455         # We do this so that we don't run the provision.  That's the job of 'net vampire'.
1456         my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1457                                                "localsubdc",
1458                                                "SAMBASUBDOM",
1459                                                "sub.samba.example.com",
1460                                                "2008",
1461                                                $dcvars->{PASSWORD},
1462                                                undef);
1463
1464         push (@{$ctx->{provision_options}}, "--use-ntvfs");
1465
1466         $ctx->{smb_conf_extra_options} = "
1467         max xmit = 32K
1468         server max protocol = SMB2
1469
1470 [sysvol]
1471         path = $ctx->{statedir}/sysvol
1472         read only = yes
1473
1474 [netlogon]
1475         path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1476         read only = no
1477
1478 ";
1479
1480         my $ret = $self->provision_raw_step1($ctx);
1481         unless ($ret) {
1482                 return undef;
1483         }
1484
1485         Samba::mk_krb5_conf($ctx);
1486
1487         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
1488         my $cmd = "";
1489         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1490         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1491                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1492         } else {
1493                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1494         }
1495         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1496         $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $ctx->{dnsname} subdomain ";
1497         $cmd .= "--parent-domain=$dcvars->{REALM} -U$dcvars->{DC_USERNAME}\@$dcvars->{REALM}\%$dcvars->{DC_PASSWORD}";
1498         $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs";
1499         $cmd .= " --adminpass=$ret->{PASSWORD}";
1500
1501         unless (system($cmd) == 0) {
1502                 warn("Join failed\n$cmd");
1503                 return undef;
1504         }
1505
1506         $ret->{SUBDOM_DC_SERVER} = $ret->{SERVER};
1507         $ret->{SUBDOM_DC_SERVER_IP} = $ret->{SERVER_IP};
1508         $ret->{SUBDOM_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1509         $ret->{SUBDOM_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1510
1511         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1512         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1513         $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1514         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1515         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1516         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1517
1518         return $ret;
1519 }
1520
1521 sub provision_ad_dc_ntvfs($$)
1522 {
1523         my ($self, $prefix) = @_;
1524
1525         # We keep the old 'winbind' name here in server services to
1526         # ensure upgrades which used that name still work with the now
1527         # alias.
1528
1529         print "PROVISIONING AD DC (NTVFS)...";
1530         my $extra_conf_options = "netbios aliases = localDC1-a
1531         server services = +winbind -winbindd";
1532         my $ret = $self->provision($prefix,
1533                                    "domain controller",
1534                                    "localdc",
1535                                    "SAMBADOMAIN",
1536                                    "samba.example.com",
1537                                    "2008",
1538                                    "locDCpass1",
1539                                    undef,
1540                                    undef,
1541                                    $extra_conf_options,
1542                                    "",
1543                                    undef);
1544
1545         return undef unless(defined $ret);
1546         unless($self->add_wins_config("$prefix/private")) {
1547                 warn("Unable to add wins configuration");
1548                 return undef;
1549         }
1550         $ret->{NETBIOSALIAS} = "localdc1-a";
1551         $ret->{DC_SERVER} = $ret->{SERVER};
1552         $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1553         $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1554         $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1555         $ret->{DC_USERNAME} = $ret->{USERNAME};
1556         $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1557         $ret->{DC_REALM} = $ret->{REALM};
1558
1559         return $ret;
1560 }
1561
1562 sub provision_fl2000dc($$)
1563 {
1564         my ($self, $prefix) = @_;
1565
1566         print "PROVISIONING DC WITH FOREST LEVEL 2000...";
1567         my $ret = $self->provision($prefix,
1568                                    "domain controller",
1569                                    "dc5",
1570                                    "SAMBA2000",
1571                                    "samba2000.example.com",
1572                                    "2000",
1573                                    "locDCpass5",
1574                                    undef,
1575                                    undef,
1576                                    "",
1577                                    "",
1578                                    undef);
1579
1580         unless($self->add_wins_config("$prefix/private")) {
1581                 warn("Unable to add wins configuration");
1582                 return undef;
1583         }
1584
1585         return $ret;
1586 }
1587
1588 sub provision_fl2003dc($$$)
1589 {
1590         my ($self, $prefix, $dcvars) = @_;
1591
1592         print "PROVISIONING DC WITH FOREST LEVEL 2003...";
1593         my $extra_conf_options = "allow dns updates = nonsecure and secure";
1594         my $ret = $self->provision($prefix,
1595                                    "domain controller",
1596                                    "dc6",
1597                                    "SAMBA2003",
1598                                    "samba2003.example.com",
1599                                    "2003",
1600                                    "locDCpass6",
1601                                    undef,
1602                                    undef,
1603                                    $extra_conf_options,
1604                                    "",
1605                                    undef);
1606
1607         unless (defined $ret) {
1608                 return undef;
1609         }
1610
1611         $ret->{DC_SERVER} = $ret->{SERVER};
1612         $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1613         $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1614         $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1615         $ret->{DC_USERNAME} = $ret->{USERNAME};
1616         $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1617
1618         my @samba_tool_options;
1619         push (@samba_tool_options, Samba::bindir_path($self, "samba-tool"));
1620         push (@samba_tool_options, "domain");
1621         push (@samba_tool_options, "passwordsettings");
1622         push (@samba_tool_options, "set");
1623         push (@samba_tool_options, "--configfile=$ret->{SERVERCONFFILE}");
1624         push (@samba_tool_options, "--min-pwd-age=0");
1625         push (@samba_tool_options, "--history-length=1");
1626
1627         my $samba_tool_cmd = join(" ", @samba_tool_options);
1628
1629         unless (system($samba_tool_cmd) == 0) {
1630                 warn("Unable to set min password age to 0: \n$samba_tool_cmd\n");
1631                 return undef;
1632         }
1633
1634         return $ret;
1635
1636         unless($self->add_wins_config("$prefix/private")) {
1637                 warn("Unable to add wins configuration");
1638                 return undef;
1639         }
1640
1641         return $ret;
1642 }
1643
1644 sub provision_fl2008r2dc($$$)
1645 {
1646         my ($self, $prefix, $dcvars) = @_;
1647
1648         print "PROVISIONING DC WITH FOREST LEVEL 2008r2...";
1649         my $ret = $self->provision($prefix,
1650                                    "domain controller",
1651                                    "dc7",
1652                                    "SAMBA2008R2",
1653                                    "samba2008R2.example.com",
1654                                    "2008_R2",
1655                                    "locDCpass7",
1656                                    undef,
1657                                    undef,
1658                                    "",
1659                                    "",
1660                                    undef);
1661
1662         unless ($self->add_wins_config("$prefix/private")) {
1663                 warn("Unable to add wins configuration");
1664                 return undef;
1665         }
1666
1667         return $ret;
1668 }
1669
1670
1671 sub provision_rodc($$$)
1672 {
1673         my ($self, $prefix, $dcvars) = @_;
1674         print "PROVISIONING RODC...";
1675
1676         # We do this so that we don't run the provision.  That's the job of 'net join RODC'.
1677         my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1678                                                "rodc",
1679                                                "SAMBADOMAIN",
1680                                                "samba.example.com",
1681                                                "2008",
1682                                                $dcvars->{PASSWORD},
1683                                                $dcvars->{SERVER_IP},
1684                                                $dcvars->{SERVER_IPV6});
1685         unless ($ctx) {
1686                 return undef;
1687         }
1688
1689         push (@{$ctx->{provision_options}}, "--use-ntvfs");
1690
1691         $ctx->{share} = "$ctx->{prefix_abs}/share";
1692         push(@{$ctx->{directories}}, "$ctx->{share}");
1693
1694         $ctx->{smb_conf_extra_options} = "
1695         max xmit = 32K
1696         server max protocol = SMB2
1697
1698 [sysvol]
1699         path = $ctx->{statedir}/sysvol
1700         read only = yes
1701
1702 [netlogon]
1703         path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1704         read only = yes
1705
1706 [tmp]
1707         path = $ctx->{share}
1708         read only = no
1709         posix:sharedelay = 10000
1710         posix:oplocktimeout = 3
1711         posix:writetimeupdatedelay = 50000
1712
1713 ";
1714
1715         my $ret = $self->provision_raw_step1($ctx);
1716         unless ($ret) {
1717                 return undef;
1718         }
1719
1720         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
1721         my $cmd = "";
1722         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1723         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1724                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1725         } else {
1726                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1727         }
1728         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1729         $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} RODC";
1730         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1731         $cmd .= " --server=$dcvars->{DC_SERVER} --use-ntvfs";
1732
1733         unless (system($cmd) == 0) {
1734                 warn("RODC join failed\n$cmd");
1735                 return undef;
1736         }
1737
1738         # This ensures deterministic behaviour for tests that want to have the 'testallowed account'
1739         # user password verified on the RODC
1740         my $testallowed_account = "testallowed account";
1741         $cmd = "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1742         $cmd .= "$samba_tool rodc preload '$testallowed_account' $ret->{CONFIGURATION}";
1743         $cmd .= " --server=$dcvars->{DC_SERVER}";
1744
1745         unless (system($cmd) == 0) {
1746                 warn("RODC join failed\n$cmd");
1747                 return undef;
1748         }
1749
1750         # we overwrite the kdc after the RODC join
1751         # so that use the RODC as kdc and test
1752         # the proxy code
1753         $ctx->{kdc_ipv4} = $ret->{SERVER_IP};
1754         $ctx->{kdc_ipv6} = $ret->{SERVER_IPV6};
1755         Samba::mk_krb5_conf($ctx);
1756
1757         $ret->{RODC_DC_SERVER} = $ret->{SERVER};
1758         $ret->{RODC_DC_SERVER_IP} = $ret->{SERVER_IP};
1759         $ret->{RODC_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1760         $ret->{RODC_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1761
1762         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1763         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1764         $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1765         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1766         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1767         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1768
1769         return $ret;
1770 }
1771
1772 sub provision_ad_dc($$)
1773 {
1774         my ($self, $prefix) = @_;
1775
1776         my $prefix_abs = abs_path($prefix);
1777
1778         my $bindir_abs = abs_path($self->{bindir});
1779         my $lockdir="$prefix_abs/lockdir";
1780         my $conffile="$prefix_abs/etc/smb.conf";
1781
1782         my $extra_smbconf_options = "
1783         server services = -smb +s3fs
1784         xattr_tdb:file = $prefix_abs/statedir/xattr.tdb
1785
1786         dbwrap_tdb_mutexes:* = yes
1787
1788         kernel oplocks = no
1789         kernel change notify = no
1790
1791         logging = file
1792         printing = bsd
1793         printcap name = /dev/null
1794
1795         max protocol = SMB3
1796         read only = no
1797         server signing = auto
1798
1799         smbd:sharedelay = 100000
1800         smbd:writetimeupdatedelay = 500000
1801         create mask = 755
1802         dos filemode = yes
1803
1804         dcerpc endpoint servers = -winreg -srvsvc
1805
1806         printcap name = /dev/null
1807
1808         addprinter command = $ENV{SRCDIR_ABS}/source3/script/tests/printing/modprinter.pl -a -s $conffile --
1809         deleteprinter command = $ENV{SRCDIR_ABS}/source3/script/tests/printing/modprinter.pl -d -s $conffile --
1810
1811         printing = vlp
1812         print command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb print %p %s
1813         lpq command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpq %p
1814         lp rm command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lprm %p %j
1815         lp pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lppause %p %j
1816         lp resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpresume %p %j
1817         queue pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queuepause %p
1818         queue resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queueresume %p
1819         lpq cache time = 0
1820         print notify backchannel = yes
1821 ";
1822
1823         my $extra_smbconf_shares = "
1824
1825 [tmpenc]
1826         copy = tmp
1827         smb encrypt = required
1828
1829 [tmpcase]
1830         copy = tmp
1831         case sensitive = yes
1832
1833 [tmpguest]
1834         copy = tmp
1835         guest ok = yes
1836
1837 [hideunread]
1838         copy = tmp
1839         hide unreadable = yes
1840
1841 [durable]
1842         copy = tmp
1843         kernel share modes = no
1844         kernel oplocks = no
1845         posix locking = no
1846
1847 [print\$]
1848         copy = tmp
1849
1850 [print1]
1851         copy = tmp
1852         printable = yes
1853
1854 [print2]
1855         copy = print1
1856 [print3]
1857         copy = print1
1858 [lp]
1859         copy = print1
1860 ";
1861
1862         print "PROVISIONING AD DC...";
1863         my $ret = $self->provision($prefix,
1864                                    "domain controller",
1865                                    "addc",
1866                                    "ADDOMAIN",
1867                                    "addc.samba.example.com",
1868                                    "2008",
1869                                    "locDCpass1",
1870                                    undef,
1871                                    undef,
1872                                    $extra_smbconf_options,
1873                                    $extra_smbconf_shares,
1874                                    undef);
1875
1876         return undef unless(defined $ret);
1877         unless($self->add_wins_config("$prefix/private")) {
1878                 warn("Unable to add wins configuration");
1879                 return undef;
1880         }
1881
1882         $ret->{DC_SERVER} = $ret->{SERVER};
1883         $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1884         $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1885         $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1886         $ret->{DC_USERNAME} = $ret->{USERNAME};
1887         $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1888
1889         return $ret;
1890 }
1891
1892 sub provision_chgdcpass($$)
1893 {
1894         my ($self, $prefix) = @_;
1895
1896         print "PROVISIONING CHGDCPASS...";
1897         my $extra_provision_options = undef;
1898         push (@{$extra_provision_options}, "--dns-backend=BIND9_DLZ");
1899         my $ret = $self->provision($prefix,
1900                                    "domain controller",
1901                                    "chgdcpass",
1902                                    "CHDCDOMAIN",
1903                                    "chgdcpassword.samba.example.com",
1904                                    "2008",
1905                                    "chgDCpass1",
1906                                    undef,
1907                                    undef,
1908                                    "",
1909                                    "",
1910                                    $extra_provision_options);
1911
1912         return undef unless(defined $ret);
1913         unless($self->add_wins_config("$prefix/private")) {
1914                 warn("Unable to add wins configuration");
1915                 return undef;
1916         }
1917         
1918         # Remove secrets.tdb from this environment to test that we
1919         # still start up on systems without the new matching
1920         # secrets.tdb records.
1921         unless (unlink("$ret->{PRIVATEDIR}/secrets.tdb") || unlink("$ret->{PRIVATEDIR}/secrets.ntdb")) {
1922                 warn("Unable to remove $ret->{PRIVATEDIR}/secrets.tdb added during provision");
1923                 return undef;
1924         }
1925             
1926         $ret->{DC_SERVER} = $ret->{SERVER};
1927         $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1928         $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1929         $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1930         $ret->{DC_USERNAME} = $ret->{USERNAME};
1931         $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1932
1933         return $ret;
1934 }
1935
1936 sub teardown_env($$)
1937 {
1938         my ($self, $envvars) = @_;
1939         my $pid;
1940
1941         # This should cause samba to terminate gracefully
1942         close($envvars->{STDIN_PIPE});
1943
1944         $pid = $envvars->{SAMBA_PID};
1945         my $count = 0;
1946         my $childpid;
1947
1948         # This should give it time to write out the gcov data
1949         until ($count > 30) {
1950             if (Samba::cleanup_child($pid, "samba") == -1) {
1951                 last;
1952             }
1953             sleep(1);
1954             $count++;
1955         }
1956
1957         if ($count > 30 || kill(0, $pid)) {
1958             kill "TERM", $pid;
1959
1960             until ($count > 40) {
1961                 if (Samba::cleanup_child($pid, "samba") == -1) {
1962                     last;
1963                 }
1964                 sleep(1);
1965                 $count++;
1966             }
1967             # If it is still around, kill it
1968             warn "server process $pid took more than $count seconds to exit, killing\n";
1969             kill 9, $pid;
1970         }
1971
1972         $self->slapd_stop($envvars) if ($self->{ldap});
1973
1974         print $self->getlog_env($envvars);
1975
1976         return;
1977 }
1978
1979 sub getlog_env($$)
1980 {
1981         my ($self, $envvars) = @_;
1982         my $title = "SAMBA LOG of: $envvars->{NETBIOSNAME}\n";
1983         my $out = $title;
1984
1985         open(LOG, "<$envvars->{SAMBA_TEST_LOG}");
1986
1987         seek(LOG, $envvars->{SAMBA_TEST_LOG_POS}, SEEK_SET);
1988         while (<LOG>) {
1989                 $out .= $_;
1990         }
1991         $envvars->{SAMBA_TEST_LOG_POS} = tell(LOG);
1992         close(LOG);
1993
1994         return "" if $out eq $title;
1995
1996         return $out;
1997 }
1998
1999 sub check_env($$)
2000 {
2001         my ($self, $envvars) = @_;
2002
2003         my $childpid = Samba::cleanup_child($envvars->{SAMBA_PID}, "samba");
2004
2005         return ($childpid == 0);
2006 }
2007
2008 sub setup_env($$$)
2009 {
2010         my ($self, $envname, $path) = @_;
2011         my $target3 = $self->{target3};
2012
2013         $ENV{ENVNAME} = $envname;
2014
2015         if (defined($self->{vars}->{$envname})) {
2016                 return $self->{vars}->{$envname};
2017         }
2018
2019         if ($envname eq "ad_dc_ntvfs") {
2020                 return $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2021         } elsif ($envname eq "fl2000dc") {
2022                 return $self->setup_fl2000dc("$path/fl2000dc");
2023         } elsif ($envname eq "fl2003dc") {
2024                 if (not defined($self->{vars}->{ad_dc})) {
2025                         $self->setup_ad_dc("$path/ad_dc");
2026                 }
2027                 return $self->setup_fl2003dc("$path/fl2003dc", $self->{vars}->{ad_dc});
2028         } elsif ($envname eq "fl2008r2dc") {
2029                 if (not defined($self->{vars}->{ad_dc})) {
2030                         $self->setup_ad_dc("$path/ad_dc");
2031                 }
2032                 return $self->setup_fl2008r2dc("$path/fl2008r2dc", $self->{vars}->{ad_dc});
2033         } elsif ($envname eq "rpc_proxy") {
2034                 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2035                         $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2036                 }
2037                 return $self->setup_rpc_proxy("$path/rpc_proxy", $self->{vars}->{ad_dc_ntvfs});
2038         } elsif ($envname eq "vampire_dc") {
2039                 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2040                         $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2041                 }
2042                 return $self->setup_vampire_dc("$path/vampire_dc", $self->{vars}->{ad_dc_ntvfs});
2043         } elsif ($envname eq "promoted_dc") {
2044                 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2045                         $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2046                 }
2047                 return $self->setup_promoted_dc("$path/promoted_dc", $self->{vars}->{ad_dc_ntvfs});
2048         } elsif ($envname eq "subdom_dc") {
2049                 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2050                         $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2051                 }
2052                 return $self->setup_subdom_dc("$path/subdom_dc", $self->{vars}->{ad_dc_ntvfs});
2053         } elsif ($envname eq "s4member") {
2054                 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2055                         $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2056                 }
2057                 return $self->setup_s4member("$path/s4member", $self->{vars}->{ad_dc_ntvfs});
2058         } elsif ($envname eq "rodc") {
2059                 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2060                         $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2061                 }
2062                 return $self->setup_rodc("$path/rodc", $self->{vars}->{ad_dc_ntvfs});
2063         } elsif ($envname eq "chgdcpass") {
2064                 return $self->setup_chgdcpass("$path/chgdcpass", $self->{vars}->{chgdcpass});
2065         } elsif ($envname eq "ad_member") {
2066                 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2067                         $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2068                 }
2069                 return $target3->setup_admember("$path/ad_member", $self->{vars}->{ad_dc_ntvfs}, 29);
2070         } elsif ($envname eq "ad_dc") {
2071                 return $self->setup_ad_dc("$path/ad_dc");
2072         } elsif ($envname eq "ad_dc_no_nss") {
2073                 return $self->setup_ad_dc("$path/ad_dc_no_nss", "no_nss");
2074         } elsif ($envname eq "ad_member_rfc2307") {
2075                 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2076                         $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2077                 }
2078                 return $target3->setup_admember_rfc2307("$path/ad_member_rfc2307",
2079                                                         $self->{vars}->{ad_dc_ntvfs}, 34);
2080         } else {
2081                 return "UNKNOWN";
2082         }
2083 }
2084
2085 sub setup_s4member($$$)
2086 {
2087         my ($self, $path, $dc_vars) = @_;
2088
2089         my $env = $self->provision_s4member($path, $dc_vars);
2090
2091         if (defined $env) {
2092                 $self->check_or_start($env, "single");
2093
2094                 $self->wait_for_start($env);
2095
2096                 $self->{vars}->{s4member} = $env;
2097         }
2098
2099         return $env;
2100 }
2101
2102 sub setup_rpc_proxy($$$)
2103 {
2104         my ($self, $path, $dc_vars) = @_;
2105
2106         my $env = $self->provision_rpc_proxy($path, $dc_vars);
2107
2108         if (defined $env) {
2109                 $self->check_or_start($env, "single");
2110
2111                 $self->wait_for_start($env);
2112
2113                 $self->{vars}->{rpc_proxy} = $env;
2114         }
2115         return $env;
2116 }
2117
2118 sub setup_ad_dc_ntvfs($$)
2119 {
2120         my ($self, $path) = @_;
2121
2122         my $env = $self->provision_ad_dc_ntvfs($path);
2123         if (defined $env) {
2124                 $self->check_or_start($env, "standard");
2125
2126                 $self->wait_for_start($env);
2127
2128                 $self->{vars}->{ad_dc_ntvfs} = $env;
2129         }
2130         return $env;
2131 }
2132
2133 sub setup_chgdcpass($$)
2134 {
2135         my ($self, $path) = @_;
2136
2137         my $env = $self->provision_chgdcpass($path);
2138         if (defined $env) {
2139                 $self->check_or_start($env, "single");
2140
2141                 $self->wait_for_start($env);
2142
2143                 $self->{vars}->{chgdcpass} = $env;
2144         }
2145         return $env;
2146 }
2147
2148 sub setup_fl2000dc($$)
2149 {
2150         my ($self, $path) = @_;
2151
2152         my $env = $self->provision_fl2000dc($path);
2153         if (defined $env) {
2154                 $self->check_or_start($env, "single");
2155
2156                 $self->wait_for_start($env);
2157
2158                 $self->{vars}->{fl2000dc} = $env;
2159         }
2160
2161         return $env;
2162 }
2163
2164 sub setup_fl2003dc($$$)
2165 {
2166         my ($self, $path, $dc_vars) = @_;
2167
2168         my $env = $self->provision_fl2003dc($path);
2169
2170         if (defined $env) {
2171                 $self->check_or_start($env, "single");
2172
2173                 $self->wait_for_start($env);
2174
2175                 $env = $self->setup_trust($env, $dc_vars, "external", "--no-aes-keys");
2176
2177                 $self->{vars}->{fl2003dc} = $env;
2178         }
2179         return $env;
2180 }
2181
2182 sub setup_fl2008r2dc($$$)
2183 {
2184         my ($self, $path, $dc_vars) = @_;
2185
2186         my $env = $self->provision_fl2008r2dc($path);
2187
2188         if (defined $env) {
2189                 $self->check_or_start($env, "single");
2190
2191                 $self->wait_for_start($env);
2192
2193                 my $upn_array = ["$env->{REALM}.upn"];
2194                 my $spn_array = ["$env->{REALM}.spn"];
2195
2196                 $self->setup_namespaces($env, $upn_array, $spn_array);
2197
2198                 $env = $self->setup_trust($env, $dc_vars, "forest", "");
2199
2200                 $self->{vars}->{fl2008r2dc} = $env;
2201         }
2202
2203         return $env;
2204 }
2205
2206 sub setup_vampire_dc($$$)
2207 {
2208         my ($self, $path, $dc_vars) = @_;
2209
2210         my $env = $self->provision_vampire_dc($path, $dc_vars);
2211
2212         if (defined $env) {
2213                 $self->check_or_start($env, "single");
2214
2215                 $self->wait_for_start($env);
2216
2217                 $self->{vars}->{vampire_dc} = $env;
2218
2219                 # force replicated DC to update repsTo/repsFrom
2220                 # for vampired partitions
2221                 my $samba_tool =  Samba::bindir_path($self, "samba-tool");
2222                 my $cmd = "";
2223                 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
2224                 if (defined($env->{RESOLV_WRAPPER_CONF})) {
2225                         $cmd .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
2226                 } else {
2227                         $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
2228                 }
2229                 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2230                 $cmd .= " $samba_tool drs kcc -k no $env->{DC_SERVER}";
2231                 $cmd .= " $env->{CONFIGURATION}";
2232                 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2233                 unless (system($cmd) == 0) {
2234                         warn("Failed to exec kcc\n$cmd");
2235                         return undef;
2236                 }
2237
2238                 # as 'vampired' dc may add data in its local replica
2239                 # we need to synchronize data between DCs
2240                 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2241                 $cmd = "";
2242                 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
2243                 if (defined($env->{RESOLV_WRAPPER_CONF})) {
2244                         $cmd .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
2245                 } else {
2246                         $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
2247                 }
2248                 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2249                 $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SERVER}";
2250                 $cmd .= " $dc_vars->{CONFIGURATION}";
2251                 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2252                 # replicate Configuration NC
2253                 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2254                 unless(system($cmd_repl) == 0) {
2255                         warn("Failed to replicate\n$cmd_repl");
2256                         return undef;
2257                 }
2258                 # replicate Default NC
2259                 $cmd_repl = "$cmd \"$base_dn\"";
2260                 unless(system($cmd_repl) == 0) {
2261                         warn("Failed to replicate\n$cmd_repl");
2262                         return undef;
2263                 }
2264         }
2265
2266         return $env;
2267 }
2268
2269 sub setup_promoted_dc($$$)
2270 {
2271         my ($self, $path, $dc_vars) = @_;
2272
2273         my $env = $self->provision_promoted_dc($path, $dc_vars);
2274
2275         if (defined $env) {
2276                 $self->check_or_start($env, "single");
2277
2278                 $self->wait_for_start($env);
2279
2280                 $self->{vars}->{promoted_dc} = $env;
2281
2282                 # force source and replicated DC to update repsTo/repsFrom
2283                 # for vampired partitions
2284                 my $samba_tool =  Samba::bindir_path($self, "samba-tool");
2285                 my $cmd = "";
2286                 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2287                 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2288                 $cmd .= " $samba_tool drs kcc $env->{DC_SERVER}";
2289                 $cmd .= " $env->{CONFIGURATION}";
2290                 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2291                 unless (system($cmd) == 0) {
2292                         warn("Failed to exec kcc\n$cmd");
2293                         return undef;
2294                 }
2295
2296                 my $samba_tool =  Samba::bindir_path($self, "samba-tool");
2297                 my $cmd = "";
2298                 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2299                 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2300                 $cmd .= " $samba_tool drs kcc $env->{SERVER}";
2301                 $cmd .= " $env->{CONFIGURATION}";
2302                 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2303                 unless (system($cmd) == 0) {
2304                         warn("Failed to exec kcc\n$cmd");
2305                         return undef;
2306                 }
2307
2308                 # as 'vampired' dc may add data in its local replica
2309                 # we need to synchronize data between DCs
2310                 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2311                 $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2312                 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2313                 $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SERVER}";
2314                 $cmd .= " $dc_vars->{CONFIGURATION}";
2315                 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2316                 # replicate Configuration NC
2317                 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2318                 unless(system($cmd_repl) == 0) {
2319                         warn("Failed to replicate\n$cmd_repl");
2320                         return undef;
2321                 }
2322                 # replicate Default NC
2323                 $cmd_repl = "$cmd \"$base_dn\"";
2324                 unless(system($cmd_repl) == 0) {
2325                         warn("Failed to replicate\n$cmd_repl");
2326                         return undef;
2327                 }
2328         }
2329
2330         return $env;
2331 }
2332
2333 sub setup_subdom_dc($$$)
2334 {
2335         my ($self, $path, $dc_vars) = @_;
2336
2337         my $env = $self->provision_subdom_dc($path, $dc_vars);
2338
2339         if (defined $env) {
2340                 $self->check_or_start($env, "single");
2341
2342                 $self->wait_for_start($env);
2343
2344                 $self->{vars}->{subdom_dc} = $env;
2345
2346                 # force replicated DC to update repsTo/repsFrom
2347                 # for primary domain partitions
2348                 my $samba_tool =  Samba::bindir_path($self, "samba-tool");
2349                 my $cmd = "";
2350                 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2351                 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2352                 $cmd .= " $samba_tool drs kcc $env->{DC_SERVER}";
2353                 $cmd .= " $env->{CONFIGURATION}";
2354                 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD} --realm=$dc_vars->{DC_REALM}";
2355                 unless (system($cmd) == 0) {
2356                         warn("Failed to exec kcc\n$cmd");
2357                         return undef;
2358                 }
2359
2360                 # as 'subdomain' dc may add data in its local replica
2361                 # we need to synchronize data between DCs
2362                 my $base_dn = "DC=".join(",DC=", split(/\./, $env->{REALM}));
2363                 my $config_dn = "CN=Configuration,DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2364                 $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2365                 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2366                 $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SUBDOM_DC_SERVER}";
2367                 $cmd .= " $dc_vars->{CONFIGURATION}";
2368                 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD} --realm=$dc_vars->{DC_REALM}";
2369                 # replicate Configuration NC
2370                 my $cmd_repl = "$cmd \"$config_dn\"";
2371                 unless(system($cmd_repl) == 0) {
2372                         warn("Failed to replicate\n$cmd_repl");
2373                         return undef;
2374                 }
2375                 # replicate Default NC
2376                 $cmd_repl = "$cmd \"$base_dn\"";
2377                 unless(system($cmd_repl) == 0) {
2378                         warn("Failed to replicate\n$cmd_repl");
2379                         return undef;
2380                 }
2381         }
2382
2383         return $env;
2384 }
2385
2386 sub setup_rodc($$$)
2387 {
2388         my ($self, $path, $dc_vars) = @_;
2389
2390         my $env = $self->provision_rodc($path, $dc_vars);
2391
2392         unless ($env) {
2393                 return undef;
2394         }
2395
2396         $self->check_or_start($env, "single");
2397
2398         $self->wait_for_start($env);
2399
2400         # force source and replicated DC to update repsTo/repsFrom
2401         # for vampired partitions
2402         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
2403         my $cmd = "";
2404         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2405         $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2406         $cmd .= " $samba_tool drs kcc -k no $env->{DC_SERVER}";
2407         $cmd .= " $env->{CONFIGURATION}";
2408         $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2409         unless (system($cmd) == 0) {
2410             warn("Failed to exec kcc\n$cmd");
2411             return undef;
2412         }
2413
2414         my $samba_tool =  Samba::bindir_path($self, "samba-tool");
2415         my $cmd = "";
2416         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2417         $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2418         $cmd .= " $samba_tool drs kcc -k no $env->{SERVER}";
2419         $cmd .= " $env->{CONFIGURATION}";
2420         $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2421         unless (system($cmd) == 0) {
2422             warn("Failed to exec kcc\n$cmd");
2423             return undef;
2424         }
2425
2426         my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2427         $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2428         $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2429         $cmd .= " $samba_tool drs replicate $env->{SERVER} $env->{DC_SERVER}";
2430         $cmd .= " $dc_vars->{CONFIGURATION}";
2431         $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2432         # replicate Configuration NC
2433         my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2434         unless(system($cmd_repl) == 0) {
2435             warn("Failed to replicate\n$cmd_repl");
2436             return undef;
2437         }
2438         # replicate Default NC
2439         $cmd_repl = "$cmd \"$base_dn\"";
2440         unless(system($cmd_repl) == 0) {
2441             warn("Failed to replicate\n$cmd_repl");
2442             return undef;
2443         }
2444
2445         $self->{vars}->{rodc} = $env;
2446
2447         return $env;
2448 }
2449
2450 sub setup_ad_dc($$)
2451 {
2452         my ($self, $path, $no_nss) = @_;
2453
2454         # If we didn't build with ADS, pretend this env was never available
2455         if (not $self->{target3}->have_ads()) {
2456                return "UNKNOWN";
2457         }
2458
2459         my $env = $self->provision_ad_dc($path);
2460         unless ($env) {
2461                 return undef;
2462         }
2463
2464         if (defined($no_nss) and $no_nss) {
2465                 $env->{NSS_WRAPPER_MODULE_SO_PATH} = undef;
2466                 $env->{NSS_WRAPPER_MODULE_FN_PREFIX} = undef;
2467         }
2468
2469         $self->check_or_start($env, "single");
2470         
2471         $self->wait_for_start($env);
2472
2473         my $upn_array = ["$env->{REALM}.upn"];
2474         my $spn_array = ["$env->{REALM}.spn"];
2475
2476         $self->setup_namespaces($env, $upn_array, $spn_array);
2477
2478         $self->{vars}->{ad_dc} = $env;
2479         return $env;
2480 }
2481
2482 1;