gpo: Move policy application to the gp_ext
[Samba.git] / selftest / target / Samba4.pm
blob8a459ad71ab1313b7220a35b2dc620758f9b689f
1 #!/usr/bin/perl
2 # Bootstrap Samba and run a number of tests against it.
3 # Copyright (C) 2005-2007 Jelmer Vernooij <jelmer@samba.org>
4 # Published under the GNU GPL, v3 or later.
6 package Samba4;
8 use strict;
9 use Cwd qw(abs_path);
10 use FindBin qw($RealBin);
11 use POSIX;
12 use SocketWrapper;
13 use target::Samba;
14 use target::Samba3;
16 sub new($$$$$) {
17 my ($classname, $bindir, $ldap, $srcdir, $server_maxtime) = @_;
19 my $self = {
20 vars => {},
21 ldap => $ldap,
22 bindir => $bindir,
23 srcdir => $srcdir,
24 server_maxtime => $server_maxtime,
25 target3 => new Samba3($bindir, $srcdir, $server_maxtime)
27 bless $self;
28 return $self;
31 sub scriptdir_path($$) {
32 my ($self, $path) = @_;
33 return "$self->{srcdir}/source4/scripting/$path";
36 sub openldap_start($$$) {
39 sub slapd_start($$)
41 my $count = 0;
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!";
49 return 1;
51 # running slapd in the background means it stays in the same process group, so it can be
52 # killed by timelimit
53 my $pid = fork();
54 if ($pid == 0) {
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;
68 sleep(1);
69 while (system("$ldbsearch -H $uri -s base -b \"\" supportedLDAPVersion > /dev/null") != 0) {
70 $count++;
71 if ($count > 40) {
72 $self->slapd_stop($env_vars);
73 return 0;
75 sleep(1);
77 return 1;
80 sub slapd_stop($$)
82 my ($self, $envvars) = @_;
83 kill 9, $envvars->{SLAPD_PID};
84 return 1;
87 sub check_or_start($$$)
89 my ($self, $env_vars, $process_model) = @_;
90 my $STDIN_READER;
92 my $env_ok = $self->check_env($env_vars);
93 if ($env_ok) {
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)");
97 return undef;
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)");
109 return undef;
113 print "STARTING SAMBA...\n";
114 my $pid = fork();
115 if ($pid == 0) {
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 if (defined($ENV{MITKRB5})) {
127 $ENV{KRB5_KDC_PROFILE} = $env_vars->{MITKDC_CONFIG};
129 $ENV{SELFTEST_WINBINDD_SOCKET_DIR} = $env_vars->{SELFTEST_WINBINDD_SOCKET_DIR};
130 $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
132 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
133 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
134 $ENV{NSS_WRAPPER_HOSTS} = $env_vars->{NSS_WRAPPER_HOSTS};
135 $ENV{NSS_WRAPPER_HOSTNAME} = $env_vars->{NSS_WRAPPER_HOSTNAME};
136 $ENV{NSS_WRAPPER_MODULE_SO_PATH} = $env_vars->{NSS_WRAPPER_MODULE_SO_PATH};
137 $ENV{NSS_WRAPPER_MODULE_FN_PREFIX} = $env_vars->{NSS_WRAPPER_MODULE_FN_PREFIX};
139 if (defined($env_vars->{RESOLV_WRAPPER_CONF})) {
140 $ENV{RESOLV_WRAPPER_CONF} = $env_vars->{RESOLV_WRAPPER_CONF};
141 } else {
142 $ENV{RESOLV_WRAPPER_HOSTS} = $env_vars->{RESOLV_WRAPPER_HOSTS};
145 $ENV{UID_WRAPPER} = "1";
146 $ENV{UID_WRAPPER_ROOT} = "1";
148 $ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "samba");
149 my @preargs = ();
150 my @optargs = ();
151 if (defined($ENV{SAMBA_OPTIONS})) {
152 @optargs = split(/ /, $ENV{SAMBA_OPTIONS});
154 if(defined($ENV{SAMBA_VALGRIND})) {
155 @preargs = split(/ /,$ENV{SAMBA_VALGRIND});
158 close($env_vars->{STDIN_PIPE});
159 open STDIN, ">&", $STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
161 exec(@preargs, Samba::bindir_path($self, "samba"), "-M", $process_model, "-i", "--no-process-group", "--maximum-runtime=$self->{server_maxtime}", $env_vars->{CONFIGURATION}, @optargs) or die("Unable to start samba: $!");
163 $env_vars->{SAMBA_PID} = $pid;
164 print "DONE ($pid)\n";
166 close($STDIN_READER);
168 if ($self->wait_for_start($env_vars) != 0) {
169 warn("Samba $pid failed to start up");
170 return undef;
173 return $pid;
176 sub wait_for_start($$)
178 my ($self, $testenv_vars) = @_;
179 my $count = 0;
180 my $ret = 0;
182 if (not $self->check_env($testenv_vars)) {
183 warn("unable to confirm Samba $testenv_vars->{SAMBA_PID} is running");
184 return -1;
187 # This will return quickly when things are up, but be slow if we
188 # need to wait for (eg) SSL init
189 my $nmblookup = Samba::bindir_path($self, "nmblookup4");
191 do {
192 $ret = system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
193 if ($ret != 0) {
194 sleep(1);
195 } else {
196 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
197 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
198 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
199 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
200 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
201 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{SERVER}");
202 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{SERVER}");
203 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
204 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
205 system("$nmblookup $testenv_vars->{CONFIGURATION} $testenv_vars->{NETBIOSNAME}");
206 system("$nmblookup $testenv_vars->{CONFIGURATION} -U $testenv_vars->{SERVER_IP} $testenv_vars->{NETBIOSNAME}");
208 $count++;
209 } while ($ret != 0 && $count < 20);
210 if ($count == 20) {
211 warn("nbt not reachable after 20 retries\n");
212 teardown_env($self, $testenv_vars);
213 return 0;
216 # Ensure we have the first RID Set before we start tests. This makes the tests more reliable.
217 if ($testenv_vars->{SERVER_ROLE} eq "domain controller") {
218 print "waiting for working LDAP and a RID Set to be allocated\n";
219 my $ldbsearch = Samba::bindir_path($self, "ldbsearch");
220 my $count = 0;
221 my $base_dn = "DC=".join(",DC=", split(/\./, $testenv_vars->{REALM}));
223 my $search_dn = $base_dn;
224 if ($testenv_vars->{NETBIOSNAME} ne "RODC") {
225 # TODO currently no check for actual rIDAllocationPool
226 $search_dn = "cn=RID Set,cn=$testenv_vars->{NETBIOSNAME},ou=domain controllers,$base_dn";
228 my $max_wait = 60;
230 # Add hosts file for name lookups
231 my $cmd = "NSS_WRAPPER_HOSTS='$testenv_vars->{NSS_WRAPPER_HOSTS}' ";
232 if (defined($testenv_vars->{RESOLV_WRAPPER_CONF})) {
233 $cmd .= "RESOLV_WRAPPER_CONF='$testenv_vars->{RESOLV_WRAPPER_CONF}' ";
234 } else {
235 $cmd .= "RESOLV_WRAPPER_HOSTS='$testenv_vars->{RESOLV_WRAPPER_HOSTS}' ";
238 $cmd .= "$ldbsearch ";
239 $cmd .= "$testenv_vars->{CONFIGURATION} ";
240 $cmd .= "-H ldap://$testenv_vars->{SERVER} ";
241 $cmd .= "-U$testenv_vars->{USERNAME}%$testenv_vars->{PASSWORD} ";
242 $cmd .= "-s base ";
243 $cmd .= "-b '$search_dn' ";
244 while (system("$cmd >/dev/null") != 0) {
245 $count++;
246 if ($count > $max_wait) {
247 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}");
248 $ret = -1;
249 last;
251 sleep(1);
255 my $wbinfo = Samba::bindir_path($self, "wbinfo");
257 $count = 0;
258 do {
259 my $cmd = "NSS_WRAPPER_PASSWD=$testenv_vars->{NSS_WRAPPER_PASSWD} ";
260 $cmd .= "NSS_WRAPPER_GROUP=$testenv_vars->{NSS_WRAPPER_GROUP} ";
261 $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=$testenv_vars->{SELFTEST_WINBINDD_SOCKET_DIR} ";
262 $cmd .= "$wbinfo -P";
263 $ret = system($cmd);
265 if ($ret != 0) {
266 sleep(1);
268 $count++;
269 } while ($ret != 0 && $count < 20);
270 if ($count == 20) {
271 warn("winbind not reachable after 20 retries\n");
272 teardown_env($self, $testenv_vars);
273 return 0;
276 print $self->getlog_env($testenv_vars);
278 return $ret
281 sub write_ldb_file($$$)
283 my ($self, $file, $ldif) = @_;
285 my $ldbadd = Samba::bindir_path($self, "ldbadd");
286 open(LDIF, "|$ldbadd -H $file >/dev/null");
287 print LDIF $ldif;
288 return(close(LDIF));
291 sub add_wins_config($$)
293 my ($self, $privatedir) = @_;
295 return $self->write_ldb_file("$privatedir/wins_config.ldb", "
296 dn: name=TORTURE_11,CN=PARTNERS
297 objectClass: wreplPartner
298 name: TORTURE_11
299 address: 127.0.0.11
300 pullInterval: 0
301 pushChangeCount: 0
302 type: 0x3
306 sub mk_fedora_ds($$)
308 my ($self, $ctx) = @_;
310 #Make the subdirectory be as fedora DS would expect
311 my $fedora_ds_dir = "$ctx->{ldapdir}/slapd-$ctx->{ldap_instance}";
313 my $pidfile = "$fedora_ds_dir/logs/slapd-$ctx->{ldap_instance}.pid";
315 return ($fedora_ds_dir, $pidfile);
318 sub mk_openldap($$)
320 my ($self, $ctx) = @_;
322 my $slapd_conf_d = "$ctx->{ldapdir}/slapd.d";
323 my $pidfile = "$ctx->{ldapdir}/slapd.pid";
325 return ($slapd_conf_d, $pidfile);
328 sub setup_namespaces($$:$$)
330 my ($self, $localenv, $upn_array, $spn_array) = @_;
332 @{$upn_array} = [] unless defined($upn_array);
333 my $upn_args = "";
334 foreach my $upn (@{$upn_array}) {
335 $upn_args .= " --add-upn-suffix=$upn";
338 @{$spn_array} = [] unless defined($spn_array);
339 my $spn_args = "";
340 foreach my $spn (@{$spn_array}) {
341 $spn_args .= " --add-spn-suffix=$spn";
344 my $samba_tool = Samba::bindir_path($self, "samba-tool");
346 my $cmd_env = "NSS_WRAPPER_HOSTS='$localenv->{NSS_WRAPPER_HOSTS}' ";
347 $cmd_env .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$localenv->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
348 if (defined($localenv->{RESOLV_WRAPPER_CONF})) {
349 $cmd_env .= "RESOLV_WRAPPER_CONF=\"$localenv->{RESOLV_WRAPPER_CONF}\" ";
350 } else {
351 $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$localenv->{RESOLV_WRAPPER_HOSTS}\" ";
353 $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\" ";
354 $cmd_env .= "KRB5CCNAME=\"$localenv->{KRB5_CCACHE}\" ";
356 my $cmd_config = " $localenv->{CONFIGURATION}";
358 my $namespaces = $cmd_env;
359 $namespaces .= " $samba_tool domain trust namespaces $upn_args $spn_args";
360 $namespaces .= $cmd_config;
361 unless (system($namespaces) == 0) {
362 warn("Failed to add namespaces \n$namespaces");
363 return;
366 return;
369 sub setup_trust($$$$$)
371 my ($self, $localenv, $remoteenv, $type, $extra_args) = @_;
373 $localenv->{TRUST_SERVER} = $remoteenv->{SERVER};
374 $localenv->{TRUST_SERVER_IP} = $remoteenv->{SERVER_IP};
375 $localenv->{TRUST_SERVER_IPV6} = $remoteenv->{SERVER_IPV6};
376 $localenv->{TRUST_NETBIOSNAME} = $remoteenv->{NETBIOSNAME};
377 $localenv->{TRUST_USERNAME} = $remoteenv->{USERNAME};
378 $localenv->{TRUST_PASSWORD} = $remoteenv->{PASSWORD};
379 $localenv->{TRUST_DOMAIN} = $remoteenv->{DOMAIN};
380 $localenv->{TRUST_REALM} = $remoteenv->{REALM};
381 $localenv->{TRUST_DOMSID} = $remoteenv->{DOMSID};
383 my $samba_tool = Samba::bindir_path($self, "samba-tool");
384 # setup the trust
385 my $cmd_env = "NSS_WRAPPER_HOSTS='$localenv->{NSS_WRAPPER_HOSTS}' ";
386 $cmd_env .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$localenv->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
387 if (defined($localenv->{RESOLV_WRAPPER_CONF})) {
388 $cmd_env .= "RESOLV_WRAPPER_CONF=\"$localenv->{RESOLV_WRAPPER_CONF}\" ";
389 } else {
390 $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$localenv->{RESOLV_WRAPPER_HOSTS}\" ";
392 $cmd_env .= " KRB5_CONFIG=\"$localenv->{KRB5_CONFIG}\" ";
393 $cmd_env .= "KRB5CCNAME=\"$localenv->{KRB5_CCACHE}\" ";
395 my $cmd_config = " $localenv->{CONFIGURATION}";
396 my $cmd_creds = $cmd_config;
397 $cmd_creds .= " -U$localenv->{TRUST_DOMAIN}\\\\$localenv->{TRUST_USERNAME}\%$localenv->{TRUST_PASSWORD}";
399 my $create = $cmd_env;
400 $create .= " $samba_tool domain trust create --type=${type} $localenv->{TRUST_REALM}";
401 $create .= " $extra_args";
402 $create .= $cmd_creds;
403 unless (system($create) == 0) {
404 warn("Failed to create trust \n$create");
405 return undef;
408 my $groupname = "g_$localenv->{TRUST_DOMAIN}";
409 my $groupadd = $cmd_env;
410 $groupadd .= " $samba_tool group add '$groupname' --group-scope=Domain $cmd_config";
411 unless (system($groupadd) == 0) {
412 warn("Failed to create group \n$groupadd");
413 return undef;
415 my $groupmem = $cmd_env;
416 $groupmem .= " $samba_tool group addmembers '$groupname' '$localenv->{TRUST_DOMSID}-513' $cmd_config";
417 unless (system($groupmem) == 0) {
418 warn("Failed to add group member \n$groupmem");
419 return undef;
422 return $localenv
425 sub provision_raw_prepare($$$$$$$$$$$$)
427 my ($self, $prefix, $server_role, $hostname,
428 $domain, $realm, $samsid, $functional_level,
429 $password, $kdc_ipv4, $kdc_ipv6) = @_;
430 my $ctx;
431 my $netbiosname = uc($hostname);
433 unless(-d $prefix or mkdir($prefix, 0777)) {
434 warn("Unable to create $prefix");
435 return undef;
437 my $prefix_abs = abs_path($prefix);
439 die ("prefix=''") if $prefix_abs eq "";
440 die ("prefix='/'") if $prefix_abs eq "/";
442 unless (system("rm -rf $prefix_abs/*") == 0) {
443 warn("Unable to clean up");
447 my $swiface = Samba::get_interface($hostname);
449 $ctx->{prefix} = $prefix;
450 $ctx->{prefix_abs} = $prefix_abs;
452 $ctx->{server_role} = $server_role;
453 $ctx->{hostname} = $hostname;
454 $ctx->{netbiosname} = $netbiosname;
455 $ctx->{swiface} = $swiface;
456 $ctx->{password} = $password;
457 $ctx->{kdc_ipv4} = $kdc_ipv4;
458 $ctx->{kdc_ipv6} = $kdc_ipv6;
459 $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}";
460 if ($functional_level eq "2000") {
461 $ctx->{supported_enctypes} = "arcfour-hmac-md5 des-cbc-md5 des-cbc-crc"
465 # Set smbd log level here.
467 $ctx->{server_loglevel} =$ENV{SERVER_LOG_LEVEL} || 1;
468 $ctx->{username} = "Administrator";
469 $ctx->{domain} = $domain;
470 $ctx->{realm} = uc($realm);
471 $ctx->{dnsname} = lc($realm);
472 $ctx->{samsid} = $samsid;
474 $ctx->{functional_level} = $functional_level;
476 my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `whoami`);
477 chomp $unix_name;
478 $ctx->{unix_name} = $unix_name;
479 $ctx->{unix_uid} = $>;
480 my @mygid = split(" ", $();
481 $ctx->{unix_gid} = $mygid[0];
482 $ctx->{unix_gids_str} = $);
483 @{$ctx->{unix_gids}} = split(" ", $ctx->{unix_gids_str});
485 $ctx->{etcdir} = "$prefix_abs/etc";
486 $ctx->{piddir} = "$prefix_abs/pid";
487 $ctx->{smb_conf} = "$ctx->{etcdir}/smb.conf";
488 $ctx->{krb5_conf} = "$ctx->{etcdir}/krb5.conf";
489 $ctx->{krb5_ccache} = "$prefix_abs/krb5_ccache";
490 $ctx->{mitkdc_conf} = "$ctx->{etcdir}/mitkdc.conf";
491 $ctx->{privatedir} = "$prefix_abs/private";
492 $ctx->{binddnsdir} = "$prefix_abs/bind-dns";
493 $ctx->{ncalrpcdir} = "$prefix_abs/ncalrpc";
494 $ctx->{lockdir} = "$prefix_abs/lockdir";
495 $ctx->{logdir} = "$prefix_abs/logs";
496 $ctx->{statedir} = "$prefix_abs/statedir";
497 $ctx->{cachedir} = "$prefix_abs/cachedir";
498 $ctx->{winbindd_socket_dir} = "$prefix_abs/winbindd_socket";
499 $ctx->{ntp_signd_socket_dir} = "$prefix_abs/ntp_signd_socket";
500 $ctx->{nsswrap_passwd} = "$ctx->{etcdir}/passwd";
501 $ctx->{nsswrap_group} = "$ctx->{etcdir}/group";
502 $ctx->{nsswrap_hosts} = "$ENV{SELFTEST_PREFIX}/hosts";
503 $ctx->{nsswrap_hostname} = "$ctx->{hostname}.$ctx->{dnsname}";
504 if ($ENV{SAMBA_DNS_FAKING}) {
505 $ctx->{dns_host_file} = "$ENV{SELFTEST_PREFIX}/dns_host_file";
506 $ctx->{samba_dnsupdate} = "$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate -s $ctx->{smb_conf} --all-interfaces --use-file=$ctx->{dns_host_file}";
507 } else {
508 $ctx->{samba_dnsupdate} = "$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate -s $ctx->{smb_conf} --all-interfaces";
509 $ctx->{use_resolv_wrapper} = 1;
511 $ctx->{resolv_conf} = "$ctx->{etcdir}/resolv.conf";
513 $ctx->{tlsdir} = "$ctx->{privatedir}/tls";
515 $ctx->{ipv4} = "127.0.0.$swiface";
516 $ctx->{ipv6} = sprintf("fd00:0000:0000:0000:0000:0000:5357:5f%02x", $swiface);
517 $ctx->{interfaces} = "$ctx->{ipv4}/8 $ctx->{ipv6}/64";
519 push(@{$ctx->{directories}}, $ctx->{privatedir});
520 push(@{$ctx->{directories}}, $ctx->{binddnsdir});
521 push(@{$ctx->{directories}}, $ctx->{etcdir});
522 push(@{$ctx->{directories}}, $ctx->{piddir});
523 push(@{$ctx->{directories}}, $ctx->{lockdir});
524 push(@{$ctx->{directories}}, $ctx->{logdir});
525 push(@{$ctx->{directories}}, $ctx->{statedir});
526 push(@{$ctx->{directories}}, $ctx->{cachedir});
528 $ctx->{smb_conf_extra_options} = "";
530 my @provision_options = ();
531 push (@provision_options, "KRB5_CONFIG=\"$ctx->{krb5_conf}\"");
532 push (@provision_options, "KRB5_CCACHE=\"$ctx->{krb5_ccache}\"");
533 push (@provision_options, "NSS_WRAPPER_PASSWD=\"$ctx->{nsswrap_passwd}\"");
534 push (@provision_options, "NSS_WRAPPER_GROUP=\"$ctx->{nsswrap_group}\"");
535 push (@provision_options, "NSS_WRAPPER_HOSTS=\"$ctx->{nsswrap_hosts}\"");
536 push (@provision_options, "NSS_WRAPPER_HOSTNAME=\"$ctx->{nsswrap_hostname}\"");
537 if (defined($ctx->{use_resolv_wrapper})) {
538 push (@provision_options, "RESOLV_WRAPPER_CONF=\"$ctx->{resolv_conf}\"");
539 } else {
540 push (@provision_options, "RESOLV_WRAPPER_HOSTS=\"$ctx->{dns_host_file}\"");
542 if (defined($ENV{GDB_PROVISION})) {
543 push (@provision_options, "gdb --args");
544 if (!defined($ENV{PYTHON})) {
545 push (@provision_options, "env");
546 push (@provision_options, "python");
549 if (defined($ENV{VALGRIND_PROVISION})) {
550 push (@provision_options, "valgrind");
551 if (!defined($ENV{PYTHON})) {
552 push (@provision_options, "env");
553 push (@provision_options, "python");
556 if (defined($ENV{PYTHON})) {
557 push (@provision_options, $ENV{PYTHON});
559 push (@provision_options, Samba::bindir_path($self, "samba-tool"));
560 push (@provision_options, "domain");
561 push (@provision_options, "provision");
562 push (@provision_options, "--configfile=$ctx->{smb_conf}");
563 push (@provision_options, "--host-name=$ctx->{hostname}");
564 push (@provision_options, "--host-ip=$ctx->{ipv4}");
565 push (@provision_options, "--quiet");
566 push (@provision_options, "--domain=$ctx->{domain}");
567 push (@provision_options, "--realm=$ctx->{realm}");
568 if (defined($ctx->{samsid})) {
569 push (@provision_options, "--domain-sid=$ctx->{samsid}");
571 push (@provision_options, "--adminpass=$ctx->{password}");
572 push (@provision_options, "--krbtgtpass=krbtgt$ctx->{password}");
573 push (@provision_options, "--machinepass=machine$ctx->{password}");
574 push (@provision_options, "--root=$ctx->{unix_name}");
575 push (@provision_options, "--server-role=\"$ctx->{server_role}\"");
576 push (@provision_options, "--function-level=\"$ctx->{functional_level}\"");
578 @{$ctx->{provision_options}} = @provision_options;
580 return $ctx;
584 # Step1 creates the basic configuration
586 sub provision_raw_step1($$)
588 my ($self, $ctx) = @_;
590 mkdir($_, 0777) foreach (@{$ctx->{directories}});
593 ## lockdir and piddir must be 0755
595 chmod 0755, $ctx->{lockdir};
596 chmod 0755, $ctx->{piddir};
598 unless (open(CONFFILE, ">$ctx->{smb_conf}")) {
599 warn("can't open $ctx->{smb_conf}$?");
600 return undef;
603 Samba::prepare_keyblobs($ctx);
604 my $crlfile = "$ctx->{tlsdir}/crl.pem";
605 $crlfile = "" unless -e ${crlfile};
607 print CONFFILE "
608 [global]
609 netbios name = $ctx->{netbiosname}
610 posix:eadb = $ctx->{statedir}/eadb.tdb
611 workgroup = $ctx->{domain}
612 realm = $ctx->{realm}
613 private dir = $ctx->{privatedir}
614 binddns dir = $ctx->{binddnsdir}
615 pid directory = $ctx->{piddir}
616 ncalrpc dir = $ctx->{ncalrpcdir}
617 lock dir = $ctx->{lockdir}
618 state directory = $ctx->{statedir}
619 cache directory = $ctx->{cachedir}
620 winbindd socket directory = $ctx->{winbindd_socket_dir}
621 ntp signd socket directory = $ctx->{ntp_signd_socket_dir}
622 winbind separator = /
623 interfaces = $ctx->{interfaces}
624 tls dh params file = $ctx->{tlsdir}/dhparms.pem
625 tls crlfile = ${crlfile}
626 tls verify peer = no_check
627 panic action = $RealBin/gdb_backtrace \%d
628 wins support = yes
629 server role = $ctx->{server_role}
630 server services = +echo +smb -s3fs
631 dcerpc endpoint servers = +winreg +srvsvc
632 notify:inotify = false
633 ldb:nosync = true
634 ldap server require strong auth = yes
635 #We don't want to pass our self-tests if the PAC code is wrong
636 gensec:require_pac = true
637 log file = $ctx->{logdir}/log.\%m
638 log level = $ctx->{server_loglevel}
639 lanman auth = Yes
640 ntlm auth = Yes
641 rndc command = true
642 dns update command = $ctx->{samba_dnsupdate}
643 spn update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba_spnupdate -s $ctx->{smb_conf}
644 gpo update command = $ENV{SRCDIR_ABS}/source4/scripting/bin/samba-gpupdate -s $ctx->{smb_conf} --target=Computer
645 dreplsrv:periodic_startup_interval = 0
646 dsdb:schema update allowed = yes
648 prefork children = 4
650 vfs objects = dfs_samba4 acl_xattr fake_acls xattr_tdb streams_depot
652 idmap_ldb:use rfc2307=yes
653 winbind enum users = yes
654 winbind enum groups = yes
656 rpc server port:netlogon = 1026
660 print CONFFILE "
662 # Begin extra options
663 $ctx->{smb_conf_extra_options}
664 # End extra options
666 close(CONFFILE);
668 #Default the KDC IP to the server's IP
669 if (not defined($ctx->{kdc_ipv4})) {
670 $ctx->{kdc_ipv4} = $ctx->{ipv4};
672 if (not defined($ctx->{kdc_ipv6})) {
673 $ctx->{kdc_ipv6} = $ctx->{ipv6};
676 Samba::mk_krb5_conf($ctx);
677 Samba::mk_mitkdc_conf($ctx, abs_path(Samba::bindir_path($self, "shared")));
679 open(PWD, ">$ctx->{nsswrap_passwd}");
680 if ($ctx->{unix_uid} != 0) {
681 print PWD "root:x:0:0:root gecos:$ctx->{prefix_abs}:/bin/false\n";
683 print PWD "$ctx->{unix_name}:x:$ctx->{unix_uid}:65531:$ctx->{unix_name} gecos:$ctx->{prefix_abs}:/bin/false\n";
684 print PWD "nobody:x:65534:65533:nobody gecos:$ctx->{prefix_abs}:/bin/false
685 pdbtest:x:65533:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
686 pdbtest2:x:65532:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
687 pdbtest3:x:65531:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
688 pdbtest4:x:65530:65533:pdbtest gecos:$ctx->{prefix_abs}:/bin/false
690 close(PWD);
691 my $uid_rfc2307test = 65533;
693 open(GRP, ">$ctx->{nsswrap_group}");
694 if ($ctx->{unix_gid} != 0) {
695 print GRP "root:x:0:\n";
697 print GRP "$ctx->{unix_name}:x:$ctx->{unix_gid}:\n";
698 print GRP "wheel:x:10:
699 users:x:65531:
700 nobody:x:65533:
701 nogroup:x:65534:nobody
703 close(GRP);
704 my $gid_rfc2307test = 65532;
706 my $hostname = lc($ctx->{hostname});
707 open(HOSTS, ">>$ctx->{nsswrap_hosts}");
708 if ($hostname eq "localdc") {
709 print HOSTS "$ctx->{ipv4} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n";
710 print HOSTS "$ctx->{ipv6} ${hostname}.$ctx->{dnsname} $ctx->{dnsname} ${hostname}\n";
711 } else {
712 print HOSTS "$ctx->{ipv4} ${hostname}.$ctx->{dnsname} ${hostname}\n";
713 print HOSTS "$ctx->{ipv6} ${hostname}.$ctx->{dnsname} ${hostname}\n";
715 close(HOSTS);
717 if (defined($ctx->{resolv_conf})) {
718 open(RESOLV_CONF, ">$ctx->{resolv_conf}");
719 print RESOLV_CONF "nameserver $ctx->{kdc_ipv4}\n";
720 print RESOLV_CONF "nameserver $ctx->{kdc_ipv6}\n";
721 close(RESOLV_CONF);
724 my $configuration = "--configfile=$ctx->{smb_conf}";
726 #Ensure the config file is valid before we start
727 my $testparm = Samba::bindir_path($self, "samba-tool") . " testparm";
728 if (system("$testparm $configuration -v --suppress-prompt >/dev/null 2>&1") != 0) {
729 system("$testparm -v --suppress-prompt $configuration >&2");
730 warn("Failed to create a valid smb.conf configuration $testparm!");
731 return undef;
733 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) {
734 warn("Failed to create a valid smb.conf configuration! $testparm $configuration -v --suppress-prompt --parameter-name=\"netbios name\" --section-name=global");
735 return undef;
738 my $ret = {
739 KRB5_CONFIG => $ctx->{krb5_conf},
740 KRB5_CCACHE => $ctx->{krb5_ccache},
741 MITKDC_CONFIG => $ctx->{mitkdc_conf},
742 PIDDIR => $ctx->{piddir},
743 SERVER => $ctx->{hostname},
744 SERVER_IP => $ctx->{ipv4},
745 SERVER_IPV6 => $ctx->{ipv6},
746 NETBIOSNAME => $ctx->{netbiosname},
747 DOMAIN => $ctx->{domain},
748 USERNAME => $ctx->{username},
749 REALM => $ctx->{realm},
750 DNSNAME => $ctx->{dnsname},
751 SAMSID => $ctx->{samsid},
752 PASSWORD => $ctx->{password},
753 LDAPDIR => $ctx->{ldapdir},
754 LDAP_INSTANCE => $ctx->{ldap_instance},
755 SELFTEST_WINBINDD_SOCKET_DIR => $ctx->{winbindd_socket_dir},
756 NCALRPCDIR => $ctx->{ncalrpcdir},
757 LOCKDIR => $ctx->{lockdir},
758 STATEDIR => $ctx->{statedir},
759 CACHEDIR => $ctx->{cachedir},
760 PRIVATEDIR => $ctx->{privatedir},
761 BINDDNSDIR => $ctx->{binddnsdir},
762 SERVERCONFFILE => $ctx->{smb_conf},
763 CONFIGURATION => $configuration,
764 SOCKET_WRAPPER_DEFAULT_IFACE => $ctx->{swiface},
765 NSS_WRAPPER_PASSWD => $ctx->{nsswrap_passwd},
766 NSS_WRAPPER_GROUP => $ctx->{nsswrap_group},
767 NSS_WRAPPER_HOSTS => $ctx->{nsswrap_hosts},
768 NSS_WRAPPER_HOSTNAME => $ctx->{nsswrap_hostname},
769 SAMBA_TEST_FIFO => "$ctx->{prefix}/samba_test.fifo",
770 SAMBA_TEST_LOG => "$ctx->{prefix}/samba_test.log",
771 SAMBA_TEST_LOG_POS => 0,
772 NSS_WRAPPER_MODULE_SO_PATH => Samba::nss_wrapper_winbind_so_path($self),
773 NSS_WRAPPER_MODULE_FN_PREFIX => "winbind",
774 LOCAL_PATH => $ctx->{share},
775 UID_RFC2307TEST => $uid_rfc2307test,
776 GID_RFC2307TEST => $gid_rfc2307test,
777 SERVER_ROLE => $ctx->{server_role},
778 RESOLV_CONF => $ctx->{resolv_conf}
781 if (defined($ctx->{use_resolv_wrapper})) {
782 $ret->{RESOLV_WRAPPER_CONF} = $ctx->{resolv_conf};
783 } else {
784 $ret->{RESOLV_WRAPPER_HOSTS} = $ctx->{dns_host_file};
787 if ($ctx->{server_role} eq "domain controller") {
788 $ret->{DOMSID} = $ret->{SAMSID};
791 return $ret;
795 # Step2 runs the provision script
797 sub provision_raw_step2($$$)
799 my ($self, $ctx, $ret) = @_;
801 my $provision_cmd = join(" ", @{$ctx->{provision_options}});
802 unless (system($provision_cmd) == 0) {
803 warn("Unable to provision: \n$provision_cmd\n");
804 return undef;
807 my $testallowed_account = "testallowed";
808 my $samba_tool_cmd = "";
809 $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
810 $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
811 $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
812 . " user create --configfile=$ctx->{smb_conf} $testallowed_account $ctx->{password}";
813 unless (system($samba_tool_cmd) == 0) {
814 warn("Unable to add testallowed user: \n$samba_tool_cmd\n");
815 return undef;
818 my $ldbmodify = "";
819 $ldbmodify .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
820 $ldbmodify .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
821 $ldbmodify .= Samba::bindir_path($self, "ldbmodify");
822 my $base_dn = "DC=".join(",DC=", split(/\./, $ctx->{realm}));
824 if ($ctx->{server_role} ne "domain controller") {
825 $base_dn = "DC=$ctx->{netbiosname}";
828 my $user_dn = "cn=$testallowed_account,cn=users,$base_dn";
829 $testallowed_account = "testallowed account";
830 open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
831 print LDIF "dn: $user_dn
832 changetype: modify
833 replace: samAccountName
834 samAccountName: $testallowed_account
837 close(LDIF);
839 open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
840 print LDIF "dn: $user_dn
841 changetype: modify
842 replace: userPrincipalName
843 userPrincipalName: testallowed upn\@$ctx->{realm}
844 replace: servicePrincipalName
845 servicePrincipalName: host/testallowed
848 close(LDIF);
850 $samba_tool_cmd = "";
851 $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
852 $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
853 $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
854 . " user create --configfile=$ctx->{smb_conf} testdenied $ctx->{password}";
855 unless (system($samba_tool_cmd) == 0) {
856 warn("Unable to add testdenied user: \n$samba_tool_cmd\n");
857 return undef;
860 my $user_dn = "cn=testdenied,cn=users,$base_dn";
861 open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
862 print LDIF "dn: $user_dn
863 changetype: modify
864 replace: userPrincipalName
865 userPrincipalName: testdenied_upn\@$ctx->{realm}.upn
868 close(LDIF);
870 $samba_tool_cmd = "";
871 $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
872 $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
873 $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
874 . " user create --configfile=$ctx->{smb_conf} testupnspn $ctx->{password}";
875 unless (system($samba_tool_cmd) == 0) {
876 warn("Unable to add testupnspn user: \n$samba_tool_cmd\n");
877 return undef;
880 my $user_dn = "cn=testupnspn,cn=users,$base_dn";
881 open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
882 print LDIF "dn: $user_dn
883 changetype: modify
884 replace: userPrincipalName
885 userPrincipalName: http/testupnspn.$ctx->{dnsname}\@$ctx->{realm}
886 replace: servicePrincipalName
887 servicePrincipalName: http/testupnspn.$ctx->{dnsname}
890 close(LDIF);
892 $samba_tool_cmd = "";
893 $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
894 $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
895 $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
896 . " group addmembers --configfile=$ctx->{smb_conf} 'Allowed RODC Password Replication Group' '$testallowed_account'";
897 unless (system($samba_tool_cmd) == 0) {
898 warn("Unable to add '$testallowed_account' user to 'Allowed RODC Password Replication Group': \n$samba_tool_cmd\n");
899 return undef;
902 # Create to users alice and bob!
903 my $user_account_array = ["alice", "bob", "jane"];
905 foreach my $user_account (@{$user_account_array}) {
906 my $samba_tool_cmd = "";
908 $samba_tool_cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
909 $samba_tool_cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
910 $samba_tool_cmd .= Samba::bindir_path($self, "samba-tool")
911 . " user create --configfile=$ctx->{smb_conf} $user_account Secret007";
912 unless (system($samba_tool_cmd) == 0) {
913 warn("Unable to create user: $user_account\n$samba_tool_cmd\n");
914 return undef;
918 my $ldbmodify = "";
919 $ldbmodify .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
920 $ldbmodify .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
921 $ldbmodify .= Samba::bindir_path($self, "ldbmodify");
923 my $base_dn = "DC=".join(",DC=", split(/\./, $ctx->{realm}));
924 my $user_dn = "cn=jane,cn=users,$base_dn";
926 open(LDIF, "|$ldbmodify -H $ctx->{privatedir}/sam.ldb");
927 print LDIF "dn: $user_dn
928 changetype: modify
929 replace: userPrincipalName
930 userPrincipalName: jane.doe\@$ctx->{realm}
933 close(LDIF);
935 return $ret;
938 sub provision($$$$$$$$$$)
940 my ($self, $prefix, $server_role, $hostname,
941 $domain, $realm, $functional_level,
942 $password, $kdc_ipv4, $kdc_ipv6, $extra_smbconf_options, $extra_smbconf_shares,
943 $extra_provision_options) = @_;
945 my $samsid = Samba::random_domain_sid();
947 my $ctx = $self->provision_raw_prepare($prefix, $server_role,
948 $hostname,
949 $domain, $realm,
950 $samsid,
951 $functional_level,
952 $password, $kdc_ipv4, $kdc_ipv6);
954 if (defined($extra_provision_options)) {
955 push (@{$ctx->{provision_options}}, @{$extra_provision_options});
956 } else {
957 push (@{$ctx->{provision_options}}, "--use-ntvfs");
960 $ctx->{share} = "$ctx->{prefix_abs}/share";
961 push(@{$ctx->{directories}}, "$ctx->{share}");
962 push(@{$ctx->{directories}}, "$ctx->{share}/test1");
963 push(@{$ctx->{directories}}, "$ctx->{share}/test2");
965 # precreate directories for printer drivers
966 push(@{$ctx->{directories}}, "$ctx->{share}/W32X86");
967 push(@{$ctx->{directories}}, "$ctx->{share}/x64");
968 push(@{$ctx->{directories}}, "$ctx->{share}/WIN40");
970 my $msdfs = "no";
971 $msdfs = "yes" if ($server_role eq "domain controller");
972 $ctx->{smb_conf_extra_options} = "
974 max xmit = 32K
975 server max protocol = SMB2
976 host msdfs = $msdfs
977 lanman auth = yes
979 # fruit:copyfile is a global option
980 fruit:copyfile = yes
982 $extra_smbconf_options
984 [tmp]
985 path = $ctx->{share}
986 read only = no
987 posix:sharedelay = 100000
988 posix:oplocktimeout = 3
989 posix:writetimeupdatedelay = 500000
991 [xcopy_share]
992 path = $ctx->{share}
993 read only = no
994 posix:sharedelay = 100000
995 posix:oplocktimeout = 3
996 posix:writetimeupdatedelay = 500000
997 create mask = 777
998 force create mode = 777
1000 [posix_share]
1001 path = $ctx->{share}
1002 read only = no
1003 create mask = 0777
1004 force create mode = 0
1005 directory mask = 0777
1006 force directory mode = 0
1008 [test1]
1009 path = $ctx->{share}/test1
1010 read only = no
1011 posix:sharedelay = 100000
1012 posix:oplocktimeout = 3
1013 posix:writetimeupdatedelay = 500000
1015 [test2]
1016 path = $ctx->{share}/test2
1017 read only = no
1018 posix:sharedelay = 100000
1019 posix:oplocktimeout = 3
1020 posix:writetimeupdatedelay = 500000
1022 [cifs]
1023 path = $ctx->{share}/_ignore_cifs_
1024 read only = no
1025 ntvfs handler = cifs
1026 cifs:server = $ctx->{netbiosname}
1027 cifs:share = tmp
1028 cifs:use-s4u2proxy = yes
1029 # There is no username specified here, instead the client is expected
1030 # to log in with kerberos, and the serverwill use delegated credentials.
1031 # Or the server tries s4u2self/s4u2proxy to impersonate the client
1033 [simple]
1034 path = $ctx->{share}
1035 read only = no
1036 ntvfs handler = simple
1038 [sysvol]
1039 path = $ctx->{statedir}/sysvol
1040 read only = no
1042 [netlogon]
1043 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1044 read only = no
1046 [cifsposix]
1047 copy = simple
1048 ntvfs handler = cifsposix
1050 [vfs_fruit]
1051 path = $ctx->{share}
1052 vfs objects = catia fruit streams_xattr acl_xattr
1053 ea support = yes
1054 fruit:resource = file
1055 fruit:metadata = netatalk
1056 fruit:locking = netatalk
1057 fruit:encoding = native
1059 $extra_smbconf_shares
1062 if (defined($self->{ldap})) {
1063 $ctx->{ldapdir} = "$ctx->{privatedir}/ldap";
1064 push(@{$ctx->{directories}}, "$ctx->{ldapdir}");
1066 my $ldap_uri= "$ctx->{ldapdir}/ldapi";
1067 $ldap_uri =~ s|/|%2F|g;
1068 $ldap_uri = "ldapi://$ldap_uri";
1069 $ctx->{ldap_uri} = $ldap_uri;
1071 $ctx->{ldap_instance} = lc($ctx->{netbiosname});
1074 my $ret = $self->provision_raw_step1($ctx);
1075 unless (defined $ret) {
1076 return undef;
1079 if (defined($self->{ldap})) {
1080 $ret->{LDAP_URI} = $ctx->{ldap_uri};
1081 push (@{$ctx->{provision_options}}, "--ldap-backend-type=" . $self->{ldap});
1082 push (@{$ctx->{provision_options}}, "--ldap-backend-nosync");
1083 if ($self->{ldap} eq "openldap") {
1084 push (@{$ctx->{provision_options}}, "--slapd-path=" . $ENV{OPENLDAP_SLAPD});
1085 ($ret->{SLAPD_CONF_D}, $ret->{OPENLDAP_PIDFILE}) = $self->mk_openldap($ctx) or die("Unable to create openldap directories");
1087 } elsif ($self->{ldap} eq "fedora-ds") {
1088 push (@{$ctx->{provision_options}}, "--slapd-path=" . "$ENV{FEDORA_DS_ROOT}/sbin/ns-slapd");
1089 push (@{$ctx->{provision_options}}, "--setup-ds-path=" . "$ENV{FEDORA_DS_ROOT}/sbin/setup-ds.pl");
1090 ($ret->{FEDORA_DS_DIR}, $ret->{FEDORA_DS_PIDFILE}) = $self->mk_fedora_ds($ctx) or die("Unable to create fedora ds directories");
1095 return $self->provision_raw_step2($ctx, $ret);
1098 sub provision_s4member($$$$$)
1100 my ($self, $prefix, $dcvars, $hostname, $more_conf) = @_;
1101 print "PROVISIONING MEMBER...\n";
1102 my $extra_smb_conf = "
1103 passdb backend = samba_dsdb
1104 winbindd:use external pipes = true
1106 # the source4 smb server doesn't allow signing by default
1107 server signing = enabled
1108 raw NTLMv2 auth = yes
1110 rpc_server:default = external
1111 rpc_server:svcctl = embedded
1112 rpc_server:srvsvc = embedded
1113 rpc_server:eventlog = embedded
1114 rpc_server:ntsvcs = embedded
1115 rpc_server:winreg = embedded
1116 rpc_server:spoolss = embedded
1117 rpc_daemon:spoolssd = embedded
1118 rpc_server:tcpip = no
1120 if ($more_conf) {
1121 $extra_smb_conf = $extra_smb_conf . $more_conf . "\n";
1123 my $ret = $self->provision($prefix,
1124 "member server",
1125 $hostname,
1126 $dcvars->{DOMAIN},
1127 $dcvars->{REALM},
1128 "2008",
1129 "locMEMpass3",
1130 $dcvars->{SERVER_IP},
1131 $dcvars->{SERVER_IPV6},
1132 $extra_smb_conf, "", undef);
1133 unless ($ret) {
1134 return undef;
1137 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1138 my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1139 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1140 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1141 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1142 } else {
1143 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1145 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1146 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1147 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} member";
1148 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1149 $cmd .= " --machinepass=machine$ret->{PASSWORD}";
1151 unless (system($cmd) == 0) {
1152 warn("Join failed\n$cmd");
1153 return undef;
1156 $ret->{MEMBER_SERVER} = $ret->{SERVER};
1157 $ret->{MEMBER_SERVER_IP} = $ret->{SERVER_IP};
1158 $ret->{MEMBER_SERVER_IPV6} = $ret->{SERVER_IPV6};
1159 $ret->{MEMBER_NETBIOSNAME} = $ret->{NETBIOSNAME};
1160 $ret->{MEMBER_USERNAME} = $ret->{USERNAME};
1161 $ret->{MEMBER_PASSWORD} = $ret->{PASSWORD};
1163 $ret->{DOMSID} = $dcvars->{DOMSID};
1164 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1165 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1166 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1167 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1168 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1169 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1171 return $ret;
1174 sub provision_rpc_proxy($$$)
1176 my ($self, $prefix, $dcvars) = @_;
1177 print "PROVISIONING RPC PROXY...\n";
1179 my $extra_smbconf_options = "
1180 passdb backend = samba_dsdb
1182 # rpc_proxy
1183 dcerpc_remote:binding = ncacn_ip_tcp:$dcvars->{SERVER}
1184 dcerpc endpoint servers = epmapper, remote
1185 dcerpc_remote:interfaces = rpcecho
1187 [cifs_to_dc]
1188 path = /tmp/_ignore_cifs_to_dc_/_none_
1189 read only = no
1190 ntvfs handler = cifs
1191 cifs:server = $dcvars->{SERVER}
1192 cifs:share = cifs
1193 cifs:use-s4u2proxy = yes
1194 # There is no username specified here, instead the client is expected
1195 # to log in with kerberos, and the serverwill use delegated credentials.
1196 # Or the server tries s4u2self/s4u2proxy to impersonate the client
1200 my $ret = $self->provision($prefix,
1201 "member server",
1202 "localrpcproxy",
1203 $dcvars->{DOMAIN},
1204 $dcvars->{REALM},
1205 "2008",
1206 "locRPCproxypass4",
1207 $dcvars->{SERVER_IP},
1208 $dcvars->{SERVER_IPV6},
1209 $extra_smbconf_options, "", undef);
1210 unless ($ret) {
1211 return undef;
1214 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1216 # The joind runs in the context of the rpc_proxy/member for now
1217 my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1218 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1219 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1220 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1221 } else {
1222 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1224 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1225 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1226 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} member";
1227 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1228 $cmd .= " --machinepass=machine$ret->{PASSWORD}";
1230 unless (system($cmd) == 0) {
1231 warn("Join failed\n$cmd");
1232 return undef;
1235 # Setting up delegation runs in the context of the DC for now
1236 $cmd = "";
1237 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1238 $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
1239 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1240 $cmd .= "$samba_tool delegation for-any-protocol '$ret->{NETBIOSNAME}\$' on";
1241 $cmd .= " $dcvars->{CONFIGURATION}";
1242 print $cmd;
1244 unless (system($cmd) == 0) {
1245 warn("Delegation failed\n$cmd");
1246 return undef;
1249 # Setting up delegation runs in the context of the DC for now
1250 $cmd = "";
1251 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$dcvars->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1252 $cmd .= "KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
1253 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1254 $cmd .= "$samba_tool delegation add-service '$ret->{NETBIOSNAME}\$' cifs/$dcvars->{SERVER}";
1255 $cmd .= " $dcvars->{CONFIGURATION}";
1257 unless (system($cmd) == 0) {
1258 warn("Delegation failed\n$cmd");
1259 return undef;
1262 $ret->{RPC_PROXY_SERVER} = $ret->{SERVER};
1263 $ret->{RPC_PROXY_SERVER_IP} = $ret->{SERVER_IP};
1264 $ret->{RPC_PROXY_SERVER_IPV6} = $ret->{SERVER_IPV6};
1265 $ret->{RPC_PROXY_NETBIOSNAME} = $ret->{NETBIOSNAME};
1266 $ret->{RPC_PROXY_USERNAME} = $ret->{USERNAME};
1267 $ret->{RPC_PROXY_PASSWORD} = $ret->{PASSWORD};
1269 $ret->{DOMSID} = $dcvars->{DOMSID};
1270 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1271 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1272 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1273 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1274 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1275 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1277 return $ret;
1280 sub provision_promoted_dc($$$)
1282 my ($self, $prefix, $dcvars) = @_;
1283 print "PROVISIONING PROMOTED DC...\n";
1285 # We do this so that we don't run the provision. That's the job of 'samba-tool domain dcpromo'.
1286 my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1287 "promotedvdc",
1288 $dcvars->{DOMAIN},
1289 $dcvars->{REALM},
1290 $dcvars->{SAMSID},
1291 "2008",
1292 $dcvars->{PASSWORD},
1293 $dcvars->{SERVER_IP},
1294 $dcvars->{SERVER_IPV6});
1296 push (@{$ctx->{provision_options}}, "--use-ntvfs");
1298 $ctx->{smb_conf_extra_options} = "
1299 max xmit = 32K
1300 server max protocol = SMB2
1302 ntlm auth = ntlmv2-only
1304 [sysvol]
1305 path = $ctx->{statedir}/sysvol
1306 read only = yes
1308 [netlogon]
1309 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1310 read only = no
1314 my $ret = $self->provision_raw_step1($ctx);
1315 unless ($ret) {
1316 return undef;
1319 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1320 my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1321 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1322 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1323 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1324 } else {
1325 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1327 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1328 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1329 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} MEMBER --realm=$dcvars->{REALM}";
1330 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1331 $cmd .= " --machinepass=machine$ret->{PASSWORD}";
1333 unless (system($cmd) == 0) {
1334 warn("Join failed\n$cmd");
1335 return undef;
1338 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1339 my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1340 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1341 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1342 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1343 } else {
1344 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1346 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1347 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1348 $cmd .= "$samba_tool domain dcpromo $ret->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
1349 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1350 $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs --dns-backend=BIND9_DLZ";
1352 unless (system($cmd) == 0) {
1353 warn("Join failed\n$cmd");
1354 return undef;
1357 $ret->{PROMOTED_DC_SERVER} = $ret->{SERVER};
1358 $ret->{PROMOTED_DC_SERVER_IP} = $ret->{SERVER_IP};
1359 $ret->{PROMOTED_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1360 $ret->{PROMOTED_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1362 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1363 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1364 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1365 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1366 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1367 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1369 return $ret;
1372 sub provision_vampire_dc($$$)
1374 my ($self, $prefix, $dcvars, $fl) = @_;
1375 print "PROVISIONING VAMPIRE DC @ FL $fl...\n";
1376 my $name = "localvampiredc";
1377 my $extra_conf = "";
1379 if ($fl == "2000") {
1380 $name = "vampire2000dc";
1381 } else {
1382 $extra_conf = "drs: immediate link sync = yes
1383 drs: max link sync = 250";
1386 # We do this so that we don't run the provision. That's the job of 'net vampire'.
1387 my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1388 $name,
1389 $dcvars->{DOMAIN},
1390 $dcvars->{REALM},
1391 $dcvars->{DOMSID},
1392 $fl,
1393 $dcvars->{PASSWORD},
1394 $dcvars->{SERVER_IP},
1395 $dcvars->{SERVER_IPV6});
1397 push (@{$ctx->{provision_options}}, "--use-ntvfs");
1399 $ctx->{smb_conf_extra_options} = "
1400 max xmit = 32K
1401 server max protocol = SMB2
1403 ntlm auth = mschapv2-and-ntlmv2-only
1404 $extra_conf
1406 [sysvol]
1407 path = $ctx->{statedir}/sysvol
1408 read only = yes
1410 [netlogon]
1411 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1412 read only = no
1416 my $ret = $self->provision_raw_step1($ctx);
1417 unless ($ret) {
1418 return undef;
1421 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1422 my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1423 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1424 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1425 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1426 } else {
1427 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1429 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1430 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1431 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} DC --realm=$dcvars->{REALM}";
1432 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD} --domain-critical-only";
1433 $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs";
1434 $cmd .= " --backend-store=mdb";
1436 unless (system($cmd) == 0) {
1437 warn("Join failed\n$cmd");
1438 return undef;
1441 if ($fl == "2000") {
1442 $ret->{VAMPIRE_2000_DC_SERVER} = $ret->{SERVER};
1443 $ret->{VAMPIRE_2000_DC_SERVER_IP} = $ret->{SERVER_IP};
1444 $ret->{VAMPIRE_2000_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1445 $ret->{VAMPIRE_2000_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1446 } else {
1447 $ret->{VAMPIRE_DC_SERVER} = $ret->{SERVER};
1448 $ret->{VAMPIRE_DC_SERVER_IP} = $ret->{SERVER_IP};
1449 $ret->{VAMPIRE_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1450 $ret->{VAMPIRE_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1452 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1453 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1454 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1455 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1456 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1457 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1458 $ret->{DC_REALM} = $dcvars->{DC_REALM};
1460 return $ret;
1463 sub provision_subdom_dc($$$)
1465 my ($self, $prefix, $dcvars) = @_;
1466 print "PROVISIONING SUBDOMAIN DC...\n";
1468 # We do this so that we don't run the provision. That's the job of 'net vampire'.
1469 my $samsid = undef; # TODO pass the domain sid all the way down
1470 my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1471 "localsubdc",
1472 "SAMBASUBDOM",
1473 "sub.samba.example.com",
1474 $samsid,
1475 "2008",
1476 $dcvars->{PASSWORD},
1477 undef);
1479 push (@{$ctx->{provision_options}}, "--use-ntvfs");
1481 $ctx->{smb_conf_extra_options} = "
1482 max xmit = 32K
1483 server max protocol = SMB2
1485 [sysvol]
1486 path = $ctx->{statedir}/sysvol
1487 read only = yes
1489 [netlogon]
1490 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1491 read only = no
1495 my $ret = $self->provision_raw_step1($ctx);
1496 unless ($ret) {
1497 return undef;
1500 Samba::mk_krb5_conf($ctx);
1501 Samba::mk_mitkdc_conf($ctx, abs_path(Samba::bindir_path($self, "shared")));
1503 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1504 my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1505 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1506 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1507 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1508 } else {
1509 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1511 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1512 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1513 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $ctx->{dnsname} subdomain ";
1514 $cmd .= "--parent-domain=$dcvars->{REALM} -U$dcvars->{DC_USERNAME}\@$dcvars->{REALM}\%$dcvars->{DC_PASSWORD}";
1515 $cmd .= " --machinepass=machine$ret->{PASSWORD} --use-ntvfs";
1516 $cmd .= " --adminpass=$ret->{PASSWORD}";
1518 unless (system($cmd) == 0) {
1519 warn("Join failed\n$cmd");
1520 return undef;
1523 $ret->{SUBDOM_DC_SERVER} = $ret->{SERVER};
1524 $ret->{SUBDOM_DC_SERVER_IP} = $ret->{SERVER_IP};
1525 $ret->{SUBDOM_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1526 $ret->{SUBDOM_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1528 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1529 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1530 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1531 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1532 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1533 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1535 return $ret;
1538 sub provision_ad_dc_ntvfs($$)
1540 my ($self, $prefix) = @_;
1542 # We keep the old 'winbind' name here in server services to
1543 # ensure upgrades which used that name still work with the now
1544 # alias.
1546 print "PROVISIONING AD DC (NTVFS)...\n";
1547 my $extra_conf_options = "netbios aliases = localDC1-a
1548 server services = +winbind -winbindd
1549 ldap server require strong auth = allow_sasl_over_tls
1550 allow nt4 crypto = yes
1551 raw NTLMv2 auth = yes
1552 lsa over netlogon = yes
1553 rpc server port = 1027
1554 auth event notification = true
1555 dsdb event notification = true
1556 dsdb password event notification = true
1557 dsdb group change notification = true
1558 server schannel = auto
1560 my $ret = $self->provision($prefix,
1561 "domain controller",
1562 "localdc",
1563 "SAMBADOMAIN",
1564 "samba.example.com",
1565 "2008",
1566 "locDCpass1",
1567 undef,
1568 undef,
1569 $extra_conf_options,
1571 undef);
1572 unless ($ret) {
1573 return undef;
1576 unless($self->add_wins_config("$prefix/private")) {
1577 warn("Unable to add wins configuration");
1578 return undef;
1580 $ret->{NETBIOSALIAS} = "localdc1-a";
1581 $ret->{DC_SERVER} = $ret->{SERVER};
1582 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1583 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1584 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1585 $ret->{DC_USERNAME} = $ret->{USERNAME};
1586 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1587 $ret->{DC_REALM} = $ret->{REALM};
1589 return $ret;
1592 sub provision_fl2000dc($$)
1594 my ($self, $prefix) = @_;
1596 print "PROVISIONING DC WITH FOREST LEVEL 2000...\n";
1597 my $extra_conf_options = "
1598 spnego:simulate_w2k=yes
1599 ntlmssp_server:force_old_spnego=yes
1601 my $extra_provision_options = undef;
1602 # This environment uses plain text secrets
1603 # i.e. secret attributes are not encrypted on disk.
1604 # This allows testing of the --plaintext-secrets option for
1605 # provision
1606 push (@{$extra_provision_options}, "--plaintext-secrets");
1607 my $ret = $self->provision($prefix,
1608 "domain controller",
1609 "dc5",
1610 "SAMBA2000",
1611 "samba2000.example.com",
1612 "2000",
1613 "locDCpass5",
1614 undef,
1615 undef,
1616 $extra_conf_options,
1618 $extra_provision_options);
1619 unless ($ret) {
1620 return undef;
1623 unless($self->add_wins_config("$prefix/private")) {
1624 warn("Unable to add wins configuration");
1625 return undef;
1627 $ret->{DC_SERVER} = $ret->{SERVER};
1628 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1629 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1630 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1631 $ret->{DC_USERNAME} = $ret->{USERNAME};
1632 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1633 $ret->{DC_REALM} = $ret->{REALM};
1635 return $ret;
1638 sub provision_fl2003dc($$$)
1640 my ($self, $prefix, $dcvars) = @_;
1641 my $swiface1 = Samba::get_interface("fakednsforwarder1");
1642 my $swiface2 = Samba::get_interface("fakednsforwarder2");
1644 print "PROVISIONING DC WITH FOREST LEVEL 2003...\n";
1645 my $extra_conf_options = "allow dns updates = nonsecure and secure
1646 dcesrv:header signing = no
1647 dns forwarder = 127.0.0.$swiface1 127.0.0.$swiface2";
1648 my $ret = $self->provision($prefix,
1649 "domain controller",
1650 "dc6",
1651 "SAMBA2003",
1652 "samba2003.example.com",
1653 "2003",
1654 "locDCpass6",
1655 undef,
1656 undef,
1657 $extra_conf_options,
1659 undef);
1660 unless (defined $ret) {
1661 return undef;
1664 $ret->{DC_SERVER} = $ret->{SERVER};
1665 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1666 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1667 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1668 $ret->{DC_USERNAME} = $ret->{USERNAME};
1669 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1670 $ret->{DNS_FORWARDER1} = "127.0.0.$swiface1";
1671 $ret->{DNS_FORWARDER2} = "127.0.0.$swiface2";
1673 my @samba_tool_options;
1674 push (@samba_tool_options, Samba::bindir_path($self, "samba-tool"));
1675 push (@samba_tool_options, "domain");
1676 push (@samba_tool_options, "passwordsettings");
1677 push (@samba_tool_options, "set");
1678 push (@samba_tool_options, "--configfile=$ret->{SERVERCONFFILE}");
1679 push (@samba_tool_options, "--min-pwd-age=0");
1680 push (@samba_tool_options, "--history-length=1");
1682 my $samba_tool_cmd = join(" ", @samba_tool_options);
1684 unless (system($samba_tool_cmd) == 0) {
1685 warn("Unable to set min password age to 0: \n$samba_tool_cmd\n");
1686 return undef;
1689 unless($self->add_wins_config("$prefix/private")) {
1690 warn("Unable to add wins configuration");
1691 return undef;
1694 return $ret;
1697 sub provision_fl2008r2dc($$$)
1699 my ($self, $prefix, $dcvars) = @_;
1701 print "PROVISIONING DC WITH FOREST LEVEL 2008r2...\n";
1702 my $extra_conf_options = "ldap server require strong auth = no";
1703 my $ret = $self->provision($prefix,
1704 "domain controller",
1705 "dc7",
1706 "SAMBA2008R2",
1707 "samba2008R2.example.com",
1708 "2008_R2",
1709 "locDCpass7",
1710 undef,
1711 undef,
1712 $extra_conf_options,
1714 undef);
1715 unless (defined $ret) {
1716 return undef;
1719 unless ($self->add_wins_config("$prefix/private")) {
1720 warn("Unable to add wins configuration");
1721 return undef;
1723 $ret->{DC_SERVER} = $ret->{SERVER};
1724 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
1725 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1726 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1727 $ret->{DC_USERNAME} = $ret->{USERNAME};
1728 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
1729 $ret->{DC_REALM} = $ret->{REALM};
1731 return $ret;
1735 sub provision_rodc($$$)
1737 my ($self, $prefix, $dcvars) = @_;
1738 print "PROVISIONING RODC...\n";
1740 # We do this so that we don't run the provision. That's the job of 'net join RODC'.
1741 my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
1742 "rodc",
1743 $dcvars->{DOMAIN},
1744 $dcvars->{REALM},
1745 $dcvars->{DOMSID},
1746 "2008",
1747 $dcvars->{PASSWORD},
1748 $dcvars->{SERVER_IP},
1749 $dcvars->{SERVER_IPV6});
1750 unless ($ctx) {
1751 return undef;
1754 push (@{$ctx->{provision_options}}, "--use-ntvfs");
1756 $ctx->{share} = "$ctx->{prefix_abs}/share";
1757 push(@{$ctx->{directories}}, "$ctx->{share}");
1759 $ctx->{smb_conf_extra_options} = "
1760 max xmit = 32K
1761 server max protocol = SMB2
1762 password server = $dcvars->{DC_SERVER}
1764 [sysvol]
1765 path = $ctx->{statedir}/sysvol
1766 read only = yes
1768 [netlogon]
1769 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
1770 read only = yes
1772 [tmp]
1773 path = $ctx->{share}
1774 read only = no
1775 posix:sharedelay = 10000
1776 posix:oplocktimeout = 3
1777 posix:writetimeupdatedelay = 50000
1781 my $ret = $self->provision_raw_step1($ctx);
1782 unless ($ret) {
1783 return undef;
1786 my $samba_tool = Samba::bindir_path($self, "samba-tool");
1787 my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1788 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1789 if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1790 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1791 } else {
1792 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1794 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1795 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1796 $cmd .= "$samba_tool domain join $ret->{CONFIGURATION} $dcvars->{REALM} RODC";
1797 $cmd .= " -U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
1798 $cmd .= " --server=$dcvars->{DC_SERVER} --use-ntvfs";
1800 unless (system($cmd) == 0) {
1801 warn("RODC join failed\n$cmd");
1802 return undef;
1805 # This ensures deterministic behaviour for tests that want to have the 'testallowed account'
1806 # user password verified on the RODC
1807 my $testallowed_account = "testallowed account";
1808 $cmd = "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1809 $cmd .= "KRB5CCNAME=\"$ret->{KRB5_CCACHE}\" ";
1810 $cmd .= "$samba_tool rodc preload '$testallowed_account' $ret->{CONFIGURATION}";
1811 $cmd .= " --server=$dcvars->{DC_SERVER}";
1813 unless (system($cmd) == 0) {
1814 warn("RODC join failed\n$cmd");
1815 return undef;
1818 # we overwrite the kdc after the RODC join
1819 # so that use the RODC as kdc and test
1820 # the proxy code
1821 $ctx->{kdc_ipv4} = $ret->{SERVER_IP};
1822 $ctx->{kdc_ipv6} = $ret->{SERVER_IPV6};
1823 Samba::mk_krb5_conf($ctx);
1824 Samba::mk_mitkdc_conf($ctx, abs_path(Samba::bindir_path($self, "shared")));
1826 $ret->{RODC_DC_SERVER} = $ret->{SERVER};
1827 $ret->{RODC_DC_SERVER_IP} = $ret->{SERVER_IP};
1828 $ret->{RODC_DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
1829 $ret->{RODC_DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
1831 $ret->{DC_SERVER} = $dcvars->{DC_SERVER};
1832 $ret->{DC_SERVER_IP} = $dcvars->{DC_SERVER_IP};
1833 $ret->{DC_SERVER_IPV6} = $dcvars->{DC_SERVER_IPV6};
1834 $ret->{DC_NETBIOSNAME} = $dcvars->{DC_NETBIOSNAME};
1835 $ret->{DC_USERNAME} = $dcvars->{DC_USERNAME};
1836 $ret->{DC_PASSWORD} = $dcvars->{DC_PASSWORD};
1838 return $ret;
1841 sub read_config_h($)
1843 my ($name) = @_;
1844 my %ret = {};
1845 open(LF, "<$name") or die("unable to read $name: $!");
1846 while (<LF>) {
1847 chomp;
1848 next if not (/^#define /);
1849 if (/^#define (.*?)[ \t]+(.*?)$/) {
1850 $ret{$1} = $2;
1851 next;
1853 if (/^#define (.*?)[ \t]+$/) {
1854 $ret{$1} = 1;;
1855 next;
1858 close(LF);
1859 return \%ret;
1862 sub provision_ad_dc($$$$$$)
1864 my ($self, $prefix, $hostname, $domain, $realm, $smbconf_args,
1865 $extra_provision_options) = @_;
1867 my $prefix_abs = abs_path($prefix);
1869 my $bindir_abs = abs_path($self->{bindir});
1870 my $lockdir="$prefix_abs/lockdir";
1871 my $conffile="$prefix_abs/etc/smb.conf";
1873 my $require_mutexes = "dbwrap_tdb_require_mutexes:* = yes";
1874 $require_mutexes = "" if ($ENV{SELFTEST_DONT_REQUIRE_TDB_MUTEX_SUPPORT} eq "1");
1876 my $config_h = {};
1878 if (defined($ENV{CONFIG_H})) {
1879 $config_h = read_config_h($ENV{CONFIG_H});
1882 my $password_hash_gpg_key_ids = "password hash gpg key ids = 4952E40301FAB41A";
1883 $password_hash_gpg_key_ids = "" unless defined($config_h->{HAVE_GPGME});
1885 my $extra_smbconf_options = "
1886 server services = -smb +s3fs
1887 xattr_tdb:file = $prefix_abs/statedir/xattr.tdb
1889 dbwrap_tdb_mutexes:* = yes
1890 ${require_mutexes}
1892 ${password_hash_gpg_key_ids}
1894 kernel oplocks = no
1895 kernel change notify = no
1896 smb2 leases = no
1898 logging = file
1899 printing = bsd
1900 printcap name = /dev/null
1902 max protocol = SMB3
1903 read only = no
1905 smbd:sharedelay = 100000
1906 smbd:writetimeupdatedelay = 500000
1907 create mask = 755
1908 dos filemode = yes
1909 check parent directory delete on close = yes
1911 dcerpc endpoint servers = -winreg -srvsvc
1913 printcap name = /dev/null
1915 addprinter command = $ENV{SRCDIR_ABS}/source3/script/tests/printing/modprinter.pl -a -s $conffile --
1916 deleteprinter command = $ENV{SRCDIR_ABS}/source3/script/tests/printing/modprinter.pl -d -s $conffile --
1918 printing = vlp
1919 print command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb print %p %s
1920 lpq command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpq %p
1921 lp rm command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lprm %p %j
1922 lp pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lppause %p %j
1923 lp resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpresume %p %j
1924 queue pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queuepause %p
1925 queue resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queueresume %p
1926 lpq cache time = 0
1927 print notify backchannel = yes
1929 server schannel = auto
1930 auth event notification = true
1931 dsdb event notification = true
1932 dsdb password event notification = true
1933 dsdb group change notification = true
1934 $smbconf_args
1937 my $extra_smbconf_shares = "
1939 [tmpenc]
1940 copy = tmp
1941 smb encrypt = required
1943 [tmpcase]
1944 copy = tmp
1945 case sensitive = yes
1947 [tmpguest]
1948 copy = tmp
1949 guest ok = yes
1951 [hideunread]
1952 copy = tmp
1953 hide unreadable = yes
1955 [durable]
1956 copy = tmp
1957 kernel share modes = no
1958 kernel oplocks = no
1959 posix locking = no
1961 [print\$]
1962 copy = tmp
1964 [print1]
1965 copy = tmp
1966 printable = yes
1968 [print2]
1969 copy = print1
1970 [print3]
1971 copy = print1
1972 [lp]
1973 copy = print1
1976 push (@{$extra_provision_options}, "--backend-store=mdb");
1977 print "PROVISIONING AD DC...\n";
1978 my $ret = $self->provision($prefix,
1979 "domain controller",
1980 $hostname,
1981 $domain,
1982 $realm,
1983 "2008",
1984 "locDCpass1",
1985 undef,
1986 undef,
1987 $extra_smbconf_options,
1988 $extra_smbconf_shares,
1989 $extra_provision_options);
1990 unless (defined $ret) {
1991 return undef;
1994 unless($self->add_wins_config("$prefix/private")) {
1995 warn("Unable to add wins configuration");
1996 return undef;
1999 $ret->{DC_SERVER} = $ret->{SERVER};
2000 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
2001 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
2002 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
2003 $ret->{DC_USERNAME} = $ret->{USERNAME};
2004 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
2006 return $ret;
2009 sub provision_chgdcpass($$)
2011 my ($self, $prefix) = @_;
2013 print "PROVISIONING CHGDCPASS...\n";
2014 my $extra_provision_options = undef;
2015 # This environment disallows the use of this password
2016 # (and also removes the default AD complexity checks)
2017 my $unacceptable_password = "widk3Dsle32jxdBdskldsk55klASKQ";
2018 push (@{$extra_provision_options}, "--dns-backend=BIND9_DLZ");
2019 my $ret = $self->provision($prefix,
2020 "domain controller",
2021 "chgdcpass",
2022 "CHDCDOMAIN",
2023 "chgdcpassword.samba.example.com",
2024 "2008",
2025 "chgDCpass1",
2026 undef,
2027 undef,
2028 "check password script = sed -e '/$unacceptable_password/{;q1}; /$unacceptable_password/!{q0}'\n",
2030 $extra_provision_options);
2031 unless (defined $ret) {
2032 return undef;
2035 unless($self->add_wins_config("$prefix/private")) {
2036 warn("Unable to add wins configuration");
2037 return undef;
2040 # Remove secrets.tdb from this environment to test that we
2041 # still start up on systems without the new matching
2042 # secrets.tdb records.
2043 unless (unlink("$ret->{PRIVATEDIR}/secrets.tdb") || unlink("$ret->{PRIVATEDIR}/secrets.ntdb")) {
2044 warn("Unable to remove $ret->{PRIVATEDIR}/secrets.tdb added during provision");
2045 return undef;
2048 $ret->{DC_SERVER} = $ret->{SERVER};
2049 $ret->{DC_SERVER_IP} = $ret->{SERVER_IP};
2050 $ret->{DC_SERVER_IPV6} = $ret->{SERVER_IPV6};
2051 $ret->{DC_NETBIOSNAME} = $ret->{NETBIOSNAME};
2052 $ret->{DC_USERNAME} = $ret->{USERNAME};
2053 $ret->{DC_PASSWORD} = $ret->{PASSWORD};
2054 $ret->{UNACCEPTABLE_PASSWORD} = $unacceptable_password;
2056 return $ret;
2059 sub teardown_env_terminate($$)
2061 my ($self, $envvars) = @_;
2062 my $pid;
2064 # This should cause samba to terminate gracefully
2065 close($envvars->{STDIN_PIPE});
2067 $pid = $envvars->{SAMBA_PID};
2068 my $count = 0;
2069 my $childpid;
2071 # This should give it time to write out the gcov data
2072 until ($count > 15) {
2073 if (Samba::cleanup_child($pid, "samba") != 0) {
2074 return;
2076 sleep(1);
2077 $count++;
2080 # After 15 Seconds, work out why this thing is still alive
2081 warn "server process $pid took more than $count seconds to exit, showing backtrace:\n";
2082 system("$self->{srcdir}/selftest/gdb_backtrace $pid");
2084 until ($count > 30) {
2085 if (Samba::cleanup_child($pid, "samba") != 0) {
2086 return;
2088 sleep(1);
2089 $count++;
2092 if (kill(0, $pid)) {
2093 warn "server process $pid took more than $count seconds to exit, sending SIGTERM\n";
2094 kill "TERM", $pid;
2097 until ($count > 40) {
2098 if (Samba::cleanup_child($pid, "samba") != 0) {
2099 return;
2101 sleep(1);
2102 $count++;
2104 # If it is still around, kill it
2105 if (kill(0, $pid)) {
2106 warn "server process $pid took more than $count seconds to exit, killing\n with SIGKILL\n";
2107 kill 9, $pid;
2109 return;
2112 sub teardown_env($$)
2114 my ($self, $envvars) = @_;
2115 teardown_env_terminate($self, $envvars);
2117 $self->slapd_stop($envvars) if ($self->{ldap});
2119 print $self->getlog_env($envvars);
2121 return;
2124 sub getlog_env($$)
2126 my ($self, $envvars) = @_;
2127 my $title = "SAMBA LOG of: $envvars->{NETBIOSNAME} pid $envvars->{SAMBA_PID}\n";
2128 my $out = $title;
2130 open(LOG, "<$envvars->{SAMBA_TEST_LOG}");
2132 seek(LOG, $envvars->{SAMBA_TEST_LOG_POS}, SEEK_SET);
2133 while (<LOG>) {
2134 $out .= $_;
2136 $envvars->{SAMBA_TEST_LOG_POS} = tell(LOG);
2137 close(LOG);
2139 return "" if $out eq $title;
2141 return $out;
2144 sub check_env($$)
2146 my ($self, $envvars) = @_;
2147 my $samba_pid = $envvars->{SAMBA_PID};
2149 if (not defined($samba_pid)) {
2150 return 0;
2151 } elsif ($samba_pid > 0) {
2152 my $childpid = Samba::cleanup_child($samba_pid, "samba");
2154 if ($childpid == 0) {
2155 return 1;
2157 return 0;
2158 } else {
2159 return 1;
2163 # Declare the environments Samba4 makes available.
2164 # To be set up, they will be called as
2165 # samba4->setup_$envname($self, $path, $dep_1_vars, $dep_2_vars, ...)
2166 %Samba4::ENV_DEPS = (
2167 # name => [dep_1, dep_2, ...],
2168 ad_dc_ntvfs => [],
2169 ad_dc => [],
2170 ad_dc_no_nss => [],
2171 ad_dc_no_ntlm => [],
2172 ad_dc_ntvfs => [],
2173 backupfromdc => [],
2175 fl2008r2dc => ["ad_dc"],
2176 fl2003dc => ["ad_dc"],
2177 fl2000dc => [],
2179 vampire_2000_dc => ["fl2000dc"],
2180 vampire_dc => ["ad_dc_ntvfs"],
2181 promoted_dc => ["ad_dc_ntvfs"],
2182 subdom_dc => ["ad_dc_ntvfs"],
2184 rodc => ["ad_dc_ntvfs"],
2185 rpc_proxy => ["ad_dc_ntvfs"],
2186 chgdcpass => [],
2188 s4member_dflt_domain => ["ad_dc_ntvfs"],
2189 s4member => ["ad_dc_ntvfs"],
2191 restoredc => ["backupfromdc"],
2192 renamedc => ["backupfromdc"],
2193 offlinebackupdc => ["backupfromdc"],
2194 labdc => ["backupfromdc"],
2196 none => [],
2199 sub setup_s4member
2201 my ($self, $path, $dc_vars) = @_;
2203 my $env = $self->provision_s4member($path, $dc_vars, "s4member");
2205 if (defined $env) {
2206 if (not defined($self->check_or_start($env, "standard"))) {
2207 return undef;
2211 return $env;
2214 sub setup_s4member_dflt_domain
2216 my ($self, $path, $dc_vars) = @_;
2218 my $env = $self->provision_s4member($path, $dc_vars, "s4member_dflt",
2219 "winbind use default domain = yes");
2221 if (defined $env) {
2222 if (not defined($self->check_or_start($env, "standard"))) {
2223 return undef;
2227 return $env;
2230 sub setup_rpc_proxy
2232 my ($self, $path, $dc_vars) = @_;
2234 my $env = $self->provision_rpc_proxy($path, $dc_vars);
2236 if (defined $env) {
2237 if (not defined($self->check_or_start($env, "standard"))) {
2238 return undef;
2241 return $env;
2244 sub setup_ad_dc_ntvfs
2246 my ($self, $path) = @_;
2248 my $env = $self->provision_ad_dc_ntvfs($path);
2249 if (defined $env) {
2250 if (not defined($self->check_or_start($env, "standard"))) {
2251 warn("Failed to start ad_dc_ntvfs");
2252 return undef;
2255 return $env;
2258 sub setup_chgdcpass
2260 my ($self, $path) = @_;
2262 my $env = $self->provision_chgdcpass($path);
2263 if (defined $env) {
2264 if (not defined($self->check_or_start($env, "standard"))) {
2265 return undef;
2268 return $env;
2271 sub setup_fl2000dc
2273 my ($self, $path) = @_;
2275 my $env = $self->provision_fl2000dc($path);
2276 if (defined $env) {
2277 if (not defined($self->check_or_start($env, "standard"))) {
2278 return undef;
2282 return $env;
2285 sub setup_fl2003dc
2287 my ($self, $path, $dc_vars) = @_;
2289 my $env = $self->provision_fl2003dc($path);
2291 if (defined $env) {
2292 if (not defined($self->check_or_start($env, "standard"))) {
2293 return undef;
2296 $env = $self->setup_trust($env, $dc_vars, "external", "--no-aes-keys");
2298 return $env;
2301 sub setup_fl2008r2dc
2303 my ($self, $path, $dc_vars) = @_;
2305 my $env = $self->provision_fl2008r2dc($path);
2307 if (defined $env) {
2308 if (not defined($self->check_or_start($env, "standard"))) {
2309 return undef;
2312 my $upn_array = ["$env->{REALM}.upn"];
2313 my $spn_array = ["$env->{REALM}.spn"];
2315 $self->setup_namespaces($env, $upn_array, $spn_array);
2317 $env = $self->setup_trust($env, $dc_vars, "forest", "");
2320 return $env;
2323 sub setup_vampire_dc
2325 return setup_generic_vampire_dc(@_, "2008");
2328 sub setup_vampire_2000_dc
2330 return setup_generic_vampire_dc(@_, "2000");
2333 sub setup_generic_vampire_dc
2335 my ($self, $path, $dc_vars, $fl) = @_;
2337 my $env = $self->provision_vampire_dc($path, $dc_vars, $fl);
2339 if (defined $env) {
2340 if (not defined($self->check_or_start($env, "single"))) {
2341 return undef;
2344 # force replicated DC to update repsTo/repsFrom
2345 # for vampired partitions
2346 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2348 # as 'vampired' dc may add data in its local replica
2349 # we need to synchronize data between DCs
2350 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2351 my $cmd = "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
2352 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
2353 if (defined($env->{RESOLV_WRAPPER_CONF})) {
2354 $cmd .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
2355 } else {
2356 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
2358 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2359 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2360 $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SERVER}";
2361 $cmd .= " $dc_vars->{CONFIGURATION}";
2362 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2363 # replicate Configuration NC
2364 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2365 unless(system($cmd_repl) == 0) {
2366 warn("Failed to replicate\n$cmd_repl");
2367 return undef;
2369 # replicate Default NC
2370 $cmd_repl = "$cmd \"$base_dn\"";
2371 unless(system($cmd_repl) == 0) {
2372 warn("Failed to replicate\n$cmd_repl");
2373 return undef;
2376 # Pull in a full set of changes from the main DC
2377 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2378 $cmd = "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
2379 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
2380 if (defined($env->{RESOLV_WRAPPER_CONF})) {
2381 $cmd .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
2382 } else {
2383 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
2385 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2386 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2387 $cmd .= " $samba_tool drs replicate $env->{SERVER} $env->{DC_SERVER}";
2388 $cmd .= " $dc_vars->{CONFIGURATION}";
2389 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2390 # replicate Configuration NC
2391 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2392 unless(system($cmd_repl) == 0) {
2393 warn("Failed to replicate\n$cmd_repl");
2394 return undef;
2396 # replicate Default NC
2397 $cmd_repl = "$cmd \"$base_dn\"";
2398 unless(system($cmd_repl) == 0) {
2399 warn("Failed to replicate\n$cmd_repl");
2400 return undef;
2404 return $env;
2407 sub setup_promoted_dc
2409 my ($self, $path, $dc_vars) = @_;
2411 my $env = $self->provision_promoted_dc($path, $dc_vars);
2413 if (defined $env) {
2414 if (not defined($self->check_or_start($env, "single"))) {
2415 return undef;
2418 # force source and replicated DC to update repsTo/repsFrom
2419 # for vampired partitions
2420 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2421 my $cmd = "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
2422 # as 'vampired' dc may add data in its local replica
2423 # we need to synchronize data between DCs
2424 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2425 $cmd = "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2426 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2427 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2428 $cmd .= " $samba_tool drs replicate $env->{DC_SERVER} $env->{SERVER}";
2429 $cmd .= " $dc_vars->{CONFIGURATION}";
2430 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2431 # replicate Configuration NC
2432 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2433 unless(system($cmd_repl) == 0) {
2434 warn("Failed to replicate\n$cmd_repl");
2435 return undef;
2437 # replicate Default NC
2438 $cmd_repl = "$cmd \"$base_dn\"";
2439 unless(system($cmd_repl) == 0) {
2440 warn("Failed to replicate\n$cmd_repl");
2441 return undef;
2445 return $env;
2448 sub setup_subdom_dc
2450 my ($self, $path, $dc_vars) = @_;
2452 my $env = $self->provision_subdom_dc($path, $dc_vars);
2454 if (defined $env) {
2455 if (not defined($self->check_or_start($env, "single"))) {
2456 return undef;
2459 # force replicated DC to update repsTo/repsFrom
2460 # for primary domain partitions
2461 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2462 my $cmd = "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
2463 # as 'subdomain' dc may add data in its local replica
2464 # we need to synchronize data between DCs
2465 my $base_dn = "DC=".join(",DC=", split(/\./, $env->{REALM}));
2466 my $config_dn = "CN=Configuration,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->{DC_SERVER} $env->{SUBDOM_DC_SERVER}";
2471 $cmd .= " $dc_vars->{CONFIGURATION}";
2472 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD} --realm=$dc_vars->{DC_REALM}";
2473 # replicate Configuration NC
2474 my $cmd_repl = "$cmd \"$config_dn\"";
2475 unless(system($cmd_repl) == 0) {
2476 warn("Failed to replicate\n$cmd_repl");
2477 return undef;
2479 # replicate Default NC
2480 $cmd_repl = "$cmd \"$base_dn\"";
2481 unless(system($cmd_repl) == 0) {
2482 warn("Failed to replicate\n$cmd_repl");
2483 return undef;
2487 return $env;
2490 sub setup_rodc
2492 my ($self, $path, $dc_vars) = @_;
2494 my $env = $self->provision_rodc($path, $dc_vars);
2496 unless ($env) {
2497 return undef;
2500 if (not defined($self->check_or_start($env, "standard"))) {
2501 return undef;
2504 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2505 my $cmd = "";
2507 my $base_dn = "DC=".join(",DC=", split(/\./, $dc_vars->{REALM}));
2508 $cmd .= "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
2509 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\"";
2510 $cmd .= " KRB5_CONFIG=\"$env->{KRB5_CONFIG}\"";
2511 $cmd .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2512 $cmd .= " $samba_tool drs replicate $env->{SERVER} $env->{DC_SERVER}";
2513 $cmd .= " $dc_vars->{CONFIGURATION}";
2514 $cmd .= " -U$dc_vars->{DC_USERNAME}\%$dc_vars->{DC_PASSWORD}";
2515 # replicate Configuration NC
2516 my $cmd_repl = "$cmd \"CN=Configuration,$base_dn\"";
2517 unless(system($cmd_repl) == 0) {
2518 warn("Failed to replicate\n$cmd_repl");
2519 return undef;
2521 # replicate Default NC
2522 $cmd_repl = "$cmd \"$base_dn\"";
2523 unless(system($cmd_repl) == 0) {
2524 warn("Failed to replicate\n$cmd_repl");
2525 return undef;
2528 return $env;
2531 sub setup_ad_dc
2533 my ($self, $path) = @_;
2535 # If we didn't build with ADS, pretend this env was never available
2536 if (not $self->{target3}->have_ads()) {
2537 return "UNKNOWN";
2540 my $env = $self->provision_ad_dc($path, "addc", "ADDOMAIN",
2541 "addom.samba.example.com", "", undef);
2542 unless ($env) {
2543 return undef;
2546 if (not defined($self->check_or_start($env, "single"))) {
2547 return undef;
2550 my $upn_array = ["$env->{REALM}.upn"];
2551 my $spn_array = ["$env->{REALM}.spn"];
2553 $self->setup_namespaces($env, $upn_array, $spn_array);
2555 return $env;
2558 sub setup_ad_dc_no_nss
2560 my ($self, $path) = @_;
2562 # If we didn't build with ADS, pretend this env was never available
2563 if (not $self->{target3}->have_ads()) {
2564 return "UNKNOWN";
2567 my $env = $self->provision_ad_dc($path, "addc_no_nss", "ADNONSSDOMAIN",
2568 "adnonssdom.samba.example.com", "", undef);
2569 unless ($env) {
2570 return undef;
2573 $env->{NSS_WRAPPER_MODULE_SO_PATH} = undef;
2574 $env->{NSS_WRAPPER_MODULE_FN_PREFIX} = undef;
2576 if (not defined($self->check_or_start($env, "single"))) {
2577 return undef;
2580 my $upn_array = ["$env->{REALM}.upn"];
2581 my $spn_array = ["$env->{REALM}.spn"];
2583 $self->setup_namespaces($env, $upn_array, $spn_array);
2585 return $env;
2588 sub setup_ad_dc_no_ntlm
2590 my ($self, $path) = @_;
2592 # If we didn't build with ADS, pretend this env was never available
2593 if (not $self->{target3}->have_ads()) {
2594 return "UNKNOWN";
2597 my $env = $self->provision_ad_dc($path, "addc_no_ntlm", "ADNONTLMDOMAIN",
2598 "adnontlmdom.samba.example.com",
2599 "ntlm auth = disabled", undef);
2600 unless ($env) {
2601 return undef;
2604 if (not defined($self->check_or_start($env, "prefork"))) {
2605 return undef;
2608 my $upn_array = ["$env->{REALM}.upn"];
2609 my $spn_array = ["$env->{REALM}.spn"];
2611 $self->setup_namespaces($env, $upn_array, $spn_array);
2613 return $env;
2616 # Sets up a DC that's solely used to do a domain backup from. We then use the
2617 # backupfrom-DC to create the restore-DC - this proves that the backup/restore
2618 # process will create a Samba DC that will actually start up.
2619 # We don't use the backup-DC for anything else because its domain will conflict
2620 # with the restore DC.
2621 sub setup_backupfromdc
2623 my ($self, $path) = @_;
2625 # If we didn't build with ADS, pretend this env was never available
2626 if (not $self->{target3}->have_ads()) {
2627 return "UNKNOWN";
2630 my $provision_args = ["--site=Backup-Site"];
2632 my $env = $self->provision_ad_dc($path, "backupfromdc", "BACKUPDOMAIN",
2633 "backupdom.samba.example.com", "",
2634 $provision_args);
2635 unless ($env) {
2636 return undef;
2639 if (not defined($self->check_or_start($env, "standard"))) {
2640 return undef;
2643 my $upn_array = ["$env->{REALM}.upn"];
2644 my $spn_array = ["$env->{REALM}.spn"];
2646 $self->setup_namespaces($env, $upn_array, $spn_array);
2648 return $env;
2651 # returns the server/user-auth params needed to run an online backup cmd
2652 sub get_backup_server_args
2654 # dcvars contains the env info for the backup DC testenv
2655 my ($self, $dcvars) = @_;
2656 my $server = $dcvars->{DC_SERVER_IP};
2657 my $server_args = "--server=$server ";
2658 $server_args .= "-U$dcvars->{DC_USERNAME}\%$dcvars->{DC_PASSWORD}";
2660 return $server_args;
2663 # Creates a backup of a running testenv DC
2664 sub create_backup
2666 # note: dcvars contains the env info for the backup DC testenv
2667 my ($self, $env, $dcvars, $backupdir, $backup_cmd) = @_;
2669 # get all the env variables we pass in with the samba-tool command
2670 my $cmd_env = "NSS_WRAPPER_HOSTS='$env->{NSS_WRAPPER_HOSTS}' ";
2671 $cmd_env .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$env->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
2672 if (defined($env->{RESOLV_WRAPPER_CONF})) {
2673 $cmd_env .= "RESOLV_WRAPPER_CONF=\"$env->{RESOLV_WRAPPER_CONF}\" ";
2674 } else {
2675 $cmd_env .= "RESOLV_WRAPPER_HOSTS=\"$env->{RESOLV_WRAPPER_HOSTS}\" ";
2677 # Note: use the backupfrom-DC's krb5.conf to do the backup
2678 $cmd_env .= " KRB5_CONFIG=\"$dcvars->{KRB5_CONFIG}\" ";
2679 $cmd_env .= "KRB5CCNAME=\"$env->{KRB5_CCACHE}\" ";
2681 # use samba-tool to create a backup from the 'backupfromdc' DC
2682 my $cmd = "";
2683 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2685 $cmd .= "$cmd_env $samba_tool domain backup $backup_cmd";
2686 $cmd .= " --targetdir=$backupdir";
2688 print "Executing: $cmd\n";
2689 unless(system($cmd) == 0) {
2690 warn("Failed to create backup using: \n$cmd");
2691 return undef;
2694 # get the name of the backup file created
2695 opendir(DIR, $backupdir);
2696 my @files = grep(/\.tar/, readdir(DIR));
2697 closedir(DIR);
2699 if(scalar @files != 1) {
2700 warn("Backup file not found in directory $backupdir\n");
2701 return undef;
2703 my $backup_file = "$backupdir/$files[0]";
2704 print "Using backup file $backup_file...\n";
2706 return $backup_file;
2709 # Restores a backup-file to populate a testenv for a new DC
2710 sub restore_backup_file
2712 my ($self, $backup_file, $restore_opts, $restoredir, $smbconf) = @_;
2714 # pass the restore command the testenv's smb.conf that we've already
2715 # generated. But move it to a temp-dir first, so that the restore doesn't
2716 # overwrite it
2717 my $tmpdir = File::Temp->newdir();
2718 my $tmpconf = "$tmpdir/smb.conf";
2719 my $cmd = "cp $smbconf $tmpconf";
2720 unless(system($cmd) == 0) {
2721 warn("Failed to backup smb.conf using: \n$cmd");
2722 return -1;
2725 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2726 $cmd = "$samba_tool domain backup restore --backup-file=$backup_file";
2727 $cmd .= " --targetdir=$restoredir $restore_opts --configfile=$tmpconf";
2729 print "Executing: $cmd\n";
2730 unless(system($cmd) == 0) {
2731 warn("Failed to restore backup using: \n$cmd");
2732 return -1;
2735 print "Restore complete\n";
2736 return 0
2739 # sets up the initial directory and returns the new testenv's env info
2740 # (without actually doing a 'domain join')
2741 sub prepare_dc_testenv
2743 my ($self, $prefix, $dcname, $domain, $realm, $password) = @_;
2745 my $ctx = $self->provision_raw_prepare($prefix, "domain controller",
2746 $dcname,
2747 $domain,
2748 $realm,
2749 undef,
2750 "2008",
2751 $password,
2752 undef,
2753 undef);
2755 # the restore uses a slightly different state-dir location to other testenvs
2756 $ctx->{statedir} = "$ctx->{prefix_abs}/state";
2757 push(@{$ctx->{directories}}, "$ctx->{statedir}");
2759 # add support for sysvol/netlogon/tmp shares
2760 $ctx->{share} = "$ctx->{prefix_abs}/share";
2761 push(@{$ctx->{directories}}, "$ctx->{share}");
2763 $ctx->{smb_conf_extra_options} = "
2764 max xmit = 32K
2765 server max protocol = SMB2
2767 [sysvol]
2768 path = $ctx->{statedir}/sysvol
2769 read only = no
2771 [netlogon]
2772 path = $ctx->{statedir}/sysvol/$ctx->{dnsname}/scripts
2773 read only = no
2775 [tmp]
2776 path = $ctx->{share}
2777 read only = no
2778 posix:sharedelay = 10000
2779 posix:oplocktimeout = 3
2780 posix:writetimeupdatedelay = 50000
2784 my $env = $self->provision_raw_step1($ctx);
2786 $env->{DC_SERVER} = $env->{SERVER};
2787 $env->{DC_SERVER_IP} = $env->{SERVER_IP};
2788 $env->{DC_SERVER_IPV6} = $env->{SERVER_IPV6};
2789 $env->{DC_NETBIOSNAME} = $env->{NETBIOSNAME};
2790 $env->{DC_USERNAME} = $env->{USERNAME};
2791 $env->{DC_PASSWORD} = $env->{PASSWORD};
2793 return ($env, $ctx);
2797 # Set up a DC testenv solely by using the samba-tool domain backup/restore
2798 # commands. This proves that we can backup an online DC ('backupfromdc') and
2799 # use the backup file to create a valid, working samba DC.
2800 sub setup_restoredc
2802 # note: dcvars contains the env info for the dependent testenv ('backupfromdc')
2803 my ($self, $prefix, $dcvars) = @_;
2804 print "Preparing RESTORE DC...\n";
2806 my ($env, $ctx) = $self->prepare_dc_testenv($prefix, "restoredc",
2807 $dcvars->{DOMAIN},
2808 $dcvars->{REALM},
2809 $dcvars->{PASSWORD});
2811 # create a backup of the 'backupfromdc'
2812 my $backupdir = File::Temp->newdir();
2813 my $server_args = $self->get_backup_server_args($dcvars);
2814 my $backup_args = "online $server_args";
2815 my $backup_file = $self->create_backup($env, $dcvars, $backupdir,
2816 $backup_args);
2817 unless($backup_file) {
2818 return undef;
2821 # restore the backup file to populate the restore-DC testenv
2822 my $restore_dir = abs_path($prefix);
2823 my $ret = $self->restore_backup_file($backup_file,
2824 "--newservername=$env->{SERVER}",
2825 $restore_dir, $env->{SERVERCONFFILE});
2826 unless ($ret == 0) {
2827 return undef;
2830 # start samba for the restored DC
2831 if (not defined($self->check_or_start($env, "standard"))) {
2832 return undef;
2835 my $upn_array = ["$env->{REALM}.upn"];
2836 my $spn_array = ["$env->{REALM}.spn"];
2838 $self->setup_namespaces($env, $upn_array, $spn_array);
2840 return $env;
2843 # Set up a DC testenv solely by using the 'samba-tool domain backup rename' and
2844 # restore commands. This proves that we can backup and rename an online DC
2845 # ('backupfromdc') and use the backup file to create a valid, working samba DC.
2846 sub setup_renamedc
2848 # note: dcvars contains the env info for the dependent testenv ('backupfromdc')
2849 my ($self, $prefix, $dcvars) = @_;
2850 print "Preparing RENAME DC...\n";
2852 my $realm = "renamedom.samba.example.com";
2853 my ($env, $ctx) = $self->prepare_dc_testenv($prefix, "renamedc",
2854 "RENAMEDOMAIN", $realm,
2855 $dcvars->{PASSWORD});
2857 # create a backup of the 'backupfromdc' which renames the domain
2858 my $backupdir = File::Temp->newdir();
2859 my $server_args = $self->get_backup_server_args($dcvars);
2860 my $backup_args = "rename $env->{DOMAIN} $env->{REALM} $server_args";
2861 my $backup_file = $self->create_backup($env, $dcvars, $backupdir,
2862 $backup_args);
2863 unless($backup_file) {
2864 return undef;
2867 # restore the backup file to populate the rename-DC testenv
2868 my $restore_dir = abs_path($prefix);
2869 my $restore_opts = "--newservername=$env->{SERVER} --host-ip=$env->{SERVER_IP}";
2870 my $ret = $self->restore_backup_file($backup_file, $restore_opts,
2871 $restore_dir, $env->{SERVERCONFFILE});
2872 unless ($ret == 0) {
2873 return undef;
2876 # start samba for the restored DC
2877 if (not defined($self->check_or_start($env, "standard"))) {
2878 return undef;
2881 my $upn_array = ["$env->{REALM}.upn"];
2882 my $spn_array = ["$env->{REALM}.spn"];
2884 $self->setup_namespaces($env, $upn_array, $spn_array);
2886 return $env;
2889 # Set up a DC testenv solely by using the 'samba-tool domain backup offline' and
2890 # restore commands. This proves that we do an offline backup of a local DC
2891 # ('backupfromdc') and use the backup file to create a valid, working samba DC.
2892 sub setup_offlinebackupdc
2894 # note: dcvars contains the env info for the dependent testenv ('backupfromdc')
2895 my ($self, $prefix, $dcvars) = @_;
2896 print "Preparing OFFLINE BACKUP DC...\n";
2898 my ($env, $ctx) = $self->prepare_dc_testenv($prefix, "offlinebackupdc",
2899 $dcvars->{DOMAIN},
2900 $dcvars->{REALM},
2901 $dcvars->{PASSWORD});
2903 # create an offline backup of the 'backupfromdc' target
2904 my $backupdir = File::Temp->newdir();
2905 my $cmd = "offline -s $dcvars->{SERVERCONFFILE}";
2906 my $backup_file = $self->create_backup($env, $dcvars,
2907 $backupdir, $cmd);
2909 unless($backup_file) {
2910 return undef;
2913 # restore the backup file to populate the rename-DC testenv
2914 my $restore_dir = abs_path($prefix);
2915 my $restore_opts = "--newservername=$env->{SERVER} --host-ip=$env->{SERVER_IP}";
2916 my $ret = $self->restore_backup_file($backup_file, $restore_opts,
2917 $restore_dir, $env->{SERVERCONFFILE});
2918 unless ($ret == 0) {
2919 return undef;
2922 # re-create the testenv's krb5.conf (the restore may have overwritten it)
2923 Samba::mk_krb5_conf($ctx);
2925 # start samba for the restored DC
2926 if (not defined($self->check_or_start($env, "standard"))) {
2927 return undef;
2930 my $upn_array = ["$env->{REALM}.upn"];
2931 my $spn_array = ["$env->{REALM}.spn"];
2933 $self->setup_namespaces($env, $upn_array, $spn_array);
2935 return $env;
2938 # Set up a DC testenv solely by using the samba-tool 'domain backup rename' and
2939 # restore commands, using the --no-secrets option. This proves that we can
2940 # create a realistic lab environment from an online DC ('backupfromdc').
2941 sub setup_labdc
2943 # note: dcvars contains the env info for the dependent testenv ('backupfromdc')
2944 my ($self, $prefix, $dcvars) = @_;
2945 print "Preparing LAB-DOMAIN DC...\n";
2947 my ($env, $ctx) = $self->prepare_dc_testenv($prefix, "labdc",
2948 "LABDOMAIN",
2949 "labdom.samba.example.com",
2950 $dcvars->{PASSWORD});
2952 # create a backup of the 'backupfromdc' which renames the domain and uses
2953 # the --no-secrets option to scrub any sensitive info
2954 my $backupdir = File::Temp->newdir();
2955 my $server_args = $self->get_backup_server_args($dcvars);
2956 my $backup_args = "rename $env->{DOMAIN} $env->{REALM} $server_args";
2957 $backup_args .= " --no-secrets";
2958 my $backup_file = $self->create_backup($env, $dcvars, $backupdir,
2959 $backup_args);
2960 unless($backup_file) {
2961 return undef;
2964 # restore the backup file to populate the lab-DC testenv
2965 my $restore_dir = abs_path($prefix);
2966 my $restore_opts = "--newservername=$env->{SERVER} --host-ip=$env->{SERVER_IP}";
2967 my $ret = $self->restore_backup_file($backup_file, $restore_opts,
2968 $restore_dir, $env->{SERVERCONFFILE});
2969 unless ($ret == 0) {
2970 return undef;
2973 # because we don't include any secrets in the backup, we need to reset the
2974 # admin user's password back to what the testenv expects
2975 my $samba_tool = Samba::bindir_path($self, "samba-tool");
2976 my $cmd = "$samba_tool user setpassword $env->{USERNAME} ";
2977 $cmd .= "--newpassword=$env->{PASSWORD} -H $restore_dir/private/sam.ldb";
2979 unless(system($cmd) == 0) {
2980 warn("Failed to reset admin's password: \n$cmd");
2981 return -1;
2984 # start samba for the restored DC
2985 if (not defined($self->check_or_start($env, "standard"))) {
2986 return undef;
2989 my $upn_array = ["$env->{REALM}.upn"];
2990 my $spn_array = ["$env->{REALM}.spn"];
2992 $self->setup_namespaces($env, $upn_array, $spn_array);
2994 return $env;
2997 sub setup_none
2999 my ($self, $path) = @_;
3001 my $ret = {
3002 KRB5_CONFIG => abs_path($path) . "/no_krb5.conf",
3003 SAMBA_PID => -1,