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