selftest: Check that LDAP is available during RODC startup
[nivanova/samba-autobuild/.git] / selftest / target / Samba4.pm
index 5bf888aecbbebced08c46b46ae521eb61542f6f8..1209893792fc846b669bc740ccbf6a829bf01107 100755 (executable)
@@ -122,6 +122,7 @@ sub check_or_start($$$)
                SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
 
                $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
+               $ENV{KRB5CCNAME} = "$env_vars->{KRB5_CCACHE}.samba";
                $ENV{SELFTEST_WINBINDD_SOCKET_DIR} = $env_vars->{SELFTEST_WINBINDD_SOCKET_DIR};
                $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
 
@@ -210,7 +211,7 @@ sub wait_for_start($$)
        }
 
        # Ensure we have the first RID Set before we start tests.  This makes the tests more reliable.
-       if ($testenv_vars->{SERVER_ROLE} eq "domain controller" and not ($testenv_vars->{NETBIOSNAME} eq "RODC")) {
+       if ($testenv_vars->{SERVER_ROLE} eq "domain controller") {
                # Add hosts file for name lookups
                $ENV{NSS_WRAPPER_HOSTS} = $testenv_vars->{NSS_WRAPPER_HOSTS};
                if (defined($testenv_vars->{RESOLV_WRAPPER_CONF})) {
@@ -219,22 +220,27 @@ sub wait_for_start($$)
                        $ENV{RESOLV_WRAPPER_HOSTS} = $testenv_vars->{RESOLV_WRAPPER_HOSTS};
                }
 
-           print "waiting for working LDAP and a RID Set to be allocated\n";
-           my $ldbsearch = Samba::bindir_path($self, "ldbsearch");
-           my $count = 0;
-           my $base_dn = "DC=".join(",DC=", split(/\./, $testenv_vars->{REALM}));
-           my $rid_set_dn = "cn=RID Set,cn=$testenv_vars->{NETBIOSNAME},ou=domain controllers,$base_dn";
-           my $max_wait = 60;
-           my $cmd = "$ldbsearch $testenv_vars->{CONFIGURATION} -H ldap://$testenv_vars->{SERVER} -U$testenv_vars->{USERNAME}%$testenv_vars->{PASSWORD} -s base -b \"$rid_set_dn\" rIDAllocationPool";
-           while (system("$cmd >/dev/null") != 0) {
-               $count++;
-               if ($count > $max_wait) {
-                   warn("Timed out ($max_wait sec) waiting for working LDAP and a RID Set to be allocated by $testenv_vars->{NETBIOSNAME} PID $testenv_vars->{SAMBA_PID}");
-                   $ret = -1;
-                   last;
+               print "waiting for working LDAP and a RID Set to be allocated\n";
+               my $ldbsearch = Samba::bindir_path($self, "ldbsearch");
+               my $count = 0;
+               my $base_dn = "DC=".join(",DC=", split(/\./, $testenv_vars->{REALM}));
+
+               my $search_dn = $base_dn;
+               if ($testenv_vars->{NETBIOSNAME} ne "RODC") {
+                       # TODO currently no check for actual rIDAllocationPool
+                       $search_dn = "cn=RID Set,cn=$testenv_vars->{NETBIOSNAME},ou=domain controllers,$base_dn";
+               }
+               my $max_wait = 60;
+               my $cmd = "$ldbsearch $testenv_vars->{CONFIGURATION} -H ldap://$testenv_vars->{SERVER} -U$testenv_vars->{USERNAME}%$testenv_vars->{PASSWORD} -s base -b \"$search_dn\"";
+               while (system("$cmd >/dev/null") != 0) {
+                       $count++;
+                       if ($count > $max_wait) {
+                               warn("Timed out ($max_wait sec) waiting for working LDAP and a RID Set to be allocated by $testenv_vars->{NETBIOSNAME} PID $testenv_vars->{SAMBA_PID}");
+                               $ret = -1;
+                               last;
+                       }
+                       sleep(1);
                }
-               sleep(1);
-           }
        }
        print $self->getlog_env($testenv_vars);
 
@@ -313,7 +319,8 @@ sub setup_namespaces($$:$$)
        } else {
                $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$localenv->{RESOLV_WRAPPER_HOSTS}\" ";
        }
-       $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\"";
+       $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\" ";
+       $cmd_env .= "KRB5CCNAME=\"$localenv->{KRB5_CCACHE}\" ";
 
        my $cmd_config = " $localenv->{CONFIGURATION}";
 
@@ -350,7 +357,8 @@ sub setup_trust($$$$$)
        } else {
                $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$localenv->{RESOLV_WRAPPER_HOSTS}\" ";
        }
