]>
git.proxmox.com Git - pmg-api.git/blob - PMG/AccessControl.pm
1 package PMG
::AccessControl
;
8 use PVE
::JSONSchema
qw(get_standard_option);
10 my $realm_regex = qr/[A-Za-z][A-Za-z0-9\.\-_]+/;
12 PVE
::JSONSchema
::register_format
('pmg-realm', \
&verify_realm
);
14 my ($realm, $noerr) = @_;
16 if ($realm !~ m/^${realm_regex}$/) {
17 return undef if $noerr;
18 die "value does not look like a valid realm\n";
23 PVE
::JSONSchema
::register_standard_option
('realm', {
24 description
=> "Authentication domain ID",
25 type
=> 'string', format
=> 'pmg-realm',
29 PVE
::JSONSchema
::register_format
('pmg-userid', \
&verify_username
);
31 my ($username, $noerr) = @_;
33 $username = '' if !$username;
34 my $len = length($username);
36 die "user name '$username' is too short\n" if !$noerr;
40 die "user name '$username' is too long ($len > 64)\n" if !$noerr;
44 # we only allow a limited set of characters
45 # colon is not allowed, because we store usernames in
46 # colon separated lists)!
47 # slash is not allowed because it is used as pve API delimiter
48 # also see "man useradd"
49 if ($username =~ m!^([^\s:/]+)\@(${realm_regex})$!) {
50 return wantarray ?
($username, $1, $2) : $username;
53 die "value '$username' does not look like a valid user name\n" if !$noerr;
58 PVE
::JSONSchema
::register_standard_option
('userid', {
59 description
=> "User ID",
60 type
=> 'string', format
=> 'pmg-userid',
71 $path = '/' if !$path;
73 $path = "/$path" if $path !~ m
|^/|;
75 return undef if $path !~ m
|^[[:alnum
:]\
.\
-\_\
/]+$|;
80 # password should be utf8 encoded
81 # Note: some plugins delay/sleep if auth fails
82 sub authenticate_user
{
83 my ($username, $password, $otp) = @_;
85 die "no username specified\n" if !$username;
89 ($username, $ruid, $realm) = verify_username
($username);
91 if ($realm eq 'pam') {
92 is_valid_user_utf8
($ruid, $password);
96 die "no such realm '$realm'\n";
99 sub domain_set_password
{
100 my ($realm, $username, $password) = @_;
102 die "no auth domain specified" if !$realm;
104 die "not implemented";
107 sub check_user_exist
{
108 my ($usercfg, $username, $noerr) = @_;
110 $username = verify_username
($username, $noerr);
111 return undef if !$username;
113 return $usercfg->{users
}->{$username} if $usercfg && $usercfg->{users
}->{$username};
115 die "no such user ('$username')\n" if !$noerr;
120 sub check_user_enabled
{
121 my ($usercfg, $username, $noerr) = @_;
123 my $data = check_user_exist
($usercfg, $username, $noerr);
124 return undef if !$data;
126 return 1 if $data->{enable
};
128 die "user '$username' is disabled\n" if !$noerr;
133 sub is_valid_user_utf8
{
134 my ($username, $password) = @_;
136 # user (www-data) need to be able to read /etc/passwd /etc/shadow
138 my $pamh = Authen
::PAM-
>new('common-auth', $username, sub {
141 my $msg_type = shift;
143 push @res, (0, $password);
150 my $err = $pamh->pam_strerror($pamh);
151 die "Error during PAM init: $err";
156 if (($res = $pamh->pam_authenticate(0)) != PAM_SUCCESS
) {
157 my $err = $pamh->pam_strerror($res);
158 die "auth failed: $err";
161 if (($res = $pamh->pam_acct_mgmt(0)) != PAM_SUCCESS
) {
162 my $err = $pamh->pam_strerror($res);
163 die "auth failed: $err";
166 $pamh = 0; # call destructor
172 my ($username, $password) = @_;
174 return is_valid_user_utf8
($username, encode
("utf8", $password));