dsdb-acl: use acl_check_access_on_objectclass() instead of acl_check_access_on_class()
[Samba/gebeck_regimport.git] / selftest / target / Samba3.pm
blob8546bd28951983010e5dc873bf4e1bbc91268cac
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.
6 package Samba3;
8 use strict;
9 use Cwd qw(abs_path);
10 use FindBin qw($RealBin);
11 use POSIX;
12 use target::Samba;
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: $!");
20 while (<IN>) {
21 if (/WITH_ADS/) {
22 $found_ads = 1;
25 close IN;
27 # If we were not built with ADS support, pretend we were never even available
28 return $found_ads;
31 sub new($$) {
32 my ($classname, $bindir, $binary_mapping, $srcdir, $server_maxtime) = @_;
33 my $self = { vars => {},
34 bindir => $bindir,
35 binary_mapping => $binary_mapping,
36 srcdir => $srcdir,
37 server_maxtime => $server_maxtime
39 bless $self;
40 return $self;
43 sub teardown_env($$)
45 my ($self, $envvars) = @_;
46 my $count = 0;
48 # This should cause smbd to terminate gracefully
49 close($envvars->{STDIN_PIPE});
51 my $smbdpid = $envvars->{SMBD_TL_PID};
52 my $nmbdpid = $envvars->{NMBD_TL_PID};
53 my $winbinddpid = $envvars->{WINBINDD_TL_PID};
55 # This should give it time to write out the gcov data
56 until ($count > 20) {
57 my $smbdchild = Samba::cleanup_child($smbdpid, "smbd");
58 my $nmbdchild = Samba::cleanup_child($nmbdpid, "nmbd");
59 my $winbinddchild = Samba::cleanup_child($winbinddpid, "winbindd");
60 if ($smbdchild == -1
61 && $nmbdchild == -1
62 && $winbinddchild == -1) {
63 last;
65 sleep(1);
66 $count++;
69 if ($count <= 20 && kill(0, $smbdpid, $nmbdpid, $winbinddpid) == 0) {
70 return;
73 $self->stop_sig_term($smbdpid);
74 $self->stop_sig_term($nmbdpid);
75 $self->stop_sig_term($winbinddpid);
77 $count = 0;
78 until ($count > 10) {
79 my $smbdchild = Samba::cleanup_child($smbdpid, "smbd");
80 my $nmbdchild = Samba::cleanup_child($nmbdpid, "nmbd");
81 my $winbinddchild = Samba::cleanup_child($winbinddpid, "winbindd");
82 if ($smbdchild == -1
83 && $nmbdchild == -1
84 && $winbinddchild == -1) {
85 last;
87 sleep(1);
88 $count++;
91 if ($count <= 10 && kill(0, $smbdpid, $nmbdpid, $winbinddpid) == 0) {
92 return;
95 warn("timelimit process did not quit on SIGTERM, sending SIGKILL");
96 $self->stop_sig_kill($smbdpid);
97 $self->stop_sig_kill($nmbdpid);
98 $self->stop_sig_kill($winbinddpid);
100 return 0;
103 sub getlog_env_app($$$)
105 my ($self, $envvars, $name) = @_;
107 my $title = "$name LOG of: $envvars->{NETBIOSNAME}\n";
108 my $out = $title;
110 open(LOG, "<".$envvars->{$name."_TEST_LOG"});
112 seek(LOG, $envvars->{$name."_TEST_LOG_POS"}, SEEK_SET);
113 while (<LOG>) {
114 $out .= $_;
116 $envvars->{$name."_TEST_LOG_POS"} = tell(LOG);
117 close(LOG);
119 return "" if $out eq $title;
121 return $out;
124 sub getlog_env($$)
126 my ($self, $envvars) = @_;
127 my $ret = "";
129 $ret .= $self->getlog_env_app($envvars, "SMBD");
130 $ret .= $self->getlog_env_app($envvars, "NMBD");
131 $ret .= $self->getlog_env_app($envvars, "WINBINDD");
133 return $ret;
136 sub check_env($$)
138 my ($self, $envvars) = @_;
140 my $childpid = waitpid(-1, WNOHANG);
142 # TODO ...
143 return 1;
146 sub setup_env($$$)
148 my ($self, $envname, $path) = @_;
150 if (defined($self->{vars}->{$envname})) {
151 return $self->{vars}->{$envname};
154 if ($envname eq "s3dc") {
155 return $self->setup_s3dc("$path/s3dc");
156 } elsif ($envname eq "simpleserver") {
157 return $self->setup_simpleserver("$path/simpleserver");
158 } elsif ($envname eq "maptoguest") {
159 return $self->setup_maptoguest("$path/maptoguest");
160 } elsif ($envname eq "ktest") {
161 return $self->setup_ktest("$path/ktest");
162 } elsif ($envname eq "member") {
163 if (not defined($self->{vars}->{s3dc})) {
164 if (not defined($self->setup_s3dc("$path/s3dc"))) {
165 return undef;
168 return $self->setup_member("$path/member", $self->{vars}->{s3dc});
169 } else {
170 return "UNKNOWN";
174 sub setup_s3dc($$)
176 my ($self, $path) = @_;
178 print "PROVISIONING S3DC...";
180 my $s3dc_options = "
181 domain master = yes
182 domain logons = yes
183 lanman auth = yes
185 rpc_server:epmapper = external
186 rpc_server:spoolss = external
187 rpc_server:lsarpc = external
188 rpc_server:samr = external
189 rpc_server:netlogon = external
190 rpc_server:register_embedded_np = yes
192 rpc_daemon:epmd = fork
193 rpc_daemon:spoolssd = fork
194 rpc_daemon:lsasd = fork
197 my $vars = $self->provision($path,
198 "LOCALS3DC2",
199 "locals3dc2pass",
200 $s3dc_options);
202 $vars or return undef;
204 if (not $self->check_or_start($vars, "yes", "yes", "yes")) {
205 return undef;
208 $vars->{DC_SERVER} = $vars->{SERVER};
209 $vars->{DC_SERVER_IP} = $vars->{SERVER_IP};
210 $vars->{DC_NETBIOSNAME} = $vars->{NETBIOSNAME};
211 $vars->{DC_USERNAME} = $vars->{USERNAME};
212 $vars->{DC_PASSWORD} = $vars->{PASSWORD};
214 $self->{vars}->{s3dc} = $vars;
216 return $vars;
219 sub setup_member($$$)
221 my ($self, $prefix, $s3dcvars) = @_;
223 print "PROVISIONING MEMBER...";
225 my $member_options = "
226 security = domain
227 server signing = on
229 my $ret = $self->provision($prefix,
230 "LOCALMEMBER3",
231 "localmember3pass",
232 $member_options);
234 $ret or return undef;
236 my $net = Samba::bindir_path($self, "net");
237 my $cmd = "";
238 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
239 $cmd .= "$net join $ret->{CONFIGURATION} $s3dcvars->{DOMAIN} member";
240 $cmd .= " -U$s3dcvars->{USERNAME}\%$s3dcvars->{PASSWORD}";
242 if (system($cmd) != 0) {
243 warn("Join failed\n$cmd");
244 return undef;
247 if (not $self->check_or_start($ret, "yes", "yes", "yes")) {
248 return undef;
251 $ret->{DC_SERVER} = $s3dcvars->{SERVER};
252 $ret->{DC_SERVER_IP} = $s3dcvars->{SERVER_IP};
253 $ret->{DC_NETBIOSNAME} = $s3dcvars->{NETBIOSNAME};
254 $ret->{DC_USERNAME} = $s3dcvars->{USERNAME};
255 $ret->{DC_PASSWORD} = $s3dcvars->{PASSWORD};
257 return $ret;
260 sub setup_admember($$$$)
262 my ($self, $prefix, $dcvars) = @_;
264 # If we didn't build with ADS, pretend this env was never available
265 if (not $self->have_ads()) {
266 return "UNKNOWN";
269 print "PROVISIONING S3 AD MEMBER...";
271 my $member_options = "
272 security = ads
273 server signing = on
274 workgroup = $dcvars->{DOMAIN}
275 realm = $dcvars->{REALM}
278 my $ret = $self->provision($prefix,
279 "LOCALADMEMBER",
280 "loCalMemberPass",
281 $member_options);
283 $ret or return undef;
285 close(USERMAP);
286 $ret->{DOMAIN} = $dcvars->{DOMAIN};
287 $ret->{REALM} = $dcvars->{REALM};
289 my $ctx;
290 my $prefix_abs = abs_path($prefix);
291 $ctx = {};
292 $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
293 $ctx->{domain} = $dcvars->{DOMAIN};
294 $ctx->{realm} = $dcvars->{REALM};
295 $ctx->{dnsname} = lc($dcvars->{REALM});
296 $ctx->{kdc_ipv4} = $dcvars->{SERVER_IP};
297 Samba::mk_krb5_conf($ctx, "");
299 $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
301 my $net = Samba::bindir_path($self, "net");
302 my $cmd = "";
303 $cmd .= "SOCKET_WRAPPER_DEFAULT_IFACE=\"$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}\" ";
304 $cmd .= "KRB5_CONFIG=\"$ret->{KRB5_CONFIG}\" ";
305 $cmd .= "$net join $ret->{CONFIGURATION}";
306 $cmd .= " -U$dcvars->{USERNAME}\%$dcvars->{PASSWORD}";
308 if (system($cmd) != 0) {
309 warn("Join failed\n$cmd");
310 return undef;
313 # We need world access to this share, as otherwise the domain
314 # administrator from the AD domain provided by Samba4 can't
315 # access the share for tests.
316 chmod 0777, "$prefix/share";
318 if (not $self->check_or_start($ret, "yes", "yes", "yes")) {
319 return undef;
322 $ret->{DC_SERVER} = $dcvars->{SERVER};
323 $ret->{DC_SERVER_IP} = $dcvars->{SERVER_IP};
324 $ret->{DC_NETBIOSNAME} = $dcvars->{NETBIOSNAME};
325 $ret->{DC_USERNAME} = $dcvars->{USERNAME};
326 $ret->{DC_PASSWORD} = $dcvars->{PASSWORD};
328 # Special case, this is called from Samba4.pm but needs to use the Samba3 check_env and get_log_env
329 $ret->{target} = $self;
331 return $ret;
334 sub setup_simpleserver($$)
336 my ($self, $path) = @_;
337 my $vfs_modulesdir_abs = $ENV{VFSLIBDIR};
339 print "PROVISIONING server with security=share...";
341 my $prefix_abs = abs_path($path);
343 my $simpleserver_options = "
344 lanman auth = yes
345 vfs objects = $vfs_modulesdir_abs/xattr_tdb.so $vfs_modulesdir_abs/streams_depot.so
347 [vfs_aio_fork]
348 path = $prefix_abs/share
349 vfs objects = $vfs_modulesdir_abs/aio_fork.so
350 read only = no
351 vfs_aio_fork:erratic_testing_mode=yes
354 my $vars = $self->provision($path,
355 "LOCALSHARE4",
356 "local4pass",
357 $simpleserver_options);
359 $vars or return undef;
361 if (not $self->check_or_start($vars, "yes", "no", "yes")) {
362 return undef;
365 $self->{vars}->{simpleserver} = $vars;
367 return $vars;
370 sub setup_ktest($$$)
372 my ($self, $prefix) = @_;
374 # If we didn't build with ADS, pretend this env was never available
375 if (not $self->have_ads()) {
376 return "UNKNOWN";
379 print "PROVISIONING server with security=ads...";
381 my $ktest_options = "
382 workgroup = KTEST
383 realm = ktest.samba.example.com
384 security = ads
385 username map = $prefix/lib/username.map
386 server signing = required
389 my $ret = $self->provision($prefix,
390 "LOCALKTEST6",
391 "localktest6pass",
392 $ktest_options);
394 $ret or return undef;
396 my $ctx;
397 my $prefix_abs = abs_path($prefix);
398 $ctx = {};
399 $ctx->{krb5_conf} = "$prefix_abs/lib/krb5.conf";
400 $ctx->{domain} = "KTEST";
401 $ctx->{realm} = "KTEST.SAMBA.EXAMPLE.COM";
402 $ctx->{dnsname} = lc($ctx->{realm});
403 $ctx->{kdc_ipv4} = "0.0.0.0";
404 Samba::mk_krb5_conf($ctx, "");
406 $ret->{KRB5_CONFIG} = $ctx->{krb5_conf};
408 open(USERMAP, ">$prefix/lib/username.map") or die("Unable to open $prefix/lib/username.map");
409 print USERMAP "
410 $ret->{USERNAME} = KTEST\\Administrator
412 close(USERMAP);
414 #This is the secrets.tdb created by 'net ads join' from Samba3 to a
415 #Samba4 DC with the same parameters as are being used here. The
416 #domain SID is S-1-5-21-1071277805-689288055-3486227160
418 system("cp $self->{srcdir}/source3/selftest/ktest-secrets.tdb $prefix/private/secrets.tdb");
419 chmod 0600, "$prefix/private/secrets.tdb";
421 #This uses a pre-calculated krb5 credentials cache, obtained by running Samba4 with:
422 # "--option=kdc:service ticket lifetime=239232" "--option=kdc:user ticket lifetime=239232" "--option=kdc:renewal lifetime=239232"
424 #and having in krb5.conf:
425 # ticket_lifetime = 799718400
426 # renew_lifetime = 799718400
428 # The commands for the -2 keytab where were:
429 # kinit administrator@KTEST.SAMBA.EXAMPLE.COM
430 # kvno host/localktest6@KTEST.SAMBA.EXAMPLE.COM
431 # kvno cifs/localktest6@KTEST.SAMBA.EXAMPLE.COM
432 # kvno host/LOCALKTEST6@KTEST.SAMBA.EXAMPLE.COM
433 # kvno cifs/LOCALKTEST6@KTEST.SAMBA.EXAMPLE.COM
435 # and then for the -3 keytab, I did
437 # net changetrustpw; kdestroy and the same again.
439 # This creates a credential cache with a very long lifetime (2036 at
440 # at 2011-04), and shows that running 'net changetrustpw' does not
441 # break existing logins (for the secrets.tdb method at least).
444 $ret->{KRB5_CCACHE}="FILE:$prefix/krb5_ccache";
446 system("cp $self->{srcdir}/source3/selftest/ktest-krb5_ccache-2 $prefix/krb5_ccache-2");
447 chmod 0600, "$prefix/krb5_ccache-2";
449 system("cp $self->{srcdir}/source3/selftest/ktest-krb5_ccache-3 $prefix/krb5_ccache-3");
450 chmod 0600, "$prefix/krb5_ccache-3";
452 # We need world access to this share, as otherwise the domain
453 # administrator from the AD domain provided by ktest can't
454 # access the share for tests.
455 chmod 0777, "$prefix/share";
457 if (not $self->check_or_start($ret, "yes", "no", "yes")) {
458 return undef;
460 return $ret;
463 sub setup_maptoguest($$)
465 my ($self, $path) = @_;
467 print "PROVISIONING maptoguest...";
469 my $options = "
470 map to guest = bad user
473 my $vars = $self->provision($path,
474 "maptoguest",
475 "maptoguestpass",
476 $options);
478 $vars or return undef;
480 if (not $self->check_or_start($vars, "yes", "no", "yes")) {
481 return undef;
484 $self->{vars}->{s3maptoguest} = $vars;
486 return $vars;
489 sub stop_sig_term($$) {
490 my ($self, $pid) = @_;
491 kill("USR1", $pid) or kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
494 sub stop_sig_kill($$) {
495 my ($self, $pid) = @_;
496 kill("ALRM", $pid) or warn("Unable to kill $pid: $!");
499 sub write_pid($$$)
501 my ($env_vars, $app, $pid) = @_;
503 open(PID, ">$env_vars->{PIDDIR}/timelimit.$app.pid");
504 print PID $pid;
505 close(PID);
508 sub read_pid($$)
510 my ($env_vars, $app) = @_;
512 open(PID, "<$env_vars->{PIDDIR}/timelimit.$app.pid");
513 my $pid = <PID>;
514 close(PID);
515 return $pid;
518 sub check_or_start($$$$$) {
519 my ($self, $env_vars, $nmbd, $winbindd, $smbd) = @_;
521 # use a pipe for stdin in the child processes. This allows
522 # those processes to monitor the pipe for EOF to ensure they
523 # exit when the test script exits
524 pipe(STDIN_READER, $env_vars->{STDIN_PIPE});
526 unlink($env_vars->{NMBD_TEST_LOG});
527 print "STARTING NMBD...";
528 my $pid = fork();
529 if ($pid == 0) {
530 open STDOUT, ">$env_vars->{NMBD_TEST_LOG}";
531 open STDERR, '>&STDOUT';
533 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
535 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
536 $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
537 $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
539 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
540 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
541 $ENV{NSS_WRAPPER_WINBIND_SO_PATH} = $env_vars->{NSS_WRAPPER_WINBIND_SO_PATH};
543 $ENV{UID_WRAPPER} = "1";
545 if ($nmbd ne "yes") {
546 $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
547 my $signame = shift;
548 print("Skip nmbd received signal $signame");
549 exit 0;
551 sleep($self->{server_maxtime});
552 exit 0;
555 my @optargs = ("-d0");
556 if (defined($ENV{NMBD_OPTIONS})) {
557 @optargs = split(/ /, $ENV{NMBD_OPTIONS});
560 $ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "nmbd");
562 my @preargs = (Samba::bindir_path($self, "timelimit"), $self->{server_maxtime});
563 if(defined($ENV{NMBD_VALGRIND})) {
564 @preargs = split(/ /, $ENV{NMBD_VALGRIND});
567 close($env_vars->{STDIN_PIPE});
568 open STDIN, ">&", \*STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
570 exec(@preargs, Samba::bindir_path($self, "nmbd"), "-F", "--no-process-group", "--log-stdout", "-s", $env_vars->{SERVERCONFFILE}, @optargs) or die("Unable to start nmbd: $!");
572 $env_vars->{NMBD_TL_PID} = $pid;
573 write_pid($env_vars, "nmbd", $pid);
574 print "DONE\n";
576 unlink($env_vars->{WINBINDD_TEST_LOG});
577 print "STARTING WINBINDD...";
578 $pid = fork();
579 if ($pid == 0) {
580 open STDOUT, ">$env_vars->{WINBINDD_TEST_LOG}";
581 open STDERR, '>&STDOUT';
583 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
585 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
586 $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
587 $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
589 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
590 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
591 $ENV{NSS_WRAPPER_WINBIND_SO_PATH} = $env_vars->{NSS_WRAPPER_WINBIND_SO_PATH};
593 $ENV{UID_WRAPPER} = "1";
595 if ($winbindd ne "yes") {
596 $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
597 my $signame = shift;
598 print("Skip winbindd received signal $signame");
599 exit 0;
601 sleep($self->{server_maxtime});
602 exit 0;
605 my @optargs = ("-d0");
606 if (defined($ENV{WINBINDD_OPTIONS})) {
607 @optargs = split(/ /, $ENV{WINBINDD_OPTIONS});
610 $ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "winbindd");
612 my @preargs = (Samba::bindir_path($self, "timelimit"), $self->{server_maxtime});
613 if(defined($ENV{WINBINDD_VALGRIND})) {
614 @preargs = split(/ /, $ENV{WINBINDD_VALGRIND});
617 print "Starting winbindd with config $env_vars->{SERVERCONFFILE}\n";
619 close($env_vars->{STDIN_PIPE});
620 open STDIN, ">&", \*STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
622 exec(@preargs, Samba::bindir_path($self, "winbindd"), "-F", "--no-process-group", "--stdout", "-s", $env_vars->{SERVERCONFFILE}, @optargs) or die("Unable to start winbindd: $!");
624 $env_vars->{WINBINDD_TL_PID} = $pid;
625 write_pid($env_vars, "winbindd", $pid);
626 print "DONE\n";
628 unlink($env_vars->{SMBD_TEST_LOG});
629 print "STARTING SMBD...";
630 $pid = fork();
631 if ($pid == 0) {
632 open STDOUT, ">$env_vars->{SMBD_TEST_LOG}";
633 open STDERR, '>&STDOUT';
635 SocketWrapper::set_default_iface($env_vars->{SOCKET_WRAPPER_DEFAULT_IFACE});
637 $ENV{KRB5_CONFIG} = $env_vars->{KRB5_CONFIG};
638 $ENV{WINBINDD_SOCKET_DIR} = $env_vars->{WINBINDD_SOCKET_DIR};
639 $ENV{NMBD_SOCKET_DIR} = $env_vars->{NMBD_SOCKET_DIR};
641 $ENV{NSS_WRAPPER_PASSWD} = $env_vars->{NSS_WRAPPER_PASSWD};
642 $ENV{NSS_WRAPPER_GROUP} = $env_vars->{NSS_WRAPPER_GROUP};
643 $ENV{NSS_WRAPPER_WINBIND_SO_PATH} = $env_vars->{NSS_WRAPPER_WINBIND_SO_PATH};
645 $ENV{UID_WRAPPER} = "1";
647 if ($smbd ne "yes") {
648 $SIG{USR1} = $SIG{ALRM} = $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub {
649 my $signame = shift;
650 print("Skip smbd received signal $signame");
651 exit 0;
653 sleep($self->{server_maxtime});
654 exit 0;
657 $ENV{MAKE_TEST_BINARY} = Samba::bindir_path($self, "smbd");
658 my @optargs = ("-d0");
659 if (defined($ENV{SMBD_OPTIONS})) {
660 @optargs = split(/ /, $ENV{SMBD_OPTIONS});
662 my @preargs = (Samba::bindir_path($self, "timelimit"), $self->{server_maxtime});
663 if(defined($ENV{SMBD_VALGRIND})) {
664 @preargs = split(/ /,$ENV{SMBD_VALGRIND});
667 close($env_vars->{STDIN_PIPE});
668 open STDIN, ">&", \*STDIN_READER or die "can't dup STDIN_READER to STDIN: $!";
670 exec(@preargs, Samba::bindir_path($self, "smbd"), "-F", "--no-process-group", "--log-stdout", "-s", $env_vars->{SERVERCONFFILE}, @optargs) or die("Unable to start smbd: $!");
672 $env_vars->{SMBD_TL_PID} = $pid;
673 write_pid($env_vars, "smbd", $pid);
674 print "DONE\n";
676 close(STDIN_READER);
678 return $self->wait_for_start($env_vars, $nmbd, $winbindd, $smbd);
681 sub provision($$$$$$)
683 my ($self, $prefix, $server, $password, $extra_options, $no_delete_prefix) = @_;
686 ## setup the various environment variables we need
689 my $swiface = Samba::get_interface($server);
690 my %ret = ();
691 my $server_ip = "127.0.0.$swiface";
692 my $domain = "SAMBA-TEST";
694 my $unix_name = ($ENV{USER} or $ENV{LOGNAME} or `PATH=/usr/ucb:$ENV{PATH} whoami`);
695 chomp $unix_name;
696 my $unix_uid = $>;
697 my $unix_gids_str = $);
698 my @unix_gids = split(" ", $unix_gids_str);
700 my $prefix_abs = abs_path($prefix);
701 my $bindir_abs = abs_path($self->{bindir});
702 my $vfs_modulesdir_abs = ($ENV{VFSLIBDIR} or $bindir_abs);
704 my $dns_host_file = "$ENV{SELFTEST_PREFIX}/dns_host_file";
706 my @dirs = ();
708 my $shrdir="$prefix_abs/share";
709 push(@dirs,$shrdir);
711 my $libdir="$prefix_abs/lib";
712 push(@dirs,$libdir);
714 my $piddir="$prefix_abs/pid";
715 push(@dirs,$piddir);
717 my $privatedir="$prefix_abs/private";
718 push(@dirs,$privatedir);
720 my $lockdir="$prefix_abs/lockdir";
721 push(@dirs,$lockdir);
723 my $eventlogdir="$prefix_abs/lockdir/eventlog";
724 push(@dirs,$eventlogdir);
726 my $logdir="$prefix_abs/logs";
727 push(@dirs,$logdir);
729 my $driver32dir="$shrdir/W32X86";
730 push(@dirs,$driver32dir);
732 my $driver64dir="$shrdir/x64";
733 push(@dirs,$driver64dir);
735 my $driver40dir="$shrdir/WIN40";
736 push(@dirs,$driver40dir);
738 my $ro_shrdir="$shrdir/root-tmp";
739 push(@dirs,$ro_shrdir);
741 my $msdfs_shrdir="$shrdir/msdfsshare";
742 push(@dirs,$msdfs_shrdir);
744 my $msdfs_deeppath="$msdfs_shrdir/deeppath";
745 push(@dirs,$msdfs_deeppath);
747 # this gets autocreated by winbindd
748 my $wbsockdir="$prefix_abs/winbindd";
749 my $wbsockprivdir="$lockdir/winbindd_privileged";
751 my $nmbdsockdir="$prefix_abs/nmbd";
752 unlink($nmbdsockdir);
755 ## create the test directory layout
757 die ("prefix_abs = ''") if $prefix_abs eq "";
758 die ("prefix_abs = '/'") if $prefix_abs eq "/";
760 mkdir($prefix_abs, 0777);
761 print "CREATE TEST ENVIRONMENT IN '$prefix'...";
762 if (not defined($no_delete_prefix) or not $no_delete_prefix) {
763 system("rm -rf $prefix_abs/*");
765 mkdir($_, 0777) foreach(@dirs);
768 ## lockdir and piddir must be 0755
770 chmod 0755, $lockdir;
771 chmod 0755, $piddir;
775 ## create ro and msdfs share layout
778 chmod 0755, $ro_shrdir;
779 my $unreadable_file = "$ro_shrdir/unreadable_file";
780 unless (open(UNREADABLE_FILE, ">$unreadable_file")) {
781 warn("Unable to open $unreadable_file");
782 return undef;
784 close(UNREADABLE_FILE);
785 chmod 0600, $unreadable_file;
787 my $msdfs_target = "$ro_shrdir/msdfs-target";
788 unless (open(MSDFS_TARGET, ">$msdfs_target")) {
789 warn("Unable to open $msdfs_target");
790 return undef;
792 close(MSDFS_TARGET);
793 chmod 0666, $msdfs_target;
794 symlink "msdfs:$server_ip\\ro-tmp", "$msdfs_shrdir/msdfs-src1";
795 symlink "msdfs:$server_ip\\ro-tmp", "$msdfs_shrdir/deeppath/msdfs-src2";
797 my $conffile="$libdir/server.conf";
799 my $nss_wrapper_pl = "$ENV{PERL} $self->{srcdir}/lib/nss_wrapper/nss_wrapper.pl";
800 my $nss_wrapper_passwd = "$privatedir/passwd";
801 my $nss_wrapper_group = "$privatedir/group";
803 my $mod_printer_pl = "$ENV{PERL} $self->{srcdir}/source3/script/tests/printing/modprinter.pl";
805 my @eventlog_list = ("dns server", "application");
808 ## calculate uids and gids
811 my ($max_uid, $max_gid);
812 my ($uid_nobody, $uid_root, $uid_pdbtest);
813 my ($gid_nobody, $gid_nogroup, $gid_root, $gid_domusers, $gid_domadmins);
815 if ($unix_uid < 0xffff - 2) {
816 $max_uid = 0xffff;
817 } else {
818 $max_uid = $unix_uid;
821 $uid_root = $max_uid - 1;
822 $uid_nobody = $max_uid - 2;
823 $uid_pdbtest = $max_uid - 3;
825 if ($unix_gids[0] < 0xffff - 3) {
826 $max_gid = 0xffff;
827 } else {
828 $max_gid = $unix_gids[0];
831 $gid_nobody = $max_gid - 1;
832 $gid_nogroup = $max_gid - 2;
833 $gid_root = $max_gid - 3;
834 $gid_domusers = $max_gid - 4;
835 $gid_domadmins = $max_gid - 5;
838 ## create conffile
841 unless (open(CONF, ">$conffile")) {
842 warn("Unable to open $conffile");
843 return undef;
845 print CONF "
846 [global]
847 netbios name = $server
848 interfaces = $server_ip/8
849 bind interfaces only = yes
850 panic action = $self->{srcdir}/selftest/gdb_backtrace %d %\$(MAKE_TEST_BINARY)
851 smbd:suicide mode = yes
853 workgroup = $domain
855 private dir = $privatedir
856 pid directory = $piddir
857 lock directory = $lockdir
858 log file = $logdir/log.\%m
859 log level = 1
860 debug pid = yes
861 max log size = 0
863 state directory = $lockdir
864 cache directory = $lockdir
866 passdb backend = tdbsam
868 time server = yes
870 add user script = $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action add --name %u --gid $gid_nogroup
871 add group script = $nss_wrapper_pl --group_path $nss_wrapper_group --type group --action add --name %g
872 add machine script = $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action add --name %u --gid $gid_nogroup
873 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
874 delete user script = $nss_wrapper_pl --passwd_path $nss_wrapper_passwd --type passwd --action delete --name %u
875 delete group script = $nss_wrapper_pl --group_path $nss_wrapper_group --type group --action delete --name %g
876 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
878 addprinter command = $mod_printer_pl -a -s $conffile --
879 deleteprinter command = $mod_printer_pl -d -s $conffile --
881 eventlog list = application \"dns server\"
883 kernel oplocks = no
884 kernel change notify = no
886 syslog = no
887 printing = bsd
888 printcap name = /dev/null
890 winbindd:socket dir = $wbsockdir
891 nmbd:socket dir = $nmbdsockdir
892 idmap config * : range = 100000-200000
893 winbind enum users = yes
894 winbind enum groups = yes
896 # min receivefile size = 4000
898 read only = no
899 server signing = auto
901 smbd:sharedelay = 100000
902 smbd:writetimeupdatedelay = 500000
903 map hidden = no
904 map system = no
905 map readonly = no
906 store dos attributes = yes
907 create mask = 0777
908 directory mask = 0777
909 dos filemode = yes
910 vfs objects = $vfs_modulesdir_abs/acl_xattr.so $vfs_modulesdir_abs/fake_acls.so $vfs_modulesdir_abs/xattr_tdb.so $vfs_modulesdir_abs/streams_depot.so
912 printing = vlp
913 print command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb print %p %s
914 lpq command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpq %p
915 lp rm command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lprm %p %j
916 lp pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lppause %p %j
917 lp resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb lpresume %p %j
918 queue pause command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queuepause %p
919 queue resume command = $bindir_abs/vlp tdbfile=$lockdir/vlp.tdb queueresume %p
920 lpq cache time = 0
922 ncalrpc dir = $prefix_abs/ncalrpc
923 resolv:host file = $dns_host_file
925 # The samba3.blackbox.smbclient_s3 test uses this to test that
926 # sending messages works, and that the %m sub works.
927 message command = mv %s $shrdir/message.%m
929 # Begin extra options
930 $extra_options
931 # End extra options
933 #Include user defined custom parameters if set
936 if (defined($ENV{INCLUDE_CUSTOM_CONF})) {
937 print CONF "\t$ENV{INCLUDE_CUSTOM_CONF}\n";
940 print CONF "
941 [tmp]
942 path = $shrdir
943 comment = smb username is [%U]
944 [tmpenc]
945 path = $shrdir
946 comment = encrypt smb username is [%U]
947 smb encrypt = required
948 [tmpguest]
949 path = $shrdir
950 guest ok = yes
951 [guestonly]
952 path = $shrdir
953 guest only = yes
954 guest ok = yes
955 [forceuser]
956 path = $shrdir
957 force user = $unix_name
958 guest ok = yes
959 [forcegroup]
960 path = $shrdir
961 force group = nogroup
962 guest ok = yes
963 [ro-tmp]
964 path = $ro_shrdir
965 guest ok = yes
966 [write-list-tmp]
967 path = $shrdir
968 read only = yes
969 write list = $unix_name
970 [valid-users-tmp]
971 path = $shrdir
972 valid users = $unix_name
973 [msdfs-share]
974 path = $msdfs_shrdir
975 msdfs root = yes
976 guest ok = yes
977 [hideunread]
978 copy = tmp
979 hide unreadable = yes
980 [tmpcase]
981 copy = tmp
982 case sensitive = yes
983 [hideunwrite]
984 copy = tmp
985 hide unwriteable files = yes
986 [durable]
987 copy = tmp
988 kernel share modes = no
989 kernel oplocks = no
990 posix locking = no
991 [print1]
992 copy = tmp
993 printable = yes
995 [print2]
996 copy = print1
997 [print3]
998 copy = print1
999 default devmode = no
1000 [lp]
1001 copy = print1
1002 [xcopy_share]
1003 path = $shrdir
1004 comment = smb username is [%U]
1005 create mask = 777
1006 force create mode = 777
1007 [posix_share]
1008 path = $shrdir
1009 comment = smb username is [%U]
1010 create mask = 0777
1011 force create mode = 0
1012 directory mask = 0777
1013 force directory mode = 0
1014 vfs objects = $vfs_modulesdir_abs/xattr_tdb.so
1016 [print\$]
1017 copy = tmp
1019 close(CONF);
1022 ## create a test account
1025 unless (open(PASSWD, ">$nss_wrapper_passwd")) {
1026 warn("Unable to open $nss_wrapper_passwd");
1027 return undef;
1029 print PASSWD "nobody:x:$uid_nobody:$gid_nobody:nobody gecos:$prefix_abs:/bin/false
1030 $unix_name:x:$unix_uid:$unix_gids[0]:$unix_name gecos:$prefix_abs:/bin/false
1031 pdbtest:x:$uid_pdbtest:$gid_nogroup:pdbtest gecos:$prefix_abs:/bin/false
1033 if ($unix_uid != 0) {
1034 print PASSWD "root:x:$uid_root:$gid_root:root gecos:$prefix_abs:/bin/false";
1036 close(PASSWD);
1038 unless (open(GROUP, ">$nss_wrapper_group")) {
1039 warn("Unable to open $nss_wrapper_group");
1040 return undef;
1042 print GROUP "nobody:x:$gid_nobody:
1043 nogroup:x:$gid_nogroup:nobody
1044 $unix_name-group:x:$unix_gids[0]:
1045 domusers:X:$gid_domusers:
1046 domadmins:X:$gid_domadmins:
1048 if ($unix_gids[0] != 0) {
1049 print GROUP "root:x:$gid_root:";
1052 close(GROUP);
1054 foreach my $evlog (@eventlog_list) {
1055 my $evlogtdb = "$eventlogdir/$evlog.tdb";
1056 open(EVENTLOG, ">$evlogtdb") or die("Unable to open $evlogtdb");
1057 close(EVENTLOG);
1060 $ENV{NSS_WRAPPER_PASSWD} = $nss_wrapper_passwd;
1061 $ENV{NSS_WRAPPER_GROUP} = $nss_wrapper_group;
1063 my $cmd = Samba::bindir_path($self, "smbpasswd")." -c $conffile -L -s -a $unix_name > /dev/null";
1064 unless (open(PWD, "|$cmd")) {
1065 warn("Unable to set password for test account\n$cmd");
1066 return undef;
1068 print PWD "$password\n$password\n";
1069 unless (close(PWD)) {
1070 warn("Unable to set password for test account\n$cmd");
1071 return undef;
1073 print "DONE\n";
1075 open(DNS_UPDATE_LIST, ">$prefix/dns_update_list") or die("Unable to open $$prefix/dns_update_list");
1076 print DNS_UPDATE_LIST "A $server. $server_ip";
1077 close(DNS_UPDATE_LIST);
1079 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) {
1080 die "Unable to update hostname into $dns_host_file";
1083 $ret{SERVER_IP} = $server_ip;
1084 $ret{NMBD_TEST_LOG} = "$prefix/nmbd_test.log";
1085 $ret{NMBD_TEST_LOG_POS} = 0;
1086 $ret{WINBINDD_TEST_LOG} = "$prefix/winbindd_test.log";
1087 $ret{WINBINDD_TEST_LOG_POS} = 0;
1088 $ret{SMBD_TEST_LOG} = "$prefix/smbd_test.log";
1089 $ret{SMBD_TEST_LOG_POS} = 0;
1090 $ret{SERVERCONFFILE} = $conffile;
1091 $ret{CONFIGURATION} ="-s $conffile";
1092 $ret{SERVER} = $server;
1093 $ret{USERNAME} = $unix_name;
1094 $ret{USERID} = $unix_uid;
1095 $ret{DOMAIN} = $domain;
1096 $ret{NETBIOSNAME} = $server;
1097 $ret{PASSWORD} = $password;
1098 $ret{PIDDIR} = $piddir;
1099 $ret{WINBINDD_SOCKET_DIR} = $wbsockdir;
1100 $ret{WINBINDD_PRIV_PIPE_DIR} = $wbsockprivdir;
1101 $ret{NMBD_SOCKET_DIR} = $nmbdsockdir;
1102 $ret{SOCKET_WRAPPER_DEFAULT_IFACE} = $swiface;
1103 $ret{NSS_WRAPPER_PASSWD} = $nss_wrapper_passwd;
1104 $ret{NSS_WRAPPER_GROUP} = $nss_wrapper_group;
1105 $ret{NSS_WRAPPER_WINBIND_SO_PATH} = Samba::nss_wrapper_winbind_so_path($self);
1106 $ret{LOCAL_PATH} = "$shrdir";
1108 return \%ret;
1111 sub wait_for_start($$$$$)
1113 my ($self, $envvars, $nmbd, $winbindd, $smbd) = @_;
1114 my $ret;
1116 if ($nmbd eq "yes") {
1117 # give time for nbt server to register its names
1118 print "delaying for nbt name registration\n";
1119 sleep(10);
1120 # This will return quickly when things are up, but be slow if we need to wait for (eg) SSL init
1121 my $nmblookup = Samba::bindir_path($self, "nmblookup3");
1122 system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} __SAMBA__");
1123 system("$nmblookup $envvars->{CONFIGURATION} __SAMBA__");
1124 system("$nmblookup $envvars->{CONFIGURATION} -U 127.255.255.255 __SAMBA__");
1125 system("$nmblookup $envvars->{CONFIGURATION} -U $envvars->{SERVER_IP} $envvars->{SERVER}");
1126 system("$nmblookup $envvars->{CONFIGURATION} $envvars->{SERVER}");
1129 if ($winbindd eq "yes") {
1130 print "checking for winbindd\n";
1131 my $count = 0;
1132 do {
1133 $ret = system("WINBINDD_SOCKET_DIR=" . $envvars->{WINBINDD_SOCKET_DIR} . " " . Samba::bindir_path($self, "wbinfo") . " -p");
1134 if ($ret != 0) {
1135 sleep(2);
1137 $count++;
1138 } while ($ret != 0 && $count < 10);
1139 if ($count == 10) {
1140 print "WINBINDD not reachable after 20 seconds\n";
1141 teardown_env($self, $envvars);
1142 return 0;
1146 if ($smbd eq "yes") {
1147 # make sure smbd is also up set
1148 print "wait for smbd\n";
1150 my $count = 0;
1151 do {
1152 $ret = system(Samba::bindir_path($self, "smbclient3") ." $envvars->{CONFIGURATION} -L $envvars->{SERVER} -U% -p 139");
1153 if ($ret != 0) {
1154 sleep(2);
1156 $count++
1157 } while ($ret != 0 && $count < 10);
1158 if ($count == 10) {
1159 print "SMBD failed to start up in a reasonable time (20sec)\n";
1160 teardown_env($self, $envvars);
1161 return 0;
1165 # Ensure we have domain users mapped.
1166 $ret = system(Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} groupmap add rid=513 unixgroup=domusers type=domain");
1167 if ($ret != 0) {
1168 return 1;
1170 $ret = system(Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} groupmap add rid=512 unixgroup=domadmins type=domain");
1171 if ($ret != 0) {
1172 return 1;
1175 if ($winbindd eq "yes") {
1176 # note: creating builtin groups requires winbindd for the
1177 # unix id allocator
1178 $ret = system("WINBINDD_SOCKET_DIR=" . $envvars->{WINBINDD_SOCKET_DIR} . " " . Samba::bindir_path($self, "net") ." $envvars->{CONFIGURATION} sam createbuiltingroup Users");
1179 if ($ret != 0) {
1180 print "Failed to create BUILTIN\\Users group\n";
1181 return 0;
1183 my $count = 0;
1184 do {
1185 system(Samba::bindir_path($self, "net") . " $envvars->{CONFIGURATION} cache flush");
1186 $ret = system("WINBINDD_SOCKET_DIR=" . $envvars->{WINBINDD_SOCKET_DIR} . " " . Samba::bindir_path($self, "wbinfo") . " --sid-to-gid=S-1-5-32-545");
1187 if ($ret != 0) {
1188 sleep(2);
1190 $count++;
1191 } while ($ret != 0 && $count < 10);
1192 if ($count == 10) {
1193 print "WINBINDD not reachable after 20 seconds\n";
1194 teardown_env($self, $envvars);
1195 return 0;
1199 print $self->getlog_env($envvars);
1201 return 1;