pyldb: avoid segfault when adding an element with no name
[kai/samba-autobuild/.git] / selftest / target / Samba.pm
index a6390a6db949b84aecda08c2e0aef6ac52ed4477..38b38669dac95e61f07c06270535aade6422eb28 100644 (file)
@@ -25,6 +25,9 @@ sub new($$$$$) {
 %Samba::ENV_DEPS = (%Samba3::ENV_DEPS, %Samba4::ENV_DEPS);
 our %ENV_DEPS;
 
+%Samba::ENV_DEPS_POST = (%Samba3::ENV_DEPS_POST, %Samba4::ENV_DEPS_POST);
+our %ENV_DEPS_POST;
+
 %Samba::ENV_TARGETS = (
        (map { $_ => "Samba3" } keys %Samba3::ENV_DEPS),
        (map { $_ => "Samba4" } keys %Samba4::ENV_DEPS),
@@ -59,6 +62,8 @@ sub setup_env($$$)
                return $target->{vars}->{$envname};
        }
 
+       $target->{vars}->{$envname} = "";
+
        my @dep_vars;
        foreach(@{$ENV_DEPS{$envname}}) {
                my $vars = $self->setup_env($_, $path);
@@ -87,6 +92,13 @@ sub setup_env($$$)
        $target->{vars}->{$envname} = $env;
        $target->{vars}->{$envname}->{target} = $target;
 
+       foreach(@{$ENV_DEPS_POST{$envname}}) {
+               my $vars = $self->setup_env($_, $path);
+               if (not defined($vars)) {
+                       return undef;
+               }
+       }
+
        return $env;
 }
 
@@ -94,9 +106,20 @@ sub bindir_path($$) {
        my ($object, $path) = @_;
 
        my $valpath = "$object->{bindir}/$path";
+       my $python_cmd = "";
+       my $result = $path;
+       if (defined $ENV{'PYTHON'}) {
+               $python_cmd = $ENV{'PYTHON'} . " ";
+       }
 
-       return $valpath if (-f $valpath or -d $valpath);
-       return $path;
+       if (-f $valpath or -d $valpath) {
+               $result = $valpath;
+       }
+       # make sure we prepend samba-tool with calling $PYTHON python version
+       if ($path eq "samba-tool") {
+               $result = $python_cmd . $result;
+       }
+       return $result;
 }
 
 sub nss_wrapper_winbind_so_path($) {
@@ -239,16 +262,22 @@ sub mk_krb5_conf($$)
  ticket_lifetime = 24h
  forwardable = yes
  allow_weak_crypto = yes
- # Set the grace clocskew to 5 seconds
- # This is especially required by samba3.raw.session krb5 and
- # reauth tests
- clockskew = 5
+
  # We are running on the same machine, do not correct
  # system clock differences
  kdc_timesync = 0
 
 ";
 
+       if (defined($ENV{MITKRB5})) {
+               print KRB5CONF "
+ # Set the grace clocskew to 5 seconds
+ # This is especially required by samba3.raw.session krb5 and
+ # reauth tests when not using Heimdal
+ clockskew = 5
+    ";
+       }
+
        if (defined($ctx->{krb5_ccname})) {
                print KRB5CONF "
  default_ccache_name = $ctx->{krb5_ccname}
@@ -368,59 +397,157 @@ sub mk_mitkdc_conf($$)
        close(KDCCONF);
 }
 
+sub realm_to_ip_mappings
+{
+       # this maps the DNS realms for the various testenvs to the corresponding
+       # PDC (i.e. the first DC created for that realm).
+       my %realm_to_pdc_mapping = (
+               'adnonssdom.samba.example.com'    => 'addc_no_nss',
+               'adnontlmdom.samba.example.com'   => 'addc_no_ntlm',
+               'samba2000.example.com'           => 'dc5',
+               'samba2003.example.com'           => 'dc6',
+               'samba2008r2.example.com'         => 'dc7',
+               'addom.samba.example.com'         => 'addc',
+               'sub.samba.example.com'           => 'localsubdc',
+               'chgdcpassword.samba.example.com' => 'chgdcpass',
+               'backupdom.samba.example.com'     => 'backupfromdc',
+               'renamedom.samba.example.com'     => 'renamedc',
+               'labdom.samba.example.com'        => 'labdc',
+               'schema.samba.example.com'        => 'liveupgrade1dc',
+               'samba.example.com'               => 'localdc',
+       );
+
+       my @mapping = ();
+
+       # convert the hashmap to a list of key=value strings, where key is the
+       # realm and value is the IP address
+       while (my ($realm, $pdc) = each(%realm_to_pdc_mapping)) {
+               my $ipaddr = get_ipv4_addr($pdc);
+               push(@mapping, "$realm=$ipaddr");
+       }
+       # return the mapping as a single comma-separated string
+       return join(',', @mapping);
+}
+
 sub get_interface($)
 {
-    my ($netbiosname) = @_;
-    $netbiosname = lc($netbiosname);
-
-    my %interfaces = ();
-    $interfaces{"localnt4dc2"} = 3;
-    $interfaces{"localnt4member3"} = 4;
-    $interfaces{"localshare4"} = 5;
-
-    $interfaces{"localktest6"} = 7;
-    $interfaces{"maptoguest"} = 8;
-    $interfaces{"localnt4dc9"} = 9;
-
-    # 11-16 used by selftest.pl for client interfaces
-
-    $interfaces{"addc_no_nss"} = 17;
-    $interfaces{"addc_no_ntlm"} = 18;
-    $interfaces{"idmapadmember"} = 19;
-    $interfaces{"idmapridmember"} = 20;
-    $interfaces{"localdc"} = 21;
-    $interfaces{"localvampiredc"} = 22;
-    $interfaces{"s4member"} = 23;
-    $interfaces{"localrpcproxy"} = 24;
-    $interfaces{"dc5"} = 25;
-    $interfaces{"dc6"} = 26;
-    $interfaces{"dc7"} = 27;
-    $interfaces{"rodc"} = 28;
-    $interfaces{"localadmember"} = 29;
-    $interfaces{"addc"} = 30;
-    $interfaces{"localsubdc"} = 31;
-    $interfaces{"chgdcpass"} = 32;
-    $interfaces{"promotedvdc"} = 33;
-    $interfaces{"rfc2307member"} = 34;
-    $interfaces{"fileserver"} = 35;
-    $interfaces{"fakednsforwarder1"} = 36;
-    $interfaces{"fakednsforwarder2"} = 37;
-    $interfaces{"s4member_dflt"} = 38;
-    $interfaces{"vampire2000dc"} = 39;
-    $interfaces{"backupfromdc"} = 40;
-    $interfaces{"restoredc"} = 41;
-    $interfaces{"renamedc"} = 42;
-    $interfaces{"labdc"} = 43;
-
-    # update lib/socket_wrapper/socket_wrapper.c
-    #  #define MAX_WRAPPED_INTERFACES 64
-    # if you wish to have more than 64 interfaces
-
-    if (not defined($interfaces{$netbiosname})) {
-       die();
-    }
+       my ($netbiosname) = @_;
+       $netbiosname = lc($netbiosname);
+
+       # this maps the SOCKET_WRAPPER_DEFAULT_IFACE value for each possible
+       # testenv to the DC's NETBIOS name. This value also corresponds to last
+       # digit of the DC's IP address. Note that the NETBIOS name may differ from
+       # the testenv name.
+       # Note that when adding a DC with a new realm, also update
+       # get_realm_ip_mappings() above.
+       my %testenv_iface_mapping = (
+               localnt4dc2       => 3,
+               localnt4member3   => 4,
+               localshare4       => 5,
+               # 6 is spare
+               localktest6       => 7,
+               maptoguest        => 8,
+               localnt4dc9       => 9,
+               # 10 is spare
+
+               # 11-16 are used by selftest.pl for the client.conf. Most tests only
+               # use the first .11 IP. However, some tests (like winsreplication) rely
+               # on the client having multiple IPs.
+               client            => 11,
+
+               addc_no_nss       => 17,
+               addc_no_ntlm      => 18,
+               idmapadmember     => 19,
+               idmapridmember    => 20,
+               localdc           => 21,
+               localvampiredc    => 22,
+               s4member          => 23,
+               localrpcproxy     => 24,
+               dc5               => 25,
+               dc6               => 26,
+               dc7               => 27,
+               rodc              => 28,
+               localadmember     => 29,
+               addc              => 30,
+               localsubdc        => 31,
+               chgdcpass         => 32,
+               promotedvdc       => 33,
+               rfc2307member     => 34,
+               fileserver        => 35,
+               fakednsforwarder1 => 36,
+               fakednsforwarder2 => 37,
+               s4member_dflt     => 38,
+               vampire2000dc     => 39,
+               backupfromdc      => 40,
+               restoredc         => 41,
+               renamedc          => 42,
+               labdc             => 43,
+               offlinebackupdc   => 44,
+               customdc          => 45,
+               prockilldc        => 46,
+               proclimitdc       => 47,
+               liveupgrade1dc    => 48,
+               liveupgrade2dc    => 49,
+
+               rootdnsforwarder  => 64,
+
+               # Note: that you also need to update dns_hub.py when adding a new
+               # multi-DC testenv
+               # update lib/socket_wrapper/socket_wrapper.c
+               #  #define MAX_WRAPPED_INTERFACES 64
+               # if you wish to have more than 64 interfaces
+       );
+
+       if (not defined($testenv_iface_mapping{$netbiosname})) {
+               die();
+       }
+
+       return $testenv_iface_mapping{$netbiosname};
+}
+
+sub get_ipv4_addr
+{
+       my ($hostname, $iface_num) = @_;
+       my $swiface = Samba::get_interface($hostname);
+
+       # Handle testenvs with multiple different addresses, i.e. IP multihoming.
+       # Currently only the selftest client has multiple IPv4 addresses.
+       if (defined($iface_num)) {
+               $swiface += $iface_num;
+       }
+
+       return "127.0.0.$swiface";
+}
+
+sub get_ipv6_addr
+{
+       (my $hostname) = @_;
+       my $swiface = Samba::get_interface($hostname);
+
+       return sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface);
+}
+
+# returns the 'interfaces' setting for smb.conf, i.e. the IPv4/IPv6
+# addresses for testenv
+sub get_interfaces_config
+{
+       my ($hostname, $num_ips) = @_;
+       my $interfaces = "";
 
-    return $interfaces{$netbiosname};
+       # We give the client.conf multiple different IPv4 addresses.
+       # All other testenvs generally just have one IPv4 address.
+       if (! defined($num_ips)) {
+               $num_ips = 1;
+       }
+       for (my $i = 0; $i < $num_ips; $i++) {
+               my $ipv4_addr = Samba::get_ipv4_addr($hostname, $i);
+               $interfaces .= "$ipv4_addr/8 ";
+       }
+
+       my $ipv6_addr = Samba::get_ipv6_addr($hostname);
+       $interfaces .= "$ipv6_addr/64";
+
+       return $interfaces;
 }
 
 sub cleanup_child($$)
@@ -453,4 +580,121 @@ sub random_domain_sid()
        return $domain_sid;
 }
 