-       $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\"";
+       $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\" ";
+       $cmd_env .= "KRB5CCNAME=\"$localenv->{KRB5_CCACHE}\" ";
 
        my $cmd_config = " $localenv->{CONFIGURATION}";
        my $cmd_creds = $cmd_config;
@@ -402,6 +410,7 @@ sub provision_raw_prepare($$$$$$$$$$$)
        $ctx->{password} = $password;
        $ctx->{kdc_ipv4} = $kdc_ipv4;
        $ctx->{kdc_ipv6} = $kdc_ipv6;
+       $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}";
        if ($functional_level eq "2000") {
                $ctx->{supported_enctypes} = "arcfour-hmac-md5 des-cbc-md5 des-cbc-crc"
        }
@@ -430,6 +439,7 @@ sub provision_raw_prepare($$$$$$$$$$$)
        $ctx->{piddir} = "$prefix_abs/pid";
        $ctx->{smb_conf} = "$ctx->{etcdir}/smb.conf";
        $ctx->{krb5_conf} = "$ctx->{etcdir}/krb5.conf";
+       $ctx->{krb5_ccache} = "$prefix_abs/krb5_ccache";
        $ctx->{privatedir} = "$prefix_abs/private";
        $ctx->{ncalrpcdir} = "$prefix_abs/ncalrpc";
        $ctx->{lockdir} = "$prefix_abs/lockdir";
@@ -437,7 +447,6 @@ sub provision_raw_prepare($$$$$$$$$$$)
        $ctx->{statedir} = "$prefix_abs/statedir";
        $ctx->{cachedir} = "$prefix_abs/cachedir";
        $ctx->{winbindd_socket_dir} = "$prefix_abs/winbindd_socket";
-       $ctx->{winbindd_privileged_socket_dir} = "$prefix_abs/winbindd_privileged_socket";
        $ctx->{ntp_signd_socket_dir} = "$prefix_abs/ntp_signd_socket";
        $ctx->{nsswrap_passwd} = "$ctx->{etcdir}/passwd";
        $ctx->{nsswrap_group} = "$ctx->{etcdir}/group";
@@ -469,7 +478,8 @@ sub provision_raw_prepare($$$$$$$$$$$)
        $ctx->{smb_conf_extra_options} = "";
 
        my @provision_options = ();
-       push (@provision_options, "KRB5_CONFIG=\"$ctx->{krb5_config}\"");
+       push (@provision_options, "KRB5_CONFIG=\"$ctx->{krb5_conf}\"");
+       push (@provision_options, "KRB5_CCACHE=\"$ctx->{krb5_ccache}\"");
        push (@provision_options, "NSS_WRAPPER_PASSWD=\"$ctx->{nsswrap_passwd}\"");
        push (@provision_options, "NSS_WRAPPER_GROUP=\"$ctx->{nsswrap_group}\"");
        push (@provision_options, "NSS_WRAPPER_HOSTS=\"$ctx->{nsswrap_hosts}\"");
@@ -554,7 +564,6 @@ sub provision_raw_step1($$)
        state directory = $ctx->{statedir}
        cache directory = $ctx->{cachedir}
        winbindd socket directory = $ctx->{winbindd_socket_dir}
-       winbindd privileged socket directory = $ctx->{winbindd_privileged_socket_dir}
        ntp signd socket directory = $ctx->{ntp_signd_socket_dir}
        winbind separator = /
        interfaces = $ctx->{interfaces}
