]> git.proxmox.com Git - pve-access-control.git/blob - PVE/Auth/AD.pm
06fac9dff9f4faa279469e51f7a179c93aa83684
[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 PVE::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 format => 'address',
20 maxLength => 256,
21 },
22 server2 => {
23 description => "Fallback Server IP address (or DNS name)",
24 type => 'string',
25 optional => 1,
26 format => 'address',
27 maxLength => 256,
28 },
29 secure => {
30 description => "Use secure LDAPS protocol.",
31 type => 'boolean',
32 optional => 1,
33 },
34 sslversion => {
35 description => "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!",
36 type => 'string',
37 enum => [qw(tlsv1 tlsv1_1 tlsv1_2 tlsv1_3)],
38 optional => 1,
39 },
40 default => {
41 description => "Use this as default realm",
42 type => 'boolean',
43 optional => 1,
44 },
45 comment => {
46 description => "Description.",
47 type => 'string',
48 optional => 1,
49 maxLength => 4096,
50 },
51 port => {
52 description => "Server port.",
53 type => 'integer',
54 minimum => 1,
55 maximum => 65535,
56 optional => 1,
57 },
58 domain => {
59 description => "AD domain name",
60 type => 'string',
61 pattern => '\S+',
62 optional => 1,
63 maxLength => 256,
64 },
65 tfa => PVE::JSONSchema::get_standard_option('tfa'),
66 };
67 }
68
69 sub options {
70 return {
71 server1 => {},
72 server2 => { optional => 1 },
73 domain => {},
74 port => { optional => 1 },
75 secure => { optional => 1 },
76 sslversion => { optional => 1 },
77 default => { optional => 1 },,
78 comment => { optional => 1 },
79 tfa => { optional => 1 },
80 verify => { optional => 1 },
81 capath => { optional => 1 },
82 cert => { optional => 1 },
83 certkey => { optional => 1 },
84 };
85 }
86
87 sub authenticate_user {
88 my ($class, $config, $realm, $username, $password) = @_;
89
90 my $servers = [$config->{server1}];
91 push @$servers, $config->{server2} if $config->{server2};
92
93 my $default_port = $config->{secure} ? 636: 389;
94 my $port = $config->{port} // $default_port;
95 my $scheme = $config->{secure} ? 'ldaps' : 'ldap';
96
97 my %ad_args;
98 if ($config->{verify}) {
99 $ad_args{verify} = 'require';
100 $ad_args{clientcert} = $config->{cert} if $config->{cert};
101 $ad_args{clientkey} = $config->{certkey} if $config->{certkey};
102 if (defined(my $capath = $config->{capath})) {
103 if (-d $capath) {
104 $ad_args{capath} = $capath;
105 } else {
106 $ad_args{cafile} = $capath;
107 }
108 }
109 } elsif (defined($config->{verify})) {
110 $ad_args{verify} = 'none';
111 }
112
113 if ($config->{secure}) {
114 $ad_args{sslversion} = $config->{sslversion} // 'tlsv1_2';
115 }
116
117 my $ldap = PVE::LDAP::ldap_connect($servers, $scheme, $port, \%ad_args);
118
119 $username = "$username\@$config->{domain}"
120 if $username !~ m/@/ && $config->{domain};
121
122 PVE::LDAP::auth_user_dn($ldap, $username, $password);
123
124 $ldap->unbind();
125 return 1;
126 }
127
128 1;