summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilan Bouchet-Valat <nalimilan@club.fr>2010-01-10 20:39:42 +0100
committerMilan Bouchet-Valat <nalimilan@club.fr>2010-01-11 17:37:43 +0100
commit73b1da98e7dce731bb30f86c45173c88b735be60 (patch)
tree9fe20b84d940a0cf7abeb5ae382443da74ba93ec
parentcf7148081bfc2d5dff7fd742ce1cd1dda4fdf1f4 (diff)
Use PAM to set password
Instead of getting the password encrypted by the client, get it in plain text, and set it via PAM. This behavior is standard on all supported platforms, which allows for code simplification, and avoids bugs when new password encryption algorithms appear. Never return the encrypted password on the bus. Instead, PAM should always be used to change it, possibly authenticating when changing own password.
-rw-r--r--Users/Users.pm153
-rw-r--r--UsersConfig.pm11
2 files changed, 38 insertions, 126 deletions
diff --git a/Users/Users.pm b/Users/Users.pm
index 8034ce8..f924d83 100644
--- a/Users/Users.pm
+++ b/Users/Users.pm
@@ -46,6 +46,8 @@
package Users::Users;
+use Authen::PAM;
+
use Utils::Util;
use Utils::Report;
use Utils::File;
@@ -73,6 +75,9 @@ $cmd_deluser = &Utils::File::locate_tool ("deluser");
$cmd_chfn = &Utils::File::locate_tool ("chfn");
$cmd_pw = &Utils::File::locate_tool ("pw");
+$cmd_passwd = &Utils::File::locate_tool ("passwd");
+$cmd_chpasswd = &Utils::File::locate_tool ("chpasswd");
+
# enum like for verbose group array positions
my $i = 0;
my $LOGIN = $i++;
@@ -273,45 +278,6 @@ my $logindefs_dist_map = {
'users_write_groups_fail' => ['warn', 'Writing groups failed.'],
});
-
-sub do_get_use_md5
-{
- my ($file) = @_;
- my ($fh, @line, $i, $use_md5);
-
- my $fh = &Utils::File::open_read_from_names ("/etc/pam.d/$file");
- return 0 if (!$fh);
-
- $use_md5 = 0;
-
- while (<$fh>)
- {
- next if &Utils::Util::ignore_line ($_);
- chomp;
- @line = split /[ \t]+/;
-
- if ($line[0] eq "\@include")
- {
- $use_md5 = &do_get_use_md5 ($line[1]);
- }
- elsif ($line[0] eq "password")
- {
- foreach $i (@line)
- {
- $use_md5 = 1 if ($i eq "md5");
- }
- }
- }
-
- close $fh;
- return $use_md5;
-}
-
-sub get_use_md5
-{
- return &do_get_use_md5 ("passwd");
-}
-
sub logindefs_add_defaults
{
# Common for all distros
@@ -402,6 +368,9 @@ sub get
push @comment, "" while (scalar (@comment) < 5);
$line[$COMMENT] = [@comment];
+ # always return empty string - anyway, passwd should be in /etc/shadow
+ $line[$PASSWD] = "";
+
$users_hash{$login} = [@line];
# max value for an unsigned 32 bits integer means no main group
@@ -416,32 +385,6 @@ sub get
}
&Utils::File::close_file ($ifh);
- $ifh = &Utils::File::open_read_from_names(@shadow_names);
-
- if ($ifh)
- {
- while (<$ifh>)
- {
- chomp;
-
- # FreeBSD allows comments in the shadow passwd file.
- next if &Utils::Util::ignore_line ($_);
-
- @line = split ':', $_, -1;
- $login = shift @line;
- $passwd = shift @line;
-
- # do not add data if the user isn't present
- next if (!exists $users_hash{$login});
-
- $users_hash{$login}[$PASSWD] = $passwd;
-
- # FIXME: add the rest of the fields?
- #push @{$$users_hash{$login}}, @line;
- }
-
- &Utils::File::close_file ($ifh);
- }
# transform the hash into an array
foreach $login (keys %users_hash)
@@ -557,21 +500,24 @@ sub set_passwd
if ($Utils::Backend::tool{"system"} eq "FreeBSD")
{
my ($command);
- $command = "$cmd_pw usermod -H 0";
+ $command = "$cmd_pw usermod \'$login\' -h 0";
$pwdpipe = &Utils::File::run_pipe_write ($command);
print $pwdpipe $password;
&Utils::File::close_file ($pwdpipe);
}
elsif ($Utils::Backend::tool{"system"} eq "SunOS")
{
- &modify_shadow_password ($login, $password);
+ my ($command);
+ $command = "$cmd_passwd --stdin \'$login\'";
+ $pwdpipe = &Utils::File::run_pipe_write ($command);
+ print $pwdpipe $password;
+ &Utils::File::close_file ($pwdpipe);
}
else
{
- my (@command);
- @command = ($cmd_usermod, "-p", $password, $login);
-
- &Utils::File::run (@command);
+ $pwdpipe = &Utils::File::run_pipe_write ($cmd_chpasswd);
+ print $pwdpipe "$login:$password";
+ &Utils::File::close_file ($pwdpipe);
}
}
@@ -601,7 +547,6 @@ sub add_user
if ($Utils::Backend::tool{"system"} eq "FreeBSD")
{
- my $pwdpipe;
my $logindefs;
# FreeBSD doesn't create the home directory
@@ -612,23 +557,15 @@ sub add_user
}
&Utils::File::run ($tool_mkdir, "-p", $$user[$HOME]);
- $command = "$cmd_pw useradd " .
- " -n \'" . $$user[$LOGIN] . "\'" .
- " -H 0"; # pw(8) reads password from STDIN
+ @command = ($cmd_pw, "useradd", "-n", $$user[$LOGIN],
+ "-h", "-"); # disable login until password is set
- $command .= "-d \' $$user[$HOME] \' " if ($$user[$HOME]);
- $command .= "-s \' $$user[$SHELL] \' " if ($$user[$SHELL]);
- $command .= "-u $$user[$UID]" if ($real_uid);
- $command .= "-g $$user[$GID]" if ($real_gid);
-
-# @command = ($cmd_pw, "useradd", "-n", $$user[$LOGIN],
-# "-d", $$user[$HOME],
-# "-s", $$user[$SHELL],
-# "-H", "0"); # pw(8) reads password from STDIN
+ push (@command, ("-s", $$user[$HOME])) if ($$user[$HOME]);
+ push (@command, ("-s", $$user[$SHELL])) if ($$user[$SHELL]);
+ push (@command, ("-u", $$user[$UID])) if ($real_uid);
+ push (@command, ("-g", $$user[$GID])) if ($real_gid);
- $pwdpipe = &Utils::File::run_pipe_write ($command);
- print $pwdpipe $$user[$PASSWD];
- &Utils::File::close_file ($pwdpipe);
+ &Utils::File::run (@command);
}
elsif ($Utils::Backend::tool{"system"} eq "SunOS")
{
@@ -641,7 +578,6 @@ sub add_user
push (@command, $$user[$LOGIN]);
&Utils::File::run (@command);
- &modify_shadow_password ($$user[$LOGIN], $$user[$PASSWD]);
}
else
{
@@ -663,18 +599,11 @@ sub add_user
push (@command, $$user[$LOGIN]);
&Utils::File::run (@command);
-
- # password can't be set in non-interactive
- # mode with adduser, call usermod instead
- @command = ($cmd_usermod, "-p", $$user[$PASSWD], $$user[$LOGIN]);
-
- &Utils::File::run (@command);
}
else
{
# fallback to useradd
- @command = ($cmd_useradd, "-m",
- "-p", $$user[$PASSWD]);
+ @command = ($cmd_useradd, "-m");
push (@command, ("-d", $$user[$HOME])) if ($$user[$HOME]);
push (@command, ("-s", $$user[$SHELL])) if ($$user[$SHELL]);
@@ -695,6 +624,7 @@ sub add_user
}
&change_user_chfn ($$user[$LOGIN], undef, $$user[$COMMENT]);
+ &set_passwd ($$user[$LOGIN], $$user[$PASSWD]);
}
sub change_user
@@ -703,38 +633,20 @@ sub change_user
if ($Utils::Backend::tool{"system"} eq "FreeBSD")
{
- my $pwdpipe;
-
- $command = "$cmd_pw usermod \'" . $$old_user[$LOGIN] . "\'" .
- " -l \'" . $$new_user[$LOGIN] . "\'" .
- " -u \'" . $$new_user[$UID] . "\'" .
- " -d \'" . $$new_user[$HOME] . "\'" .
- " -g \'" . $$new_user[$GID] . "\'" .
- " -s \'" . $$new_user[$SHELL] . "\'" .
- " -H 0"; # pw(8) reads password from STDIN
-
- $pwdpipe = &Utils::File::run_pipe_write ($command);
- print $pwdpipe $$new_user[$PASSWD];
- &Utils::File::close_file ($pwdpipe);
- }
- elsif ($Utils::Backend::tool{"system"} eq "SunOS")
- {
- @command = ($cmd_usermod, "-d", $$new_user[$HOME],
- "-g", $$new_user[$GID],
- "-l", $$new_user[$LOGIN],
- "-s", $$new_user[$SHELL],
- "-u", $$new_user[$UID],
- $$old_user[$LOGIN]);
+ @command = ($cmd_pw, "usermod", $$old_user[$LOGIN],
+ "-l", $$new_user[$LOGIN],
+ "-u", $$new_user[$UID],
+ "-d", $$new_user[$HOME],
+ "-g", $$new_user[$GID],
+ "-s", $$new_user[$SHELL]);
&Utils::File::run (@command);
- &modify_shadow_password ($$new_user[$LOGIN], $$new_user[$PASSWD]);
}
else
{
@command = ($cmd_usermod, "-d", $$new_user[$HOME],
"-g", $$new_user[$GID],
"-l", $$new_user[$LOGIN],
- "-p", $$new_user[$PASSWD],
"-s", $$new_user[$SHELL],
"-u", $$new_user[$UID],
$$old_user[$LOGIN]);
@@ -743,6 +655,7 @@ sub change_user
}
&change_user_chfn ($$new_user[$LOGIN], $$old_user[$COMMENT], $$new_user[$COMMENT]);
+ &set_passwd ($$new_user[$LOGIN], $$new_user[$PASSWD]);
}
sub set_logindefs
diff --git a/UsersConfig.pm b/UsersConfig.pm
index 50c4ad4..562aca1 100644
--- a/UsersConfig.pm
+++ b/UsersConfig.pm
@@ -32,11 +32,11 @@ use Users::Shells;
my $OBJECT_NAME = "UsersConfig2";
my $OBJECT_PATH = "$Utils::Backend::DBUS_PATH/$OBJECT_NAME";
-# settings: list of shells, use MD5, umin, umax, home prefix, default shell, default group, encrypted home support
+# settings: list of shells, umin, umax, home prefix, default shell, default group, encrypted home support
# only configuration settings are set via UsersConfig
-my $set_format = [ [ "array", "string" ], "bool", "uint32", "uint32", "string", "string", "uint32", "bool" ];
+my $set_format = [ [ "array", "string" ], "uint32", "uint32", "string", "string", "uint32", "bool" ];
# array of users plus configuration settings
-my $get_format = [[ "array", $UserConfig::USER_FORMAT ], [ "array", "string" ], "bool", "uint32", "uint32", "string", "string", "uint32", "bool" ];
+my $get_format = [[ "array", $UserConfig::USER_FORMAT ], [ "array", "string" ], "uint32", "uint32", "string", "string", "uint32", "bool" ];
sub new
@@ -55,15 +55,14 @@ dbus_method ("set", $set_format, []);
sub get
{
my ($self) = @_;
- my $logindefs, $users, $use_md5, $shells;
+ my $logindefs, $users, $shells;
$self->SUPER::reset_counter ();
- $use_md5 = &Users::Users::get_use_md5 ();
$logindefs = &Users::Users::get_logindefs ();
$users = &Users::Users::get ();
$shells = &Users::Shells::get ();
- return ($users, $shells, $use_md5, $$logindefs{"umin"},
+ return ($users, $shells, $$logindefs{"umin"},
$$logindefs{"umax"}, $$logindefs{"home_prefix"},
$$logindefs{"shell"}, $$logindefs{"group"}, 0);
}