#!/usr/bin/perl
# Copyright (C) 2009 Stefan Metzmacher <metze@samba.org>
# Published under the GNU GPL, v3 or later.

package Samba34;

use strict;
use Cwd qw(abs_path);
use FindBin qw($RealBin);
use POSIX;

use target::Samba3;
use target::Samba4;

sub new($$) {
	my ($classname, $bindir) = @_;
	my $self = {
		bindir => $bindir,
		target3 => new Samba3($bindir),
		target4 => new Samba4($bindir, undef, "../source4/setup", "4")
	};
	bless $self;
	return $self;
}

sub teardown_env($$)
{
	my ($self, $envvars) = @_;

	return 0;
}

sub getlog_env($$)
{
	my ($self, $envvars) = @_;

	return "";
}

sub check_env($$)
{
	my ($self, $envvars) = @_;

	return 1;
}

sub setup_franky_dc($$)
{
	my ($self, $path) = @_;
	my $ret = undef;
	my $target3 = $self->{target3};
	my $target4 = $self->{target4};

	my $smbd_path = $target3->binpath("smbd");
	my $net3 = $target3->binpath("net");
	my $net4 = $target4->bindir_path("net");
	my $bindir_abs = abs_path($self->{bindir});

	my $domsid = "S-1-5-21-123260556-2972382748-1729953856";

	my $ctx4 = $target4->provision_raw_prepare($path, "domain controller",
						   "FRANKYDC4",
						   "FRANKYDC",
						   "4",
						   "frankydc4pass",
						   "127.0.0.4");

	push (@{$ctx4->{provision_options}}, "--domain-sid=$domsid");

	$ctx4->{tmpdir} = "$ctx4->{prefix_abs}/tmp";
	push(@{$ctx4->{directories}}, "$ctx4->{tmpdir}");

	$ctx4->{sysvoldir} = "$ctx4->{prefix_abs}/sysvol";
	push(@{$ctx4->{directories}}, "$ctx4->{sysvoldir}");

	$ctx4->{netlogondir} = "$ctx4->{sysvoldir}/$ctx4->{dnsname}/scripts";
	push(@{$ctx4->{directories}}, "$ctx4->{sysvoldir}/$ctx4->{dnsname}");
	push(@{$ctx4->{directories}}, "$ctx4->{netlogondir}");

	$ctx4->{smb_conf_extra_options} = "

	# Samba3 options
	security = user
	auth methods = netlogond guest
	auth_netlogond:socket = $ctx4->{ncalrpcdir}/DEFAULT
	auth_netlogond:machinepwscript = $net4 -d -1 machinepw $ctx4->{netbiosname}\$
	domain master = yes
	domain logons = yes
	winbindd:socket dir = $ctx4->{winbindd_socket_dir}
	log file = $ctx4->{prefix_abs}/smbd3.log
	kernel oplocks = no
	kernel change notify = no
	syslog = no
	printing = bsd
	printcap name = /dev/null
	idmap uid = 100000-200000
	idmap gid = 100000-200000

	# Samba4 options
	server services = rpc ldap cldap kdc ntp_signd samba3_smb
	dcerpc endpoint servers = epmapper srvsvc wkssvc samr netlogon lsarpc drsuapi winreg dssetup
	samba3:smbd = $smbd_path

	# Share defaults
	smbd:sharedelay = 100000
	smbd:writetimeupdatedelay = 500000
	map hidden = yes
	map system = yes
	create mask = 755
	vfs objects = $bindir_abs/xattr_tdb.so $bindir_abs/streams_depot.so

[tmp]
	path = $ctx4->{tmpdir}
	read only = no

[sysvol]
	path = $ctx4->{sysvoldir}
	read only = no

[netlogon]
	path = $ctx4->{netlogondir}
	read only = no

";

	my $env4 = $target4->provision_raw_step1($ctx4);

	$env4 = $target4->provision_raw_step2($ctx4, $env4);

	$ret->{s4} = $env4;
	$ret->{s3}->{NMBD_TEST_LOG}		= "$ctx4->{prefix_abs}/nmbd_test.log";
	$ret->{s3}->{NMBD_TEST_LOG_POS}		= 0;
	$ret->{s3}->{WINBINDD_TEST_LOG}		= "$ctx4->{prefix_abs}/winbindd_test.log";
	$ret->{s3}->{WINBINDD_TEST_LOG_POS}	= 0;
	$ret->{s3}->{SMBD_TEST_LOG}		= "$ctx4->{prefix_abs}/smbd_test.log";
	$ret->{s3}->{SMBD_TEST_LOG_POS}		= 0;
	$ret->{s3}->{SERVERCONFFILE}		= $env4->{SERVERCONFFILE};
	$ret->{s3}->{CONFIGURATION}		= "-s $env4->{SERVERCONFFILE}";
	$ret->{s3}->{PIDDIR}			= $env4->{PIDDIR};
	$ret->{s3}->{WINBINDD_SOCKET_DIR}	= $env4->{WINBINDD_SOCKET_DIR};
	$ret->{s3}->{WINBINDD_PRIV_PIPE_DIR}	= $env4->{WINBINDD_PRIV_PIPE_DIR};
	$ret->{s3}->{SOCKET_WRAPPER_DEFAULT_IFACE}=$env4->{SOCKET_WRAPPER_DEFAULT_IFACE};
	$ret->{s3}->{NSS_WRAPPER_PASSWD}	= $env4->{NSS_WRAPPER_PASSWD};
	$ret->{s3}->{NSS_WRAPPER_GROUP}		= $env4->{NSS_WRAPPER_GROUP};
	$ret->{s3}->{SERVER}			= $env4->{SERVER};
	$ret->{s3}->{SERVER_IP}			= $env4->{SERVER_IP};
	$ret->{s3}->{NETBIOSNAME}		= $env4->{NETBIOSNAME};
	$ret->{s3}->{DOMAIN}			= $env4->{DOMAIN};
	$ret->{s3}->{USERNAME}			= $env4->{USERNAME};
	$ret->{s3}->{PASSWORD}			= $env4->{PASSWORD};

	$ret->{SERVERCONFFILE}			= $env4->{SERVERCONFFILE};
	$ret->{CONFIGURATION}			= "-s $env4->{SERVERCONFFILE}";
	$ret->{PIDDIR}				= $env4->{PIDDIR};
	$ret->{WINBINDD_SOCKET_DIR}		= $env4->{WINBINDD_SOCKET_DIR};
	$ret->{WINBINDD_PRIV_PIPE_DIR}		= $env4->{WINBINDD_PRIV_PIPE_DIR};
	$ret->{SOCKET_WRAPPER_DEFAULT_IFACE}	= $env4->{SOCKET_WRAPPER_DEFAULT_IFACE};
	$ret->{NSS_WRAPPER_PASSWD}		= $env4->{NSS_WRAPPER_PASSWD};
	$ret->{NSS_WRAPPER_GROUP}		= $env4->{NSS_WRAPPER_GROUP};
	$ret->{KRB5_CONFIG}			= $env4->{KRB5_CONFIG};
	$ret->{NCALRPCDIR}			= $env4->{NCALRPCDIR};
	$ret->{LOCKDIR}				= $env4->{LOCKDIR};
	$ret->{SERVER}				= $env4->{SERVER};
	$ret->{SERVER_IP}			= $env4->{SERVER_IP};
	$ret->{NETBIOSNAME}			= $env4->{NETBIOSNAME};
	$ret->{DOMAIN}				= $env4->{DOMAIN};
	$ret->{REALM}				= $env4->{REALM};

	$ret->{USERNAME}			= "metze";
	$ret->{PASSWORD}			= "geheim";

	my @newuser_options = ();
	push (@newuser_options, "NSS_WRAPPER_PASSWD=\"$ret->{NSS_WRAPPER_PASSWD}\"");
	push (@newuser_options, "NSS_WRAPPER_GROUP=\"$ret->{NSS_WRAPPER_GROUP}\"");
	if (defined($ENV{PYTHON})) {
		push (@newuser_options, $ENV{PYTHON});
	}
	push (@newuser_options, "../source4/setup/newuser");
	push (@newuser_options, split(' ', $ret->{CONFIGURATION}));
	push (@newuser_options, "--quiet");
	push (@newuser_options, $ret->{USERNAME});
	push (@newuser_options, $ret->{PASSWORD});

	my $newuser_cmd = join(" ", @newuser_options);
	(system($newuser_cmd) == 0) or die("Unable to add new user: \n$newuser_cmd\n");

	my $setlocalsid = "$net3 $ret->{s3}->{CONFIGURATION} setlocalsid $domsid";
	(system("$setlocalsid") == 0) or die("Failed to run[$?]: $setlocalsid");
	my $setdomainsid = "$net3 $ret->{s3}->{CONFIGURATION} setdomainsid $domsid";
	(system("$setdomainsid") == 0) or die("Failed to run[$?]: $setdomainsid");

	my $maxruntime = ($ENV{SMBD_MAXTIME} or 7500);
	$target3->check_or_start($ret->{s3},
				 $maxruntime,	# nmbd
				 $maxruntime,	# don't start winbindd
				 "skip");	# don't start smbd
	my $tmp = $ENV{SMB_CONF_PATH};
	$ENV{SMB_CONF_PATH} = $ret->{SERVERCONFFILE};
	$target4->check_or_start($ret->{s4}, $maxruntime);
	$ENV{SMB_CONF_PATH} = $tmp;

	$target3->wait_for_start($ret->{s3});
	$target4->wait_for_start($ret->{s4});

	$self->{vars}->{franky_dc} = $ret;

	return $ret;
}

sub setup_env($$$)
{
	my ($self, $envname, $path) = @_;

	if ($envname eq "franky_dc") {
		return $self->setup_franky_dc("$path/franky_dc");
	}

	die("Samba34 can't provide environment '$envname'");
}

sub stop($)
{
	my ($self) = @_;
}

1;
