#!/usr/bin/perl -w

# $Id: smbldap-qmail-passwd,v 0.3-2 2004/09/16 01:15:32 Jun Futagawa Exp $
#
#  This code was developped by Jun Futagawa, and based on smblda-tools
#  developped by IDEALX (http://IDEALX.org/) and contributors
#  (their names can be found in that CONTRIBUTORS file).
#
#               Copyright (C) 2004 Jun Futagawa
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU General Public License
#  as published by the Free Software Foundation; either version 2
#  of the License, or (at your option) any later version.
#
#  This program is distributed in the hope that it will be useful,
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
#  GNU General Public License for more details.
#
#  You should have received a copy of the GNU General Public License
#  along with this program; if not, write to the Free Software
#  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
#  USA.

# Purpose of smbldap-qmail-passwd : change unix passwd of qmailUser

use vars qw(@ARGV);

use strict;
use FindBin;
use FindBin qw($RealBin);
use Getopt::Std;
use IO::Handle;
use IO::File;
use lib "$RealBin/";

use smbldap_tools;
use smbldap_qmail_tools;

my $slappasswd = "/usr/sbin/slappasswd";

#####################

my $fout = new IO::Handle();
$fout->fdopen(fileno(STDOUT), "w") or die "cannot open STDOUT";

my %Options;
my $ok = getopts('sp:h?', \%Options);
if ( (!$ok) || (@ARGV < 1) || ($Options{'?'}) ) {
	$fout->printf('%s',
		"Version 0.3-2\n".
		"Usage: $0 [-psh?] username\n".
		"  -p	password\n".
		"  -s	strict mode. check qmailUser objectClass\n".
		"  -h,?	show this help message\n"
	);
	exit(1);
}

# read only first @ARGV
my $userName = $ARGV[0];
if (!defined($userName)) {
	$userName = $ENV{"USER"};
}

# untaint $userName (can finish with one or two $)
if ($userName =~ /^([\w -.]+\$?)$/) {
	$userName = $1;
} else {
	$fout->printf('%s', "$0: illegal username\n");
	exit(1);
}

# check strictly qmailUser objectClass
if (defined($Options{'s'})) {
	if (! isQmailUser($userName)) {
		$fout->printf('%s', "$0: The entry of user $userName doesn't have qmailUser objectClass\n");
		exit(1);
	}
}

# test existence of user in LDAP
my $userEntry;
if (!defined($userEntry = readUserEntry($userName))) {
	$fout->printf('%s', "$0: user $userName doesn't exist\n");
	exit(1);
}

my $dn = $userEntry->dn();
# non-root user
my $oldpass;
if ($< != 0) {
	$fout->printf('%s', "Changing password for $userName\n");
	# prompt for current password
	$fout->printf('%s', "(current) UNIX password: ");
	system("stty -echo") if (-t STDIN);
	chomp($oldpass = <STDIN>);
	system("stty echo") if (-t STDIN);
	$fout->printf('%s', "\n");

	if (!is_user_valid($userName, $dn, $oldpass)) {
		$fout->printf('%s', "Authentication failure\n");
		exit(1);
	}
}

# prompt for new password
my $pass;
my $pass2;

if (!defined($pass = $Options{'p'})) {
	$fout->printf('%s', "New password : ");
	system("stty -echo") if (-t STDIN);
	chomp($pass = <STDIN>);
	system("stty echo") if (-t STDIN);
	$fout->printf('%s',"\n");

	$fout->printf('%s', "Retype new password : ");
	system("stty -echo") if (-t STDIN);
	chomp($pass2 = <STDIN>);
	system("stty echo") if (-t STDIN);
	$fout->printf('%s', "\n");

	if ($pass ne $pass2) {
		$fout->printf('%s', "New passwords don't match!\n");
		exit(1);
	}
}

# First, connecting to the directory
if ($< != 0) {
	$config{masterDN}="uid=$userName,$config{usersdn}";
	$config{masterPw}="$oldpass";
}
my $ldap_master=connect_ldap_master();

# change unix password
my $hash_password = '';
if ( $config{hash_encrypt} eq "CRYPT" && defined($config{crypt_salt_format}) ) {
	$hash_password = `$slappasswd -h {$config{hash_encrypt}} -c '$config{crypt_salt_format}' -s '$pass'`;
} else {
	$hash_password = `$slappasswd -h {$config{hash_encrypt}} -s '$pass'`;
}

chomp($hash_password);
my $result = $ldap_master->modify (
			"$dn",
				changes => [
					replace => [userPassword => "$hash_password"]
				]
			);
$result->code && warn "Unable to change password : ", $result->error;

# close session
$ldap_master->unbind;

########################################

=head1 NAME

smbldap-qmail-passwd - change unix passwd of qmailUser

=head1 SYNOPSIS

smbldap-qmail-passwd [username]

=head1 DESCRIPTION

    The smbldap-qmail-passwd changes passwords for qmailUser accounts.

=head1 SEE ALSO

    passwd(1)

=cut

#'
