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