]> git.proxmox.com Git - pve-access-control.git/blame - PVE/Auth/PVE.pm
d/control: bump debhelper compat to >= 12
[pve-access-control.git] / PVE / Auth / PVE.pm
CommitLineData
5bb4e06a
DM
1package PVE::Auth::PVE;
2
3use strict;
7c410d63 4use warnings;
3641833b 5use Encode;
7c410d63 6
63358f40 7use PVE::Tools;
5bb4e06a
DM
8use PVE::Auth::Plugin;
9use PVE::Cluster qw(cfs_register_file cfs_read_file cfs_write_file cfs_lock_file);
10
11use base qw(PVE::Auth::Plugin);
12
13my $shadowconfigfile = "priv/shadow.cfg";
14
15cfs_register_file($shadowconfigfile,
16 \&parse_shadow_passwd,
17 \&write_shadow_config);
18
19sub parse_shadow_passwd {
20 my ($filename, $raw) = @_;
21
22 my $shadow = {};
23
8978ab37
FG
24 return $shadow if !defined($raw);
25
62af314a 26 while ($raw =~ /^\s*(.+?)\s*$/gm) {
5bb4e06a
DM
27 my $line = $1;
28
5bb4e06a
DM
29 if ($line !~ m/^\S+:\S+:$/) {
30 warn "pve shadow password: ignore invalid line $.\n";
31 next;
32 }
33
34 my ($userid, $crypt_pass) = split (/:/, $line);
35 $shadow->{users}->{$userid}->{shadow} = $crypt_pass;
36 }
37
38 return $shadow;
39}
40
41sub write_shadow_config {
42 my ($filename, $cfg) = @_;
43
44 my $data = '';
45 foreach my $userid (keys %{$cfg->{users}}) {
46 my $crypt_pass = $cfg->{users}->{$userid}->{shadow};
47 $data .= "$userid:$crypt_pass:\n";
48 }
49
50 return $data
51}
52
53sub lock_shadow_config {
54 my ($code, $errmsg) = @_;
55
56 cfs_lock_file($shadowconfigfile, undef, $code);
57 my $err = $@;
58 if ($err) {
59 $errmsg ? die "$errmsg: $err" : die $err;
60 }
61}
62
63sub type {
64 return 'pve';
65}
66
96f8ebd6 67sub options {
5bb4e06a
DM
68 return {
69 default => { optional => 1 },
70 comment => { optional => 1 },
96f8ebd6 71 tfa => { optional => 1 },
5bb4e06a
DM
72 };
73}
74
75sub authenticate_user {
76 my ($class, $config, $realm, $username, $password) = @_;
77
78 die "no password\n" if !$password;
79
80 my $shadow_cfg = cfs_read_file($shadowconfigfile);
81
82 if ($shadow_cfg->{users}->{$username}) {
3641833b
DM
83 my $encpw = crypt(Encode::encode('utf8', $password),
84 $shadow_cfg->{users}->{$username}->{shadow});
85 die "invalid credentials\n" if ($encpw ne $shadow_cfg->{users}->{$username}->{shadow});
5bb4e06a
DM
86 } else {
87 die "no password set\n";
88 }
89
90 return 1;
91}
92
93sub store_password {
94 my ($class, $config, $realm, $username, $password) = @_;
95
96 lock_shadow_config(sub {
97 my $shadow_cfg = cfs_read_file($shadowconfigfile);
63358f40 98 my $epw = PVE::Tools::encrypt_pw($password);
5bb4e06a
DM
99 $shadow_cfg->{users}->{$username}->{shadow} = $epw;
100 cfs_write_file($shadowconfigfile, $shadow_cfg);
101 });
102}
103
104sub delete_user {
105 my ($class, $config, $realm, $username) = @_;
106
107 lock_shadow_config(sub {
108 my $shadow_cfg = cfs_read_file($shadowconfigfile);
109
110 delete $shadow_cfg->{users}->{$username};
111
112 cfs_write_file($shadowconfigfile, $shadow_cfg);
113 });
114}
115
1161;