]> git.samba.org - samba.git/blob - selftest/target/Samba4.pm
selftest:Samba4: add bindir_path() utility function to construct the binary pathes
[samba.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
13 sub new($$$$) {
14         my ($classname, $bindir, $ldap, $setupdir) = @_;
15         my $self = { 
16                 vars => {}, 
17                 ldap => $ldap, 
18                 bindir => $bindir, 
19                 setupdir => $setupdir 
20         };
21         bless $self;
22         return $self;
23 }
24
25 sub bindir_path($$) {
26         my ($self, $path) = @_;
27
28         return "$self->{bindir}/$path";
29 }
30
31 sub openldap_start($$$) {
32         my ($slapd_conf, $uri, $logs) = @_;
33         my $oldpath = $ENV{PATH};
34         my $olroot = "";
35         my $olpath = "";
36         if (defined $ENV{OPENLDAP_ROOT}) {
37             $olroot = "$ENV{OPENLDAP_ROOT}";
38             $olpath = "$olroot/libexec:$olroot/sbin:";
39         }
40         $ENV{PATH} = "$olpath/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}";
41         system("slapd -d0 -f $slapd_conf -h $uri > $logs 2>&1 &");
42         $ENV{PATH} = $oldpath;
43 }
44
45 sub slapd_start($$)
46 {
47         my $count = 0;
48         my ($self, $env_vars) = @_;
49
50         my $uri = $env_vars->{LDAP_URI};
51
52         # running slapd in the background means it stays in the same process group, so it can be
53         # killed by timelimit
54         if ($self->{ldap} eq "fedora-ds") {
55                 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 &");
56         } elsif ($self->{ldap} eq "openldap") {
57                 openldap_start($env_vars->{SLAPD_CONF}, $uri, "$env_vars->{LDAPDIR}/logs");
58         }
59         my $ldbsearch = $self->bindir_path("ldbsearch");
60         while (system("$ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") != 0) {
61                 $count++;
62                 if ($count > 40) {
63                     $self->slapd_stop($env_vars);
64                     return 0;
65                 }
66                 sleep(1);
67         }
68         return 1;
69 }
70
71 sub slapd_stop($$)
72 {
73         my ($self, $envvars) = @_;
74         if ($self->{ldap} eq "fedora-ds") {
75                 system("$envvars->{LDAPDIR}/slapd-samba4/stop-slapd");
76         } elsif ($self->{ldap} eq "openldap") {
77                 open(IN, "<$envvars->{OPENLDAP_PIDFILE}") or 
78                         die("unable to open slapd pid file: $envvars->{OPENLDAP_PIDFILE}");
79                 kill 9, <IN>;
80                 close(IN);
81         }
82         return 1;
83 }
84
85 sub check_or_start($$$) 
86 {
87         my ($self, $env_vars, $max_time) = @_;
88         return 0 if ( -p $env_vars->{SMBD_TEST_FIFO});
89
90         unlink($env_vars->{SMBD_TEST_FIFO});
91         POSIX::mkfifo($env_vars->{SMBD_TEST_FIFO}, 0700);
92         unlink($env_vars->{SMBD_TEST_LOG});
93         
94         print "STARTING SMBD... ";
95         my $pid = fork();
96         if ($pid == 0) {
97                 open STDIN, $env_vars->{SMBD_TEST_FIFO};
98                 open STDOUT, ">$env_vars->{SMBD_TEST_LOG}";
99                 open STDERR, '>&STDOUT';
100                 
101                 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
102
103                 my $valgrind = "";
104                 if (defined($ENV{SMBD_VALGRIND})) {
105                     $valgrind = $ENV{SMBD_VALGRIND};
106                 } 
107
108                 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG}; 
109
110                 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
111                 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
112
113                 # Start slapd before smbd, but with the fifo on stdin
114                 if (defined($self->{ldap})) {
115                     $self->slapd_start($env_vars) or 
116                         die("couldn't start slapd (2nd time)");
117                 }
118
119                 my $optarg = "";
120                 if (defined($max_time)) {
121                         $optarg = "--maximum-runtime=$max_time ";
122                 }
123                 if (defined($ENV{SMBD_OPTIONS})) {
124                         $optarg.= " $ENV{SMBD_OPTIONS}";
125                 }
126                 my $samba = $self->bindir_path("samba");
127                 my $ret = system("$valgrind $samba $optarg $env_vars->{CONFIGURATION} -M single -i --leak-report-full");
128                 if ($? == -1) {
129                         print "Unable to start $samba: $ret: $!\n";
130                         exit 1;
131                 }
132                 unlink($env_vars->{SMBD_TEST_FIFO});
133                 my $exit = $? >> 8;
134                 if ( $ret == 0 ) {
135                         print "$samba exits with status $exit\n";
136                 } elsif ( $ret & 127 ) {
137                         print "$samba got signal ".($ret & 127)." and exits with $exit!\n";
138                 } else {
139                         $ret = $? >> 8;
140                         print "$samba failed with status $exit!\n";
141                 }
142                 exit $exit;
143         }
144         print "DONE\n";
145
146         open(DATA, ">$env_vars->{SMBD_TEST_FIFO}");
147
148         return $pid;
149 }
150
151 sub wait_for_start($$)
152 {
153         my ($self, $testenv_vars) = @_;
154         # give time for nbt server to register its names
155         print "delaying for nbt name registration\n";
156         sleep 2;
157
158         # This will return quickly when things are up, but be slow if we 
159         # need to wait for (eg) SSL init 
160         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
161         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
162         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
163         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
164         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSALIAS}");
165         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSALIAS}");
166         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
167         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
168         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
169         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
170         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSALIAS}");
171         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSALIAS}");
172
173         print $self->getlog_env($testenv_vars);
174 }
175
176 sub write_ldb_file($$$)
177 {
178         my ($self, $file, $ldif) = @_;
179
180         my $ldbadd = $self->bindir_path("ldbadd");
181         open(LDIF, "|$ldbadd -H $file >/dev/null");
182         print LDIF $ldif;
183         return close(LDIF);
184 }
185
186 sub add_wins_config($$)
187 {
188         my ($self, $privatedir) = @_;
189
190         return $self->write_ldb_file("$privatedir/wins_config.ldb", "
191 dn: name=TORTURE_6,CN=PARTNERS
192 objectClass: wreplPartner
193 name: TORTURE_6
194 address: 127.0.0.6
195 pullInterval: 0
196 pushChangeCount: 0
197 type: 0x3
198 ");
199 }
200
201 sub mk_fedora_ds($$$)
202 {
203         my ($self, $ldapdir, $configuration) = @_;
204
205         my $fedora_ds_inf = "$ldapdir/fedorads.inf";
206         my $fedora_ds_extra_ldif = "$ldapdir/fedorads-partitions.ldif";
207
208         #Make the subdirectory be as fedora DS would expect
209         my $fedora_ds_dir = "$ldapdir/slapd-samba4";
210
211         my $pidfile = "$fedora_ds_dir/logs/slapd-samba4.pid";
212
213 my $dir = getcwd();
214 chdir "$ENV{FEDORA_DS_ROOT}/bin" || die;
215         if (system("perl $ENV{FEDORA_DS_ROOT}/sbin/setup-ds.pl --silent --file=$fedora_ds_inf >&2") != 0) {
216             chdir $dir;
217             die("perl $ENV{FEDORA_DS_ROOT}/sbin/setup-ds.pl --silent --file=$fedora_ds_inf FAILED: $?");
218         }
219         chdir $dir || die;
220
221         return ($fedora_ds_dir, $pidfile);
222 }
223
224 sub mk_openldap($$$)
225 {
226         my ($self, $ldapdir, $configuration) = @_;
227
228         my $slapd_conf = "$ldapdir/slapd.conf";
229         my $pidfile = "$ldapdir/slapd.pid";
230         my $modconf = "$ldapdir/modules.conf";
231
232         my $oldpath = $ENV{PATH};
233         my $olpath = "";
234         my $olroot = "";
235         if (defined $ENV{OPENLDAP_ROOT}) {
236                $olroot = "$ENV{OPENLDAP_ROOT}";
237                $olpath = "$olroot/libexec:$olroot/sbin:";
238         }
239         $ENV{PATH} = "$olpath/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}";
240
241         unlink($modconf);
242         open(CONF, ">$modconf"); close(CONF);
243
244         if (system("slaptest -u -f $slapd_conf >&2") != 0) {
245                 open(CONF, ">$modconf"); 
246                 # enable slapd modules
247                 print CONF "
248 modulepath      $olroot/libexec/openldap
249 moduleload      syncprov
250 moduleload      memberof
251 moduleload      refint
252 ";
253                 close(CONF);
254         }
255         if (system("slaptest -u -f $slapd_conf >&2") != 0) {
256                 open(CONF, ">$modconf"); 
257                 # enable slapd modules
258                 print CONF "
259 modulepath      $olroot/libexec/openldap
260 moduleload      back_hdb
261 moduleload      syncprov
262 moduleload      memberof
263 moduleload      refint
264 ";
265                 close(CONF);
266         }
267
268         if (system("slaptest -u -f $slapd_conf >&2") != 0) {
269                 open(CONF, ">$modconf"); 
270                 # enable slapd modules
271                 print CONF "
272 moduleload      back_hdb
273 moduleload      syncprov
274 moduleload      memberof
275 moduleload      refint
276 ";
277                 close(CONF);
278         }
279
280         if (system("slaptest -u -f $slapd_conf >&2") != 0) {
281                 open(CONF, ">$modconf"); 
282                 # enable slapd modules
283                 print CONF "
284 modulepath      /usr/lib/ldap
285 moduleload      back_hdb
286 moduleload      syncprov
287 moduleload      memberof
288 moduleload      refint
289 ";
290                 close(CONF);
291         }
292
293         if (system("slaptest -u -f $slapd_conf >&2") != 0) {
294                 open(CONF, ">$modconf"); 
295                 # enable slapd modules (Fedora layout)
296                 print CONF "
297 modulepath      /usr/lib/openldap
298 moduleload      syncprov
299 moduleload      memberof
300 moduleload      refint
301 ";
302                 close(CONF);
303         }
304
305         if (system("slaptest -u -f $slapd_conf >&2") != 0) {
306                 open(CONF, ">$modconf"); 
307                 # enable slapd modules (Fedora x86_64 layout)
308                 print CONF "
309 modulepath      /usr/lib64/openldap
310 moduleload      syncprov
311 moduleload      memberof
312 moduleload      refint
313 ";
314                 close(CONF);
315         }
316
317         system("slaptest -u -f $slapd_conf") == 0 or die("slaptest still fails after adding modules");
318
319     
320         $ENV{PATH} = $oldpath;
321
322         return ($slapd_conf, $pidfile);
323 }
324
325 sub mk_keyblobs($$)
326 {
327         my ($self, $tlsdir) = @_;
328
329         #TLS and PKINIT crypto blobs
330         my $dhfile = "$tlsdir/dhparms.pem";
331         my $cafile = "$tlsdir/ca.pem";
332         my $certfile = "$tlsdir/cert.pem";
333         my $reqkdc = "$tlsdir/req-kdc.der";
334         my $kdccertfile = "$tlsdir/kdc.pem";
335         my $keyfile = "$tlsdir/key.pem";
336         my $adminkeyfile = "$tlsdir/adminkey.pem";
337         my $reqadmin = "$tlsdir/req-admin.der";
338         my $admincertfile = "$tlsdir/admincert.pem";
339
340         mkdir($tlsdir, 0777);
341
342         #This is specified here to avoid draining entropy on every run
343         open(DHFILE, ">$dhfile");
344         print DHFILE <<EOF;
345 -----BEGIN DH PARAMETERS-----
346 MGYCYQC/eWD2xkb7uELmqLi+ygPMKyVcpHUo2yCluwnbPutEueuxrG/Cys8j8wLO
347 svCN/jYNyR2NszOmg7ZWcOC/4z/4pWDVPUZr8qrkhj5MRKJc52MncfaDglvEdJrv
348 YX70obsCAQI=
349 -----END DH PARAMETERS-----
350 EOF
351         close(DHFILE);
352
353         #Likewise, we pregenerate the key material.  This allows the 
354         #other certificates to be pre-generated
355         open(KEYFILE, ">$keyfile");
356         print KEYFILE <<EOF;
357 -----BEGIN RSA PRIVATE KEY-----
358 MIICXQIBAAKBgQDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpc
359 ol3+S9/6I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H
360 6H+pPqVIRLOmrWImai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQAB
361 AoGAAqDLzFRR/BF1kpsiUfL4WFvTarCe9duhwj7ORc6fs785qAXuwUYAJ0Uvzmy6
362 HqoGv3t3RfmeHDmjcpPHsbOKnsOQn2MgmthidQlPBMWtQMff5zdoYNUFiPS0XQBq
363 szNW4PRjaA9KkLQVTwnzdXGkBSkn/nGxkaVu7OR3vJOBoo0CQQDO4upypesnbe6p
364 9/xqfZ2uim8IwV1fLlFClV7WlCaER8tsQF4lEi0XSzRdXGUD/dilpY88Nb+xok/X
365 8Z8OvgAXAkEA+pcLsx1gN7kxnARxv54jdzQjC31uesJgMKQXjJ0h75aUZwTNHmZQ
366 vPxi6u62YiObrN5oivkixwFNncT9MxTxVQJBAMaWUm2SjlLe10UX4Zdm1MEB6OsC
367 kVoX37CGKO7YbtBzCfTzJGt5Mwc1DSLA2cYnGJqIfSFShptALlwedot0HikCQAJu
368 jNKEKnbf+TdGY8Q0SKvTebOW2Aeg80YFkaTvsXCdyXrmdQcifw4WdO9KucJiDhSz
369 Y9hVapz7ykEJtFtWjLECQQDIlfc63I5ZpXfg4/nN4IJXUW6AmPVOYIA5215itgki
370 cSlMYli1H9MEXH0pQMGv5Qyd0OYIx2DDg96mZ+aFvqSG
371 -----END RSA PRIVATE KEY-----
372 EOF
373         close(KEYFILE);
374
375         open(ADMINKEYFILE, ">$adminkeyfile");
376
377         print ADMINKEYFILE <<EOF;
378 -----BEGIN RSA PRIVATE KEY-----
379 MIICXQIBAAKBgQD0+OL7TQBj0RejbIH1+g5GeRaWaM9xF43uE5y7jUHEsi5owhZF
380 5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMFxB6esnXhl0Jpip1JkUMM
381 XLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xdl3JRlwIDAQAB
382 AoGAP8mjCP628Ebc2eACQzOWjgEvwYCPK4qPmYOf1zJkArzG2t5XAGJ5WGrENRuB
383 cm3XFh1lpmaADl982UdW3gul4gXUy6w4XjKK4vVfhyHj0kZ/LgaXUK9BAGhroJ2L
384 osIOUsaC6jdx9EwSRctwdlF3wWJ8NK0g28AkvIk+FlolW4ECQQD7w5ouCDnf58CN
385 u4nARx4xv5XJXekBvOomkCQAmuOsdOb6b9wn3mm2E3au9fueITjb3soMR31AF6O4
386 eAY126rXAkEA+RgHzybzZEP8jCuznMqoN2fq/Vrs6+W3M8/G9mzGEMgLLpaf2Jiz
387 I9tLZ0+OFk9tkRaoCHPfUOCrVWJZ7Y53QQJBAMhoA6rw0WDyUcyApD5yXg6rusf4
388 ASpo/tqDkqUIpoL464Qe1tjFqtBM3gSXuhs9xsz+o0bzATirmJ+WqxrkKTECQHt2
389 OLCpKqwAspU7N+w32kaUADoRLisCEdrhWklbwpQgwsIVsCaoEOpt0CLloJRYTANE
390 yoZeAErTALjyZYZEPcECQQDlUi0N8DFxQ/lOwWyR3Hailft+mPqoPCa8QHlQZnlG
391 +cfgNl57YHMTZFwgUVFRdJNpjH/WdZ5QxDcIVli0q+Ko
392 -----END RSA PRIVATE KEY-----
393 EOF
394
395         #generated with 
396         # hxtool issue-certificate --self-signed --issue-ca \
397         # --ca-private-key="FILE:$KEYFILE" \
398         # --subject="CN=CA,DC=samba,DC=example,DC=com" \
399         # --certificate="FILE:$CAFILE" --lifetime="25 years"
400
401         open(CAFILE, ">$cafile");
402         print CAFILE <<EOF;
403 -----BEGIN CERTIFICATE-----
404 MIICcTCCAdqgAwIBAgIUaBPmjnPVqyFqR5foICmLmikJTzgwCwYJKoZIhvcNAQEFMFIxEzAR
405 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
406 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTIyMzEyWhgPMjAzMzAyMjQx
407 MjIzMTJaMFIxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
408 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMIGfMA0GCSqGSIb3DQEBAQUA
409 A4GNADCBiQKBgQDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpcol3+S9/6
410 I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H6H+pPqVIRLOmrWIm
411 ai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQABo0IwQDAOBgNVHQ8BAf8EBAMC
412 AaYwHQYDVR0OBBYEFMLZufegDKLZs0VOyFXYK1L6M8oyMA8GA1UdEwEB/wQFMAMBAf8wDQYJ
413 KoZIhvcNAQEFBQADgYEAAZJbCAAkaqgFJ0xgNovn8Ydd0KswQPjicwiODPgw9ZPoD2HiOUVO
414 yYDRg/dhFF9y656OpcHk4N7qZ2sl3RlHkzDu+dseETW+CnKvQIoXNyeARRJSsSlwrwcoD4JR
415 HTLk2sGigsWwrJ2N99sG/cqSJLJ1MFwLrs6koweBnYU0f/g=
416 -----END CERTIFICATE-----
417 EOF
418
419         #generated with GNUTLS internally in Samba.  
420
421         open(CERTFILE, ">$certfile");
422         print CERTFILE <<EOF;
423 -----BEGIN CERTIFICATE-----
424 MIICYTCCAcygAwIBAgIE5M7SRDALBgkqhkiG9w0BAQUwZTEdMBsGA1UEChMUU2Ft
425 YmEgQWRtaW5pc3RyYXRpb24xNDAyBgNVBAsTK1NhbWJhIC0gdGVtcG9yYXJ5IGF1
426 dG9nZW5lcmF0ZWQgY2VydGlmaWNhdGUxDjAMBgNVBAMTBVNhbWJhMB4XDTA2MDgw
427 NDA0MzY1MloXDTA4MDcwNDA0MzY1MlowZTEdMBsGA1UEChMUU2FtYmEgQWRtaW5p
428 c3RyYXRpb24xNDAyBgNVBAsTK1NhbWJhIC0gdGVtcG9yYXJ5IGF1dG9nZW5lcmF0
429 ZWQgY2VydGlmaWNhdGUxDjAMBgNVBAMTBVNhbWJhMIGcMAsGCSqGSIb3DQEBAQOB
430 jAAwgYgCgYDKg6pAwCHUMA1DfHDmWhZfd+F0C+9Jxcqvpw9ii9En3E1uflpcol3+
431 S9/6I/uaTmJHZre+DF3dTzb/UOZo0Zem8N+IzzkgoGkFafjXuT3BL5UPY2/H6H+p
432 PqVIRLOmrWImai359YyoKhFyo37Y6HPeU8QcZ+u2rS9geapIWfeuowIDAQABoyUw
433 IzAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMBMAsGCSqGSIb3DQEB
434 BQOBgQAmkN6XxvDnoMkGcWLCTwzxGfNNSVcYr7TtL2aJh285Xw9zaxcm/SAZBFyG
435 LYOChvh6hPU7joMdDwGfbiLrBnMag+BtGlmPLWwp/Kt1wNmrRhduyTQFhN3PP6fz
436 nBr9vVny2FewB2gHmelaPS//tXdxivSXKz3NFqqXLDJjq7P8wA==
437 -----END CERTIFICATE-----
438 EOF
439         close(CERTFILE);
440
441         #KDC certificate
442         # hxtool request-create \
443         # --subject="CN=krbtgt,CN=users,DC=samba,DC=example,DC=com" \
444         # --key="FILE:$KEYFILE" $KDCREQ
445
446         # hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
447         # --type="pkinit-kdc" \
448         # --pk-init-principal="krbtgt/SAMBA.EXAMPLE.COM@SAMBA.EXAMPLE.COM" \
449         # --req="PKCS10:$KDCREQ" --certificate="FILE:$KDCCERTFILE" \
450         # --lifetime="25 years"
451
452         open(KDCCERTFILE, ">$kdccertfile");
453         print KDCCERTFILE <<EOF;
454 -----BEGIN CERTIFICATE-----
455 MIIDDDCCAnWgAwIBAgIUI2Tzj+JnMzMcdeabcNo30rovzFAwCwYJKoZIhvcNAQEFMFIxEzAR
456 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
457 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTMxOTIzWhgPMjAzMzAyMjQx
458 MzE5MjNaMGYxEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
459 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMQ8wDQYDVQQDDAZrcmJ0
460 Z3QwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMqDqkDAIdQwDUN8cOZaFl934XQL70nF
461 yq+nD2KL0SfcTW5+WlyiXf5L3/oj+5pOYkdmt74MXd1PNv9Q5mjRl6bw34jPOSCgaQVp+Ne5
462 PcEvlQ9jb8fof6k+pUhEs6atYiZqLfn1jKgqEXKjftjoc95TxBxn67atL2B5qkhZ966jAgMB
463 AAGjgcgwgcUwDgYDVR0PAQH/BAQDAgWgMBIGA1UdJQQLMAkGBysGAQUCAwUwVAYDVR0RBE0w
464 S6BJBgYrBgEFAgKgPzA9oBMbEVNBTUJBLkVYQU1QTEUuQ09NoSYwJKADAgEBoR0wGxsGa3Ji
465 dGd0GxFTQU1CQS5FWEFNUExFLkNPTTAfBgNVHSMEGDAWgBTC2bn3oAyi2bNFTshV2CtS+jPK
466 MjAdBgNVHQ4EFgQUwtm596AMotmzRU7IVdgrUvozyjIwCQYDVR0TBAIwADANBgkqhkiG9w0B
467 AQUFAAOBgQBmrVD5MCmZjfHp1nEnHqTIh8r7lSmVtDx4s9MMjxm9oNrzbKXynvdhwQYFVarc
468 ge4yRRDXtSebErOl71zVJI9CVeQQpwcH+tA85oGA7oeFtO/S7ls581RUU6tGgyxV4veD+lJv
469 KPH5LevUtgD+q9H4LU4Sq5N3iFwBaeryB0g2wg==
470 -----END CERTIFICATE-----
471 EOF
472
473         # hxtool request-create \
474         # --subject="CN=Administrator,CN=users,DC=samba,DC=example,DC=com" \
475         # --key="FILE:$ADMINKEYFILE" $ADMINREQFILE
476
477         # hxtool issue-certificate --ca-certificate=FILE:$CAFILE,$KEYFILE \
478         # --type="pkinit-client" \
479         # --pk-init-principal="administrator@SAMBA.EXAMPLE.COM" \
480         # --req="PKCS10:$ADMINREQFILE" --certificate="FILE:$ADMINCERTFILE" \
481         # --lifetime="25 years"
482         
483         open(ADMINCERTFILE, ">$admincertfile");
484         print ADMINCERTFILE <<EOF;
485 -----BEGIN CERTIFICATE-----
486 MIIDHTCCAoagAwIBAgIUC0W5dW/N9kE+NgD0mKK34YgyqQ0wCwYJKoZIhvcNAQEFMFIxEzAR
487 BgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxlMRUwEwYKCZImiZPy
488 LGQBGQwFc2FtYmExCzAJBgNVBAMMAkNBMCIYDzIwMDgwMzAxMTMyMzAwWhgPMjAzMzAyMjQx
489 MzIzMDBaMG0xEzARBgoJkiaJk/IsZAEZDANjb20xFzAVBgoJkiaJk/IsZAEZDAdleGFtcGxl
490 MRUwEwYKCZImiZPyLGQBGQwFc2FtYmExDjAMBgNVBAMMBXVzZXJzMRYwFAYDVQQDDA1BZG1p
491 bmlzdHJhdG9yMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD0+OL7TQBj0RejbIH1+g5G
492 eRaWaM9xF43uE5y7jUHEsi5owhZF5iIoHZeeL6cpDF5y1BZRs0JlA1VqMry1jjKlzFYVEMMF
493 xB6esnXhl0Jpip1JkUMMXLOP1m/0dqayuHBWozj9f/cdyCJr0wJIX1Z8Pr+EjYRGPn/MF0xd
494 l3JRlwIDAQABo4HSMIHPMA4GA1UdDwEB/wQEAwIFoDAoBgNVHSUEITAfBgcrBgEFAgMEBggr
495 BgEFBQcDAgYKKwYBBAGCNxQCAjBIBgNVHREEQTA/oD0GBisGAQUCAqAzMDGgExsRU0FNQkEu
496 RVhBTVBMRS5DT02hGjAYoAMCAQGhETAPGw1hZG1pbmlzdHJhdG9yMB8GA1UdIwQYMBaAFMLZ
497 ufegDKLZs0VOyFXYK1L6M8oyMB0GA1UdDgQWBBQg81bLyfCA88C2B/BDjXlGuaFaxjAJBgNV
498 HRMEAjAAMA0GCSqGSIb3DQEBBQUAA4GBAHsqSqul0hZCXn4t8Kfp3v/JLMiUMJihR1XOgzoa
499 ufLOQ1HNzFUHKuo1JEQ1+i5gHT/arLu/ZBF4BfQol7vW27gKIEt0fkRV8EvoPxXvSokHq0Ku
500 HCuPOhYNEP3wYiwB3g93NMCinWVlz0mh5aijEU7y/XrjlZxBKFFrTE+BJi1o
501 -----END CERTIFICATE-----
502 EOF
503         close(ADMINCERTFILE);
504 }
505
506 sub provision($$$$$$)
507 {
508         my ($self, $prefix, $server_role, $netbiosname, $netbiosalias, $swiface, $password) = @_;
509
510         my $server_loglevel = 1;
511         my $username = "administrator";
512         my $domain = "SAMBADOMAIN";
513         my $realm = "SAMBA.EXAMPLE.COM";
514         my $dnsname = "samba.example.com";
515         my $basedn = "dc=samba,dc=example,dc=com";
516         my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `whoami`);
517         chomp $unix_name;
518         my $unix_uid = $>;
519         my $unix_gids_str = $);
520         my @unix_gids = split(" ", $unix_gids_str);
521         my $srcdir="$RealBin/..";
522         -d $prefix or mkdir($prefix, 0777) or die("Unable to create $prefix");
523         my $prefix_abs = abs_path($prefix);
524         my $tmpdir = "$prefix_abs/tmp";
525         my $etcdir = "$prefix_abs/etc";
526         my $piddir = "$prefix_abs/pid";
527         my $conffile = "$etcdir/smb.conf";
528         my $krb5_config = "$etcdir/krb5.conf";
529         my $privatedir = "$prefix_abs/private";
530         my $ncalrpcdir = "$prefix_abs/ncalrpc";
531         my $lockdir = "$prefix_abs/lockdir";
532         my $winbindd_socket_dir = "$prefix_abs/winbindd_socket";
533         my $winbindd_privileged_socket_dir = "$prefix_abs/winbindd_privileged_socket";
534         my $ntp_signd_socket_dir = "$prefix_abs/ntp_signd_socket";
535         my $nsswrap_passwd = "$etcdir/passwd";
536         my $nsswrap_group = "$etcdir/group";
537
538         my $configuration = "--configfile=$conffile";
539         my $ldapdir = "$privatedir/ldap";
540
541         my $tlsdir = "$privatedir/tls";
542
543         my $ifaceipv4 = "127.0.0.$swiface";
544         my $interfaces = "$ifaceipv4/8";
545
546         (system("rm -rf $prefix/*") == 0) or die("Unable to clean up");
547         mkdir($_, 0777) foreach ($privatedir, $etcdir, $piddir, $ncalrpcdir, $lockdir, 
548                 $tmpdir, "$tmpdir/test1", "$tmpdir/test2");
549
550
551         my $localbasedn = $basedn;
552         $localbasedn = "CN=$netbiosname" if $server_role eq "member server";
553
554         open(CONFFILE, ">$conffile");
555         print CONFFILE "
556 [global]
557         netbios name = $netbiosname
558         netbios aliases = $netbiosalias
559         workgroup = $domain
560         realm = $realm
561         private dir = $privatedir
562         pid directory = $piddir
563         ncalrpc dir = $ncalrpcdir
564         lock dir = $lockdir
565         setup directory = $self->{setupdir}
566         modules dir = $self->{bindir}/modules
567         winbindd socket directory = $winbindd_socket_dir
568         winbindd privileged socket directory = $winbindd_privileged_socket_dir
569         ntp signd socket directory = $ntp_signd_socket_dir
570         winbind separator = /
571         name resolve order = bcast
572         interfaces = $interfaces
573         tls dh params file = $tlsdir/dhparms.pem
574         panic action = $RealBin/gdb_backtrace \%PID% \%PROG%
575         wins support = yes
576         server role = $server_role
577         max xmit = 32K
578         server max protocol = SMB2
579         notify:inotify = false
580         ldb:nosync = true
581 #We don't want to pass our self-tests if the PAC code is wrong
582         gensec:require_pac = true
583         log level = $server_loglevel
584         lanman auth = Yes
585
586 [tmp]
587         path = $tmpdir
588         read only = no
589         ntvfs handler = posix
590         posix:sharedelay = 100000
591         posix:eadb = $lockdir/eadb.tdb
592         posix:oplocktimeout = 3
593         posix:writetimeupdatedelay = 500000
594
595 [test1]
596         path = $tmpdir/test1
597         read only = no
598         ntvfs handler = posix
599         posix:sharedelay = 100000
600         posix:eadb = $lockdir/eadb.tdb
601         posix:oplocktimeout = 3
602         posix:writetimeupdatedelay = 500000
603
604 [test2]
605         path = $tmpdir/test2
606         read only = no
607         ntvfs handler = posix
608         posix:sharedelay = 100000
609         posix:eadb = $lockdir/eadb.tdb
610         posix:oplocktimeout = 3
611         posix:writetimeupdatedelay = 500000
612
613 [cifs]
614         read only = no
615         ntvfs handler = cifs
616         cifs:server = $netbiosname
617         cifs:share = tmp
618 #There is no username specified here, instead the client is expected
619 #to log in with kerberos, and the serverwill use delegated credentials.
620
621 [simple]
622         path = $tmpdir
623         read only = no
624         ntvfs handler = simple
625
626 [sysvol]
627         path = $lockdir/sysvol
628         read only = yes
629
630 [netlogon]
631         path = $lockdir/sysvol/$dnsname/scripts
632         read only = no
633
634 [cifsposix]
635         copy = simple
636         ntvfs handler = cifsposix   
637 ";
638         close(CONFFILE);
639
640         $self->mk_keyblobs($tlsdir);
641
642         open(KRB5CONF, ">$krb5_config");
643         print KRB5CONF "
644 #Generated krb5.conf for $realm
645
646 [libdefaults]
647  default_realm = $realm
648  dns_lookup_realm = false
649  dns_lookup_kdc = false
650  ticket_lifetime = 24h
651  forwardable = yes
652
653 [realms]
654  $realm = {
655   kdc = 127.0.0.1:88
656   admin_server = 127.0.0.1:88
657   default_domain = $dnsname
658  }
659  $dnsname = {
660   kdc = 127.0.0.1:88
661   admin_server = 127.0.0.1:88
662   default_domain = $dnsname
663  }
664  $domain = {
665   kdc = 127.0.0.1:88
666   admin_server = 127.0.0.1:88
667   default_domain = $dnsname
668  }
669
670 [appdefaults]
671         pkinit_anchors = FILE:$tlsdir/ca.pem
672
673 [kdc]
674         enable-pkinit = true
675         pkinit_identity = FILE:$tlsdir/kdc.pem,$tlsdir/key.pem
676         pkinit_anchors = FILE:$tlsdir/ca.pem
677
678 [domain_realm]
679  .$dnsname = $realm
680 ";
681         close(KRB5CONF);
682
683         open(PWD, ">$nsswrap_passwd");
684         print PWD "
685 root:x:0:0:root gecos:$prefix_abs:/bin/false
686 $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false
687 nobody:x:65534:65533:nobody gecos:$prefix_abs:/bin/false
688 ";
689         close(PWD);
690
691         open(GRP, ">$nsswrap_group");
692         print GRP "
693 root:x:0:
694 wheel:x:10:
695 users:x:100:
696 nobody:x:65533:
697 nogroup:x:65534:nobody
698 ";
699         close(GRP);
700
701 #Ensure the config file is valid before we start
702         my $testparm = $self->bindir_path("testparm");
703         if (system("$testparm $configuration -v --suppress-prompt >/dev/null 2>&1") != 0) {
704                 system("$testparm -v --suppress-prompt $configuration >&2");
705                 die("Failed to create a valid smb.conf configuration $testparm!");
706         }
707
708         (system("($testparm $configuration -v --suppress-prompt --parameter-name=\"netbios name\" --section-name=global 2> /dev/null | grep -i \"^$netbiosname\" ) >/dev/null 2>&1") == 0) or die("Failed to create a valid smb.conf configuration! $self->{bindir}/testparm $configuration -v --suppress-prompt --parameter-name=\"netbios name\" --section-name=global");
709
710         my @provision_options = ();
711         push (@provision_options, "NSS_WRAPPER_PASSWD=\"$nsswrap_passwd\"");
712         push (@provision_options, "NSS_WRAPPER_GROUP=\"$nsswrap_group\"");
713         if (defined($ENV{GDB_PROVISION})) {
714                 push (@provision_options, "gdb --args python");
715         }
716         if (defined($ENV{VALGRIND_PROVISION})) {
717                 push (@provision_options, "valgrind");
718         }
719         push (@provision_options, "$self->{setupdir}/provision");
720         push (@provision_options, split(' ', $configuration));
721         push (@provision_options, "--host-name=$netbiosname");
722         push (@provision_options, "--host-ip=$ifaceipv4");
723         push (@provision_options, "--quiet");
724         push (@provision_options, "--domain=$domain");
725         push (@provision_options, "--realm=$realm");
726         push (@provision_options, "--adminpass=$password");
727         push (@provision_options, "--krbtgtpass=krbtgt$password");
728         push (@provision_options, "--machinepass=machine$password");
729         push (@provision_options, "--root=$unix_name");
730
731         push (@provision_options, "--server-role=\"$server_role\"");
732
733         my $ldap_uri= "$ldapdir/ldapi";
734         $ldap_uri =~ s|/|%2F|g;
735         $ldap_uri = "ldapi://$ldap_uri";
736
737         my $ret = {
738                 KRB5_CONFIG => $krb5_config,
739                 PIDDIR => $piddir,
740                 SERVER => $netbiosname,
741                 SERVER_IP => $ifaceipv4,
742                 NETBIOSNAME => $netbiosname,
743                 NETBIOSALIAS => $netbiosalias,
744                 LDAP_URI => $ldap_uri,
745                 DOMAIN => $domain,
746                 USERNAME => $username,
747                 REALM => $realm,
748                 PASSWORD => $password,
749                 LDAPDIR => $ldapdir,
750                 WINBINDD_SOCKET_DIR => $winbindd_socket_dir,
751                 NCALRPCDIR => $ncalrpcdir,
752                 LOCKDIR => $lockdir,
753                 CONFIGURATION => $configuration,
754                 SOCKET_WRAPPER_DEFAULT_IFACE => $swiface,
755                 NSS_WRAPPER_PASSWD => $nsswrap_passwd,
756                 NSS_WRAPPER_GROUP => $nsswrap_group,
757         };
758
759         if (defined($self->{ldap})) {
760
761                 push (@provision_options, "--ldap-backend=$ldap_uri");
762                 system("$self->{setupdir}/provision-backend $configuration --ldap-admin-pass=$password --root=$unix_name --realm=$realm --domain=$domain --host-name=$netbiosname --ldap-backend-type=$self->{ldap}>&2") == 0 or die("backend provision failed");
763
764                 push (@provision_options, "--password=$password");
765
766                 if ($self->{ldap} eq "openldap") {
767                        push (@provision_options, "--username=samba-admin");
768                        ($ret->{SLAPD_CONF}, $ret->{OPENLDAP_PIDFILE}) = $self->mk_openldap($ldapdir, $configuration) or die("Unable to create openldap directories");
769                        push (@provision_options, "--ldap-backend-type=openldap");
770                 } elsif ($self->{ldap} eq "fedora-ds") {
771                        push (@provision_options, "--simple-bind-dn=cn=Manager,$localbasedn");
772                        ($ret->{FEDORA_DS_DIR}, $ret->{FEDORA_DS_PIDFILE}) = $self->mk_fedora_ds($ldapdir, $configuration) or die("Unable to create fedora ds directories");
773                        push (@provision_options, "--ldap-backend-type=fedora-ds");
774                  }
775
776                 $self->slapd_start($ret) or 
777                         die("couldn't start slapd");
778         }
779
780         my $provision_cmd = join(" ", @provision_options);
781         (system($provision_cmd) == 0) or die("Unable to provision: \n$provision_cmd\n");
782
783         if (defined($self->{ldap})) {
784                 $self->slapd_stop($ret) or 
785                         die("couldn't stop slapd");
786         }
787
788         return $ret; 
789 }
790
791 sub provision_member($$$)
792 {
793         my ($self, $prefix, $dcvars) = @_;
794         print "PROVISIONING MEMBER...";
795
796         my $ret = $self->provision($prefix,
797                                    "member server",
798                                    "localmember3",
799                                    "localmember",
800                                    3,
801                                    "localmemberpass");
802
803         $ret or die("Unable to provision");
804
805         my $net = $self->bindir_path("net");
806         my $cmd = "";
807         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
808         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
809         $cmd .= "$net join $ret->{CONFIGURATION} $dcvars->{DOMAIN} member";
810         $cmd .= " -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD}";
811
812         system($cmd) == 0 or die("Join failed\n$cmd");
813
814         $ret->{SMBD_TEST_FIFO} = "$prefix/smbd_test.fifo";
815         $ret->{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
816         $ret->{SMBD_TEST_LOG_POS} = 0;
817
818         $ret->{DC_SERVER} = $dcvars->{SERVER};
819         $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP};
820         $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME};
821         $ret->{DC_NETBIOSALIAS} = $dcvars->{NETBIOSALIAS};
822         $ret->{DC_USERNAME} = $dcvars->{USERNAME};
823         $ret->{DC_PASSWORD} = $dcvars->{PASSWORD};
824
825         return $ret;
826 }
827
828 sub provision_dc($$)
829 {
830         my ($self, $prefix) = @_;
831
832         print "PROVISIONING DC...";
833         my $ret = $self->provision($prefix,
834                                    "domain controller",
835                                    "localdc1",
836                                    "localdc",
837                                    1,
838                                    "localdcpass");
839
840         $self->add_wins_config("$prefix/private") or 
841                 die("Unable to add wins configuration");
842
843         $ret->{SMBD_TEST_FIFO} = "$prefix/server_test.fifo";
844         $ret->{SMBD_TEST_LOG} = "$prefix/server_test.log";
845         $ret->{SMBD_TEST_LOG_POS} = 0;
846         return $ret;
847 }
848
849 sub teardown_env($$)
850 {
851         my ($self, $envvars) = @_;
852         my $pid;
853
854         close(DATA);
855
856         if (-f "$envvars->{PIDDIR}/samba.pid" ) {
857                 open(IN, "<$envvars->{PIDDIR}/samba.pid") or die("unable to open server pid file");
858                 $pid = <IN>;
859                 close(IN);
860
861                 # Give the process 20 seconds to exit.  gcov needs
862                 # this time to write out the covarge data
863                 my $count = 0;
864                 until (kill(0, $pid) == 0) {
865                     # if no process sucessfully signalled, then we are done
866                     sleep(1);
867                     $count++;
868                     last if $count > 20;
869                 }
870                 
871                 # If it is still around, kill it
872                 if ($count > 20) {
873                     print "server process $pid took more than $count seconds to exit, killing\n";
874                     kill 9, $pid;
875                 }
876         }
877
878         my $failed = $? >> 8;
879
880         $self->slapd_stop($envvars) if ($self->{ldap});
881
882         print $self->getlog_env($envvars);
883
884         return $failed;
885 }
886
887 sub getlog_env($$)
888 {
889         my ($self, $envvars) = @_;
890         my $title = "SMBD LOG of: $envvars->{NETBIOSNAME}\n";
891         my $out = $title;
892
893         open(LOG, "<$envvars->{SMBD_TEST_LOG}");
894
895         seek(LOG, $envvars->{SMBD_TEST_LOG_POS}, SEEK_SET);
896         while (<LOG>) {
897                 $out .= $_;
898         }
899         $envvars->{SMBD_TEST_LOG_POS} = tell(LOG);
900         close(LOG);
901
902         return "" if $out eq $title;
903  
904         return $out;
905 }
906
907 sub check_env($$)
908 {
909         my ($self, $envvars) = @_;
910
911         return 1 if (-p $envvars->{SMBD_TEST_FIFO});
912
913         print $self->getlog_env($envvars);
914
915         return 0;
916 }
917
918 sub setup_env($$$)
919 {
920         my ($self, $envname, $path) = @_;
921
922         if ($envname eq "dc") {
923                 return $self->setup_dc("$path/dc");
924         } elsif ($envname eq "member") {
925                 if (not defined($self->{vars}->{dc})) {
926                         $self->setup_dc("$path/dc");
927                 }
928                 return $self->setup_member("$path/member", $self->{vars}->{dc});
929         } else {
930                 die("Samba4 can't provide environment '$envname'");
931         }
932 }
933
934 sub setup_member($$$$)
935 {
936         my ($self, $path, $dc_vars) = @_;
937
938         my $env = $self->provision_member($path, $dc_vars);
939
940         $self->check_or_start($env, ($ENV{SMBD_MAXTIME} or 7500));
941
942         $self->wait_for_start($env);
943
944         return $env;
945 }
946
947 sub setup_dc($$)
948 {
949         my ($self, $path) = @_;
950
951         my $env = $self->provision_dc($path);
952
953         $self->check_or_start($env, 
954                 ($ENV{SMBD_MAXTIME} or 7500));
955
956         $self->wait_for_start($env);
957
958         $self->{vars}->{dc} = $env;
959
960         return $env;
961 }
962
963 sub stop($)
964 {
965         my ($self) = @_;
966 }
967
968 1;