dc1c14e9628d4c0ed7f8e14b4475e7a031f2d2a2
[samba.git] / selftest / target / Samba3.pm
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.
5
6 # NOTE: Refer to the README for more details about the various testenvs,
7 # and tips about adding new testenvs.
8
9 package Samba3;
10
11 use strict;
12 use warnings;
13 use Cwd qw(abs_path);
14 use FindBin qw($RealBin);
15 use POSIX;
16 use target::Samba;
17 use File::Path 'remove_tree';
18
19 sub return_alias_env
20 {
21         my ($self, $path, $env) = @_;
22
23         # just an alias
24         return $env;
25 }
26
27 sub have_ads($) {
28         my ($self) = @_;
29         my $found_ads = 0;
30         my $smbd_build_options = Samba::bindir_path($self, "smbd") . " --configfile=/dev/null -b|";
31         open(IN, $smbd_build_options) or die("Unable to run $smbd_build_options: $!");
32
33         while (<IN>) {
34                 if (/WITH_ADS/) {
35                        $found_ads = 1;
36                 }
37         }
38         close IN;
39
40         # If we were not built with ADS support, pretend we were never even available
41         print "smbd does not have ADS support\n" unless $found_ads;
42         return $found_ads;
43 }
44
45 # return smb.conf parameters applicable to @path, based on the underlying
46 # filesystem type
47 sub get_fs_specific_conf($$)
48 {
49         my ($self, $path) = @_;
50         my $mods = "";
51         my $stat_out = `stat --file-system $path` or return "";
52
53         if ($stat_out =~ m/Type:\s+btrfs/) {
54                 $mods .= "streams_xattr btrfs";
55         }
56
57         if ($mods) {
58                 return "vfs objects = $mods";
59         }
60
61         return '';
62 }
63
64 sub new($$) {
65         my ($classname, $SambaCtx, $bindir, $srcdir, $server_maxtime) = @_;
66         my $self = { vars => {},
67                      SambaCtx => $SambaCtx,
68                      bindir => $bindir,
69                      srcdir => $srcdir,
70                      server_maxtime => $server_maxtime
71         };
72         bless $self;
73         return $self;
74 }
75
76 sub teardown_env($$)
77 {
78         my ($self, $envvars) = @_;
79
80         if (defined($envvars->{CTDB_PREFIX})) {
81                 $self->teardown_env_ctdb($envvars);
82         } else {
83                 $self->teardown_env_samba($envvars);
84         }
85
86         return;
87 }
88
89 sub teardown_env_samba($$)
90 {
91         my ($self, $envvars) = @_;
92         my $count = 0;
93
94         # This should cause smbd to terminate gracefully
95         close($envvars->{STDIN_PIPE});
96
97         my $smbdpid = $envvars->{SMBD_TL_PID};
98         my $nmbdpid = $envvars->{NMBD_TL_PID};
99         my $winbinddpid = $envvars->{WINBINDD_TL_PID};
100
101         # This should give it time to write out the gcov data
102         until ($count > 20) {
103             my $smbdchild = Samba::cleanup_child($smbdpid, "smbd");
104             my $nmbdchild = Samba::cleanup_child($nmbdpid, "nmbd");
105             my $winbinddchild = Samba::cleanup_child($winbinddpid, "winbindd");
106             if ($smbdchild == -1
107                 && $nmbdchild == -1
108                 && $winbinddchild == -1) {
109                 last;
110             }
111             sleep(1);
112             $count++;
113         }
114
115         if ($count <= 20 && kill(0, $smbdpid, $nmbdpid, $winbinddpid) == 0) {
116             return;
117         }
118
119         $self->stop_sig_term($smbdpid);
120         $self->stop_sig_term($nmbdpid);
121         $self->stop_sig_term($winbinddpid);
122
123         $count = 0;
124         until ($count > 10) {
125             my $smbdchild = Samba::cleanup_child($smbdpid, "smbd");
126             my $nmbdchild = Samba::cleanup_child($nmbdpid, "nmbd");
127             my $winbinddchild = Samba::cleanup_child($winbinddpid, "winbindd");
128             if ($smbdchild == -1
129                 && $nmbdchild == -1
130                 && $winbinddchild == -1) {
131                 last;
132             }
133             sleep(1);
134             $count++;
135         }
136
137         if ($count <= 10 && kill(0, $smbdpid, $nmbdpid, $winbinddpid) == 0) {
138             return;
139         }
140
141         warn("timelimit process did not quit on SIGTERM, sending SIGKILL");
142         $self->stop_sig_kill($smbdpid);
143         $self->stop_sig_kill($nmbdpid);
144         $self->stop_sig_kill($winbinddpid);
145
146         return 0;
147 }
148
149 sub teardown_env_ctdb($$)
150 {
151         my ($self, $data) = @_;
152
153         if (defined($data->{SAMBA_NODES})) {
154                 my $num_nodes = $data->{NUM_NODES};
155                 my $nodes = $data->{SAMBA_NODES};
156
157                 for (my $i = 0; $i < $num_nodes; $i++) {
158                         if (defined($nodes->[$i])) {
159                                 $self->teardown_env_samba($nodes->[$i]);
160                         }
161                 }
162         }
163
164         close($data->{CTDB_STDIN_PIPE});
165
166         if (not defined($data->{SAMBA_NODES})) {
167                 # Give waiting children time to exit
168                 sleep(5);
169         }
170
171         return 0;
172 }
173
174 sub getlog_env_app($$$)
175 {
176         my ($self, $envvars, $name) = @_;
177
178         my $title = "$name LOG of: $envvars->{NETBIOSNAME}\n";
179         my $out = $title;
180
181         open(LOG, "<".$envvars->{$name."_TEST_LOG"});
182
183         seek(LOG, $envvars->{$name."_TEST_LOG_POS"}, SEEK_SET);
184         while (<LOG>) {
185                 $out .= $_;
186         }
187         $envvars->{$name."_TEST_LOG_POS"} = tell(LOG);
188         close(LOG);
189
190         return "" if $out eq $title;
191  
192         return $out;
193 }
194
195 sub getlog_env($$)
196 {
197         my ($self, $envvars) = @_;
198         my $ret = "";
199
200         $ret .= $self->getlog_env_app($envvars, "SMBD");
201         $ret .= $self->getlog_env_app($envvars, "NMBD");
202         $ret .= $self->getlog_env_app($envvars, "WINBINDD");
203
204         return $ret;
205 }
206
207 sub check_env($$)
208 {
209         my ($self, $envvars) = @_;
210
211         my $childpid = waitpid(-1, WNOHANG);
212
213         # TODO ...
214         return 1;
215 }
216
217 # Declare the environments Samba3 makes available.
218 # To be set up, they will be called as
219 #   samba3->setup_$envname($self, $path, $dep_1_vars, $dep_2_vars, ...)
220 %Samba3::ENV_DEPS = (
221         # name              => [dep_1, dep_2, ...],
222         nt4_dc              => [],
223         nt4_dc_smb1         => [],
224         nt4_dc_smb1_done    => ["nt4_dc_smb1"],
225         nt4_dc_schannel     => [],
226
227         simpleserver        => [],
228         fileserver          => [],
229         fileserver_smb1     => [],
230         fileserver_smb1_done => ["fileserver_smb1"],
231         maptoguest          => [],
232         ktest               => [],
233
234         nt4_member          => ["nt4_dc"],
235
236         ad_member           => ["ad_dc", "fl2008r2dc", "fl2003dc"],
237         ad_member_rfc2307   => ["ad_dc_ntvfs"],
238         ad_member_idmap_rid => ["ad_dc"],
239         ad_member_idmap_ad  => ["fl2008r2dc"],
240         ad_member_fips      => ["ad_dc_fips"],
241         ad_member_offlogon  => ["ad_dc"],
242         ad_member_oneway    => ["fl2000dc"],
243
244         clusteredmember => ["nt4_dc"],
245 );
246
247 %Samba3::ENV_DEPS_POST = ();
248
249 sub setup_nt4_dc
250 {
251         my ($self, $path, $more_conf, $server) = @_;
252
253         print "PROVISIONING NT4 DC...";
254
255         my $nt4_dc_options = "
256         domain master = yes
257         domain logons = yes
258         lanman auth = yes
259         ntlm auth = yes
260         raw NTLMv2 auth = yes
261         server schannel = auto
262
263         rpc_server:epmapper = external
264         rpc_server:spoolss = external
265         rpc_server:lsarpc = external
266         rpc_server:samr = external
267         rpc_server:netlogon = external
268         rpc_server:register_embedded_np = yes
269         rpc_server:FssagentRpc = external
270
271         rpc_daemon:epmd = fork
272         rpc_daemon:spoolssd = fork
273         rpc_daemon:lsasd = fork
274         rpc_daemon:fssd = fork
275         fss: sequence timeout = 1
276         check parent directory delete on close = yes
277 ";
278
279         if (defined($more_conf)) {
280                 $nt4_dc_options = $nt4_dc_options . $more_conf;
281         }
282         if (!defined($server)) {
283                 $server = "LOCALNT4DC2";
284         }
285         my $vars = $self->provision(
286             prefix => $path,
287             domain => "SAMBA-TEST",
288             server => $server,
289             password => "localntdc2pass",
290             extra_options => $nt4_dc_options);
291
292         $vars or return undef;
293
294         if (not $self->check_or_start(
295                 env_vars => $vars,
296                 nmbd => "yes",
297                 winbindd => "yes",
298                 smbd => "yes")) {
299                return undef;
300         }
301
302         $vars->{DOMSID} = $vars->{SAMSID};
303         $vars->{DC_SERVER} = $vars->{SERVER};
304         $vars->{DC_SERVER_IP} = $vars->{SERVER_IP};
305         $vars->{DC_SERVER_IPV6} = $vars->{SERVER_IPV6};
306         $vars->{DC_NETBIOSNAME} = $vars->{NETBIOSNAME};
307         $vars->{DC_USERNAME} = $vars->{USERNAME};
308         $vars->{DC_PASSWORD} = $vars->{PASSWORD};
309
310         return $vars;
311 }
312
313 sub setup_nt4_dc_smb1
314 {
315         my ($self, $path) = @_;
316         my $conf = "
317 [global]
318         client min protocol = CORE
319         server min protocol = LANMAN1
320 ";
321         return $self->setup_nt4_dc($path, $conf, "LCLNT4DC2SMB1");
322 }
323
324 sub setup_nt4_dc_smb1_done
325 {
326         my ($self, $path, $dep_env) = @_;
327         return $self->return_alias_env($path, $dep_env);
328 }
329
330 sub setup_nt4_dc_schannel
331 {
332         my ($self, $path) = @_;
333
334         print "PROVISIONING NT4 DC WITH SERVER SCHANNEL ...";
335
336         my $pdc_options = "
337         domain master = yes
338         domain logons = yes
339         lanman auth = yes
340
341         rpc_server:epmapper = external
342         rpc_server:spoolss = external
343         rpc_server:lsarpc = external
344         rpc_server:samr = external
345         rpc_server:netlogon = external
346         rpc_server:register_embedded_np = yes
347
348         rpc_daemon:epmd = fork
349         rpc_daemon:spoolssd = fork
350         rpc_daemon:lsasd = fork
351
352         server schannel = yes
353         # used to reproduce bug #12772
354         server max protocol = SMB2_02
355 ";
356
357         my $vars = $self->provision(
358             prefix => $path,
359             domain => "NT4SCHANNEL",
360             server => "LOCALNT4DC9",
361             password => "localntdc9pass",
362             extra_options => $pdc_options);
363
364         $vars or return undef;
365
366         if (not $self->check_or_start(
367                 env_vars => $vars,
368                 nmbd => "yes",
369                 winbindd => "yes",
370                 smbd => "yes")) {
371                return undef;
372         }
373
374         $vars->{DOMSID} = $vars->{SAMSID};
375         $vars->{DC_SERVER} = $vars->{SERVER};
376         $vars->{DC_SERVER_IP} = $vars->{SERVER_IP};
377         $vars->{DC_SERVER_IPV6} = $vars->{SERVER_IPV6};
378         $vars->{DC_NETBIOSNAME} = $vars->{NETBIOSNAME};
379         $vars->{DC_USERNAME} = $vars->{USERNAME};
380         $vars->{DC_PASSWORD} = $vars->{PASSWORD};
381
382         return $vars;
383 }
384
385 sub setup_nt4_member
386 {
387         my ($self, $prefix, $nt4_dc_vars) = @_;
388         my $count = 0;
389         my $rc;
390
391         print "PROVISIONING MEMBER...";
392
393         my $require_mutexes = "dbwrap_tdb_require_mutexes:* = yes";
394         if ($ENV{SELFTEST_DONT_REQUIRE_TDB_MUTEX_SUPPORT} // '' eq "1") {
395                 $require_mutexes = "";
396         }
397
398         my $member_options = "
399         security = domain
400         dbwrap_tdb_mutexes:* = yes
401         ${require_mutexes}
402 ";
403         my $ret = $self->provision(
404             prefix => $prefix,
405             domain => $nt4_dc_vars->{DOMAIN},
406             server => "LOCALNT4MEMBER3",
407             password => "localnt4member3pass",
408             extra_options => $member_options);
409
410         $ret or return undef;
411
412         my $nmblookup = Samba::bindir_path($self, "nmblookup");
413         do {
414                 print "Waiting for the LOGON SERVER registration ...\n";
415                 $rc = system("$nmblookup $ret->{CONFIGURATION} $ret->{DOMAIN}\#1c");
416                 if ($rc != 0) {
417                         sleep(1);
418                 }
419                 $count++;
420         } while ($rc != 0 && $count < 10);
421         if ($count == 10) {
422                 print "NMBD not reachable after 10 retries\n";
423                 teardown_env($self, $ret);
424                 return 0;
425         }
426
427         my $net = Samba::bindir_path($self, "net");
428         # Add hosts file for name lookups
429         my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
430         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
431         $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
432         $cmd .= "$net rpc join $ret->{CONFIGURATION} $nt4_dc_vars->{DOMAIN} member";
433         $cmd .= " -U$nt4_dc_vars->{USERNAME}\%$nt4_dc_vars->{PASSWORD}";
434
435         if (system($cmd) != 0) {
436             warn("Join failed\n$cmd");
437             return undef;
438         }
439
440         # Add hosts file for name lookups
441         $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
442         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
443         $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
444         $cmd .= "$net $ret->{CONFIGURATION} primarytrust dumpinfo | grep -q 'REDACTED SECRET VALUES'";
445
446         if (system($cmd) != 0) {
447             warn("check failed\n$cmd");
448             return undef;
449         }
450
451         if (not $self->check_or_start(
452                 env_vars => $ret,
453                 nmbd => "yes",
454                 winbindd => "yes",
455                 smbd => "yes")) {
456                return undef;
457         }
458
459         $ret->{DOMSID} = $nt4_dc_vars->{DOMSID};
460         $ret->{DC_SERVER} = $nt4_dc_vars->{SERVER};
461         $ret->{DC_SERVER_IP} = $nt4_dc_vars->{SERVER_IP};
462         $ret->{DC_SERVER_IPV6} = $nt4_dc_vars->{SERVER_IPV6};
463         $ret->{DC_NETBIOSNAME} = $nt4_dc_vars->{NETBIOSNAME};
464         $ret->{DC_USERNAME} = $nt4_dc_vars->{USERNAME};
465         $ret->{DC_PASSWORD} = $nt4_dc_vars->{PASSWORD};
466
467         return $ret;
468 }
469
470 sub setup_clusteredmember
471 {
472         my ($self, $prefix, $nt4_dc_vars) = @_;
473         my $count = 0;
474         my $rc;
475         my @retvals = ();
476         my $ret;
477
478         print "PROVISIONING CLUSTEREDMEMBER...\n";
479
480         my $prefix_abs = abs_path($prefix);
481         mkdir($prefix_abs, 0777);
482
483         my $server_name = "CLUSTEREDMEMBER";
484
485         my $ctdb_data = $self->setup_ctdb($prefix);
486
487         if (not $ctdb_data) {
488                 print "No ctdb data\n";
489                 return undef;
490         }
491
492         print "PROVISIONING CLUSTERED SAMBA...\n";
493
494         my $num_nodes = $ctdb_data->{NUM_NODES};
495         my $nodes = $ctdb_data->{CTDB_NODES};
496
497         # Enable cleanup of earlier nodes if a later node fails
498         $ctdb_data->{SAMBA_NODES} = \@retvals;
499
500         for (my $i = 0; $i < $num_nodes; $i++) {
501                 my $node = $nodes->[$i];
502                 my $socket = $node->{SOCKET_FILE};
503                 my $server_name = $node->{SERVER_NAME};
504                 my $pub_iface = $node->{SOCKET_WRAPPER_DEFAULT_IFACE};
505                 my $node_prefix = $node->{NODE_PREFIX};
506
507                 print "NODE_PREFIX=${node_prefix}\n";
508                 print "SOCKET=${socket}\n";
509
510                 my $require_mutexes = "dbwrap_tdb_require_mutexes:* = yes";
511                 if ($ENV{SELFTEST_DONT_REQUIRE_TDB_MUTEX_SUPPORT} // '' eq "1") {
512                         $require_mutexes = "" ;
513                 }
514
515                 my $member_options = "
516        security = domain
517        server signing = on
518        clustering = yes
519        ctdbd socket = ${socket}
520        dbwrap_tdb_mutexes:* = yes
521        ${require_mutexes}
522 ";
523
524                 my $node_ret = $self->provision(
525                     prefix => "$node_prefix",
526                     domain => $nt4_dc_vars->{DOMAIN},
527                     server => "$server_name",
528                     password => "clustermember8pass",
529                     netbios_name => "CLUSTEREDMEMBER",
530                     share_dir => "${prefix_abs}/shared",
531                     extra_options => $member_options,
532                     no_delete_prefix => 1);
533                 if (not $node_ret) {
534                         print "Provision node $i failed\n";
535                         teardown_env($self, $ctdb_data);
536                         return undef;
537                 }
538
539                 my $nmblookup = Samba::bindir_path($self, "nmblookup");
540                 do {
541                         print "Waiting for the LOGON SERVER registration ...\n";
542                         $rc = system("$nmblookup $node_ret->{CONFIGURATION} " .
543                                      "$node_ret->{DOMAIN}\#1c");
544                         if ($rc != 0) {
545                                 sleep(1);
546                         }
547                         $count++;
548                 } while ($rc != 0 && $count < 10);
549
550                 if ($count == 10) {
551                         print "NMBD not reachable after 10 retries\n";
552                         teardown_env($self, $node_ret);
553                         teardown_env($self, $ctdb_data);
554                         return undef;
555                 }
556
557                 push(@retvals, $node_ret);
558         }
559
560         $ret = {%$ctdb_data, %{$retvals[0]}};
561
562         my $net = Samba::bindir_path($self, "net");
563         my $cmd = "";
564         $cmd .= "UID_WRAPPER_ROOT=1 ";
565         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
566         $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
567         $cmd .= "$net join $ret->{CONFIGURATION} $nt4_dc_vars->{DOMAIN} member";
568         $cmd .= " -U$nt4_dc_vars->{USERNAME}\%$nt4_dc_vars->{PASSWORD}";
569
570         if (system($cmd) != 0) {
571                 warn("Join failed\n$cmd");
572                 teardown_env($self, $ret);
573                 return undef;
574         }
575
576         for (my $i=0; $i<@retvals; $i++) {
577                 my $node_provision = $retvals[$i];
578                 my $ok;
579                 $ok = $self->check_or_start(
580                     env_vars => $node_provision,
581                     winbindd => "yes",
582                     smbd => "yes",
583                     child_cleanup => sub {
584                         map {
585                             my $fh = $_->{STDIN_PIPE};
586                             close($fh) if defined($fh);
587                         } @retvals });
588                 if (not $ok) {
589                         teardown_env($self, $ret);
590                         return undef;
591                 }
592         }
593
594         #
595         # Build a unclist for every share
596         #
597         unless (open(NODES, "<$ret->{CTDB_NODES_FILE}")) {
598                 warn("Unable to open CTDB nodes file");
599                 teardown_env($self, $ret);
600                 return undef;
601         }
602         my @nodes = <NODES>;
603         close(NODES);
604         chomp @nodes;
605
606         my $conffile = $ret->{SERVERCONFFILE};
607         $cmd = "";
608         $cmd .= 'sed -n -e \'s|^\[\(.*\)\]$|\1|p\'';
609         $cmd .= " \"$conffile\"";
610         $cmd .= " | grep -vx 'global'";
611
612         my @shares = `$cmd`;
613         $rc = $?;
614         if ($rc != 0) {
615                 warn("Listing shares failed\n$cmd");
616                 teardown_env($self, $ret);
617                 return undef;
618         }
619         chomp @shares;
620
621         my $unclistdir = "${prefix_abs}/unclists";
622         mkdir($unclistdir, 0777);
623         foreach my $share (@shares) {
624                 my $l = "${unclistdir}/${share}.txt";
625                 unless (open(UNCLIST, ">${l}")) {
626                         warn("Unable to open UNC list ${l}");
627                         teardown_env($self, $ret);
628                         return undef;
629                 }
630                 foreach my $node (@nodes) {
631                         print UNCLIST "//${node}/${share}\n";
632                 }
633                 close(UNCLIST);
634         }
635
636         $ret->{DOMSID} = $nt4_dc_vars->{DOMSID};
637         $ret->{DC_SERVER} = $nt4_dc_vars->{SERVER};
638         $ret->{DC_SERVER_IP} = $nt4_dc_vars->{SERVER_IP};
639         $ret->{DC_SERVER_IPV6} = $nt4_dc_vars->{SERVER_IPV6};
640         $ret->{DC_NETBIOSNAME} = $nt4_dc_vars->{NETBIOSNAME};
641         $ret->{DC_USERNAME} = $nt4_dc_vars->{USERNAME};
642         $ret->{DC_PASSWORD} = $nt4_dc_vars->{PASSWORD};
643
644         return $ret;
645 }
646
647 sub provision_ad_member
648 {
649         my ($self,
650             $prefix,
651             $machine_account,
652             $dcvars,
653             $trustvars_f,
654             $trustvars_e,
655             $force_fips_mode,
656             $offline_logon) = @_;
657
658         my $prefix_abs = abs_path($prefix);
659         my @dirs = ();
660
661         mkdir($prefix_abs, 0777);
662
663         my $share_dir="$prefix_abs/share";
664         push(@dirs, $share_dir);
665
666         my $substitution_path = "$share_dir/D_$dcvars->{DOMAIN}";
667         push(@dirs, $substitution_path);
668
669         $substitution_path = "$share_dir/D_$dcvars->{DOMAIN}/U_alice";
670         push(@dirs, $substitution_path);
671
672         $substitution_path = "$share_dir/D_$dcvars->{DOMAIN}/U_alice/G_domain users";
673         push(@dirs, $substitution_path);
674
675         # Using '/' as the winbind separator is a bad idea ...
676         $substitution_path = "$share_dir/D_$dcvars->{DOMAIN}/u_$dcvars->{DOMAIN}";
677         push(@dirs, $substitution_path);
678
679         $substitution_path = "$share_dir/D_$dcvars->{DOMAIN}/u_$dcvars->{DOMAIN}/alice";
680         push(@dirs, $substitution_path);
681
682         $substitution_path = "$share_dir/D_$dcvars->{DOMAIN}/u_$dcvars->{DOMAIN}/alice/g_$dcvars->{DOMAIN}";
683         push(@dirs, $substitution_path);
684
685         $substitution_path = "$share_dir/D_$dcvars->{DOMAIN}/u_$dcvars->{DOMAIN}/alice/g_$dcvars->{DOMAIN}/domain users";
686         push(@dirs, $substitution_path);
687
688         my $option_offline_logon = "no";
689         if (defined($offline_logon)) {
690                 $option_offline_logon = "yes";
691         }
692
693         my $netbios_aliases = "";
694         if ($machine_account eq "LOCALADMEMBER") {
695                 $netbios_aliases = "netbios aliases = foo bar";
696         }
697
698         my $member_options = "
699         security = ads
700         workgroup = $dcvars->{DOMAIN}
701         realm = $dcvars->{REALM}
702         $netbios_aliases
703         template homedir = /home/%D/%G/%U
704         auth event notification = true
705         password server = $dcvars->{SERVER}
706         winbind scan trusted domains = no
707         winbind offline logon = $option_offline_logon
708
709         allow dcerpc auth level connect:lsarpc = yes
710         dcesrv:max auth states = 8
711
712         rpc_server:epmapper = external
713         rpc_server:lsarpc = external
714         rpc_server:samr = external
715         rpc_server:netlogon = disabled
716         rpc_server:register_embedded_np = yes
717
718         rpc_daemon:epmd = fork
719         rpc_daemon:lsasd = fork
720
721 [sub_dug]
722         path = $share_dir/D_%D/U_%U/G_%G
723         writeable = yes
724
725 [sub_dug2]
726         path = $share_dir/D_%D/u_%u/g_%g
727         writeable = yes
728
729 [sub_valid_users]
730         path = $share_dir
731         valid users = ADDOMAIN/%U
732
733 [sub_valid_users_domain]
734     path = $share_dir
735     valid users = %D/%U
736
737 [sub_valid_users_group]
738     path = $share_dir
739     valid users = \@$dcvars->{DOMAIN}/%G
740
741 [valid_users]
742     path = $share_dir
743     valid users = $dcvars->{DOMAIN}/$dcvars->{DC_USERNAME}
744
745 [valid_users_group]
746     path = $share_dir
747     valid users = \"\@$dcvars->{DOMAIN}/domain users\"
748
749 [valid_users_unix_group]
750     path = $share_dir
751     valid users = \"+$dcvars->{DOMAIN}/domain users\"
752
753 [valid_users_unix_nis_group]
754     path = $share_dir
755     valid users = \"+&$dcvars->{DOMAIN}/domain users\"
756
757 [valid_users_nis_unix_group]
758     path = $share_dir
759     valid users = \"&+$dcvars->{DOMAIN}/domain users\"
760
761 [invalid_users]
762     path = $share_dir
763     invalid users = $dcvars->{DOMAIN}/$dcvars->{DC_USERNAME}
764
765 [valid_and_invalid_users]
766     path = $share_dir
767     valid users = $dcvars->{DOMAIN}/$dcvars->{DC_USERNAME} $dcvars->{DOMAIN}/alice
768     invalid users = $dcvars->{DOMAIN}/$dcvars->{DC_USERNAME}
769 ";
770
771         my $ret = $self->provision(
772             prefix => $prefix,
773             domain => $dcvars->{DOMAIN},
774             realm => $dcvars->{REALM},
775             server => $machine_account,
776             password => "loCalMemberPass",
777             extra_options => $member_options,
778             resolv_conf => $dcvars->{RESOLV_CONF});
779
780         $ret or return undef;
781
782         mkdir($_, 0777) foreach(@dirs);
783
784         close(USERMAP);
785         $ret->{DOMAIN} = $dcvars->{DOMAIN};
786         $ret->{REALM} = $dcvars->{REALM};
787         $ret->{DOMSID} = $dcvars->{DOMSID};
788
789         my $ctx;
790         $ctx = {};
791         $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
792         $ctx->{domain} = $dcvars->{DOMAIN};
793         $ctx->{realm} = $dcvars->{REALM};
794         $ctx->{dnsname} = lc($dcvars->{REALM});
795         $ctx->{kdc_ipv4} = $dcvars->{SERVER_IP};
796         $ctx->{kdc_ipv6} = $dcvars->{SERVER_IPV6};
797         $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}";
798         Samba::mk_krb5_conf($ctx, "");
799
800         $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
801
802         if (defined($force_fips_mode)) {
803                 $ret->{GNUTLS_FORCE_FIPS_MODE} = "1";
804                 $ret->{OPENSSL_FORCE_FIPS_MODE} = "1";
805         }
806
807         my $net = Samba::bindir_path($self, "net");
808         # Add hosts file for name lookups
809         my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
810         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
811         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
812                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
813         } else {
814                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
815         }
816         if (defined($force_fips_mode)) {
817                 $cmd .= "GNUTLS_FORCE_FIPS_MODE=1 ";
818                 $cmd .= "OPENSSL_FORCE_FIPS_MODE=1 ";
819         }
820         $cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
821         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
822         $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
823         $cmd .= "$net join $ret->{CONFIGURATION}";
824         $cmd .= " -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD} --use-kerberos=required";
825
826         if (system($cmd) != 0) {
827             warn("Join failed\n$cmd");
828             return undef;
829         }
830
831         # We need world access to this share, as otherwise the domain
832         # administrator from the AD domain provided by Samba4 can't
833         # access the share for tests.
834         chmod 0777, "$prefix/share";
835
836         if (defined($offline_logon)) {
837                 my $wbinfo = Samba::bindir_path($self, "wbinfo");
838
839                 if (not $self->check_or_start(
840                         env_vars => $ret,
841                         winbindd => "yes")) {
842                         return undef;
843                 }
844
845                 # Fill samlogoncache for alice
846                 $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' ";
847                 $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' ";
848                 $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
849                 $cmd .= "$wbinfo --pam-logon=ADDOMAIN/alice%Secret007";
850                 if (system($cmd) != 0) {
851                         warn("Filling the cache failed\n$cmd");
852                         return undef;
853                 }
854
855                 $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' ";
856                 $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' ";
857                 $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
858                 $cmd .= "$wbinfo --ccache-save=ADDOMAIN/alice%Secret007";
859                 if (system($cmd) != 0) {
860                         warn("Filling the cache failed\n$cmd");
861                         return undef;
862                 }
863
864                 # Fill samlogoncache for bob
865                 $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' ";
866                 $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' ";
867                 $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
868                 $cmd .= "$wbinfo --pam-logon=ADDOMAIN/bob%Secret007";
869                 if (system($cmd) != 0) {
870                         warn("Filling the cache failed\n$cmd");
871                         return undef;
872                 }
873
874                 $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' ";
875                 $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' ";
876                 $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
877                 $cmd .= "$wbinfo --ccache-save=ADDOMAIN/bob%Secret007";
878                 if (system($cmd) != 0) {
879                         warn("Filling the cache failed\n$cmd");
880                         return undef;
881                 }
882
883                 # Set windindd offline
884                 my $smbcontrol = Samba::bindir_path($self, "smbcontrol");
885                 $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' ";
886                 $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' ";
887                 $cmd .= "UID_WRAPPER_ROOT='1' ";
888                 $cmd .= "$smbcontrol $ret->{CONFIGURATION} winbindd offline";
889                 if (system($cmd) != 0) {
890                         warn("Setting winbindd offline failed\n$cmd");
891                         return undef;
892                 }
893
894                 # Validate the offline cache
895                 $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' ";
896                 $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' ";
897                 $cmd .= "UID_WRAPPER_ROOT='1' ";
898                 $cmd .= "$smbcontrol $ret->{CONFIGURATION} winbindd validate-cache";
899                 if (system($cmd) != 0) {
900                         warn("Validation of winbind credential cache failed\n$cmd");
901                         teardown_env($self, $ret);
902                         return undef;
903                 }
904
905                 # Shut down winbindd
906                 teardown_env($self, $ret);
907
908                 ### Change SOCKET_WRAPPER_DIR so it can't connect to AD
909                 my $swrap_env = $ENV{SOCKET_WRAPPER_DIR};
910                 $ENV{SOCKET_WRAPPER_DIR} = "$prefix_abs";
911
912                 # Start winbindd in offline mode
913                 if (not $self->check_or_start(
914                         env_vars => $ret,
915                         winbindd => "yes",
916                         skip_wait => 1)) {
917                         return undef;
918                 }
919
920                 # Set socket dir again
921                 $ENV{SOCKET_WRAPPER_DIR} = $swrap_env;
922
923                 print "checking for winbindd\n";
924                 my $count = 0;
925                 my $rc = 0;
926                 $cmd = "NSS_WRAPPER_PASSWD='$ret->{NSS_WRAPPER_PASSWD}' ";
927                 $cmd .= "NSS_WRAPPER_GROUP='$ret->{NSS_WRAPPER_GROUP}' ";
928                 $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
929                 $cmd .= "$wbinfo --ping";
930
931                 do {
932                         $rc = system($cmd);
933                         if ($rc != 0) {
934                                 sleep(1);
935                         }
936                         $count++;
937                 } while ($rc != 0 && $count < 20);
938                 if ($count == 20) {
939                         print "WINBINDD not reachable after 20 seconds\n";
940                         teardown_env($self, $ret);
941                         return undef;
942                 }
943         } else {
944                 if (not $self->check_or_start(
945                         env_vars => $ret,
946                         nmbd => "yes",
947                         winbindd => "yes",
948                         smbd => "yes")) {
949                         return undef;
950                 }
951         }
952
953         $ret->{DC_SERVER} = $dcvars->{SERVER};
954         $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP};
955         $ret->{DC_SERVER_IPV6} = $dcvars->{SERVER_IPV6};
956         $ret->{DC_SERVERCONFFILE} = $dcvars->{SERVERCONFFILE};
957         $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME};
958         $ret->{DC_USERNAME} = $dcvars->{USERNAME};
959         $ret->{DC_PASSWORD} = $dcvars->{PASSWORD};
960
961         # forest trust
962         $ret->{TRUST_F_BOTH_SERVER} = $trustvars_f->{SERVER};
963         $ret->{TRUST_F_BOTH_SERVER_IP} = $trustvars_f->{SERVER_IP};
964         $ret->{TRUST_F_BOTH_SERVER_IPV6} = $trustvars_f->{SERVER_IPV6};
965         $ret->{TRUST_F_BOTH_NETBIOSNAME} = $trustvars_f->{NETBIOSNAME};
966         $ret->{TRUST_F_BOTH_USERNAME} = $trustvars_f->{USERNAME};
967         $ret->{TRUST_F_BOTH_PASSWORD} = $trustvars_f->{PASSWORD};
968         $ret->{TRUST_F_BOTH_DOMAIN} = $trustvars_f->{DOMAIN};
969         $ret->{TRUST_F_BOTH_REALM} = $trustvars_f->{REALM};
970
971         # external trust
972         $ret->{TRUST_E_BOTH_SERVER} = $trustvars_e->{SERVER};
973         $ret->{TRUST_E_BOTH_SERVER_IP} = $trustvars_e->{SERVER_IP};
974         $ret->{TRUST_E_BOTH_SERVER_IPV6} = $trustvars_e->{SERVER_IPV6};
975         $ret->{TRUST_E_BOTH_NETBIOSNAME} = $trustvars_e->{NETBIOSNAME};
976         $ret->{TRUST_E_BOTH_USERNAME} = $trustvars_e->{USERNAME};
977         $ret->{TRUST_E_BOTH_PASSWORD} = $trustvars_e->{PASSWORD};
978         $ret->{TRUST_E_BOTH_DOMAIN} = $trustvars_e->{DOMAIN};
979         $ret->{TRUST_E_BOTH_REALM} = $trustvars_e->{REALM};
980
981         return $ret;
982 }
983
984 sub setup_ad_member
985 {
986         my ($self,
987             $prefix,
988             $dcvars,
989             $trustvars_f,
990             $trustvars_e) = @_;
991
992         # If we didn't build with ADS, pretend this env was never available
993         if (not $self->have_ads()) {
994                 return "UNKNOWN";
995         }
996
997         print "PROVISIONING AD MEMBER...";
998
999         return $self->provision_ad_member($prefix,
1000                                           "LOCALADMEMBER",
1001                                           $dcvars,
1002                                           $trustvars_f,
1003                                           $trustvars_e);
1004 }
1005
1006 sub setup_ad_member_rfc2307
1007 {
1008         my ($self, $prefix, $dcvars) = @_;
1009
1010         # If we didn't build with ADS, pretend this env was never available
1011         if (not $self->have_ads()) {
1012                 return "UNKNOWN";
1013         }
1014
1015         print "PROVISIONING S3 AD MEMBER WITH idmap_rfc2307 config...";
1016
1017         my $member_options = "
1018         security = ads
1019         workgroup = $dcvars->{DOMAIN}
1020         realm = $dcvars->{REALM}
1021         idmap cache time = 0
1022         idmap negative cache time = 0
1023         idmap config * : backend = autorid
1024         idmap config * : range = 1000000-1999999
1025         idmap config * : rangesize = 100000
1026         idmap config $dcvars->{DOMAIN} : backend = rfc2307
1027         idmap config $dcvars->{DOMAIN} : range = 2000000-2999999
1028         idmap config $dcvars->{DOMAIN} : ldap_server = ad
1029         idmap config $dcvars->{DOMAIN} : bind_path_user = ou=idmap,dc=samba,dc=example,dc=com
1030         idmap config $dcvars->{DOMAIN} : bind_path_group = ou=idmap,dc=samba,dc=example,dc=com
1031
1032         password server = $dcvars->{SERVER}
1033 ";
1034
1035         my $ret = $self->provision(
1036             prefix => $prefix,
1037             domain => $dcvars->{DOMAIN},
1038             realm => $dcvars->{REALM},
1039             server => "RFC2307MEMBER",
1040             password => "loCalMemberPass",
1041             extra_options => $member_options,
1042             resolv_conf => $dcvars->{RESOLV_CONF});
1043
1044         $ret or return undef;
1045
1046         close(USERMAP);
1047         $ret->{DOMAIN} = $dcvars->{DOMAIN};
1048         $ret->{REALM} = $dcvars->{REALM};
1049         $ret->{DOMSID} = $dcvars->{DOMSID};
1050
1051         my $ctx;
1052         my $prefix_abs = abs_path($prefix);
1053         $ctx = {};
1054         $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
1055         $ctx->{domain} = $dcvars->{DOMAIN};
1056         $ctx->{realm} = $dcvars->{REALM};
1057         $ctx->{dnsname} = lc($dcvars->{REALM});
1058         $ctx->{kdc_ipv4} = $dcvars->{SERVER_IP};
1059         $ctx->{kdc_ipv6} = $dcvars->{SERVER_IPV6};
1060         $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}";
1061         Samba::mk_krb5_conf($ctx, "");
1062
1063         $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
1064
1065         my $net = Samba::bindir_path($self, "net");
1066         # Add hosts file for name lookups
1067         my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1068         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1069         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1070                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1071         } else {
1072                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1073         }
1074         $cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
1075         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1076         $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
1077         $cmd .= "$net join $ret->{CONFIGURATION}";
1078         $cmd .= " -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD}";
1079
1080         if (system($cmd) != 0) {
1081             warn("Join failed\n$cmd");
1082             return undef;
1083         }
1084
1085         # We need world access to this share, as otherwise the domain
1086         # administrator from the AD domain provided by Samba4 can't
1087         # access the share for tests.
1088         chmod 0777, "$prefix/share";
1089
1090         if (not $self->check_or_start(
1091                 env_vars => $ret,
1092                 nmbd => "yes",
1093                 winbindd => "yes",
1094                 smbd => "yes")) {
1095                 return undef;
1096         }
1097
1098         $ret->{DC_SERVER} = $dcvars->{SERVER};
1099         $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP};
1100         $ret->{DC_SERVER_IPV6} = $dcvars->{SERVER_IPV6};
1101         $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME};
1102         $ret->{DC_USERNAME} = $dcvars->{USERNAME};
1103         $ret->{DC_PASSWORD} = $dcvars->{PASSWORD};
1104
1105         return $ret;
1106 }
1107
1108 sub setup_ad_member_idmap_rid
1109 {
1110         my ($self, $prefix, $dcvars) = @_;
1111
1112         # If we didn't build with ADS, pretend this env was never available
1113         if (not $self->have_ads()) {
1114                 return "UNKNOWN";
1115         }
1116
1117         print "PROVISIONING S3 AD MEMBER WITH idmap_rid config...";
1118
1119         my $member_options = "
1120         security = ads
1121         workgroup = $dcvars->{DOMAIN}
1122         realm = $dcvars->{REALM}
1123         idmap config * : backend = tdb
1124         idmap config * : range = 1000000-1999999
1125         idmap config $dcvars->{DOMAIN} : backend = rid
1126         idmap config $dcvars->{DOMAIN} : range = 2000000-2999999
1127         # Prevent overridding the provisioned lib/krb5.conf which sets certain
1128         # values required for tests to succeed
1129         create krb5 conf = no
1130         map to guest = bad user
1131 ";
1132
1133         my $ret = $self->provision(
1134             prefix => $prefix,
1135             domain => $dcvars->{DOMAIN},
1136             realm => $dcvars->{REALM},
1137             server => "IDMAPRIDMEMBER",
1138             password => "loCalMemberPass",
1139             extra_options => $member_options,
1140             resolv_conf => $dcvars->{RESOLV_CONF});
1141
1142         $ret or return undef;
1143
1144         close(USERMAP);
1145         $ret->{DOMAIN} = $dcvars->{DOMAIN};
1146         $ret->{REALM} = $dcvars->{REALM};
1147         $ret->{DOMSID} = $dcvars->{DOMSID};
1148
1149         my $ctx;
1150         my $prefix_abs = abs_path($prefix);
1151         $ctx = {};
1152         $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
1153         $ctx->{domain} = $dcvars->{DOMAIN};
1154         $ctx->{realm} = $dcvars->{REALM};
1155         $ctx->{dnsname} = lc($dcvars->{REALM});
1156         $ctx->{kdc_ipv4} = $dcvars->{SERVER_IP};
1157         $ctx->{kdc_ipv6} = $dcvars->{SERVER_IPV6};
1158         $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}";
1159         Samba::mk_krb5_conf($ctx, "");
1160
1161         $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
1162
1163         my $net = Samba::bindir_path($self, "net");
1164         # Add hosts file for name lookups
1165         my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1166         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1167         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1168                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1169         } else {
1170                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1171         }
1172         $cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
1173         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1174         $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
1175         $cmd .= "$net join $ret->{CONFIGURATION}";
1176         $cmd .= " -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD}";
1177
1178         if (system($cmd) != 0) {
1179             warn("Join failed\n$cmd");
1180             return undef;
1181         }
1182
1183         # We need world access to this share, as otherwise the domain
1184         # administrator from the AD domain provided by Samba4 can't
1185         # access the share for tests.
1186         chmod 0777, "$prefix/share";
1187
1188         if (not $self->check_or_start(
1189                 env_vars => $ret,
1190                 nmbd => "yes",
1191                 winbindd => "yes",
1192                 smbd => "yes")) {
1193                 return undef;
1194         }
1195
1196         $ret->{DC_SERVER} = $dcvars->{SERVER};
1197         $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP};
1198         $ret->{DC_SERVER_IPV6} = $dcvars->{SERVER_IPV6};
1199         $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME};
1200         $ret->{DC_USERNAME} = $dcvars->{USERNAME};
1201         $ret->{DC_PASSWORD} = $dcvars->{PASSWORD};
1202
1203         return $ret;
1204 }
1205
1206 sub setup_ad_member_idmap_ad
1207 {
1208         my ($self, $prefix, $dcvars) = @_;
1209
1210         # If we didn't build with ADS, pretend this env was never available
1211         if (not $self->have_ads()) {
1212                 return "UNKNOWN";
1213         }
1214
1215         print "PROVISIONING S3 AD MEMBER WITH idmap_ad config...";
1216
1217         my $member_options = "
1218         security = ads
1219         workgroup = $dcvars->{DOMAIN}
1220         realm = $dcvars->{REALM}
1221         password server = $dcvars->{SERVER}
1222         idmap config * : backend = tdb
1223         idmap config * : range = 1000000-1999999
1224         idmap config $dcvars->{DOMAIN} : backend = ad
1225         idmap config $dcvars->{DOMAIN} : range = 2000000-2999999
1226         idmap config $dcvars->{DOMAIN} : unix_primary_group = yes
1227         idmap config $dcvars->{DOMAIN} : unix_nss_info = yes
1228         idmap config $dcvars->{TRUST_DOMAIN} : backend = ad
1229         idmap config $dcvars->{TRUST_DOMAIN} : range = 2000000-2999999
1230         gensec_gssapi:requested_life_time = 5
1231 ";
1232
1233         my $ret = $self->provision(
1234             prefix => $prefix,
1235             domain => $dcvars->{DOMAIN},
1236             realm => $dcvars->{REALM},
1237             server => "IDMAPADMEMBER",
1238             password => "loCalMemberPass",
1239             extra_options => $member_options,
1240             resolv_conf => $dcvars->{RESOLV_CONF});
1241
1242         $ret or return undef;
1243
1244         close(USERMAP);
1245         $ret->{DOMAIN} = $dcvars->{DOMAIN};
1246         $ret->{REALM} = $dcvars->{REALM};
1247         $ret->{DOMSID} = $dcvars->{DOMSID};
1248
1249         my $ctx;
1250         my $prefix_abs = abs_path($prefix);
1251         $ctx = {};
1252         $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
1253         $ctx->{domain} = $dcvars->{DOMAIN};
1254         $ctx->{realm} = $dcvars->{REALM};
1255         $ctx->{dnsname} = lc($dcvars->{REALM});
1256         $ctx->{kdc_ipv4} = $dcvars->{SERVER_IP};
1257         $ctx->{kdc_ipv6} = $dcvars->{SERVER_IPV6};
1258         $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}";
1259         Samba::mk_krb5_conf($ctx, "");
1260
1261         $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
1262
1263         my $net = Samba::bindir_path($self, "net");
1264         # Add hosts file for name lookups
1265         my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1266         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1267         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1268                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1269         } else {
1270                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1271         }
1272         $cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
1273         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1274         $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
1275         $cmd .= "$net join $ret->{CONFIGURATION}";
1276         $cmd .= " -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD}";
1277
1278         if (system($cmd) != 0) {
1279             warn("Join failed\n$cmd");
1280             return undef;
1281         }
1282
1283         # We need world access to this share, as otherwise the domain
1284         # administrator from the AD domain provided by Samba4 can't
1285         # access the share for tests.
1286         chmod 0777, "$prefix/share";
1287
1288         if (not $self->check_or_start(
1289                 env_vars => $ret,
1290                 nmbd => "yes",
1291                 winbindd => "yes",
1292                 smbd => "yes")) {
1293                 return undef;
1294         }
1295
1296         $ret->{DC_SERVER} = $dcvars->{SERVER};
1297         $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP};
1298         $ret->{DC_SERVER_IPV6} = $dcvars->{SERVER_IPV6};
1299         $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME};
1300         $ret->{DC_USERNAME} = $dcvars->{USERNAME};
1301         $ret->{DC_PASSWORD} = $dcvars->{PASSWORD};
1302
1303         $ret->{TRUST_SERVER} = $dcvars->{TRUST_SERVER};
1304         $ret->{TRUST_USERNAME} = $dcvars->{TRUST_USERNAME};
1305         $ret->{TRUST_PASSWORD} = $dcvars->{TRUST_PASSWORD};
1306         $ret->{TRUST_DOMAIN} = $dcvars->{TRUST_DOMAIN};
1307         $ret->{TRUST_REALM} = $dcvars->{TRUST_REALM};
1308         $ret->{TRUST_DOMSID} = $dcvars->{TRUST_DOMSID};
1309
1310         return $ret;
1311 }
1312
1313 sub setup_ad_member_oneway
1314 {
1315         my ($self, $prefix, $dcvars) = @_;
1316
1317         # If we didn't build with ADS, pretend this env was never available
1318         if (not $self->have_ads()) {
1319                 return "UNKNOWN";
1320         }
1321
1322         print "PROVISIONING S3 AD MEMBER WITH one-way trust...";
1323
1324         my $member_options = "
1325         security = ads
1326         workgroup = $dcvars->{DOMAIN}
1327         realm = $dcvars->{REALM}
1328         password server = $dcvars->{SERVER}
1329         idmap config * : backend = tdb
1330         idmap config * : range = 1000000-1999999
1331         gensec_gssapi:requested_life_time = 5
1332 ";
1333
1334         my $ret = $self->provision(
1335             prefix => $prefix,
1336             domain => $dcvars->{DOMAIN},
1337             server => "S2KMEMBER",
1338             password => "loCalS2KMemberPass",
1339             extra_options => $member_options,
1340             resolv_conf => $dcvars->{RESOLV_CONF});
1341
1342         $ret or return undef;
1343
1344         close(USERMAP);
1345         $ret->{DOMAIN} = $dcvars->{DOMAIN};
1346         $ret->{REALM} = $dcvars->{REALM};
1347         $ret->{DOMSID} = $dcvars->{DOMSID};
1348
1349         my $ctx;
1350         my $prefix_abs = abs_path($prefix);
1351         $ctx = {};
1352         $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
1353         $ctx->{domain} = $dcvars->{DOMAIN};
1354         $ctx->{realm} = $dcvars->{REALM};
1355         $ctx->{dnsname} = lc($dcvars->{REALM});
1356         $ctx->{kdc_ipv4} = $dcvars->{SERVER_IP};
1357         $ctx->{kdc_ipv6} = $dcvars->{SERVER_IPV6};
1358         $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}";
1359         Samba::mk_krb5_conf($ctx, "");
1360
1361         $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
1362
1363         my $net = Samba::bindir_path($self, "net");
1364         # Add hosts file for name lookups
1365         my $cmd = "NSS_WRAPPER_HOSTS='$ret->{NSS_WRAPPER_HOSTS}' ";
1366         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
1367         if (defined($ret->{RESOLV_WRAPPER_CONF})) {
1368                 $cmd .= "RESOLV_WRAPPER_CONF=\"$ret->{RESOLV_WRAPPER_CONF}\" ";
1369         } else {
1370                 $cmd .= "RESOLV_WRAPPER_HOSTS=\"$ret->{RESOLV_WRAPPER_HOSTS}\" ";
1371         }
1372         $cmd .= "RESOLV_CONF=\"$ret->{RESOLV_CONF}\" ";
1373         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
1374         $cmd .= "SELFTEST_WINBINDD_SOCKET_DIR=\"$ret->{SELFTEST_WINBINDD_SOCKET_DIR}\" ";
1375         $cmd .= "$net join $ret->{CONFIGURATION}";
1376         $cmd .= " -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD}";
1377
1378         if (system($cmd) != 0) {
1379             warn("Join failed\n$cmd");
1380             return undef;
1381         }
1382
1383         if (not $self->check_or_start(
1384                 env_vars => $ret,
1385                 winbindd => "yes")) {
1386                 return undef;
1387         }
1388
1389         $ret->{DC_SERVER} = $dcvars->{SERVER};
1390         $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP};
1391         $ret->{DC_SERVER_IPV6} = $dcvars->{SERVER_IPV6};
1392         $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME};
1393         $ret->{DC_USERNAME} = $dcvars->{USERNAME};
1394         $ret->{DC_PASSWORD} = $dcvars->{PASSWORD};
1395
1396         $ret->{TRUST_SERVER} = $dcvars->{TRUST_SERVER};
1397         $ret->{TRUST_USERNAME} = $dcvars->{TRUST_USERNAME};
1398         $ret->{TRUST_PASSWORD} = $dcvars->{TRUST_PASSWORD};
1399         $ret->{TRUST_DOMAIN} = $dcvars->{TRUST_DOMAIN};
1400         $ret->{TRUST_REALM} = $dcvars->{TRUST_REALM};
1401         $ret->{TRUST_DOMSID} = $dcvars->{TRUST_DOMSID};
1402
1403         return $ret;
1404 }
1405
1406 sub setup_ad_member_fips
1407 {
1408         my ($self,
1409             $prefix,
1410             $dcvars,
1411             $trustvars_f,
1412             $trustvars_e) = @_;
1413
1414         # If we didn't build with ADS, pretend this env was never available
1415         if (not $self->have_ads()) {
1416                 return "UNKNOWN";
1417         }
1418
1419         print "PROVISIONING AD FIPS MEMBER...";
1420
1421         return $self->provision_ad_member($prefix,
1422                                           "FIPSADMEMBER",
1423                                           $dcvars,
1424                                           $trustvars_f,
1425                                           $trustvars_e,
1426                                           1);
1427 }
1428
1429 sub setup_ad_member_offlogon
1430 {
1431         my ($self,
1432             $prefix,
1433             $dcvars,
1434             $trustvars_f,
1435             $trustvars_e) = @_;
1436
1437         # If we didn't build with ADS, pretend this env was never available
1438         if (not $self->have_ads()) {
1439                 return "UNKNOWN";
1440         }
1441
1442         print "PROVISIONING AD MEMBER OFFLINE LOGON...";
1443
1444         return $self->provision_ad_member($prefix,
1445                                           "OFFLINEADMEM",
1446                                           $dcvars,
1447                                           $trustvars_f,
1448                                           $trustvars_e,
1449                                           undef,
1450                                           1);
1451 }
1452
1453 sub setup_simpleserver
1454 {
1455         my ($self, $path) = @_;
1456
1457         print "PROVISIONING simple server...";
1458
1459         my $prefix_abs = abs_path($path);
1460
1461         my $simpleserver_options = "
1462         lanman auth = yes
1463         ntlm auth = yes
1464         vfs objects = xattr_tdb streams_depot
1465         change notify = no
1466         server smb encrypt = off
1467
1468 [vfs_aio_pthread]
1469         path = $prefix_abs/share
1470         read only = no
1471         vfs objects = aio_pthread
1472         aio_pthread:aio open = yes
1473         smbd async dosmode = no
1474
1475 [vfs_aio_pthread_async_dosmode_default1]
1476         path = $prefix_abs/share
1477         read only = no
1478         vfs objects = aio_pthread
1479         store dos attributes = yes
1480         aio_pthread:aio open = yes
1481         smbd async dosmode = yes
1482
1483 [vfs_aio_pthread_async_dosmode_default2]
1484         path = $prefix_abs/share
1485         read only = no
1486         vfs objects = aio_pthread xattr_tdb
1487         store dos attributes = yes
1488         aio_pthread:aio open = yes
1489         smbd async dosmode = yes
1490
1491 [vfs_aio_pthread_async_dosmode_force_sync1]
1492         path = $prefix_abs/share
1493         read only = no
1494         vfs objects = aio_pthread
1495         store dos attributes = yes
1496         aio_pthread:aio open = yes
1497         smbd async dosmode = yes
1498         # This simulates non linux systems
1499         smbd:force sync user path safe threadpool = yes
1500         smbd:force sync user chdir safe threadpool = yes
1501         smbd:force sync root path safe threadpool = yes
1502         smbd:force sync root chdir safe threadpool = yes
1503
1504 [vfs_aio_pthread_async_dosmode_force_sync2]
1505         path = $prefix_abs/share
1506         read only = no
1507         vfs objects = aio_pthread xattr_tdb
1508         store dos attributes = yes
1509         aio_pthread:aio open = yes
1510         smbd async dosmode = yes
1511         # This simulates non linux systems
1512         smbd:force sync user path safe threadpool = yes
1513         smbd:force sync user chdir safe threadpool = yes
1514         smbd:force sync root path safe threadpool = yes
1515         smbd:force sync root chdir safe threadpool = yes
1516
1517 [vfs_aio_fork]
1518         path = $prefix_abs/share
1519         vfs objects = aio_fork
1520         read only = no
1521         vfs_aio_fork:erratic_testing_mode=yes
1522
1523 [dosmode]
1524         path = $prefix_abs/share
1525         vfs objects =
1526         store dos attributes = yes
1527         hide files = /hidefile/
1528         hide dot files = yes
1529
1530 [hidenewfiles]
1531         path = $prefix_abs/share
1532         hide new files timeout = 5
1533 ";
1534
1535         my $vars = $self->provision(
1536             prefix => $path,
1537             domain => "WORKGROUP",
1538             server => "LOCALSHARE4",
1539             password => "local4pass",
1540             extra_options => $simpleserver_options);
1541
1542         $vars or return undef;
1543
1544         if (not $self->check_or_start(
1545                 env_vars => $vars,
1546                 nmbd => "yes",
1547                 smbd => "yes")) {
1548                return undef;
1549         }
1550
1551         return $vars;
1552 }
1553
1554 sub create_file_chmod($$)
1555 {
1556     my ($name, $mode) = @_;
1557     my $fh;
1558
1559     unless (open($fh, '>', $name)) {
1560         warn("Unable to open $name");
1561         return undef;
1562     }
1563     chmod($mode, $fh);
1564 }
1565
1566 sub setup_fileserver
1567 {
1568         my ($self, $path, $more_conf, $server) = @_;
1569         my $prefix_abs = abs_path($path);
1570         my $srcdir_abs = abs_path($self->{srcdir});
1571
1572         print "PROVISIONING file server ...\n";
1573
1574         my @dirs = ();
1575
1576         mkdir($prefix_abs, 0777);
1577
1578         my $usershare_dir="$prefix_abs/lib/usershare";
1579
1580         mkdir("$prefix_abs/lib", 0755);
1581         remove_tree($usershare_dir);
1582         mkdir($usershare_dir, 01770);
1583
1584         my $share_dir="$prefix_abs/share";
1585
1586         # Create share directory structure
1587         my $lower_case_share_dir="$share_dir/lower-case";
1588         push(@dirs, $lower_case_share_dir);
1589
1590         my $lower_case_share_dir_30000="$share_dir/lower-case-30000";
1591         push(@dirs, $lower_case_share_dir_30000);
1592
1593         my $dfree_share_dir="$share_dir/dfree";
1594         push(@dirs, $dfree_share_dir);
1595         push(@dirs, "$dfree_share_dir/subdir1");
1596         push(@dirs, "$dfree_share_dir/subdir2");
1597         push(@dirs, "$dfree_share_dir/subdir3");
1598
1599         my $quotadir_dir="$share_dir/quota";
1600         push(@dirs, $quotadir_dir);
1601
1602         my $valid_users_sharedir="$share_dir/valid_users";
1603         push(@dirs,$valid_users_sharedir);
1604
1605         my $offline_sharedir="$share_dir/offline";
1606         push(@dirs,$offline_sharedir);
1607
1608         my $force_user_valid_users_dir = "$share_dir/force_user_valid_users";
1609         push(@dirs, $force_user_valid_users_dir);
1610
1611         my $smbget_sharedir="$share_dir/smbget";
1612         push(@dirs,$smbget_sharedir);
1613
1614         my $tarmode_sharedir="$share_dir/tarmode";
1615         push(@dirs,$tarmode_sharedir);
1616
1617         my $tarmode2_sharedir="$share_dir/tarmode2";
1618         push(@dirs,$tarmode2_sharedir);
1619
1620         my $smbcacls_sharedir="$share_dir/smbcacls";
1621         push(@dirs,$smbcacls_sharedir);
1622
1623         my $usershare_sharedir="$share_dir/usershares";
1624         push(@dirs,$usershare_sharedir);
1625
1626         my $dropbox_sharedir="$share_dir/dropbox";
1627         push(@dirs,$dropbox_sharedir);
1628
1629         my $bad_iconv_sharedir="$share_dir/bad_iconv";
1630         push(@dirs, $bad_iconv_sharedir);
1631
1632         my $ip4 = Samba::get_ipv4_addr("FILESERVER");
1633         my $fileserver_options = "
1634         kernel change notify = yes
1635         rpc_server:mdssvc = embedded
1636         spotlight backend = elasticsearch
1637         elasticsearch:address = $ip4
1638         elasticsearch:port = 8080
1639         elasticsearch:mappings = $srcdir_abs/source3/rpc_server/mdssvc/elasticsearch_mappings.json
1640
1641         usershare path = $usershare_dir
1642         usershare max shares = 10
1643         usershare allow guests = yes
1644         usershare prefix allow list = $usershare_sharedir
1645
1646         get quota command = $prefix_abs/getset_quota.py
1647         set quota command = $prefix_abs/getset_quota.py
1648 [tarmode]
1649         path = $tarmode_sharedir
1650         comment = tar test share
1651         xattr_tdb:file = $prefix_abs/tarmode-xattr.tdb
1652 [tarmode2]
1653         path = $tarmode2_sharedir
1654         comment = tar test share
1655         xattr_tdb:file = $prefix_abs/tarmode2-xattr.tdb
1656 [spotlight]
1657         path = $share_dir
1658         spotlight = yes
1659         read only = no
1660 [no_spotlight]
1661         path = $share_dir
1662         spotlight = no
1663         read only = no
1664 [lowercase]
1665         path = $lower_case_share_dir
1666         comment = smb username is [%U]
1667         case sensitive = True
1668         default case = lower
1669         preserve case = no
1670         short preserve case = no
1671 [lowercase-30000]
1672         path = $lower_case_share_dir_30000
1673         comment = smb username is [%U]
1674         case sensitive = True
1675         default case = lower
1676         preserve case = no
1677         short preserve case = no
1678 [dfree]
1679         path = $dfree_share_dir
1680         comment = smb username is [%U]
1681         dfree command = $srcdir_abs/testprogs/blackbox/dfree.sh
1682 [valid-users-access]
1683         path = $valid_users_sharedir
1684         valid users = +userdup
1685 [offline]
1686         path = $offline_sharedir
1687         vfs objects = offline
1688
1689 # BUG: https://bugzilla.samba.org/show_bug.cgi?id=9878
1690 # RH BUG: https://bugzilla.redhat.com/show_bug.cgi?id=1077651
1691 [force_user_valid_users]
1692         path = $force_user_valid_users_dir
1693         comment = force user with valid users combination test share
1694         valid users = +force_user
1695         force user = force_user
1696         force group = everyone
1697         write list = force_user
1698
1699 [smbget]
1700         path = $smbget_sharedir
1701         comment = smb username is [%U]
1702         guest ok = yes
1703 [ign_sysacls]
1704         path = $share_dir
1705         comment = ignore system acls
1706         acl_xattr:ignore system acls = yes
1707 [inherit_owner]
1708         path = $share_dir
1709         comment = inherit owner
1710         inherit owner = yes
1711 [inherit_owner_u]
1712         path = $share_dir
1713         comment = inherit only unix owner
1714         inherit owner = unix only
1715         acl_xattr:ignore system acls = yes
1716 # BUG: https://bugzilla.samba.org/show_bug.cgi?id=13690
1717 [force_group_test]
1718         path = $share_dir
1719         comment = force group test
1720 #       force group = everyone
1721
1722 [create_mode_664]
1723         path = $share_dir
1724         comment = smb username is [%U]
1725         create mask = 0644
1726         force create mode = 0664
1727         vfs objects = dirsort
1728
1729 [dropbox]
1730         path = $dropbox_sharedir
1731         comment = smb username is [%U]
1732         writeable = yes
1733         vfs objects =
1734
1735 [bad_iconv]
1736         path = $bad_iconv_sharedir
1737         comment = smb username is [%U]
1738         vfs objects =
1739
1740 [homes]
1741         comment = Home directories
1742         browseable = No
1743         read only = No
1744 ";
1745
1746         if (defined($more_conf)) {
1747                 $fileserver_options = $fileserver_options . $more_conf;
1748         }
1749         if (!defined($server)) {
1750                 $server = "FILESERVER";
1751         }
1752
1753         my $vars = $self->provision(
1754             prefix => $path,
1755             domain => "WORKGROUP",
1756             server => $server,
1757             password => "fileserver",
1758             extra_options => $fileserver_options,
1759             no_delete_prefix => 1);
1760
1761         $vars or return undef;
1762
1763         if (not $self->check_or_start(
1764                 env_vars => $vars,
1765                 nmbd => "yes",
1766                 smbd => "yes")) {
1767                return undef;
1768         }
1769
1770
1771         mkdir($_, 0777) foreach(@dirs);
1772
1773         ## Create case sensitive lower case share dir
1774         foreach my $file ('a'..'z') {
1775                 my $full_path = $lower_case_share_dir . '/' . $file;
1776                 open my $fh, '>', $full_path;
1777                 # Add some content to file
1778                 print $fh $full_path;
1779                 close $fh;
1780         }
1781
1782         for (my $file = 1; $file < 51; ++$file) {
1783                 my $full_path = $lower_case_share_dir . '/' . $file;
1784                 open my $fh, '>', $full_path;
1785                 # Add some content to file
1786                 print $fh $full_path;
1787                 close $fh;
1788         }
1789
1790         # Create content for 30000 share
1791         foreach my $file ('a'..'z') {
1792                 my $full_path = $lower_case_share_dir_30000 . '/' . $file;
1793                 open my $fh, '>', $full_path;
1794                 # Add some content to file
1795                 print $fh $full_path;
1796                 close $fh;
1797         }
1798
1799         for (my $file = 1; $file < 30001; ++$file) {
1800                 my $full_path = $lower_case_share_dir_30000 . '/' . $file;
1801                 open my $fh, '>', $full_path;
1802                 # Add some content to file
1803                 print $fh $full_path;
1804                 close $fh;
1805         }
1806
1807         ##
1808         ## create a listable file in valid_users_share
1809         ##
1810         create_file_chmod("$valid_users_sharedir/foo", 0644) or return undef;
1811
1812         ##
1813         ## create a valid utf8 filename which is invalid as a CP850 conversion
1814         ##
1815         create_file_chmod("$bad_iconv_sharedir/\xED\x9F\xBF", 0644) or return undef;
1816
1817         return $vars;
1818 }
1819
1820 sub setup_fileserver_smb1
1821 {
1822         my ($self, $path) = @_;
1823         my $prefix_abs = abs_path($path);
1824         my $conf = "
1825 [global]
1826         client min protocol = CORE
1827         server min protocol = LANMAN1
1828
1829 [hidenewfiles]
1830         path = $prefix_abs/share
1831         hide new files timeout = 5
1832 [vfs_aio_pthread]
1833         path = $prefix_abs/share
1834         read only = no
1835         vfs objects = aio_pthread
1836         aio_pthread:aio open = yes
1837         smbd async dosmode = no
1838
1839 [vfs_aio_pthread_async_dosmode_default1]
1840         path = $prefix_abs/share
1841         read only = no
1842         vfs objects = aio_pthread
1843         store dos attributes = yes
1844         aio_pthread:aio open = yes
1845         smbd async dosmode = yes
1846
1847 [vfs_aio_pthread_async_dosmode_default2]
1848         path = $prefix_abs/share
1849         read only = no
1850         vfs objects = aio_pthread xattr_tdb
1851         store dos attributes = yes
1852         aio_pthread:aio open = yes
1853         smbd async dosmode = yes
1854
1855 [vfs_aio_pthread_async_dosmode_force_sync1]
1856         path = $prefix_abs/share
1857         read only = no
1858         vfs objects = aio_pthread
1859         store dos attributes = yes
1860         aio_pthread:aio open = yes
1861         smbd async dosmode = yes
1862         # This simulates non linux systems
1863         smbd:force sync user path safe threadpool = yes
1864         smbd:force sync user chdir safe threadpool = yes
1865         smbd:force sync root path safe threadpool = yes
1866         smbd:force sync root chdir safe threadpool = yes
1867
1868 [vfs_aio_pthread_async_dosmode_force_sync2]
1869         path = $prefix_abs/share
1870         read only = no
1871         vfs objects = aio_pthread xattr_tdb
1872         store dos attributes = yes
1873         aio_pthread:aio open = yes
1874         smbd async dosmode = yes
1875         # This simulates non linux systems
1876         smbd:force sync user path safe threadpool = yes
1877         smbd:force sync user chdir safe threadpool = yes
1878         smbd:force sync root path safe threadpool = yes
1879         smbd:force sync root chdir safe threadpool = yes
1880
1881 [vfs_aio_fork]
1882         path = $prefix_abs/share
1883         vfs objects = aio_fork
1884         read only = no
1885         vfs_aio_fork:erratic_testing_mode=yes
1886 ";
1887         return $self->setup_fileserver($path, $conf, "FILESERVERSMB1");
1888 }
1889
1890 sub setup_fileserver_smb1_done
1891 {
1892         my ($self, $path, $dep_env) = @_;
1893         return $self->return_alias_env($path, $dep_env);
1894 }
1895
1896 sub setup_ktest
1897 {
1898         my ($self, $prefix) = @_;
1899
1900         # If we didn't build with ADS, pretend this env was never available
1901         if (not $self->have_ads()) {
1902                 return "UNKNOWN";
1903         }
1904
1905         print "PROVISIONING server with security=ads...";
1906
1907         my $ktest_options = "
1908         workgroup = KTEST
1909         realm = ktest.samba.example.com
1910         security = ads
1911         username map = $prefix/lib/username.map
1912         server signing = required
1913         server min protocol = SMB3_00
1914         client max protocol = SMB3
1915
1916         # This disables NTLM auth against the local SAM, which
1917         # we use can then test this setting by.
1918         ntlm auth = disabled
1919 ";
1920
1921         my $ret = $self->provision(
1922             prefix => $prefix,
1923             domain => "KTEST",
1924             server => "LOCALKTEST6",
1925             password => "localktest6pass",
1926             extra_options => $ktest_options);
1927
1928         $ret or return undef;
1929
1930         my $ctx;
1931         my $prefix_abs = abs_path($prefix);
1932         $ctx = {};
1933         $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
1934         $ctx->{domain} = "KTEST";
1935         $ctx->{realm} = "KTEST.SAMBA.EXAMPLE.COM";
1936         $ctx->{dnsname} = lc($ctx->{realm});
1937         $ctx->{kdc_ipv4} = "0.0.0.0";
1938         $ctx->{kdc_ipv6} = "::";
1939         $ctx->{krb5_ccname} = "$prefix_abs/krb5cc_%{uid}";
1940         Samba::mk_krb5_conf($ctx, "");
1941
1942         $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
1943
1944         open(USERMAP, ">$prefix/lib/username.map") or die("Unable to open $prefix/lib/username.map");
1945         print USERMAP "
1946 $ret->{USERNAME} = KTEST\\Administrator
1947 ";
1948         close(USERMAP);
1949
1950 #This is the secrets.tdb created by 'net ads join' from Samba3 to a
1951 #Samba4 DC with the same parameters as are being used here.  The
1952 #domain SID is S-1-5-21-1071277805-689288055-3486227160
1953         $ret->{SAMSID} = "S-1-5-21-1911091480-1468226576-2729736297";
1954         $ret->{DOMSID} = "S-1-5-21-1071277805-689288055-3486227160";
1955
1956         system("cp $self->{srcdir}/source3/selftest/ktest-secrets.tdb $prefix/private/secrets.tdb");
1957         chmod 0600, "$prefix/private/secrets.tdb";
1958
1959 #Make sure there's no old ntdb file.
1960         system("rm -f $prefix/private/secrets.ntdb");
1961
1962 #This uses a pre-calculated krb5 credentials cache, obtained by running Samba4 with:
1963 # "--option=kdc:service ticket lifetime=239232" "--option=kdc:user ticket lifetime=239232" "--option=kdc:renewal lifetime=239232"
1964 #
1965 #and having in krb5.conf:
1966 # ticket_lifetime = 799718400
1967 # renew_lifetime = 799718400
1968 #
1969 # The commands for the -2 keytab where were:
1970 # kinit administrator@KTEST.SAMBA.EXAMPLE.COM
1971 # kvno host/localktest6@KTEST.SAMBA.EXAMPLE.COM
1972 # kvno cifs/localktest6@KTEST.SAMBA.EXAMPLE.COM
1973 # kvno host/LOCALKTEST6@KTEST.SAMBA.EXAMPLE.COM
1974 # kvno cifs/LOCALKTEST6@KTEST.SAMBA.EXAMPLE.COM
1975 #
1976 # and then for the -3 keytab, I did
1977 #
1978 # net changetrustpw; kdestroy and the same again.
1979 #
1980 # This creates a credential cache with a very long lifetime (2036 at
1981 # at 2011-04), and shows that running 'net changetrustpw' does not
1982 # break existing logins (for the secrets.tdb method at least).
1983 #
1984
1985         $ret->{KRB5_CCACHE}="FILE:$prefix/krb5_ccache";
1986
1987         system("cp $self->{srcdir}/source3/selftest/ktest-krb5_ccache-2 $prefix/krb5_ccache-2");
1988         chmod 0600, "$prefix/krb5_ccache-2";
1989
1990         system("cp $self->{srcdir}/source3/selftest/ktest-krb5_ccache-3 $prefix/krb5_ccache-3");
1991         chmod 0600, "$prefix/krb5_ccache-3";
1992
1993         # We need world access to this share, as otherwise the domain
1994         # administrator from the AD domain provided by ktest can't
1995         # access the share for tests.
1996         chmod 0777, "$prefix/share";
1997
1998         if (not $self->check_or_start(
1999                 env_vars => $ret,
2000                 nmbd => "yes",
2001                 smbd => "yes")) {
2002                return undef;
2003         }
2004         return $ret;
2005 }
2006
2007 sub setup_maptoguest
2008 {
2009         my ($self, $path) = @_;
2010         my $prefix_abs = abs_path($path);
2011         my $libdir="$prefix_abs/lib";
2012         my $share_dir="$prefix_abs/share";
2013         my $errorinjectconf="$libdir/error_inject.conf";
2014
2015         print "PROVISIONING maptoguest...";
2016
2017         my $options = "
2018 map to guest = bad user
2019 ntlm auth = yes
2020
2021 [force_user_error_inject]
2022         path = $share_dir
2023         vfs objects = acl_xattr fake_acls xattr_tdb error_inject
2024         force user = user1
2025         include = $errorinjectconf
2026 ";
2027
2028         my $vars = $self->provision(
2029             prefix => $path,
2030             domain => "WORKGROUP",
2031             server => "maptoguest",
2032             password => "maptoguestpass",
2033             extra_options => $options);
2034
2035         $vars or return undef;
2036
2037         if (not $self->check_or_start(
2038                 env_vars => $vars,
2039                 nmbd => "yes",
2040                 smbd => "yes")) {
2041                return undef;
2042         }
2043
2044         return $vars;
2045 }
2046
2047 sub stop_sig_term($$) {
2048         my ($self, $pid) = @_;
2049         kill("USR1", $pid) or kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
2050 }
2051
2052 sub stop_sig_kill($$) {
2053         my ($self, $pid) = @_;
2054         kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
2055 }
2056
2057 sub write_pid($$$)
2058 {
2059         my ($env_vars, $app, $pid) = @_;
2060
2061         open(PID, ">$env_vars->{PIDDIR}/timelimit.$app.pid");
2062         print PID $pid;
2063         close(PID);
2064 }
2065
2066 sub read_pid($$)
2067 {
2068         my ($env_vars, $app) = @_;
2069
2070         open(PID, "<$env_vars->{PIDDIR}/timelimit.$app.pid");
2071         my $pid = <PID>;
2072         close(PID);
2073         return $pid;
2074 }
2075
2076 # builds up the cmd args to run an s3 binary (i.e. smbd, nmbd, etc)
2077 sub make_bin_cmd
2078 {
2079         my ($self, $binary, $env_vars, $options, $valgrind, $dont_log_stdout) = @_;
2080
2081         my @optargs = ("-d0");
2082         if (defined($options)) {
2083                 @optargs = split(/ /, $options);
2084         }
2085         my @preargs = (Samba::bindir_path($self, "timelimit"), $self->{server_maxtime});
2086
2087         if (defined($valgrind)) {
2088                 @preargs = split(/ /, $valgrind);
2089         }
2090         my @args = ("-F", "--no-process-group",
2091                     "--configfile=$env_vars->{SERVERCONFFILE}",
2092                     "-l", $env_vars->{LOGDIR});
2093
2094         if (not defined($dont_log_stdout)) {
2095                 push(@args, "--debug-stdout");
2096         }
2097         return (@preargs, $binary, @args, @optargs);
2098 }
2099
2100 sub check_or_start($$) {
2101         my ($self, %args) = @_;
2102         my $env_vars = $args{env_vars};
2103         my $nmbd = $args{nmbd} // "no";
2104         my $winbindd = $args{winbindd} // "no";
2105         my $smbd = $args{smbd} // "no";
2106         my $child_cleanup = $args{child_cleanup};
2107         my $skip_wait = $args{skip_wait} // 0;
2108
2109         my $STDIN_READER;
2110
2111         # use a pipe for stdin in the child processes. This allows
2112         # those processes to monitor the pipe for EOF to ensure they
2113         # exit when the test script exits
2114         pipe($STDIN_READER, $env_vars->{STDIN_PIPE});
2115
2116         my $binary = Samba::bindir_path($self, "nmbd");
2117         my @full_cmd = $self->make_bin_cmd($binary, $env_vars,
2118                                            $ENV{NMBD_OPTIONS}, $ENV{NMBD_VALGRIND},
2119                                            $ENV{NMBD_DONT_LOG_STDOUT});
2120         my $nmbd_envs = Samba::get_env_for_process("nmbd", $env_vars);
2121         delete $nmbd_envs->{RESOLV_WRAPPER_CONF};
2122         delete $nmbd_envs->{RESOLV_WRAPPER_HOSTS};
2123
2124         # fork and exec() nmbd in the child process
2125         my $daemon_ctx = {
2126                 NAME => "nmbd",
2127                 BINARY_PATH => $binary,
2128                 FULL_CMD => [ @full_cmd ],
2129                 LOG_FILE => $env_vars->{NMBD_TEST_LOG},
2130                 PCAP_FILE => "env-$ENV{ENVNAME}-nmbd",
2131                 ENV_VARS => $nmbd_envs,
2132         };
2133         if ($nmbd ne "yes") {
2134                 $daemon_ctx->{SKIP_DAEMON} = 1;
2135         }
2136         my $pid = Samba::fork_and_exec(
2137             $self, $env_vars, $daemon_ctx, $STDIN_READER, $child_cleanup);
2138
2139         $env_vars->{NMBD_TL_PID} = $pid;
2140         write_pid($env_vars, "nmbd", $pid);
2141
2142         $binary = Samba::bindir_path($self, "winbindd");
2143         @full_cmd = $self->make_bin_cmd($binary, $env_vars,
2144                                          $ENV{WINBINDD_OPTIONS},
2145                                          $ENV{WINBINDD_VALGRIND},
2146                                          $ENV{WINBINDD_DONT_LOG_STDOUT});
2147
2148         # fork and exec() winbindd in the child process
2149         $daemon_ctx = {
2150                 NAME => "winbindd",
2151                 BINARY_PATH => $binary,
2152                 FULL_CMD => [ @full_cmd ],
2153                 LOG_FILE => $env_vars->{WINBINDD_TEST_LOG},
2154                 PCAP_FILE => "env-$ENV{ENVNAME}-winbindd",
2155         };
2156         if ($winbindd ne "yes") {
2157                 $daemon_ctx->{SKIP_DAEMON} = 1;
2158         }
2159
2160         $pid = Samba::fork_and_exec(
2161             $self, $env_vars, $daemon_ctx, $STDIN_READER, $child_cleanup);
2162
2163         $env_vars->{WINBINDD_TL_PID} = $pid;
2164         write_pid($env_vars, "winbindd", $pid);
2165
2166         $binary = Samba::bindir_path($self, "smbd");
2167         @full_cmd = $self->make_bin_cmd($binary, $env_vars,
2168                                          $ENV{SMBD_OPTIONS}, $ENV{SMBD_VALGRIND},
2169                                          $ENV{SMBD_DONT_LOG_STDOUT});
2170
2171         # fork and exec() smbd in the child process
2172         $daemon_ctx = {
2173                 NAME => "smbd",
2174                 BINARY_PATH => $binary,
2175                 FULL_CMD => [ @full_cmd ],
2176                 LOG_FILE => $env_vars->{SMBD_TEST_LOG},
2177                 PCAP_FILE => "env-$ENV{ENVNAME}-smbd",
2178         };
2179         if ($smbd ne "yes") {
2180                 $daemon_ctx->{SKIP_DAEMON} = 1;
2181         }
2182
2183         $pid = Samba::fork_and_exec(
2184             $self, $env_vars, $daemon_ctx, $STDIN_READER, $child_cleanup);
2185
2186         $env_vars->{SMBD_TL_PID} = $pid;
2187         write_pid($env_vars, "smbd", $pid);
2188
2189         # close the parent's read-end of the pipe
2190         close($STDIN_READER);
2191
2192         if ($skip_wait) {
2193                 return 1;
2194         }
2195
2196         return $self->wait_for_start($env_vars, $nmbd, $winbindd, $smbd);
2197 }
2198
2199 sub createuser($$$$$)
2200 {
2201         my ($self, $username, $password, $conffile, $env) = @_;
2202         my $cmd = "UID_WRAPPER_ROOT=1 " . Samba::bindir_path($self, "smbpasswd")." -c $conffile -L -s -a $username > /dev/null";
2203
2204         keys %$env;
2205         while(my($var, $val) = each %$env) {
2206                 $cmd = "$var=\"$val\" $cmd";
2207         }
2208
2209         unless (open(PWD, "|$cmd")) {
2210             warn("Unable to set password for $username account\n$cmd");
2211             return undef;
2212         }
2213         print PWD "$password\n$password\n";
2214         unless (close(PWD)) {
2215             warn("Unable to set password for $username account\n$cmd");
2216             return undef;
2217         }
2218 }
2219
2220 sub provision($$)
2221 {
2222         my ($self, %args) = @_;
2223
2224         my $prefix = $args{prefix};
2225         my $domain = $args{domain};
2226         my $realm = $args{realm};
2227         my $server = $args{server};
2228         my $password = $args{password};
2229         my $extra_options = $args{extra_options};
2230         my $resolv_conf = $args{resolv_conf};
2231         my $no_delete_prefix= $args{no_delete_prefix};
2232         my $netbios_name = $args{netbios_name} // $server;
2233         my $server_log_level = $ENV{SERVER_LOG_LEVEL} || 1;
2234
2235         ##
2236         ## setup the various environment variables we need
2237         ##
2238
2239         my $samsid = Samba::random_domain_sid();
2240         my $swiface = Samba::get_interface($server);
2241         my %ret = ();
2242         my %createuser_env = ();
2243         my $server_ip = Samba::get_ipv4_addr($server);
2244         my $server_ipv6 = Samba::get_ipv6_addr($server);
2245         my $dns_domain;
2246         if (defined($realm)) {
2247             $dns_domain = lc($realm);
2248         } else {
2249             $dns_domain = "samba.example.com";
2250         }
2251
2252         my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `PATH=/usr/ucb:$ENV{PATH} whoami`);
2253         chomp $unix_name;
2254         my $unix_uid = $>;
2255         my $unix_gids_str = $);
2256         my @unix_gids = split(" ", $unix_gids_str);
2257
2258         my $prefix_abs = abs_path($prefix);
2259         my $bindir_abs = abs_path($self->{bindir});
2260
2261         my @dirs = ();
2262
2263         my $shrdir=$args{share_dir} // "$prefix_abs/share";
2264         push(@dirs,$shrdir);
2265
2266         my $libdir="$prefix_abs/lib";
2267         push(@dirs,$libdir);
2268
2269         my $piddir="$prefix_abs/pid";
2270         push(@dirs,$piddir);
2271
2272         my $privatedir="$prefix_abs/private";
2273         push(@dirs,$privatedir);
2274
2275         my $cachedir = "$prefix_abs/cachedir";
2276         push(@dirs, $cachedir);
2277
2278         my $binddnsdir = "$prefix_abs/bind-dns";
2279         push(@dirs, $binddnsdir);
2280
2281         my $lockdir="$prefix_abs/lockdir";
2282         push(@dirs,$lockdir);
2283
2284         my $eventlogdir="$prefix_abs/lockdir/eventlog";
2285         push(@dirs,$eventlogdir);
2286
2287         my $logdir="$prefix_abs/logs";
2288         push(@dirs,$logdir);
2289
2290         my $driver32dir="$shrdir/W32X86";
2291         push(@dirs,$driver32dir);
2292
2293         my $driver64dir="$shrdir/x64";
2294         push(@dirs,$driver64dir);
2295
2296         my $driver40dir="$shrdir/WIN40";
2297         push(@dirs,$driver40dir);
2298
2299         my $ro_shrdir="$shrdir/root-tmp";
2300         push(@dirs,$ro_shrdir);
2301
2302         my $noperm_shrdir="$shrdir/noperm-tmp";
2303         push(@dirs,$noperm_shrdir);
2304
2305         my $msdfs_shrdir="$shrdir/msdfsshare";
2306         push(@dirs,$msdfs_shrdir);
2307
2308         my $msdfs_deeppath="$msdfs_shrdir/deeppath";
2309         push(@dirs,$msdfs_deeppath);
2310
2311         my $smbcacls_sharedir_dfs="$shrdir/smbcacls_sharedir_dfs";
2312         push(@dirs,$smbcacls_sharedir_dfs);
2313
2314         my $smbcacls_share="$shrdir/smbcacls_share";
2315         push(@dirs,$smbcacls_share);
2316
2317         my $smbcacls_share_testdir="$shrdir/smbcacls_share/smbcacls";
2318         push(@dirs,$smbcacls_share_testdir);
2319
2320         my $badnames_shrdir="$shrdir/badnames";
2321         push(@dirs,$badnames_shrdir);
2322
2323         my $lease1_shrdir="$shrdir/dynamic";
2324         push(@dirs,$lease1_shrdir);
2325
2326         my $manglenames_shrdir="$shrdir/manglenames";
2327         push(@dirs,$manglenames_shrdir);
2328
2329         my $widelinks_shrdir="$shrdir/widelinks";
2330         push(@dirs,$widelinks_shrdir);
2331
2332         my $widelinks_linkdir="$shrdir/widelinks_foo";
2333         push(@dirs,$widelinks_linkdir);
2334
2335         my $fsrvp_shrdir="$shrdir/fsrvp";
2336         push(@dirs,$fsrvp_shrdir);
2337
2338         my $shadow_tstdir="$shrdir/shadow";
2339         push(@dirs,$shadow_tstdir);
2340         my $shadow_mntdir="$shadow_tstdir/mount";
2341         push(@dirs,$shadow_mntdir);
2342         my $shadow_basedir="$shadow_mntdir/base";
2343         push(@dirs,$shadow_basedir);
2344         my $shadow_shrdir="$shadow_basedir/share";
2345         push(@dirs,$shadow_shrdir);
2346
2347         my $nosymlinks_shrdir="$shrdir/nosymlinks";
2348         push(@dirs,$nosymlinks_shrdir);
2349
2350         my $local_symlinks_shrdir="$shrdir/local_symlinks";
2351         push(@dirs,$local_symlinks_shrdir);
2352
2353         # this gets autocreated by winbindd
2354         my $wbsockdir="$prefix_abs/wbsock";
2355
2356         my $nmbdsockdir="$prefix_abs/nmbd";
2357         unlink($nmbdsockdir);
2358
2359         ## 
2360         ## create the test directory layout
2361         ##
2362         die ("prefix_abs = ''") if $prefix_abs eq "";
2363         die ("prefix_abs = '/'") if $prefix_abs eq "/";
2364
2365         mkdir($prefix_abs, 0777);
2366         print "CREATE TEST ENVIRONMENT IN '$prefix'...";
2367         if (not defined($no_delete_prefix) or not $no_delete_prefix) {
2368             system("rm -rf $prefix_abs/*");
2369         }
2370         mkdir($_, 0777) foreach(@dirs);
2371
2372         my $fs_specific_conf = $self->get_fs_specific_conf($shrdir);
2373
2374         ##
2375         ## lockdir and piddir must be 0755
2376         ##
2377         chmod 0755, $lockdir;
2378         chmod 0755, $piddir;
2379
2380
2381         ##
2382         ## Create a directory without permissions to enter
2383         ##
2384         chmod 0000, $noperm_shrdir;
2385
2386         ##
2387         ## create ro and msdfs share layout
2388         ##
2389
2390         chmod 0755, $ro_shrdir;
2391
2392         create_file_chmod("$ro_shrdir/unreadable_file", 0600) or return undef;
2393
2394         create_file_chmod("$ro_shrdir/msdfs-target", 0600) or return undef;
2395         symlink "msdfs:$server_ip\\ro-tmp,$server_ipv6\\ro-tmp",
2396                 "$msdfs_shrdir/msdfs-src1";
2397         symlink "msdfs:$server_ipv6\\ro-tmp", "$msdfs_shrdir/deeppath/msdfs-src2";
2398         symlink "msdfs:$server_ip\\smbcacls_sharedir_dfs,$server_ipv6\\smbcacls_sharedir_dfs",
2399                 "$msdfs_shrdir/smbcacls_sharedir_dfs";
2400
2401         ##
2402         ## create bad names in $badnames_shrdir
2403         ##
2404         ## (An invalid name, would be mangled to 8.3).
2405         create_file_chmod("$badnames_shrdir/\340|\231\216\377\177",
2406                           0600) or return undef;
2407
2408         ## (A bad name, would not be mangled to 8.3).
2409         create_file_chmod("$badnames_shrdir/\240\276\346\327\377\177",
2410                           0666) or return undef;
2411
2412         ## (A bad good name).
2413         create_file_chmod("$badnames_shrdir/blank.txt",
2414                           0666) or return undef;
2415
2416         ##
2417         ## create mangleable directory names in $manglenames_shrdir
2418         ##
2419         my $manglename_target = "$manglenames_shrdir/foo:bar";
2420         mkdir($manglename_target, 0777);
2421
2422         ##
2423         ## create symlinks for widelinks tests.
2424         ##
2425         my $widelinks_target = "$widelinks_linkdir/target";
2426         create_file_chmod("$widelinks_target", 0666) or return undef;
2427
2428         ##
2429         ## This link should get ACCESS_DENIED
2430         ##
2431         symlink "$widelinks_target", "$widelinks_shrdir/source";
2432         ##
2433         ## This link should be allowed
2434         ##
2435         symlink "$widelinks_shrdir", "$widelinks_shrdir/dot";
2436
2437         my $conffile="$libdir/server.conf";
2438         my $dfqconffile="$libdir/dfq.conf";
2439         my $errorinjectconf="$libdir/error_inject.conf";
2440         my $delayinjectconf="$libdir/delay_inject.conf";
2441         my $globalinjectconf="$libdir/global_inject.conf";
2442
2443         my $nss_wrapper_pl = "$ENV{PERL} $self->{srcdir}/third_party/nss_wrapper/nss_wrapper.pl";
2444         my $nss_wrapper_passwd = "$privatedir/passwd";
2445         my $nss_wrapper_group = "$privatedir/group";
2446         my $nss_wrapper_hosts = "$ENV{SELFTEST_PREFIX}/hosts";
2447         my $dns_host_file = "$ENV{SELFTEST_PREFIX}/dns_host_file";
2448
2449         my $mod_printer_pl = "$ENV{PERL} $self->{srcdir}/source3/script/tests/printing/modprinter.pl";
2450
2451         my $fake_snap_pl = "$ENV{PERL} $self->{srcdir}/source3/script/tests/fake_snap.pl";
2452
2453         my @eventlog_list = ("dns server", "application");
2454
2455         ##
2456         ## calculate uids and gids
2457         ##
2458
2459         my ($max_uid, $max_gid);
2460         my ($uid_nobody, $uid_root, $uid_pdbtest, $uid_pdbtest2, $uid_userdup);
2461         my ($uid_pdbtest_wkn);
2462         my ($uid_smbget);
2463         my ($uid_force_user);
2464         my ($gid_nobody, $gid_nogroup, $gid_root, $gid_domusers, $gid_domadmins);
2465         my ($gid_userdup, $gid_everyone);
2466         my ($gid_force_user);
2467         my ($uid_user1);
2468         my ($uid_user2);
2469         my ($uid_gooduser);
2470         my ($uid_eviluser);
2471         my ($uid_slashuser);
2472
2473         if ($unix_uid < 0xffff - 13) {
2474                 $max_uid = 0xffff;
2475         } else {
2476                 $max_uid = $unix_uid;
2477         }
2478
2479         $uid_root = $max_uid - 1;
2480         $uid_nobody = $max_uid - 2;
2481         $uid_pdbtest = $max_uid - 3;
2482         $uid_pdbtest2 = $max_uid - 4;
2483         $uid_userdup = $max_uid - 5;
2484         $uid_pdbtest_wkn = $max_uid - 6;
2485         $uid_force_user = $max_uid - 7;
2486         $uid_smbget = $max_uid - 8;
2487         $uid_user1 = $max_uid - 9;
2488         $uid_user2 = $max_uid - 10;
2489         $uid_gooduser = $max_uid - 11;
2490         $uid_eviluser = $max_uid - 12;
2491         $uid_slashuser = $max_uid - 13;
2492
2493         if ($unix_gids[0] < 0xffff - 8) {
2494                 $max_gid = 0xffff;
2495         } else {
2496                 $max_gid = $unix_gids[0];
2497         }
2498
2499         $gid_nobody = $max_gid - 1;
2500         $gid_nogroup = $max_gid - 2;
2501         $gid_root = $max_gid - 3;
2502         $gid_domusers = $max_gid - 4;
2503         $gid_domadmins = $max_gid - 5;
2504         $gid_userdup = $max_gid - 6;
2505         $gid_everyone = $max_gid - 7;
2506         $gid_force_user = $max_gid - 8;
2507
2508         ##
2509         ## create conffile
2510         ##
2511
2512         unless (open(CONF, ">$conffile")) {
2513                 warn("Unable to open $conffile");
2514                 return undef;
2515         }
2516
2517         my $interfaces = Samba::get_interfaces_config($server);
2518
2519         print CONF "
2520 [global]
2521         dcesrv:fuzz directory = $cachedir/fuzz
2522         netbios name = $netbios_name
2523         interfaces = $interfaces
2524         bind interfaces only = yes
2525         panic action = cd $self->{srcdir} && $self->{srcdir}/selftest/gdb_backtrace %d %\$(MAKE_TEST_BINARY)
2526         smbd:suicide mode = yes
2527         smbd:FSCTL_SMBTORTURE = yes
2528
2529         client min protocol = SMB2_02
2530         server min protocol = SMB2_02
2531
2532         server multi channel support = yes
2533
2534         workgroup = $domain
2535
2536         private dir = $privatedir
2537         binddns dir = $binddnsdir
2538         pid directory = $piddir
2539         lock directory = $lockdir
2540         log file = $logdir/log.\%m
2541         log level = $server_log_level
2542         debug pid = yes
2543         max log size = 0
2544
2545         state directory = $lockdir
2546         cache directory = $lockdir
2547
2548         passdb backend = tdbsam
2549
2550         time server = yes
2551
2552         add user script =               $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action add --name %u --gid $gid_nogroup
2553         add group script =              $nss_wrapper_pl --group_path  $nss_wrapper_group  --type group  --action add --name %g
2554         add machine script =            $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action add --name %u --gid $gid_nogroup
2555         add user to group script =      $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type member --action add --member %u --name %g --group_path $nss_wrapper_group
2556         delete user script =            $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action delete --name %u
2557         delete group script =           $nss_wrapper_pl --group_path  $nss_wrapper_group  --type group  --action delete --name %g
2558         delete user from group script = $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type member --action delete --member %u --name %g --group_path $nss_wrapper_group
2559
2560         addprinter command =            $mod_printer_pl -a -s $conffile --
2561         deleteprinter command =         $mod_printer_pl -d -s $conffile --
2562
2563         eventlog list = application \"dns server\"
2564
2565         kernel oplocks = no
2566         kernel change notify = no
2567
2568         logging = file
2569         printing = bsd
2570         printcap name = /dev/null
2571
2572         winbindd socket directory = $wbsockdir
2573         nmbd:socket dir = $nmbdsockdir
2574         idmap config * : range = 100000-200000
2575         winbind enum users = yes
2576         winbind enum groups = yes
2577         winbind separator = /
2578         include system krb5 conf = no
2579
2580 #       min receivefile size = 4000
2581
2582         read only = no
2583
2584         smbd:sharedelay = 100000
2585         smbd:writetimeupdatedelay = 500000
2586         map hidden = no
2587         map system = no
2588         map readonly = no
2589         store dos attributes = yes
2590         create mask = 755
2591         dos filemode = yes
2592         strict rename = yes
2593         strict sync = yes
2594         mangled names = yes
2595         vfs objects = acl_xattr fake_acls xattr_tdb streams_depot time_audit full_audit
2596
2597         full_audit:syslog = no
2598         full_audit:success = none
2599         full_audit:failure = none
2600
2601         printing = vlp
2602         print command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb print %p %s
2603         lpq command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpq %p
2604         lp rm command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lprm %p %j
2605         lp pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lppause %p %j
2606         lp resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpresume %p %j
2607         queue pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queuepause %p
2608         queue resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queueresume %p
2609         lpq cache time = 0
2610         print notify backchannel = yes
2611
2612         ncalrpc dir = $prefix_abs/ncalrpc
2613
2614         # The samba3.blackbox.smbclient_s3 test uses this to test that
2615         # sending messages works, and that the %m sub works.
2616         message command = mv %s $shrdir/message.%m
2617
2618         # fsrvp server requires registry shares
2619         registry shares = yes
2620
2621         # Used by RPC SRVSVC tests
2622         add share command = $bindir_abs/smbaddshare
2623         change share command = $bindir_abs/smbchangeshare
2624         delete share command = $bindir_abs/smbdeleteshare
2625
2626         # fruit:copyfile is a global option
2627         fruit:copyfile = yes
2628
2629         #this does not mean that we use non-secure test env,
2630         #it just means we ALLOW one to be configured.
2631         allow insecure wide links = yes
2632
2633         include = $globalinjectconf
2634
2635         # Begin extra options
2636         $extra_options
2637         # End extra options
2638
2639         #Include user defined custom parameters if set
2640 ";
2641
2642         if (defined($ENV{INCLUDE_CUSTOM_CONF})) {
2643                 print CONF "\t$ENV{INCLUDE_CUSTOM_CONF}\n";
2644         }
2645
2646         print CONF "
2647 [smbcacls_share]
2648         path = $smbcacls_share
2649         comment = smb username is [%U]
2650         msdfs root = yes
2651
2652 [smbcacls_sharedir_dfs]
2653         path = $smbcacls_sharedir_dfs
2654         comment = smb username is [%U]
2655 [tmp]
2656         path = $shrdir
2657         comment = smb username is [%U]
2658 [tmpsort]
2659         path = $shrdir
2660         comment = Load dirsort module
2661         vfs objects = dirsort acl_xattr fake_acls xattr_tdb streams_depot
2662 [tmpenc]
2663         path = $shrdir
2664         comment = encrypt smb username is [%U]
2665         server smb encrypt = required
2666         vfs objects = dirsort
2667 [tmpguest]
2668         path = $shrdir
2669         guest ok = yes
2670 [guestonly]
2671         path = $shrdir
2672         guest only = yes
2673         guest ok = yes
2674 [forceuser]
2675         path = $shrdir
2676         force user = $unix_name
2677         guest ok = yes
2678 [forceuser_unixonly]
2679         comment = force a user with unix user SID and group SID
2680         path = $shrdir
2681         force user = pdbtest
2682         guest ok = yes
2683 [forceuser_wkngroup]
2684         comment = force a user with well-known group SID
2685         path = $shrdir
2686         force user = pdbtest_wkn
2687         guest ok = yes
2688 [forcegroup]
2689         path = $shrdir
2690         force group = nogroup
2691         guest ok = yes
2692 [ro-tmp]
2693         path = $ro_shrdir
2694         guest ok = yes
2695 [noperm]
2696         path = $noperm_shrdir
2697         wide links = yes
2698         guest ok = yes
2699 [write-list-tmp]
2700         path = $shrdir
2701         read only = yes
2702         write list = $unix_name
2703 [valid-users-tmp]
2704         path = $shrdir
2705         valid users = $unix_name
2706         access based share enum = yes
2707 [msdfs-share]
2708         path = $msdfs_shrdir
2709         msdfs root = yes
2710         msdfs shuffle referrals = yes
2711         guest ok = yes
2712 [hideunread]
2713         copy = tmp
2714         hide unreadable = yes
2715 [tmpcase]
2716         copy = tmp
2717         case sensitive = yes
2718 [hideunwrite]
2719         copy = tmp
2720         hide unwriteable files = yes
2721 [durable]
2722         copy = tmp
2723         kernel share modes = no
2724         kernel oplocks = no
2725         posix locking = no
2726 [fs_specific]
2727         copy = tmp
2728         $fs_specific_conf
2729 [print1]
2730         copy = tmp
2731         printable = yes
2732
2733 [print2]
2734         copy = print1
2735 [print3]
2736         copy = print1
2737         default devmode = no
2738
2739 [print_var_exp]
2740         copy = print1
2741         print command = $self->{srcdir}/source3/script/tests/printing/printing_var_exp_lpr_cmd.sh \"Windows user: %U\" \"UNIX user: %u\" \"Domain: %D\"
2742
2743 [lp]
2744         copy = print1
2745
2746 [nfs4acl_simple_40]
2747         path = $shrdir
2748         comment = smb username is [%U]
2749         nfs4:mode = simple
2750         nfs4acl_xattr:version = 40
2751         vfs objects = nfs4acl_xattr xattr_tdb
2752
2753 [nfs4acl_special_40]
2754         path = $shrdir
2755         comment = smb username is [%U]
2756         nfs4:mode = special
2757         nfs4acl_xattr:version = 40
2758         vfs objects = nfs4acl_xattr xattr_tdb
2759
2760 [nfs4acl_simple_41]
2761         path = $shrdir
2762         comment = smb username is [%U]
2763         nfs4:mode = simple
2764         vfs objects = nfs4acl_xattr xattr_tdb
2765
2766 [nfs4acl_xdr_40]
2767         path = $shrdir
2768         comment = smb username is [%U]
2769         vfs objects = nfs4acl_xattr xattr_tdb
2770         nfs4:mode = simple
2771         nfs4acl_xattr:encoding = xdr
2772         nfs4acl_xattr:version = 40
2773
2774 [nfs4acl_xdr_41]
2775         path = $shrdir
2776         comment = smb username is [%U]
2777         vfs objects = nfs4acl_xattr xattr_tdb
2778         nfs4:mode = simple
2779         nfs4acl_xattr:encoding = xdr
2780         nfs4acl_xattr:version = 41
2781
2782 [nfs4acl_nfs_40]
2783         path = $shrdir
2784         comment = smb username is [%U]
2785         vfs objects = nfs4acl_xattr xattr_tdb
2786         nfs4:mode = simple
2787         nfs4acl_xattr:encoding = nfs
2788         nfs4acl_xattr:version = 40
2789         nfs4acl_xattr:xattr_name = security.nfs4acl_xdr
2790
2791 [nfs4acl_nfs_41]
2792         path = $shrdir
2793         comment = smb username is [%U]
2794         vfs objects = nfs4acl_xattr xattr_tdb
2795         nfs4:mode = simple
2796         nfs4acl_xattr:encoding = nfs
2797         nfs4acl_xattr:version = 41
2798         nfs4acl_xattr:xattr_name = security.nfs4acl_xdr
2799
2800 [xcopy_share]
2801         path = $shrdir
2802         comment = smb username is [%U]
2803         create mask = 777
2804         force create mode = 777
2805 [posix_share]
2806         path = $shrdir
2807         comment = smb username is [%U]
2808         create mask = 0777
2809         force create mode = 0
2810         directory mask = 0777
2811         force directory mode = 0
2812         vfs objects = xattr_tdb streams_depot
2813 [aio]
2814         copy = durable
2815         aio read size = 1
2816         aio write size = 1
2817
2818 [print\$]
2819         copy = tmp
2820
2821 [vfs_fruit]
2822         path = $shrdir
2823         vfs objects = catia fruit streams_xattr acl_xattr xattr_tdb
2824         fruit:resource = file
2825         fruit:metadata = netatalk
2826         fruit:locking = netatalk
2827         fruit:encoding = native
2828         fruit:veto_appledouble = no
2829
2830 [vfs_fruit_xattr]
2831         path = $shrdir
2832         # This is used by vfs.fruit tests that require real fs xattr
2833         vfs objects = catia fruit streams_xattr acl_xattr
2834         fruit:resource = file
2835         fruit:metadata = netatalk
2836         fruit:locking = netatalk
2837         fruit:encoding = native
2838         fruit:veto_appledouble = no
2839
2840 [vfs_fruit_metadata_stream]
2841         path = $shrdir
2842         vfs objects = fruit streams_xattr acl_xattr xattr_tdb
2843         fruit:resource = file
2844         fruit:metadata = stream
2845         fruit:veto_appledouble = no
2846
2847 [vfs_fruit_stream_depot]
2848         path = $shrdir
2849         vfs objects = fruit streams_depot acl_xattr xattr_tdb
2850         fruit:resource = stream
2851         fruit:metadata = stream
2852         fruit:veto_appledouble = no
2853
2854 [vfs_wo_fruit]
2855         path = $shrdir
2856         vfs objects = streams_xattr acl_xattr xattr_tdb
2857
2858 [vfs_wo_fruit_stream_depot]
2859         path = $shrdir
2860         vfs objects = streams_depot acl_xattr xattr_tdb
2861
2862 [vfs_fruit_timemachine]
2863         path = $shrdir
2864         vfs objects = fruit streams_xattr acl_xattr xattr_tdb
2865         fruit:resource = file
2866         fruit:metadata = stream
2867         fruit:time machine = yes
2868         fruit:time machine max size = 32K
2869
2870 [vfs_fruit_wipe_intentionally_left_blank_rfork]
2871         path = $shrdir
2872         vfs objects = fruit streams_xattr acl_xattr xattr_tdb
2873         fruit:resource = file
2874         fruit:metadata = stream
2875         fruit:wipe_intentionally_left_blank_rfork = true
2876         fruit:delete_empty_adfiles = false
2877         fruit:veto_appledouble = no
2878
2879 [vfs_fruit_delete_empty_adfiles]
2880         path = $shrdir
2881         vfs objects = fruit streams_xattr acl_xattr xattr_tdb
2882         fruit:resource = file
2883         fruit:metadata = stream
2884         fruit:wipe_intentionally_left_blank_rfork = true
2885         fruit:delete_empty_adfiles = true
2886         fruit:veto_appledouble = no
2887
2888 [vfs_fruit_zero_fileid]
2889         path = $shrdir
2890         vfs objects = fruit streams_xattr acl_xattr xattr_tdb
2891         fruit:resource = file
2892         fruit:metadata = stream
2893         fruit:zero_file_id=yes
2894
2895 [badname-tmp]
2896         path = $badnames_shrdir
2897         guest ok = yes
2898
2899 [manglenames_share]
2900         path = $manglenames_shrdir
2901         guest ok = yes
2902
2903 [dynamic_share]
2904         path = $shrdir/dynamic/%t
2905         guest ok = yes
2906         root preexec = mkdir %P
2907
2908 [widelinks_share]
2909         path = $widelinks_shrdir
2910         wide links = no
2911         guest ok = yes
2912
2913 [fsrvp_share]
2914         path = $fsrvp_shrdir
2915         comment = fake shapshots using rsync
2916         vfs objects = shell_snap shadow_copy2
2917         shell_snap:check path command = $fake_snap_pl --check
2918         shell_snap:create command = $fake_snap_pl --create
2919         shell_snap:delete command = $fake_snap_pl --delete
2920         # a relative path here fails, the snapshot dir is no longer found
2921         shadow:snapdir = $fsrvp_shrdir/.snapshots
2922
2923 [shadow1]
2924         path = $shadow_shrdir
2925         comment = previous versions snapshots under mount point
2926         vfs objects = shadow_copy2
2927         shadow:mountpoint = $shadow_mntdir
2928
2929 [shadow2]
2930         path = $shadow_shrdir
2931         comment = previous versions snapshots outside mount point
2932         vfs objects = shadow_copy2
2933         shadow:mountpoint = $shadow_mntdir
2934         shadow:snapdir = $shadow_tstdir/.snapshots
2935
2936 [shadow3]
2937         path = $shadow_shrdir
2938         comment = previous versions with subvolume snapshots, snapshots under base dir
2939         vfs objects = shadow_copy2
2940         shadow:mountpoint = $shadow_mntdir
2941         shadow:basedir = $shadow_basedir
2942         shadow:snapdir = $shadow_basedir/.snapshots
2943
2944 [shadow4]
2945         path = $shadow_shrdir
2946         comment = previous versions with subvolume snapshots, snapshots outside mount point
2947         vfs objects = shadow_copy2
2948         shadow:mountpoint = $shadow_mntdir
2949         shadow:basedir = $shadow_basedir
2950         shadow:snapdir = $shadow_tstdir/.snapshots
2951
2952 [shadow5]
2953         path = $shadow_shrdir
2954         comment = previous versions at volume root snapshots under mount point
2955         vfs objects = shadow_copy2
2956         shadow:mountpoint = $shadow_shrdir
2957
2958 [shadow6]
2959         path = $shadow_shrdir
2960         comment = previous versions at volume root snapshots outside mount point
2961         vfs objects = shadow_copy2
2962         shadow:mountpoint = $shadow_shrdir
2963         shadow:snapdir = $shadow_tstdir/.snapshots
2964
2965 [shadow7]
2966         path = $shadow_shrdir
2967         comment = previous versions snapshots everywhere
2968         vfs objects = shadow_copy2
2969         shadow:mountpoint = $shadow_mntdir
2970         shadow:snapdirseverywhere = yes
2971
2972 [shadow8]
2973         path = $shadow_shrdir
2974         comment = previous versions using snapsharepath
2975         vfs objects = shadow_copy2
2976         shadow:mountpoint = $shadow_mntdir
2977         shadow:snapdir = $shadow_tstdir/.snapshots
2978         shadow:snapsharepath = share
2979
2980 [shadow_fmt0]
2981         comment = Testing shadow:format with default option
2982         vfs object = shadow_copy2
2983         path = $shadow_shrdir
2984         read only = no
2985         guest ok = yes
2986         shadow:mountpoint = $shadow_mntdir
2987         shadow:basedir = $shadow_basedir
2988         shadow:snapdir = $shadow_basedir/.snapshots
2989         shadow:format = \@GMT-%Y.%m.%d-%H.%M.%S
2990
2991 [shadow_fmt1]
2992         comment = Testing shadow:format with only date component
2993         vfs object = shadow_copy2
2994         path = $shadow_shrdir
2995         read only = no
2996         guest ok = yes
2997         shadow:mountpoint = $shadow_mntdir
2998         shadow:basedir = $shadow_basedir
2999         shadow:snapdir = $shadow_basedir/.snapshots
3000         shadow:format = \@GMT-%Y-%m-%d
3001
3002 [shadow_fmt2]
3003         comment = Testing shadow:format with some hardcoded prefix
3004         vfs object = shadow_copy2
3005         path = $shadow_shrdir
3006         read only = no
3007         guest ok = yes
3008         shadow:mountpoint = $shadow_mntdir
3009         shadow:basedir = $shadow_basedir
3010         shadow:snapdir = $shadow_basedir/.snapshots
3011         shadow:format = snap\@GMT-%Y.%m.%d-%H.%M.%S
3012
3013 [shadow_fmt3]
3014         comment = Testing shadow:format with modified format
3015         vfs object = shadow_copy2
3016         path = $shadow_shrdir
3017         read only = no
3018         guest ok = yes
3019         shadow:mountpoint = $shadow_mntdir
3020         shadow:basedir = $shadow_basedir
3021         shadow:snapdir = $shadow_basedir/.snapshots
3022         shadow:format = \@GMT-%Y.%m.%d-%H_%M_%S-snap
3023
3024 [shadow_fmt4]
3025         comment = Testing shadow:snapprefix regex
3026         vfs object = shadow_copy2
3027         path = $shadow_shrdir
3028         read only = no
3029         guest ok = yes
3030         shadow:mountpoint = $shadow_mntdir
3031         shadow:basedir = $shadow_basedir
3032         shadow:snapdir = $shadow_basedir/.snapshots
3033         shadow:snapprefix = \^s[a-z]*p\$
3034         shadow:format = _GMT-%Y.%m.%d-%H.%M.%S
3035
3036 [shadow_fmt5]
3037         comment = Testing shadow:snapprefix with delim regex
3038         vfs object = shadow_copy2
3039         path = $shadow_shrdir
3040         read only = no
3041         guest ok = yes
3042         shadow:mountpoint = $shadow_mntdir
3043         shadow:basedir = $shadow_basedir
3044         shadow:snapdir = $shadow_basedir/.snapshots
3045         shadow:delimiter = \@GMT
3046         shadow:snapprefix = [a-z]*
3047         shadow:format = \@GMT-%Y.%m.%d-%H.%M.%S
3048
3049 [shadow_wl]
3050         path = $shadow_shrdir
3051         comment = previous versions with wide links allowed
3052         vfs objects = shadow_copy2
3053         shadow:mountpoint = $shadow_mntdir
3054         wide links = yes
3055
3056 [shadow_write]
3057         path = $shadow_tstdir
3058         comment = previous versions snapshots under mount point
3059         vfs objects = shadow_copy2 streams_xattr error_inject
3060         aio write size = 0
3061         error_inject:pwrite = EBADF
3062         shadow:mountpoint = $shadow_tstdir
3063         shadow:fixinodes = yes
3064
3065 [dfq]
3066         path = $shrdir/dfree
3067         vfs objects = acl_xattr fake_acls xattr_tdb fake_dfq
3068         admin users = $unix_name
3069         include = $dfqconffile
3070 [dfq_cache]
3071         path = $shrdir/dfree
3072         vfs objects = acl_xattr fake_acls xattr_tdb fake_dfq
3073         admin users = $unix_name
3074         include = $dfqconffile
3075         dfree cache time = 60
3076 [dfq_owner]
3077         path = $shrdir/dfree
3078         vfs objects = acl_xattr fake_acls xattr_tdb fake_dfq
3079         inherit owner = yes
3080         include = $dfqconffile
3081 [quotadir]
3082         path = $shrdir/quota
3083         admin users = $unix_name
3084
3085 [acl_xattr_ign_sysacl_posix]
3086         copy = tmp
3087         acl_xattr:ignore system acls = yes
3088         acl_xattr:default acl style = posix
3089 [acl_xattr_ign_sysacl_windows]
3090         copy = tmp
3091         acl_xattr:ignore system acls = yes
3092         acl_xattr:default acl style = windows
3093
3094 [mangle_illegal]
3095         copy = tmp
3096         mangled names = illegal
3097
3098 [nosymlinks]
3099         copy = tmp
3100         path = $nosymlinks_shrdir
3101         follow symlinks = no
3102
3103 [local_symlinks]
3104         copy = tmp
3105         path = $local_symlinks_shrdir
3106         follow symlinks = yes
3107
3108 [kernel_oplocks]
3109         copy = tmp
3110         kernel oplocks = yes
3111         vfs objects = streams_xattr xattr_tdb
3112
3113 [streams_xattr]
3114         copy = tmp
3115         vfs objects = streams_xattr xattr_tdb
3116
3117 [compound_find]
3118         copy = tmp
3119         smbd:find async delay usec = 10000
3120 [error_inject]
3121         copy = tmp
3122         vfs objects = error_inject
3123         include = $errorinjectconf
3124
3125 [delay_inject]
3126         copy = tmp
3127         vfs objects = delay_inject
3128         kernel share modes = no
3129         kernel oplocks = no
3130         posix locking = no
3131         include = $delayinjectconf
3132
3133 [aio_delay_inject]
3134         copy = tmp
3135         vfs objects = delay_inject
3136         delay_inject:pread_send = 2000
3137         delay_inject:pwrite_send = 2000
3138
3139 [brl_delay_inject1]
3140         copy = tmp
3141         vfs objects = delay_inject
3142         delay_inject:brl_lock_windows = 90
3143         delay_inject:brl_lock_windows_use_timer = yes
3144
3145 [brl_delay_inject2]
3146         copy = tmp
3147         vfs objects = delay_inject
3148         delay_inject:brl_lock_windows = 90
3149         delay_inject:brl_lock_windows_use_timer = no
3150
3151 [delete_readonly]
3152         path = $prefix_abs/share
3153         delete readonly = yes
3154
3155 [enc_desired]
3156         path = $prefix_abs/share
3157         vfs objects =
3158         server smb encrypt = desired
3159
3160 [enc_off]
3161         path = $prefix_abs/share
3162         vfs objects =
3163         server smb encrypt = off
3164
3165 [notify_priv]
3166         copy = tmp
3167         honor change notify privilege = yes
3168
3169 [acls_non_canonical]
3170         copy = tmp
3171         acl flag inherited canonicalization = no
3172         ";
3173
3174         close(CONF);
3175
3176         my $net = Samba::bindir_path($self, "net");
3177         my $cmd = "";
3178         $cmd .= "UID_WRAPPER_ROOT=1 ";
3179         $cmd .= "SMB_CONF_PATH=\"$conffile\" ";
3180         $cmd .= "$net setlocalsid $samsid";
3181
3182         my $net_ret = system($cmd);
3183         if ($net_ret != 0) {
3184             warn("net setlocalsid failed: $net_ret\n$cmd");
3185             return undef;
3186         }
3187
3188         unless (open(ERRORCONF, ">$errorinjectconf")) {
3189                 warn("Unable to open $errorinjectconf");
3190                 return undef;
3191         }
3192         close(ERRORCONF);
3193
3194         unless (open(DELAYCONF, ">$delayinjectconf")) {
3195                 warn("Unable to open $delayinjectconf");
3196                 return undef;
3197         }
3198         close(DELAYCONF);
3199
3200         unless (open(DFQCONF, ">$dfqconffile")) {
3201                 warn("Unable to open $dfqconffile");
3202                 return undef;
3203         }
3204         close(DFQCONF);
3205
3206         unless (open(DELAYCONF, ">$globalinjectconf")) {
3207                 warn("Unable to open $globalinjectconf");
3208                 return undef;
3209         }
3210         close(DELAYCONF);
3211
3212         ##
3213         ## create a test account
3214         ##
3215
3216         unless (open(PASSWD, ">$nss_wrapper_passwd")) {
3217            warn("Unable to open $nss_wrapper_passwd");
3218            return undef;
3219         } 
3220         print PASSWD "nobody:x:$uid_nobody:$gid_nobody:nobody gecos:$prefix_abs:/bin/false
3221 $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false
3222 pdbtest:x:$uid_pdbtest:$gid_nogroup:pdbtest gecos:$prefix_abs:/bin/false
3223 pdbtest2:x:$uid_pdbtest2:$gid_nogroup:pdbtest gecos:$prefix_abs:/bin/false
3224 userdup:x:$uid_userdup:$gid_userdup:userdup gecos:$prefix_abs:/bin/false
3225 pdbtest_wkn:x:$uid_pdbtest_wkn:$gid_everyone:pdbtest_wkn gecos:$prefix_abs:/bin/false
3226 force_user:x:$uid_force_user:$gid_force_user:force user gecos:$prefix_abs:/bin/false
3227 smbget_user:x:$uid_smbget:$gid_domusers:smbget_user gecos:$prefix_abs:/bin/false
3228 user1:x:$uid_user1:$gid_nogroup:user1 gecos:$prefix_abs:/bin/false
3229 user2:x:$uid_user2:$gid_nogroup:user2 gecos:$prefix_abs:/bin/false
3230 gooduser:x:$uid_gooduser:$gid_domusers:gooduser gecos:$prefix_abs:/bin/false
3231 eviluser:x:$uid_eviluser:$gid_domusers:eviluser gecos::/bin/false
3232 slashuser:x:$uid_slashuser:$gid_domusers:slashuser gecos:/:/bin/false
3233 ";
3234         if ($unix_uid != 0) {
3235                 print PASSWD "root:x:$uid_root:$gid_root:root gecos:$prefix_abs:/bin/false
3236 ";
3237         }
3238         close(PASSWD);
3239
3240         unless (open(GROUP, ">$nss_wrapper_group")) {
3241              warn("Unable to open $nss_wrapper_group");
3242              return undef;
3243         }
3244         print GROUP "nobody:x:$gid_nobody:
3245 nogroup:x:$gid_nogroup:nobody
3246 $unix_name-group:x:$unix_gids[0]:
3247 domusers:X:$gid_domusers:
3248 domadmins:X:$gid_domadmins:
3249 userdup:x:$gid_userdup:$unix_name
3250 everyone:x:$gid_everyone:
3251 force_user:x:$gid_force_user:
3252 ";
3253         if ($unix_gids[0] != 0) {
3254                 print GROUP "root:x:$gid_root:
3255 ";
3256         }
3257
3258         close(GROUP);
3259
3260         ## hosts
3261         my $hostname = lc($server);
3262         unless (open(HOSTS, ">>$nss_wrapper_hosts")) {
3263                 warn("Unable to open $nss_wrapper_hosts");
3264                 return undef;
3265         }
3266         print HOSTS "${server_ip} ${hostname}.${dns_domain} ${hostname}\n";
3267         print HOSTS "${server_ipv6} ${hostname}.${dns_domain} ${hostname}\n";
3268         close(HOSTS);
3269
3270         $resolv_conf = "$privatedir/no_resolv.conf" unless defined($resolv_conf);
3271
3272         foreach my $evlog (@eventlog_list) {
3273                 my $evlogtdb = "$eventlogdir/$evlog.tdb";
3274                 open(EVENTLOG, ">$evlogtdb") or die("Unable to open $evlogtdb");
3275                 close(EVENTLOG);
3276         }
3277
3278         $createuser_env{NSS_WRAPPER_PASSWD} = $nss_wrapper_passwd;
3279         $createuser_env{NSS_WRAPPER_GROUP} = $nss_wrapper_group;
3280         $createuser_env{NSS_WRAPPER_HOSTS} = $nss_wrapper_hosts;
3281         $createuser_env{NSS_WRAPPER_HOSTNAME} = "${hostname}.samba.example.com";
3282         if ($ENV{SAMBA_DNS_FAKING}) {
3283                 $createuser_env{RESOLV_WRAPPER_HOSTS} = $dns_host_file;
3284         } else {
3285                 $createuser_env{RESOLV_WRAPPER_CONF} = $resolv_conf;
3286         }
3287         $createuser_env{RESOLV_CONF} = $resolv_conf;
3288
3289         createuser($self, $unix_name, $password, $conffile, \%createuser_env) || die("Unable to create user");
3290         createuser($self, "force_user", $password, $conffile, \%createuser_env) || die("Unable to create force_user");
3291         createuser($self, "smbget_user", $password, $conffile, \%createuser_env) || die("Unable to create smbget_user");
3292         createuser($self, "user1", $password, $conffile, \%createuser_env) || die("Unable to create user1");
3293         createuser($self, "user2", $password, $conffile, \%createuser_env) || die("Unable to create user2");
3294         createuser($self, "gooduser", $password, $conffile, \%createuser_env) || die("Unable to create gooduser");
3295         createuser($self, "eviluser", $password, $conffile, \%createuser_env) || die("Unable to create eviluser");
3296         createuser($self, "slashuser", $password, $conffile, \%createuser_env) || die("Unable to create slashuser");
3297
3298         open(DNS_UPDATE_LIST, ">$prefix/dns_update_list") or die("Unable to open $$prefix/dns_update_list");
3299         print DNS_UPDATE_LIST "A $server. $server_ip\n";
3300         print DNS_UPDATE_LIST "AAAA $server. $server_ipv6\n";
3301         close(DNS_UPDATE_LIST);
3302
3303         print "DONE\n";
3304
3305         $ret{SERVER_IP} = $server_ip;
3306         $ret{SERVER_IPV6} = $server_ipv6;
3307         $ret{NMBD_TEST_LOG} = "$prefix/nmbd_test.log";
3308         $ret{NMBD_TEST_LOG_POS} = 0;
3309         $ret{WINBINDD_TEST_LOG} = "$prefix/winbindd_test.log";
3310         $ret{WINBINDD_TEST_LOG_POS} = 0;
3311         $ret{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
3312         $ret{SMBD_TEST_LOG_POS} = 0;
3313         $ret{SERVERCONFFILE} = $conffile;
3314         $ret{TESTENV_DIR} = $prefix_abs;
3315         $ret{CONFIGURATION} ="--configfile=$conffile";
3316         $ret{LOCK_DIR} = $lockdir;
3317         $ret{SERVER} = $server;
3318         $ret{USERNAME} = $unix_name;
3319         $ret{USERID} = $unix_uid;
3320         $ret{DOMAIN} = $domain;
3321         $ret{SAMSID} = $samsid;
3322         $ret{NETBIOSNAME} = $server;
3323         $ret{PASSWORD} = $password;
3324         $ret{PIDDIR} = $piddir;
3325         $ret{SELFTEST_WINBINDD_SOCKET_DIR} = $wbsockdir;
3326         $ret{NMBD_SOCKET_DIR} = $nmbdsockdir;
3327         $ret{SOCKET_WRAPPER_DEFAULT_IFACE} = $swiface;
3328         $ret{NSS_WRAPPER_PASSWD} = $nss_wrapper_passwd;
3329         $ret{NSS_WRAPPER_GROUP} = $nss_wrapper_group;
3330         $ret{NSS_WRAPPER_HOSTS} = $nss_wrapper_hosts;
3331         $ret{NSS_WRAPPER_HOSTNAME} = "${hostname}.samba.example.com";
3332         $ret{NSS_WRAPPER_MODULE_SO_PATH} = Samba::nss_wrapper_winbind_so_path($self);
3333         $ret{NSS_WRAPPER_MODULE_FN_PREFIX} = "winbind";
3334         if ($ENV{SAMBA_DNS_FAKING}) {
3335                 $ret{RESOLV_WRAPPER_HOSTS} = $dns_host_file;
3336         } else {
3337                 $ret{RESOLV_WRAPPER_CONF} = $resolv_conf;
3338         }
3339         $ret{RESOLV_CONF} = $resolv_conf;
3340         $ret{LOCAL_PATH} = "$shrdir";
3341         $ret{LOGDIR} = $logdir;
3342
3343         #
3344         # Avoid hitting system krb5.conf -
3345         # An env that needs Kerberos will reset this to the real
3346         # value.
3347         #
3348         $ret{KRB5_CONFIG} = abs_path($prefix) . "/no_krb5.conf";
3349
3350         # Define KRB5CCNAME for each environment we set up
3351         $ret{KRB5_CCACHE} = abs_path($prefix) . "/krb5ccache";
3352         $ENV{KRB5CCNAME} = $ret{KRB5_CCACHE};
3353
3354         return \%ret;
3355 }
3356
3357 sub wait_for_start($$$$$)
3358 {
3359         my ($self, $envvars, $nmbd, $winbindd, $smbd) = @_;
3360         my $cmd;
3361         my $netcmd;
3362         my $ret;
3363
3364         if ($nmbd eq "yes") {
3365                 my $count = 0;
3366
3367                 # give time for nbt server to register its names
3368                 print "checking for nmbd\n";
3369
3370                 # This will return quickly when things are up, but be slow if we need to wait for (eg) SSL init
3371                 my $nmblookup = Samba::bindir_path($self, "nmblookup");
3372
3373                 do {
3374                         $ret = system("$nmblookup $envvars->{CONFIGURATION} $envvars->{SERVER}");
3375                         if ($ret != 0) {
3376                                 sleep(1);
3377                         } else {
3378                                 system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} __SAMBA__");
3379                                 system("$nmblookup $envvars->{CONFIGURATION} __SAMBA__");
3380                                 system("$nmblookup $envvars->{CONFIGURATION} -U 10.255.255.255 __SAMBA__");
3381                                 system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} $envvars->{SERVER}");
3382                         }
3383                         $count++;
3384                 } while ($ret != 0 && $count < 10);
3385                 if ($count == 10) {
3386                         print "NMBD not reachable after 10 retries\n";
3387                         teardown_env($self, $envvars);
3388                         return 0;
3389                 }
3390         }
3391
3392         if ($winbindd eq "yes") {
3393             print "checking for winbindd\n";
3394             my $count = 0;
3395             $cmd = "SELFTEST_WINBINDD_SOCKET_DIR='$envvars->{SELFTEST_WINBINDD_SOCKET_DIR}' ";
3396             $cmd .= "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' ";
3397             $cmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' ";
3398             $cmd .= Samba::bindir_path($self, "wbinfo") . " --ping-dc";
3399
3400             do {
3401                 $ret = system($cmd);
3402                 if ($ret != 0) {
3403                     sleep(1);
3404                 }
3405                 $count++;
3406             } while ($ret != 0 && $count < 20);
3407             if ($count == 20) {
3408                 print "WINBINDD not reachable after 20 seconds\n";
3409                 teardown_env($self, $envvars);
3410                 return 0;
3411             }
3412         }
3413
3414         if ($smbd eq "yes") {
3415             # make sure smbd is also up set
3416             print "wait for smbd\n";
3417
3418             my $count = 0;
3419             do {
3420                 if (defined($envvars->{GNUTLS_FORCE_FIPS_MODE})) {
3421                         # We don't have NTLM in FIPS mode, so lets use
3422                         # smbcontrol instead of smbclient.
3423                         $cmd = Samba::bindir_path($self, "smbcontrol");
3424                         $cmd .= " $envvars->{CONFIGURATION}";
3425                         $cmd .= " smbd ping";
3426                 } else {
3427                         # This uses NTLM which is not available in FIPS
3428                         $cmd = Samba::bindir_path($self, "smbclient");
3429                         $cmd .= " $envvars->{CONFIGURATION}";
3430                         $cmd .= " -L $envvars->{SERVER}";
3431                         $cmd .= " -U%";
3432                         $cmd .= " -I $envvars->{SERVER_IP}";
3433                         $cmd .= " -p 139";
3434                 }
3435
3436                 $ret = system($cmd);
3437                 if ($ret != 0) {
3438                     sleep(1);
3439                 }
3440                 $count++
3441             } while ($ret != 0 && $count < 20);
3442             if ($count == 20) {
3443                 print "SMBD failed to start up in a reasonable time (20sec)\n";
3444                 teardown_env($self, $envvars);
3445                 return 0;
3446             }
3447         }
3448
3449         # Ensure we have domain users mapped.
3450         $netcmd = "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' ";
3451         $netcmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' ";
3452         $netcmd .= "UID_WRAPPER_ROOT='1' ";
3453         $netcmd .= Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} ";
3454
3455         $cmd = $netcmd . "groupmap delete ntgroup=domusers";
3456         $ret = system($cmd);
3457
3458         $cmd = $netcmd . "groupmap add rid=513 unixgroup=domusers type=domain";
3459         $ret = system($cmd);
3460         if ($ret != 0) {
3461                 print("\"$cmd\" failed\n");
3462                 return 1;
3463         }
3464
3465         $cmd = $netcmd . "groupmap delete ntgroup=domadmins";
3466         $ret = system($cmd);
3467
3468         $cmd = $netcmd . "groupmap add rid=512 unixgroup=domadmins type=domain";
3469         $ret = system($cmd);
3470         if ($ret != 0) {
3471                 print("\"$cmd\" failed\n");
3472                 return 1;
3473         }
3474
3475         $cmd = $netcmd . "groupmap delete ntgroup=everyone";
3476         $ret = system($cmd);
3477
3478         $cmd = $netcmd . "groupmap add sid=S-1-1-0 unixgroup=everyone type=builtin";
3479         $ret = system($cmd);
3480         if ($ret != 0) {
3481                 print("\"$cmd\" failed\n");
3482                 return 1;
3483         }
3484
3485         # note: creating builtin groups requires winbindd for the
3486         # unix id allocator
3487         my $create_builtin_users = "no";
3488         if ($winbindd eq "yes") {
3489                 $cmd = "SELFTEST_WINBINDD_SOCKET_DIR='$envvars->{SELFTEST_WINBINDD_SOCKET_DIR}' ";
3490                 $cmd .= "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' ";
3491                 $cmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' ";
3492                 $cmd .= Samba::bindir_path($self, "wbinfo") . " --sid-to-gid=S-1-5-32-545";
3493                 my $wbinfo_out = qx($cmd 2>&1);
3494                 if ($? != 0) {
3495                         # wbinfo doesn't give us a better error code then
3496                         # WBC_ERR_DOMAIN_NOT_FOUND, but at least that's
3497                         # different then WBC_ERR_WINBIND_NOT_AVAILABLE
3498                         if ($wbinfo_out !~ /WBC_ERR_DOMAIN_NOT_FOUND/) {
3499                                 print("Failed to run \"wbinfo --sid-to-gid=S-1-5-32-545\": $wbinfo_out");
3500                                 teardown_env($self, $envvars);
3501                                 return 0;
3502                         }
3503                         $create_builtin_users = "yes";
3504                 }
3505         }
3506         if ($create_builtin_users eq "yes") {
3507             $cmd = "SELFTEST_WINBINDD_SOCKET_DIR='$envvars->{SELFTEST_WINBINDD_SOCKET_DIR}' ";
3508             $cmd .= "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' ";
3509             $cmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' ";
3510             $cmd .= Samba::bindir_path($self, "net") . " $envvars->{CONFIGURATION} ";
3511             $cmd .= "sam createbuiltingroup Users";
3512             $ret = system($cmd);
3513             if ($ret != 0) {
3514                 print "Failed to create BUILTIN\\Users group\n";
3515                 teardown_env($self, $envvars);
3516                 return 0;
3517             }
3518
3519             $cmd = Samba::bindir_path($self, "net") . " $envvars->{CONFIGURATION} ";
3520             $cmd .= "cache del IDMAP/SID2XID/S-1-5-32-545";
3521             system($cmd);
3522
3523             $cmd = "SELFTEST_WINBINDD_SOCKET_DIR='$envvars->{SELFTEST_WINBINDD_SOCKET_DIR}' ";
3524             $cmd .= "NSS_WRAPPER_PASSWD='$envvars->{NSS_WRAPPER_PASSWD}' ";
3525             $cmd .= "NSS_WRAPPER_GROUP='$envvars->{NSS_WRAPPER_GROUP}' ";
3526             $cmd .= Samba::bindir_path($self, "wbinfo") . " --sid-to-gid=S-1-5-32-545";
3527             $ret = system($cmd);
3528             if ($ret != 0) {
3529                 print "Missing \"BUILTIN\\Users\", did net sam createbuiltingroup Users fail?\n";
3530                 teardown_env($self, $envvars);
3531                 return 0;
3532             }
3533         }
3534
3535         print $self->getlog_env($envvars);
3536
3537         return 1;
3538 }
3539
3540 ##
3541 ## provision and start of ctdb
3542 ##
3543 sub setup_ctdb($$)
3544 {
3545         my ($self, $prefix) = @_;
3546         my $num_nodes = 3;
3547
3548         my $data = $self->provision_ctdb($prefix, $num_nodes);
3549         $data or return undef;
3550
3551         my $rc = $self->check_or_start_ctdb($data);
3552         if (not $rc) {
3553                 print("check_or_start_ctdb() failed\n");
3554                 return undef;
3555         }
3556
3557         $rc = $self->wait_for_start_ctdb($data);
3558         if (not $rc) {
3559                 print "Cluster startup failed\n";
3560                 return undef;
3561         }
3562
3563         return $data;
3564 }
3565
3566 sub provision_ctdb($$$$)
3567 {
3568         my ($self, $prefix, $num_nodes, $no_delete_prefix) = @_;
3569         my $rc;
3570
3571         print "PROVISIONING CTDB...\n";
3572
3573         my $prefix_abs = abs_path($prefix);
3574
3575         #
3576         # check / create directories:
3577         #
3578         die ("prefix_abs = ''") if $prefix_abs eq "";
3579         die ("prefix_abs = '/'") if $prefix_abs eq "/";
3580
3581         mkdir ($prefix_abs, 0777);
3582
3583         print "CREATE CTDB TEST ENVIRONMENT in '$prefix_abs'...\n";
3584
3585         if (not defined($no_delete_prefix) or not $no_delete_prefix) {
3586                 system("rm -rf $prefix_abs/*");
3587         }
3588
3589         #
3590         # Per-node data
3591         #
3592         my @nodes = ();
3593         for (my $i = 0; $i < $num_nodes; $i++) {
3594                 my %node = ();
3595                 my $server_name = "ctdb${i}";
3596                 my $pub_iface = Samba::get_interface($server_name);
3597                 my $ip = Samba::get_ipv4_addr($server_name);
3598
3599                 $node{NODE_NUMBER} = "$i";
3600                 $node{SERVER_NAME} = "$server_name";
3601                 $node{SOCKET_WRAPPER_DEFAULT_IFACE} = "$pub_iface";
3602                 $node{IP} = "$ip";
3603
3604                 push(@nodes, \%node);
3605         }
3606
3607         #
3608         # nodes
3609         #
3610         my $nodes_file = "$prefix/nodes.in";
3611         unless (open(NODES, ">$nodes_file")) {
3612                 warn("Unable to open nodesfile '$nodes_file'");
3613                 return undef;
3614         }
3615         for (my $i = 0; $i < $num_nodes; $i++) {
3616                 my $ip = $nodes[$i]->{IP};
3617                 print NODES "${ip}\n";
3618         }
3619         close(NODES);
3620
3621         #
3622         # local_daemons.sh setup
3623         #
3624         # Socket wrapper setup is done by selftest.pl, so don't use
3625         # the CTDB-specific setup
3626         #
3627         my $cmd;
3628         $cmd .= "ctdb/tests/local_daemons.sh " . $prefix_abs . " setup";
3629         $cmd .= " -n " . $num_nodes;
3630         $cmd .= " -N " . $nodes_file;
3631         # CTDB should not attempt to manage public addresses -
3632         # clients should just connect to CTDB private addresses
3633         $cmd .= " -P " . "/dev/null";
3634
3635         my $ret = system($cmd);
3636         if ($ret != 0) {
3637                 print("\"$cmd\" failed\n");
3638                 return undef;
3639         }
3640
3641         #
3642         # Unix domain socket and node directory for each daemon
3643         #
3644         for (my $i = 0; $i < $num_nodes; $i++) {
3645                 my ($cmd, $ret, $out);
3646
3647                 my $cmd_prefix = "ctdb/tests/local_daemons.sh ${prefix_abs}";
3648
3649                 #
3650                 # socket
3651                 #
3652
3653                 $cmd = "${cmd_prefix} print-socket ${i}";
3654
3655                 $out = `$cmd`;
3656                 $ret = $?;
3657                 if ($ret != 0) {
3658                     print("\"$cmd\" failed\n");
3659                     return undef;
3660                 }
3661                 chomp $out;
3662                 $nodes[$i]->{SOCKET_FILE} = "$out";
3663
3664                 #
3665                 # node directory
3666                 #
3667
3668                 $cmd = "${cmd_prefix} onnode ${i} 'echo \$CTDB_BASE'";
3669
3670                 $out = `$cmd`;
3671                 $ret = $?;
3672                 if ($ret != 0) {
3673                     print("\"$cmd\" failed\n");
3674                     return undef;
3675                 }
3676                 chomp $out;
3677                 $nodes[$i]->{NODE_PREFIX} = "$out";
3678         }
3679
3680         my %ret = ();
3681
3682         $ret{CTDB_PREFIX} = "$prefix";
3683         $ret{NUM_NODES} = $num_nodes;
3684         $ret{CTDB_NODES} = \@nodes;
3685         $ret{CTDB_NODES_FILE} = $nodes_file;
3686
3687         return \%ret;
3688 }
3689
3690 sub check_or_start_ctdb($$) {
3691         my ($self, $data) = @_;
3692
3693         my $prefix = $data->{CTDB_PREFIX};
3694         my $num_nodes = $data->{NUM_NODES};
3695         my $nodes = $data->{CTDB_NODES};
3696         my $STDIN_READER;
3697
3698         # Share a single stdin pipe for all nodes
3699         pipe($STDIN_READER, $data->{CTDB_STDIN_PIPE});
3700
3701         for (my $i = 0; $i < $num_nodes; $i++) {
3702                 my $node = $nodes->[$i];
3703
3704                 $node->{STDIN_PIPE} = $data->{CTDB_STDIN_PIPE};
3705
3706                 my $cmd = "ctdb/tests/local_daemons.sh";
3707                 my @full_cmd = ("$cmd", "$prefix", "start", "$i");
3708                 my $daemon_ctx = {
3709                         NAME => "ctdbd",
3710                         BINARY_PATH => $cmd,
3711                         FULL_CMD => [ @full_cmd ],
3712                         TEE_STDOUT => 1,
3713                         LOG_FILE => "/dev/null",
3714                         ENV_VARS => {},
3715                 };
3716
3717                 print "STARTING CTDBD (node ${i})\n";
3718
3719                 # This does magic with $STDIN_READER, so use it
3720                 my $ret = Samba::fork_and_exec($self,
3721                                                $node,
3722                                                $daemon_ctx,
3723                                                $STDIN_READER);
3724
3725                 if ($ret == 0) {
3726                         print("\"$cmd\" failed\n");
3727                         teardown_env_ctdb($self, $data);
3728                         return 0;
3729                 }
3730         }
3731
3732         close($STDIN_READER);
3733
3734         return 1;
3735 }
3736
3737 sub wait_for_start_ctdb($$)
3738 {
3739         my ($self, $data) = @_;
3740
3741         my $prefix = $data->{CTDB_PREFIX};
3742
3743         print "Wait for ctdbd...\n";
3744
3745         my $ctdb = Samba::bindir_path($self, "ctdb");
3746         my $cmd;
3747         $cmd .= "ctdb/tests/local_daemons.sh ${prefix} onnode all";
3748         $cmd .= " ${ctdb} nodestatus all 2>&1";
3749
3750         my $count = 0;
3751         my $wait_seconds = 60;
3752         my $out;
3753
3754         until ($count > $wait_seconds) {
3755                 $out = `$cmd`;
3756                 my $ret = $?;
3757                 if ($ret == 0) {
3758                         print "\ncluster became healthy\n";
3759                         last;
3760                 }
3761                 print "Waiting for CTDB...\n";
3762                 sleep(1);
3763                 $count++;
3764         }
3765
3766         if ($count > $wait_seconds) {
3767                 print "\nGiving up to wait for CTDB...\n";
3768                 print "${out}\n\n";
3769                 print "CTDB log:\n";
3770                 $cmd = "ctdb/tests/local_daemons.sh ${prefix} print-log all >&2";
3771                 system($cmd);
3772                 teardown_env_ctdb($self, $data);
3773                 return 0;
3774         }
3775
3776         print "\nCTDB initialized\n";
3777
3778         return 1;
3779 }
3780
3781 1;