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