Line data Source code
1 : /*
2 : Unix SMB/CIFS implementation.
3 : LDAP server
4 : Copyright (C) Stefan Metzmacher 2004
5 :
6 : This program is free software; you can redistribute it and/or modify
7 : it under the terms of the GNU General Public License as published by
8 : the Free Software Foundation; either version 3 of the License, or
9 : (at your option) any later version.
10 :
11 : This program is distributed in the hope that it will be useful,
12 : but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : GNU General Public License for more details.
15 :
16 : You should have received a copy of the GNU General Public License
17 : along with this program. If not, see <http://www.gnu.org/licenses/>.
18 : */
19 :
20 : #include "includes.h"
21 : #include "ldap_server/ldap_server.h"
22 : #include "auth/auth.h"
23 : #include "samba/service.h"
24 : #include <ldb.h>
25 : #include <ldb_errors.h>
26 : #include "../lib/util/dlinklist.h"
27 : #include "dsdb/samdb/samdb.h"
28 : #include "auth/gensec/gensec.h"
29 : #include "auth/gensec/gensec_tstream.h"
30 : #include "param/param.h"
31 : #include "../lib/util/tevent_ntstatus.h"
32 : #include "lib/util/time_basic.h"
33 :
34 337 : static char *ldapsrv_bind_error_msg(TALLOC_CTX *mem_ctx,
35 : HRESULT hresult,
36 : uint32_t DSID,
37 : NTSTATUS status)
38 : {
39 0 : WERROR werr;
40 337 : char *msg = NULL;
41 :
42 337 : status = nt_status_squash(status);
43 337 : werr = ntstatus_to_werror(status);
44 :
45 : /*
46 : * There are 4 lower case hex digits following 'v' at the end,
47 : * but different Windows Versions return different values:
48 : *
49 : * Windows 2008R2 uses 'v1db1'
50 : * Windows 2012R2 uses 'v2580'
51 : *
52 : * We just match Windows 2008R2 as that's what was referenced
53 : * in https://bugzilla.samba.org/show_bug.cgi?id=9048
54 : */
55 337 : msg = talloc_asprintf(mem_ctx, "%08X: LdapErr: DSID-%08X, comment: "
56 : "AcceptSecurityContext error, data %x, v1db1",
57 337 : (unsigned)HRES_ERROR_V(hresult),
58 : (unsigned)DSID,
59 337 : (unsigned)W_ERROR_V(werr));
60 :
61 337 : return msg;
62 : }
63 :
64 : struct ldapsrv_bind_wait_context {
65 : struct ldapsrv_reply *reply;
66 : struct tevent_req *req;
67 : NTSTATUS status;
68 : bool done;
69 : };
70 :
71 : struct ldapsrv_bind_wait_state {
72 : uint8_t dummy;
73 : };
74 :
75 36354 : static struct tevent_req *ldapsrv_bind_wait_send(TALLOC_CTX *mem_ctx,
76 : struct tevent_context *ev,
77 : void *private_data)
78 : {
79 122 : struct ldapsrv_bind_wait_context *bind_wait =
80 36354 : talloc_get_type_abort(private_data,
81 : struct ldapsrv_bind_wait_context);
82 122 : struct tevent_req *req;
83 122 : struct ldapsrv_bind_wait_state *state;
84 :
85 36354 : req = tevent_req_create(mem_ctx, &state,
86 : struct ldapsrv_bind_wait_state);
87 36354 : if (req == NULL) {
88 0 : return NULL;
89 : }
90 36354 : bind_wait->req = req;
91 :
92 36354 : tevent_req_defer_callback(req, ev);
93 :
94 36354 : if (!bind_wait->done) {
95 36232 : return req;
96 : }
97 :
98 0 : if (tevent_req_nterror(req, bind_wait->status)) {
99 0 : return tevent_req_post(req, ev);
100 : }
101 :
102 0 : tevent_req_done(req);
103 0 : return tevent_req_post(req, ev);
104 : }
105 :
106 36354 : static NTSTATUS ldapsrv_bind_wait_recv(struct tevent_req *req)
107 : {
108 36354 : return tevent_req_simple_recv_ntstatus(req);
109 : }
110 :
111 36354 : static NTSTATUS ldapsrv_bind_wait_setup(struct ldapsrv_call *call,
112 : struct ldapsrv_reply *reply)
113 : {
114 36354 : struct ldapsrv_bind_wait_context *bind_wait = NULL;
115 :
116 36354 : if (call->wait_private != NULL) {
117 0 : return NT_STATUS_INTERNAL_ERROR;
118 : }
119 :
120 36354 : bind_wait = talloc_zero(call, struct ldapsrv_bind_wait_context);
121 36354 : if (bind_wait == NULL) {
122 0 : return NT_STATUS_NO_MEMORY;
123 : }
124 36354 : bind_wait->reply = reply;
125 :
126 36354 : call->wait_private = bind_wait;
127 36354 : call->wait_send = ldapsrv_bind_wait_send;
128 36354 : call->wait_recv = ldapsrv_bind_wait_recv;
129 36354 : return NT_STATUS_OK;
130 : }
131 :
132 36354 : static void ldapsrv_bind_wait_finished(struct ldapsrv_call *call,
133 : NTSTATUS status)
134 : {
135 122 : struct ldapsrv_bind_wait_context *bind_wait =
136 36354 : talloc_get_type_abort(call->wait_private,
137 : struct ldapsrv_bind_wait_context);
138 :
139 36354 : bind_wait->done = true;
140 36354 : bind_wait->status = status;
141 :
142 36354 : if (bind_wait->req == NULL) {
143 0 : return;
144 : }
145 :
146 36354 : if (tevent_req_nterror(bind_wait->req, status)) {
147 0 : return;
148 : }
149 :
150 36354 : tevent_req_done(bind_wait->req);
151 : }
152 :
153 : static void ldapsrv_BindSimple_done(struct tevent_req *subreq);
154 :
155 471 : static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
156 : {
157 471 : struct ldap_BindRequest *req = &call->request->r.BindRequest;
158 471 : struct ldapsrv_reply *reply = NULL;
159 471 : struct ldap_BindResponse *resp = NULL;
160 0 : int result;
161 471 : const char *errstr = NULL;
162 0 : NTSTATUS status;
163 471 : bool using_tls = call->conn->sockets.active == call->conn->sockets.tls;
164 471 : struct tevent_req *subreq = NULL;
165 :
166 471 : DEBUG(10, ("BindSimple dn: %s\n",req->dn));
167 :
168 471 : reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
169 471 : if (!reply) {
170 0 : return NT_STATUS_NO_MEMORY;
171 : }
172 :
173 471 : if (req->dn != NULL &&
174 471 : strlen(req->dn) != 0 &&
175 453 : call->conn->require_strong_auth > LDAP_SERVER_REQUIRE_STRONG_AUTH_NO &&
176 385 : !using_tls)
177 : {
178 5 : status = NT_STATUS_NETWORK_ACCESS_DENIED;
179 5 : result = LDAP_STRONG_AUTH_REQUIRED;
180 5 : errstr = talloc_asprintf(reply,
181 : "BindSimple: Transport encryption required.");
182 5 : goto do_reply;
183 : }
184 :
185 466 : subreq = authenticate_ldap_simple_bind_send(call,
186 466 : call->conn->connection->event.ctx,
187 466 : call->conn->connection->msg_ctx,
188 466 : call->conn->lp_ctx,
189 466 : call->conn->connection->remote_address,
190 466 : call->conn->connection->local_address,
191 : using_tls,
192 : req->dn,
193 : req->creds.password);
194 466 : if (subreq == NULL) {
195 0 : return NT_STATUS_NO_MEMORY;
196 : }
197 466 : tevent_req_set_callback(subreq, ldapsrv_BindSimple_done, call);
198 :
199 466 : status = ldapsrv_bind_wait_setup(call, reply);
200 466 : if (!NT_STATUS_IS_OK(status)) {
201 0 : TALLOC_FREE(subreq);
202 0 : return status;
203 : }
204 :
205 : /*
206 : * The rest will be async.
207 : */
208 466 : return NT_STATUS_OK;
209 :
210 5 : do_reply:
211 5 : resp = &reply->msg->r.BindResponse;
212 5 : resp->response.resultcode = result;
213 5 : resp->response.errormessage = errstr;
214 5 : resp->response.dn = NULL;
215 5 : resp->response.referral = NULL;
216 5 : resp->SASL.secblob = NULL;
217 :
218 5 : ldapsrv_queue_reply(call, reply);
219 5 : return NT_STATUS_OK;
220 : }
221 :
222 466 : static void ldapsrv_BindSimple_done(struct tevent_req *subreq)
223 : {
224 0 : struct ldapsrv_call *call =
225 466 : tevent_req_callback_data(subreq,
226 : struct ldapsrv_call);
227 0 : struct ldapsrv_bind_wait_context *bind_wait =
228 466 : talloc_get_type_abort(call->wait_private,
229 : struct ldapsrv_bind_wait_context);
230 466 : struct ldapsrv_reply *reply = bind_wait->reply;
231 466 : struct auth_session_info *session_info = NULL;
232 0 : NTSTATUS status;
233 466 : struct ldap_BindResponse *resp = NULL;
234 0 : int result;
235 466 : const char *errstr = NULL;
236 :
237 466 : status = authenticate_ldap_simple_bind_recv(subreq,
238 : call,
239 : &session_info);
240 466 : if (NT_STATUS_IS_OK(status)) {
241 344 : char *ldb_errstring = NULL;
242 344 : result = LDAP_SUCCESS;
243 344 : errstr = NULL;
244 :
245 344 : talloc_unlink(call->conn, call->conn->session_info);
246 344 : call->conn->session_info = talloc_steal(call->conn, session_info);
247 :
248 344 : call->conn->authz_logged = true;
249 :
250 : /* don't leak the old LDB */
251 344 : talloc_unlink(call->conn, call->conn->ldb);
252 :
253 344 : result = ldapsrv_backend_Init(call->conn, &ldb_errstring);
254 :
255 344 : if (result != LDB_SUCCESS) {
256 : /* Only put the detailed error in DEBUG() */
257 0 : DBG_ERR("ldapsrv_backend_Init failed: %s: %s\n",
258 : ldb_errstring, ldb_strerror(result));
259 0 : errstr = talloc_strdup(reply,
260 : "Simple Bind: Failed to advise "
261 : "ldb new credentials");
262 0 : result = LDB_ERR_OPERATIONS_ERROR;
263 : }
264 : } else {
265 122 : status = nt_status_squash(status);
266 :
267 122 : result = LDAP_INVALID_CREDENTIALS;
268 122 : errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_INVALID_TOKEN,
269 : 0x0C0903A9, status);
270 : }
271 :
272 466 : resp = &reply->msg->r.BindResponse;
273 466 : resp->response.resultcode = result;
274 466 : resp->response.errormessage = errstr;
275 466 : resp->response.dn = NULL;
276 466 : resp->response.referral = NULL;
277 466 : resp->SASL.secblob = NULL;
278 :
279 466 : ldapsrv_queue_reply(call, reply);
280 466 : ldapsrv_bind_wait_finished(call, NT_STATUS_OK);
281 466 : }
282 :
283 : struct ldapsrv_sasl_postprocess_context {
284 : struct ldapsrv_connection *conn;
285 : struct tstream_context *sasl;
286 : };
287 :
288 : struct ldapsrv_sasl_postprocess_state {
289 : uint8_t dummy;
290 : };
291 :
292 26015 : static struct tevent_req *ldapsrv_sasl_postprocess_send(TALLOC_CTX *mem_ctx,
293 : struct tevent_context *ev,
294 : void *private_data)
295 : {
296 122 : struct ldapsrv_sasl_postprocess_context *context =
297 26015 : talloc_get_type_abort(private_data,
298 : struct ldapsrv_sasl_postprocess_context);
299 122 : struct tevent_req *req;
300 122 : struct ldapsrv_sasl_postprocess_state *state;
301 :
302 26015 : req = tevent_req_create(mem_ctx, &state,
303 : struct ldapsrv_sasl_postprocess_state);
304 26015 : if (req == NULL) {
305 0 : return NULL;
306 : }
307 :
308 26015 : TALLOC_FREE(context->conn->sockets.sasl);
309 26015 : context->conn->sockets.sasl = talloc_move(context->conn, &context->sasl);
310 26015 : context->conn->sockets.active = context->conn->sockets.sasl;
311 :
312 26015 : tevent_req_done(req);
313 26015 : return tevent_req_post(req, ev);
314 : }
315 :
316 26015 : static NTSTATUS ldapsrv_sasl_postprocess_recv(struct tevent_req *req)
317 : {
318 26015 : return tevent_req_simple_recv_ntstatus(req);
319 : }
320 :
321 26511 : static NTSTATUS ldapsrv_setup_gensec(struct ldapsrv_connection *conn,
322 : const char *sasl_mech,
323 : struct gensec_security **_gensec_security)
324 : {
325 122 : NTSTATUS status;
326 :
327 122 : struct gensec_security *gensec_security;
328 :
329 26633 : status = samba_server_gensec_start(conn,
330 26389 : conn->connection->event.ctx,
331 26511 : conn->connection->msg_ctx,
332 : conn->lp_ctx,
333 : conn->server_credentials,
334 : "ldap",
335 : &gensec_security);
336 26511 : if (!NT_STATUS_IS_OK(status)) {
337 0 : return status;
338 : }
339 :
340 26511 : status = gensec_set_target_service_description(gensec_security,
341 : "LDAP");
342 26511 : if (!NT_STATUS_IS_OK(status)) {
343 0 : return status;
344 : }
345 :
346 26633 : status = gensec_set_remote_address(gensec_security,
347 26511 : conn->connection->remote_address);
348 26511 : if (!NT_STATUS_IS_OK(status)) {
349 0 : return status;
350 : }
351 :
352 26633 : status = gensec_set_local_address(gensec_security,
353 26511 : conn->connection->local_address);
354 26511 : if (!NT_STATUS_IS_OK(status)) {
355 0 : return status;
356 : }
357 :
358 26511 : gensec_want_feature(gensec_security, GENSEC_FEATURE_ASYNC_REPLIES);
359 26511 : gensec_want_feature(gensec_security, GENSEC_FEATURE_LDAP_STYLE);
360 :
361 26511 : if (conn->sockets.active == conn->sockets.tls) {
362 50 : gensec_want_feature(gensec_security, GENSEC_FEATURE_LDAPS_TRANSPORT);
363 : }
364 :
365 26511 : status = gensec_start_mech_by_sasl_name(gensec_security, sasl_mech);
366 :
367 26511 : if (!NT_STATUS_IS_OK(status)) {
368 0 : return status;
369 : }
370 :
371 26511 : *_gensec_security = gensec_security;
372 26511 : return status;
373 : }
374 :
375 : static void ldapsrv_BindSASL_done(struct tevent_req *subreq);
376 :
377 35888 : static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
378 : {
379 35888 : struct ldap_BindRequest *req = &call->request->r.BindRequest;
380 122 : struct ldapsrv_reply *reply;
381 122 : struct ldap_BindResponse *resp;
382 122 : struct ldapsrv_connection *conn;
383 35888 : int result = 0;
384 35888 : const char *errstr=NULL;
385 35888 : NTSTATUS status = NT_STATUS_OK;
386 35888 : DATA_BLOB input = data_blob_null;
387 35888 : struct tevent_req *subreq = NULL;
388 :
389 35888 : DEBUG(10, ("BindSASL dn: %s\n",req->dn));
390 :
391 35888 : reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
392 35888 : if (!reply) {
393 0 : return NT_STATUS_NO_MEMORY;
394 : }
395 35888 : resp = &reply->msg->r.BindResponse;
396 : /* Windows 2000 mmc doesn't like secblob == NULL and reports a decoding error */
397 35888 : resp->SASL.secblob = talloc_zero(reply, DATA_BLOB);
398 35888 : if (resp->SASL.secblob == NULL) {
399 0 : return NT_STATUS_NO_MEMORY;
400 : }
401 :
402 35888 : conn = call->conn;
403 :
404 : /*
405 : * TODO: a SASL bind with a different mechanism
406 : * should cancel an inprogress SASL bind.
407 : * (see RFC 4513)
408 : */
409 :
410 35888 : if (!conn->gensec) {
411 26511 : status = ldapsrv_setup_gensec(conn, req->creds.SASL.mechanism,
412 : &conn->gensec);
413 26511 : if (!NT_STATUS_IS_OK(status)) {
414 0 : DEBUG(1, ("Failed to start GENSEC server for [%s] code: %s\n",
415 : ldb_binary_encode_string(call, req->creds.SASL.mechanism),
416 : nt_errstr(status)));
417 0 : result = LDAP_OPERATIONS_ERROR;
418 0 : errstr = talloc_asprintf(reply, "SASL: Failed to start authentication system: %s",
419 : nt_errstr(status));
420 0 : goto do_reply;
421 : }
422 : }
423 :
424 35888 : if (req->creds.SASL.secblob) {
425 35564 : input = *req->creds.SASL.secblob;
426 : }
427 :
428 35888 : subreq = gensec_update_send(call, conn->connection->event.ctx,
429 : conn->gensec, input);
430 35888 : if (subreq == NULL) {
431 0 : return NT_STATUS_NO_MEMORY;
432 : }
433 35888 : tevent_req_set_callback(subreq, ldapsrv_BindSASL_done, call);
434 :
435 35888 : status = ldapsrv_bind_wait_setup(call, reply);
436 35888 : if (!NT_STATUS_IS_OK(status)) {
437 0 : TALLOC_FREE(subreq);
438 0 : return status;
439 : }
440 :
441 : /*
442 : * The rest will be async.
443 : */
444 35888 : return NT_STATUS_OK;
445 :
446 0 : do_reply:
447 0 : if (result != LDAP_SASL_BIND_IN_PROGRESS) {
448 : /*
449 : * We should destroy the gensec context
450 : * when we hit a fatal error.
451 : *
452 : * Note: conn->gensec is already cleared
453 : * for the LDAP_SUCCESS case.
454 : */
455 0 : talloc_unlink(conn, conn->gensec);
456 0 : conn->gensec = NULL;
457 : }
458 :
459 0 : resp->response.resultcode = result;
460 0 : resp->response.dn = NULL;
461 0 : resp->response.errormessage = errstr;
462 0 : resp->response.referral = NULL;
463 :
464 0 : ldapsrv_queue_reply(call, reply);
465 0 : return NT_STATUS_OK;
466 : }
467 :
468 35888 : static void ldapsrv_BindSASL_done(struct tevent_req *subreq)
469 : {
470 122 : struct ldapsrv_call *call =
471 35888 : tevent_req_callback_data(subreq,
472 : struct ldapsrv_call);
473 122 : struct ldapsrv_bind_wait_context *bind_wait =
474 35888 : talloc_get_type_abort(call->wait_private,
475 : struct ldapsrv_bind_wait_context);
476 35888 : struct ldap_BindRequest *req = &call->request->r.BindRequest;
477 35888 : struct ldapsrv_reply *reply = bind_wait->reply;
478 35888 : struct ldap_BindResponse *resp = &reply->msg->r.BindResponse;
479 35888 : struct ldapsrv_connection *conn = call->conn;
480 35888 : struct auth_session_info *session_info = NULL;
481 35888 : struct ldapsrv_sasl_postprocess_context *context = NULL;
482 122 : NTSTATUS status;
483 122 : int result;
484 35888 : const char *errstr = NULL;
485 35888 : char *ldb_errstring = NULL;
486 35888 : DATA_BLOB output = data_blob_null;
487 122 : NTTIME expire_time_nt;
488 :
489 35888 : status = gensec_update_recv(subreq, call, &output);
490 35888 : TALLOC_FREE(subreq);
491 :
492 35888 : if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
493 9478 : *resp->SASL.secblob = output;
494 9478 : result = LDAP_SASL_BIND_IN_PROGRESS;
495 9478 : errstr = NULL;
496 9478 : goto do_reply;
497 : }
498 :
499 26410 : if (!NT_STATUS_IS_OK(status)) {
500 215 : status = nt_status_squash(status);
501 215 : result = LDAP_INVALID_CREDENTIALS;
502 215 : errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_LOGON_DENIED,
503 : 0x0C0904DC, status);
504 215 : goto do_reply;
505 : }
506 :
507 26372 : if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
508 177 : gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
509 :
510 26018 : context = talloc_zero(call, struct ldapsrv_sasl_postprocess_context);
511 26018 : if (context == NULL) {
512 0 : ldapsrv_bind_wait_finished(call, NT_STATUS_NO_MEMORY);
513 0 : return;
514 : }
515 : }
516 :
517 26195 : if (context && conn->sockets.tls) {
518 2 : TALLOC_FREE(context);
519 2 : status = NT_STATUS_NOT_SUPPORTED;
520 2 : result = LDAP_UNWILLING_TO_PERFORM;
521 2 : errstr = talloc_asprintf(reply,
522 : "SASL:[%s]: Sign or Seal are not allowed if TLS is used",
523 : req->creds.SASL.mechanism);
524 2 : goto do_reply;
525 : }
526 :
527 26193 : if (context && conn->sockets.sasl) {
528 0 : TALLOC_FREE(context);
529 0 : status = NT_STATUS_NOT_SUPPORTED;
530 0 : result = LDAP_UNWILLING_TO_PERFORM;
531 0 : errstr = talloc_asprintf(reply,
532 : "SASL:[%s]: Sign or Seal are not allowed if SASL encryption has already been set up",
533 : req->creds.SASL.mechanism);
534 0 : goto do_reply;
535 : }
536 :
537 26193 : if (context == NULL) {
538 177 : switch (call->conn->require_strong_auth) {
539 8 : case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO:
540 52 : break;
541 47 : case LDAP_SERVER_REQUIRE_STRONG_AUTH_ALLOW_SASL_OVER_TLS:
542 47 : if (call->conn->sockets.active == call->conn->sockets.tls) {
543 44 : break;
544 : }
545 3 : status = NT_STATUS_NETWORK_ACCESS_DENIED;
546 3 : result = LDAP_STRONG_AUTH_REQUIRED;
547 3 : errstr = talloc_asprintf(reply,
548 : "SASL:[%s]: not allowed if TLS is used.",
549 : req->creds.SASL.mechanism);
550 125 : goto do_reply;
551 :
552 122 : case LDAP_SERVER_REQUIRE_STRONG_AUTH_YES:
553 122 : status = NT_STATUS_NETWORK_ACCESS_DENIED;
554 122 : result = LDAP_STRONG_AUTH_REQUIRED;
555 122 : errstr = talloc_asprintf(reply,
556 : "SASL:[%s]: Sign or Seal are required.",
557 : req->creds.SASL.mechanism);
558 122 : goto do_reply;
559 : }
560 : }
561 :
562 26068 : if (context != NULL) {
563 26016 : context->conn = conn;
564 26016 : status = gensec_create_tstream(context,
565 : context->conn->gensec,
566 : context->conn->sockets.raw,
567 : &context->sasl);
568 26016 : if (!NT_STATUS_IS_OK(status)) {
569 0 : result = LDAP_OPERATIONS_ERROR;
570 0 : errstr = talloc_asprintf(reply,
571 : "SASL:[%s]: Failed to setup SASL socket: %s",
572 : req->creds.SASL.mechanism, nt_errstr(status));
573 0 : goto do_reply;
574 : }
575 : }
576 :
577 26068 : status = gensec_session_info(conn->gensec, call, &session_info);
578 26068 : if (!NT_STATUS_IS_OK(status)) {
579 1 : result = LDAP_OPERATIONS_ERROR;
580 1 : errstr = talloc_asprintf(reply,
581 : "SASL:[%s]: Failed to get session info: %s",
582 : req->creds.SASL.mechanism, nt_errstr(status));
583 1 : goto do_reply;
584 : }
585 :
586 26067 : talloc_unlink(conn, conn->session_info);
587 26067 : conn->session_info = talloc_steal(conn, session_info);
588 :
589 : /* don't leak the old LDB */
590 26067 : talloc_unlink(conn, conn->ldb);
591 :
592 26067 : call->conn->authz_logged = true;
593 :
594 26067 : result = ldapsrv_backend_Init(call->conn, &ldb_errstring);
595 :
596 26067 : if (result != LDB_SUCCESS) {
597 : /* Only put the detailed error in DEBUG() */
598 0 : DBG_ERR("ldapsrv_backend_Init failed: %s: %s\n",
599 : ldb_errstring, ldb_strerror(result));
600 0 : errstr = talloc_strdup(reply,
601 : "SASL Bind: Failed to advise "
602 : "ldb new credentials");
603 0 : result = LDB_ERR_OPERATIONS_ERROR;
604 0 : goto do_reply;
605 : }
606 :
607 26067 : expire_time_nt = gensec_expire_time(conn->gensec);
608 26067 : if (expire_time_nt != GENSEC_EXPIRE_TIME_INFINITY) {
609 122 : struct timeval_buf buf;
610 :
611 17264 : nttime_to_timeval(&conn->limits.expire_time, expire_time_nt);
612 :
613 17264 : DBG_DEBUG("Setting connection expire_time to %s\n",
614 : timeval_str_buf(&conn->limits.expire_time,
615 : false,
616 : true,
617 : &buf));
618 : }
619 :
620 26067 : if (context != NULL) {
621 26015 : const void *ptr = NULL;
622 :
623 26015 : ptr = talloc_reparent(conn, context->sasl, conn->gensec);
624 26015 : if (ptr == NULL) {
625 0 : ldapsrv_bind_wait_finished(call, NT_STATUS_NO_MEMORY);
626 0 : return;
627 : }
628 :
629 26015 : call->postprocess_send = ldapsrv_sasl_postprocess_send;
630 26015 : call->postprocess_recv = ldapsrv_sasl_postprocess_recv;
631 26015 : call->postprocess_private = context;
632 : } else {
633 52 : talloc_unlink(conn, conn->gensec);
634 : }
635 26067 : conn->gensec = NULL;
636 :
637 26067 : *resp->SASL.secblob = output;
638 26067 : result = LDAP_SUCCESS;
639 26067 : errstr = NULL;
640 :
641 35766 : do_reply:
642 35888 : if (result != LDAP_SASL_BIND_IN_PROGRESS) {
643 : /*
644 : * We should destroy the gensec context
645 : * when we hit a fatal error.
646 : *
647 : * Note: conn->gensec is already cleared
648 : * for the LDAP_SUCCESS case.
649 : */
650 26410 : talloc_unlink(conn, conn->gensec);
651 26410 : conn->gensec = NULL;
652 : }
653 :
654 35888 : resp->response.resultcode = result;
655 35888 : resp->response.dn = NULL;
656 35888 : resp->response.errormessage = errstr;
657 35888 : resp->response.referral = NULL;
658 :
659 35888 : ldapsrv_queue_reply(call, reply);
660 35888 : ldapsrv_bind_wait_finished(call, NT_STATUS_OK);
661 : }
662 :
663 36359 : NTSTATUS ldapsrv_BindRequest(struct ldapsrv_call *call)
664 : {
665 36359 : struct ldap_BindRequest *req = &call->request->r.BindRequest;
666 122 : struct ldapsrv_reply *reply;
667 122 : struct ldap_BindResponse *resp;
668 :
669 36359 : if (call->conn->pending_calls != NULL) {
670 0 : reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
671 0 : if (!reply) {
672 0 : return NT_STATUS_NO_MEMORY;
673 : }
674 :
675 0 : resp = &reply->msg->r.BindResponse;
676 0 : resp->response.resultcode = LDAP_BUSY;
677 0 : resp->response.dn = NULL;
678 0 : resp->response.errormessage = talloc_asprintf(reply, "Pending requests on this LDAP session");
679 0 : resp->response.referral = NULL;
680 0 : resp->SASL.secblob = NULL;
681 :
682 0 : ldapsrv_queue_reply(call, reply);
683 0 : return NT_STATUS_OK;
684 : }
685 :
686 : /*
687 : * TODO: a simple bind should cancel an
688 : * inprogress SASL bind.
689 : * (see RFC 4513)
690 : */
691 36359 : switch (req->mechanism) {
692 471 : case LDAP_AUTH_MECH_SIMPLE:
693 471 : return ldapsrv_BindSimple(call);
694 35888 : case LDAP_AUTH_MECH_SASL:
695 35888 : return ldapsrv_BindSASL(call);
696 : }
697 :
698 0 : reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
699 0 : if (!reply) {
700 0 : return NT_STATUS_NO_MEMORY;
701 : }
702 :
703 0 : resp = &reply->msg->r.BindResponse;
704 0 : resp->response.resultcode = LDAP_AUTH_METHOD_NOT_SUPPORTED;
705 0 : resp->response.dn = NULL;
706 0 : resp->response.errormessage = talloc_asprintf(reply, "Bad AuthenticationChoice [%d]", req->mechanism);
707 0 : resp->response.referral = NULL;
708 0 : resp->SASL.secblob = NULL;
709 :
710 0 : ldapsrv_queue_reply(call, reply);
711 0 : return NT_STATUS_OK;
712 : }
713 :
714 : struct ldapsrv_unbind_wait_context {
715 : uint8_t dummy;
716 : };
717 :
718 : struct ldapsrv_unbind_wait_state {
719 : uint8_t dummy;
720 : };
721 :
722 21 : static struct tevent_req *ldapsrv_unbind_wait_send(TALLOC_CTX *mem_ctx,
723 : struct tevent_context *ev,
724 : void *private_data)
725 : {
726 0 : struct ldapsrv_unbind_wait_context *unbind_wait =
727 21 : talloc_get_type_abort(private_data,
728 : struct ldapsrv_unbind_wait_context);
729 0 : struct tevent_req *req;
730 0 : struct ldapsrv_unbind_wait_state *state;
731 :
732 21 : req = tevent_req_create(mem_ctx, &state,
733 : struct ldapsrv_unbind_wait_state);
734 21 : if (req == NULL) {
735 0 : return NULL;
736 : }
737 :
738 0 : (void)unbind_wait;
739 :
740 21 : tevent_req_nterror(req, NT_STATUS_LOCAL_DISCONNECT);
741 21 : return tevent_req_post(req, ev);
742 : }
743 :
744 21 : static NTSTATUS ldapsrv_unbind_wait_recv(struct tevent_req *req)
745 : {
746 21 : return tevent_req_simple_recv_ntstatus(req);
747 : }
748 :
749 21 : static NTSTATUS ldapsrv_unbind_wait_setup(struct ldapsrv_call *call)
750 : {
751 21 : struct ldapsrv_unbind_wait_context *unbind_wait = NULL;
752 :
753 21 : if (call->wait_private != NULL) {
754 0 : return NT_STATUS_INTERNAL_ERROR;
755 : }
756 :
757 21 : unbind_wait = talloc_zero(call, struct ldapsrv_unbind_wait_context);
758 21 : if (unbind_wait == NULL) {
759 0 : return NT_STATUS_NO_MEMORY;
760 : }
761 :
762 21 : call->wait_private = unbind_wait;
763 21 : call->wait_send = ldapsrv_unbind_wait_send;
764 21 : call->wait_recv = ldapsrv_unbind_wait_recv;
765 21 : return NT_STATUS_OK;
766 : }
767 :
768 21 : NTSTATUS ldapsrv_UnbindRequest(struct ldapsrv_call *call)
769 : {
770 21 : struct ldapsrv_call *c = NULL;
771 21 : struct ldapsrv_call *n = NULL;
772 :
773 21 : DEBUG(10, ("UnbindRequest\n"));
774 :
775 21 : for (c = call->conn->pending_calls; c != NULL; c = n) {
776 0 : n = c->next;
777 :
778 0 : DLIST_REMOVE(call->conn->pending_calls, c);
779 0 : TALLOC_FREE(c);
780 : }
781 :
782 21 : return ldapsrv_unbind_wait_setup(call);
783 : }
|