#!/usr/local/bin/perl -w
# $File: //depot/RT/osf/sbin/openfoundry-setup $ $Author: autrijus $
# $Revision: #1 $ $Change: 9948 $ $DateTime: 2004/02/08 00:09:19 $

use strict;
use FindBin;
use ExtUtils::MakeMaker;
use lib "$FindBin::Bin/openfoundry-lib";
use lib "$FindBin::Bin/../libexec/openfoundry";

use constant VARS => {
    VCS => qw(
	DB_TYPE DB_HOST DB_PORT
	DB_DBA_USER DB_DBA_PASSWORD
	RT_URL
	SVNREPOS
	CVSROOT CVSUSER CVSGROUP
    ),
    WEB => qw(
	RT_NAME TZ
	DB_TYPE DB_HOST DB_PORT
	DB_DBA_USER DB_DBA_PASSWORD
	HOST WEB_HOST EMAIL_HOST 
    ),
};

use vars map "\$\L$_", +VARS, 'DB_PAM_MODULE';

die "$0: This command is reserved for the superuser.\n" unless -w '/etc';

eval { require "/usr/local/etc/openfoundry.conf.sample" };
eval { require "/usr/local/etc/openfoundry.conf" };

foreach my $var (+VARS) {
    no strict 'refs';
    my $val = (map /^$var=(.+)/g, @ARGV)[-1] || $ENV{$var};
    ${"\L$var"} = prompt("$var:", defined($val) ? $val : ());
}

if ( $db_type =~ /^p(g|(?:ostgres?))(?:sql)?$/i ) {
    $db_type = 'Pg';
    $db_pam_module = 'pam_pgsql';
}
elsif ( $db_type =~ /^mysql$/i ) {
    $db_type = 'mysql';
    $db_pam_module = 'pam_mysql';
}
else {
    die "DB_TYPE '$db_type' unsupported";
}

&pam_conf;
&openfoundry_conf;

sub openfoundry_conf {
    my $conf = "/usr/local/etc/openfoundry.conf";

    my @in_lines;
    if (open my $IN, $conf) {
	@in_lines = grep {
	    my $line = $_;
	    !grep $line =~ /\$ENV\{$_\}/, +VARS
	} <$IN>;
	close $IN;
    }

    no strict 'refs';
    no warnings 'uninitialized';
    open my $OUT, '>', $conf or die $!;
    print $OUT (
	@in_lines,
	map {
	    "\$ENV{$_}" .
	    ("\t" x (2 - int((length($_)-1) / 8))) .
	    "= '${lc$_}';\n"
	} +VARS,
    );
    close $OUT;
    chown 0600, $conf;

    print "===> $conf successfully written.\n";
}

sub pam_conf {
    my %params = (
	host		=> $db_host,
	user		=> $db_dba_user,
	passwd		=> $db_dba_password,
	db		=> 'rt3',
	table		=> 'Users',
	usercolumn	=> 'Name',
	passwdcolumn	=> 'Password',
	crypt		=> 'md5',
    );
    my %keys_pg = (
	db		=> 'database',
	usercolumn	=> 'user_column',
	passwdcolumn	=> 'pwd_column',
	crypt		=> 'pw_type',
    );

    my $params = '';
    $params = join('', map " $_=$params{$_}", sort keys %params)
	if $db_pam_module eq 'pam_mysql';
    @params{values(%keys_pg)} = delete @params{keys(%keys_pg)}
	if $db_pam_module eq 'pam_pgsql';

    my @conf_lines = (
	"auth        required    $db_pam_module.so$params\n",
	"account     required    pam_permit.so\n",
	"password    required    $db_pam_module.so$params\n",
	"session     required    pam_permit.so\n",
    );

    my $service = 'sshdcvs';
    my $pam_d = "/usr/local/etc/pam.d";
    my $pam_conf = "/etc/pam.conf";
    my $pam_module_conf = "/etc/$db_pam_module.conf";

    if (-e $pam_conf) {
	open my $IN, $pam_conf or die $!;
	my @in_lines = grep !/^(?:# )?$service\s+/, <$IN>;
	close $IN;
	open my $OUT, '>', $pam_conf or die $!;
	print $OUT (
	    @in_lines,
	    "# $service: added by $0 at " . localtime() . $/,
	    map "$service $_", @conf_lines,
	);
	close $OUT;

	print "===> $pam_conf successfully written.\n";
    }
    elsif (-d $pam_d) {
	open my $OUT, '>', "$pam_d/$service" or die $!;
	print $OUT @conf_lines;
	close $OUT;

	print "===> $pam_d/$service successfully written.\n";
    }
    else {
	die "Cannot find $pam_conf or $pam_d/, aborting!\n";
    }

    if ($db_pam_module eq 'pam_pgsql') {
	open my $OUT, '>', "$pam_module_conf" or die $!;
	print $OUT "$_ = $params{$_}\n" for sort keys %params;
	close $OUT;
	print "===> $pam_module_conf successfully written.\n";
    }
}

1;
