r22494: Skip subSchema again, but we will need to remap this objectClass.
[samba.git] / source4 / script / tests / Samba4.pm
index 4f8c0877ae01e2f3c871a8781f28bd9a12486038..e9166cef09b6fe2979f9695506d3c1c8ee6e69a9 100644 (file)
@@ -6,6 +6,7 @@
 package Samba4;
 
 use strict;
+use Cwd qw(abs_path);
 use FindBin qw($RealBin);
 use POSIX;
 
@@ -21,6 +22,14 @@ sub new($$$$) {
        return $self;
 }
 
+sub openldap_start($$$) {
+        my ($slapd_conf, $uri, $logs) = @_;
+        my $oldpath = $ENV{PATH};
+        $ENV{PATH} = "/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}";
+        system("slapd -d -f $slapd_conf -h $uri > $logs 2>&1 &");
+        $ENV{PATH} = $oldpath;
+}
+
 sub slapd_start($$)
 {
        my $count = 0;
@@ -33,14 +42,11 @@ sub slapd_start($$)
        if ($self->{ldap} eq "fedora") {
                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 &");
        } elsif ($self->{ldap} eq "openldap") {
-               my $oldpath = $ENV{PATH};
-               $ENV{PATH} = "/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}";
-               system("slapd -d0 -f $env_vars->{SLAPD_CONF} -h $uri > $env_vars->{LDAPDIR}/logs 2>&1 &");
-               $ENV{PATH} = $oldpath;
+               openldap_start($env_vars->{SLAPD_CONF}, $uri, "$env_vars->{LDAPDIR}/logs");
        }
        while (system("$self->{bindir}/ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") != 0) {
                $count++;
-               if ($count > 10) {
+               if ($count > 40) {
                    $self->slapd_stop($env_vars);
                    return 0;
                }
@@ -60,6 +66,7 @@ sub slapd_stop($$)
                kill 9, <IN>;
                close(IN);
        }
+       return 1;
 }
 
 sub check_or_start($$$) 
@@ -67,32 +74,32 @@ sub check_or_start($$$)
        my ($self, $env_vars, $max_time) = @_;
        return 0 if ( -p $env_vars->{SMBD_TEST_FIFO});
 
-       # Start slapd before smbd
-       if (defined($self->{ldap})) {
-               $self->slapd_start($env_vars) or 
-                       die("couldn't start slapd");
-
-               print "LDAP PROVISIONING...";
-               $self->provision_ldap($env_vars);
-       }
-
-       SocketWrapper::set_default_iface(1);
-
        unlink($env_vars->{SMBD_TEST_FIFO});
        POSIX::mkfifo($env_vars->{SMBD_TEST_FIFO}, 0700);
        unlink($env_vars->{SMBD_TEST_LOG});
        
-       my $valgrind = "";
-       if (defined($ENV{SMBD_VALGRIND})) {
-               $valgrind = $ENV{SMBD_VALGRIND};
-       } 
-
        print "STARTING SMBD... ";
        my $pid = fork();
        if ($pid == 0) {
                open STDIN, $env_vars->{SMBD_TEST_FIFO};
                open STDOUT, ">$env_vars->{SMBD_TEST_LOG}";
                open STDERR, '>&STDOUT';
+               
+               SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
+
+               my $valgrind = "";
+               if (defined($ENV{SMBD_VALGRIND})) {
+                   $valgrind = $ENV{SMBD_VALGRIND};
+               } 
+
+               $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG}; 
+
+               # Start slapd before smbd, but with the fifo on stdin
+               if (defined($self->{ldap})) {
+                   $self->slapd_start($env_vars) or 
+                       die("couldn't start slapd (2nd time)");
+               }
+
                my $optarg = "";
                if (defined($max_time)) {
                        $optarg = "--maximum-runtime=$max_time ";
@@ -137,6 +144,10 @@ sub wait_for_start($$)
        system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER} $testenv_vars->{NETBIOSNAME}");
        system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
        system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER} $testenv_vars->{NETBIOSNAME}");
+       system("bin/nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
+       system("bin/nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER} $testenv_vars->{NETBIOSNAME}");
+
+       print $self->getlog_env($testenv_vars);
 }
 
 sub write_ldb_file($$$)