@@ -586,6 +595,9 @@ sub provision_raw_step1($$)
         idmap_ldb:use rfc2307=yes
        winbind enum users = yes
        winbind enum groups = yes
+
+        rpc server port:netlogon = 1026
+
 ";
 
        print CONFFILE "
@@ -667,6 +679,7 @@ nogroup:x:65534:nobody
 
        my $ret = {
                KRB5_CONFIG => $ctx->{krb5_conf},
+               KRB5_CCACHE => $ctx->{krb5_ccache},
                PIDDIR => $ctx->{piddir},
                SERVER => $ctx->{hostname},
                SERVER_IP => $ctx->{ipv4},
@@ -728,6 +741,7 @@ sub provision_raw_step2($$$)
        my $testallowed_account = "testallowed";
        my $samba_tool_cmd = "";
        $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
            . " user create --configfile=$ctx->{smb_conf} $testallowed_account $ctx->{password}";
        unless (system($samba_tool_cmd) == 0) {
@@ -737,6 +751,7 @@ sub provision_raw_step2($$$)
 
        my $ldbmodify = "";
        $ldbmodify .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $ldbmodify .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $ldbmodify .= Samba::bindir_path($self, "ldbmodify");
        my $base_dn = "DC=".join(",DC=", split(/\./, $ctx->{realm}));
 
@@ -768,6 +783,7 @@ servicePrincipalName: host/testallowed
 
        $samba_tool_cmd = "";
        $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
            . " user create --configfile=$ctx->{smb_conf} testdenied $ctx->{password}";
        unless (system($samba_tool_cmd) == 0) {
@@ -787,6 +803,7 @@ userPrincipalName: testdenied_upn\@$ctx->{realm}.upn
 
        $samba_tool_cmd = "";
        $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
            . " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account'";
        unless (system($samba_tool_cmd) == 0) {
@@ -794,6 +811,22 @@ userPrincipalName: testdenied_upn\@$ctx->{realm}.upn
                return undef;
        }
 
+       # Create to users alice and bob!
+       my $user_account_array = ["alice", "bob"];
+
+       foreach my $user_account (@{$user_account_array}) {
+               my $samba_tool_cmd = "";
+
+               $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+               $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
+               $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
+                   . " user create --configfile=$ctx->{smb_conf} $user_account Secret007";
+               unless (system($samba_tool_cmd) == 0) {
+                       warn("Unable to create user: $user_account\n$samba_tool_cmd\n");
+                       return undef;
+               }
+       }
+
        return $ret;
 }
 
@@ -833,7 +866,6 @@ sub provision($$$$$$$$$$)
        server max protocol = SMB2
        host msdfs = $msdfs
        lanman auth = yes
-       allow nt4 crypto = yes
 
        # fruit:copyfile is a global option
        fruit:copyfile = yes
@@ -910,7 +942,7 @@ sub provision($$$$$$$$$$)
        path = $ctx->{share}
        vfs objects = catia fruit streams_xattr acl_xattr
        ea support = yes
-       fruit:ressource = file
+       fruit:resource = file
        fruit:metadata = netatalk
        fruit:locking = netatalk
        fruit:encoding = native
@@ -954,9 +986,9 @@ $extra_smbconf_shares
        return $self->provision_raw_step2($ctx, $ret);
 }
 
-sub provision_s4member($$$)
+sub provision_s4member($$$$$)
 {
-       my ($self, $prefix, $dcvars) = @_;
+       my ($self, $prefix, $dcvars, $hostname, $more_conf) = @_;
        print "PROVISIONING MEMBER...\n";
        my $extra_smb_conf = "
         passdb backend = samba_dsdb
@@ -975,9 +1007,12 @@ rpc_server:spoolss = embedded
 rpc_daemon:spoolssd = embedded
 rpc_server:tcpip = no
 ";
+       if ($more_conf) {
+               $extra_smb_conf = $extra_smb_conf . $more_conf . "\n";
+       }
        my $ret = $self->provision($prefix,
                                   "member server",
-                                  "s4member",
+                                  $hostname,
                                   "SAMBADOMAIN",
                                   "samba.example.com",
                                   "2008",
@@ -998,6 +1033,7 @@ rpc_server:tcpip = no
                $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
        }
        $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} member";
        $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
        $cmd .= " --machinepass=machine$ret->{PASSWORD}";
@@ -1075,6 +1111,7 @@ sub provision_rpc_proxy($$$)
                $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
        }
        $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} member";
        $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
        $cmd .= " --machinepass=machine$ret->{PASSWORD}";
