]> git.proxmox.com Git - pve-access-control.git/blob - PVE/Auth/LDAP.pm
Fix #861: use safer sprintf formatting
[pve-access-control.git] / PVE / Auth / LDAP.pm
1 package PVE::Auth::LDAP;
2
3 use strict;
4 use warnings;
5
6 use PVE::Auth::Plugin;
7 use Net::LDAP;
8 use Net::IP;
9 use base qw(PVE::Auth::Plugin);
10
11 sub type {
12 return 'ldap';
13 }
14
15 sub properties {
16 return {
17 base_dn => {
18 description => "LDAP base domain name",
19 type => 'string',
20 pattern => '\w+=[^,]+(,\s*\w+=[^,]+)*',
21 optional => 1,
22 maxLength => 256,
23 },
24 user_attr => {
25 description => "LDAP user attribute name",
26 type => 'string',
27 pattern => '\S{2,}',
28 optional => 1,
29 maxLength => 256,
30 },
31 };
32 }
33
34 sub options {
35 return {
36 server1 => {},
37 server2 => { optional => 1 },
38 base_dn => {},
39 user_attr => {},
40 port => { optional => 1 },
41 secure => { optional => 1 },
42 default => { optional => 1 },
43 comment => { optional => 1 },
44 tfa => { optional => 1 },
45 };
46 }
47
48 my $authenticate_user_ldap = sub {
49 my ($config, $server, $username, $password) = @_;
50
51 my $default_port = $config->{secure} ? 636: 389;
52 my $port = $config->{port} ? $config->{port} : $default_port;
53 my $scheme = $config->{secure} ? 'ldaps' : 'ldap';
54 $server = "[$server]" if Net::IP::ip_is_ipv6($server);
55 my $conn_string = "$scheme://${server}:$port";
56
57 my $ldap = Net::LDAP->new($conn_string, verify => 'none') || die "$@\n";
58 my $search = $config->{user_attr} . "=" . $username;
59 my $result = $ldap->search( base => "$config->{base_dn}",
60 scope => "sub",
61 filter => "$search",
62 attrs => ['dn']
63 );
64 die "no entries returned\n" if !$result->entries;
65 my @entries = $result->entries;
66 my $res = $ldap->bind($entries[0]->dn, password => $password);
67
68 my $code = $res->code();
69 my $err = $res->error;
70
71 $ldap->unbind();
72
73 die "$err\n" if ($code);
74 };
75
76 sub authenticate_user {
77 my ($class, $config, $realm, $username, $password) = @_;
78
79 eval { &$authenticate_user_ldap($config, $config->{server1}, $username, $password); };
80 my $err = $@;
81 return 1 if !$err;
82 die $err if !$config->{server2};
83 &$authenticate_user_ldap($config, $config->{server2}, $username, $password);
84 }
85
86 1;