@@ -167,7 +178,7 @@ sub mk_fedora($$$$$$)
 {
        my ($self, $ldapdir, $basedn, $root, $password, $privatedir, $configuration) = @_;
 
-       mkdir($ldapdir);
+       mkdir($ldapdir, 0777);
 
        my $fedora_ds_inf = "$ldapdir/fedorads.inf";
        my $fedora_ds_initial_ldif = "$ldapdir/fedorads-initial.ldif";
@@ -213,7 +224,7 @@ start_server= 0
 # These entries need to be added to get the container for the 
 # provision to be aimed at.
 
-dn: cn=\"dc=$basedn\",cn=mapping tree,cn=config
+dn: cn=\"$basedn\",cn=mapping tree,cn=config
 objectclass: top
 objectclass: extensibleObject
 objectclass: nsMappingTree
@@ -225,11 +236,47 @@ dn: cn=userData,cn=ldbm database,cn=plugins,cn=config
 objectclass: extensibleObject
 objectclass: nsBackendInstance
 nsslapd-suffix: $basedn
+cn=userData
+
+dn: cn=\"cn=Configuration,$basedn\",cn=mapping tree,cn=config
+objectclass: top
+objectclass: extensibleObject
+objectclass: nsMappingTree
+nsslapd-state: backend
+nsslapd-backend: configData
+nsslapd-parent-suffix: $basedn
+cn: cn=Configuration,$basedn
+
+dn: cn=configData,cn=ldbm database,cn=plugins,cn=config
+objectclass: extensibleObject
+objectclass: nsBackendInstance
+nsslapd-suffix: cn=Configuration,$basedn
+cn=configData
+
+dn: cn=\"cn=Schema,cn=Configuration,$basedn\",cn=mapping tree,cn=config
+objectclass: top
+objectclass: extensibleObject
+objectclass: nsMappingTree
+nsslapd-state: backend
+nsslapd-backend: schemaData
+nsslapd-parent-suffix: cn=Configuration,$basedn
+cn: cn=Schema,cn=Configuration,$basedn
+
+dn: cn=schemaData,cn=ldbm database,cn=plugins,cn=config
+objectclass: extensibleObject
+objectclass: nsBackendInstance
+nsslapd-suffix: cn=Schema,cn=Configuration,$basedn
+cn=schemaData
 ";
        close(LDIF);
 
-       system("perl $ENV{FEDORA_DS_PREFIX}/bin/ds_newinst.pl $fedora_ds_inf >&2") == 0 or return 0;
-
+my $dir = getcwd();
+chdir "$ENV{FEDORA_DS_PREFIX}/bin" || die;
+       if (system("perl $ENV{FEDORA_DS_PREFIX}/bin/ds_newinst.pl $fedora_ds_inf >&2") != 0) {
+            chdir $dir;
+            die("perl $ENV{FEDORA_DS_PREFIX}/bin/ds_newinst.pl $fedora_ds_inf FAILED: $?");
+        }
+        chdir $dir || die;
        foreach(<$fedora_ds_dir/schema/*>) {
                unlink unless (/00core.*/);
        }
@@ -251,11 +298,45 @@ nsslapd-pluginDescription: Allow bitwise matching rules
 ";
        close(LDIF);
 
-       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");
+       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");
 
        return ($fedora_ds_dir, $pidfile);
 }
 
