]> git.proxmox.com Git - pmg-api.git/blame - PMG/AccessControl.pm
cleanup error message
[pmg-api.git] / PMG / AccessControl.pm
CommitLineData
1360e6f0
DM
1package PMG::AccessControl;
2
3use strict;
4use warnings;
5use Authen::PAM;
9d7f54a3 6use PVE::Tools;
1360e6f0
DM
7
8use PVE::JSONSchema qw(get_standard_option);
9
62ebb4bc 10use PMG::UserConfig;
1360e6f0
DM
11
12sub normalize_path {
13 my $path = shift;
14
15 $path =~ s|/+|/|g;
16
17 $path =~ s|/$||;
18
19 $path = '/' if !$path;
20
21 $path = "/$path" if $path !~ m|^/|;
22
23 return undef if $path !~ m|^[[:alnum:]\.\-\_\/]+$|;
24
25 return $path;
26}
27
1360e6f0
DM
28# password should be utf8 encoded
29# Note: some plugins delay/sleep if auth fails
30sub authenticate_user {
31 my ($username, $password, $otp) = @_;
32
33 die "no username specified\n" if !$username;
34
35 my ($ruid, $realm);
36
62ebb4bc 37 ($username, $ruid, $realm) = PMG::Utils::verify_username($username);
1360e6f0
DM
38
39 if ($realm eq 'pam') {
62ebb4bc
DM
40 die "invalid pam user (only root allowed)\n" if $ruid ne 'root';
41 authenticate_pam_user($ruid, $password);
1360e6f0
DM
42 return $username;
43 }
44
62ebb4bc
DM
45 if ($realm eq 'pmg') {
46 my $usercfg = PMG::UserConfig->new();
47 $usercfg->authenticate_user($ruid, $password);
48 return $username;
49 }
50
1360e6f0
DM
51 die "no such realm '$realm'\n";
52}
53
54sub domain_set_password {
62ebb4bc 55 my ($realm, $ruid, $password) = @_;
1360e6f0
DM
56
57 die "no auth domain specified" if !$realm;
58
62ebb4bc
DM
59 if ($realm eq 'pam') {
60 die "invalid pam user (only root allowed)\n" if $ruid ne 'root';
1360e6f0 61
62ebb4bc 62 my $cmd = ['usermod'];
1360e6f0 63
62ebb4bc 64 my $epw = PMG::Utils::encrypt_pw($password);
1360e6f0 65
62ebb4bc 66 push @$cmd, '-p', $epw, $ruid;
1360e6f0 67
62ebb4bc 68 run_command($cmd, errmsg => "change password for '$ruid' failed");
1360e6f0 69
62ebb4bc
DM
70 } elsif ($realm eq 'pmg') {
71 PMG::UserConfig->set_password($ruid, $password);
72 } else {
73 die "no such realm '$realm'\n";
74 }
1360e6f0
DM
75}
76
62ebb4bc 77# test if user exists and is enabled
1360e6f0 78sub check_user_enabled {
62ebb4bc 79 my ($username, $noerr) = @_;
1360e6f0 80
62ebb4bc 81 my ($userid, $ruid, $realm) = PMG::Utils::verify_username($username, 1);
1360e6f0 82
62ebb4bc
DM
83 if ($realm && $ruid) {
84 if ($realm eq 'pam') {
85 return 1 if $ruid eq 'root';
86 } elsif ($realm eq 'pmg') {
87 my $usercfg = PMG::UserConfig->new();
88 my $data = $usercfg->check_user_exist($ruid, $noerr);
89 return 1 if $data && $data->{enable};
90 }
91 }
1360e6f0
DM
92
93 die "user '$username' is disabled\n" if !$noerr;
94
95 return undef;
96}
97
62ebb4bc 98sub authenticate_pam_user {
1360e6f0
DM
99 my ($username, $password) = @_;
100
62ebb4bc 101 # user need to be able to read /etc/passwd /etc/shadow
1360e6f0
DM
102
103 my $pamh = Authen::PAM->new('common-auth', $username, sub {
104 my @res;
105 while(@_) {
106 my $msg_type = shift;
107 my $msg = shift;
108 push @res, (0, $password);
109 }
110 push @res, 0;
111 return @res;
112 });
113
114 if (!ref($pamh)) {
115 my $err = $pamh->pam_strerror($pamh);
116 die "Error during PAM init: $err";
117 }
118
119 my $res;
120
121 if (($res = $pamh->pam_authenticate(0)) != PAM_SUCCESS) {
122 my $err = $pamh->pam_strerror($res);
123 die "auth failed: $err";
124 }
125
9d7f54a3 126 if (($res = $pamh->pam_acct_mgmt(0)) != PAM_SUCCESS) {
1360e6f0
DM
127 my $err = $pamh->pam_strerror($res);
128 die "auth failed: $err";
129 }
130
131 $pamh = 0; # call destructor
132
133 return 1;
134}
135
1360e6f0 1361;