e4a2417c6ac6711590d5655eb1a0f64e639441e4
[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 package Samba3;
7
8 use strict;
9 use Cwd qw(abs_path);
10 use FindBin qw($RealBin);
11 use POSIX;
12 use target::Samba;
13
14 sub have_ads($) {
15         my ($self) = @_;
16         my $found_ads = 0;
17         my $smbd_build_options = Samba::bindir_path($self, "smbd") . " -b|";
18         open(IN, $smbd_build_options) or die("Unable to run $smbd_build_options: $!");
19
20         while (<IN>) {
21                 if (/WITH_ADS/) {
22                        $found_ads = 1;
23                 }
24         }
25         close IN;
26
27         # If we were not built with ADS support, pretend we were never even available
28         print "smbd does not have ADS support\n" unless $found_ads;
29         return $found_ads;
30 }
31
32 # return smb.conf parameters applicable to @path, based on the underlying
33 # filesystem type
34 sub get_fs_specific_conf($$)
35 {
36         my ($self, $path) = @_;
37         my $mods = "";
38         my $stat_out = `stat --file-system $path` or return "";
39
40         if ($stat_out =~ m/Type:\s+btrfs/) {
41                 $mods .= "btrfs ";
42         }
43
44         if ($mods) {
45                 return "vfs objects = $mods";
46         }
47
48         return undef;
49 }
50
51 sub new($$) {
52         my ($classname, $bindir, $binary_mapping, $srcdir, $server_maxtime) = @_;
53         my $self = { vars => {},
54                      bindir => $bindir,
55                      binary_mapping => $binary_mapping,
56                      srcdir => $srcdir,
57                      server_maxtime => $server_maxtime
58         };
59         bless $self;
60         return $self;
61 }
62
63 sub teardown_env($$)
64 {
65         my ($self, $envvars) = @_;
66         my $count = 0;
67
68         # This should cause smbd to terminate gracefully
69         close($envvars->{STDIN_PIPE});
70
71         my $smbdpid = $envvars->{SMBD_TL_PID};
72         my $nmbdpid = $envvars->{NMBD_TL_PID};
73         my $winbinddpid = $envvars->{WINBINDD_TL_PID};
74
75         # This should give it time to write out the gcov data
76         until ($count > 20) {
77             my $smbdchild = Samba::cleanup_child($smbdpid, "smbd");
78             my $nmbdchild = Samba::cleanup_child($nmbdpid, "nmbd");
79             my $winbinddchild = Samba::cleanup_child($winbinddpid, "winbindd");
80             if ($smbdchild == -1
81                 && $nmbdchild == -1
82                 && $winbinddchild == -1) {
83                 last;
84             }
85             sleep(1);
86             $count++;
87         }
88
89         if ($count <= 20 && kill(0, $smbdpid, $nmbdpid, $winbinddpid) == 0) {
90             return;
91         }
92
93         $self->stop_sig_term($smbdpid);
94         $self->stop_sig_term($nmbdpid);
95         $self->stop_sig_term($winbinddpid);
96
97         $count = 0;
98         until ($count > 10) {
99             my $smbdchild = Samba::cleanup_child($smbdpid, "smbd");
100             my $nmbdchild = Samba::cleanup_child($nmbdpid, "nmbd");
101             my $winbinddchild = Samba::cleanup_child($winbinddpid, "winbindd");
102             if ($smbdchild == -1
103                 && $nmbdchild == -1
104                 && $winbinddchild == -1) {
105                 last;
106             }
107             sleep(1);
108             $count++;
109         }
110
111         if ($count <= 10 && kill(0, $smbdpid, $nmbdpid, $winbinddpid) == 0) {
112             return;
113         }
114
115         warn("timelimit process did not quit on SIGTERM, sending SIGKILL");
116         $self->stop_sig_kill($smbdpid);
117         $self->stop_sig_kill($nmbdpid);
118         $self->stop_sig_kill($winbinddpid);
119
120         return 0;
121 }
122
123 sub getlog_env_app($$$)
124 {
125         my ($self, $envvars, $name) = @_;
126
127         my $title = "$name LOG of: $envvars->{NETBIOSNAME}\n";
128         my $out = $title;
129
130         open(LOG, "<".$envvars->{$name."_TEST_LOG"});
131
132         seek(LOG, $envvars->{$name."_TEST_LOG_POS"}, SEEK_SET);
133         while (<LOG>) {
134                 $out .= $_;
135         }
136         $envvars->{$name."_TEST_LOG_POS"} = tell(LOG);
137         close(LOG);
138
139         return "" if $out eq $title;
140  
141         return $out;
142 }
143
144 sub getlog_env($$)
145 {
146         my ($self, $envvars) = @_;
147         my $ret = "";
148
149         $ret .= $self->getlog_env_app($envvars, "SMBD");
150         $ret .= $self->getlog_env_app($envvars, "NMBD");
151         $ret .= $self->getlog_env_app($envvars, "WINBINDD");
152
153         return $ret;
154 }
155
156 sub check_env($$)
157 {
158         my ($self, $envvars) = @_;
159
160         my $childpid = waitpid(-1, WNOHANG);
161
162         # TODO ...
163         return 1;
164 }
165
166 sub setup_env($$$)
167 {
168         my ($self, $envname, $path) = @_;
169         
170         if (defined($self->{vars}->{$envname})) {
171                 return $self->{vars}->{$envname};
172         }
173
174         if ($envname eq "s3dc") {
175                 return $self->setup_s3dc("$path/s3dc");
176         } elsif ($envname eq "simpleserver") {
177                 return $self->setup_simpleserver("$path/simpleserver");
178         } elsif ($envname eq "maptoguest") {
179                 return $self->setup_maptoguest("$path/maptoguest");
180         } elsif ($envname eq "ktest") {
181                 return $self->setup_ktest("$path/ktest");
182         } elsif ($envname eq "member") {
183                 if (not defined($self->{vars}->{s3dc})) {
184                         if (not defined($self->setup_s3dc("$path/s3dc"))) {
185                                 return undef;
186                         }
187                 }
188                 return $self->setup_member("$path/member", $self->{vars}->{s3dc});
189         } else {
190                 return "UNKNOWN";
191         }
192 }
193
194 sub setup_s3dc($$)
195 {
196         my ($self, $path) = @_;
197
198         print "PROVISIONING S3DC...";
199
200         my $s3dc_options = "
201         domain master = yes
202         domain logons = yes
203         lanman auth = yes
204
205         rpc_server:epmapper = external
206         rpc_server:spoolss = external
207         rpc_server:lsarpc = external
208         rpc_server:samr = external
209         rpc_server:netlogon = external
210         rpc_server:register_embedded_np = yes
211
212         rpc_daemon:epmd = fork
213         rpc_daemon:spoolssd = fork
214         rpc_daemon:lsasd = fork
215 ";
216
217         my $vars = $self->provision($path,
218                                     "LOCALS3DC2",
219                                     "locals3dc2pass",
220                                     $s3dc_options);
221
222         $vars or return undef;
223
224         if (not $self->check_or_start($vars, "yes", "yes", "yes")) {
225                return undef;
226         }
227
228         $vars->{DC_SERVER} = $vars->{SERVER};
229         $vars->{DC_SERVER_IP} = $vars->{SERVER_IP};
230         $vars->{DC_NETBIOSNAME} = $vars->{NETBIOSNAME};
231         $vars->{DC_USERNAME} = $vars->{USERNAME};
232         $vars->{DC_PASSWORD} = $vars->{PASSWORD};
233
234         $self->{vars}->{s3dc} = $vars;
235
236         return $vars;
237 }
238
239 sub setup_member($$$)
240 {
241         my ($self, $prefix, $s3dcvars) = @_;
242
243         print "PROVISIONING MEMBER...";
244
245         my $member_options = "
246         security = domain
247         server signing = on
248 ";
249         my $ret = $self->provision($prefix,
250                                    "LOCALMEMBER3",
251                                    "localmember3pass",
252                                    $member_options);
253
254         $ret or return undef;
255
256         my $net = Samba::bindir_path($self, "net");
257         my $cmd = "";
258         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
259         $cmd .= "$net join $ret->{CONFIGURATION} $s3dcvars->{DOMAIN} member";
260         $cmd .= " -U$s3dcvars->{USERNAME}\%$s3dcvars->{PASSWORD}";
261
262         if (system($cmd) != 0) {
263             warn("Join failed\n$cmd");
264             return undef;
265         }
266
267         if (not $self->check_or_start($ret, "yes", "yes", "yes")) {
268                return undef;
269         }
270
271         $ret->{DC_SERVER} = $s3dcvars->{SERVER};
272         $ret->{DC_SERVER_IP} = $s3dcvars->{SERVER_IP};
273         $ret->{DC_NETBIOSNAME} = $s3dcvars->{NETBIOSNAME};
274         $ret->{DC_USERNAME} = $s3dcvars->{USERNAME};
275         $ret->{DC_PASSWORD} = $s3dcvars->{PASSWORD};
276
277         return $ret;
278 }
279
280 sub setup_admember($$$$)
281 {
282         my ($self, $prefix, $dcvars) = @_;
283
284         # If we didn't build with ADS, pretend this env was never available
285         if (not $self->have_ads()) {
286                 return "UNKNOWN";
287         }
288
289         print "PROVISIONING S3 AD MEMBER...";
290
291         my $member_options = "
292         security = ads
293         server signing = on
294         workgroup = $dcvars->{DOMAIN}
295         realm = $dcvars->{REALM}
296 ";
297
298         my $ret = $self->provision($prefix,
299                                    "LOCALADMEMBER",
300                                    "loCalMemberPass",
301                                    $member_options);
302
303         $ret or return undef;
304
305         close(USERMAP);
306         $ret->{DOMAIN} = $dcvars->{DOMAIN};
307         $ret->{REALM} = $dcvars->{REALM};
308
309         my $ctx;
310         my $prefix_abs = abs_path($prefix);
311         $ctx = {};
312         $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
313         $ctx->{domain} = $dcvars->{DOMAIN};
314         $ctx->{realm} = $dcvars->{REALM};
315         $ctx->{dnsname} = lc($dcvars->{REALM});
316         $ctx->{kdc_ipv4} = $dcvars->{SERVER_IP};
317         Samba::mk_krb5_conf($ctx, "");
318
319         $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
320
321         my $net = Samba::bindir_path($self, "net");
322         my $cmd = "";
323         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
324         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
325         $cmd .= "$net join $ret->{CONFIGURATION}";
326         $cmd .= " -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD}";
327
328         if (system($cmd) != 0) {
329             warn("Join failed\n$cmd");
330             return undef;
331         }
332
333         # We need world access to this share, as otherwise the domain
334         # administrator from the AD domain provided by Samba4 can't
335         # access the share for tests.
336         chmod 0777, "$prefix/share";
337
338         if (not $self->check_or_start($ret, "yes", "yes", "yes")) {
339                 return undef;
340         }
341
342         $ret->{DC_SERVER} = $dcvars->{SERVER};
343         $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP};
344         $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME};
345         $ret->{DC_USERNAME} = $dcvars->{USERNAME};
346         $ret->{DC_PASSWORD} = $dcvars->{PASSWORD};
347
348         # Special case, this is called from Samba4.pm but needs to use the Samba3 check_env and get_log_env
349         $ret->{target} = $self;
350
351         return $ret;
352 }
353
354 sub setup_admember_rfc2307($$$$)
355 {
356         my ($self, $prefix, $dcvars) = @_;
357
358         # If we didn't build with ADS, pretend this env was never available
359         if (not $self->have_ads()) {
360                 return "UNKNOWN";
361         }
362
363         print "PROVISIONING S3 AD MEMBER WITH idmap_rfc2307 config...";
364
365         my $member_options = "
366         security = ads
367         server signing = on
368         workgroup = $dcvars->{DOMAIN}
369         realm = $dcvars->{REALM}
370         idmap config $dcvars->{DOMAIN} : backend = rfc2307
371         idmap config $dcvars->{DOMAIN} : range = 2000000-2999999
372         idmap config $dcvars->{DOMAIN} : ldap_server = ad
373         idmap config $dcvars->{DOMAIN} : bind_path_user = ou=idmap,dc=samba,dc=example,dc=com
374         idmap config $dcvars->{DOMAIN} : bind_path_group = ou=idmap,dc=samba,dc=example,dc=com
375 ";
376
377         my $ret = $self->provision($prefix,
378                                    "RFC2307MEMBER",
379                                    "loCalMemberPass",
380                                    $member_options);
381
382         $ret or return undef;
383
384         close(USERMAP);
385         $ret->{DOMAIN} = $dcvars->{DOMAIN};
386         $ret->{REALM} = $dcvars->{REALM};
387
388         my $ctx;
389         my $prefix_abs = abs_path($prefix);
390         $ctx = {};
391         $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
392         $ctx->{domain} = $dcvars->{DOMAIN};
393         $ctx->{realm} = $dcvars->{REALM};
394         $ctx->{dnsname} = lc($dcvars->{REALM});
395         $ctx->{kdc_ipv4} = $dcvars->{SERVER_IP};
396         Samba::mk_krb5_conf($ctx, "");
397
398         $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
399
400         my $net = Samba::bindir_path($self, "net");
401         my $cmd = "";
402         $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
403         $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
404         $cmd .= "$net join $ret->{CONFIGURATION}";
405         $cmd .= " -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD}";
406
407         if (system($cmd) != 0) {
408             warn("Join failed\n$cmd");
409             return undef;
410         }
411
412         # We need world access to this share, as otherwise the domain
413         # administrator from the AD domain provided by Samba4 can't
414         # access the share for tests.
415         chmod 0777, "$prefix/share";
416
417         if (not $self->check_or_start($ret, "yes", "yes", "yes")) {
418                 return undef;
419         }
420
421         $ret->{DC_SERVER} = $dcvars->{SERVER};
422         $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP};
423         $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME};
424         $ret->{DC_USERNAME} = $dcvars->{USERNAME};
425         $ret->{DC_PASSWORD} = $dcvars->{PASSWORD};
426
427         # Special case, this is called from Samba4.pm but needs to use the Samba3 check_env and get_log_env
428         $ret->{target} = $self;
429
430         return $ret;
431 }
432
433 sub setup_simpleserver($$)
434 {
435         my ($self, $path) = @_;
436
437         print "PROVISIONING server with security=share...";
438
439         my $prefix_abs = abs_path($path);
440
441         my $simpleserver_options = "
442         lanman auth = yes
443         vfs objects = xattr_tdb streams_depot
444
445 [vfs_aio_fork]
446         path = $prefix_abs/share
447         vfs objects = aio_fork
448         read only = no
449         vfs_aio_fork:erratic_testing_mode=yes
450 ";
451
452         my $vars = $self->provision($path,
453                                     "LOCALSHARE4",
454                                     "local4pass",
455                                     $simpleserver_options);
456
457         $vars or return undef;
458
459         if (not $self->check_or_start($vars, "yes", "no", "yes")) {
460                return undef;
461         }
462
463         $self->{vars}->{simpleserver} = $vars;
464
465         return $vars;
466 }
467
468 sub setup_ktest($$$)
469 {
470         my ($self, $prefix) = @_;
471
472         # If we didn't build with ADS, pretend this env was never available
473         if (not $self->have_ads()) {
474                 return "UNKNOWN";
475         }
476
477         print "PROVISIONING server with security=ads...";
478
479         my $ktest_options = "
480         workgroup = KTEST
481         realm = ktest.samba.example.com
482         security = ads
483         username map = $prefix/lib/username.map
484         server signing = required
485 ";
486
487         my $ret = $self->provision($prefix,
488                                    "LOCALKTEST6",
489                                    "localktest6pass",
490                                    $ktest_options);
491
492         $ret or return undef;
493
494         my $ctx;
495         my $prefix_abs = abs_path($prefix);
496         $ctx = {};
497         $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
498         $ctx->{domain} = "KTEST";
499         $ctx->{realm} = "KTEST.SAMBA.EXAMPLE.COM";
500         $ctx->{dnsname} = lc($ctx->{realm});
501         $ctx->{kdc_ipv4} = "0.0.0.0";
502         Samba::mk_krb5_conf($ctx, "");
503
504         $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
505
506         open(USERMAP, ">$prefix/lib/username.map") or die("Unable to open $prefix/lib/username.map");
507         print USERMAP "
508 $ret->{USERNAME} = KTEST\\Administrator
509 ";
510         close(USERMAP);
511
512 #This is the secrets.tdb created by 'net ads join' from Samba3 to a
513 #Samba4 DC with the same parameters as are being used here.  The
514 #domain SID is S-1-5-21-1071277805-689288055-3486227160
515
516         system("cp $self->{srcdir}/source3/selftest/ktest-secrets.tdb $prefix/private/secrets.tdb");
517         chmod 0600, "$prefix/private/secrets.tdb";
518
519 #Make sure there's no old ntdb file.
520         system("rm -f $prefix/private/secrets.ntdb");
521
522 #This uses a pre-calculated krb5 credentials cache, obtained by running Samba4 with:
523 # "--option=kdc:service ticket lifetime=239232" "--option=kdc:user ticket lifetime=239232" "--option=kdc:renewal lifetime=239232"
524 #
525 #and having in krb5.conf:
526 # ticket_lifetime = 799718400
527 # renew_lifetime = 799718400
528 #
529 # The commands for the -2 keytab where were:
530 # kinit administrator@KTEST.SAMBA.EXAMPLE.COM
531 # kvno host/localktest6@KTEST.SAMBA.EXAMPLE.COM
532 # kvno cifs/localktest6@KTEST.SAMBA.EXAMPLE.COM
533 # kvno host/LOCALKTEST6@KTEST.SAMBA.EXAMPLE.COM
534 # kvno cifs/LOCALKTEST6@KTEST.SAMBA.EXAMPLE.COM
535 #
536 # and then for the -3 keytab, I did
537 #
538 # net changetrustpw; kdestroy and the same again.
539 #
540 # This creates a credential cache with a very long lifetime (2036 at
541 # at 2011-04), and shows that running 'net changetrustpw' does not
542 # break existing logins (for the secrets.tdb method at least).
543 #
544
545         $ret->{KRB5_CCACHE}="FILE:$prefix/krb5_ccache";
546
547         system("cp $self->{srcdir}/source3/selftest/ktest-krb5_ccache-2 $prefix/krb5_ccache-2");
548         chmod 0600, "$prefix/krb5_ccache-2";
549
550         system("cp $self->{srcdir}/source3/selftest/ktest-krb5_ccache-3 $prefix/krb5_ccache-3");
551         chmod 0600, "$prefix/krb5_ccache-3";
552
553         # We need world access to this share, as otherwise the domain
554         # administrator from the AD domain provided by ktest can't
555         # access the share for tests.
556         chmod 0777, "$prefix/share";
557
558         if (not $self->check_or_start($ret, "yes", "no", "yes")) {
559                return undef;
560         }
561         return $ret;
562 }
563
564 sub setup_maptoguest($$)
565 {
566         my ($self, $path) = @_;
567
568         print "PROVISIONING maptoguest...";
569
570         my $options = "
571 map to guest = bad user
572 ";
573
574         my $vars = $self->provision($path,
575                                     "maptoguest",
576                                     "maptoguestpass",
577                                     $options);
578
579         $vars or return undef;
580
581         if (not $self->check_or_start($vars, "yes", "no", "yes")) {
582                return undef;
583         }
584
585         $self->{vars}->{s3maptoguest} = $vars;
586
587         return $vars;
588 }
589
590 sub stop_sig_term($$) {
591         my ($self, $pid) = @_;
592         kill("USR1", $pid) or kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
593 }
594
595 sub stop_sig_kill($$) {
596         my ($self, $pid) = @_;
597         kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
598 }
599
600 sub write_pid($$$)
601 {
602         my ($env_vars, $app, $pid) = @_;
603
604         open(PID, ">$env_vars->{PIDDIR}/timelimit.$app.pid");
605         print PID $pid;
606         close(PID);
607 }
608
609 sub read_pid($$)
610 {
611         my ($env_vars, $app) = @_;
612
613         open(PID, "<$env_vars->{PIDDIR}/timelimit.$app.pid");
614         my $pid = <PID>;
615         close(PID);
616         return $pid;
617 }
618
619 sub check_or_start($$$$$) {
620         my ($self, $env_vars, $nmbd, $winbindd, $smbd) = @_;
621
622         # use a pipe for stdin in the child processes. This allows
623         # those processes to monitor the pipe for EOF to ensure they
624         # exit when the test script exits
625         pipe(STDIN_READER, $env_vars->{STDIN_PIPE});
626
627         unlink($env_vars->{NMBD_TEST_LOG});
628         print "STARTING NMBD...";
629         my $pid = fork();
630         if ($pid == 0) {
631                 open STDOUT, ">$env_vars->{NMBD_TEST_LOG}";
632                 open STDERR, '>&STDOUT';
633
634                 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
635
636                 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
637                 $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
638                 $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
639
640                 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
641                 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
642                 $ENV{NSS_WRAPPER_WINBIND_SO_PATH} = $env_vars->{NSS_WRAPPER_WINBIND_SO_PATH};
643
644                 $ENV{UID_WRAPPER} = "1";
645
646                 if ($nmbd ne "yes") {
647                         $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
648                                 my $signame = shift;
649                                 print("Skip nmbd received signal $signame");
650                                 exit 0;
651                         };
652                         sleep($self->{server_maxtime});
653                         exit 0;
654                 }
655
656                 my @optargs = ("-d0");
657                 if (defined($ENV{NMBD_OPTIONS})) {
658                         @optargs = split(/ /, $ENV{NMBD_OPTIONS});
659                 }
660
661                 $ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "nmbd");
662
663                 my @preargs = (Samba::bindir_path($self, "timelimit"), $self->{server_maxtime});
664                 if(defined($ENV{NMBD_VALGRIND})) { 
665                         @preargs = split(/ /, $ENV{NMBD_VALGRIND});
666                 }
667
668                 close($env_vars->{STDIN_PIPE});
669                 open STDIN, ">&", \*STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
670
671                 exec(@preargs, Samba::bindir_path($self, "nmbd"), "-F", "--no-process-group", "--log-stdout", "-s", $env_vars->{SERVERCONFFILE}, @optargs) or die("Unable to start nmbd: $!");
672         }
673         $env_vars->{NMBD_TL_PID} = $pid;
674         write_pid($env_vars, "nmbd", $pid);
675         print "DONE\n";
676
677         unlink($env_vars->{WINBINDD_TEST_LOG});
678         print "STARTING WINBINDD...";
679         $pid = fork();
680         if ($pid == 0) {
681                 open STDOUT, ">$env_vars->{WINBINDD_TEST_LOG}";
682                 open STDERR, '>&STDOUT';
683
684                 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
685
686                 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
687                 $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
688                 $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
689
690                 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
691                 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
692                 $ENV{NSS_WRAPPER_WINBIND_SO_PATH} = $env_vars->{NSS_WRAPPER_WINBIND_SO_PATH};
693
694                 $ENV{UID_WRAPPER} = "1";
695
696                 if ($winbindd ne "yes") {
697                         $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
698                                 my $signame = shift;
699                                 print("Skip winbindd received signal $signame");
700                                 exit 0;
701                         };
702                         sleep($self->{server_maxtime});
703                         exit 0;
704                 }
705
706                 my @optargs = ("-d0");
707                 if (defined($ENV{WINBINDD_OPTIONS})) {
708                         @optargs = split(/ /, $ENV{WINBINDD_OPTIONS});
709                 }
710
711                 $ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "winbindd");
712
713                 my @preargs = (Samba::bindir_path($self, "timelimit"), $self->{server_maxtime});
714                 if(defined($ENV{WINBINDD_VALGRIND})) {
715                         @preargs = split(/ /, $ENV{WINBINDD_VALGRIND});
716                 }
717
718                 print "Starting winbindd with config $env_vars->{SERVERCONFFILE}\n";
719
720                 close($env_vars->{STDIN_PIPE});
721                 open STDIN, ">&", \*STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
722
723                 exec(@preargs, Samba::bindir_path($self, "winbindd"), "-F", "--no-process-group", "--stdout", "-s", $env_vars->{SERVERCONFFILE}, @optargs) or die("Unable to start winbindd: $!");
724         }
725         $env_vars->{WINBINDD_TL_PID} = $pid;
726         write_pid($env_vars, "winbindd", $pid);
727         print "DONE\n";
728
729         unlink($env_vars->{SMBD_TEST_LOG});
730         print "STARTING SMBD...";
731         $pid = fork();
732         if ($pid == 0) {
733                 open STDOUT, ">$env_vars->{SMBD_TEST_LOG}";
734                 open STDERR, '>&STDOUT';
735
736                 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
737
738                 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
739                 $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
740                 $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
741
742                 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
743                 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
744                 $ENV{NSS_WRAPPER_WINBIND_SO_PATH} = $env_vars->{NSS_WRAPPER_WINBIND_SO_PATH};
745
746                 $ENV{UID_WRAPPER} = "1";
747
748                 if ($smbd ne "yes") {
749                         $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
750                                 my $signame = shift;
751                                 print("Skip smbd received signal $signame");
752                                 exit 0;
753                         };
754                         sleep($self->{server_maxtime});
755                         exit 0;
756                 }
757
758                 $ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "smbd");
759                 my @optargs = ("-d0");
760                 if (defined($ENV{SMBD_OPTIONS})) {
761                         @optargs = split(/ /, $ENV{SMBD_OPTIONS});
762                 }
763                 my @preargs = (Samba::bindir_path($self, "timelimit"), $self->{server_maxtime});
764                 if(defined($ENV{SMBD_VALGRIND})) {
765                         @preargs = split(/ /,$ENV{SMBD_VALGRIND});
766                 }
767
768                 close($env_vars->{STDIN_PIPE});
769                 open STDIN, ">&", \*STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
770
771                 exec(@preargs, Samba::bindir_path($self, "smbd"), "-F", "--no-process-group", "--log-stdout", "-s", $env_vars->{SERVERCONFFILE}, @optargs) or die("Unable to start smbd: $!");
772         }
773         $env_vars->{SMBD_TL_PID} = $pid;
774         write_pid($env_vars, "smbd", $pid);
775         print "DONE\n";
776
777         close(STDIN_READER);
778
779         return $self->wait_for_start($env_vars, $nmbd, $winbindd, $smbd);
780 }
781
782 sub provision($$$$$$)
783 {
784         my ($self, $prefix, $server, $password, $extra_options, $no_delete_prefix) = @_;
785
786         ##
787         ## setup the various environment variables we need
788         ##
789
790         my $swiface = Samba::get_interface($server);
791         my %ret = ();
792         my $server_ip = "127.0.0.$swiface";
793         my $domain = "SAMBA-TEST";
794
795         my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `PATH=/usr/ucb:$ENV{PATH} whoami`);
796         chomp $unix_name;
797         my $unix_uid = $>;
798         my $unix_gids_str = $);
799         my @unix_gids = split(" ", $unix_gids_str);
800
801         my $prefix_abs = abs_path($prefix);
802         my $bindir_abs = abs_path($self->{bindir});
803
804         my $dns_host_file = "$ENV{SELFTEST_PREFIX}/dns_host_file";
805
806         my @dirs = ();
807
808         my $shrdir="$prefix_abs/share";
809         push(@dirs,$shrdir);
810
811         my $libdir="$prefix_abs/lib";
812         push(@dirs,$libdir);
813
814         my $piddir="$prefix_abs/pid";
815         push(@dirs,$piddir);
816
817         my $privatedir="$prefix_abs/private";
818         push(@dirs,$privatedir);
819
820         my $lockdir="$prefix_abs/lockdir";
821         push(@dirs,$lockdir);
822
823         my $eventlogdir="$prefix_abs/lockdir/eventlog";
824         push(@dirs,$eventlogdir);
825
826         my $logdir="$prefix_abs/logs";
827         push(@dirs,$logdir);
828
829         my $driver32dir="$shrdir/W32X86";
830         push(@dirs,$driver32dir);
831
832         my $driver64dir="$shrdir/x64";
833         push(@dirs,$driver64dir);
834
835         my $driver40dir="$shrdir/WIN40";
836         push(@dirs,$driver40dir);
837
838         my $ro_shrdir="$shrdir/root-tmp";
839         push(@dirs,$ro_shrdir);
840
841         my $msdfs_shrdir="$shrdir/msdfsshare";
842         push(@dirs,$msdfs_shrdir);
843
844         my $msdfs_deeppath="$msdfs_shrdir/deeppath";
845         push(@dirs,$msdfs_deeppath);
846
847         # this gets autocreated by winbindd
848         my $wbsockdir="$prefix_abs/winbindd";
849         my $wbsockprivdir="$lockdir/winbindd_privileged";
850
851         my $nmbdsockdir="$prefix_abs/nmbd";
852         unlink($nmbdsockdir);
853
854         my $fs_specific_conf = $self->get_fs_specific_conf($shrdir);
855
856         ## 
857         ## create the test directory layout
858         ##
859         die ("prefix_abs = ''") if $prefix_abs eq "";
860         die ("prefix_abs = '/'") if $prefix_abs eq "/";
861
862         mkdir($prefix_abs, 0777);
863         print "CREATE TEST ENVIRONMENT IN '$prefix'...";
864         if (not defined($no_delete_prefix) or not $no_delete_prefix) {
865             system("rm -rf $prefix_abs/*");
866         }
867         mkdir($_, 0777) foreach(@dirs);
868
869         ##
870         ## lockdir and piddir must be 0755
871         ##
872         chmod 0755, $lockdir;
873         chmod 0755, $piddir;
874
875
876         ##
877         ## create ro and msdfs share layout
878         ##
879
880         chmod 0755, $ro_shrdir;
881         my $unreadable_file = "$ro_shrdir/unreadable_file";
882         unless (open(UNREADABLE_FILE, ">$unreadable_file")) {
883                 warn("Unable to open $unreadable_file");
884                 return undef;
885         }
886         close(UNREADABLE_FILE);
887         chmod 0600, $unreadable_file;
888
889         my $msdfs_target = "$ro_shrdir/msdfs-target";
890         unless (open(MSDFS_TARGET, ">$msdfs_target")) {
891                 warn("Unable to open $msdfs_target");
892                 return undef;
893         }
894         close(MSDFS_TARGET);
895         chmod 0666, $msdfs_target;
896         symlink "msdfs:$server_ip\\ro-tmp", "$msdfs_shrdir/msdfs-src1";
897         symlink "msdfs:$server_ip\\ro-tmp", "$msdfs_shrdir/deeppath/msdfs-src2";
898
899         my $conffile="$libdir/server.conf";
900
901         my $nss_wrapper_pl = "$ENV{PERL} $self->{srcdir}/lib/nss_wrapper/nss_wrapper.pl";
902         my $nss_wrapper_passwd = "$privatedir/passwd";
903         my $nss_wrapper_group = "$privatedir/group";
904
905         my $mod_printer_pl = "$ENV{PERL} $self->{srcdir}/source3/script/tests/printing/modprinter.pl";
906
907         my @eventlog_list = ("dns server", "application");
908
909         ##
910         ## calculate uids and gids
911         ##
912
913         my ($max_uid, $max_gid);
914         my ($uid_nobody, $uid_root, $uid_pdbtest);
915         my ($gid_nobody, $gid_nogroup, $gid_root, $gid_domusers, $gid_domadmins);
916
917         if ($unix_uid < 0xffff - 2) {
918                 $max_uid = 0xffff;
919         } else {
920                 $max_uid = $unix_uid;
921         }
922
923         $uid_root = $max_uid - 1;
924         $uid_nobody = $max_uid - 2;
925         $uid_pdbtest = $max_uid - 3;
926
927         if ($unix_gids[0] < 0xffff - 3) {
928                 $max_gid = 0xffff;
929         } else {
930                 $max_gid = $unix_gids[0];
931         }
932
933         $gid_nobody = $max_gid - 1;
934         $gid_nogroup = $max_gid - 2;
935         $gid_root = $max_gid - 3;
936         $gid_domusers = $max_gid - 4;
937         $gid_domadmins = $max_gid - 5;
938
939         ##
940         ## create conffile
941         ##
942
943         unless (open(CONF, ">$conffile")) {
944                 warn("Unable to open $conffile");
945                 return undef;
946         }
947         print CONF "
948 [global]
949         netbios name = $server
950         interfaces = $server_ip/8
951         bind interfaces only = yes
952         panic action = cd $self->{srcdir} && $self->{srcdir}/selftest/gdb_backtrace %d %\$(MAKE_TEST_BINARY)
953         smbd:suicide mode = yes
954
955         workgroup = $domain
956
957         private dir = $privatedir
958         pid directory = $piddir
959         lock directory = $lockdir
960         log file = $logdir/log.\%m
961         log level = 1
962         debug pid = yes
963         max log size = 0
964
965         state directory = $lockdir
966         cache directory = $lockdir
967
968         passdb backend = tdbsam
969
970         time server = yes
971
972         add user script =               $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action add --name %u --gid $gid_nogroup
973         add group script =              $nss_wrapper_pl --group_path  $nss_wrapper_group  --type group  --action add --name %g
974         add machine script =            $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action add --name %u --gid $gid_nogroup
975         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
976         delete user script =            $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action delete --name %u
977         delete group script =           $nss_wrapper_pl --group_path  $nss_wrapper_group  --type group  --action delete --name %g
978         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
979
980         addprinter command =            $mod_printer_pl -a -s $conffile --
981         deleteprinter command =         $mod_printer_pl -d -s $conffile --
982
983         eventlog list = application \"dns server\"
984
985         kernel oplocks = no
986         kernel change notify = no
987
988         syslog = no
989         printing = bsd
990         printcap name = /dev/null
991
992         winbindd socket directory = $wbsockdir
993         nmbd:socket dir = $nmbdsockdir
994         idmap config * : range = 100000-200000
995         winbind enum users = yes
996         winbind enum groups = yes
997
998 #       min receivefile size = 4000
999
1000         read only = no
1001         server signing = auto
1002
1003         smbd:sharedelay = 100000
1004         smbd:writetimeupdatedelay = 500000
1005         map hidden = no
1006         map system = no
1007         map readonly = no
1008         store dos attributes = yes
1009         create mask = 755
1010         dos filemode = yes
1011         vfs objects = acl_xattr fake_acls xattr_tdb streams_depot
1012
1013         printing = vlp
1014         print command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb print %p %s
1015         lpq command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpq %p
1016         lp rm command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lprm %p %j
1017         lp pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lppause %p %j
1018         lp resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpresume %p %j
1019         queue pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queuepause %p
1020         queue resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queueresume %p
1021         lpq cache time = 0
1022         print notify backchannel = yes
1023
1024         ncalrpc dir = $prefix_abs/ncalrpc
1025         resolv:host file = $dns_host_file
1026
1027         # The samba3.blackbox.smbclient_s3 test uses this to test that
1028         # sending messages works, and that the %m sub works.
1029         message command = mv %s $shrdir/message.%m
1030
1031         # Begin extra options
1032         $extra_options
1033         # End extra options
1034
1035         #Include user defined custom parameters if set
1036 ";
1037
1038         if (defined($ENV{INCLUDE_CUSTOM_CONF})) {
1039                 print CONF "\t$ENV{INCLUDE_CUSTOM_CONF}\n";
1040         }
1041
1042         print CONF "
1043 [tmp]
1044         path = $shrdir
1045         comment = smb username is [%U]
1046 [tmpenc]
1047         path = $shrdir
1048         comment = encrypt smb username is [%U]
1049         smb encrypt = required
1050         vfs objects = dirsort
1051 [tmpguest]
1052         path = $shrdir
1053         guest ok = yes
1054 [guestonly]
1055         path = $shrdir
1056         guest only = yes
1057         guest ok = yes
1058 [forceuser]
1059         path = $shrdir
1060         force user = $unix_name
1061         guest ok = yes
1062 [forcegroup]
1063         path = $shrdir
1064         force group = nogroup
1065         guest ok = yes
1066 [ro-tmp]
1067         path = $ro_shrdir
1068         guest ok = yes
1069 [write-list-tmp]
1070         path = $shrdir
1071         read only = yes
1072         write list = $unix_name
1073 [valid-users-tmp]
1074         path = $shrdir
1075         valid users = $unix_name
1076 [msdfs-share]
1077         path = $msdfs_shrdir
1078         msdfs root = yes
1079         guest ok = yes
1080 [hideunread]
1081         copy = tmp
1082         hide unreadable = yes
1083 [tmpcase]
1084         copy = tmp
1085         case sensitive = yes
1086 [hideunwrite]
1087         copy = tmp
1088         hide unwriteable files = yes
1089 [durable]
1090         copy = tmp
1091         kernel share modes = no
1092         kernel oplocks = no
1093         posix locking = no
1094 [fs_specific]
1095         copy = tmp
1096         $fs_specific_conf
1097 [print1]
1098         copy = tmp
1099         printable = yes
1100
1101 [print2]
1102         copy = print1
1103 [print3]
1104         copy = print1
1105         default devmode = no
1106 [lp]
1107         copy = print1
1108
1109 [nfs4acl_simple]
1110         path = $shrdir
1111         comment = smb username is [%U]
1112         nfs4:mode = simple
1113         vfs objects = nfs4acl_xattr xattr_tdb
1114
1115 [nfs4acl_special]
1116         path = $shrdir
1117         comment = smb username is [%U]
1118         nfs4:mode = special
1119         vfs objects = nfs4acl_xattr xattr_tdb
1120
1121 [xcopy_share]
1122         path = $shrdir
1123         comment = smb username is [%U]
1124         create mask = 777
1125         force create mode = 777
1126 [posix_share]
1127         path = $shrdir
1128         comment = smb username is [%U]
1129         create mask = 0777
1130         force create mode = 0
1131         directory mask = 0777
1132         force directory mode = 0
1133         vfs objects = xattr_tdb
1134 [aio]
1135         copy = tmp
1136         aio read size = 1
1137         aio write size = 1
1138
1139 [print\$]
1140         copy = tmp
1141         ";
1142         close(CONF);
1143
1144         ##
1145         ## create a test account
1146         ##
1147
1148         unless (open(PASSWD, ">$nss_wrapper_passwd")) {
1149            warn("Unable to open $nss_wrapper_passwd");
1150            return undef;
1151         } 
1152         print PASSWD "nobody:x:$uid_nobody:$gid_nobody:nobody gecos:$prefix_abs:/bin/false
1153 $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false
1154 pdbtest:x:$uid_pdbtest:$gid_nogroup:pdbtest gecos:$prefix_abs:/bin/false
1155 ";
1156         if ($unix_uid != 0) {
1157                 print PASSWD "root:x:$uid_root:$gid_root:root gecos:$prefix_abs:/bin/false
1158 ";
1159         }
1160         close(PASSWD);
1161
1162         unless (open(GROUP, ">$nss_wrapper_group")) {
1163              warn("Unable to open $nss_wrapper_group");
1164              return undef;
1165         }
1166         print GROUP "nobody:x:$gid_nobody:
1167 nogroup:x:$gid_nogroup:nobody
1168 $unix_name-group:x:$unix_gids[0]:
1169 domusers:X:$gid_domusers:
1170 domadmins:X:$gid_domadmins:
1171 ";
1172         if ($unix_gids[0] != 0) {
1173                 print GROUP "root:x:$gid_root:
1174 ";
1175         }
1176
1177         close(GROUP);
1178
1179         foreach my $evlog (@eventlog_list) {
1180                 my $evlogtdb = "$eventlogdir/$evlog.tdb";
1181                 open(EVENTLOG, ">$evlogtdb") or die("Unable to open $evlogtdb");
1182                 close(EVENTLOG);
1183         }
1184
1185         $ENV{NSS_WRAPPER_PASSWD} = $nss_wrapper_passwd;
1186         $ENV{NSS_WRAPPER_GROUP} = $nss_wrapper_group;
1187
1188         my $cmd = Samba::bindir_path($self, "smbpasswd")." -c $conffile -L -s -a $unix_name > /dev/null";
1189         unless (open(PWD, "|$cmd")) {
1190              warn("Unable to set password for test account\n$cmd");
1191              return undef;
1192         }
1193         print PWD "$password\n$password\n";
1194         unless (close(PWD)) {
1195              warn("Unable to set password for test account\n$cmd");
1196              return undef; 
1197         }
1198         print "DONE\n";
1199
1200         open(DNS_UPDATE_LIST, ">$prefix/dns_update_list") or die("Unable to open $$prefix/dns_update_list");
1201         print DNS_UPDATE_LIST "A $server. $server_ip";
1202         close(DNS_UPDATE_LIST);
1203
1204         if (system("$ENV{SRCDIR_ABS}/source4/scripting/bin/samba_dnsupdate --all-interfaces --use-file=$dns_host_file -s $conffile --update-list=$prefix/dns_update_list --no-substiutions --no-credentials") != 0) {
1205                 die "Unable to update hostname into $dns_host_file";
1206         }
1207
1208         $ret{SERVER_IP} = $server_ip;
1209         $ret{NMBD_TEST_LOG} = "$prefix/nmbd_test.log";
1210         $ret{NMBD_TEST_LOG_POS} = 0;
1211         $ret{WINBINDD_TEST_LOG} = "$prefix/winbindd_test.log";
1212         $ret{WINBINDD_TEST_LOG_POS} = 0;
1213         $ret{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
1214         $ret{SMBD_TEST_LOG_POS} = 0;
1215         $ret{SERVERCONFFILE} = $conffile;
1216         $ret{CONFIGURATION} ="-s $conffile";
1217         $ret{SERVER} = $server;
1218         $ret{USERNAME} = $unix_name;
1219         $ret{USERID} = $unix_uid;
1220         $ret{DOMAIN} = $domain;
1221         $ret{NETBIOSNAME} = $server;
1222         $ret{PASSWORD} = $password;
1223         $ret{PIDDIR} = $piddir;
1224         $ret{WINBINDD_SOCKET_DIR} = $wbsockdir;
1225         $ret{WINBINDD_PRIV_PIPE_DIR} = $wbsockprivdir;
1226         $ret{NMBD_SOCKET_DIR} = $nmbdsockdir;
1227         $ret{SOCKET_WRAPPER_DEFAULT_IFACE} = $swiface;
1228         $ret{NSS_WRAPPER_PASSWD} = $nss_wrapper_passwd;
1229         $ret{NSS_WRAPPER_GROUP} = $nss_wrapper_group;
1230         $ret{NSS_WRAPPER_WINBIND_SO_PATH} = Samba::nss_wrapper_winbind_so_path($self);
1231         $ret{LOCAL_PATH} = "$shrdir";
1232
1233         return \%ret;
1234 }
1235
1236 sub wait_for_start($$$$$)
1237 {
1238         my ($self, $envvars, $nmbd, $winbindd, $smbd) = @_;
1239         my $ret;
1240
1241         if ($nmbd eq "yes") {
1242             # give time for nbt server to register its names
1243             print "delaying for nbt name registration\n";
1244             sleep(10);
1245             # This will return quickly when things are up, but be slow if we need to wait for (eg) SSL init 
1246             my $nmblookup = Samba::bindir_path($self, "nmblookup3");
1247             system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} __SAMBA__");
1248             system("$nmblookup $envvars->{CONFIGURATION} __SAMBA__");
1249             system("$nmblookup $envvars->{CONFIGURATION} -U 127.255.255.255 __SAMBA__");
1250             system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} $envvars->{SERVER}");
1251             system("$nmblookup $envvars->{CONFIGURATION} $envvars->{SERVER}");
1252         }
1253
1254         if ($winbindd eq "yes") {
1255             print "checking for winbindd\n";
1256             my $count = 0;
1257             do {
1258                 $ret = system("WINBINDD_SOCKET_DIR=" . $envvars->{WINBINDD_SOCKET_DIR} . " " . Samba::bindir_path($self, "wbinfo") . " -p");
1259                 if ($ret != 0) {
1260                     sleep(2);
1261                 }
1262                 $count++;
1263             } while ($ret != 0 && $count < 10);
1264             if ($count == 10) {
1265                 print "WINBINDD not reachable after 20 seconds\n";
1266                 teardown_env($self, $envvars);
1267                 return 0;
1268             }
1269         }
1270
1271         if ($smbd eq "yes") {
1272             # make sure smbd is also up set
1273             print "wait for smbd\n";
1274
1275             my $count = 0;
1276             do {
1277                 $ret = system(Samba::bindir_path($self, "smbclient3") ." $envvars->{CONFIGURATION} -L $envvars->{SERVER} -U% -p 139");
1278                 if ($ret != 0) {
1279                     sleep(2);
1280                 }
1281                 $count++
1282             } while ($ret != 0 && $count < 10);
1283             if ($count == 10) {
1284                 print "SMBD failed to start up in a reasonable time (20sec)\n";
1285                 teardown_env($self, $envvars);
1286                 return 0;
1287             }
1288         }
1289
1290         # Ensure we have domain users mapped.
1291         $ret = system(Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} groupmap add rid=513 unixgroup=domusers type=domain");
1292         if ($ret != 0) {
1293             return 1;
1294         }
1295         $ret = system(Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} groupmap add rid=512 unixgroup=domadmins type=domain");
1296         if ($ret != 0) {
1297             return 1;
1298         }
1299
1300         if ($winbindd eq "yes") {
1301             # note: creating builtin groups requires winbindd for the
1302             # unix id allocator
1303             $ret = system("WINBINDD_SOCKET_DIR=" . $envvars->{WINBINDD_SOCKET_DIR} . " " . Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} sam createbuiltingroup Users");
1304             if ($ret != 0) {
1305                 print "Failed to create BUILTIN\\Users group\n";
1306                 return 0;
1307             }
1308             my $count = 0;
1309             do {
1310                 system(Samba::bindir_path($self, "net") . " $envvars->{CONFIGURATION} cache flush");
1311                 $ret = system("WINBINDD_SOCKET_DIR=" . $envvars->{WINBINDD_SOCKET_DIR} . " " . Samba::bindir_path($self, "wbinfo") . " --sid-to-gid=S-1-5-32-545");
1312                 if ($ret != 0) {
1313                     sleep(2);
1314                 }
1315                 $count++;
1316             } while ($ret != 0 && $count < 10);
1317             if ($count == 10) {
1318                 print "WINBINDD not reachable after 20 seconds\n";
1319                 teardown_env($self, $envvars);
1320                 return 0;
1321             }
1322         }
1323
1324         print $self->getlog_env($envvars);
1325
1326         return 1;
1327 }
1328
1329 1;