2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Tridgell 2005
7 Copyright (C) Volker Lendecke 2004
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "libcli/ldap/libcli_ldap.h"
26 #include "libcli/ldap/ldap_proto.h"
27 #include "libcli/ldap/ldap_client.h"
28 #include "lib/tls/tls.h"
29 #include "auth/gensec/gensec.h"
30 #include "source4/auth/gensec/gensec_tstream.h"
31 #include "auth/credentials/credentials.h"
32 #include "lib/stream/packet.h"
33 #include "param/param.h"
34 #include "param/loadparm.h"
35 #include "librpc/gen_ndr/ads.h"
37 struct ldap_simple_creds
{
42 _PUBLIC_ NTSTATUS
ldap_rebind(struct ldap_connection
*conn
)
45 struct ldap_simple_creds
*creds
;
47 switch (conn
->bind
.type
) {
49 status
= ldap_bind_sasl(conn
, (struct cli_credentials
*)conn
->bind
.creds
,
53 case LDAP_BIND_SIMPLE
:
54 creds
= (struct ldap_simple_creds
*)conn
->bind
.creds
;
57 return NT_STATUS_UNSUCCESSFUL
;
60 status
= ldap_bind_simple(conn
, creds
->dn
, creds
->pw
);
64 return NT_STATUS_UNSUCCESSFUL
;
71 static struct ldap_message
*new_ldap_simple_bind_msg(struct ldap_connection
*conn
,
72 const char *dn
, const char *pw
)
74 struct ldap_message
*res
;
76 res
= new_ldap_message(conn
);
81 res
->type
= LDAP_TAG_BindRequest
;
82 res
->r
.BindRequest
.version
= 3;
83 res
->r
.BindRequest
.dn
= talloc_strdup(res
, dn
);
84 res
->r
.BindRequest
.mechanism
= LDAP_AUTH_MECH_SIMPLE
;
85 res
->r
.BindRequest
.creds
.password
= talloc_strdup(res
, pw
);
93 perform a simple username/password bind
95 _PUBLIC_ NTSTATUS
ldap_bind_simple(struct ldap_connection
*conn
,
96 const char *userdn
, const char *password
)
98 struct ldap_request
*req
;
99 struct ldap_message
*msg
;
104 return NT_STATUS_INVALID_CONNECTION
;
120 if (conn
->simple_pw
) {
121 pw
= conn
->simple_pw
;
127 msg
= new_ldap_simple_bind_msg(conn
, dn
, pw
);
128 NT_STATUS_HAVE_NO_MEMORY(msg
);
130 /* send the request */
131 req
= ldap_request_send(conn
, msg
);
133 NT_STATUS_HAVE_NO_MEMORY(req
);
135 /* wait for replies */
136 status
= ldap_request_wait(req
);
137 if (!NT_STATUS_IS_OK(status
)) {
142 /* check its a valid reply */
143 msg
= req
->replies
[0];
144 if (msg
->type
!= LDAP_TAG_BindResponse
) {
146 return NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
149 status
= ldap_check_response(conn
, &msg
->r
.BindResponse
.response
);
153 if (NT_STATUS_IS_OK(status
)) {
154 struct ldap_simple_creds
*creds
= talloc(conn
, struct ldap_simple_creds
);
156 return NT_STATUS_NO_MEMORY
;
158 creds
->dn
= talloc_strdup(creds
, dn
);
159 creds
->pw
= talloc_strdup(creds
, pw
);
160 if (creds
->dn
== NULL
|| creds
->pw
== NULL
) {
161 return NT_STATUS_NO_MEMORY
;
163 conn
->bind
.type
= LDAP_BIND_SIMPLE
;
164 conn
->bind
.creds
= creds
;
171 static struct ldap_message
*new_ldap_sasl_bind_msg(struct ldap_connection
*conn
,
172 const char *sasl_mechanism
,
175 struct ldap_message
*res
;
177 res
= new_ldap_message(conn
);
182 res
->type
= LDAP_TAG_BindRequest
;
183 res
->r
.BindRequest
.version
= 3;
184 res
->r
.BindRequest
.dn
= "";
185 res
->r
.BindRequest
.mechanism
= LDAP_AUTH_MECH_SASL
;
186 res
->r
.BindRequest
.creds
.SASL
.mechanism
= talloc_strdup(res
, sasl_mechanism
);
188 res
->r
.BindRequest
.creds
.SASL
.secblob
= talloc(res
, DATA_BLOB
);
189 if (!res
->r
.BindRequest
.creds
.SASL
.secblob
) {
193 *res
->r
.BindRequest
.creds
.SASL
.secblob
= *secblob
;
195 res
->r
.BindRequest
.creds
.SASL
.secblob
= NULL
;
197 res
->controls
= NULL
;
204 perform a sasl bind using the given credentials
206 _PUBLIC_ NTSTATUS
ldap_bind_sasl(struct ldap_connection
*conn
,
207 struct cli_credentials
*creds
,
208 struct loadparm_context
*lp_ctx
)
210 const char *sasl_mech
= "GSS-SPNEGO";
212 TALLOC_CTX
*tmp_ctx
= NULL
;
213 DATA_BLOB input
= data_blob(NULL
, 0);
214 DATA_BLOB output
= data_blob(NULL
, 0);
217 uint32_t old_gensec_features
;
218 unsigned int logon_retries
= 0;
220 const DATA_BLOB
*tls_cb
= NULL
;
221 bool use_channel_bound
= lpcfg_parm_bool(lp_ctx
,
226 const char *forced_channel_binding
= lpcfg_parm_string(lp_ctx
,
229 "forced_channel_binding");
230 DATA_BLOB forced_cb
= data_blob_string_const(forced_channel_binding
);
232 if (conn
->sockets
.active
== NULL
) {
233 status
= NT_STATUS_CONNECTION_DISCONNECTED
;
237 queue_length
= tevent_queue_length(conn
->sockets
.send_queue
);
238 if (queue_length
!= 0) {
239 status
= NT_STATUS_INVALID_PARAMETER_MIX
;
240 DEBUG(1, ("SASL bind triggered with non empty send_queue[%zu]: %s\n",
241 queue_length
, nt_errstr(status
)));
245 if (conn
->pending
!= NULL
) {
246 status
= NT_STATUS_INVALID_PARAMETER_MIX
;
247 DEBUG(1, ("SASL bind triggered with pending requests: %s\n",
252 tmp_ctx
= talloc_new(conn
);
253 if (tmp_ctx
== NULL
) {
254 status
= NT_STATUS_NO_MEMORY
;
260 if (conn
->sockets
.active
== conn
->sockets
.tls
) {
262 * allow this for testing the old code:
263 * ldap_testing:no_tls_channel_bindings = no
265 bool use_tls_cb
= lpcfg_parm_bool(lp_ctx
,
268 "tls_channel_bindings",
272 * require Kerberos SIGN/SEAL only if we don't use SSL
273 * Windows seem not to like double encryption
278 tls_cb
= tstream_tls_channel_bindings(conn
->sockets
.tls
);
280 } else if (cli_credentials_is_anonymous(creds
)) {
282 * anonymous isn't protected
286 wrap_flags
= lpcfg_client_ldap_sasl_wrapping(lp_ctx
);
289 if (forced_cb
.length
!= 0) {
295 we loop back here on a logon failure, and re-create the
296 gensec session. The logon_retries counter ensures we don't
299 data_blob_free(&input
);
300 TALLOC_FREE(conn
->gensec
);
302 status
= gensec_client_start(conn
, &conn
->gensec
,
303 lpcfg_gensec_settings(conn
, lp_ctx
));
304 if (!NT_STATUS_IS_OK(status
)) {
305 DEBUG(0, ("Failed to start GENSEC engine (%s)\n", nt_errstr(status
)));
309 old_gensec_features
= cli_credentials_get_gensec_features(creds
);
310 if (wrap_flags
== 0) {
311 cli_credentials_set_gensec_features(creds
,
312 old_gensec_features
& ~(GENSEC_FEATURE_SIGN
|GENSEC_FEATURE_SEAL
),
316 /* this call also sets the gensec_want_features */
317 status
= gensec_set_credentials(conn
->gensec
, creds
);
318 if (!NT_STATUS_IS_OK(status
)) {
319 DEBUG(1, ("Failed to set GENSEC creds: %s\n",
324 /* reset the original gensec_features (on the credentials
325 * context, so we don't tattoo it ) */
326 cli_credentials_set_gensec_features(creds
,
330 if (wrap_flags
& ADS_AUTH_SASL_SEAL
) {
331 gensec_want_feature(conn
->gensec
, GENSEC_FEATURE_SIGN
);
332 gensec_want_feature(conn
->gensec
, GENSEC_FEATURE_SEAL
);
334 if (wrap_flags
& ADS_AUTH_SASL_SIGN
) {
335 gensec_want_feature(conn
->gensec
, GENSEC_FEATURE_SIGN
);
338 if (!use_channel_bound
) {
339 gensec_want_feature(conn
->gensec
, GENSEC_FEATURE_CB_OPTIONAL
);
343 * This is an indication for the NTLMSSP backend to
344 * also encrypt when only GENSEC_FEATURE_SIGN is requested
345 * in gensec_[un]wrap().
347 gensec_want_feature(conn
->gensec
, GENSEC_FEATURE_LDAP_STYLE
);
350 status
= gensec_set_target_hostname(conn
->gensec
, conn
->host
);
351 if (!NT_STATUS_IS_OK(status
)) {
352 DEBUG(1, ("Failed to set GENSEC target hostname: %s\n",
358 status
= gensec_set_target_service(conn
->gensec
, "ldap");
359 if (!NT_STATUS_IS_OK(status
)) {
360 DEBUG(1, ("Failed to set GENSEC target service: %s\n",
365 if (tls_cb
!= NULL
) {
366 uint32_t initiator_addrtype
= 0;
367 const DATA_BLOB
*initiator_address
= NULL
;
368 uint32_t acceptor_addrtype
= 0;
369 const DATA_BLOB
*acceptor_address
= NULL
;
370 const DATA_BLOB
*application_data
= tls_cb
;
372 status
= gensec_set_channel_bindings(conn
->gensec
,
378 if (!NT_STATUS_IS_OK(status
)) {
379 DBG_WARNING("Failed to set GENSEC channel bindings: %s\n",
385 status
= gensec_start_mech_by_sasl_name(conn
->gensec
, sasl_mech
);
386 if (!NT_STATUS_IS_OK(status
)) {
387 DBG_WARNING("gensec_start_mech_by_sasl_name(%s): %s\n",
388 sasl_mech
, nt_errstr(status
));
393 NTSTATUS gensec_status
;
394 struct ldap_message
*response
;
395 struct ldap_message
*msg
;
396 struct ldap_request
*req
;
397 int result
= LDAP_OTHER
;
399 status
= gensec_update(conn
->gensec
, tmp_ctx
,
402 /* The status value here, from GENSEC is vital to the security
403 * of the system. Even if the other end accepts, if GENSEC
404 * claims 'MORE_PROCESSING_REQUIRED' then you must keep
405 * feeding it blobs, or else the remote host/attacker might
406 * avoid mutual authentication requirements.
408 * Likewise, you must not feed GENSEC too much (after the OK),
409 * it doesn't like that either.
411 * For SASL/EXTERNAL, there is no data to send, but we still
412 * must send the actual Bind request the first time around.
413 * Otherwise, a result of NT_STATUS_OK with 0 output means the
414 * end of a multi-step authentication, and no message must be
418 gensec_status
= status
;
420 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
) &&
421 !NT_STATUS_IS_OK(status
)) {
424 if (NT_STATUS_IS_OK(status
) && output
.length
== 0) {
430 msg
= new_ldap_sasl_bind_msg(tmp_ctx
,
432 output
.data
!= NULL
? &output
: NULL
);
434 status
= NT_STATUS_NO_MEMORY
;
438 req
= ldap_request_send(conn
, msg
);
440 status
= NT_STATUS_NO_MEMORY
;
443 talloc_reparent(conn
, tmp_ctx
, req
);
445 status
= ldap_result_n(req
, 0, &response
);
446 if (!NT_STATUS_IS_OK(status
)) {
450 if (response
->type
!= LDAP_TAG_BindResponse
) {
451 status
= NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
455 result
= response
->r
.BindResponse
.response
.resultcode
;
457 if (result
== LDAP_STRONG_AUTH_REQUIRED
) {
458 if (wrap_flags
== 0) {
459 wrap_flags
= ADS_AUTH_SASL_SIGN
;
460 goto try_logon_again
;
464 if (result
== LDAP_INVALID_CREDENTIALS
) {
466 try a second time on invalid credentials, to
467 give the user a chance to re-enter the
468 password and to handle the case where our
469 kerberos ticket is invalid as the server
472 const char *principal
;
474 principal
= gensec_get_target_principal(conn
->gensec
);
475 if (principal
== NULL
) {
476 const char *hostname
= gensec_get_target_hostname(conn
->gensec
);
477 const char *service
= gensec_get_target_service(conn
->gensec
);
478 if (hostname
!= NULL
&& service
!= NULL
) {
479 principal
= talloc_asprintf(tmp_ctx
, "%s/%s", service
, hostname
);
483 if (cli_credentials_failed_kerberos_login(creds
, principal
, &logon_retries
) ||
484 cli_credentials_wrong_password(creds
)) {
486 destroy our gensec session and loop
487 back up to the top to retry,
488 offering the user a chance to enter
489 new credentials, or get a new ticket
492 goto try_logon_again
;
496 if (result
!= LDAP_SUCCESS
&& result
!= LDAP_SASL_BIND_IN_PROGRESS
) {
497 status
= ldap_check_response(conn
,
498 &response
->r
.BindResponse
.response
);
502 /* This is where we check if GENSEC wanted to be fed more data */
503 if (!NT_STATUS_EQUAL(gensec_status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
506 if (response
->r
.BindResponse
.SASL
.secblob
) {
507 input
= *response
->r
.BindResponse
.SASL
.secblob
;
509 input
= data_blob(NULL
, 0);
513 TALLOC_FREE(tmp_ctx
);
515 if (!NT_STATUS_IS_OK(status
)) {
519 conn
->bind
.type
= LDAP_BIND_SASL
;
520 conn
->bind
.creds
= creds
;
522 if (wrap_flags
& ADS_AUTH_SASL_SEAL
) {
523 if (!gensec_have_feature(conn
->gensec
, GENSEC_FEATURE_SIGN
)) {
524 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
527 if (!gensec_have_feature(conn
->gensec
, GENSEC_FEATURE_SEAL
)) {
528 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
530 } else if (wrap_flags
& ADS_AUTH_SASL_SIGN
) {
531 if (!gensec_have_feature(conn
->gensec
, GENSEC_FEATURE_SIGN
)) {
532 return NT_STATUS_INVALID_NETWORK_RESPONSE
;
536 if (!gensec_have_feature(conn
->gensec
, GENSEC_FEATURE_SIGN
) &&
537 !gensec_have_feature(conn
->gensec
, GENSEC_FEATURE_SEAL
)) {
541 status
= gensec_create_tstream(conn
->sockets
.raw
,
544 &conn
->sockets
.sasl
);
545 if (!NT_STATUS_IS_OK(status
)) {
549 conn
->sockets
.active
= conn
->sockets
.sasl
;
554 talloc_free(tmp_ctx
);
555 talloc_free(conn
->gensec
);