]> git.proxmox.com Git - pve-access-control.git/blame - PVE/Auth/AD.pm
d/control: bump debhelper compat to >= 12
[pve-access-control.git] / PVE / Auth / AD.pm
CommitLineData
5bb4e06a
DM
1package PVE::Auth::AD;
2
3use strict;
4use warnings;
e65b53c6 5use PVE::Auth::LDAP;
d9e93d2e 6use PVE::LDAP;
5bb4e06a 7
e65b53c6 8use base qw(PVE::Auth::LDAP);
5bb4e06a
DM
9
10sub type {
11 return 'ad';
12}
13
14sub properties {
15 return {
8bdbfd4d
DC
16 server1 => {
17 description => "Server IP address (or DNS name)",
5bb4e06a 18 type => 'string',
8b600c4d 19 format => 'address',
5bb4e06a
DM
20 maxLength => 256,
21 },
8bdbfd4d 22 server2 => {
5bb4e06a
DM
23 description => "Fallback Server IP address (or DNS name)",
24 type => 'string',
25 optional => 1,
8b600c4d 26 format => 'address',
5bb4e06a
DM
27 maxLength => 256,
28 },
8bdbfd4d 29 secure => {
72a9742b 30 description => "Use secure LDAPS protocol. DEPRECATED: use 'mode' instead.",
8bdbfd4d 31 type => 'boolean',
5bb4e06a 32 optional => 1,
5bb4e06a 33 },
07dd90d7 34 sslversion => {
3b7eaef1 35 description => "LDAPS TLS/SSL version. It's not recommended to use version older than 1.2!",
07dd90d7 36 type => 'string',
3b7eaef1 37 enum => [qw(tlsv1 tlsv1_1 tlsv1_2 tlsv1_3)],
07dd90d7
AD
38 optional => 1,
39 },
8bdbfd4d 40 default => {
5bb4e06a 41 description => "Use this as default realm",
8bdbfd4d 42 type => 'boolean',
5bb4e06a
DM
43 optional => 1,
44 },
8bdbfd4d 45 comment => {
5bb4e06a 46 description => "Description.",
8bdbfd4d 47 type => 'string',
5bb4e06a
DM
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 },
8bdbfd4d 65 tfa => PVE::JSONSchema::get_standard_option('tfa'),
5bb4e06a
DM
66 };
67}
68
69sub options {
70 return {
71 server1 => {},
72 server2 => { optional => 1 },
73 domain => {},
74 port => { optional => 1 },
75 secure => { optional => 1 },
07dd90d7 76 sslversion => { optional => 1 },
5bb4e06a
DM
77 default => { optional => 1 },,
78 comment => { optional => 1 },
96f8ebd6 79 tfa => { optional => 1 },
23e0cf85
DC
80 verify => { optional => 1 },
81 capath => { optional => 1 },
82 cert => { optional => 1 },
83 certkey => { optional => 1 },
e65b53c6
DC
84 base_dn => { optional => 1 },
85 bind_dn => { optional => 1 },
782b702d 86 password => { optional => 1 },
e65b53c6
DC
87 user_attr => { optional => 1 },
88 filter => { optional => 1 },
89 sync_attributes => { optional => 1 },
90 user_classes => { optional => 1 },
91 group_dn => { optional => 1 },
92 group_name_attr => { optional => 1 },
93 group_filter => { optional => 1 },
94 group_classes => { optional => 1 },
0ae051a4 95 'sync-defaults-options' => { optional => 1 },
72a9742b 96 mode => { optional => 1 },
eb41d200 97 'case-sensitive' => { optional => 1 },
5bb4e06a
DM
98 };
99}
100
e65b53c6
DC
101sub get_users {
102 my ($class, $config, $realm) = @_;
103
104 $config->{user_attr} //= 'sAMAccountName';
105
106 return $class->SUPER::get_users($config, $realm);
107}
108
d9e93d2e
DC
109sub authenticate_user {
110 my ($class, $config, $realm, $username, $password) = @_;
111
112 my $servers = [$config->{server1}];
113 push @$servers, $config->{server2} if $config->{server2};
5bb4e06a 114
72a9742b 115 my ($scheme, $port) = $class->get_scheme_and_port($config);
5bb4e06a 116
23e0cf85
DC
117 my %ad_args;
118 if ($config->{verify}) {
119 $ad_args{verify} = 'require';
d9e93d2e
DC
120 $ad_args{clientcert} = $config->{cert} if $config->{cert};
121 $ad_args{clientkey} = $config->{certkey} if $config->{certkey};
23e0cf85
DC
122 if (defined(my $capath = $config->{capath})) {
123 if (-d $capath) {
124 $ad_args{capath} = $capath;
125 } else {
126 $ad_args{cafile} = $capath;
127 }
128 }
129 } elsif (defined($config->{verify})) {
130 $ad_args{verify} = 'none';
131 }
132
72a9742b 133 if ($scheme ne 'ldap') {
d9e93d2e 134 $ad_args{sslversion} = $config->{sslversion} // 'tlsv1_2';
07dd90d7
AD
135 }
136
d9e93d2e 137 my $ldap = PVE::LDAP::ldap_connect($servers, $scheme, $port, \%ad_args);
23e0cf85
DC
138
139 $username = "$username\@$config->{domain}"
5bb4e06a
DM
140 if $username !~ m/@/ && $config->{domain};
141
d9e93d2e 142 PVE::LDAP::auth_user_dn($ldap, $username, $password);
5bb4e06a
DM
143
144 $ldap->unbind();
5bb4e06a
DM
145 return 1;
146}
147
1481;