07dcf3620654a5153d6b1d562b0d9c9a49a9e752
[metze/samba/wip.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
14 sub new($$$$$) {
15         my ($classname, $bindir, $ldap, $srcdir, $exeext) = @_;
16         $exeext = "" unless defined($exeext);
17         my $self = {
18                 vars => {},
19                 ldap => $ldap,
20                 bindir => $bindir,
21                 srcdir => $srcdir,
22                 exeext => $exeext
23         };
24         bless $self;
25         return $self;
26 }
27
28 sub bindir_path($$) {
29         my ($self, $path) = @_;
30
31         my $valpath = "$self->{bindir}/$path$self->{exeext}";
32
33         return $valpath if (-f $valpath);
34         return $path;
35 }
36
37 sub scriptdir_path($$) {
38         my ($self, $path) = @_;
39         return "$self->{srcdir}/source4/scripting/$path";
40 }
41
42 sub openldap_start($$$) {
43 }
44
45 sub slapd_start($$)
46 {
47         my $count = 0;
48         my ($self, $env_vars) = @_;
49         my $ldbsearch = $self->bindir_path("ldbsearch");
50
51         my $uri = $env_vars->{LDAP_URI};
52
53         if (system("$ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") == 0) {
54             print "A SLAPD is still listening to $uri before we started the LDAP backend.  Aborting!";
55             return 1;
56         }
57         # running slapd in the background means it stays in the same process group, so it can be
58         # killed by timelimit
59         if ($self->{ldap} eq "fedora-ds") {
60                 system("$ENV{FEDORA_DS_ROOT}/sbin/ns-slapd -D $env_vars->{FEDORA_DS_DIR} -d0 -i $env_vars->{FEDORA_DS_PIDFILE}> $env_vars->{LDAPDIR}/logs 2>&1 &");
61         } elsif ($self->{ldap} eq "openldap") {
62                 system("$ENV{OPENLDAP_SLAPD} -d0 -F $env_vars->{SLAPD_CONF_D} -h $uri > $env_vars->{LDAPDIR}/logs 2>&1 &");
63         }
64         while (system("$ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") != 0) {
65                 $count++;
66                 if ($count > 40) {
67                         $self->slapd_stop($env_vars);
68                         return 0;
69                 }
70                 sleep(1);
71         }
72         return 1;
73 }
74
75 sub slapd_stop($$)
76 {
77         my ($self, $envvars) = @_;
78         if ($self->{ldap} eq "fedora-ds") {
79                 system("$envvars->{LDAPDIR}/slapd-$envvars->{LDAP_INSTANCE}/stop-slapd");
80         } elsif ($self->{ldap} eq "openldap") {
81                 unless (open(IN, "<$envvars->{OPENLDAP_PIDFILE}")) {
82                         warn("unable to open slapd pid file: $envvars->{OPENLDAP_PIDFILE}");
83                         return 0;
84                 }
85                 kill 9, <IN>;
86                 close(IN);
87         }
88         return 1;
89 }
90
91 sub check_or_start($$$)
92 {
93         my ($self, $env_vars, $max_time) = @_;
94         return 0 if ( -p $env_vars->{SAMBA_TEST_FIFO});
95
96         unlink($env_vars->{SAMBA_TEST_FIFO});
97         POSIX::mkfifo($env_vars->{SAMBA_TEST_FIFO}, 0700);
98         unlink($env_vars->{SAMBA_TEST_LOG});
99         
100         my $pwd = `pwd`;
101         print "STARTING SAMBA for $ENV{ENVNAME}\n";
102         my $pid = fork();
103         if ($pid == 0) {
104                 open STDIN, $env_vars->{SAMBA_TEST_FIFO};
105                 # we want out from samba to go to the log file, but also
106                 # to the users terminal when running 'make test' on the command
107                 # line. This puts it on stderr on the terminal
108                 open STDOUT, "| tee $env_vars->{SAMBA_TEST_LOG} 1>&2";
109                 open STDERR, '>&STDOUT';
110
111                 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
112
113                 my $valgrind = "";
114                 if (defined($ENV{SAMBA_VALGRIND})) {
115                     $valgrind = $ENV{SAMBA_VALGRIND};
116                 }
117
118                 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
119                 $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
120
121                 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
122                 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
123
124                 $ENV{UID_WRAPPER} = "1";
125
126                 # Start slapd before samba, but with the fifo on stdin
127                 if (defined($self->{ldap})) {
128                         unless($self->slapd_start($env_vars)) {
129                                 warn("couldn't start slapd (main run)");
130                                 return undef;
131                         }
132                 }
133
134                 my $optarg = "";
135                 if (defined($max_time)) {
136                         $optarg = "--maximum-runtime=$max_time ";
137                 }
138                 if (defined($ENV{SAMBA_OPTIONS})) {
139                         $optarg.= " $ENV{SAMBA_OPTIONS}";
140                 }
141                 my $samba = $self->bindir_path("samba");
142
143                 # allow selection of the process model using
144                 # the environment varibale SAMBA_PROCESS_MODEL
145                 # that allows us to change the process model for
146                 # individual machines in the build farm
147                 my $model = "single";
148                 if (defined($ENV{SAMBA_PROCESS_MODEL})) {
149                         $model = $ENV{SAMBA_PROCESS_MODEL};
150                 }
151                 chomp($pwd);
152                 my $cmdline = "$valgrind ${pwd}/$samba $optarg $env_vars->{CONFIGURATION} -M $model -i";
153                 my $ret = system("$cmdline");
154                 if ($ret == -1) {
155                         print "Unable to start $cmdline: $ret: $!\n";
156                         exit 1;
157                 }
158                 my $exit = ($ret >> 8);
159                 unlink($env_vars->{SAMBA_TEST_FIFO});
160                 if ($ret == 0) {
161                         print "$samba exited with no error\n";
162                         exit 0;
163                 } elsif ( $ret & 127 ) {
164                         print "$samba got signal ".($ret & 127)." and exits with $exit!\n";
165                 } else {
166                         print "$samba failed with status $exit!\n";
167                 }
168                 if ($exit == 0) {
169                         $exit = -1;
170                 }
171                 exit $exit;
172         }
173         print "DONE\n";
174
175         open(DATA, ">$env_vars->{SAMBA_TEST_FIFO}");
176
177         return $pid;
178 }
179
180 sub wait_for_start($$)
181 {
182         my ($self, $testenv_vars) = @_;
183         # give time for nbt server to register its names
184         print "delaying for nbt name registration\n";
185         sleep 2;
186
187         # This will return quickly when things are up, but be slow if we
188         # need to wait for (eg) SSL init
189         my $nmblookup = $self->bindir_path("nmblookup");
190         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
191         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
192         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
193         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
194         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSALIAS}");
195         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSALIAS}");
196         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
197         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
198         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
199         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
200         system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSALIAS}");
201         system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSALIAS}");
202
203         print $self->getlog_env($testenv_vars);
204 }
205
206 sub write_ldb_file($$$)
207 {
208         my ($self, $file, $ldif) = @_;
209
210         my $ldbadd = $self->bindir_path("ldbadd");
211         open(LDIF, "|$ldbadd -H $file >/dev/null");
212         print LDIF $ldif;
213         return(close(LDIF));
214 }
215
216 sub add_wins_config($$)
217 {
218         my ($self, $privatedir) = @_;
219
220         return $self->write_ldb_file("$privatedir/wins_config.ldb", "
221 dn: name=TORTURE_11,CN=PARTNERS
222 objectClass: wreplPartner
223 name: TORTURE_11
224 address: 127.0.0.11
225 pullInterval: 0
226 pushChangeCount: 0
227 type: 0x3
228 ");
229 }
230
231 sub mk_fedora_ds($$)
232 {
233         my ($self, $ctx) = @_;
234
235         #Make the subdirectory be as fedora DS would expect
236         my $fedora_ds_dir = "$ctx->{ldapdir}/slapd-$ctx->{ldap_instance}";
237
238         my $pidfile = "$fedora_ds_dir/logs/slapd-$ctx->{ldap_instance}.pid";
239
240         return ($fedora_ds_dir, $pidfile);
241 }
242
243 sub mk_openldap($$)
244 {
245         my ($self, $ctx) = @_;
246
247         my $slapd_conf_d = "$ctx->{ldapdir}/slapd.d";
248         my $pidfile = "$ctx->{ldapdir}/slapd.pid";
249
250         return ($slapd_conf_d, $pidfile);
251 }
252
253 sub mk_keyblobs($$)
254 {
255         my ($self, $tlsdir) = @_;
256
257         #TLS and PKINIT crypto blobs
258         my $dhfile = "$tlsdir/dhparms.pem";
259         my $cafile = "$tlsdir/ca.pem";
260         my $certfile = "$tlsdir/cert.pem";
261         my $reqkdc = "$tlsdir/req-kdc.der";
262         my $kdccertfile = "$tlsdir/kdc.pem";
263         my $keyfile = "$tlsdir/key.pem";
264         my $adminkeyfile = "$tlsdir/adminkey.pem";
265         my $reqadmin = "$tlsdir/req-admin.der";
266         my $admincertfile = "$tlsdir/admincert.pem";
267         my $admincertupnfile = "$tlsdir/admincertupn.pem";
268
269         mkdir($tlsdir, 0777);
270
271         #This is specified here to avoid draining entropy on every run
272         open(DHFILE, ">$dhfile");
273         print DHFILE <<EOF;
274 -----BEGIN DH PARAMETERS-----
275 MGYCYQC/eWD2xkb7uELmqLi+ygPMKyVcpHUo2yCluwnbPutEueuxrG/Cys8j8wLO
276 svCN/jYNyR2NszOmg7ZWcOC/4z/4pWDVPUZr8qrkhj5MRKJc52MncfaDglvEdJrv
277 YX70obsCAQI=
278 -----END DH PARAMETERS-----
279 EOF
280         close(DHFILE);
281
282         #Likewise, we pregenerate the key material.  This allows the
283         #other certificates to be pre-generated
284         open(KEYFILE, ">$keyfile");
285         print KEYFILE <<EOF;
286 -----BEGIN RSA PRIVATE KEY-----
287 MIICXQIBAAKBgQDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpc
288 ol3+S9/6I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H
289 6H+pPqVIRLOmrWImai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQAB
290 AoGAAqDLzFRR/BF1kpsiUfL4WFvTarCe9duhwj7ORc6fs785qAXuwUYAJ0Uvzmy6
291 HqoGv3t3RfmeHDmjcpPHsbOKnsOQn2MgmthidQlPBMWtQMff5zdoYNUFiPS0XQBq
292 szNW4PRjaA9KkLQVTwnzdXGkBSkn/nGxkaVu7OR3vJOBoo0CQQDO4upypesnbe6p
293 9/xqfZ2uim8IwV1fLlFClV7WlCaER8tsQF4lEi0XSzRdXGUD/dilpY88Nb+xok/X
294 8Z8OvgAXAkEA+pcLsx1gN7kxnARxv54jdzQjC31uesJgMKQXjJ0h75aUZwTNHmZQ
295 vPxi6u62YiObrN5oivkixwFNncT9MxTxVQJBAMaWUm2SjlLe10UX4Zdm1MEB6OsC
296 kVoX37CGKO7YbtBzCfTzJGt5Mwc1DSLA2cYnGJqIfSFShptALlwedot0HikCQAJu
297 jNKEKnbf+TdGY8Q0SKvTebOW2Aeg80YFkaTvsXCdyXrmdQcifw4WdO9KucJiDhSz
298 Y9hVapz7ykEJtFtWjLECQQDIlfc63I5ZpXfg4/nN4IJXUW6AmPVOYIA5215itgki
299 cSlMYli1H9MEXH0pQMGv5Qyd0OYIx2DDg96mZ+aFvqSG
300 -----END RSA PRIVATE KEY-----
301 EOF
302         close(KEYFILE);
303
304         open(ADMINKEYFILE, ">$adminkeyfile");
305
306         print ADMINKEYFILE <<EOF;
307 -----BEGIN RSA PRIVATE KEY-----
308 MIICXQIBAAKBgQD0+OL7TQBj0RejbIH1+g5GeRaWaM9xF43uE5y7jUHEsi5owhZF
309 5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMFxB6esnXhl0Jpip1JkUMM
310 XLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xdl3JRlwIDAQAB
311 AoGAP8mjCP628Ebc2eACQzOWjgEvwYCPK4qPmYOf1zJkArzG2t5XAGJ5WGrENRuB
312 cm3XFh1lpmaADl982UdW3gul4gXUy6w4XjKK4vVfhyHj0kZ/LgaXUK9BAGhroJ2L
313 osIOUsaC6jdx9EwSRctwdlF3wWJ8NK0g28AkvIk+FlolW4ECQQD7w5ouCDnf58CN
314 u4nARx4xv5XJXekBvOomkCQAmuOsdOb6b9wn3mm2E3au9fueITjb3soMR31AF6O4
315 eAY126rXAkEA+RgHzybzZEP8jCuznMqoN2fq/Vrs6+W3M8/G9mzGEMgLLpaf2Jiz
316 I9tLZ0+OFk9tkRaoCHPfUOCrVWJZ7Y53QQJBAMhoA6rw0WDyUcyApD5yXg6rusf4
317 ASpo/tqDkqUIpoL464Qe1tjFqtBM3gSXuhs9xsz+o0bzATirmJ+WqxrkKTECQHt2
318 OLCpKqwAspU7N+w32kaUADoRLisCEdrhWklbwpQgwsIVsCaoEOpt0CLloJRYTANE
319 yoZeAErTALjyZYZEPcECQQDlUi0N8DFxQ/lOwWyR3Hailft+mPqoPCa8QHlQZnlG
320 +cfgNl57YHMTZFwgUVFRdJNpjH/WdZ5QxDcIVli0q+Ko
321 -----END RSA PRIVATE KEY-----
322 EOF
323
324         #generated with
325         # hxtool issue-certificate --self-signed --issue-ca \
326         # --ca-private-key="FILE:$KEYFILE" \
327         # --subject="CN=CA,DC=samba,DC=example,DC=com" \
328         # --certificate="FILE:$CAFILE" --lifetime="25 years"
329
330         open(CAFILE, ">$cafile");
331         print CAFILE <<EOF;
332 -----BEGIN CERTIFICATE-----
333 MIICcTCCAdqgAwIBAgIUaBPmjnPVqyFqR5foICmLmikJTzgwCwYJKoZIhvcNAQEFMFIxEzAR
334 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
335 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTIyMzEyWhgPMjAzMzAyMjQx
336 MjIzMTJaMFIxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
337 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMIGfMA0GCSqGSIb3DQEBAQUA
338 A4GNADCBiQKBgQDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpcol3+S9/6
339 I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H6H+pPqVIRLOmrWIm
340 ai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
341 AaYwHQYDVR0OBBYEFMLZufegDKLZs0VOyFXYK1L6M8oyMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
342 KoZIhvcNAQEFBQADgYEAAZJbCAAkaqgFJ0xgNovn8Ydd0KswQPjicwiODPgw9ZPoD2HiOUVO
343 yYDRg/dhFF9y656OpcHk4N7qZ2sl3RlHkzDu+dseETW+CnKvQIoXNyeARRJSsSlwrwcoD4JR
344 HTLk2sGigsWwrJ2N99sG/cqSJLJ1MFwLrs6koweBnYU0f/g=
345 -----END CERTIFICATE-----
346 EOF
347
348         #generated with GNUTLS internally in Samba.
349
350         open(CERTFILE, ">$certfile");
351         print CERTFILE <<EOF;
352 -----BEGIN CERTIFICATE-----
353 MIICYTCCAcygAwIBAgIE5M7SRDALBgkqhkiG9w0BAQUwZTEdMBsGA1UEChMUU2Ft
354 YmEgQWRtaW5pc3RyYXRpb24xNDAyBgNVBAsTK1NhbWJhIC0gdGVtcG9yYXJ5IGF1
355 dG9nZW5lcmF0ZWQgY2VydGlmaWNhdGUxDjAMBgNVBAMTBVNhbWJhMB4XDTA2MDgw
356 NDA0MzY1MloXDTA4MDcwNDA0MzY1MlowZTEdMBsGA1UEChMUU2FtYmEgQWRtaW5p
357 c3RyYXRpb24xNDAyBgNVBAsTK1NhbWJhIC0gdGVtcG9yYXJ5IGF1dG9nZW5lcmF0
358 ZWQgY2VydGlmaWNhdGUxDjAMBgNVBAMTBVNhbWJhMIGcMAsGCSqGSIb3DQEBAQOB
359 jAAwgYgCgYDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpcol3+
360 S9/6I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H6H+p
361 PqVIRLOmrWImai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQABoyUw
362 IzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGCSqGSIb3DQEB
363 BQOBgQAmkN6XxvDnoMkGcWLCTwzxGfNNSVcYr7TtL2aJh285Xw9zaxcm/SAZBFyG
364 LYOChvh6hPU7joMdDwGfbiLrBnMag+BtGlmPLWwp/Kt1wNmrRhduyTQFhN3PP6fz
365 nBr9vVny2FewB2gHmelaPS//tXdxivSXKz3NFqqXLDJjq7P8wA==
366 -----END CERTIFICATE-----
367 EOF
368         close(CERTFILE);
369
370         #KDC certificate
371         # hxtool request-create \
372         # --subject="CN=krbtgt,CN=users,DC=samba,DC=example,DC=com" \
373         # --key="FILE:$KEYFILE" $KDCREQ
374
375         # hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
376         # --type="pkinit-kdc" \
377         # --pk-init-principal="krbtgt/SAMBA.EXAMPLE.COM@SAMBA.EXAMPLE.COM" \
378         # --req="PKCS10:$KDCREQ" --certificate="FILE:$KDCCERTFILE" \
379         # --lifetime="25 years"
380
381         open(KDCCERTFILE, ">$kdccertfile");
382         print KDCCERTFILE <<EOF;
383 -----BEGIN CERTIFICATE-----
384 MIIDDDCCAnWgAwIBAgIUI2Tzj+JnMzMcdeabcNo30rovzFAwCwYJKoZIhvcNAQEFMFIxEzAR
385 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
386 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTMxOTIzWhgPMjAzMzAyMjQx
387 MzE5MjNaMGYxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
388 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMQ8wDQYDVQQDDAZrcmJ0
389 Z3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMqDqkDAIdQwDUN8cOZaFl934XQL70nF
390 yq+nD2KL0SfcTW5+WlyiXf5L3/oj+5pOYkdmt74MXd1PNv9Q5mjRl6bw34jPOSCgaQVp+Ne5
391 PcEvlQ9jb8fof6k+pUhEs6atYiZqLfn1jKgqEXKjftjoc95TxBxn67atL2B5qkhZ966jAgMB
392 AAGjgcgwgcUwDgYDVR0PAQH/BAQDAgWgMBIGA1UdJQQLMAkGBysGAQUCAwUwVAYDVR0RBE0w
393 S6BJBgYrBgEFAgKgPzA9oBMbEVNBTUJBLkVYQU1QTEUuQ09NoSYwJKADAgEBoR0wGxsGa3Ji
394 dGd0GxFTQU1CQS5FWEFNUExFLkNPTTAfBgNVHSMEGDAWgBTC2bn3oAyi2bNFTshV2CtS+jPK
395 MjAdBgNVHQ4EFgQUwtm596AMotmzRU7IVdgrUvozyjIwCQYDVR0TBAIwADANBgkqhkiG9w0B
396 AQUFAAOBgQBmrVD5MCmZjfHp1nEnHqTIh8r7lSmVtDx4s9MMjxm9oNrzbKXynvdhwQYFVarc
397 ge4yRRDXtSebErOl71zVJI9CVeQQpwcH+tA85oGA7oeFtO/S7ls581RUU6tGgyxV4veD+lJv
398 KPH5LevUtgD+q9H4LU4Sq5N3iFwBaeryB0g2wg==
399 -----END CERTIFICATE-----
400 EOF
401
402         # hxtool request-create \
403         # --subject="CN=Administrator,CN=users,DC=samba,DC=example,DC=com" \
404         # --key="FILE:$ADMINKEYFILE" $ADMINREQFILE
405
406         # hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
407         # --type="pkinit-client" \
408         # --pk-init-principal="administrator@SAMBA.EXAMPLE.COM" \
409         # --req="PKCS10:$ADMINREQFILE" --certificate="FILE:$ADMINCERTFILE" \
410         # --lifetime="25 years"
411         
412         open(ADMINCERTFILE, ">$admincertfile");
413         print ADMINCERTFILE <<EOF;
414 -----BEGIN CERTIFICATE-----
415 MIIDHTCCAoagAwIBAgIUUggzW4lLRkMKe1DAR2NKatkMDYwwCwYJKoZIhvcNAQELMFIxEzAR
416 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
417 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDkwNzI3MDMzMjE1WhgPMjAzNDA3MjIw
418 MzMyMTVaMG0xEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
419 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMRYwFAYDVQQDDA1BZG1p
420 bmlzdHJhdG9yMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0+OL7TQBj0RejbIH1+g5G
421 eRaWaM9xF43uE5y7jUHEsi5owhZF5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMF
422 xB6esnXhl0Jpip1JkUMMXLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xd
423 l3JRlwIDAQABo4HSMIHPMA4GA1UdDwEB/wQEAwIFoDAoBgNVHSUEITAfBgcrBgEFAgMEBggr
424 BgEFBQcDAgYKKwYBBAGCNxQCAjBIBgNVHREEQTA/oD0GBisGAQUCAqAzMDGgExsRU0FNQkEu
425 RVhBTVBMRS5DT02hGjAYoAMCAQGhETAPGw1BZG1pbmlzdHJhdG9yMB8GA1UdIwQYMBaAFMLZ
426 ufegDKLZs0VOyFXYK1L6M8oyMB0GA1UdDgQWBBQg81bLyfCA88C2B/BDjXlGuaFaxjAJBgNV
427 HRMEAjAAMA0GCSqGSIb3DQEBCwUAA4GBAEf/OSHUDJaGdtWGNuJeqcVYVMwrfBAc0OSwVhz1
428 7/xqKHWo8wIMPkYRtaRHKLNDsF8GkhQPCpVsa6mX/Nt7YQnNvwd+1SBP5E8GvwWw9ZzLJvma
429 nk2n89emuayLpVtp00PymrDLRBcNaRjFReQU8f0o509kiVPHduAp3jOiy13l
430 -----END CERTIFICATE-----
431 EOF
432         close(ADMINCERTFILE);
433
434         # hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
435         # --type="pkinit-client" \
436         # --ms-upn="administrator@samba.example.com" \
437         # --req="PKCS10:$ADMINREQFILE" --certificate="FILE:$ADMINCERTUPNFILE" \
438         # --lifetime="25 years"
439         
440         open(ADMINCERTUPNFILE, ">$admincertupnfile");
441         print ADMINCERTUPNFILE <<EOF;
442 -----BEGIN CERTIFICATE-----
443 MIIDDzCCAnigAwIBAgIUUp3CJMuNaEaAdPKp3QdNIwG7a4wwCwYJKoZIhvcNAQELMFIxEzAR
444 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
445 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDkwNzI3MDMzMzA1WhgPMjAzNDA3MjIw
446 MzMzMDVaMG0xEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
447 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMRYwFAYDVQQDDA1BZG1p
448 bmlzdHJhdG9yMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0+OL7TQBj0RejbIH1+g5G
449 eRaWaM9xF43uE5y7jUHEsi5owhZF5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMF
450 xB6esnXhl0Jpip1JkUMMXLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xd
451 l3JRlwIDAQABo4HEMIHBMA4GA1UdDwEB/wQEAwIFoDAoBgNVHSUEITAfBgcrBgEFAgMEBggr
452 BgEFBQcDAgYKKwYBBAGCNxQCAjA6BgNVHREEMzAxoC8GCisGAQQBgjcUAgOgIQwfYWRtaW5p
453 c3RyYXRvckBzYW1iYS5leGFtcGxlLmNvbTAfBgNVHSMEGDAWgBTC2bn3oAyi2bNFTshV2CtS
454 +jPKMjAdBgNVHQ4EFgQUIPNWy8nwgPPAtgfwQ415RrmhWsYwCQYDVR0TBAIwADANBgkqhkiG
455 9w0BAQsFAAOBgQBk42+egeUB3Ji2PC55fbt3FNKxvmm2xUUFkV9POK/YR9rajKOwk5jtYSeS
456 Zd7J9s//rNFNa7waklFkDaY56+QWTFtdvxfE+KoHaqt6X8u6pqi7p3M4wDKQox+9Dx8yWFyq
457 Wfz/8alZ5aMezCQzXJyIaJsCLeKABosSwHcpAFmxlQ==
458 -----END CERTIFICATE-----
459 EOF
460 }
461
462 sub mk_krb5_conf($$)
463 {
464         my ($self, $ctx) = @_;
465
466         unless (open(KRB5CONF, ">$ctx->{krb5_conf}")) {
467                 warn("can't open $ctx->{krb5_conf}$?");
468                 return undef;
469         }
470         print KRB5CONF "
471 #Generated krb5.conf for $ctx->{realm}
472
473 [libdefaults]
474  default_realm = $ctx->{realm}
475  dns_lookup_realm = false
476  dns_lookup_kdc = false
477  ticket_lifetime = 24h
478  forwardable = yes
479  allow_weak_crypto = yes
480
481 [realms]
482  $ctx->{realm} = {
483   kdc = $ctx->{kdc_ipv4}:88
484   admin_server = $ctx->{kdc_ipv4}:88
485   default_domain = $ctx->{dnsname}
486  }
487  $ctx->{dnsname} = {
488   kdc = $ctx->{kdc_ipv4}:88
489   admin_server = $ctx->{kdc_ipv4}:88
490   default_domain = $ctx->{dnsname}
491  }
492  $ctx->{domain} = {
493   kdc = $ctx->{kdc_ipv4}:88
494   admin_server = $ctx->{kdc_ipv4}:88
495   default_domain = $ctx->{dnsname}
496  }
497
498 [appdefaults]
499         pkinit_anchors = FILE:$ctx->{tlsdir}/ca.pem
500
501 [kdc]
502         enable-pkinit = true
503         pkinit_identity = FILE:$ctx->{tlsdir}/kdc.pem,$ctx->{tlsdir}/key.pem
504         pkinit_anchors = FILE:$ctx->{tlsdir}/ca.pem
505
506 [domain_realm]
507  .$ctx->{dnsname} = $ctx->{realm}
508 ";
509         close(KRB5CONF);
510 }
511
512 sub provision_raw_prepare($$$$$$$$$$)
513 {
514         my ($self, $prefix, $server_role, $netbiosname, $netbiosalias,
515             $domain, $realm, $functional_level,
516             $swiface, $password, $kdc_ipv4) = @_;
517         my $ctx;
518
519         unless(-d $prefix or mkdir($prefix, 0777)) {
520                 warn("Unable to create $prefix");
521                 return undef;
522         }
523         my $prefix_abs = abs_path($prefix);
524
525         die ("prefix=''") if $prefix_abs eq "";
526         die ("prefix='/'") if $prefix_abs eq "/";
527
528         unless (system("rm -rf $prefix_abs/*") == 0) {
529                 warn("Unable to clean up");
530         }
531
532         $ctx->{prefix} = $prefix;
533         $ctx->{prefix_abs} = $prefix_abs;
534         
535         $ctx->{dns_host_file} = "$ENV{SELFTEST_PREFIX}/dns_host_file";
536
537         $ctx->{server_role} = $server_role;
538         $ctx->{netbiosname} = $netbiosname;
539         $ctx->{netbiosalias} = $netbiosalias;
540         $ctx->{swiface} = $swiface;
541         $ctx->{password} = $password;
542         $ctx->{kdc_ipv4} = $kdc_ipv4;
543
544         $ctx->{server_loglevel} =$ENV{SERVER_LOG_LEVEL} || 1;
545         $ctx->{username} = "Administrator";
546         $ctx->{domain} = $domain;
547         $ctx->{realm} = uc($realm);
548         $ctx->{dnsname} = lc($realm);
549         $ctx->{sid_generator} = "internal";
550
551         $ctx->{functional_level} = $functional_level;
552
553         my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `whoami`);
554         chomp $unix_name;
555         $ctx->{unix_name} = $unix_name;
556         $ctx->{unix_uid} = $>;
557         $ctx->{unix_gids_str} = $);
558         @{$ctx->{unix_gids}} = split(" ", $ctx->{unix_gids_str});
559
560         $ctx->{etcdir} = "$prefix_abs/etc";
561         $ctx->{piddir} = "$prefix_abs/pid";
562         $ctx->{smb_conf} = "$ctx->{etcdir}/smb.conf";
563         $ctx->{krb5_conf} = "$ctx->{etcdir}/krb5.conf";
564         $ctx->{privatedir} = "$prefix_abs/private";
565         $ctx->{ncalrpcdir} = "$prefix_abs/ncalrpc";
566         $ctx->{lockdir} = "$prefix_abs/lockdir";
567         $ctx->{winbindd_socket_dir} = "$prefix_abs/winbindd_socket";
568         $ctx->{winbindd_privileged_socket_dir} = "$prefix_abs/winbindd_privileged_socket";
569         $ctx->{ntp_signd_socket_dir} = "$prefix_abs/ntp_signd_socket";
570         $ctx->{nsswrap_passwd} = "$ctx->{etcdir}/passwd";
571         $ctx->{nsswrap_group} = "$ctx->{etcdir}/group";
572
573         $ctx->{tlsdir} = "$ctx->{privatedir}/tls";
574
575         $ctx->{ipv4} = "127.0.0.$swiface";
576         $ctx->{interfaces} = "$ctx->{ipv4}/8";
577
578         push(@{$ctx->{directories}}, $ctx->{privatedir});
579         push(@{$ctx->{directories}}, $ctx->{etcdir});
580         push(@{$ctx->{directories}}, $ctx->{piddir});
581         push(@{$ctx->{directories}}, $ctx->{ncalrpcdir});
582         push(@{$ctx->{directories}}, $ctx->{lockdir});
583
584         $ctx->{smb_conf_extra_options} = "";
585
586         my @provision_options = ();
587         push (@provision_options, "NSS_WRAPPER_PASSWD=\"$ctx->{nsswrap_passwd}\"");
588         push (@provision_options, "NSS_WRAPPER_GROUP=\"$ctx->{nsswrap_group}\"");
589         if (defined($ENV{GDB_PROVISION})) {
590                 push (@provision_options, "gdb --args");
591                 if (!defined($ENV{PYTHON})) {
592                     push (@provision_options, "env");
593                     push (@provision_options, "python");
594                 }
595         }
596         if (defined($ENV{VALGRIND_PROVISION})) {
597                 push (@provision_options, "valgrind");
598                 if (!defined($ENV{PYTHON})) {
599                     push (@provision_options, "env");
600                     push (@provision_options, "python");
601                 }
602         }
603         if (defined($ENV{PYTHON})) {
604                 push (@provision_options, $ENV{PYTHON});
605         }
606         push (@provision_options, "$self->{srcdir}/source4/setup/provision");
607         push (@provision_options, "--configfile=$ctx->{smb_conf}");
608         push (@provision_options, "--host-name=$ctx->{netbiosname}");
609         push (@provision_options, "--host-ip=$ctx->{ipv4}");
610         push (@provision_options, "--quiet");
611         push (@provision_options, "--domain=$ctx->{domain}");
612         push (@provision_options, "--realm=$ctx->{realm}");
613         push (@provision_options, "--adminpass=$ctx->{password}");
614         push (@provision_options, "--krbtgtpass=krbtgt$ctx->{password}");
615         push (@provision_options, "--machinepass=machine$ctx->{password}");
616         push (@provision_options, "--root=$ctx->{unix_name}");
617         push (@provision_options, "--server-role=\"$ctx->{server_role}\"");
618         push (@provision_options, "--function-level=\"$ctx->{functional_level}\"");
619
620         @{$ctx->{provision_options}} = @provision_options;
621
622         return $ctx;
623 }
624
625 #
626 # Step1 creates the basic configuration
627 #
628 sub provision_raw_step1($$)
629 {
630         my ($self, $ctx) = @_;
631
632         mkdir($_, 0777) foreach (@{$ctx->{directories}});
633
634         unless (open(CONFFILE, ">$ctx->{smb_conf}")) {
635                 warn("can't open $ctx->{smb_conf}$?");
636                 return undef;
637         }
638         print CONFFILE "
639 [global]
640         netbios name = $ctx->{netbiosname}
641         netbios aliases = $ctx->{netbiosalias}
642         posix:eadb = $ctx->{lockdir}/eadb.tdb
643         workgroup = $ctx->{domain}
644         realm = $ctx->{realm}
645         private dir = $ctx->{privatedir}
646         pid directory = $ctx->{piddir}
647         ncalrpc dir = $ctx->{ncalrpcdir}
648         lock dir = $ctx->{lockdir}
649         winbindd socket directory = $ctx->{winbindd_socket_dir}
650         winbindd privileged socket directory = $ctx->{winbindd_privileged_socket_dir}
651         ntp signd socket directory = $ctx->{ntp_signd_socket_dir}
652         winbind separator = /
653         name resolve order = file bcast
654         interfaces = $ctx->{interfaces}
655         tls dh params file = $ctx->{tlsdir}/dhparms.pem
656         panic action = $RealBin/gdb_backtrace \%PID% \%PROG%
657         wins support = yes
658         server role = $ctx->{server_role}
659         server services = +echo
660         notify:inotify = false
661         ldb:nosync = true
662 #We don't want to pass our self-tests if the PAC code is wrong
663         gensec:require_pac = true
664         log level = $ctx->{server_loglevel}
665         lanman auth = Yes
666         rndc command = true
667         dns update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate --all-interfaces --use-file=$ctx->{dns_host_file}
668         spn update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_spnupdate
669         resolv:host file = $ctx->{dns_host_file}
670         dreplsrv:periodic_startup_interval = 0
671 ";
672
673         if (defined($ctx->{sid_generator}) && $ctx->{sid_generator} ne "internal") {
674                 print CONFFILE "
675         sid generator = $ctx->{sid_generator}";
676         }
677
678         print CONFFILE "
679
680         # Begin extra options
681         $ctx->{smb_conf_extra_options}
682         # End extra options
683 ";
684         close(CONFFILE);
685
686         $self->mk_keyblobs($ctx->{tlsdir});
687
688         $self->mk_krb5_conf($ctx);
689
690         open(PWD, ">$ctx->{nsswrap_passwd}");
691         print PWD "
692 root:x:0:0:root gecos:$ctx->{prefix_abs}:/bin/false
693 $ctx->{unix_name}:x:$ctx->{unix_uid}:@{$ctx->{unix_gids}}[0]:$ctx->{unix_name} gecos:$ctx->{prefix_abs}:/bin/false
694 nobody:x:65534:65533:nobody gecos:$ctx->{prefix_abs}:/bin/false
695 ";
696         close(PWD);
697
698         open(GRP, ">$ctx->{nsswrap_group}");
699         print GRP "
700 root:x:0:
701 wheel:x:10:
702 users:x:100:
703 nobody:x:65533:
704 nogroup:x:65534:nobody
705 ";
706         close(GRP);
707
708         my $configuration = "--configfile=$ctx->{smb_conf}";
709
710 #Ensure the config file is valid before we start
711         my $testparm = $self->scriptdir_path("bin/testparm");
712         if (system("$testparm $configuration -v --suppress-prompt >/dev/null 2>&1") != 0) {
713                 system("$testparm -v --suppress-prompt $configuration >&2");
714                 warn("Failed to create a valid smb.conf configuration $testparm!");
715                 return undef;
716         }
717         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) {
718                 warn("Failed to create a valid smb.conf configuration! $testparm $configuration -v --suppress-prompt --parameter-name=\"netbios name\" --section-name=global");
719                 return undef;
720         }
721
722         my $ret = {
723                 KRB5_CONFIG => $ctx->{krb5_conf},
724                 PIDDIR => $ctx->{piddir},
725                 SERVER => $ctx->{netbiosname},
726                 SERVER_IP => $ctx->{ipv4},
727                 NETBIOSNAME => $ctx->{netbiosname},
728                 NETBIOSALIAS => $ctx->{netbiosalias},
729                 DOMAIN => $ctx->{domain},
730                 USERNAME => $ctx->{username},
731                 REALM => $ctx->{realm},
732                 PASSWORD => $ctx->{password},
733                 LDAPDIR => $ctx->{ldapdir},
734                 LDAP_INSTANCE => $ctx->{ldap_instance},
735                 WINBINDD_SOCKET_DIR => $ctx->{winbindd_socket_dir},
736                 NCALRPCDIR => $ctx->{ncalrpcdir},
737                 LOCKDIR => $ctx->{lockdir},
738                 SERVERCONFFILE => $ctx->{smb_conf},
739                 CONFIGURATION => $configuration,
740                 SOCKET_WRAPPER_DEFAULT_IFACE => $ctx->{swiface},
741                 NSS_WRAPPER_PASSWD => $ctx->{nsswrap_passwd},
742                 NSS_WRAPPER_GROUP => $ctx->{nsswrap_group},
743                 SAMBA_TEST_FIFO => "$ctx->{prefix}/samba_test.fifo",
744                 SAMBA_TEST_LOG => "$ctx->{prefix}/samba_test.log",
745                 SAMBA_TEST_LOG_POS => 0,
746         };
747
748         return $ret;
749 }
750
751 #
752 # Step2 runs the provision script
753 #
754 sub provision_raw_step2($$$)
755 {
756         my ($self, $ctx, $ret) = @_;
757
758         my $provision_cmd = join(" ", @{$ctx->{provision_options}});
759         unless (system($provision_cmd) == 0) {
760                 warn("Unable to provision: \n$provision_cmd\n");
761                 return undef;
762         }
763
764         return $ret;
765 }
766
767 sub provision($$$$$$$$$)
768 {
769         my ($self, $prefix, $server_role, $netbiosname, $netbiosalias,
770             $domain, $realm, $functional_level,
771             $swiface, $password, $kdc_ipv4, $extra_smbconf_options) = @_;
772
773         my $ctx = $self->provision_raw_prepare($prefix, $server_role,
774                                                $netbiosname, $netbiosalias,
775                                                $domain, $realm, $functional_level,
776                                                $swiface, $password, $kdc_ipv4);
777
778         $ctx->{tmpdir} = "$ctx->{prefix_abs}/tmp";
779         push(@{$ctx->{directories}}, "$ctx->{tmpdir}");
780         push(@{$ctx->{directories}}, "$ctx->{tmpdir}/test1");
781         push(@{$ctx->{directories}}, "$ctx->{tmpdir}/test2");
782         my $msdfs = "no";
783         $msdfs = "yes" if ($server_role eq "domain controller");
784         $ctx->{smb_conf_extra_options} = "
785
786         max xmit = 32K
787         server max protocol = SMB2
788         $extra_smbconf_options
789         host msdfs = $msdfs
790         lanman auth = yes
791
792 [tmp]
793         path = $ctx->{tmpdir}
794         read only = no
795         posix:sharedelay = 10000
796         posix:oplocktimeout = 3
797         posix:writetimeupdatedelay = 500000
798
799 [test1]
800         path = $ctx->{tmpdir}/test1
801         read only = no
802         posix:sharedelay = 10000
803         posix:oplocktimeout = 3
804         posix:writetimeupdatedelay = 50000
805
806 [test2]
807         path = $ctx->{tmpdir}/test2
808         read only = no
809         posix:sharedelay = 10000
810         posix:oplocktimeout = 3
811         posix:writetimeupdatedelay = 50000
812
813 [cifs]
814         read only = no
815         ntvfs handler = cifs
816         cifs:server = $ctx->{netbiosname}
817         cifs:share = tmp
818 #There is no username specified here, instead the client is expected
819 #to log in with kerberos, and the serverwill use delegated credentials.
820
821 [simple]
822         path = $ctx->{tmpdir}
823         read only = no
824         ntvfs handler = simple
825
826 [sysvol]
827         path = $ctx->{lockdir}/sysvol
828         read only = yes
829
830 [netlogon]
831         path = $ctx->{lockdir}/sysvol/$ctx->{dnsname}/scripts
832         read only = no
833
834 [cifsposix]
835         copy = simple
836         ntvfs handler = cifsposix
837 ";
838
839         if (defined($self->{ldap})) {
840                 $ctx->{ldapdir} = "$ctx->{privatedir}/ldap";
841                 push(@{$ctx->{directories}}, "$ctx->{ldapdir}");
842
843                 my $ldap_uri= "$ctx->{ldapdir}/ldapi";
844                 $ldap_uri =~ s|/|%2F|g;
845                 $ldap_uri = "ldapi://$ldap_uri";
846                 $ctx->{ldap_uri} = $ldap_uri;
847                 if ($self->{ldap} eq "fedora-ds") {
848                         $ctx->{sid_generator} = "backend";
849                 }
850
851                 $ctx->{ldap_instance} = lc($ctx->{netbiosname});
852         }
853
854         my $ret = $self->provision_raw_step1($ctx);
855         unless (defined $ret) {
856                 return undef;
857         }
858
859         if (defined($self->{ldap})) {
860                 $ret->{LDAP_URI} = $ctx->{ldap_uri};
861                 push (@{$ctx->{provision_options}}, "--ldap-backend-type=" . $self->{ldap});
862                 push (@{$ctx->{provision_options}}, "--ldap-backend-nosync");
863                 if ($self->{ldap} eq "openldap") {
864                         push (@{$ctx->{provision_options}}, "--slapd-path=" . $ENV{OPENLDAP_SLAPD});
865                         ($ret->{SLAPD_CONF_D}, $ret->{OPENLDAP_PIDFILE}) = $self->mk_openldap($ctx) or die("Unable to create openldap directories");
866
867                 } elsif ($self->{ldap} eq "fedora-ds") {
868                         push (@{$ctx->{provision_options}}, "--slapd-path=" . "$ENV{FEDORA_DS_ROOT}/sbin/ns-slapd");
869                         push (@{$ctx->{provision_options}}, "--setup-ds-path=" . "$ENV{FEDORA_DS_ROOT}/sbin/setup-ds.pl");
870                         ($ret->{FEDORA_DS_DIR}, $ret->{FEDORA_DS_PIDFILE}) = $self->mk_fedora_ds($ctx) or die("Unable to create fedora ds directories");
871                 }
872
873         }
874
875         return $self->provision_raw_step2($ctx, $ret);
876 }
877
878 sub provision_member($$$)
879 {
880         my ($self, $prefix, $dcvars) = @_;
881         print "PROVISIONING MEMBER...";
882
883         my $ret = $self->provision($prefix,
884                                    "member server",
885                                    "localmember",
886                                    "member3",
887                                    "SAMBADOMAIN",
888                                    "samba.example.com",
889                                    "2008",
890                                    3,
891                                    "locMEMpass3",
892                                    $dcvars->{SERVER_IP},
893                                    "");
894         unless ($ret) {
895                 return undef;
896         }
897
898         my $samba_tool = $self->bindir_path("samba-tool");
899         my $cmd = "";
900         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
901         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
902         $cmd .= "$samba_tool join $ret->{CONFIGURATION} $dcvars->{REALM} member";
903         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
904
905         unless (system($cmd) == 0) {
906                 warn("Join failed\n$cmd");
907                 return undef;
908         }
909
910         $ret->{MEMBER_SERVER} = $ret->{SERVER};
911         $ret->{MEMBER_SERVER_IP} = $ret->{SERVER_IP};
912         $ret->{MEMBER_NETBIOSNAME} = $ret->{NETBIOSNAME};
913         $ret->{MEMBER_NETBIOSALIAS} = $ret->{NETBIOSALIAS};
914         $ret->{MEMBER_USERNAME} = $ret->{USERNAME};
915         $ret->{MEMBER_PASSWORD} = $ret->{PASSWORD};
916
917         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
918         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
919         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
920         $ret->{DC_NETBIOSALIAS} = $dcvars->{DC_NETBIOSALIAS};
921         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
922         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
923
924         return $ret;
925 }
926
927 sub provision_rpc_proxy($$$)
928 {
929         my ($self, $prefix, $dcvars) = @_;
930         print "PROVISIONING RPC PROXY...";
931
932         my $extra_smbconf_options = "dcerpc_remote:binding = ncacn_ip_tcp:localdc
933        dcerpc endpoint servers = epmapper, remote
934        dcerpc_remote:interfaces = rpcecho
935 ";
936
937         my $ret = $self->provision($prefix,
938                                    "member server",
939                                    "localrpcproxy",
940                                    "rpcproxy4",
941                                    "SAMBADOMAIN",
942                                    "samba.example.com",
943                                    "2008",
944                                    4,
945                                    "locRPCproxypass4",
946                                    $dcvars->{SERVER_IP},
947                                    $extra_smbconf_options);
948
949         unless ($ret) {
950                 return undef;
951         }
952
953         my $samba_tool = $self->bindir_path("samba-tool");
954         my $cmd = "";
955         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
956         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
957         $cmd .= "$samba_tool join $ret->{CONFIGURATION} $dcvars->{REALM} member";
958         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
959
960         unless (system($cmd) == 0) {
961                 warn("Join failed\n$cmd");
962                 return undef;
963         }
964
965         $ret->{RPC_PROXY_SERVER} = $ret->{SERVER};
966         $ret->{RPC_PROXY_SERVER_IP} = $ret->{SERVER_IP};
967         $ret->{RPC_PROXY_NETBIOSNAME} = $ret->{NETBIOSNAME};
968         $ret->{RPC_PROXY_NETBIOSALIAS} = $ret->{NETBIOSALIAS};
969         $ret->{RPC_PROXY_USERNAME} = $ret->{USERNAME};
970         $ret->{RPC_PROXY_PASSWORD} = $ret->{PASSWORD};
971
972         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
973         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
974         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
975         $ret->{DC_NETBIOSALIAS} = $dcvars->{DC_NETBIOSALIAS};
976         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
977         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
978
979         return $ret;
980 }
981
982 sub provision_vampire_dc($$$)
983 {
984         my ($self, $prefix, $dcvars) = @_;
985         print "PROVISIONING VAMPIRE DC...";
986
987         # We do this so that we don't run the provision.  That's the job of 'net vampire'.
988         my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
989                                                "localvampiredc",
990                                                "dc2",
991                                                "SAMBADOMAIN",
992                                                "samba.example.com",
993                                                "2008",
994                                                2, $dcvars->{PASSWORD},
995                                                $dcvars->{SERVER_IP});
996
997         $ctx->{smb_conf_extra_options} = "
998         max xmit = 32K
999         server max protocol = SMB2
1000
1001 [sysvol]
1002         path = $ctx->{lockdir}/sysvol
1003         read only = yes
1004
1005 [netlogon]
1006         path = $ctx->{lockdir}/sysvol/$ctx->{dnsname}/scripts
1007         read only = no
1008
1009 ";
1010
1011         my $ret = $self->provision_raw_step1($ctx);
1012         unless ($ret) {
1013                 return undef;
1014         }
1015
1016         my $samba_tool = $self->bindir_path("samba-tool");
1017         my $cmd = "";
1018         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1019         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1020         $cmd .= "$samba_tool join $ret->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
1021         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1022
1023         unless (system($cmd) == 0) {
1024                 warn("Join failed\n$cmd");
1025                 return undef;
1026         }
1027
1028         $ret->{VAMPIRE_DC_SERVER} = $ret->{SERVER};
1029         $ret->{VAMPIRE_DC_SERVER_IP} = $ret->{SERVER_IP};
1030         $ret->{VAMPIRE_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1031         $ret->{VAMPIRE_DC_NETBIOSALIAS} = $ret->{NETBIOSALIAS};
1032
1033         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1034         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1035         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1036         $ret->{DC_NETBIOSALIAS} = $dcvars->{DC_NETBIOSALIAS};
1037         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1038         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1039
1040         return $ret;
1041 }
1042
1043 sub provision_dc($$)
1044 {
1045         my ($self, $prefix) = @_;
1046
1047         print "PROVISIONING DC...";
1048         my $ret = $self->provision($prefix,
1049                                    "domain controller",
1050                                    "localdc",
1051                                    "dc1",
1052                                    "SAMBADOMAIN",
1053                                    "samba.example.com",
1054                                    "2008",
1055                                    1,
1056                                    "locDCpass1",
1057                                    "127.0.0.1", "");
1058
1059         return undef unless(defined $ret);
1060         unless($self->add_wins_config("$prefix/private")) {
1061                 warn("Unable to add wins configuration");
1062                 return undef;
1063         }
1064
1065         $ret->{DC_SERVER} = $ret->{SERVER};
1066         $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1067         $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1068         $ret->{DC_NETBIOSALIAS} = $ret->{NETBIOSALIAS};
1069         $ret->{DC_USERNAME} = $ret->{USERNAME};
1070         $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1071
1072         return $ret;
1073 }
1074
1075 sub provision_fl2000dc($$)
1076 {
1077         my ($self, $prefix) = @_;
1078
1079         print "PROVISIONING DC...";
1080         my $ret = $self->provision($prefix,
1081                                    "domain controller",
1082                                    "dc5",
1083                                    "localfl2000dc",
1084                                    "SAMBA2000",
1085                                    "samba2000.example.com",
1086                                    "2000",
1087                                    5,
1088                                    "locDCpass5",
1089                                    "127.0.0.5", "");
1090
1091         unless($self->add_wins_config("$prefix/private")) {
1092                 warn("Unable to add wins configuration");
1093                 return undef;
1094         }
1095
1096         return $ret;
1097 }
1098
1099 sub provision_fl2003dc($$)
1100 {
1101         my ($self, $prefix) = @_;
1102
1103         print "PROVISIONING DC...";
1104         my $ret = $self->provision($prefix,
1105                                    "domain controller",
1106                                    "dc6",
1107                                    "localfl2003dc",
1108                                    "SAMBA2003",
1109                                    "samba2003.example.com",
1110                                    "2003",
1111                                    6,
1112                                    "locDCpass6",
1113                                    "127.0.0.6", "");
1114
1115         unless($self->add_wins_config("$prefix/private")) {
1116                 warn("Unable to add wins configuration");
1117                 return undef;
1118         }
1119
1120         return $ret;
1121 }
1122
1123 sub provision_fl2008r2dc($$)
1124 {
1125         my ($self, $prefix) = @_;
1126
1127         print "PROVISIONING DC...";
1128         my $ret = $self->provision($prefix,
1129                                    "domain controller",
1130                                    "dc7",
1131                                    "localfl2000r2dc",
1132                                    "SAMBA2008R2",
1133                                    "samba2008R2.example.com",
1134                                    "2008_R2",
1135                                    7,
1136                                    "locDCpass7",
1137                                    "127.0.0.7", "");
1138
1139         unless ($self->add_wins_config("$prefix/private")) {
1140                 warn("Unable to add wins configuration");
1141                 return undef;
1142         }
1143
1144         return $ret;
1145 }
1146
1147
1148 sub provision_rodc($$$)
1149 {
1150         my ($self, $prefix, $dcvars) = @_;
1151         print "PROVISIONING RODC...";
1152
1153         # We do this so that we don't run the provision.  That's the job of 'net join RODC'.
1154         my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1155                                                "rodc",
1156                                                "dc8",
1157                                                "SAMBADOMAIN",
1158                                                "samba.example.com",
1159                                                "2008",
1160                                                8, $dcvars->{PASSWORD},
1161                                                $dcvars->{SERVER_IP});
1162         unless ($ctx) {
1163                 return undef;
1164         }
1165
1166         $ctx->{tmpdir} = "$ctx->{prefix_abs}/tmp";
1167         push(@{$ctx->{directories}}, "$ctx->{tmpdir}");
1168
1169         $ctx->{smb_conf_extra_options} = "
1170         max xmit = 32K
1171         server max protocol = SMB2
1172
1173 [sysvol]
1174         path = $ctx->{lockdir}/sysvol
1175         read only = yes
1176
1177 [netlogon]
1178         path = $ctx->{lockdir}/sysvol/$ctx->{dnsname}/scripts
1179         read only = yes
1180
1181 [tmp]
1182         path = $ctx->{tmpdir}
1183         read only = no
1184         posix:sharedelay = 10000
1185         posix:oplocktimeout = 3
1186         posix:writetimeupdatedelay = 500000
1187
1188 ";
1189
1190         my $ret = $self->provision_raw_step1($ctx);
1191         unless ($ret) {
1192                 return undef;
1193         }
1194
1195         my $samba_tool = $self->bindir_path("samba-tool");
1196         my $cmd = "";
1197         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1198         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1199         $cmd .= "$samba_tool join $ret->{CONFIGURATION} $dcvars->{REALM} RODC";
1200         $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1201         $cmd .= " --server=$dcvars->{DC_SERVER}";
1202
1203         unless (system($cmd) == 0) {
1204                 warn("RODC join failed\n$cmd");
1205                 return undef;
1206         }
1207
1208         # we overwrite the kdc after the RODC join
1209         # so that use the RODC as kdc and test
1210         # the proxy code
1211         $ctx->{kdc_ipv4} = $ret->{SERVER_IP};
1212         $self->mk_krb5_conf($ctx);
1213
1214         $ret->{RODC_DC_SERVER} = $ret->{SERVER};
1215         $ret->{RODC_DC_SERVER_IP} = $ret->{SERVER_IP};
1216         $ret->{RODC_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1217         $ret->{RODC_DC_NETBIOSALIAS} = $ret->{NETBIOSALIAS};
1218
1219         $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1220         $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1221         $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1222         $ret->{DC_NETBIOSALIAS} = $dcvars->{DC_NETBIOSALIAS};
1223         $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1224         $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1225
1226         return $ret;
1227 }
1228
1229 sub teardown_env($$)
1230 {
1231         my ($self, $envvars) = @_;
1232         my $pid;
1233
1234         close(DATA);
1235
1236         if (open(IN, "<$envvars->{PIDDIR}/samba.pid")) {
1237                 $pid = <IN>;
1238                 close(IN);
1239
1240                 # Give the process 20 seconds to exit.  gcov needs
1241                 # this time to write out the covarge data
1242                 my $count = 0;
1243                 until (kill(0, $pid) == 0) {
1244                         # if no process sucessfully signalled, then we are done
1245                         sleep(1);
1246                         $count++;
1247                         last if $count > 20;
1248                 }
1249
1250                 # If it is still around, kill it
1251                 if ($count > 20) {
1252                         print "server process $pid took more than $count seconds to exit, killing\n";
1253                         kill 9, $pid;
1254                 }
1255         }
1256
1257         my $failed = $? >> 8;
1258
1259         $self->slapd_stop($envvars) if ($self->{ldap});
1260
1261         print $self->getlog_env($envvars);
1262
1263         return $failed;
1264 }
1265
1266 sub getlog_env($$)
1267 {
1268         my ($self, $envvars) = @_;
1269         my $title = "SAMBA LOG of: $envvars->{NETBIOSNAME}\n";
1270         my $out = $title;
1271
1272         open(LOG, "<$envvars->{SAMBA_TEST_LOG}");
1273
1274         seek(LOG, $envvars->{SAMBA_TEST_LOG_POS}, SEEK_SET);
1275         while (<LOG>) {
1276                 $out .= $_;
1277         }
1278         $envvars->{SAMBA_TEST_LOG_POS} = tell(LOG);
1279         close(LOG);
1280
1281         return "" if $out eq $title;
1282
1283         return $out;
1284 }
1285
1286 sub check_env($$)
1287 {
1288         my ($self, $envvars) = @_;
1289
1290         return (-p $envvars->{SAMBA_TEST_FIFO});
1291 }
1292
1293 sub setup_env($$$)
1294 {
1295         my ($self, $envname, $path) = @_;
1296
1297         $ENV{ENVNAME} = $envname;
1298
1299         if ($envname eq "dc") {
1300                 return $self->setup_dc("$path/dc");
1301         } elsif ($envname eq "fl2000dc") {
1302                 return $self->setup_fl2000dc("$path/fl2000dc");
1303         } elsif ($envname eq "fl2003dc") {
1304                 return $self->setup_fl2003dc("$path/fl2003dc");
1305         } elsif ($envname eq "fl2008r2dc") {
1306                 return $self->setup_fl2008r2dc("$path/fl2008r2dc");
1307         } elsif ($envname eq "rpc_proxy") {
1308                 if (not defined($self->{vars}->{dc})) {
1309                         $self->setup_dc("$path/dc");
1310                 }
1311                 return $self->setup_rpc_proxy("$path/rpc_proxy", $self->{vars}->{dc});
1312         } elsif ($envname eq "vampire_dc") {
1313                 if (not defined($self->{vars}->{dc})) {
1314                         $self->setup_dc("$path/dc");
1315                 }
1316                 return $self->setup_vampire_dc("$path/vampire_dc", $self->{vars}->{dc});
1317         } elsif ($envname eq "member") {
1318                 if (not defined($self->{vars}->{dc})) {
1319                         $self->setup_dc("$path/dc");
1320                 }
1321                 return $self->setup_member("$path/member", $self->{vars}->{dc});
1322         } elsif ($envname eq "rodc") {
1323                 if (not defined($self->{vars}->{dc})) {
1324                         $self->setup_dc("$path/dc");
1325                 }
1326                 return $self->setup_rodc("$path/rodc", $self->{vars}->{dc});
1327         } elsif ($envname eq "all") {
1328                 if (not defined($self->{vars}->{dc})) {
1329                         $ENV{ENVNAME} = "dc";
1330                         $self->setup_dc("$path/dc");
1331                 }
1332                 my $ret = $self->setup_member("$path/member", $self->{vars}->{dc});
1333                 if (not defined($self->{vars}->{rpc_proxy})) {
1334                         $ENV{ENVNAME} = "rpc_proxy";
1335                         my $rpc_proxy_ret = $self->setup_rpc_proxy("$path/rpc_proxy", $self->{vars}->{dc});
1336                         
1337                         $ret->{RPC_PROXY_SERVER} = $rpc_proxy_ret->{SERVER};
1338                         $ret->{RPC_PROXY_SERVER_IP} = $rpc_proxy_ret->{SERVER_IP};
1339                         $ret->{RPC_PROXY_NETBIOSNAME} = $rpc_proxy_ret->{NETBIOSNAME};
1340                         $ret->{RPC_PROXY_NETBIOSALIAS} = $rpc_proxy_ret->{NETBIOSALIAS};
1341                         $ret->{RPC_PROXY_USERNAME} = $rpc_proxy_ret->{USERNAME};
1342                         $ret->{RPC_PROXY_PASSWORD} = $rpc_proxy_ret->{PASSWORD};
1343                 }
1344                 if (not defined($self->{vars}->{fl2000dc})) {
1345                         $ENV{ENVNAME} = "fl2000dc";
1346                         my $fl2000dc_ret = $self->setup_fl2000dc("$path/fl2000dc", $self->{vars}->{dc});
1347                         
1348                         $ret->{FL2000DC_SERVER} = $fl2000dc_ret->{SERVER};
1349                         $ret->{FL2000DC_SERVER_IP} = $fl2000dc_ret->{SERVER_IP};
1350                         $ret->{FL2000DC_NETBIOSNAME} = $fl2000dc_ret->{NETBIOSNAME};
1351                         $ret->{FL2000DC_NETBIOSALIAS} = $fl2000dc_ret->{NETBIOSALIAS};
1352                         $ret->{FL2000DC_USERNAME} = $fl2000dc_ret->{USERNAME};
1353                         $ret->{FL2000DC_PASSWORD} = $fl2000dc_ret->{PASSWORD};
1354                 }
1355                 if (not defined($self->{vars}->{fl2003dc})) {
1356                         $ENV{ENVNAME} = "fl2003dc";
1357                         my $fl2003dc_ret = $self->setup_fl2003dc("$path/fl2003dc", $self->{vars}->{dc});
1358
1359                         $ret->{FL2003DC_SERVER} = $fl2003dc_ret->{SERVER};
1360                         $ret->{FL2003DC_SERVER_IP} = $fl2003dc_ret->{SERVER_IP};
1361                         $ret->{FL2003DC_NETBIOSNAME} = $fl2003dc_ret->{NETBIOSNAME};
1362                         $ret->{FL2003DC_NETBIOSALIAS} = $fl2003dc_ret->{NETBIOSALIAS};
1363                         $ret->{FL2003DC_USERNAME} = $fl2003dc_ret->{USERNAME};
1364                         $ret->{FL2003DC_PASSWORD} = $fl2003dc_ret->{PASSWORD};
1365                 }
1366                 if (not defined($self->{vars}->{fl2008r2dc})) {
1367                         $ENV{ENVNAME} = "fl2008r2dc";
1368                         my $fl2008r2dc_ret = $self->setup_fl2008r2dc("$path/fl2008r2dc", $self->{vars}->{dc});
1369
1370                         $ret->{FL2008R2DC_SERVER} = $fl2008r2dc_ret->{SERVER};
1371                         $ret->{FL2008R2DC_SERVER_IP} = $fl2008r2dc_ret->{SERVER_IP};
1372                         $ret->{FL2008R2DC_NETBIOSNAME} = $fl2008r2dc_ret->{NETBIOSNAME};
1373                         $ret->{FL2008R2DC_NETBIOSALIAS} = $fl2008r2dc_ret->{NETBIOSALIAS};
1374                         $ret->{FL2008R2DC_USERNAME} = $fl2008r2dc_ret->{USERNAME};
1375                         $ret->{FL2008R2DC_PASSWORD} = $fl2008r2dc_ret->{PASSWORD};
1376                 }
1377                 return $ret;
1378         } else {
1379                 warn("Samba4 can't provide environment '$envname'");
1380                 return undef;
1381         }
1382 }
1383
1384 sub setup_member($$$)
1385 {
1386         my ($self, $path, $dc_vars) = @_;
1387
1388         my $env = $self->provision_member($path, $dc_vars);
1389
1390         if (defined $env) {
1391                 $self->check_or_start($env, ($ENV{SMBD_MAXTIME} or 7500));
1392
1393                 $self->wait_for_start($env);
1394
1395                 $self->{vars}->{member} = $env;
1396         }
1397
1398         return $env;
1399 }
1400
1401 sub setup_rpc_proxy($$$)
1402 {
1403         my ($self, $path, $dc_vars) = @_;
1404
1405         my $env = $self->provision_rpc_proxy($path, $dc_vars);
1406
1407         if (defined $env) {
1408                 $self->check_or_start($env, ($ENV{SMBD_MAXTIME} or 7500));
1409
1410                 $self->wait_for_start($env);
1411
1412                 $self->{vars}->{rpc_proxy} = $env;
1413         }
1414         return $env;
1415 }
1416
1417 sub setup_dc($$)
1418 {
1419         my ($self, $path) = @_;
1420
1421         my $env = $self->provision_dc($path);
1422         if (defined $env) {
1423                 $self->check_or_start($env,
1424                         ($ENV{SMBD_MAXTIME} or 7500));
1425
1426                 $self->wait_for_start($env);
1427
1428                 $self->{vars}->{dc} = $env;
1429         }
1430         return $env;
1431 }
1432
1433 sub setup_fl2000dc($$)
1434 {
1435         my ($self, $path) = @_;
1436
1437         my $env = $self->provision_fl2000dc($path);
1438         if (defined $env) {
1439                 $self->check_or_start($env,
1440                         ($ENV{SMBD_MAXTIME} or 7500));
1441
1442                 $self->wait_for_start($env);
1443
1444                 $self->{vars}->{fl2000dc} = $env;
1445         }
1446
1447         return $env;
1448 }
1449
1450 sub setup_fl2003dc($$)
1451 {
1452         my ($self, $path) = @_;
1453
1454         my $env = $self->provision_fl2003dc($path);
1455
1456         if (defined $env) {
1457                 $self->check_or_start($env,
1458                         ($ENV{SMBD_MAXTIME} or 7500));
1459
1460                 $self->wait_for_start($env);
1461
1462                 $self->{vars}->{fl2003dc} = $env;
1463         }
1464         return $env;
1465 }
1466
1467 sub setup_fl2008r2dc($$)
1468 {
1469         my ($self, $path) = @_;
1470
1471         my $env = $self->provision_fl2008r2dc($path);
1472
1473         if (defined $env) {
1474                 $self->check_or_start($env,
1475                         ($ENV{SMBD_MAXTIME} or 7500));
1476
1477                 $self->wait_for_start($env);
1478
1479                 $self->{vars}->{fl2008r2dc} = $env;
1480         }
1481
1482         return $env;
1483 }
1484
1485 sub setup_vampire_dc($$$)
1486 {
1487         my ($self, $path, $dc_vars) = @_;
1488
1489         my $env = $self->provision_vampire_dc($path, $dc_vars);
1490
1491         if (defined $env) {
1492                 $self->check_or_start($env,
1493                         ($ENV{SMBD_MAXTIME} or 7500));
1494
1495                 $self->wait_for_start($env);
1496
1497                 $self->{vars}->{vampire_dc} = $env;
1498
1499                 # force replicated DC to update repsTo/repsFrom
1500                 # for vampired partitions
1501                 my $samba_tool = $self->bindir_path("samba-tool");
1502                 my $cmd = "";
1503                 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
1504                 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
1505                 $cmd .= " $samba_tool drs kcc $env->{DC_SERVER}";
1506                 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
1507                 unless (system($cmd) == 0) {
1508                         warn("Failed to exec kcc\n$cmd");
1509                         return undef;
1510                 }
1511
1512                 # as 'vampired' dc may add data in its local replica
1513                 # we need to synchronize data between DCs
1514                 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
1515                 $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
1516                 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
1517                 $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{VAMPIRE_DC_SERVER}";
1518                 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
1519                 # replicate Configuration NC
1520                 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
1521                 unless(system($cmd_repl) == 0) {
1522                         warn("Failed to replicate\n$cmd_repl");
1523                         return undef;
1524                 }
1525                 # replicate Default NC
1526                 $cmd_repl = "$cmd \"$base_dn\"";
1527                 unless(system($cmd_repl) == 0) {
1528                         warn("Failed to replicate\n$cmd_repl");
1529                         return undef;
1530                 }
1531         }
1532
1533         return $env;
1534 }
1535
1536 sub setup_rodc($$$)
1537 {
1538         my ($self, $path, $dc_vars) = @_;
1539
1540         my $env = $self->provision_rodc($path, $dc_vars);
1541
1542         unless ($env) {
1543                 return undef;
1544         }
1545
1546         $self->check_or_start($env,
1547                 ($ENV{SMBD_MAXTIME} or 7500));
1548
1549         $self->wait_for_start($env);
1550
1551         $self->{vars}->{rodc} = $env;
1552
1553         return $env;
1554 }
1555
1556 1;