]>
git.proxmox.com Git - pmg-api.git/blob - src/PMG/AccessControl.pm
1 package PMG
::AccessControl
;
8 use PVE
::JSONSchema
qw(get_standard_option);
9 use PVE
::Exception
qw(raise raise_perm_exc);
22 $path = '/' if !$path;
24 $path = "/$path" if $path !~ m
|^/|;
26 return undef if $path !~ m
|^[[:alnum
:]\
.\
-\_\
/]+$|;
31 # password should be utf8 encoded
32 # Note: some plugins delay/sleep if auth fails
33 sub authenticate_user
{
34 my ($username, $password, $otp) = @_;
36 die "no username specified\n" if !$username;
40 ($username, $ruid, $realm) = PMG
::Utils
::verify_username
($username);
42 if ($realm eq 'pam') {
43 die "invalid pam user (only root allowed)\n" if $ruid ne 'root';
44 authenticate_pam_user
($ruid, $password);
46 } elsif ($realm eq 'pmg') {
47 my $usercfg = PMG
::UserConfig-
>new();
48 $usercfg->authenticate_user($username, $password);
50 } elsif ($realm eq 'quarantine') {
51 my $ldap_cfg = PMG
::LDAPConfig-
>new();
52 my $ldap = PMG
::LDAPSet-
>new_from_ldap_cfg($ldap_cfg, 1);
54 if (my $ldapinfo = $ldap->account_info($ruid, $password)) {
55 my $pmail = $ldapinfo->{pmail
};
56 return $pmail . '@quarantine';
58 die "ldap login failed\n";
62 die "no such realm '$realm'\n";
65 sub set_user_password
{
66 my ($username, $password) = @_;
70 ($username, $ruid, $realm) = PMG
::Utils
::verify_username
($username);
72 if ($realm eq 'pam') {
73 die "invalid pam user (only root allowed)\n" if $ruid ne 'root';
75 my $cmd = ['usermod'];
77 my $epw = PVE
::Tools
::encrypt_pw
($password);
79 push @$cmd, '-p', $epw, $ruid;
81 PVE
::Tools
::run_command
($cmd, errmsg
=> "change password for '$ruid' failed");
83 } elsif ($realm eq 'pmg') {
84 PMG
::UserConfig-
>set_user_password($username, $password);
86 die "no such realm '$realm'\n";
90 # test if user exists and is enabled
92 sub check_user_enabled
{
93 my ($usercfg, $username, $noerr) = @_;
97 ($username, $ruid, $realm) = PMG
::Utils
::verify_username
($username, 1);
99 if ($realm && $ruid) {
100 if ($realm eq 'pam') {
101 return 'root' if $ruid eq 'root';
102 } elsif ($realm eq 'pmg') {
103 my $usercfg = PMG
::UserConfig-
>new();
104 my $data = $usercfg->lookup_user_data($username, $noerr);
105 return $data->{role} if $data && $data->{enable
};
106 } elsif ($realm eq 'quarantine') {
111 raise_perm_exc
("user '$username' is disabled") if !$noerr;
116 sub authenticate_pam_user
{
117 my ($username, $password) = @_;
119 # user need to be able to read /etc/passwd /etc/shadow
121 my $pamh = Authen
::PAM-
>new('common-auth', $username, sub {
124 my $msg_type = shift;
126 push @res, (0, $password);
133 my $err = $pamh->pam_strerror($pamh);
134 die "Error during PAM init: $err";
139 if (($res = $pamh->pam_authenticate(0)) != PAM_SUCCESS
) {
140 my $err = $pamh->pam_strerror($res);
141 die "auth failed: $err";
144 if (($res = $pamh->pam_acct_mgmt(0)) != PAM_SUCCESS
) {
145 my $err = $pamh->pam_strerror($res);
146 die "auth failed: $err";
149 $pamh = 0; # call destructor