@@ -1088,6 +1125,7 @@ sub provision_rpc_proxy($$$)
        $cmd = "";
        $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
        $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool delegation for-any-protocol '$ret->{NETBIOSNAME}\$' on";
         $cmd .= " $dcvars->{CONFIGURATION}";
         print $cmd;
@@ -1101,6 +1139,7 @@ sub provision_rpc_proxy($$$)
        $cmd = "";
        $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
        $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool delegation add-service '$ret->{NETBIOSNAME}\$' cifs/$dcvars->{SERVER}";
         $cmd .= " $dcvars->{CONFIGURATION}";
 
@@ -1171,6 +1210,7 @@ sub provision_promoted_dc($$$)
                $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
        }
        $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} MEMBER --realm=$dcvars->{REALM}";
        $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
        $cmd .= " --machinepass=machine$ret->{PASSWORD}";
@@ -1184,6 +1224,7 @@ sub provision_promoted_dc($$$)
        my $cmd = "";
        $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
        $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool domain dcpromo $ret->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
        $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
        $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs --dns-backend=BIND9_DLZ";
@@ -1210,15 +1251,20 @@ sub provision_promoted_dc($$$)
 
 sub provision_vampire_dc($$$)
 {
-       my ($self, $prefix, $dcvars) = @_;
-       print "PROVISIONING VAMPIRE DC...\n";
+       my ($self, $prefix, $dcvars, $fl) = @_;
+       print "PROVISIONING VAMPIRE DC @ FL $fl...\n";
+       my $name = "localvampiredc";
+
+       if ($fl == "2000") {
+           $name = "vampire2000dc";
+       }
 
        # We do this so that we don't run the provision.  That's the job of 'net vampire'.
        my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
-                                              "localvampiredc",
-                                              "SAMBADOMAIN",
-                                              "samba.example.com",
-                                              "2008",
+                                              $name,
+                                              $dcvars->{DOMAIN},
+                                              $dcvars->{REALM},
+                                              $fl,
                                               $dcvars->{PASSWORD},
                                               $dcvars->{SERVER_IP},
                                               $dcvars->{SERVER_IPV6});
@@ -1253,6 +1299,7 @@ sub provision_vampire_dc($$$)
                $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
        }
        $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
        $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD} --domain-critical-only";
        $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs";
@@ -1262,11 +1309,17 @@ sub provision_vampire_dc($$$)
                return undef;
        }
 
