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