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