-       $ret->{VAMPIRE_DC_SERVER} = $ret->{SERVER};
-       $ret->{VAMPIRE_DC_SERVER_IP} = $ret->{SERVER_IP};
-       $ret->{VAMPIRE_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
-       $ret->{VAMPIRE_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
-
+        if ($fl == "2000") {
+               $ret->{VAMPIRE_2000_DC_SERVER} = $ret->{SERVER};
+               $ret->{VAMPIRE_2000_DC_SERVER_IP} = $ret->{SERVER_IP};
+               $ret->{VAMPIRE_2000_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
+               $ret->{VAMPIRE_2000_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
+        } else {
+               $ret->{VAMPIRE_DC_SERVER} = $ret->{SERVER};
+               $ret->{VAMPIRE_DC_SERVER_IP} = $ret->{SERVER_IP};
+               $ret->{VAMPIRE_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
+               $ret->{VAMPIRE_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
+        }
        $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
        $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
        $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
@@ -1324,6 +1377,7 @@ sub provision_subdom_dc($$$)
                $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
        }
        $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $ctx->{dnsname} subdomain ";
        $cmd .= "--parent-domain=$dcvars->{REALM} -U$dcvars->{DC_USERNAME}\@$dcvars->{REALM}\%$dcvars->{DC_PASSWORD}";
        $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs";
@@ -1361,6 +1415,9 @@ sub provision_ad_dc_ntvfs($$)
         my $extra_conf_options = "netbios aliases = localDC1-a
         server services = +winbind -winbindd
        ldap server require strong auth = allow_sasl_over_tls
+       allow nt4 crypto = yes
+       lsa over netlogon = yes
+        rpc server port = 1027
        ";
        my $ret = $self->provision($prefix,
                                   "domain controller",
@@ -1588,6 +1645,7 @@ sub provision_rodc($$$)
                $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
        }
        $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} RODC";
        $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
        $cmd .= " --server=$dcvars->{DC_SERVER} --use-ntvfs";
@@ -1601,6 +1659,7 @@ sub provision_rodc($$$)
         # user password verified on the RODC
        my $testallowed_account = "testallowed account";
        $cmd = "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
+       $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
        $cmd .= "$samba_tool rodc preload '$testallowed_account' $ret->{CONFIGURATION}";
        $cmd .= " --server=$dcvars->{DC_SERVER}";
 
@@ -1631,6 +1690,27 @@ sub provision_rodc($$$)
        return $ret;
 }
 
+sub read_config_h($)
+{
+       my ($name) = @_;
+       my %ret = {};
+       open(LF, "<$name") or die("unable to read $name: $!");
+       while (<LF>) {
+               chomp;
+               next if not (/^#define /);
+               if (/^#define (.*?)[ \t]+(.*?)$/) {
+                       $ret{$1} = $2;
+                       next;
+               }
+               if (/^#define (.*?)[ \t]+$/) {
+                       $ret{$1} = 1;;
+                       next;
+               }
+       }
+       close(LF);
+       return \%ret;
+}
+
 sub provision_ad_dc($$)
 {
        my ($self, $prefix) = @_;
@@ -1644,6 +1724,15 @@ sub provision_ad_dc($$)
        my $require_mutexes = "dbwrap_tdb_require_mutexes:* = yes";
        $require_mutexes = "" if ($ENV{SELFTEST_DONT_REQUIRE_TDB_MUTEX_SUPPORT} eq "1");
 
+       my $config_h = {};
+
+       if (defined($ENV{CONFIG_H})) {
+               $config_h = read_config_h($ENV{CONFIG_H});
+       }
+
+       my $password_hash_gpg_key_ids = "password hash gpg key ids = 4952E40301FAB41A";
+       $password_hash_gpg_key_ids = "" unless defined($config_h->{HAVE_GPGME});
+
        my $extra_smbconf_options = "
         server services = -smb +s3fs
         xattr_tdb:file = $prefix_abs/statedir/xattr.tdb
@@ -1651,6 +1740,8 @@ sub provision_ad_dc($$)
        dbwrap_tdb_mutexes:* = yes
        ${require_mutexes}
 
+       ${password_hash_gpg_key_ids}
+
        kernel oplocks = no
        kernel change notify = no
        smb2 leases = no
@@ -1807,7 +1898,7 @@ sub provision_chgdcpass($$)
        return $ret;
 }
 
-sub teardown_env($$)
+sub teardown_env_terminate($$)
 {
        my ($self, $envvars) = @_;
        my $pid;
@@ -1820,28 +1911,50 @@ sub teardown_env($$)
        my $childpid;
 
        # This should give it time to write out the gcov data
+       until ($count > 15) {
+           if (Samba::cleanup_child($pid, "samba") != 0) {
+               return;
+           }
+           sleep(1);
+           $count++;
+       }
+
+       # After 15 Seconds, work out why this thing is still alive
+       warn "server process $pid took more than $count seconds to exit, showing backtrace:\n";
+       system("$self->{srcdir}/selftest/gdb_backtrace $pid");
+
        until ($count > 30) {
-           if (Samba::cleanup_child($pid, "samba") == -1) {
-               last;
+           if (Samba::cleanup_child($pid, "samba") != 0) {
+               return;
            }
            sleep(1);
            $count++;
        }
 
-       if ($count > 30 || kill(0, $pid)) {
+       if (kill(0, $pid)) {
+           warn "server process $pid took more than $count seconds to exit, sending SIGTERM\n";
            kill "TERM", $pid;
+       }
 
-           until ($count > 40) {
-               if (Samba::cleanup_child($pid, "samba") == -1) {
-                   last;
-               }
-               sleep(1);
-               $count++;
+       until ($count > 40) {
+           if (Samba::cleanup_child($pid, "samba") != 0) {
+               return;
            }
-           # If it is still around, kill it
-           warn "server process $pid took more than $count seconds to exit, killing\n";
+           sleep(1);
+           $count++;
+       }
+       # If it is still around, kill it
+       if (kill(0, $pid)) {
+           warn "server process $pid took more than $count seconds to exit, killing\n with SIGKILL\n";
            kill 9, $pid;
        }
+       return;
+}
+
+sub teardown_env($$)
+{
+       my ($self, $envvars) = @_;
+       teardown_env_terminate($self, $envvars);
 
        $self->slapd_stop($envvars) if ($self->{ldap});
 
@@ -1905,6 +2018,11 @@ sub setup_env($$$)
                return $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
        } elsif ($envname eq "fl2000dc") {
                return $self->setup_fl2000dc("$path/fl2000dc");
+       } elsif ($envname eq "vampire_2000_dc") {
+               if (not defined($self->{vars}->{fl2000dc})) {
+                       $self->setup_fl2000dc("$path/fl2000dc");
+               }
+               return $self->setup_vampire_dc("$path/vampire_2000_dc", $self->{vars}->{fl2000dc}, "2000");
        } elsif ($envname eq "fl2003dc") {
                if (not defined($self->{vars}->{ad_dc})) {
                        $self->setup_ad_dc("$path/ad_dc");
@@ -1924,7 +2042,7 @@ sub setup_env($$$)
                if (not defined($self->{vars}->{ad_dc_ntvfs})) {
                        $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
                }
-               return $self->setup_vampire_dc("$path/vampire_dc", $self->{vars}->{ad_dc_ntvfs});
+               return $self->setup_vampire_dc("$path/vampire_dc", $self->{vars}->{ad_dc_ntvfs}, "2008");
        } elsif ($envname eq "promoted_dc") {
                if (not defined($self->{vars}->{ad_dc_ntvfs})) {
                        $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
@@ -1935,6 +2053,11 @@ sub setup_env($$$)
                        $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
                }
                return $self->setup_subdom_dc("$path/subdom_dc", $self->{vars}->{ad_dc_ntvfs});
+       } elsif ($envname eq "s4member_dflt_domain") {
+               if (not defined($self->{vars}->{ad_dc_ntvfs})) {
+                       $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
+               }
+               return $self->setup_s4member_dflt_domain("$path/s4member_dflt_domain", $self->{vars}->{ad_dc_ntvfs});
        } elsif ($envname eq "s4member") {
                if (not defined($self->{vars}->{ad_dc_ntvfs})) {
                        $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
@@ -1973,7 +2096,7 @@ sub setup_s4member($$$)
 {
        my ($self, $path, $dc_vars) = @_;
 
-       my $env = $self->provision_s4member($path, $dc_vars);
+       my $env = $self->provision_s4member($path, $dc_vars, "s4member");
 
        if (defined $env) {
                if (not defined($self->check_or_start($env, "standard"))) {
@@ -1986,6 +2109,24 @@ sub setup_s4member($$$)
        return $env;
 }
 
+sub setup_s4member_dflt_domain($$$)
+{
+       my ($self, $path, $dc_vars) = @_;
+
+       my $env = $self->provision_s4member($path, $dc_vars, "s4member_dflt",
+                                           "winbind use default domain = yes");
+
+       if (defined $env) {
+               if (not defined($self->check_or_start($env, "standard"))) {
+                       return undef;
+               }
+
+               $self->{vars}->{s4member_dflt_domain} = $env;
+       }
+
+       return $env;
+}
+
 sub setup_rpc_proxy($$$)
 {
        my ($self, $path, $dc_vars) = @_;
@@ -2091,11 +2232,11 @@ sub setup_fl2008r2dc($$$)
        return $env;
 }
 
-sub setup_vampire_dc($$$)
+sub setup_vampire_dc($$$$)
 {
-       my ($self, $path, $dc_vars) = @_;
+       my ($self, $path, $dc_vars, $fl) = @_;
 
-       my $env = $self->provision_vampire_dc($path, $dc_vars);
+       my $env = $self->provision_vampire_dc($path, $dc_vars, $fl);
 
        if (defined $env) {
                if (not defined($self->check_or_start($env, "single"))) {
@@ -2115,6 +2256,7 @@ sub setup_vampire_dc($$$)
                        $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
                }
                $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
+               $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
                $cmd .= " $samba_tool drs kcc -k no $env->{DC_SERVER}";
                $cmd .= " $env->{CONFIGURATION}";
                $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
@@ -2134,6 +2276,7 @@ sub setup_vampire_dc($$$)
                        $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
                }
                $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
+               $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
                $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SERVER}";
                $cmd .= " $dc_vars->{CONFIGURATION}";
                $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
@@ -2149,6 +2292,33 @@ sub setup_vampire_dc($$$)
                        warn("Failed to replicate\n$cmd_repl");
                        return undef;
                }
+
+               # Pull in a full set of changes from the main DC
+               my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
+               $cmd = "";
+               $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
+               if (defined($env->{RESOLV_WRAPPER_CONF})) {
+                       $cmd .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
+               } else {
+                       $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
+               }
+               $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
+               $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
+               $cmd .= " $samba_tool drs replicate $env->{SERVER} $env->{DC_SERVER}";
+               $cmd .= " $dc_vars->{CONFIGURATION}";
+               $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
+               # replicate Configuration NC
+               my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
+               unless(system($cmd_repl) == 0) {
+                       warn("Failed to replicate\n$cmd_repl");
+                       return undef;
+               }
+               # replicate Default NC
+               $cmd_repl = "$cmd \"$base_dn\"";
+               unless(system($cmd_repl) == 0) {
+                       warn("Failed to replicate\n$cmd_repl");
+                       return undef;
+               }
        }
 
        return $env;
@@ -2173,6 +2343,7 @@ sub setup_promoted_dc($$$)
                my $cmd = "";
                $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
                $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
+               $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
                $cmd .= " $samba_tool drs kcc $env->{DC_SERVER}";
                $cmd .= " $env->{CONFIGURATION}";
                $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
@@ -2185,6 +2356,7 @@ sub setup_promoted_dc($$$)
                my $cmd = "";
                $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
                $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
+               $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
                $cmd .= " $samba_tool drs kcc $env->{SERVER}";
                $cmd .= " $env->{CONFIGURATION}";
                $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
@@ -2198,6 +2370,7 @@ sub setup_promoted_dc($$$)
                my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
                $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
                $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
+               $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
                $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SERVER}";
                $cmd .= " $dc_vars->{CONFIGURATION}";
                $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
@@ -2237,6 +2410,7 @@ sub setup_subdom_dc($$$)
                my $cmd = "";
                $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
                $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
+               $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
                $cmd .= " $samba_tool drs kcc $env->{DC_SERVER}";
                $cmd .= " $env->{CONFIGURATION}";
                $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD} --realm=$dc_vars->{DC_REALM}";
@@ -2251,6 +2425,7 @@ sub setup_subdom_dc($$$)
                my $config_dn = "CN=Configuration,DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
                $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
                $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
+               $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
                $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SUBDOM_DC_SERVER}";
                $cmd .= " $dc_vars->{CONFIGURATION}";
                $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD} --realm=$dc_vars->{DC_REALM}";
@@ -2291,6 +2466,7 @@ sub setup_rodc($$$)
        my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
        $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
        $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
+       $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
        $cmd .= " $samba_tool drs replicate $env->{SERVER} $env->{DC_SERVER}";
        $cmd .= " $dc_vars->{CONFIGURATION}";
        $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";