+my @exported_envvars = (
+       # domain stuff
+       "DOMAIN",
+       "DNSNAME",
+       "REALM",
+       "DOMSID",
+
+       # stuff related to a trusted domain
+       "TRUST_SERVER",
+       "TRUST_USERNAME",
+       "TRUST_PASSWORD",
+       "TRUST_DOMAIN",
+       "TRUST_REALM",
+       "TRUST_DOMSID",
+
+       # domain controller stuff
+       "DC_SERVER",
+       "DC_SERVER_IP",
+       "DC_SERVER_IPV6",
+       "DC_NETBIOSNAME",
+       "DC_NETBIOSALIAS",
+
+       # server stuff
+       "SERVER",
+       "SERVER_IP",
+       "SERVER_IPV6",
+       "NETBIOSNAME",
+       "NETBIOSALIAS",
+       "SAMSID",
+
+       # only use these 2 as a last resort. Some tests need to test both client-
+       # side and server-side. In this case, run as default client, ans access
+       # server's smb.conf as needed, typically using:
+       #  param.LoadParm(filename_for_non_global_lp=os.environ['SERVERCONFFILE'])
+       "SERVERCONFFILE",
+       "DC_SERVERCONFFILE",
+
+       # user stuff
+       "USERNAME",
+       "USERID",
+       "PASSWORD",
+       "DC_USERNAME",
+       "DC_PASSWORD",
+
+       # UID/GID for rfc2307 mapping tests
+       "UID_RFC2307TEST",
+       "GID_RFC2307TEST",
+
+       # misc stuff
+       "KRB5_CONFIG",
+       "KRB5CCNAME",
+       "SELFTEST_WINBINDD_SOCKET_DIR",
+       "NMBD_SOCKET_DIR",
+       "LOCAL_PATH",
+       "DNS_FORWARDER1",
+       "DNS_FORWARDER2",
+       "RESOLV_CONF",
+       "UNACCEPTABLE_PASSWORD",
+       "LOCK_DIR",
+       "SMBD_TEST_LOG",
+
+       # nss_wrapper
+       "NSS_WRAPPER_PASSWD",
+       "NSS_WRAPPER_GROUP",
+       "NSS_WRAPPER_HOSTS",
+       "NSS_WRAPPER_HOSTNAME",
+       "NSS_WRAPPER_MODULE_SO_PATH",
+       "NSS_WRAPPER_MODULE_FN_PREFIX",
+
+       # resolv_wrapper
+       "RESOLV_WRAPPER_CONF",
+       "RESOLV_WRAPPER_HOSTS",
+);
+
+sub exported_envvars_str
+{
+       my ($testenv_vars) = @_;
+       my $out = "";
+
+       foreach (@exported_envvars) {
+               next unless defined($testenv_vars->{$_});
+               $out .= $_."=".$testenv_vars->{$_}."\n";
+       }
+
+       return $out;
+}
+
+sub clear_exported_envvars
+{
+       foreach (@exported_envvars) {
+               delete $ENV{$_};
+       }
+}
+
+sub export_envvars
+{
+       my ($testenv_vars) = @_;
+
+       foreach (@exported_envvars) {
+               if (defined($testenv_vars->{$_})) {
+                       $ENV{$_} = $testenv_vars->{$_};
+               } else {
+                       delete $ENV{$_};
+               }
+       }
+}
+
+sub export_envvars_to_file
+{
+       my ($filepath, $testenv_vars) = @_;
+       my $env_str = exported_envvars_str($testenv_vars);
+
+       open(FILE, "> $filepath");
+       print FILE "$env_str";
+       close(FILE);
+}
+
 1;