# ldap-useradmin-lib.pl
# Module sponsored by
# Sanitaetsbetrieb Brixen  - Azienda Sanitaria di Bressanone
# www.sb-brixen.it         - www.as-bressanone.it

do '../web-lib.pl';
&init_config();
require '../ui-lib.pl';
&foreign_require("useradmin", "user-lib.pl");
%uconfig = &foreign_config("useradmin");

%utext = &load_language("useradmin");
foreach $t (keys %utext) {
	$text{$t} ||= $utext{$t};
	}

eval "use Net::LDAP";
if ($@) { $net_ldap_error = $@; }
else { $got_net_ldap++; }
eval "use Net::IMAP";
if ($@) { $net_imap_error = $@; }
else { $got_net_imap++; }

$secret_file = "/etc/ldap.secret";
$samba_class = $config{'samba_class'} || "sambaAccount";
$cyrus_class = $config{'imap_class'} || "SuSEeMailObject";

# get_nss_config()
# Parses the NSS config file into a hash reference
sub get_nss_config
{
return undef if (!$config{'auth_ldap'});
if (!%nss_config_cache) {
	open(CONF, $config{'auth_ldap'});
	while(<CONF>) {
		s/\r|\n//g;
		s/#.*$//;
		if (/^\s*(\S+)\s*(.*)/) {
			$nss_config_cache{lc($1)} = $2;
			}
		}
	close(CONF);
	}
return \%nss_config_cache;
}

# ldap_connect(return-error)
# Connect to the LDAP server and return a handle to the Net::LDAP object
sub ldap_connect
{
local $conf = &get_nss_config();
local ($host, $port);
if ($conf) {
	$host = $conf->{'host'};
	$port = $conf->{'port'};
	}
else {
	$host = $config{'ldap_host'};
	$port = $config{'ldap_port'};
	}
$port ||= 389;
local $ldap = Net::LDAP->new($host, port => $port);
if (!$ldap) {
	local $err = &text('conn_econn',
			   "<tt>$host</tt>","<tt>$port</tt>");
	if ($_[0]) { return $err; }
	else { &error($err); }
	}

local ($dn, $password);
if ($config{'login'}) {
	# Use the configured login
	$dn = $config{'login'};
	$password = $config{'pass'};
	}
elsif ($conf->{'rootbinddn'}) {
	# Use the root login if we have one
	$dn = $conf->{'rootbinddn'};
	open(SECRET, $secret_file);
	chop($password = <SECRET>);
	close(SECRET);
	}
else {
	# Use the normal login
	$dn = $conf->{'binddn'};
	$password = $conf->{'bindpw'};
	}
local $mesg = $ldap->bind(dn => $dn, password => $password);
if ($mesg->code) {
	local $err = &text('conn_elogin', "<tt>$conf{'host'}</tt>",
		     $dn, $mesg->error);
	if ($_[0]) { return $err; }
	else { &error($err); }
	}
return $ldap;
}

# get_user_base()
sub get_user_base
{
local $conf = &get_nss_config();
local $base = $config{'user_base'} || $conf->{'nss_base_passwd'} || $conf->{'base'};
$base =~ s/\?.*$//;
return $base;
}

# get_group_base()
sub get_group_base
{
local $conf = &get_nss_config();
local $base = $config{'group_base'} || $conf->{'nss_base_group'} || $conf->{'base'};
$base =~ s/\?.*$//;
return $base;
}

# imap_connect(return-error)
# Connect and login to the IMAP server
sub imap_connect
{
local $imap = new Net::IMAP($config{'imap_host'});
if (!$imap) {
	local $err = &text('imap_econn', "<tt>$config{'imap_host'}</tt>");
	if ($_[0]) { return $err; }
	else { &error($err); }
	}
local $rv = $imap->login($config{'imap_login'}, $config{'imap_pass'});
if ($rv->{'Status'} ne 'ok') {
	local $err = &text('imap_elogin', "<tt>$config{'imap_host'}</tt>",
			   "<tt>$config{'imap_login'}</tt>", $rv->{'Text'});
	if ($_[0]) { return $err; }
	else { &error($err); }
	}
return $imap;
}

# samba_password(password)
# Converts a plain text string into two Samba passwords (nt and lm) with the
# ntpasswd program.
sub samba_password
{
local ($nt, $lm);
&foreign_check("samba") || &error($text{'usave_esamba'});
&foreign_require("samba", "smbhash.pl");
$nt = &samba::nthash($_[0]);
$lm = &samba::lmhash($_[0]);
return ($nt, $lm);
}

# encrypt_password(string)
sub encrypt_password
{
&seed_random();
if ($config{'md5'} == 3) {
	# LDAP MD5 encryption
	local $qp = quotemeta($_[0]);
	local $out = `$config{'slappasswd'} -h '{md5}' -s $qp 2>/dev/null`;
	$out =~ s/\s+$//;
	$out =~ s/^\{md5\}//i;
	return $out;
	}
if ($config{'md5'} == 1) {
	# Unix MD5 encryption
	&foreign_require("useradmin", "user-lib.pl");
	return &useradmin::encrypt_md5($_[0]);
	}
elsif ($config{'md5'} == 0) {
	# Standard Unix crypt
	local $salt = chr(int(rand(26))+65).chr(int(rand(26))+65);
	return crypt($_[0], $salt);
	}
else {
	# No encryption!
	return $_[0];
	}
}

1;

