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