]> git.proxmox.com Git - pve-access-control.git/blob - PVE/Auth/PAM.pm
drop libdigest-hmac-perl dependency
[pve-access-control.git] / 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 = new Authen::PAM('common-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 my $res;
47
48 if (($res = $pamh->pam_authenticate(0)) != PAM_SUCCESS) {
49 my $err = $pamh->pam_strerror($res);
50 die "$err\n";
51 }
52
53 if (($res = $pamh->pam_acct_mgmt (0)) != PAM_SUCCESS) {
54 my $err = $pamh->pam_strerror($res);
55 die "$err\n";
56 }
57
58 $pamh = 0; # call destructor
59
60 return 1;
61 }
62
63
64 sub store_password {
65 my ($class, $config, $realm, $username, $password) = @_;
66
67 my $cmd = ['usermod'];
68
69 my $epw = PVE::Auth::Plugin::encrypt_pw($password);
70
71 push @$cmd, '-p', $epw, $username;
72
73 run_command($cmd, errmsg => 'change password failed');
74 }
75
76 1;