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 264 : static char *ldapsrv_bind_error_msg(TALLOC_CTX *mem_ctx,
35 : HRESULT hresult,
36 : uint32_t DSID,
37 : NTSTATUS status)
38 : {
39 : WERROR werr;
40 264 : char *msg = NULL;
41 :
42 264 : status = nt_status_squash(status);
43 264 : 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 264 : msg = talloc_asprintf(mem_ctx, "%08X: LdapErr: DSID-%08X, comment: "
56 : "AcceptSecurityContext error, data %x, v1db1",
57 264 : (unsigned)HRES_ERROR_V(hresult),
58 : (unsigned)DSID,
59 264 : (unsigned)W_ERROR_V(werr));
60 :
61 264 : 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 26445 : static struct tevent_req *ldapsrv_bind_wait_send(TALLOC_CTX *mem_ctx,
76 : struct tevent_context *ev,
77 : void *private_data)
78 : {
79 19680 : struct ldapsrv_bind_wait_context *bind_wait =
80 6765 : talloc_get_type_abort(private_data,
81 : struct ldapsrv_bind_wait_context);
82 : struct tevent_req *req;
83 : struct ldapsrv_bind_wait_state *state;
84 :
85 26445 : req = tevent_req_create(mem_ctx, &state,
86 : struct ldapsrv_bind_wait_state);
87 26445 : if (req == NULL) {
88 0 : return NULL;
89 : }
90 26445 : bind_wait->req = req;
91 :
92 26445 : tevent_req_defer_callback(req, ev);
93 :
94 26445 : if (!bind_wait->done) {
95 26445 : 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 26445 : static NTSTATUS ldapsrv_bind_wait_recv(struct tevent_req *req)
107 : {
108 26445 : return tevent_req_simple_recv_ntstatus(req);
109 : }
110 :
111 26445 : static NTSTATUS ldapsrv_bind_wait_setup(struct ldapsrv_call *call,
112 : struct ldapsrv_reply *reply)
113 : {
114 26445 : struct ldapsrv_bind_wait_context *bind_wait = NULL;
115 :
116 26445 : if (call->wait_private != NULL) {
117 0 : return NT_STATUS_INTERNAL_ERROR;
118 : }
119 :
120 26445 : bind_wait = talloc_zero(call, struct ldapsrv_bind_wait_context);
121 26445 : if (bind_wait == NULL) {
122 0 : return NT_STATUS_NO_MEMORY;
123 : }
124 26445 : bind_wait->reply = reply;
125 :
126 26445 : call->wait_private = bind_wait;
127 26445 : call->wait_send = ldapsrv_bind_wait_send;
128 26445 : call->wait_recv = ldapsrv_bind_wait_recv;
129 26445 : return NT_STATUS_OK;
130 : }
131 :
132 26445 : static void ldapsrv_bind_wait_finished(struct ldapsrv_call *call,
133 : NTSTATUS status)
134 : {
135 19680 : struct ldapsrv_bind_wait_context *bind_wait =
136 26445 : talloc_get_type_abort(call->wait_private,
137 : struct ldapsrv_bind_wait_context);
138 :
139 26445 : bind_wait->done = true;
140 26445 : bind_wait->status = status;
141 :
142 26445 : if (bind_wait->req == NULL) {
143 0 : return;
144 : }
145 :
146 26445 : if (tevent_req_nterror(bind_wait->req, status)) {
147 0 : return;
148 : }
149 :
150 26445 : tevent_req_done(bind_wait->req);
151 : }
152 :
153 : static void ldapsrv_BindSimple_done(struct tevent_req *subreq);
154 :
155 379 : static NTSTATUS ldapsrv_BindSimple(struct ldapsrv_call *call)
156 : {
157 379 : struct ldap_BindRequest *req = &call->request->r.BindRequest;
158 379 : struct ldapsrv_reply *reply = NULL;
159 379 : struct ldap_BindResponse *resp = NULL;
160 : int result;
161 379 : const char *errstr = NULL;
162 : NTSTATUS status;
163 379 : bool using_tls = call->conn->sockets.active == call->conn->sockets.tls;
164 379 : struct tevent_req *subreq = NULL;
165 :
166 379 : DEBUG(10, ("BindSimple dn: %s\n",req->dn));
167 :
168 379 : reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
169 379 : if (!reply) {
170 0 : return NT_STATUS_NO_MEMORY;
171 : }
172 :
173 716 : if (req->dn != NULL &&
174 712 : strlen(req->dn) != 0 &&
175 676 : call->conn->require_strong_auth > LDAP_SERVER_REQUIRE_STRONG_AUTH_NO &&
176 311 : !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 2039 : subreq = authenticate_ldap_simple_bind_send(call,
186 374 : call->conn->connection->event.ctx,
187 374 : call->conn->connection->msg_ctx,
188 374 : call->conn->lp_ctx,
189 374 : call->conn->connection->remote_address,
190 374 : call->conn->connection->local_address,
191 : using_tls,
192 : req->dn,
193 : req->creds.password);
194 374 : if (subreq == NULL) {
195 0 : return NT_STATUS_NO_MEMORY;
196 : }
197 374 : tevent_req_set_callback(subreq, ldapsrv_BindSimple_done, call);
198 :
199 374 : status = ldapsrv_bind_wait_setup(call, reply);
200 374 : 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 374 : 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 374 : static void ldapsrv_BindSimple_done(struct tevent_req *subreq)
223 : {
224 333 : struct ldapsrv_call *call =
225 374 : tevent_req_callback_data(subreq,
226 : struct ldapsrv_call);
227 333 : struct ldapsrv_bind_wait_context *bind_wait =
228 374 : talloc_get_type_abort(call->wait_private,
229 : struct ldapsrv_bind_wait_context);
230 374 : struct ldapsrv_reply *reply = bind_wait->reply;
231 374 : struct auth_session_info *session_info = NULL;
232 : NTSTATUS status;
233 374 : struct ldap_BindResponse *resp = NULL;
234 : int result;
235 374 : const char *errstr = NULL;
236 :
237 374 : status = authenticate_ldap_simple_bind_recv(subreq,
238 : call,
239 : &session_info);
240 374 : if (NT_STATUS_IS_OK(status)) {
241 283 : char *ldb_errstring = NULL;
242 283 : result = LDAP_SUCCESS;
243 283 : errstr = NULL;
244 :
245 283 : talloc_unlink(call->conn, call->conn->session_info);
246 283 : call->conn->session_info = talloc_steal(call->conn, session_info);
247 :
248 283 : call->conn->authz_logged = true;
249 :
250 : /* don't leak the old LDB */
251 283 : talloc_unlink(call->conn, call->conn->ldb);
252 :
253 283 : result = ldapsrv_backend_Init(call->conn, &ldb_errstring);
254 :
255 283 : if (result != LDB_SUCCESS) {
256 : /* Only put the detailed error in DEBUG() */
257 0 : DBG_ERR("ldapsrv_backend_Init failed: %s: %s",
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 91 : status = nt_status_squash(status);
266 :
267 91 : result = LDAP_INVALID_CREDENTIALS;
268 91 : errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_INVALID_TOKEN,
269 : 0x0C0903A9, status);
270 : }
271 :
272 374 : resp = &reply->msg->r.BindResponse;
273 374 : resp->response.resultcode = result;
274 374 : resp->response.errormessage = errstr;
275 374 : resp->response.dn = NULL;
276 374 : resp->response.referral = NULL;
277 374 : resp->SASL.secblob = NULL;
278 :
279 374 : ldapsrv_queue_reply(call, reply);
280 374 : ldapsrv_bind_wait_finished(call, NT_STATUS_OK);
281 374 : }
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 18860 : static struct tevent_req *ldapsrv_sasl_postprocess_send(TALLOC_CTX *mem_ctx,
293 : struct tevent_context *ev,
294 : void *private_data)
295 : {
296 14304 : struct ldapsrv_sasl_postprocess_context *context =
297 4556 : talloc_get_type_abort(private_data,
298 : struct ldapsrv_sasl_postprocess_context);
299 : struct tevent_req *req;
300 : struct ldapsrv_sasl_postprocess_state *state;
301 :
302 18860 : req = tevent_req_create(mem_ctx, &state,
303 : struct ldapsrv_sasl_postprocess_state);
304 18860 : if (req == NULL) {
305 0 : return NULL;
306 : }
307 :
308 18860 : TALLOC_FREE(context->conn->sockets.sasl);
309 18860 : context->conn->sockets.sasl = talloc_move(context->conn, &context->sasl);
310 18860 : context->conn->sockets.active = context->conn->sockets.sasl;
311 :
312 18860 : tevent_req_done(req);
313 18860 : return tevent_req_post(req, ev);
314 : }
315 :
316 18860 : static NTSTATUS ldapsrv_sasl_postprocess_recv(struct tevent_req *req)
317 : {
318 18860 : return tevent_req_simple_recv_ntstatus(req);
319 : }
320 :
321 19216 : static NTSTATUS ldapsrv_setup_gensec(struct ldapsrv_connection *conn,
322 : const char *sasl_mech,
323 : struct gensec_security **_gensec_security)
324 : {
325 : NTSTATUS status;
326 :
327 : struct gensec_security *gensec_security;
328 :
329 48510 : status = samba_server_gensec_start(conn,
330 19216 : conn->connection->event.ctx,
331 19216 : conn->connection->msg_ctx,
332 : conn->lp_ctx,
333 : conn->server_credentials,
334 : "ldap",
335 : &gensec_security);
336 19216 : if (!NT_STATUS_IS_OK(status)) {
337 0 : return status;
338 : }
339 :
340 19216 : status = gensec_set_target_service_description(gensec_security,
341 : "LDAP");
342 19216 : if (!NT_STATUS_IS_OK(status)) {
343 0 : return status;
344 : }
345 :
346 19216 : status = gensec_set_remote_address(gensec_security,
347 19216 : conn->connection->remote_address);
348 19216 : if (!NT_STATUS_IS_OK(status)) {
349 0 : return status;
350 : }
351 :
352 19216 : status = gensec_set_local_address(gensec_security,
353 19216 : conn->connection->local_address);
354 19216 : if (!NT_STATUS_IS_OK(status)) {
355 0 : return status;
356 : }
357 :
358 19216 : gensec_want_feature(gensec_security, GENSEC_FEATURE_ASYNC_REPLIES);
359 19216 : gensec_want_feature(gensec_security, GENSEC_FEATURE_LDAP_STYLE);
360 :
361 19216 : if (conn->sockets.active == conn->sockets.tls) {
362 50 : gensec_want_feature(gensec_security, GENSEC_FEATURE_LDAPS_TRANSPORT);
363 : }
364 :
365 19216 : status = gensec_start_mech_by_sasl_name(gensec_security, sasl_mech);
366 :
367 19216 : if (!NT_STATUS_IS_OK(status)) {
368 0 : return status;
369 : }
370 :
371 19216 : *_gensec_security = gensec_security;
372 19216 : return status;
373 : }
374 :
375 : static void ldapsrv_BindSASL_done(struct tevent_req *subreq);
376 :
377 26071 : static NTSTATUS ldapsrv_BindSASL(struct ldapsrv_call *call)
378 : {
379 26071 : struct ldap_BindRequest *req = &call->request->r.BindRequest;
380 : struct ldapsrv_reply *reply;
381 : struct ldap_BindResponse *resp;
382 : struct ldapsrv_connection *conn;
383 26071 : int result = 0;
384 26071 : const char *errstr=NULL;
385 26071 : NTSTATUS status = NT_STATUS_OK;
386 26071 : DATA_BLOB input = data_blob_null;
387 26071 : struct tevent_req *subreq = NULL;
388 :
389 26071 : DEBUG(10, ("BindSASL dn: %s\n",req->dn));
390 :
391 26071 : reply = ldapsrv_init_reply(call, LDAP_TAG_BindResponse);
392 26071 : if (!reply) {
393 0 : return NT_STATUS_NO_MEMORY;
394 : }
395 26071 : resp = &reply->msg->r.BindResponse;
396 : /* Windows 2000 mmc doesn't like secblob == NULL and reports a decoding error */
397 26071 : resp->SASL.secblob = talloc_zero(reply, DATA_BLOB);
398 26071 : if (resp->SASL.secblob == NULL) {
399 0 : return NT_STATUS_NO_MEMORY;
400 : }
401 :
402 26071 : 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 26071 : if (!conn->gensec) {
411 19216 : status = ldapsrv_setup_gensec(conn, req->creds.SASL.mechanism,
412 : &conn->gensec);
413 19216 : 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 26071 : if (req->creds.SASL.secblob) {
425 25977 : input = *req->creds.SASL.secblob;
426 : }
427 :
428 26071 : subreq = gensec_update_send(call, conn->connection->event.ctx,
429 : conn->gensec, input);
430 26071 : if (subreq == NULL) {
431 0 : return NT_STATUS_NO_MEMORY;
432 : }
433 26071 : tevent_req_set_callback(subreq, ldapsrv_BindSASL_done, call);
434 :
435 26071 : status = ldapsrv_bind_wait_setup(call, reply);
436 26071 : 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 26071 : 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 26071 : static void ldapsrv_BindSASL_done(struct tevent_req *subreq)
469 : {
470 19347 : struct ldapsrv_call *call =
471 26071 : tevent_req_callback_data(subreq,
472 : struct ldapsrv_call);
473 19347 : struct ldapsrv_bind_wait_context *bind_wait =
474 26071 : talloc_get_type_abort(call->wait_private,
475 : struct ldapsrv_bind_wait_context);
476 26071 : struct ldap_BindRequest *req = &call->request->r.BindRequest;
477 26071 : struct ldapsrv_reply *reply = bind_wait->reply;
478 26071 : struct ldap_BindResponse *resp = &reply->msg->r.BindResponse;
479 26071 : struct ldapsrv_connection *conn = call->conn;
480 26071 : struct auth_session_info *session_info = NULL;
481 26071 : struct ldapsrv_sasl_postprocess_context *context = NULL;
482 : NTSTATUS status;
483 : int result;
484 26071 : const char *errstr = NULL;
485 26071 : char *ldb_errstring = NULL;
486 26071 : DATA_BLOB output = data_blob_null;
487 : NTTIME expire_time_nt;
488 :
489 26071 : status = gensec_update_recv(subreq, call, &output);
490 26071 : TALLOC_FREE(subreq);
491 :
492 26071 : if (NT_STATUS_EQUAL(NT_STATUS_MORE_PROCESSING_REQUIRED, status)) {
493 6858 : *resp->SASL.secblob = output;
494 6858 : result = LDAP_SASL_BIND_IN_PROGRESS;
495 6858 : errstr = NULL;
496 6858 : goto do_reply;
497 : }
498 :
499 19213 : if (!NT_STATUS_IS_OK(status)) {
500 173 : status = nt_status_squash(status);
501 173 : result = LDAP_INVALID_CREDENTIALS;
502 173 : errstr = ldapsrv_bind_error_msg(reply, HRES_SEC_E_LOGON_DENIED,
503 : 0x0C0904DC, status);
504 173 : goto do_reply;
505 : }
506 :
507 19217 : if (gensec_have_feature(conn->gensec, GENSEC_FEATURE_SIGN) ||
508 177 : gensec_have_feature(conn->gensec, GENSEC_FEATURE_SEAL)) {
509 :
510 18863 : context = talloc_zero(call, struct ldapsrv_sasl_postprocess_context);
511 18863 : if (context == NULL) {
512 0 : ldapsrv_bind_wait_finished(call, NT_STATUS_NO_MEMORY);
513 0 : return;
514 : }
515 : }
516 :
517 19040 : 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 19038 : 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 19038 : if (context == NULL) {
538 177 : switch (call->conn->require_strong_auth) {
539 8 : case LDAP_SERVER_REQUIRE_STRONG_AUTH_NO:
540 8 : 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 7 : 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 18913 : if (context != NULL) {
563 18861 : context->conn = conn;
564 18861 : status = gensec_create_tstream(context,
565 : context->conn->gensec,
566 : context->conn->sockets.raw,
567 : &context->sasl);
568 18861 : 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 18913 : status = gensec_session_info(conn->gensec, call, &session_info);
578 18913 : 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 18912 : talloc_unlink(conn, conn->session_info);
587 18912 : conn->session_info = talloc_steal(conn, session_info);
588 :
589 : /* don't leak the old LDB */
590 18912 : talloc_unlink(conn, conn->ldb);
591 :
592 18912 : call->conn->authz_logged = true;
593 :
594 18912 : result = ldapsrv_backend_Init(call->conn, &ldb_errstring);
595 :
596 18912 : if (result != LDB_SUCCESS) {
597 : /* Only put the detailed error in DEBUG() */
598 0 : DBG_ERR("ldapsrv_backend_Init failed: %s: %s",
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 18912 : expire_time_nt = gensec_expire_time(conn->gensec);
608 18912 : if (expire_time_nt != GENSEC_EXPIRE_TIME_INFINITY) {
609 : struct timeval_buf buf;
610 :
611 12361 : nttime_to_timeval(&conn->limits.expire_time, expire_time_nt);
612 :
613 12361 : 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 18912 : if (context != NULL) {
621 18860 : const void *ptr = NULL;
622 :
623 18860 : ptr = talloc_reparent(conn, context->sasl, conn->gensec);
624 18860 : if (ptr == NULL) {
625 0 : ldapsrv_bind_wait_finished(call, NT_STATUS_NO_MEMORY);
626 0 : return;
627 : }
628 :
629 18860 : call->postprocess_send = ldapsrv_sasl_postprocess_send;
630 18860 : call->postprocess_recv = ldapsrv_sasl_postprocess_recv;
631 18860 : call->postprocess_private = context;
632 : } else {
633 52 : talloc_unlink(conn, conn->gensec);
634 : }
635 18912 : conn->gensec = NULL;
636 :
637 18912 : *resp->SASL.secblob = output;
638 18912 : result = LDAP_SUCCESS;
639 18912 : errstr = NULL;
640 :
641 26071 : do_reply:
642 26071 : 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 19213 : talloc_unlink(conn, conn->gensec);
651 19213 : conn->gensec = NULL;
652 : }
653 :
654 26071 : resp->response.resultcode = result;
655 26071 : resp->response.dn = NULL;
656 26071 : resp->response.errormessage = errstr;
657 26071 : resp->response.referral = NULL;
658 :
659 26071 : ldapsrv_queue_reply(call, reply);
660 26071 : ldapsrv_bind_wait_finished(call, NT_STATUS_OK);
661 : }
662 :
663 26450 : NTSTATUS ldapsrv_BindRequest(struct ldapsrv_call *call)
664 : {
665 26450 : struct ldap_BindRequest *req = &call->request->r.BindRequest;
666 : struct ldapsrv_reply *reply;
667 : struct ldap_BindResponse *resp;
668 :
669 26450 : 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 26450 : switch (req->mechanism) {
692 379 : case LDAP_AUTH_MECH_SIMPLE:
693 379 : return ldapsrv_BindSimple(call);
694 26071 : case LDAP_AUTH_MECH_SASL:
695 26071 : 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 90 : static struct tevent_req *ldapsrv_unbind_wait_send(TALLOC_CTX *mem_ctx,
723 : struct tevent_context *ev,
724 : void *private_data)
725 : {
726 51 : struct ldapsrv_unbind_wait_context *unbind_wait =
727 39 : talloc_get_type_abort(private_data,
728 : struct ldapsrv_unbind_wait_context);
729 : struct tevent_req *req;
730 : struct ldapsrv_unbind_wait_state *state;
731 :
732 90 : req = tevent_req_create(mem_ctx, &state,
733 : struct ldapsrv_unbind_wait_state);
734 90 : if (req == NULL) {
735 0 : return NULL;
736 : }
737 :
738 : (void)unbind_wait;
739 :
740 90 : tevent_req_nterror(req, NT_STATUS_LOCAL_DISCONNECT);
741 90 : return tevent_req_post(req, ev);
742 : }
743 :
744 90 : static NTSTATUS ldapsrv_unbind_wait_recv(struct tevent_req *req)
745 : {
746 90 : return tevent_req_simple_recv_ntstatus(req);
747 : }
748 :
749 90 : static NTSTATUS ldapsrv_unbind_wait_setup(struct ldapsrv_call *call)
750 : {
751 90 : struct ldapsrv_unbind_wait_context *unbind_wait = NULL;
752 :
753 90 : if (call->wait_private != NULL) {
754 0 : return NT_STATUS_INTERNAL_ERROR;
755 : }
756 :
757 90 : unbind_wait = talloc_zero(call, struct ldapsrv_unbind_wait_context);
758 90 : if (unbind_wait == NULL) {
759 0 : return NT_STATUS_NO_MEMORY;
760 : }
761 :
762 90 : call->wait_private = unbind_wait;
763 90 : call->wait_send = ldapsrv_unbind_wait_send;
764 90 : call->wait_recv = ldapsrv_unbind_wait_recv;
765 90 : return NT_STATUS_OK;
766 : }
767 :
768 90 : NTSTATUS ldapsrv_UnbindRequest(struct ldapsrv_call *call)
769 : {
770 90 : struct ldapsrv_call *c = NULL;
771 90 : struct ldapsrv_call *n = NULL;
772 :
773 90 : DEBUG(10, ("UnbindRequest\n"));
774 :
775 90 : 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 90 : return ldapsrv_unbind_wait_setup(call);
783 : }
|