+sub write_openldap_dbconfig($) {
+    my ( $ldapdbdir ) = @_;
+       open(CONF, ">$ldapdbdir/DB_CONFIG");
+       print CONF "
+#
+       # Set the database in memory cache size.
+       #
+       set_cachesize   0       524288        0
+       
+       
+       #
+       # Set database flags (this is a test environment, we don't need to fsync()).
+       #               
+       set_flags       DB_TXN_NOSYNC
+       
+       #
+       # Set log values.
+       #
+       set_lg_regionmax        104857
+       set_lg_max              1048576
+       set_lg_bsize            209715
+       set_lg_dir              $ldapdbdir/bdb-logs
+       
+       
+       #
+       # Set temporary file creation directory.
+       #                       
+       set_tmp_dir             $ldapdbdir/tmp
+       ";
+       close(CONF);
+
+
+}
+
 sub mk_openldap($$$$$$$$)
 {
        my ($self, $ldapdir, $basedn, $password, $privatedir, $dnsname, $configuration, $provision_options) = @_;
@@ -264,7 +345,7 @@ sub mk_openldap($$$$$$$$)
        my $pidfile = "$ldapdir/slapd.pid";
        my $modconf = "$ldapdir/modules.conf";
 
-       mkdir($_) foreach ($ldapdir, "$ldapdir/db", "$ldapdir/db/bdb-logs", 
+       mkdir($_, 0777) foreach ($ldapdir, "$ldapdir/db", "$ldapdir/db/user", "$ldapdir/db/config", "$ldapdir/db/schema", "$ldapdir/db/bdb-logs", 
                "$ldapdir/db/tmp");
 
        open(CONF, ">$slapd_conf");
@@ -293,11 +374,34 @@ include $modconf
 defaultsearchbase \"$basedn\"
 
 backend                bdb
+database        bdb
+suffix         \"cn=Schema,cn=Configuration,$basedn\"
+directory      $ldapdir/db/schema
+index           objectClass eq
+index           samAccountName eq
+index name eq
+index objectCategory eq
+index lDAPDisplayName eq
+index subClassOf eq
+
+database        bdb
+suffix         \"cn=Configuration,$basedn\"
+directory      $ldapdir/db/config
+index           objectClass eq
+index           samAccountName eq
+index name eq
+index objectSid eq
+index objectCategory eq
+index nCName eq pres
+index subClassOf eq
+index dnsRoot eq
+index nETBIOSName eq pres
+
 database        bdb
 suffix         \"$basedn\"
 rootdn          \"cn=Manager,$basedn\"
 rootpw          $password
-directory      $ldapdir/db
+directory      $ldapdir/db/user
 index           objectClass eq
 index           samAccountName eq
 index name eq
@@ -322,41 +426,16 @@ syncprov-sessionlog 100
 ";
 
        close(CONF);
-
-       open(CONF, ">$ldapdir/db/DB_CONFIG");
-       print CONF "
-#
-       # Set the database in memory cache size.
-       #
-       set_cachesize   0       524288        0
-       
        
-       #
-       # Set database flags (this is a test environment, we don't need to fsync()).
-       #               
-       set_flags       DB_TXN_NOSYNC
-       
-       #
-       # Set log values.
-       #
-       set_lg_regionmax        104857
-       set_lg_max              1048576
-       set_lg_bsize            209715
-       set_lg_dir              $ldapdir/db/bdb-logs
-       
-       
-       #
-       # Set temporary file creation directory.
-       #                       
-       set_tmp_dir             $ldapdir/db/tmp
-       ";
-       close(CONF);
+       write_openldap_dbconfig("$ldapdir/db/user");
+       write_openldap_dbconfig("$ldapdir/db/config");
+       write_openldap_dbconfig("$ldapdir/db/schema");
 
        #This uses the provision we just did, to read out the schema
-       system("$self->{bindir}/ad2oLschema $configuration -H $privatedir/sam.ldb -I $self->{setupdir}/schema-map-openldap-2.3 -O $ldapdir/ad.schema >&2");
+       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");
 
        #Now create an LDAP baseDN
-       system("$self->{bindir}/smbscript $self->{setupdir}/provision $provision_options --ldap-base >&2");
+       system("$self->{bindir}/smbscript $self->{setupdir}/provision $provision_options --ldap-base >&2") == 0 or die("creating an OpenLDAP basedn failed");
 
        my $oldpath = $ENV{PATH};
        $ENV{PATH} = "/usr/local/sbin:/usr/sbin:/sbin:$ENV{PATH}";
@@ -376,7 +455,9 @@ moduleload  syncprov
        }
 
        system("slaptest -u -f $slapd_conf") == 0 or die("slaptest still fails after adding modules");
-       system("slapadd -f $slapd_conf < $privatedir/$dnsname.ldif >/dev/null") == 0 or die("slapadd failed");
+       system("slapadd -b $basedn -f $slapd_conf -l $privatedir/$dnsname.ldif >/dev/null") == 0 or die("slapadd failed");
+       system("slapadd -b cn=Configuration,$basedn -f $slapd_conf -l $privatedir/$dnsname-config.ldif >/dev/null") == 0 or die("slapadd failed");
+       system("slapadd -b cn=Schema,cn=Configuration,$basedn -f $slapd_conf -l $privatedir/$dnsname-schema.ldif >/dev/null") == 0 or die("slapadd failed");
 
     system("slaptest -f $slapd_conf >/dev/null") == 0 or 
                die ("slaptest after database load failed");
@@ -388,7 +469,7 @@ moduleload  syncprov
 
 sub provision($$$$$)
 {
-       my ($self, $prefix, $server_role, $domain, $netbiosname) = @_;
+       my ($self, $prefix, $server_role, $domain, $netbiosname, $swiface) = @_;
 
        my $smbd_loglevel = 1;
        my $username = "administrator";
@@ -399,9 +480,8 @@ sub provision($$$$$)
        my $root = ($ENV{USER} or $ENV{LOGNAME} or `whoami`);
        my $server = "localhost";
        my $srcdir="$RealBin/../..";
-       -d $prefix or mkdir($prefix) or die("Unable to create $prefix");
-       my $prefix_abs = getcwd()."/".$prefix;
-
+       -d $prefix or mkdir($prefix, 0777) or die("Unable to create $prefix");
+       my $prefix_abs = abs_path($prefix);
        my $tmpdir = "$prefix_abs/tmp";
        my $etcdir = "$prefix_abs/etc";
        my $piddir = "$prefix_abs/pid";
@@ -409,16 +489,19 @@ sub provision($$$$$)
        my $krb5_config = "$etcdir/krb5.conf";
        my $privatedir = "$prefix_abs/private";
        my $ncalrpcdir = "$prefix_abs/ncalrpc";
-       my $lockdir= "$prefix_abs/lockdir";
-
+       my $lockdir = "$prefix_abs/lockdir";
        my $winbindd_socket_dir = "$prefix_abs/winbind_socket";
+
        my $configuration = "--configfile=$conffile";
        my $ldapdir = "$prefix_abs/ldap";
 
        my $tlsdir = "$privatedir/tls";
 
+       my $ifaceipv4 = "127.0.0.$swiface";
+       my $interfaces = "$ifaceipv4/8";
+
        (system("rm -rf $prefix/*") == 0) or die("Unable to clean up");
-       mkdir($_) foreach ($privatedir, $etcdir, $piddir, $ncalrpcdir, $lockdir, 
+       mkdir($_, 0777) foreach ($privatedir, $etcdir, $piddir, $ncalrpcdir, $lockdir, 
                $tmpdir);
 
        open(CONFFILE, ">$conffile");
@@ -436,7 +519,7 @@ sub provision($$$$$)
        js include = $srcdir/scripting/libjs
        winbindd socket directory = $winbindd_socket_dir
        name resolve order = bcast
-       interfaces = 127.0.0.1/8
+       interfaces = $interfaces
        tls dh params file = $tlsdir/dhparms.pem
        panic action = $srcdir/script/gdb_backtrace \%PID% \%PROG%
        wins support = yes
@@ -460,11 +543,10 @@ sub provision($$$$$)
 [cifs]
        read only = no
        ntvfs handler = cifs
-       cifs:server = $server
-       cifs:user = $username
-       cifs:password = $password
-       cifs:domain = $domain
+       cifs:server = $netbiosname
        cifs:share = tmp
+#There is no username specified here, instead the client is expected
+#to log in with kerberos, and smbd will used delegated credentials.
 
 [simple]
        path = $tmpdir
@@ -524,14 +606,14 @@ sub provision($$$$$)
 #Ensure the config file is valid before we start
        if (system("$self->{bindir}/testparm $configuration -v --suppress-prompt >/dev/null 2>&1") != 0) {
                system("$self->{bindir}/testparm $configuration >&2");
-               die("Failed to create configuration!");
+               die("Failed to create a valid smb.conf configuration!");
        }
 
-       (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!");
+       (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!");
 
        my @provision_options = ($configuration);
        push (@provision_options, "--host-name=$netbiosname");
-       push (@provision_options, "--host-ip=127.0.0.1");
+       push (@provision_options, "--host-ip=$ifaceipv4");
        push (@provision_options, "--quiet");
        push (@provision_options, "--domain $domain");
        push (@provision_options, "--realm $realm");
@@ -560,19 +642,32 @@ sub provision($$$$$)
                LDAPDIR => $ldapdir,
                WINBINDD_SOCKET_DIR => $winbindd_socket_dir,
                NCALRPCDIR => $ncalrpcdir,
-               CONFIGURATION => $configuration
+               CONFIGURATION => $configuration,
+               SOCKET_WRAPPER_DEFAULT_IFACE => $swiface
        };
 
-       if (not defined($self->{ldap})) {
-       } elsif ($self->{ldap} eq "openldap") {
-               ($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");
-       } elsif ($self->{ldap} eq "fedora") {
-               ($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");
-               push (@provision_options, "--ldap-module=nsuniqueid");
-       }
+       if (defined($self->{ldap})) {
+
+               if ($self->{ldap} eq "openldap") {
+                      ($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");
+               } elsif ($self->{ldap} eq "fedora") {
+                      ($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");
+                      push (@provision_options, "--ldap-module=nsuniqueid");
+               }
+
+               $self->slapd_start($ret) or 
+                       die("couldn't start slapd");
+                   
+               $ret->{PROVISION_OPTIONS} = join(' ', @provision_options);
 
-       $ret->{PROVISION_OPTIONS} = join(' ', @provision_options);
+               print "LDAP PROVISIONING...";
+               $self->provision_ldap($ret);
 
+               $self->slapd_stop($ret) or 
+                       die("couldn't stop slapd");
+       } else {
+               $ret->{PROVISION_OPTIONS} = join(' ', @provision_options);
+        }
        return $ret; 
 }
 
@@ -582,7 +677,7 @@ sub provision_member($$$)
        print "PROVISIONING MEMBER...";
 
        my $ret = $self->provision($prefix, "member server", "SAMBADOMAIN", 
-               "localmember");
+               "localmember", 3);
 
        $ret or die("Unable to provision");
 
@@ -590,6 +685,7 @@ sub provision_member($$$)
 
        $ret->{SMBD_TEST_FIFO} = "$prefix/smbd_test.fifo";
        $ret->{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
+       $ret->{SMBD_TEST_LOG_POS} = 0;
        return $ret;
 }
 
@@ -599,13 +695,14 @@ sub provision_dc($$)
 
        print "PROVISIONING DC...";
        my $ret = $self->provision($prefix, "domain controller", "SAMBADOMAIN", 
-               "localtest");
+               "localtest", 1);
 
        $self->add_wins_config("$prefix/private") or 
                die("Unable to add wins configuration");
 
        $ret->{SMBD_TEST_FIFO} = "$prefix/smbd_test.fifo";
        $ret->{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
+       $ret->{SMBD_TEST_LOG_POS} = 0;
        return $ret;
 }
 
@@ -642,13 +739,46 @@ sub teardown_env($$)
 
        $self->slapd_stop($envvars) if ($self->{ldap});
 
+       print $self->getlog_env($envvars);
+
        return $failed;
 }
 
+sub getlog_env($$)
+{
+       my ($self, $envvars) = @_;
+       my $title = "SMBD LOG of: $envvars->{NETBIOSNAME}\n";
+       my $out = $title;
+
+       open(LOG, "<$envvars->{SMBD_TEST_LOG}");
+
+       seek(LOG, $envvars->{SMBD_TEST_LOG_POS}, SEEK_SET);
+       while (<LOG>) {
+               $out .= $_;
+       }
+       $envvars->{SMBD_TEST_LOG_POS} = tell(LOG);
+       close(LOG);
+
+       return "" if $out eq $title;
+       return $out;
+}
+
+sub check_env($$)
+{
+       my ($self, $envvars) = @_;
+
+       return 1 if (-p $envvars->{SMBD_TEST_FIFO});
+
+       print $self->getlog_env($envvars);
+
+       return 0;
+}
+
 sub setup_env($$$)
 {
        my ($self, $envname, $path) = @_;
-       
+
        if ($envname eq "dc") {
                return $self->setup_dc("$path/dc");
        } elsif ($envname eq "member") {
@@ -667,7 +797,7 @@ sub setup_member($$$$)
 
        my $env = $self->provision_member($path, $dc_vars);
 
-       $self->check_or_start($env, ($ENV{SMBD_MAX_TIME} or 5400));
+       $self->check_or_start($env, ($ENV{SMBD_MAXTIME} or 6500));
 
        $self->wait_for_start($env);
 
@@ -681,7 +811,7 @@ sub setup_dc($$)
        my $env = $self->provision_dc($path);
 
        $self->check_or_start($env, 
-               ($ENV{SMBD_MAX_TIME} or 5400));
+               ($ENV{SMBD_MAXTIME} or 6500));
 
        $self->wait_for_start($env);