]> git.proxmox.com Git - pve-access-control.git/blob - PVE/Auth/AD.pm
e03d04c8b367b83ad2cc33bbdcc7767675f53154
[pve-access-control.git] / PVE / Auth / AD.pm
1 package PVE::Auth::AD;
2
3 use strict;
4 use warnings;
5 use PVE::Auth::Plugin;
6 use Net::LDAP;
7 use Net::IP;
8
9 use base qw(PVE::Auth::Plugin);
10
11 sub type {
12 return 'ad';
13 }
14
15 sub properties {
16 return {
17 server1 => {
18 description => "Server IP address (or DNS name)",
19 type => 'string',
20 format => 'address',
21 maxLength => 256,
22 },
23 server2 => {
24 description => "Fallback Server IP address (or DNS name)",
25 type => 'string',
26 optional => 1,
27 format => 'address',
28 maxLength => 256,
29 },
30 secure => {
31 description => "Use secure LDAPS protocol.",
32 type => 'boolean',
33 optional => 1,
34
35 },
36 default => {
37 description => "Use this as default realm",
38 type => 'boolean',
39 optional => 1,
40 },
41 comment => {
42 description => "Description.",
43 type => 'string',
44 optional => 1,
45 maxLength => 4096,
46 },
47 port => {
48 description => "Server port.",
49 type => 'integer',
50 minimum => 1,
51 maximum => 65535,
52 optional => 1,
53 },
54 domain => {
55 description => "AD domain name",
56 type => 'string',
57 pattern => '\S+',
58 optional => 1,
59 maxLength => 256,
60 },
61 tfa => PVE::JSONSchema::get_standard_option('tfa'),
62 };
63 }
64
65 sub options {
66 return {
67 server1 => {},
68 server2 => { optional => 1 },
69 domain => {},
70 port => { optional => 1 },
71 secure => { optional => 1 },
72 default => { optional => 1 },,
73 comment => { optional => 1 },
74 tfa => { optional => 1 },
75 };
76 }
77
78 my $authenticate_user_ad = sub {
79 my ($config, $server, $username, $password) = @_;
80
81 my $default_port = $config->{secure} ? 636: 389;
82 my $port = $config->{port} ? $config->{port} : $default_port;
83 my $scheme = $config->{secure} ? 'ldaps' : 'ldap';
84 $server = "[$server]" if Net::IP::ip_is_ipv6($server);
85 my $conn_string = "$scheme://${server}:$port";
86
87 my $ldap = Net::LDAP->new($conn_string) || die "$@\n";
88
89 $username = "$username\@$config->{domain}"
90 if $username !~ m/@/ && $config->{domain};
91
92 my $res = $ldap->bind($username, password => $password);
93
94 my $code = $res->code();
95 my $err = $res->error;
96
97 $ldap->unbind();
98
99 die "$err\n" if ($code);
100 };
101
102 sub authenticate_user {
103 my ($class, $config, $realm, $username, $password) = @_;
104
105 eval { &$authenticate_user_ad($config, $config->{server1}, $username, $password); };
106 my $err = $@;
107 return 1 if !$err;
108 die $err if !$config->{server2};
109 &$authenticate_user_ad($config, $config->{server2}, $username, $password);
110 return 1;
111 }
112
113 1;