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.
10 use FindBin qw($RealBin);
17 my ($classname, $bindir, $ldap, $srcdir, $server_maxtime) = @_;
24 server_maxtime => $server_maxtime,
25 target3 => new Samba3($bindir, $srcdir, $server_maxtime)
31 sub scriptdir_path($$) {
32 my ($self, $path) = @_;
33 return "$self->{srcdir}/source4/scripting/$path";
36 sub openldap_start($$$) {
42 my ($self, $env_vars, $STDIN_READER) = @_;
43 my $ldbsearch = Samba::bindir_path($self, "ldbsearch");
45 my $uri = $env_vars->{LDAP_URI};
47 if (system("$ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") == 0) {
48 print "A SLAPD is still listening to $uri before we started the LDAP backend. Aborting!";
51 # running slapd in the background means it stays in the same process group, so it can be
55 open STDOUT, ">$env_vars->{LDAPDIR}/logs";
56 open STDERR, '>&STDOUT';
57 close($env_vars->{STDIN_PIPE});
58 open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
60 if ($self->{ldap} eq "fedora-ds") {
61 exec("$ENV{FEDORA_DS_ROOT}/sbin/ns-slapd", "-D", $env_vars->{FEDORA_DS_DIR}, "-d0", "-i", $env_vars->{FEDORA_DS_PIDFILE});
62 } elsif ($self->{ldap} eq "openldap") {
63 exec($ENV{OPENLDAP_SLAPD}, "-dnone", "-F", $env_vars->{SLAPD_CONF_D}, "-h", $uri);
65 die("Unable to start slapd: $!");
67 $env_vars->{SLAPD_PID} = $pid;
69 while (system("$ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") != 0) {
72 $self->slapd_stop($env_vars);
82 my ($self, $envvars) = @_;
83 kill 9, $envvars->{SLAPD_PID};
87 sub check_or_start($$$)
89 my ($self, $env_vars, $process_model) = @_;
92 my $env_ok = $self->check_env($env_vars);
94 return $env_vars->{SAMBA_PID};
95 } elsif (defined($env_vars->{SAMBA_PID})) {
96 warn("SAMBA PID $env_vars->{SAMBA_PID} is not running (died)");
100 # use a pipe for stdin in the child processes. This allows
101 # those processes to monitor the pipe for EOF to ensure they
102 # exit when the test script exits
103 pipe($STDIN_READER, $env_vars->{STDIN_PIPE});
105 # Start slapd before samba, but with the fifo on stdin
106 if (defined($self->{ldap})) {
107 unless($self->slapd_start($env_vars, $STDIN_READER)) {
108 warn("couldn't start slapd (main run)");
113 print "STARTING SAMBA...\n";
116 # we want out from samba to go to the log file, but also
117 # to the users terminal when running 'make test' on the command
118 # line. This puts it on stderr on the terminal
119 open STDOUT, "| tee $env_vars->{SAMBA_TEST_LOG} 1>&2";
120 open STDERR, '>&STDOUT';
122 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
124 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
125 $ENV{KRB5CCNAME} = "$env_vars->{KRB5_CCACHE}.samba";
126 $ENV{SELFTEST_WINBINDD_SOCKET_DIR} = $env_vars->{SELFTEST_WINBINDD_SOCKET_DIR};
127 $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
129 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
130 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
131 $ENV{NSS_WRAPPER_HOSTS} = $env_vars->{NSS_WRAPPER_HOSTS};
132 $ENV{NSS_WRAPPER_HOSTNAME} = $env_vars->{NSS_WRAPPER_HOSTNAME};
133 $ENV{NSS_WRAPPER_MODULE_SO_PATH} = $env_vars->{NSS_WRAPPER_MODULE_SO_PATH};
134 $ENV{NSS_WRAPPER_MODULE_FN_PREFIX} = $env_vars->{NSS_WRAPPER_MODULE_FN_PREFIX};
136 if (defined($env_vars->{RESOLV_WRAPPER_CONF})) {
137 $ENV{RESOLV_WRAPPER_CONF} = $env_vars->{RESOLV_WRAPPER_CONF};
139 $ENV{RESOLV_WRAPPER_HOSTS} = $env_vars->{RESOLV_WRAPPER_HOSTS};
142 $ENV{UID_WRAPPER} = "1";
143 $ENV{UID_WRAPPER_ROOT} = "1";
145 $ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "samba");
148 if (defined($ENV{SAMBA_OPTIONS})) {
149 @optargs = split(/ /, $ENV{SAMBA_OPTIONS});
151 if(defined($ENV{SAMBA_VALGRIND})) {
152 @preargs = split(/ /,$ENV{SAMBA_VALGRIND});
155 close($env_vars->{STDIN_PIPE});
156 open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
158 exec(@preargs, Samba::bindir_path($self, "samba"), "-M", $process_model, "-i", "--maximum-runtime=$self->{server_maxtime}", $env_vars->{CONFIGURATION}, @optargs) or die("Unable to start samba: $!");
160 $env_vars->{SAMBA_PID} = $pid;
161 print "DONE ($pid)\n";
163 close($STDIN_READER);
165 if ($self->wait_for_start($env_vars) != 0) {
166 warn("Samba $pid failed to start up");
173 sub wait_for_start($$)
175 my ($self, $testenv_vars) = @_;
179 if (not $self->check_env($testenv_vars)) {
180 warn("unable to confirm Samba $testenv_vars->{SAMBA_PID} is running");
184 # This will return quickly when things are up, but be slow if we
185 # need to wait for (eg) SSL init
186 my $nmblookup = Samba::bindir_path($self, "nmblookup4");
189 $ret = system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
193 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
194 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
195 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
196 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
197 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
198 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
199 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
200 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
201 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
202 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
203 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
206 } while ($ret != 0 && $count < 20);
208 warn("nbt not reachable after 20 retries\n");
209 teardown_env($self, $testenv_vars);
213 # Ensure we have the first RID Set before we start tests. This makes the tests more reliable.
214 if ($testenv_vars->{SERVER_ROLE} eq "domain controller") {
215 # Add hosts file for name lookups
216 $ENV{NSS_WRAPPER_HOSTS} = $testenv_vars->{NSS_WRAPPER_HOSTS};
217 if (defined($testenv_vars->{RESOLV_WRAPPER_CONF})) {
218 $ENV{RESOLV_WRAPPER_CONF} = $testenv_vars->{RESOLV_WRAPPER_CONF};
220 $ENV{RESOLV_WRAPPER_HOSTS} = $testenv_vars->{RESOLV_WRAPPER_HOSTS};
223 print "waiting for working LDAP and a RID Set to be allocated\n";
224 my $ldbsearch = Samba::bindir_path($self, "ldbsearch");
226 my $base_dn = "DC=".join(",DC=", split(/\./, $testenv_vars->{REALM}));
228 my $search_dn = $base_dn;
229 if ($testenv_vars->{NETBIOSNAME} ne "RODC") {
230 # TODO currently no check for actual rIDAllocationPool
231 $search_dn = "cn=RID Set,cn=$testenv_vars->{NETBIOSNAME},ou=domain controllers,$base_dn";
234 my $cmd = "$ldbsearch $testenv_vars->{CONFIGURATION} -H ldap://$testenv_vars->{SERVER} -U$testenv_vars->{USERNAME}%$testenv_vars->{PASSWORD} -s base -b \"$search_dn\"";
235 while (system("$cmd >/dev/null") != 0) {
237 if ($count > $max_wait) {
238 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}");
245 print $self->getlog_env($testenv_vars);
250 sub write_ldb_file($$$)
252 my ($self, $file, $ldif) = @_;
254 my $ldbadd = Samba::bindir_path($self, "ldbadd");
255 open(LDIF, "|$ldbadd -H $file >/dev/null");
260 sub add_wins_config($$)
262 my ($self, $privatedir) = @_;
264 return $self->write_ldb_file("$privatedir/wins_config.ldb", "
265 dn: name=TORTURE_11,CN=PARTNERS
266 objectClass: wreplPartner
277 my ($self, $ctx) = @_;
279 #Make the subdirectory be as fedora DS would expect
280 my $fedora_ds_dir = "$ctx->{ldapdir}/slapd-$ctx->{ldap_instance}";
282 my $pidfile = "$fedora_ds_dir/logs/slapd-$ctx->{ldap_instance}.pid";
284 return ($fedora_ds_dir, $pidfile);
289 my ($self, $ctx) = @_;
291 my $slapd_conf_d = "$ctx->{ldapdir}/slapd.d";
292 my $pidfile = "$ctx->{ldapdir}/slapd.pid";
294 return ($slapd_conf_d, $pidfile);
297 sub setup_namespaces($$:$$)
299 my ($self, $localenv, $upn_array, $spn_array) = @_;
301 @{$upn_array} = [] unless defined($upn_array);
303 foreach my $upn (@{$upn_array}) {
304 $upn_args .= " --add-upn-suffix=$upn";
307 @{$spn_array} = [] unless defined($spn_array);
309 foreach my $spn (@{$spn_array}) {
310 $spn_args .= " --add-spn-suffix=$spn";
313 my $samba_tool = Samba::bindir_path($self, "samba-tool");
316 $cmd_env .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$localenv->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
317 if (defined($localenv->{RESOLV_WRAPPER_CONF})) {
318 $cmd_env .= "RESOLV_WRAPPER_CONF=\"$localenv->{RESOLV_WRAPPER_CONF}\" ";
320 $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$localenv->{RESOLV_WRAPPER_HOSTS}\" ";
322 $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\" ";
323 $cmd_env .= "KRB5CCNAME=\"$localenv->{KRB5_CCACHE}\" ";
325 my $cmd_config = " $localenv->{CONFIGURATION}";
327 my $namespaces = $cmd_env;
328 $namespaces .= " $samba_tool domain trust namespaces $upn_args $spn_args";
329 $namespaces .= $cmd_config;
330 unless (system($namespaces) == 0) {
331 warn("Failed to add namespaces \n$namespaces");
338 sub setup_trust($$$$$)
340 my ($self, $localenv, $remoteenv, $type, $extra_args) = @_;
342 $localenv->{TRUST_SERVER} = $remoteenv->{SERVER};
343 $localenv->{TRUST_SERVER_IP} = $remoteenv->{SERVER_IP};
344 $localenv->{TRUST_SERVER_IPV6} = $remoteenv->{SERVER_IPV6};
345 $localenv->{TRUST_NETBIOSNAME} = $remoteenv->{NETBIOSNAME};
346 $localenv->{TRUST_USERNAME} = $remoteenv->{USERNAME};
347 $localenv->{TRUST_PASSWORD} = $remoteenv->{PASSWORD};
348 $localenv->{TRUST_DOMAIN} = $remoteenv->{DOMAIN};
349 $localenv->{TRUST_REALM} = $remoteenv->{REALM};
351 my $samba_tool = Samba::bindir_path($self, "samba-tool");
354 $cmd_env .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$localenv->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
355 if (defined($localenv->{RESOLV_WRAPPER_CONF})) {
356 $cmd_env .= "RESOLV_WRAPPER_CONF=\"$localenv->{RESOLV_WRAPPER_CONF}\" ";
358 $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$localenv->{RESOLV_WRAPPER_HOSTS}\" ";
360 $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\" ";
361 $cmd_env .= "KRB5CCNAME=\"$localenv->{KRB5_CCACHE}\" ";
363 my $cmd_config = " $localenv->{CONFIGURATION}";
364 my $cmd_creds = $cmd_config;
365 $cmd_creds .= " -U$localenv->{TRUST_DOMAIN}\\\\$localenv->{TRUST_USERNAME}\%$localenv->{TRUST_PASSWORD}";
367 my $create = $cmd_env;
368 $create .= " $samba_tool domain trust create --type=${type} $localenv->{TRUST_REALM}";
369 $create .= " $extra_args";
370 $create .= $cmd_creds;
371 unless (system($create) == 0) {
372 warn("Failed to create trust \n$create");
379 sub provision_raw_prepare($$$$$$$$$$$)
381 my ($self, $prefix, $server_role, $hostname,
382 $domain, $realm, $functional_level,
383 $password, $kdc_ipv4, $kdc_ipv6) = @_;
385 my $netbiosname = uc($hostname);
387 unless(-d $prefix or mkdir($prefix, 0777)) {
388 warn("Unable to create $prefix");
391 my $prefix_abs = abs_path($prefix);
393 die ("prefix=''") if $prefix_abs eq "";
394 die ("prefix='/'") if $prefix_abs eq "/";
396 unless (system("rm -rf $prefix_abs/*") == 0) {
397 warn("Unable to clean up");
401 my $swiface = Samba::get_interface($hostname);
403 $ctx->{prefix} = $prefix;
404 $ctx->{prefix_abs} = $prefix_abs;
406 $ctx->{server_role} = $server_role;
407 $ctx->{hostname} = $hostname;
408 $ctx->{netbiosname} = $netbiosname;
409 $ctx->{swiface} = $swiface;
410 $ctx->{password} = $password;
411 $ctx->{kdc_ipv4} = $kdc_ipv4;
412 $ctx->{kdc_ipv6} = $kdc_ipv6;
413 $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}";
414 if ($functional_level eq "2000") {
415 $ctx->{supported_enctypes} = "arcfour-hmac-md5 des-cbc-md5 des-cbc-crc"
419 # Set smbd log level here.
421 $ctx->{server_loglevel} =$ENV{SERVER_LOG_LEVEL} || 1;
422 $ctx->{username} = "Administrator";
423 $ctx->{domain} = $domain;
424 $ctx->{realm} = uc($realm);
425 $ctx->{dnsname} = lc($realm);
427 $ctx->{functional_level} = $functional_level;
429 my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `whoami`);
431 $ctx->{unix_name} = $unix_name;
432 $ctx->{unix_uid} = $>;
433 my @mygid = split(" ", $();
434 $ctx->{unix_gid} = $mygid[0];
435 $ctx->{unix_gids_str} = $);
436 @{$ctx->{unix_gids}} = split(" ", $ctx->{unix_gids_str});
438 $ctx->{etcdir} = "$prefix_abs/etc";
439 $ctx->{piddir} = "$prefix_abs/pid";
440 $ctx->{smb_conf} = "$ctx->{etcdir}/smb.conf";
441 $ctx->{krb5_conf} = "$ctx->{etcdir}/krb5.conf";
442 $ctx->{krb5_ccache} = "$prefix_abs/krb5_ccache";
443 $ctx->{privatedir} = "$prefix_abs/private";
444 $ctx->{ncalrpcdir} = "$prefix_abs/ncalrpc";
445 $ctx->{lockdir} = "$prefix_abs/lockdir";
446 $ctx->{logdir} = "$prefix_abs/logs";
447 $ctx->{statedir} = "$prefix_abs/statedir";
448 $ctx->{cachedir} = "$prefix_abs/cachedir";
449 $ctx->{winbindd_socket_dir} = "$prefix_abs/winbindd_socket";
450 $ctx->{ntp_signd_socket_dir} = "$prefix_abs/ntp_signd_socket";
451 $ctx->{nsswrap_passwd} = "$ctx->{etcdir}/passwd";
452 $ctx->{nsswrap_group} = "$ctx->{etcdir}/group";
453 $ctx->{nsswrap_hosts} = "$ENV{SELFTEST_PREFIX}/hosts";
454 $ctx->{nsswrap_hostname} = "$ctx->{hostname}.$ctx->{dnsname}";
455 if ($ENV{SAMBA_DNS_FAKING}) {
456 $ctx->{dns_host_file} = "$ENV{SELFTEST_PREFIX}/dns_host_file";
457 $ctx->{samba_dnsupdate} = "$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate -s $ctx->{smb_conf} --all-interfaces --use-file=$ctx->{dns_host_file}";
459 $ctx->{samba_dnsupdate} = "$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate -s $ctx->{smb_conf} --all-interfaces";
460 $ctx->{use_resolv_wrapper} = 1;
462 $ctx->{resolv_conf} = "$ctx->{etcdir}/resolv.conf";
464 $ctx->{tlsdir} = "$ctx->{privatedir}/tls";
466 $ctx->{ipv4} = "127.0.0.$swiface";
467 $ctx->{ipv6} = sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface);
468 $ctx->{interfaces} = "$ctx->{ipv4}/8 $ctx->{ipv6}/64";
470 push(@{$ctx->{directories}}, $ctx->{privatedir});
471 push(@{$ctx->{directories}}, $ctx->{etcdir});
472 push(@{$ctx->{directories}}, $ctx->{piddir});
473 push(@{$ctx->{directories}}, $ctx->{lockdir});
474 push(@{$ctx->{directories}}, $ctx->{logdir});
475 push(@{$ctx->{directories}}, $ctx->{statedir});
476 push(@{$ctx->{directories}}, $ctx->{cachedir});
478 $ctx->{smb_conf_extra_options} = "";
480 my @provision_options = ();
481 push (@provision_options, "KRB5_CONFIG=\"$ctx->{krb5_conf}\"");
482 push (@provision_options, "KRB5_CCACHE=\"$ctx->{krb5_ccache}\"");
483 push (@provision_options, "NSS_WRAPPER_PASSWD=\"$ctx->{nsswrap_passwd}\"");
484 push (@provision_options, "NSS_WRAPPER_GROUP=\"$ctx->{nsswrap_group}\"");
485 push (@provision_options, "NSS_WRAPPER_HOSTS=\"$ctx->{nsswrap_hosts}\"");
486 push (@provision_options, "NSS_WRAPPER_HOSTNAME=\"$ctx->{nsswrap_hostname}\"");
487 if (defined($ctx->{use_resolv_wrapper})) {
488 push (@provision_options, "RESOLV_WRAPPER_CONF=\"$ctx->{resolv_conf}\"");
490 push (@provision_options, "RESOLV_WRAPPER_HOSTS=\"$ctx->{dns_host_file}\"");
492 if (defined($ENV{GDB_PROVISION})) {
493 push (@provision_options, "gdb --args");
494 if (!defined($ENV{PYTHON})) {
495 push (@provision_options, "env");
496 push (@provision_options, "python");
499 if (defined($ENV{VALGRIND_PROVISION})) {
500 push (@provision_options, "valgrind");
501 if (!defined($ENV{PYTHON})) {
502 push (@provision_options, "env");
503 push (@provision_options, "python");
506 if (defined($ENV{PYTHON})) {
507 push (@provision_options, $ENV{PYTHON});
509 push (@provision_options, Samba::bindir_path($self, "samba-tool"));
510 push (@provision_options, "domain");
511 push (@provision_options, "provision");
512 push (@provision_options, "--configfile=$ctx->{smb_conf}");
513 push (@provision_options, "--host-name=$ctx->{hostname}");
514 push (@provision_options, "--host-ip=$ctx->{ipv4}");
515 push (@provision_options, "--quiet");
516 push (@provision_options, "--domain=$ctx->{domain}");
517 push (@provision_options, "--realm=$ctx->{realm}");
518 push (@provision_options, "--adminpass=$ctx->{password}");
519 push (@provision_options, "--krbtgtpass=krbtgt$ctx->{password}");
520 push (@provision_options, "--machinepass=machine$ctx->{password}");
521 push (@provision_options, "--root=$ctx->{unix_name}");
522 push (@provision_options, "--server-role=\"$ctx->{server_role}\"");
523 push (@provision_options, "--function-level=\"$ctx->{functional_level}\"");
525 @{$ctx->{provision_options}} = @provision_options;
531 # Step1 creates the basic configuration
533 sub provision_raw_step1($$)
535 my ($self, $ctx) = @_;
537 mkdir($_, 0777) foreach (@{$ctx->{directories}});
540 ## lockdir and piddir must be 0755
542 chmod 0755, $ctx->{lockdir};
543 chmod 0755, $ctx->{piddir};
545 unless (open(CONFFILE, ">$ctx->{smb_conf}")) {
546 warn("can't open $ctx->{smb_conf}$?");
550 Samba::prepare_keyblobs($ctx);
551 my $crlfile = "$ctx->{tlsdir}/crl.pem";
552 $crlfile = "" unless -e ${crlfile};
556 netbios name = $ctx->{netbiosname}
557 posix:eadb = $ctx->{statedir}/eadb.tdb
558 workgroup = $ctx->{domain}
559 realm = $ctx->{realm}
560 private dir = $ctx->{privatedir}
561 pid directory = $ctx->{piddir}
562 ncalrpc dir = $ctx->{ncalrpcdir}
563 lock dir = $ctx->{lockdir}
564 state directory = $ctx->{statedir}
565 cache directory = $ctx->{cachedir}
566 winbindd socket directory = $ctx->{winbindd_socket_dir}
567 ntp signd socket directory = $ctx->{ntp_signd_socket_dir}
568 winbind separator = /
569 interfaces = $ctx->{interfaces}
570 tls dh params file = $ctx->{tlsdir}/dhparms.pem
571 tls crlfile = ${crlfile}
572 tls verify peer = no_check
573 panic action = $RealBin/gdb_backtrace \%d
575 server role = $ctx->{server_role}
576 server services = +echo +smb -s3fs
577 dcerpc endpoint servers = +winreg +srvsvc
578 notify:inotify = false
580 ldap server require strong auth = yes
581 #We don't want to pass our self-tests if the PAC code is wrong
582 gensec:require_pac = true
583 log file = $ctx->{logdir}/log.\%m
584 log level = $ctx->{server_loglevel}
588 dns update command = $ctx->{samba_dnsupdate}
589 spn update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_spnupdate -s $ctx->{smb_conf}
590 dreplsrv:periodic_startup_interval = 0
591 dsdb:schema update allowed = yes
593 vfs objects = dfs_samba4 acl_xattr fake_acls xattr_tdb streams_depot
595 idmap_ldb:use rfc2307=yes
596 winbind enum users = yes
597 winbind enum groups = yes
599 rpc server port:netlogon = 1026
605 # Begin extra options
606 $ctx->{smb_conf_extra_options}
611 #Default the KDC IP to the server's IP
612 if (not defined($ctx->{kdc_ipv4})) {
613 $ctx->{kdc_ipv4} = $ctx->{ipv4};
615 if (not defined($ctx->{kdc_ipv6})) {
616 $ctx->{kdc_ipv6} = $ctx->{ipv6};
619 Samba::mk_krb5_conf($ctx);
621 open(PWD, ">$ctx->{nsswrap_passwd}");
622 if ($ctx->{unix_uid} != 0) {
623 print PWD "root:x:0:0:root gecos:$ctx->{prefix_abs}:/bin/false\n";
625 print PWD "$ctx->{unix_name}:x:$ctx->{unix_uid}:65531:$ctx->{unix_name} gecos:$ctx->{prefix_abs}:/bin/false\n";
626 print PWD "nobody:x:65534:65533:nobody gecos:$ctx->{prefix_abs}:/bin/false
627 pdbtest:x:65533:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
628 pdbtest2:x:65532:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
629 pdbtest3:x:65531:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
630 pdbtest4:x:65530:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
633 my $uid_rfc2307test = 65533;
635 open(GRP, ">$ctx->{nsswrap_group}");
636 if ($ctx->{unix_gid} != 0) {
637 print GRP "root:x:0:\n";
639 print GRP "$ctx->{unix_name}:x:$ctx->{unix_gid}:\n";
640 print GRP "wheel:x:10:
643 nogroup:x:65534:nobody
646 my $gid_rfc2307test = 65532;
648 my $hostname = lc($ctx->{hostname});
649 open(HOSTS, ">>$ctx->{nsswrap_hosts}");
650 if ($hostname eq "localdc") {
651 print HOSTS "$ctx->{ipv4} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n";
652 print HOSTS "$ctx->{ipv6} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n";
654 print HOSTS "$ctx->{ipv4} ${hostname}.$ctx->{dnsname} ${hostname}\n";
655 print HOSTS "$ctx->{ipv6} ${hostname}.$ctx->{dnsname} ${hostname}\n";
659 if (defined($ctx->{resolv_conf})) {
660 open(RESOLV_CONF, ">$ctx->{resolv_conf}");
661 print RESOLV_CONF "nameserver $ctx->{kdc_ipv4}\n";
662 print RESOLV_CONF "nameserver $ctx->{kdc_ipv6}\n";
666 my $configuration = "--configfile=$ctx->{smb_conf}";
668 #Ensure the config file is valid before we start
669 my $testparm = Samba::bindir_path($self, "samba-tool") . " testparm";
670 if (system("$testparm $configuration -v --suppress-prompt >/dev/null 2>&1") != 0) {
671 system("$testparm -v --suppress-prompt $configuration >&2");
672 warn("Failed to create a valid smb.conf configuration $testparm!");
675 unless (system("($testparm $configuration -v --suppress-prompt --parameter-name=\"netbios name\" --section-name=global 2> /dev/null | grep -i \"^$ctx->{netbiosname}\" ) >/dev/null 2>&1") == 0) {
676 warn("Failed to create a valid smb.conf configuration! $testparm $configuration -v --suppress-prompt --parameter-name=\"netbios name\" --section-name=global");
681 KRB5_CONFIG => $ctx->{krb5_conf},
682 KRB5_CCACHE => $ctx->{krb5_ccache},
683 PIDDIR => $ctx->{piddir},
684 SERVER => $ctx->{hostname},
685 SERVER_IP => $ctx->{ipv4},
686 SERVER_IPV6 => $ctx->{ipv6},
687 NETBIOSNAME => $ctx->{netbiosname},
688 DOMAIN => $ctx->{domain},
689 USERNAME => $ctx->{username},
690 REALM => $ctx->{realm},
691 PASSWORD => $ctx->{password},
692 LDAPDIR => $ctx->{ldapdir},
693 LDAP_INSTANCE => $ctx->{ldap_instance},
694 SELFTEST_WINBINDD_SOCKET_DIR => $ctx->{winbindd_socket_dir},
695 NCALRPCDIR => $ctx->{ncalrpcdir},
696 LOCKDIR => $ctx->{lockdir},
697 STATEDIR => $ctx->{statedir},
698 CACHEDIR => $ctx->{cachedir},
699 PRIVATEDIR => $ctx->{privatedir},
700 SERVERCONFFILE => $ctx->{smb_conf},
701 CONFIGURATION => $configuration,
702 SOCKET_WRAPPER_DEFAULT_IFACE => $ctx->{swiface},
703 NSS_WRAPPER_PASSWD => $ctx->{nsswrap_passwd},
704 NSS_WRAPPER_GROUP => $ctx->{nsswrap_group},
705 NSS_WRAPPER_HOSTS => $ctx->{nsswrap_hosts},
706 NSS_WRAPPER_HOSTNAME => $ctx->{nsswrap_hostname},
707 SAMBA_TEST_FIFO => "$ctx->{prefix}/samba_test.fifo",
708 SAMBA_TEST_LOG => "$ctx->{prefix}/samba_test.log",
709 SAMBA_TEST_LOG_POS => 0,
710 NSS_WRAPPER_MODULE_SO_PATH => Samba::nss_wrapper_winbind_so_path($self),
711 NSS_WRAPPER_MODULE_FN_PREFIX => "winbind",
712 LOCAL_PATH => $ctx->{share},
713 UID_RFC2307TEST => $uid_rfc2307test,
714 GID_RFC2307TEST => $gid_rfc2307test,
715 SERVER_ROLE => $ctx->{server_role},
716 RESOLV_CONF => $ctx->{resolv_conf}
719 if (defined($ctx->{use_resolv_wrapper})) {
720 $ret->{RESOLV_WRAPPER_CONF} = $ctx->{resolv_conf};
722 $ret->{RESOLV_WRAPPER_HOSTS} = $ctx->{dns_host_file};
729 # Step2 runs the provision script
731 sub provision_raw_step2($$$)
733 my ($self, $ctx, $ret) = @_;
735 my $provision_cmd = join(" ", @{$ctx->{provision_options}});
736 unless (system($provision_cmd) == 0) {
737 warn("Unable to provision: \n$provision_cmd\n");
741 my $testallowed_account = "testallowed";
742 my $samba_tool_cmd = "";
743 $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
744 $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
745 $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
746 . " user create --configfile=$ctx->{smb_conf} $testallowed_account $ctx->{password}";
747 unless (system($samba_tool_cmd) == 0) {
748 warn("Unable to add testallowed user: \n$samba_tool_cmd\n");
753 $ldbmodify .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
754 $ldbmodify .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
755 $ldbmodify .= Samba::bindir_path($self, "ldbmodify");
756 my $base_dn = "DC=".join(",DC=", split(/\./, $ctx->{realm}));
758 if ($ctx->{server_role} ne "domain controller") {
759 $base_dn = "DC=$ctx->{netbiosname}";
762 my $user_dn = "cn=$testallowed_account,cn=users,$base_dn";
763 $testallowed_account = "testallowed account";
764 open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
765 print LDIF "dn: $user_dn
767 replace: samAccountName
768 samAccountName: $testallowed_account
773 open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
774 print LDIF "dn: $user_dn
776 replace: userPrincipalName
777 userPrincipalName: testallowed upn\@$ctx->{realm}
778 replace: servicePrincipalName
779 servicePrincipalName: host/testallowed
784 $samba_tool_cmd = "";
785 $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
786 $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
787 $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
788 . " user create --configfile=$ctx->{smb_conf} testdenied $ctx->{password}";
789 unless (system($samba_tool_cmd) == 0) {
790 warn("Unable to add testdenied user: \n$samba_tool_cmd\n");
794 my $user_dn = "cn=testdenied,cn=users,$base_dn";
795 open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
796 print LDIF "dn: $user_dn
798 replace: userPrincipalName
799 userPrincipalName: testdenied_upn\@$ctx->{realm}.upn
804 $samba_tool_cmd = "";
805 $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
806 $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
807 $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
808 . " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account'";
809 unless (system($samba_tool_cmd) == 0) {
810 warn("Unable to add '$testallowed_account' user to 'Allowed RODC Password Replication Group': \n$samba_tool_cmd\n");
814 # Create to users alice and bob!
815 my $user_account_array = ["alice", "bob"];
817 foreach my $user_account (@{$user_account_array}) {
818 my $samba_tool_cmd = "";
820 $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
821 $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
822 $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
823 . " user create --configfile=$ctx->{smb_conf} $user_account Secret007";
824 unless (system($samba_tool_cmd) == 0) {
825 warn("Unable to create user: $user_account\n$samba_tool_cmd\n");
833 sub provision($$$$$$$$$$)
835 my ($self, $prefix, $server_role, $hostname,
836 $domain, $realm, $functional_level,
837 $password, $kdc_ipv4, $kdc_ipv6, $extra_smbconf_options, $extra_smbconf_shares,
838 $extra_provision_options) = @_;
840 my $ctx = $self->provision_raw_prepare($prefix, $server_role,
842 $domain, $realm, $functional_level,
843 $password, $kdc_ipv4, $kdc_ipv6);
845 if (defined($extra_provision_options)) {
846 push (@{$ctx->{provision_options}}, @{$extra_provision_options});
848 push (@{$ctx->{provision_options}}, "--use-ntvfs");
851 $ctx->{share} = "$ctx->{prefix_abs}/share";
852 push(@{$ctx->{directories}}, "$ctx->{share}");
853 push(@{$ctx->{directories}}, "$ctx->{share}/test1");
854 push(@{$ctx->{directories}}, "$ctx->{share}/test2");
856 # precreate directories for printer drivers
857 push(@{$ctx->{directories}}, "$ctx->{share}/W32X86");
858 push(@{$ctx->{directories}}, "$ctx->{share}/x64");
859 push(@{$ctx->{directories}}, "$ctx->{share}/WIN40");
862 $msdfs = "yes" if ($server_role eq "domain controller");
863 $ctx->{smb_conf_extra_options} = "
866 server max protocol = SMB2
870 # fruit:copyfile is a global option
873 $extra_smbconf_options
878 posix:sharedelay = 100000
879 posix:oplocktimeout = 3
880 posix:writetimeupdatedelay = 500000
885 posix:sharedelay = 100000
886 posix:oplocktimeout = 3
887 posix:writetimeupdatedelay = 500000
889 force create mode = 777
895 force create mode = 0
896 directory mask = 0777
897 force directory mode = 0
900 path = $ctx->{share}/test1
902 posix:sharedelay = 100000
903 posix:oplocktimeout = 3
904 posix:writetimeupdatedelay = 500000
907 path = $ctx->{share}/test2
909 posix:sharedelay = 100000
910 posix:oplocktimeout = 3
911 posix:writetimeupdatedelay = 500000
914 path = $ctx->{share}/_ignore_cifs_
917 cifs:server = $ctx->{netbiosname}
919 cifs:use-s4u2proxy = yes
920 # There is no username specified here, instead the client is expected
921 # to log in with kerberos, and the serverwill use delegated credentials.
922 # Or the server tries s4u2self/s4u2proxy to impersonate the client
927 ntvfs handler = simple
930 path = $ctx->{statedir}/sysvol
934 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
939 ntvfs handler = cifsposix
943 vfs objects = catia fruit streams_xattr acl_xattr
945 fruit:resource = file
946 fruit:metadata = netatalk
947 fruit:locking = netatalk
948 fruit:encoding = native
950 $extra_smbconf_shares
953 if (defined($self->{ldap})) {
954 $ctx->{ldapdir} = "$ctx->{privatedir}/ldap";
955 push(@{$ctx->{directories}}, "$ctx->{ldapdir}");
957 my $ldap_uri= "$ctx->{ldapdir}/ldapi";
958 $ldap_uri =~ s|/|%2F|g;
959 $ldap_uri = "ldapi://$ldap_uri";
960 $ctx->{ldap_uri} = $ldap_uri;
962 $ctx->{ldap_instance} = lc($ctx->{netbiosname});
965 my $ret = $self->provision_raw_step1($ctx);
966 unless (defined $ret) {
970 if (defined($self->{ldap})) {
971 $ret->{LDAP_URI} = $ctx->{ldap_uri};
972 push (@{$ctx->{provision_options}}, "--ldap-backend-type=" . $self->{ldap});
973 push (@{$ctx->{provision_options}}, "--ldap-backend-nosync");
974 if ($self->{ldap} eq "openldap") {
975 push (@{$ctx->{provision_options}}, "--slapd-path=" . $ENV{OPENLDAP_SLAPD});
976 ($ret->{SLAPD_CONF_D}, $ret->{OPENLDAP_PIDFILE}) = $self->mk_openldap($ctx) or die("Unable to create openldap directories");
978 } elsif ($self->{ldap} eq "fedora-ds") {
979 push (@{$ctx->{provision_options}}, "--slapd-path=" . "$ENV{FEDORA_DS_ROOT}/sbin/ns-slapd");
980 push (@{$ctx->{provision_options}}, "--setup-ds-path=" . "$ENV{FEDORA_DS_ROOT}/sbin/setup-ds.pl");
981 ($ret->{FEDORA_DS_DIR}, $ret->{FEDORA_DS_PIDFILE}) = $self->mk_fedora_ds($ctx) or die("Unable to create fedora ds directories");
986 return $self->provision_raw_step2($ctx, $ret);
989 sub provision_s4member($$$$$)
991 my ($self, $prefix, $dcvars, $hostname, $more_conf) = @_;
992 print "PROVISIONING MEMBER...\n";
993 my $extra_smb_conf = "
994 passdb backend = samba_dsdb
995 winbindd:use external pipes = true
997 # the source4 smb server doesn't allow signing by default
998 server signing = enabled
1000 rpc_server:default = external
1001 rpc_server:svcctl = embedded
1002 rpc_server:srvsvc = embedded
1003 rpc_server:eventlog = embedded
1004 rpc_server:ntsvcs = embedded
1005 rpc_server:winreg = embedded
1006 rpc_server:spoolss = embedded
1007 rpc_daemon:spoolssd = embedded
1008 rpc_server:tcpip = no
1011 $extra_smb_conf = $extra_smb_conf . $more_conf . "\n";
1013 my $ret = $self->provision($prefix,
1017 "samba.example.com",
1020 $dcvars->{SERVER_IP},
1021 $dcvars->{SERVER_IPV6},
1022 $extra_smb_conf, "", undef);
1027 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1029 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1030 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1031 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1033 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1035 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1036 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1037 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} member";
1038 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1039 $cmd .= " --machinepass=machine$ret->{PASSWORD}";
1041 unless (system($cmd) == 0) {
1042 warn("Join failed\n$cmd");
1046 $ret->{MEMBER_SERVER} = $ret->{SERVER};
1047 $ret->{MEMBER_SERVER_IP} = $ret->{SERVER_IP};
1048 $ret->{MEMBER_SERVER_IPV6} = $ret->{SERVER_IPV6};
1049 $ret->{MEMBER_NETBIOSNAME} = $ret->{NETBIOSNAME};
1050 $ret->{MEMBER_USERNAME} = $ret->{USERNAME};
1051 $ret->{MEMBER_PASSWORD} = $ret->{PASSWORD};
1053 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1054 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1055 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1056 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1057 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1058 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1063 sub provision_rpc_proxy($$$)
1065 my ($self, $prefix, $dcvars) = @_;
1066 print "PROVISIONING RPC PROXY...\n";
1068 my $extra_smbconf_options = "
1069 passdb backend = samba_dsdb
1072 dcerpc_remote:binding = ncacn_ip_tcp:$dcvars->{SERVER}
1073 dcerpc endpoint servers = epmapper, remote
1074 dcerpc_remote:interfaces = rpcecho
1077 path = /tmp/_ignore_cifs_to_dc_/_none_
1079 ntvfs handler = cifs
1080 cifs:server = $dcvars->{SERVER}
1082 cifs:use-s4u2proxy = yes
1083 # There is no username specified here, instead the client is expected
1084 # to log in with kerberos, and the serverwill use delegated credentials.
1085 # Or the server tries s4u2self/s4u2proxy to impersonate the client
1089 my $ret = $self->provision($prefix,
1093 "samba.example.com",
1096 $dcvars->{SERVER_IP},
1097 $dcvars->{SERVER_IPV6},
1098 $extra_smbconf_options, "", undef);
1103 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1105 # The joind runs in the context of the rpc_proxy/member for now
1107 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1108 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1109 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1111 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1113 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1114 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1115 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} member";
1116 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1117 $cmd .= " --machinepass=machine$ret->{PASSWORD}";
1119 unless (system($cmd) == 0) {
1120 warn("Join failed\n$cmd");
1124 # Setting up delegation runs in the context of the DC for now
1126 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1127 $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
1128 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1129 $cmd .= "$samba_tool delegation for-any-protocol '$ret->{NETBIOSNAME}\$' on";
1130 $cmd .= " $dcvars->{CONFIGURATION}";
1133 unless (system($cmd) == 0) {
1134 warn("Delegation failed\n$cmd");
1138 # Setting up delegation runs in the context of the DC for now
1140 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1141 $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
1142 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1143 $cmd .= "$samba_tool delegation add-service '$ret->{NETBIOSNAME}\$' cifs/$dcvars->{SERVER}";
1144 $cmd .= " $dcvars->{CONFIGURATION}";
1146 unless (system($cmd) == 0) {
1147 warn("Delegation failed\n$cmd");
1151 $ret->{RPC_PROXY_SERVER} = $ret->{SERVER};
1152 $ret->{RPC_PROXY_SERVER_IP} = $ret->{SERVER_IP};
1153 $ret->{RPC_PROXY_SERVER_IPV6} = $ret->{SERVER_IPV6};
1154 $ret->{RPC_PROXY_NETBIOSNAME} = $ret->{NETBIOSNAME};
1155 $ret->{RPC_PROXY_USERNAME} = $ret->{USERNAME};
1156 $ret->{RPC_PROXY_PASSWORD} = $ret->{PASSWORD};
1158 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1159 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1160 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1161 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1162 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1163 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1168 sub provision_promoted_dc($$$)
1170 my ($self, $prefix, $dcvars) = @_;
1171 print "PROVISIONING PROMOTED DC...\n";
1173 # We do this so that we don't run the provision. That's the job of 'samba-tool domain dcpromo'.
1174 my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1177 "samba.example.com",
1179 $dcvars->{PASSWORD},
1180 $dcvars->{SERVER_IP},
1181 $dcvars->{SERVER_IPV6});
1183 push (@{$ctx->{provision_options}}, "--use-ntvfs");
1185 $ctx->{smb_conf_extra_options} = "
1187 server max protocol = SMB2
1190 path = $ctx->{statedir}/sysvol
1194 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1199 my $ret = $self->provision_raw_step1($ctx);
1204 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1206 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1207 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1208 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1210 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1212 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1213 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1214 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} MEMBER --realm=$dcvars->{REALM}";
1215 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1216 $cmd .= " --machinepass=machine$ret->{PASSWORD}";
1218 unless (system($cmd) == 0) {
1219 warn("Join failed\n$cmd");
1223 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1225 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1226 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1227 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1228 $cmd .= "$samba_tool domain dcpromo $ret->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
1229 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1230 $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs --dns-backend=BIND9_DLZ";
1232 unless (system($cmd) == 0) {
1233 warn("Join failed\n$cmd");
1237 $ret->{PROMOTED_DC_SERVER} = $ret->{SERVER};
1238 $ret->{PROMOTED_DC_SERVER_IP} = $ret->{SERVER_IP};
1239 $ret->{PROMOTED_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1240 $ret->{PROMOTED_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1242 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1243 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1244 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1245 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1246 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1247 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1252 sub provision_vampire_dc($$$)
1254 my ($self, $prefix, $dcvars, $fl) = @_;
1255 print "PROVISIONING VAMPIRE DC @ FL $fl...\n";
1256 my $name = "localvampiredc";
1258 if ($fl == "2000") {
1259 $name = "vampire2000dc";
1262 # We do this so that we don't run the provision. That's the job of 'net vampire'.
1263 my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1268 $dcvars->{PASSWORD},
1269 $dcvars->{SERVER_IP},
1270 $dcvars->{SERVER_IPV6});
1272 push (@{$ctx->{provision_options}}, "--use-ntvfs");
1274 $ctx->{smb_conf_extra_options} = "
1276 server max protocol = SMB2
1279 path = $ctx->{statedir}/sysvol
1283 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1288 my $ret = $self->provision_raw_step1($ctx);
1293 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1295 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1296 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1297 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1299 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1301 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1302 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1303 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
1304 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD} --domain-critical-only";
1305 $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs";
1307 unless (system($cmd) == 0) {
1308 warn("Join failed\n$cmd");
1312 if ($fl == "2000") {
1313 $ret->{VAMPIRE_2000_DC_SERVER} = $ret->{SERVER};
1314 $ret->{VAMPIRE_2000_DC_SERVER_IP} = $ret->{SERVER_IP};
1315 $ret->{VAMPIRE_2000_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1316 $ret->{VAMPIRE_2000_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1318 $ret->{VAMPIRE_DC_SERVER} = $ret->{SERVER};
1319 $ret->{VAMPIRE_DC_SERVER_IP} = $ret->{SERVER_IP};
1320 $ret->{VAMPIRE_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1321 $ret->{VAMPIRE_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1323 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1324 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1325 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1326 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1327 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1328 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1329 $ret->{DC_REALM} = $dcvars->{DC_REALM};
1334 sub provision_subdom_dc($$$)
1336 my ($self, $prefix, $dcvars) = @_;
1337 print "PROVISIONING SUBDOMAIN DC...\n";
1339 # We do this so that we don't run the provision. That's the job of 'net vampire'.
1340 my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1343 "sub.samba.example.com",
1345 $dcvars->{PASSWORD},
1348 push (@{$ctx->{provision_options}}, "--use-ntvfs");
1350 $ctx->{smb_conf_extra_options} = "
1352 server max protocol = SMB2
1355 path = $ctx->{statedir}/sysvol
1359 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1364 my $ret = $self->provision_raw_step1($ctx);
1369 Samba::mk_krb5_conf($ctx);
1371 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1373 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1374 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1375 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1377 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1379 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1380 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1381 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $ctx->{dnsname} subdomain ";
1382 $cmd .= "--parent-domain=$dcvars->{REALM} -U$dcvars->{DC_USERNAME}\@$dcvars->{REALM}\%$dcvars->{DC_PASSWORD}";
1383 $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs";
1384 $cmd .= " --adminpass=$ret->{PASSWORD}";
1386 unless (system($cmd) == 0) {
1387 warn("Join failed\n$cmd");
1391 $ret->{SUBDOM_DC_SERVER} = $ret->{SERVER};
1392 $ret->{SUBDOM_DC_SERVER_IP} = $ret->{SERVER_IP};
1393 $ret->{SUBDOM_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1394 $ret->{SUBDOM_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1396 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1397 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1398 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1399 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1400 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1401 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1406 sub provision_ad_dc_ntvfs($$)
1408 my ($self, $prefix) = @_;
1410 # We keep the old 'winbind' name here in server services to
1411 # ensure upgrades which used that name still work with the now
1414 print "PROVISIONING AD DC (NTVFS)...\n";
1415 my $extra_conf_options = "netbios aliases = localDC1-a
1416 server services = +winbind -winbindd
1417 ldap server require strong auth = allow_sasl_over_tls
1418 allow nt4 crypto = yes
1419 lsa over netlogon = yes
1420 rpc server port = 1027
1422 my $ret = $self->provision($prefix,
1423 "domain controller",
1426 "samba.example.com",
1431 $extra_conf_options,
1438 unless($self->add_wins_config("$prefix/private")) {
1439 warn("Unable to add wins configuration");
1442 $ret->{NETBIOSALIAS} = "localdc1-a";
1443 $ret->{DC_SERVER} = $ret->{SERVER};
1444 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1445 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1446 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1447 $ret->{DC_USERNAME} = $ret->{USERNAME};
1448 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1449 $ret->{DC_REALM} = $ret->{REALM};
1454 sub provision_fl2000dc($$)
1456 my ($self, $prefix) = @_;
1458 print "PROVISIONING DC WITH FOREST LEVEL 2000...\n";
1459 my $extra_conf_options = "
1460 spnego:simulate_w2k=yes
1461 ntlmssp_server:force_old_spnego=yes
1463 my $ret = $self->provision($prefix,
1464 "domain controller",
1467 "samba2000.example.com",
1472 $extra_conf_options,
1479 unless($self->add_wins_config("$prefix/private")) {
1480 warn("Unable to add wins configuration");
1483 $ret->{DC_SERVER} = $ret->{SERVER};
1484 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1485 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1486 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1487 $ret->{DC_USERNAME} = $ret->{USERNAME};
1488 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1489 $ret->{DC_REALM} = $ret->{REALM};
1494 sub provision_fl2003dc($$$)
1496 my ($self, $prefix, $dcvars) = @_;
1497 my $swiface1 = Samba::get_interface("fakednsforwarder1");
1498 my $swiface2 = Samba::get_interface("fakednsforwarder2");
1500 print "PROVISIONING DC WITH FOREST LEVEL 2003...\n";
1501 my $extra_conf_options = "allow dns updates = nonsecure and secure
1502 dns forwarder = 127.0.0.$swiface1 127.0.0.$swiface2";
1503 my $ret = $self->provision($prefix,
1504 "domain controller",
1507 "samba2003.example.com",
1512 $extra_conf_options,
1515 unless (defined $ret) {
1519 $ret->{DC_SERVER} = $ret->{SERVER};
1520 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1521 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1522 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1523 $ret->{DC_USERNAME} = $ret->{USERNAME};
1524 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1525 $ret->{DNS_FORWARDER1} = "127.0.0.$swiface1";
1526 $ret->{DNS_FORWARDER2} = "127.0.0.$swiface2";
1528 my @samba_tool_options;
1529 push (@samba_tool_options, Samba::bindir_path($self, "samba-tool"));
1530 push (@samba_tool_options, "domain");
1531 push (@samba_tool_options, "passwordsettings");
1532 push (@samba_tool_options, "set");
1533 push (@samba_tool_options, "--configfile=$ret->{SERVERCONFFILE}");
1534 push (@samba_tool_options, "--min-pwd-age=0");
1535 push (@samba_tool_options, "--history-length=1");
1537 my $samba_tool_cmd = join(" ", @samba_tool_options);
1539 unless (system($samba_tool_cmd) == 0) {
1540 warn("Unable to set min password age to 0: \n$samba_tool_cmd\n");
1544 unless($self->add_wins_config("$prefix/private")) {
1545 warn("Unable to add wins configuration");
1552 sub provision_fl2008r2dc($$$)
1554 my ($self, $prefix, $dcvars) = @_;
1556 print "PROVISIONING DC WITH FOREST LEVEL 2008r2...\n";
1557 my $extra_conf_options = "ldap server require strong auth = no";
1558 my $ret = $self->provision($prefix,
1559 "domain controller",
1562 "samba2008R2.example.com",
1567 $extra_conf_options,
1570 unless (defined $ret) {
1574 unless ($self->add_wins_config("$prefix/private")) {
1575 warn("Unable to add wins configuration");
1578 $ret->{DC_SERVER} = $ret->{SERVER};
1579 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1580 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1581 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1582 $ret->{DC_USERNAME} = $ret->{USERNAME};
1583 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1584 $ret->{DC_REALM} = $ret->{REALM};
1590 sub provision_rodc($$$)
1592 my ($self, $prefix, $dcvars) = @_;
1593 print "PROVISIONING RODC...\n";
1595 # We do this so that we don't run the provision. That's the job of 'net join RODC'.
1596 my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1599 "samba.example.com",
1601 $dcvars->{PASSWORD},
1602 $dcvars->{SERVER_IP},
1603 $dcvars->{SERVER_IPV6});
1608 push (@{$ctx->{provision_options}}, "--use-ntvfs");
1610 $ctx->{share} = "$ctx->{prefix_abs}/share";
1611 push(@{$ctx->{directories}}, "$ctx->{share}");
1613 $ctx->{smb_conf_extra_options} = "
1615 server max protocol = SMB2
1618 path = $ctx->{statedir}/sysvol
1622 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1626 path = $ctx->{share}
1628 posix:sharedelay = 10000
1629 posix:oplocktimeout = 3
1630 posix:writetimeupdatedelay = 50000
1634 my $ret = $self->provision_raw_step1($ctx);
1639 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1641 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1642 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1643 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1645 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1647 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1648 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1649 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} RODC";
1650 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1651 $cmd .= " --server=$dcvars->{DC_SERVER} --use-ntvfs";
1653 unless (system($cmd) == 0) {
1654 warn("RODC join failed\n$cmd");
1658 # This ensures deterministic behaviour for tests that want to have the 'testallowed account'
1659 # user password verified on the RODC
1660 my $testallowed_account = "testallowed account";
1661 $cmd = "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1662 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1663 $cmd .= "$samba_tool rodc preload '$testallowed_account' $ret->{CONFIGURATION}";
1664 $cmd .= " --server=$dcvars->{DC_SERVER}";
1666 unless (system($cmd) == 0) {
1667 warn("RODC join failed\n$cmd");
1671 # we overwrite the kdc after the RODC join
1672 # so that use the RODC as kdc and test
1674 $ctx->{kdc_ipv4} = $ret->{SERVER_IP};
1675 $ctx->{kdc_ipv6} = $ret->{SERVER_IPV6};
1676 Samba::mk_krb5_conf($ctx);
1678 $ret->{RODC_DC_SERVER} = $ret->{SERVER};
1679 $ret->{RODC_DC_SERVER_IP} = $ret->{SERVER_IP};
1680 $ret->{RODC_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1681 $ret->{RODC_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1683 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1684 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1685 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1686 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1687 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1688 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1693 sub read_config_h($)
1697 open(LF, "<$name") or die("unable to read $name: $!");
1700 next if not (/^#define /);
1701 if (/^#define (.*?)[ \t]+(.*?)$/) {
1705 if (/^#define (.*?)[ \t]+$/) {
1714 sub provision_ad_dc($$)
1716 my ($self, $prefix) = @_;
1718 my $prefix_abs = abs_path($prefix);
1720 my $bindir_abs = abs_path($self->{bindir});
1721 my $lockdir="$prefix_abs/lockdir";
1722 my $conffile="$prefix_abs/etc/smb.conf";
1724 my $require_mutexes = "dbwrap_tdb_require_mutexes:* = yes";
1725 $require_mutexes = "" if ($ENV{SELFTEST_DONT_REQUIRE_TDB_MUTEX_SUPPORT} eq "1");
1729 if (defined($ENV{CONFIG_H})) {
1730 $config_h = read_config_h($ENV{CONFIG_H});
1733 my $password_hash_gpg_key_ids = "password hash gpg key ids = 4952E40301FAB41A";
1734 $password_hash_gpg_key_ids = "" unless defined($config_h->{HAVE_GPGME});
1736 my $extra_smbconf_options = "
1737 server services = -smb +s3fs
1738 xattr_tdb:file = $prefix_abs/statedir/xattr.tdb
1740 dbwrap_tdb_mutexes:* = yes
1743 ${password_hash_gpg_key_ids}
1746 kernel change notify = no
1751 printcap name = /dev/null
1756 smbd:sharedelay = 100000
1757 smbd:writetimeupdatedelay = 500000
1761 dcerpc endpoint servers = -winreg -srvsvc
1763 printcap name = /dev/null
1765 addprinter command = $ENV{SRCDIR_ABS}/source3/script/tests/printing/modprinter.pl -a -s $conffile --
1766 deleteprinter command = $ENV{SRCDIR_ABS}/source3/script/tests/printing/modprinter.pl -d -s $conffile --
1769 print command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb print %p %s
1770 lpq command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpq %p
1771 lp rm command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lprm %p %j
1772 lp pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lppause %p %j
1773 lp resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpresume %p %j
1774 queue pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queuepause %p
1775 queue resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queueresume %p
1777 print notify backchannel = yes
1780 my $extra_smbconf_shares = "
1784 smb encrypt = required
1788 case sensitive = yes
1796 hide unreadable = yes
1800 kernel share modes = no
1819 print "PROVISIONING AD DC...\n";
1820 my $ret = $self->provision($prefix,
1821 "domain controller",
1824 "addom.samba.example.com",
1829 $extra_smbconf_options,
1830 $extra_smbconf_shares,
1832 unless (defined $ret) {
1836 unless($self->add_wins_config("$prefix/private")) {
1837 warn("Unable to add wins configuration");
1841 $ret->{DC_SERVER} = $ret->{SERVER};
1842 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1843 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1844 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1845 $ret->{DC_USERNAME} = $ret->{USERNAME};
1846 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1851 sub provision_chgdcpass($$)
1853 my ($self, $prefix) = @_;
1855 print "PROVISIONING CHGDCPASS...\n";
1856 my $extra_provision_options = undef;
1857 # This environment disallows the use of this password
1858 # (and also removes the default AD complexity checks)
1859 my $unacceptable_password = "widk3Dsle32jxdBdskldsk55klASKQ";
1860 push (@{$extra_provision_options}, "--dns-backend=BIND9_DLZ");
1861 my $ret = $self->provision($prefix,
1862 "domain controller",
1865 "chgdcpassword.samba.example.com",
1870 "check password script = sed -e '/$unacceptable_password/{;q1}; /$unacceptable_password/!{q0}'\n",
1872 $extra_provision_options);
1873 unless (defined $ret) {
1877 unless($self->add_wins_config("$prefix/private")) {
1878 warn("Unable to add wins configuration");
1882 # Remove secrets.tdb from this environment to test that we
1883 # still start up on systems without the new matching
1884 # secrets.tdb records.
1885 unless (unlink("$ret->{PRIVATEDIR}/secrets.tdb") || unlink("$ret->{PRIVATEDIR}/secrets.ntdb")) {
1886 warn("Unable to remove $ret->{PRIVATEDIR}/secrets.tdb added during provision");
1890 $ret->{DC_SERVER} = $ret->{SERVER};
1891 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1892 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1893 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1894 $ret->{DC_USERNAME} = $ret->{USERNAME};
1895 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1896 $ret->{UNACCEPTABLE_PASSWORD} = $unacceptable_password;
1901 sub teardown_env_terminate($$)
1903 my ($self, $envvars) = @_;
1906 # This should cause samba to terminate gracefully
1907 close($envvars->{STDIN_PIPE});
1909 $pid = $envvars->{SAMBA_PID};
1913 # This should give it time to write out the gcov data
1914 until ($count > 15) {
1915 if (Samba::cleanup_child($pid, "samba") != 0) {
1922 # After 15 Seconds, work out why this thing is still alive
1923 warn "server process $pid took more than $count seconds to exit, showing backtrace:\n";
1924 system("$self->{srcdir}/selftest/gdb_backtrace $pid");
1926 until ($count > 30) {
1927 if (Samba::cleanup_child($pid, "samba") != 0) {
1934 if (kill(0, $pid)) {
1935 warn "server process $pid took more than $count seconds to exit, sending SIGTERM\n";
1939 until ($count > 40) {
1940 if (Samba::cleanup_child($pid, "samba") != 0) {
1946 # If it is still around, kill it
1947 if (kill(0, $pid)) {
1948 warn "server process $pid took more than $count seconds to exit, killing\n with SIGKILL\n";
1954 sub teardown_env($$)
1956 my ($self, $envvars) = @_;
1957 teardown_env_terminate($self, $envvars);
1959 $self->slapd_stop($envvars) if ($self->{ldap});
1961 print $self->getlog_env($envvars);
1968 my ($self, $envvars) = @_;
1969 my $title = "SAMBA LOG of: $envvars->{NETBIOSNAME} pid $envvars->{SAMBA_PID}\n";
1972 open(LOG, "<$envvars->{SAMBA_TEST_LOG}");
1974 seek(LOG, $envvars->{SAMBA_TEST_LOG_POS}, SEEK_SET);
1978 $envvars->{SAMBA_TEST_LOG_POS} = tell(LOG);
1981 return "" if $out eq $title;
1988 my ($self, $envvars) = @_;
1989 my $samba_pid = $envvars->{SAMBA_PID};
1991 if (not defined($samba_pid)) {
1993 } elsif ($samba_pid > 0) {
1994 my $childpid = Samba::cleanup_child($samba_pid, "samba");
1996 if ($childpid == 0) {
2008 my ($self, $envname, $path) = @_;
2009 my $target3 = $self->{target3};
2011 $ENV{ENVNAME} = $envname;
2013 if (defined($self->{vars}->{$envname})) {
2014 return $self->{vars}->{$envname};
2017 if ($envname eq "ad_dc_ntvfs") {
2018 return $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2019 } elsif ($envname eq "fl2000dc") {
2020 return $self->setup_fl2000dc("$path/fl2000dc");
2021 } elsif ($envname eq "vampire_2000_dc") {
2022 if (not defined($self->{vars}->{fl2000dc})) {
2023 $self->setup_fl2000dc("$path/fl2000dc");
2025 return $self->setup_vampire_dc("$path/vampire_2000_dc", $self->{vars}->{fl2000dc}, "2000");
2026 } elsif ($envname eq "fl2003dc") {
2027 if (not defined($self->{vars}->{ad_dc})) {
2028 $self->setup_ad_dc("$path/ad_dc");
2030 return $self->setup_fl2003dc("$path/fl2003dc", $self->{vars}->{ad_dc});
2031 } elsif ($envname eq "fl2008r2dc") {
2032 if (not defined($self->{vars}->{ad_dc})) {
2033 $self->setup_ad_dc("$path/ad_dc");
2035 return $self->setup_fl2008r2dc("$path/fl2008r2dc", $self->{vars}->{ad_dc});
2036 } elsif ($envname eq "rpc_proxy") {
2037 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2038 $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2040 return $self->setup_rpc_proxy("$path/rpc_proxy", $self->{vars}->{ad_dc_ntvfs});
2041 } elsif ($envname eq "vampire_dc") {
2042 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2043 $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2045 return $self->setup_vampire_dc("$path/vampire_dc", $self->{vars}->{ad_dc_ntvfs}, "2008");
2046 } elsif ($envname eq "promoted_dc") {
2047 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2048 $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2050 return $self->setup_promoted_dc("$path/promoted_dc", $self->{vars}->{ad_dc_ntvfs});
2051 } elsif ($envname eq "subdom_dc") {
2052 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2053 $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2055 return $self->setup_subdom_dc("$path/subdom_dc", $self->{vars}->{ad_dc_ntvfs});
2056 } elsif ($envname eq "s4member_dflt_domain") {
2057 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2058 $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2060 return $self->setup_s4member_dflt_domain("$path/s4member_dflt_domain", $self->{vars}->{ad_dc_ntvfs});
2061 } elsif ($envname eq "s4member") {
2062 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2063 $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2065 return $self->setup_s4member("$path/s4member", $self->{vars}->{ad_dc_ntvfs});
2066 } elsif ($envname eq "rodc") {
2067 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2068 $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2070 return $self->setup_rodc("$path/rodc", $self->{vars}->{ad_dc_ntvfs});
2071 } elsif ($envname eq "chgdcpass") {
2072 return $self->setup_chgdcpass("$path/chgdcpass", $self->{vars}->{chgdcpass});
2073 } elsif ($envname eq "ad_member") {
2074 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2075 $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2077 return $target3->setup_admember("$path/ad_member", $self->{vars}->{ad_dc_ntvfs}, 29);
2078 } elsif ($envname eq "ad_dc") {
2079 return $self->setup_ad_dc("$path/ad_dc");
2080 } elsif ($envname eq "ad_dc_no_nss") {
2081 return $self->setup_ad_dc("$path/ad_dc_no_nss", "no_nss");
2082 } elsif ($envname eq "ad_member_rfc2307") {
2083 if (not defined($self->{vars}->{ad_dc_ntvfs})) {
2084 $self->setup_ad_dc_ntvfs("$path/ad_dc_ntvfs");
2086 return $target3->setup_admember_rfc2307("$path/ad_member_rfc2307",
2087 $self->{vars}->{ad_dc_ntvfs}, 34);
2088 } elsif ($envname eq "none") {
2089 return $self->setup_none("$path/none");
2095 sub setup_s4member($$$)
2097 my ($self, $path, $dc_vars) = @_;
2099 my $env = $self->provision_s4member($path, $dc_vars, "s4member");
2102 if (not defined($self->check_or_start($env, "standard"))) {
2106 $self->{vars}->{s4member} = $env;
2112 sub setup_s4member_dflt_domain($$$)
2114 my ($self, $path, $dc_vars) = @_;
2116 my $env = $self->provision_s4member($path, $dc_vars, "s4member_dflt",
2117 "winbind use default domain = yes");
2120 if (not defined($self->check_or_start($env, "standard"))) {
2124 $self->{vars}->{s4member_dflt_domain} = $env;
2130 sub setup_rpc_proxy($$$)
2132 my ($self, $path, $dc_vars) = @_;
2134 my $env = $self->provision_rpc_proxy($path, $dc_vars);
2137 if (not defined($self->check_or_start($env, "standard"))) {
2141 $self->{vars}->{rpc_proxy} = $env;
2146 sub setup_ad_dc_ntvfs($$)
2148 my ($self, $path) = @_;
2150 my $env = $self->provision_ad_dc_ntvfs($path);
2152 if (not defined($self->check_or_start($env, "standard"))) {
2153 warn("Failed to start ad_dc_ntvfs");
2157 $self->{vars}->{ad_dc_ntvfs} = $env;
2162 sub setup_chgdcpass($$)
2164 my ($self, $path) = @_;
2166 my $env = $self->provision_chgdcpass($path);
2168 if (not defined($self->check_or_start($env, "standard"))) {
2172 $self->{vars}->{chgdcpass} = $env;
2177 sub setup_fl2000dc($$)
2179 my ($self, $path) = @_;
2181 my $env = $self->provision_fl2000dc($path);
2183 if (not defined($self->check_or_start($env, "standard"))) {
2187 $self->{vars}->{fl2000dc} = $env;
2193 sub setup_fl2003dc($$$)
2195 my ($self, $path, $dc_vars) = @_;
2197 my $env = $self->provision_fl2003dc($path);
2200 if (not defined($self->check_or_start($env, "standard"))) {
2204 $env = $self->setup_trust($env, $dc_vars, "external", "--no-aes-keys");
2206 $self->{vars}->{fl2003dc} = $env;
2211 sub setup_fl2008r2dc($$$)
2213 my ($self, $path, $dc_vars) = @_;
2215 my $env = $self->provision_fl2008r2dc($path);
2218 if (not defined($self->check_or_start($env, "standard"))) {
2222 my $upn_array = ["$env->{REALM}.upn"];
2223 my $spn_array = ["$env->{REALM}.spn"];
2225 $self->setup_namespaces($env, $upn_array, $spn_array);
2227 $env = $self->setup_trust($env, $dc_vars, "forest", "");
2229 $self->{vars}->{fl2008r2dc} = $env;
2235 sub setup_vampire_dc($$$$)
2237 my ($self, $path, $dc_vars, $fl) = @_;
2239 my $env = $self->provision_vampire_dc($path, $dc_vars, $fl);
2242 if (not defined($self->check_or_start($env, "single"))) {
2246 $self->{vars}->{vampire_dc} = $env;
2248 # force replicated DC to update repsTo/repsFrom
2249 # for vampired partitions
2250 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2252 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
2253 if (defined($env->{RESOLV_WRAPPER_CONF})) {
2254 $cmd .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
2256 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
2258 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2259 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2260 $cmd .= " $samba_tool drs kcc -k no $env->{DC_SERVER}";
2261 $cmd .= " $env->{CONFIGURATION}";
2262 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2263 unless (system($cmd) == 0) {
2264 warn("Failed to exec kcc on remote DC\n$cmd");
2268 # as 'vampired' dc may add data in its local replica
2269 # we need to synchronize data between DCs
2270 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2272 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
2273 if (defined($env->{RESOLV_WRAPPER_CONF})) {
2274 $cmd .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
2276 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
2278 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2279 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2280 $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SERVER}";
2281 $cmd .= " $dc_vars->{CONFIGURATION}";
2282 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2283 # replicate Configuration NC
2284 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2285 unless(system($cmd_repl) == 0) {
2286 warn("Failed to replicate\n$cmd_repl");
2289 # replicate Default NC
2290 $cmd_repl = "$cmd \"$base_dn\"";
2291 unless(system($cmd_repl) == 0) {
2292 warn("Failed to replicate\n$cmd_repl");
2296 # Pull in a full set of changes from the main DC
2297 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2299 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
2300 if (defined($env->{RESOLV_WRAPPER_CONF})) {
2301 $cmd .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
2303 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
2305 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2306 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2307 $cmd .= " $samba_tool drs replicate $env->{SERVER} $env->{DC_SERVER}";
2308 $cmd .= " $dc_vars->{CONFIGURATION}";
2309 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2310 # replicate Configuration NC
2311 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2312 unless(system($cmd_repl) == 0) {
2313 warn("Failed to replicate\n$cmd_repl");
2316 # replicate Default NC
2317 $cmd_repl = "$cmd \"$base_dn\"";
2318 unless(system($cmd_repl) == 0) {
2319 warn("Failed to replicate\n$cmd_repl");
2327 sub setup_promoted_dc($$$)
2329 my ($self, $path, $dc_vars) = @_;
2331 my $env = $self->provision_promoted_dc($path, $dc_vars);
2334 if (not defined($self->check_or_start($env, "single"))) {
2338 $self->{vars}->{promoted_dc} = $env;
2340 # force source and replicated DC to update repsTo/repsFrom
2341 # for vampired partitions
2342 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2344 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2345 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2346 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2347 $cmd .= " $samba_tool drs kcc $env->{DC_SERVER}";
2348 $cmd .= " $env->{CONFIGURATION}";
2349 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2350 unless (system($cmd) == 0) {
2351 warn("Failed to exec kcc on remote DC\n$cmd");
2355 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2357 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2358 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2359 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2360 $cmd .= " $samba_tool drs kcc $env->{SERVER}";
2361 $cmd .= " $env->{CONFIGURATION}";
2362 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2363 unless (system($cmd) == 0) {
2364 warn("Failed to exec kcc on promoted DC\n$cmd");
2368 # as 'vampired' dc may add data in its local replica
2369 # we need to synchronize data between DCs
2370 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2371 $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2372 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2373 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2374 $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SERVER}";
2375 $cmd .= " $dc_vars->{CONFIGURATION}";
2376 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2377 # replicate Configuration NC
2378 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2379 unless(system($cmd_repl) == 0) {
2380 warn("Failed to replicate\n$cmd_repl");
2383 # replicate Default NC
2384 $cmd_repl = "$cmd \"$base_dn\"";
2385 unless(system($cmd_repl) == 0) {
2386 warn("Failed to replicate\n$cmd_repl");
2394 sub setup_subdom_dc($$$)
2396 my ($self, $path, $dc_vars) = @_;
2398 my $env = $self->provision_subdom_dc($path, $dc_vars);
2401 if (not defined($self->check_or_start($env, "single"))) {
2405 $self->{vars}->{subdom_dc} = $env;
2407 # force replicated DC to update repsTo/repsFrom
2408 # for primary domain partitions
2409 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2411 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2412 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2413 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2414 $cmd .= " $samba_tool drs kcc $env->{DC_SERVER}";
2415 $cmd .= " $env->{CONFIGURATION}";
2416 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD} --realm=$dc_vars->{DC_REALM}";
2417 unless (system($cmd) == 0) {
2418 warn("Failed to exec kcc on remote DC\n$cmd");
2422 # as 'subdomain' dc may add data in its local replica
2423 # we need to synchronize data between DCs
2424 my $base_dn = "DC=".join(",DC=", split(/\./, $env->{REALM}));
2425 my $config_dn = "CN=Configuration,DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2426 $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2427 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2428 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2429 $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SUBDOM_DC_SERVER}";
2430 $cmd .= " $dc_vars->{CONFIGURATION}";
2431 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD} --realm=$dc_vars->{DC_REALM}";
2432 # replicate Configuration NC
2433 my $cmd_repl = "$cmd \"$config_dn\"";
2434 unless(system($cmd_repl) == 0) {
2435 warn("Failed to replicate\n$cmd_repl");
2438 # replicate Default NC
2439 $cmd_repl = "$cmd \"$base_dn\"";
2440 unless(system($cmd_repl) == 0) {
2441 warn("Failed to replicate\n$cmd_repl");
2451 my ($self, $path, $dc_vars) = @_;
2453 my $env = $self->provision_rodc($path, $dc_vars);
2459 if (not defined($self->check_or_start($env, "single"))) {
2463 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2466 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2467 $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2468 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2469 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2470 $cmd .= " $samba_tool drs replicate $env->{SERVER} $env->{DC_SERVER}";
2471 $cmd .= " $dc_vars->{CONFIGURATION}";
2472 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2473 # replicate Configuration NC
2474 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2475 unless(system($cmd_repl) == 0) {
2476 warn("Failed to replicate\n$cmd_repl");
2479 # replicate Default NC
2480 $cmd_repl = "$cmd \"$base_dn\"";
2481 unless(system($cmd_repl) == 0) {
2482 warn("Failed to replicate\n$cmd_repl");
2486 $self->{vars}->{rodc} = $env;
2493 my ($self, $path, $no_nss) = @_;
2495 # If we didn't build with ADS, pretend this env was never available
2496 if (not $self->{target3}->have_ads()) {
2500 my $env = $self->provision_ad_dc($path);
2505 if (defined($no_nss) and $no_nss) {
2506 $env->{NSS_WRAPPER_MODULE_SO_PATH} = undef;
2507 $env->{NSS_WRAPPER_MODULE_FN_PREFIX} = undef;
2510 if (not defined($self->check_or_start($env, "single"))) {
2514 my $upn_array = ["$env->{REALM}.upn"];
2515 my $spn_array = ["$env->{REALM}.spn"];
2517 $self->setup_namespaces($env, $upn_array, $spn_array);
2519 $self->{vars}->{ad_dc} = $env;
2525 my ($self, $path) = @_;
2528 KRB5_CONFIG => abs_path($path) . "/no_krb5.conf",