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