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 #ifdef __gnu_linux__
30 #define _GNU_SOURCE
31 #endif
32
33 #include "ldap_resource.h"
34
35 #include "../util/util.h"
36
37
38
39 static ResourceType ldap_resource_type = {
40 (resource_pool_init_func)ldap_resourcepool_init,
41 (resource_pool_destroy_func)ldap_resourcepool_destroy,
42 (resource_pool_createresource_func)ldap_resourcepool_createresource,
43 (resource_pool_freeresource_func)ldap_resourcepool_freeresource,
44 (resource_pool_prepare_func)ldap_resourcepool_prepare,
45 (resource_pool_finish_func)ldap_resourcepool_finish,
46 (resource_pool_getresourcedata_func)ldap_resourcepool_getresourcedata
47 };
48
49
50 ResourceType* ldap_get_resource_type(
void) {
51 return &ldap_resource_type;
52 }
53
54 LDAP* ws_ldap_resource_create_connection(
55 const char *hostname,
56 int port,
57 int ssl,
58 int ldap_version)
59 {
60 LDAP *ld =
NULL;
61
62 #ifdef SOLARIS
63 ld = ldap_init(config->hostname, config->port);
64 #else
65 char *ldap_uri =
NULL;
66 asprintf(&ldap_uri,
"ldap://%s:%d", hostname, port);
67 ld = ws_ldap_resource_create_uri_connection(ldap_uri, ldap_version);
68 free(ldap_uri);
69 #endif
70
71 if(ld) {
72 ldap_set_option(ld,
LDAP_OPT_PROTOCOL_VERSION, &ldap_version);
73 }
74
75 return ld;
76 }
77
78 LDAP* ws_ldap_resource_create_uri_connection(
79 const char *uri,
80 int ldap_version)
81 {
82 #ifdef SOLARIS
83 log_ereport(
LOG_FAILURE,
"ldap_resource_create_connection_uri is not implemented on Solaris yet");
84 return NULL;
85 #else
86
87 LDAP *ld =
NULL;
88 int init_ret = ldap_initialize(&ld, uri);
89 if(init_ret) {
90 log_ereport(
91 LOG_FAILURE,
92 "ldap_resource_create_connection failed: uri: %s",
93 uri);
94 }
95 return ld;
96 #endif
97 }
98
99 void ws_ldap_close(
LDAP *ldap) {
100 #ifdef SOLARIS
101 ldap_unbind(ldap);
102 #else
103 ldap_unbind_ext_s(ldap,
NULL,
NULL);
104 #endif
105 }
106
107
108
109
110
111
112
113
114
115 void * ldap_resourcepool_init(
pool_handle_t *pool,
const char *rpname, pblock *pb) {
116 char *ldap_uri = pblock_findval(
"Uri", pb);
117 char *host = pblock_findval(
"Host", pb);
118 char *port = pblock_findval(
"Port", pb);
119 char *binddn = pblock_findval(
"Binddn", pb);
120 char *bindpw = pblock_findval(
"Bindpw", pb);
121 char *bind = pblock_findval(
"Bind", pb);
122
123 log_ereport(
124 LOG_INFORM,
125 "create ldap resource pool: name=%s : %s%s%s%s : binddn=%s",
126 rpname,
127 ldap_uri ?
"uri=" :
"host=",
128 ldap_uri ? ldap_uri : host,
129 ldap_uri || !port ?
"" :
":",
130 !port ?
"" : port,
131 binddn ? binddn :
"''''");
132
133 if(!ldap_uri && !host) {
134 log_ereport(
LOG_MISCONFIG,
"Resource pool %s: No host or ldap uri specified", rpname);
135 return NULL;
136 }
137 if(ldap_uri && host) {
138 log_ereport(
LOG_MISCONFIG,
"Resource pool %s: Either Uri or Host must be specified, not both", rpname);
139 return NULL;
140 }
141
142 int64_t port_i =
0;
143 if(host) {
144 if(port) {
145 if(util_strtoint(port, &port_i)) {
146 if(port_i <
1 || port_i >
65535) {
147 log_ereport(
LOG_MISCONFIG,
"Resource pool %s: Port %s is out of range", rpname, port);
148 }
149 }
else {
150 log_ereport(
LOG_MISCONFIG,
"Resource pool %s: Port ''%s'' is not a valid number", rpname, port);
151 }
152 }
else {
153 port_i =
LDAP_PORT;
154 }
155 }
156
157 LDAPResourcePool *ldap_pool = pool_malloc(pool,
sizeof(LDAPResourcePool));
158 if(!ldap_pool) {
159 return NULL;
160 }
161
162 ldap_pool->name = rpname;
163 ldap_pool->pool = pool;
164 ldap_pool->ldap_uri = ldap_uri;
165 ldap_pool->host = host;
166 ldap_pool->port = (
int)port_i;
167 ldap_pool->binddn = binddn;
168 ldap_pool->bindpw = bindpw;
169 WSBool bind_def = binddn !=
NULL;
170 ldap_pool->bind = bind ? util_getboolean(bind, bind_def) : bind_def;
171
172 return ldap_pool;
173 }
174
175 void ldap_resourcepool_destroy(LDAPResourcePool *pool) {
176
177 }
178
179 void * ldap_resourcepool_createresource(LDAPResourcePool *respool) {
180 LDAP *ldap =
NULL;
181 if(respool->ldap_uri) {
182 ldap = ws_ldap_resource_create_uri_connection(respool->ldap_uri,
LDAP_VERSION3);
183 }
else {
184 ldap = ws_ldap_resource_create_connection(respool->host, respool->port,
FALSE,
LDAP_VERSION3);
185 }
186
187 if(!ldap) {
188 log_ereport(
189 LOG_FAILURE,
190 "resource pool %s: %s: cannot create LDAP session",
191 respool->name,
192 respool->ldap_uri ? respool->ldap_uri : respool->host);
193 return NULL;
194 }
195
196 if(respool->bind) {
197 struct berval *server_cred;
198 int r = ldap_resource_bind(respool, ldap, &server_cred);
199 if(r !=
LDAP_SUCCESS) {
200 log_ereport(
LOG_FAILURE,
"resource pool %s: bind failed: %s", respool->name, ldap_err2string(r));
201 ws_ldap_close(ldap);
202 return NULL;
203 }
204 }
205
206 LDAPResource *res = pool_malloc(respool->pool,
sizeof(LDAPResource));
207 if(!res) {
208 ws_ldap_close(ldap);
209 log_ereport(
LOG_CATASTROPHE,
"ldap_resourcepool_createresource: OOM");
210 return NULL;
211 }
212 res->ldap = ldap;
213 res->res_pool = respool;
214
215 return res;
216 }
217
218 void ldap_resourcepool_freeresource(LDAPResourcePool *pool, LDAPResource *res) {
219 if(res->ldap) {
220 ws_ldap_close(res->ldap);
221 }
222 pool_free(pool->pool, res);
223 }
224
225 int ldap_resourcepool_prepare(LDAPResourcePool *pool, LDAPResource *res) {
226
227 return 0;
228 }
229
230 int ldap_resourcepool_finish(LDAPResourcePool *pool, LDAPResource *res) {
231
232 return 0;
233 }
234
235 void * ldap_resourcepool_getresourcedata(LDAPResource *res) {
236 return res->ldap;
237 }
238
239
240 int ldap_resource_bind(LDAPResourcePool *respool,
LDAP *ldap,
struct berval **server_cred) {
241 if(!respool->binddn) {
242 return -
1;
243 }
244 return ws_ldap_bind(ldap, respool->binddn, respool->bindpw, server_cred);
245 }
246
247 int ws_ldap_bind(
LDAP *ldap,
const char *binddn,
const char *bindpw,
struct berval **server_cred) {
248 struct berval cred;
249 cred.bv_val = (
char*)bindpw;
250 cred.bv_len = strlen(cred.bv_val);
251 return ldap_sasl_bind_s(
252 ldap,
253 binddn,
254 LDAP_SASL_SIMPLE,
255 &cred,
256 NULL,
257 NULL,
258 server_cred);
259 }
260
261