r22377: implement check_env() for samba4
[samba.git] / source4 / script / tests / 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 slapd_start($$)
26 {
27         my $count = 0;
28         my ($self, $env_vars) = @_;
29
30         my $uri = $env_vars->{LDAP_URI};
31
32         # running slapd in the background means it stays in the same process group, so it can be
33         # killed by timelimit
34         if ($self->{ldap} eq "fedora") {
35                 system("$ENV{FEDORA_DS_PREFIX}/sbin/ns-slapd -D $env_vars->{FEDORA_DS_DIR} -d0 -i $env_vars->{FEDORA_DS_PIDFILE}> $env_vars->{LDAPDIR}/logs 2>&1 &");
36         } elsif ($self->{ldap} eq "openldap") {
37                 my $oldpath = $ENV{PATH};
38                 $ENV{PATH} = "/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}";
39                 system("slapd -d0 -f $env_vars->{SLAPD_CONF} -h $uri > $env_vars->{LDAPDIR}/logs 2>&1 &");
40                 $ENV{PATH} = $oldpath;
41         }
42         while (system("$self->{bindir}/ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") != 0) {
43                 $count++;
44                 if ($count > 10) {
45                     $self->slapd_stop($env_vars);
46                     return 0;
47                 }
48                 sleep(1);
49         }
50         return 1;
51 }
52
53 sub slapd_stop($$)
54 {
55         my ($self, $envvars) = @_;
56         if ($self->{ldap} eq "fedora") {
57                 system("$envvars->{LDAPDIR}/slapd-samba4/stop-slapd");
58         } elsif ($self->{ldap} eq "openldap") {
59                 open(IN, "<$envvars->{OPENLDAP_PIDFILE}") or 
60                         die("unable to open slapd pid file: $envvars->{OPENLDAP_PIDFILE}");
61                 kill 9, <IN>;
62                 close(IN);
63         }
64 }
65
66 sub check_or_start($$$) 
67 {
68         my ($self, $env_vars, $max_time) = @_;
69         return 0 if ( -p $env_vars->{SMBD_TEST_FIFO});
70
71         unlink($env_vars->{SMBD_TEST_FIFO});
72         POSIX::mkfifo($env_vars->{SMBD_TEST_FIFO}, 0700);
73         unlink($env_vars->{SMBD_TEST_LOG});
74         
75         print "STARTING SMBD... ";
76         my $pid = fork();
77         if ($pid == 0) {
78                 open STDIN, $env_vars->{SMBD_TEST_FIFO};
79                 open STDOUT, ">$env_vars->{SMBD_TEST_LOG}";
80                 open STDERR, '>&STDOUT';
81                 
82                 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
83
84                 # Start slapd before smbd, but with the fifo on stdin
85                 if (defined($self->{ldap})) {
86                     $self->slapd_start($env_vars) or 
87                         die("couldn't start slapd");
88                     
89                     print "LDAP PROVISIONING...";
90                     $self->provision_ldap($env_vars);
91                 }
92                 
93                 my $valgrind = "";
94                 if (defined($ENV{SMBD_VALGRIND})) {
95                     $valgrind = $ENV{SMBD_VALGRIND};
96                 } 
97
98                 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG}; 
99
100                 my $optarg = "";
101                 if (defined($max_time)) {
102                         $optarg = "--maximum-runtime=$max_time ";
103                 }
104                 my $ret = system("$valgrind $self->{bindir}/smbd $optarg $env_vars->{CONFIGURATION} -M single -i --leak-report-full");
105                 if ($? == -1) {
106                         print "Unable to start smbd: $ret: $!\n";
107                         exit 1;
108                 }
109                 unlink($env_vars->{SMBD_TEST_FIFO});
110                 my $exit = $? >> 8;
111                 if ( $ret == 0 ) {
112                         print "smbd exits with status $exit\n";
113                 } elsif ( $ret & 127 ) {
114                         print "smbd got signal ".($ret & 127)." and exits with $exit!\n";
115                 } else {
116                         $ret = $? >> 8;
117                         print "smbd failed with status $exit!\n";
118                 }
119                 exit $exit;
120         }
121         print "DONE\n";
122
123         open(DATA, ">$env_vars->{SMBD_TEST_FIFO}");
124
125         return $pid;
126 }
127
128 sub wait_for_start($$)
129 {
130         my ($self, $testenv_vars) = @_;
131         # give time for nbt server to register its names
132         print "delaying for nbt name registration\n";
133
134         # This will return quickly when things are up, but be slow if we 
135         # need to wait for (eg) SSL init 
136         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
137         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER} $testenv_vars->{SERVER}");
138         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
139         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER} $testenv_vars->{NETBIOSNAME}");
140         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
141         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER} $testenv_vars->{NETBIOSNAME}");
142         system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
143         system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER} $testenv_vars->{NETBIOSNAME}");
144
145         print $self->getlog_env($testenv_vars);
146 }
147
148 sub write_ldb_file($$$)
149 {
150         my ($self, $file, $ldif) = @_;
151
152         open(LDIF, "|$self->{bindir}/ldbadd -H $file >/dev/null");
153         print LDIF $ldif;
154         return close(LDIF);
155 }
156
157 sub add_wins_config($$)
158 {
159         my ($self, $privatedir) = @_;
160
161         return $self->write_ldb_file("$privatedir/wins_config.ldb", "
162 dn: name=TORTURE_6,CN=PARTNERS
163 objectClass: wreplPartner
164 name: TORTURE_6
165 address: 127.0.0.6
166 pullInterval: 0
167 pushChangeCount: 0
168 type: 0x3
169 ");
170 }
171
172 sub mk_fedora($$$$$$)
173 {
174         my ($self, $ldapdir, $basedn, $root, $password, $privatedir, $configuration) = @_;
175
176         mkdir($ldapdir);
177
178         my $fedora_ds_inf = "$ldapdir/fedorads.inf";
179         my $fedora_ds_initial_ldif = "$ldapdir/fedorads-initial.ldif";
180
181         #Make the subdirectory be as fedora DS would expect
182         my $fedora_ds_dir = "$ldapdir/slapd-samba4";
183
184         my $pidfile = "$fedora_ds_dir/logs/slapd-samba4.pid";
185
186         open(CONF, ">$fedora_ds_inf");
187         print CONF "
188 [General]
189 SuiteSpotUserID = $root
190 FullMachineName=   localhost
191 ServerRoot=   $ldapdir
192
193 [slapd]
194 ldapifilepath=$ldapdir/ldapi
195 Suffix= $basedn
196 RootDN= cn=Manager,$basedn
197 RootDNPwd= $password
198 ServerIdentifier= samba4
199 InstallLdifFile=$fedora_ds_initial_ldif
200
201 inst_dir= $fedora_ds_dir
202 config_dir= $fedora_ds_dir
203 schema_dir= $fedora_ds_dir/schema
204 lock_dir= $fedora_ds_dir/lock
205 log_dir= $fedora_ds_dir/logs
206 run_dir= $fedora_ds_dir/logs
207 db_dir= $fedora_ds_dir/db
208 bak_dir= $fedora_ds_dir/bak
209 tmp_dir= $fedora_ds_dir/tmp
210 ldif_dir= $fedora_ds_dir/ldif
211 cert_dir= $fedora_ds_dir
212
213 start_server= 0
214 ";
215         close(CONF);
216
217         open(LDIF, ">$fedora_ds_initial_ldif");
218         print LDIF "
219 # These entries need to be added to get the container for the 
220 # provision to be aimed at.
221
222 dn: cn=\"dc=$basedn\",cn=mapping tree,cn=config
223 objectclass: top
224 objectclass: extensibleObject
225 objectclass: nsMappingTree
226 nsslapd-state: backend
227 nsslapd-backend: userData
228 cn: $basedn
229
230 dn: cn=userData,cn=ldbm database,cn=plugins,cn=config
231 objectclass: extensibleObject
232 objectclass: nsBackendInstance
233 nsslapd-suffix: $basedn
234 ";
235         close(LDIF);
236
237         system("perl $ENV{FEDORA_DS_PREFIX}/bin/ds_newinst.pl $fedora_ds_inf >&2") == 0 or return 0;
238
239         foreach(<$fedora_ds_dir/schema/*>) {
240                 unlink unless (/00core.*/);
241         }
242
243         open(LDIF, ">>$fedora_ds_dir/dse.ldif");
244         print LDIF "dn: cn=bitwise,cn=plugins,cn=config
245 objectClass: top
246 objectClass: nsSlapdPlugin
247 objectClass: extensibleObject
248 cn: bitwise
249 nsslapd-pluginPath: $ENV{FEDORA_DS_PREFIX}/lib/fedora-ds/plugins/libbitwise-plugin.so
250 nsslapd-pluginInitfunc: bitwise_init
251 nsslapd-pluginType: matchingRule
252 nsslapd-pluginEnabled: on
253 nsslapd-pluginId: bitwise
254 nsslapd-pluginVersion: 1.1.0a3
255 nsslapd-pluginVendor: Fedora Project
256 nsslapd-pluginDescription: Allow bitwise matching rules
257 ";
258         close(LDIF);
259
260         system("$self->{bindir}/ad2oLschema $configuration -H $privatedir/sam.ldb --option=convert:target=fedora-ds -I $self->{setupdir}/schema-map-fedora-ds-1.0 -O $fedora_ds_dir/schema/99_ad.ldif >&2");
261
262         return ($fedora_ds_dir, $pidfile);
263 }
264
265 sub mk_openldap($$$$$$$$)
266 {
267         my ($self, $ldapdir, $basedn, $password, $privatedir, $dnsname, $configuration, $provision_options) = @_;
268
269         my $slapd_conf = "$ldapdir/slapd.conf";
270         my $pidfile = "$ldapdir/slapd.pid";
271         my $modconf = "$ldapdir/modules.conf";
272
273         mkdir($_) foreach ($ldapdir, "$ldapdir/db", "$ldapdir/db/bdb-logs", 
274                 "$ldapdir/db/tmp");
275
276         open(CONF, ">$slapd_conf");
277         print CONF "
278 loglevel 0
279
280 include $ldapdir/ad.schema
281
282 pidfile         $pidfile
283 argsfile        $ldapdir/slapd.args
284 sasl-realm $dnsname
285 access to * by * write
286
287 allow update_anon
288
289 authz-regexp
290           uid=([^,]*),cn=$dnsname,cn=digest-md5,cn=auth
291           ldap:///$basedn??sub?(samAccountName=\$1)
292
293 authz-regexp
294           uid=([^,]*),cn=([^,]*),cn=digest-md5,cn=auth
295           ldap:///$basedn??sub?(samAccountName=\$1)
296
297 include $modconf
298
299 defaultsearchbase \"$basedn\"
300
301 backend         bdb
302 database        bdb
303 suffix          \"$basedn\"
304 rootdn          \"cn=Manager,$basedn\"
305 rootpw          $password
306 directory       $ldapdir/db
307 index           objectClass eq
308 index           samAccountName eq
309 index name eq
310 index objectSid eq
311 index objectCategory eq
312 index member eq
313 index uidNumber eq
314 index gidNumber eq
315 index unixName eq
316 index privilege eq
317 index nCName eq pres
318 index lDAPDisplayName eq
319 index subClassOf eq
320 index dnsRoot eq
321 index nETBIOSName eq pres
322
323 #syncprov is stable in OpenLDAP 2.3, and available in 2.2.  
324 #We only need this for the contextCSN attribute anyway....
325 overlay syncprov
326 syncprov-checkpoint 100 10
327 syncprov-sessionlog 100
328 ";
329
330         close(CONF);
331
332         open(CONF, ">$ldapdir/db/DB_CONFIG");
333         print CONF "
334 #
335         # Set the database in memory cache size.
336         #
337         set_cachesize   0       524288        0
338         
339         
340         #
341         # Set database flags (this is a test environment, we don't need to fsync()).
342         #               
343         set_flags       DB_TXN_NOSYNC
344         
345         #
346         # Set log values.
347         #
348         set_lg_regionmax        104857
349         set_lg_max              1048576
350         set_lg_bsize            209715
351         set_lg_dir              $ldapdir/db/bdb-logs
352         
353         
354         #
355         # Set temporary file creation directory.
356         #                       
357         set_tmp_dir             $ldapdir/db/tmp
358         ";
359         close(CONF);
360
361         #This uses the provision we just did, to read out the schema
362         system("$self->{bindir}/ad2oLschema $configuration -H $privatedir/sam.ldb -I $self->{setupdir}/schema-map-openldap-2.3 -O $ldapdir/ad.schema >&2");
363
364         #Now create an LDAP baseDN
365         system("$self->{bindir}/smbscript $self->{setupdir}/provision $provision_options --ldap-base >&2");
366
367         my $oldpath = $ENV{PATH};
368         $ENV{PATH} = "/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}";
369
370         unlink($modconf);
371         open(CONF, ">$modconf"); close(CONF);
372
373         if (system("slaptest -u -f $slapd_conf >&2") != 0) {
374                 open(CONF, ">$modconf"); 
375                 # enable slapd modules
376                 print CONF "
377 modulepath      /usr/lib/ldap
378 moduleload      back_bdb
379 moduleload      syncprov
380 ";
381                 close(CONF);
382         }
383
384         system("slaptest -u -f $slapd_conf") == 0 or die("slaptest still fails after adding modules");
385         system("slapadd -f $slapd_conf < $privatedir/$dnsname.ldif >/dev/null") == 0 or die("slapadd failed");
386
387     system("slaptest -f $slapd_conf >/dev/null") == 0 or 
388                 die ("slaptest after database load failed");
389     
390         $ENV{PATH} = $oldpath;
391
392         return ($slapd_conf, $pidfile);
393 }
394
395 sub provision($$$$$)
396 {
397         my ($self, $prefix, $server_role, $domain, $netbiosname, $swiface) = @_;
398
399         my $smbd_loglevel = 1;
400         my $username = "administrator";
401         my $realm = "SAMBA.EXAMPLE.COM";
402         my $dnsname = "samba.example.com";
403         my $basedn = "dc=samba,dc=example,dc=com";
404         my $password = "penguin";
405         my $root = ($ENV{USER} or $ENV{LOGNAME} or `whoami`);
406         my $server = "localhost";
407         my $srcdir="$RealBin/../..";
408         -d $prefix or mkdir($prefix) or die("Unable to create $prefix");
409         my $prefix_abs = abs_path($prefix);
410         my $tmpdir = "$prefix_abs/tmp";
411         my $etcdir = "$prefix_abs/etc";
412         my $piddir = "$prefix_abs/pid";
413         my $conffile = "$etcdir/smb.conf";
414         my $krb5_config = "$etcdir/krb5.conf";
415         my $privatedir = "$prefix_abs/private";
416         my $ncalrpcdir = "$prefix_abs/ncalrpc";
417         my $lockdir = "$prefix_abs/lockdir";
418         my $winbindd_socket_dir = "$prefix_abs/winbind_socket";
419
420         my $configuration = "--configfile=$conffile";
421         my $ldapdir = "$prefix_abs/ldap";
422
423         my $tlsdir = "$privatedir/tls";
424
425         my $ifaceipv4 = "127.0.0.$swiface";
426         my $interfaces = "$ifaceipv4/8";
427
428         (system("rm -rf $prefix/*") == 0) or die("Unable to clean up");
429         mkdir($_) foreach ($privatedir, $etcdir, $piddir, $ncalrpcdir, $lockdir, 
430                 $tmpdir);
431
432         open(CONFFILE, ">$conffile");
433         print CONFFILE "
434 [global]
435         netbios name = $netbiosname
436         netbios aliases = $server
437         workgroup = $domain
438         realm = $realm
439         private dir = $privatedir
440         pid directory = $piddir
441         ncalrpc dir = $ncalrpcdir
442         lock dir = $lockdir
443         setup directory = $self->{setupdir}
444         js include = $srcdir/scripting/libjs
445         winbindd socket directory = $winbindd_socket_dir
446         name resolve order = bcast
447         interfaces = $interfaces
448         tls dh params file = $tlsdir/dhparms.pem
449         panic action = $srcdir/script/gdb_backtrace \%PID% \%PROG%
450         wins support = yes
451         server role = $server_role
452         max xmit = 32K
453         server max protocol = SMB2
454         notify:inotify = false
455         ldb:nosync = true
456         system:anonymous = true
457 #We don't want to pass our self-tests if the PAC code is wrong
458         gensec:require_pac = true
459         log level = $smbd_loglevel
460
461 [tmp]
462         path = $tmpdir
463         read only = no
464         ntvfs handler = posix
465         posix:sharedelay = 100000
466         posix:eadb = $lockdir/eadb.tdb
467
468 [cifs]
469         read only = no
470         ntvfs handler = cifs
471         cifs:server = $netbiosname
472         cifs:share = tmp
473 #There is no username specified here, instead the client is expected
474 #to log in with kerberos, and smbd will used delegated credentials.
475
476 [simple]
477         path = $tmpdir
478         read only = no
479         ntvfs handler = simple
480
481 [cifsposixtestshare]
482         copy = simple
483         ntvfs handler = cifsposix   
484 ";
485         close(CONFFILE);
486
487         die ("Unable to create key blobs") if
488                 (system("TLSDIR=$tlsdir $RealBin/mk-keyblobs.sh") != 0);
489
490         open(KRB5CONF, ">$krb5_config");
491         print KRB5CONF "
492 #Generated krb5.conf for $realm
493
494 [libdefaults]
495  default_realm = $realm
496  dns_lookup_realm = false
497  dns_lookup_kdc = false
498  ticket_lifetime = 24h
499  forwardable = yes
500
501 [realms]
502  $realm = {
503   kdc = 127.0.0.1:88
504   admin_server = 127.0.0.1:88
505   default_domain = $dnsname
506  }
507  $dnsname = {
508   kdc = 127.0.0.1:88
509   admin_server = 127.0.0.1:88
510   default_domain = $dnsname
511  }
512  $domain = {
513   kdc = 127.0.0.1:88
514   admin_server = 127.0.0.1:88
515   default_domain = $dnsname
516  }
517
518 [appdefaults]
519         pkinit_anchors = FILE:$tlsdir/ca.pem
520
521 [kdc]
522         enable-pkinit = true
523         pkinit_identity = FILE:$tlsdir/kdc.pem,$tlsdir/key.pem
524         pkinit_anchors = FILE:$tlsdir/ca.pem
525
526 [domain_realm]
527  .$dnsname = $realm
528 ";
529         close(KRB5CONF);
530
531 #Ensure the config file is valid before we start
532         if (system("$self->{bindir}/testparm $configuration -v --suppress-prompt >/dev/null 2>&1") != 0) {
533                 system("$self->{bindir}/testparm $configuration >&2");
534                 die("Failed to create configuration!");
535         }
536
537         (system("($self->{bindir}/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 configuration!");
538
539         my @provision_options = ($configuration);
540         push (@provision_options, "--host-name=$netbiosname");
541         push (@provision_options, "--host-ip=$ifaceipv4");
542         push (@provision_options, "--quiet");
543         push (@provision_options, "--domain $domain");
544         push (@provision_options, "--realm $realm");
545         push (@provision_options, "--adminpass $password");
546         push (@provision_options, "--root=$root");
547         push (@provision_options, "--simple-bind-dn=cn=Manager,$basedn");
548         push (@provision_options, "--password=$password");
549         push (@provision_options, "--root=$root");
550
551         (system("$self->{bindir}/smbscript $self->{setupdir}/provision " .  join(' ', @provision_options) . ">&2") == 0) or die("Unable to provision");
552
553         my $ldap_uri= "$ldapdir/ldapi";
554         $ldap_uri =~ s|/|%2F|g;
555         $ldap_uri = "ldapi://$ldap_uri";
556
557         my $ret = {
558                 KRB5_CONFIG => $krb5_config,
559                 PIDDIR => $piddir,
560                 SERVER => $server,
561                 NETBIOSNAME => $netbiosname,
562                 LDAP_URI => $ldap_uri,
563                 DOMAIN => $domain,
564                 USERNAME => $username,
565                 REALM => $realm,
566                 PASSWORD => $password,
567                 LDAPDIR => $ldapdir,
568                 WINBINDD_SOCKET_DIR => $winbindd_socket_dir,
569                 NCALRPCDIR => $ncalrpcdir,
570                 CONFIGURATION => $configuration,
571                 SOCKET_WRAPPER_DEFAULT_IFACE => $swiface
572         };
573
574         if (not defined($self->{ldap})) {
575         } elsif ($self->{ldap} eq "openldap") {
576                 ($ret->{SLAPD_CONF}, $ret->{OPENLDAP_PIDFILE}) = $self->mk_openldap($ldapdir, $basedn, $password, $privatedir, $dnsname, $configuration, join(' ', @provision_options)) or die("Unable to create openldap directories");
577         } elsif ($self->{ldap} eq "fedora") {
578                 ($ret->{FEDORA_DS_DIR}, $ret->{FEDORA_DS_PIDFILE}) = $self->mk_fedora($ldapdir, $basedn, $root, $password, $privatedir, $configuration) or die("Unable to create fedora ds directories");
579                 push (@provision_options, "--ldap-module=nsuniqueid");
580         }
581
582         $ret->{PROVISION_OPTIONS} = join(' ', @provision_options);
583
584         return $ret; 
585 }
586
587 sub provision_member($$$)
588 {
589         my ($self, $prefix, $dcvars) = @_;
590         print "PROVISIONING MEMBER...";
591
592         my $ret = $self->provision($prefix, "member server", "SAMBADOMAIN", 
593                 "localmember", 3);
594
595         $ret or die("Unable to provision");
596
597         system("$self->{bindir}/net join $ret->{CONFIGURATION} $dcvars->{DOMAIN} member -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD}") == 0 or die("Join failed");
598
599         $ret->{SMBD_TEST_FIFO} = "$prefix/smbd_test.fifo";
600         $ret->{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
601         $ret->{SMBD_TEST_LOG_POS} = 0;
602         return $ret;
603 }
604
605 sub provision_dc($$)
606 {
607         my ($self, $prefix) = @_;
608
609         print "PROVISIONING DC...";
610         my $ret = $self->provision($prefix, "domain controller", "SAMBADOMAIN", 
611                 "localtest", 1);
612
613         $self->add_wins_config("$prefix/private") or 
614                 die("Unable to add wins configuration");
615
616         $ret->{SMBD_TEST_FIFO} = "$prefix/smbd_test.fifo";
617         $ret->{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
618         $ret->{SMBD_TEST_LOG_POS} = 0;
619         return $ret;
620 }
621
622 sub provision_ldap($$)
623 {
624         my ($self, $envvars) = @_;
625         my $provision_aci = "";
626         
627         if ($self->{ldap} eq "fedora") {
628                 #it is easier to base64 encode this than correctly escape it:
629                 # (targetattr = "*") (version 3.0;acl "full access to all by all";allow (all)(userdn = "ldap:///anyone");)
630                 $provision_aci = "--aci=aci:: KHRhcmdldGF0dHIgPSAiKiIpICh2ZXJzaW9uIDMuMDthY2wgImZ1bGwgYWNjZXNzIHRvIGFsbCBieSBhbGwiO2FsbG93IChhbGwpKHVzZXJkbiA9ICJsZGFwOi8vL2FueW9uZSIpOykK";
631         }
632
633         system("$self->{bindir}/smbscript $self->{setupdir}/provision $envvars->{PROVISION_OPTIONS} \"$provision_aci\" --ldap-backend=$envvars->{LDAP_URI}") and
634                 die("LDAP PROVISIONING failed: $self->{bindir}/smbscript $self->{setupdir}/provision $envvars->{PROVISION_OPTIONS} \"$provision_aci\" --ldap-backend=$envvars->{LDAP_URI}");
635 }
636
637 sub teardown_env($$)
638 {
639         my ($self, $envvars) = @_;
640
641         close(DATA);
642
643         sleep(2);
644
645         my $failed = $? >> 8;
646
647         if (-f "$envvars->{PIDDIR}/smbd.pid" ) {
648                 open(IN, "<$envvars->{PIDDIR}/smbd.pid") or die("unable to open smbd pid file");
649                 kill 9, <IN>;
650                 close(IN);
651         }
652
653         $self->slapd_stop($envvars) if ($self->{ldap});
654
655         return $failed;
656 }
657
658 sub getlog_env($$)
659 {
660         my ($self, $envvars) = @_;
661         my $title = "SMBD LOG of: $envvars->{NETBIOSNAME}\n";
662         my $out = $title;
663
664         open(LOG, "<$envvars->{SMBD_TEST_LOG}");
665
666         seek(LOG, $envvars->{SMBD_TEST_LOG_POS}, SEEK_SET);
667         while (<LOG>) {
668                 $out .= $_;
669         }
670         $envvars->{SMBD_TEST_LOG_POS} = tell(LOG);
671         close(LOG);
672
673         return "" if $out eq $title;
674  
675         return $out;
676 }
677
678 sub check_env($$)
679 {
680         my ($self, $envvars) = @_;
681
682         return 1 if (-p $envvars->{SMBD_TEST_FIFO});
683
684         return 0;
685 }
686
687 sub setup_env($$$)
688 {
689         my ($self, $envname, $path) = @_;
690
691         if ($envname eq "dc") {
692                 return $self->setup_dc("$path/dc");
693         } elsif ($envname eq "member") {
694                 if (not defined($self->{vars}->{dc})) {
695                         $self->setup_dc("$path/dc");
696                 }
697                 return $self->setup_member("$path/member", $self->{vars}->{dc});
698         } else {
699                 die("Samba4 can't provide environment '$envname'");
700         }
701 }
702
703 sub setup_member($$$$)
704 {
705         my ($self, $path, $dc_vars) = @_;
706
707         my $env = $self->provision_member($path, $dc_vars);
708
709         $self->check_or_start($env, ($ENV{SMBD_MAX_TIME} or 5400));
710
711         $self->wait_for_start($env);
712
713         return $env;
714 }
715
716 sub setup_dc($$)
717 {
718         my ($self, $path) = @_;
719
720         my $env = $self->provision_dc($path);
721
722         $self->check_or_start($env, 
723                 ($ENV{SMBD_MAX_TIME} or 5400));
724
725         $self->wait_for_start($env);
726
727         $self->{vars}->{dc} = $env;
728
729         return $env;
730 }
731
732 sub stop($)
733 {
734         my ($self) = @_;
735 }
736
737 1;