1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
#pragma once
#include "clickhouse_config.h"
#include <base/types.h>
#if USE_LDAP
# error #include <ldap.h>
# define MAYBE_NORETURN
#else
# define MAYBE_NORETURN [[noreturn]]
#endif
#include <chrono>
#include <optional>
#include <set>
#include <vector>
class SipHash;
namespace DB
{
class LDAPClient
{
public:
struct SearchParams
{
enum class Scope
{
BASE,
ONE_LEVEL,
SUBTREE,
CHILDREN
};
String base_dn;
Scope scope = Scope::SUBTREE;
String search_filter;
String attribute = "cn";
void updateHash(SipHash & hash) const;
};
struct RoleSearchParams
: public SearchParams
{
String prefix;
void updateHash(SipHash & hash) const;
};
using RoleSearchParamsList = std::vector<RoleSearchParams>;
using SearchResults = std::set<String>;
using SearchResultsList = std::vector<SearchResults>;
struct Params
{
enum class ProtocolVersion
{
V2,
V3
};
enum class TLSEnable
{
NO,
YES_STARTTLS,
YES
};
enum class TLSProtocolVersion
{
SSL2,
SSL3,
TLS1_0,
TLS1_1,
TLS1_2
};
enum class TLSRequireCert
{
NEVER,
ALLOW,
TRY,
DEMAND
};
enum class SASLMechanism
{
UNKNOWN,
SIMPLE
};
ProtocolVersion protocol_version = ProtocolVersion::V3;
String host;
UInt16 port = 636;
TLSEnable enable_tls = TLSEnable::YES;
TLSProtocolVersion tls_minimum_protocol_version = TLSProtocolVersion::TLS1_2;
TLSRequireCert tls_require_cert = TLSRequireCert::DEMAND;
String tls_cert_file;
String tls_key_file;
String tls_ca_cert_file;
String tls_ca_cert_dir;
String tls_cipher_suite;
SASLMechanism sasl_mechanism = SASLMechanism::SIMPLE;
String bind_dn;
String user;
String password;
std::optional<SearchParams> user_dn_detection;
std::chrono::seconds verification_cooldown{0};
std::chrono::seconds operation_timeout{40};
std::chrono::seconds network_timeout{30};
std::chrono::seconds search_timeout{20};
UInt32 search_limit = 256; /// An arbitrary number, no particular motivation for this value.
void updateHash(SipHash & hash) const;
};
explicit LDAPClient(const Params & params_);
~LDAPClient();
LDAPClient(const LDAPClient &) = delete;
LDAPClient(LDAPClient &&) = delete;
LDAPClient & operator= (const LDAPClient &) = delete;
LDAPClient & operator= (LDAPClient &&) = delete;
protected:
MAYBE_NORETURN void handleError(int result_code, String text = "");
MAYBE_NORETURN bool openConnection();
void closeConnection() noexcept;
SearchResults search(const SearchParams & search_params);
const Params params;
#if USE_LDAP
LDAP * handle = nullptr;
#endif
String final_user_name;
String final_bind_dn;
String final_user_dn;
};
class LDAPSimpleAuthClient
: private LDAPClient
{
public:
using LDAPClient::LDAPClient;
bool authenticate(const RoleSearchParamsList * role_search_params, SearchResultsList * role_search_results);
};
}
#undef MAYBE_NORETURN
|