]> git.proxmox.com Git - pve-access-control.git/blob - src/PVE/Auth/PAM.pm
bump version to 8.1.4
[pve-access-control.git] / src / PVE / Auth / PAM.pm
1 package PVE::Auth::PAM;
2
3 use strict;
4 use warnings;
5
6 use PVE::Tools qw(run_command);
7 use PVE::Auth::Plugin;
8 use Authen::PAM qw(:constants);
9
10 use base qw(PVE::Auth::Plugin);
11
12 sub type {
13 return 'pam';
14 }
15
16 sub options {
17 return {
18 default => { optional => 1 },
19 comment => { optional => 1 },
20 tfa => { optional => 1 },
21 };
22 }
23
24 sub authenticate_user {
25 my ($class, $config, $realm, $username, $password) = @_;
26
27 # user (www-data) need to be able to read /etc/passwd /etc/shadow
28 die "no password\n" if !$password;
29
30 my $pamh = Authen::PAM->new('proxmox-ve-auth', $username, sub {
31 my @res;
32 while(@_) {
33 my $msg_type = shift;
34 my $msg = shift;
35 push @res, (0, $password);
36 }
37 push @res, 0;
38 return @res;
39 });
40
41 if (!ref ($pamh)) {
42 my $err = $pamh->pam_strerror($pamh);
43 die "error during PAM init: $err";
44 }
45
46 if (my $rpcenv = PVE::RPCEnvironment::get()) {
47 if (my $ip = $rpcenv->get_client_ip()) {
48 $pamh->pam_set_item(PAM_RHOST(), $ip);
49 }
50 }
51
52 my $res;
53
54 if (($res = $pamh->pam_authenticate(0)) != PAM_SUCCESS) {
55 my $err = $pamh->pam_strerror($res);
56 die "$err\n";
57 }
58
59 if (($res = $pamh->pam_acct_mgmt (0)) != PAM_SUCCESS) {
60 my $err = $pamh->pam_strerror($res);
61 die "$err\n";
62 }
63
64 $pamh = 0; # call destructor
65
66 return 1;
67 }
68
69
70 sub store_password {
71 my ($class, $config, $realm, $username, $password) = @_;
72
73 my $cmd = ['usermod'];
74
75 my $epw = PVE::Tools::encrypt_pw($password);
76
77 push @$cmd, '-p', $epw, $username;
78
79 run_command($cmd, errmsg => 'change password failed');
80 }
81
82 1;