]>
Commit | Line | Data |
---|---|---|
1 | package PVE::Auth::AD; | |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use PVE::Auth::LDAP; | |
6 | use PVE::LDAP; | |
7 | ||
8 | use base qw(PVE::Auth::LDAP); | |
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. DEPRECATED: use 'mode' instead.", | |
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 | base_dn => { optional => 1 }, | |
85 | bind_dn => { optional => 1 }, | |
86 | password => { optional => 1 }, | |
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 }, | |
95 | 'sync-defaults-options' => { optional => 1 }, | |
96 | mode => { optional => 1 }, | |
97 | }; | |
98 | } | |
99 | ||
100 | sub get_users { | |
101 | my ($class, $config, $realm) = @_; | |
102 | ||
103 | $config->{user_attr} //= 'sAMAccountName'; | |
104 | ||
105 | return $class->SUPER::get_users($config, $realm); | |
106 | } | |
107 | ||
108 | sub authenticate_user { | |
109 | my ($class, $config, $realm, $username, $password) = @_; | |
110 | ||
111 | my $servers = [$config->{server1}]; | |
112 | push @$servers, $config->{server2} if $config->{server2}; | |
113 | ||
114 | my ($scheme, $port) = $class->get_scheme_and_port($config); | |
115 | ||
116 | my %ad_args; | |
117 | if ($config->{verify}) { | |
118 | $ad_args{verify} = 'require'; | |
119 | $ad_args{clientcert} = $config->{cert} if $config->{cert}; | |
120 | $ad_args{clientkey} = $config->{certkey} if $config->{certkey}; | |
121 | if (defined(my $capath = $config->{capath})) { | |
122 | if (-d $capath) { | |
123 | $ad_args{capath} = $capath; | |
124 | } else { | |
125 | $ad_args{cafile} = $capath; | |
126 | } | |
127 | } | |
128 | } elsif (defined($config->{verify})) { | |
129 | $ad_args{verify} = 'none'; | |
130 | } | |
131 | ||
132 | if ($scheme ne 'ldap') { | |
133 | $ad_args{sslversion} = $config->{sslversion} // 'tlsv1_2'; | |
134 | } | |
135 | ||
136 | my $ldap = PVE::LDAP::ldap_connect($servers, $scheme, $port, \%ad_args); | |
137 | ||
138 | $username = "$username\@$config->{domain}" | |
139 | if $username !~ m/@/ && $config->{domain}; | |
140 | ||
141 | PVE::LDAP::auth_user_dn($ldap, $username, $password); | |
142 | ||
143 | $ldap->unbind(); | |
144 | return 1; | |
145 | } | |
146 | ||
147 | 1; |