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