2
Unix SMB/CIFS implementation.
4
Copyright (C) Andrew Tridgell 2001
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.
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.
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/>.
24
static ADS_STATUS ads_sasl_ntlmssp_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len)
26
struct ntlmssp_state *ntlmssp_state =
27
(struct ntlmssp_state *)ads->ldap.wrap_private_data;
31
uint8 *dptr = ads->ldap.out.buf + (4 + NTLMSSP_SIG_SIZE);
33
/* copy the data to the right location */
34
memcpy(dptr, buf, len);
36
/* create the signature and may encrypt the data */
37
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
38
nt_status = ntlmssp_seal_packet(ntlmssp_state,
43
nt_status = ntlmssp_sign_packet(ntlmssp_state,
48
status = ADS_ERROR_NT(nt_status);
49
if (!ADS_ERR_OK(status)) return status;
51
/* copy the signature to the right location */
52
memcpy(ads->ldap.out.buf + 4,
53
sig.data, NTLMSSP_SIG_SIZE);
57
/* set how many bytes must be written to the underlying socket */
58
ads->ldap.out.left = 4 + NTLMSSP_SIG_SIZE + len;
63
static ADS_STATUS ads_sasl_ntlmssp_unwrap(ADS_STRUCT *ads)
65
struct ntlmssp_state *ntlmssp_state =
66
(struct ntlmssp_state *)ads->ldap.wrap_private_data;
70
uint8 *dptr = ads->ldap.in.buf + (4 + NTLMSSP_SIG_SIZE);
71
uint32 dlen = ads->ldap.in.ofs - (4 + NTLMSSP_SIG_SIZE);
73
/* wrap the signature into a DATA_BLOB */
74
sig = data_blob_const(ads->ldap.in.buf + 4, NTLMSSP_SIG_SIZE);
76
/* verify the signature and maybe decrypt the data */
77
if (ntlmssp_state->neg_flags & NTLMSSP_NEGOTIATE_SEAL) {
78
nt_status = ntlmssp_unseal_packet(ntlmssp_state,
83
nt_status = ntlmssp_check_packet(ntlmssp_state,
88
status = ADS_ERROR_NT(nt_status);
89
if (!ADS_ERR_OK(status)) return status;
91
/* set the amount of bytes for the upper layer and set the ofs to the data */
92
ads->ldap.in.left = dlen;
93
ads->ldap.in.ofs = 4 + NTLMSSP_SIG_SIZE;
98
static void ads_sasl_ntlmssp_disconnect(ADS_STRUCT *ads)
100
struct ntlmssp_state *ntlmssp_state =
101
(struct ntlmssp_state *)ads->ldap.wrap_private_data;
103
ntlmssp_end(&ntlmssp_state);
105
ads->ldap.wrap_ops = NULL;
106
ads->ldap.wrap_private_data = NULL;
109
static const struct ads_saslwrap_ops ads_sasl_ntlmssp_ops = {
111
.wrap = ads_sasl_ntlmssp_wrap,
112
.unwrap = ads_sasl_ntlmssp_unwrap,
113
.disconnect = ads_sasl_ntlmssp_disconnect
117
perform a LDAP/SASL/SPNEGO/NTLMSSP bind (just how many layers can
118
we fit on one socket??)
120
static ADS_STATUS ads_sasl_spnego_ntlmssp_bind(ADS_STRUCT *ads)
122
DATA_BLOB msg1 = data_blob_null;
123
DATA_BLOB blob = data_blob_null;
124
DATA_BLOB blob_in = data_blob_null;
125
DATA_BLOB blob_out = data_blob_null;
126
struct berval cred, *scred = NULL;
133
struct ntlmssp_state *ntlmssp_state;
135
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_client_start(&ntlmssp_state))) {
136
return ADS_ERROR_NT(nt_status);
138
ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_SIGN;
140
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_username(ntlmssp_state, ads->auth.user_name))) {
141
return ADS_ERROR_NT(nt_status);
143
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_domain(ntlmssp_state, ads->auth.realm))) {
144
return ADS_ERROR_NT(nt_status);
146
if (!NT_STATUS_IS_OK(nt_status = ntlmssp_set_password(ntlmssp_state, ads->auth.password))) {
147
return ADS_ERROR_NT(nt_status);
150
switch (ads->ldap.wrap_type) {
151
case ADS_SASLWRAP_TYPE_SEAL:
152
features = NTLMSSP_FEATURE_SIGN | NTLMSSP_FEATURE_SEAL;
154
case ADS_SASLWRAP_TYPE_SIGN:
155
if (ads->auth.flags & ADS_AUTH_SASL_FORCE) {
156
features = NTLMSSP_FEATURE_SIGN;
159
* windows servers are broken with sign only,
160
* so we need to use seal here too
162
features = NTLMSSP_FEATURE_SIGN | NTLMSSP_FEATURE_SEAL;
163
ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL;
166
case ADS_SASLWRAP_TYPE_PLAIN:
170
ntlmssp_want_feature(ntlmssp_state, features);
172
blob_in = data_blob_null;
175
nt_status = ntlmssp_update(ntlmssp_state,
177
data_blob_free(&blob_in);
178
if ((NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)
179
|| NT_STATUS_IS_OK(nt_status))
180
&& blob_out.length) {
182
/* and wrap it in a SPNEGO wrapper */
183
msg1 = gen_negTokenInit(OID_NTLMSSP, blob_out);
185
/* wrap it in SPNEGO */
186
msg1 = spnego_gen_auth(blob_out);
189
data_blob_free(&blob_out);
191
cred.bv_val = (char *)msg1.data;
192
cred.bv_len = msg1.length;
194
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
195
data_blob_free(&msg1);
196
if ((rc != LDAP_SASL_BIND_IN_PROGRESS) && (rc != 0)) {
201
ntlmssp_end(&ntlmssp_state);
202
return ADS_ERROR(rc);
205
blob = data_blob(scred->bv_val, scred->bv_len);
208
blob = data_blob_null;
213
ntlmssp_end(&ntlmssp_state);
214
data_blob_free(&blob_out);
215
return ADS_ERROR_NT(nt_status);
219
(rc == LDAP_SASL_BIND_IN_PROGRESS)) {
220
DATA_BLOB tmp_blob = data_blob_null;
221
/* the server might give us back two challenges */
222
if (!spnego_parse_challenge(blob, &blob_in,
225
ntlmssp_end(&ntlmssp_state);
226
data_blob_free(&blob);
227
DEBUG(3,("Failed to parse challenges\n"));
228
return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
230
data_blob_free(&tmp_blob);
231
} else if (rc == LDAP_SASL_BIND_IN_PROGRESS) {
232
if (!spnego_parse_auth_response(blob, nt_status, OID_NTLMSSP,
235
ntlmssp_end(&ntlmssp_state);
236
data_blob_free(&blob);
237
DEBUG(3,("Failed to parse auth response\n"));
238
return ADS_ERROR_NT(NT_STATUS_INVALID_PARAMETER);
241
data_blob_free(&blob);
242
data_blob_free(&blob_out);
244
} while (rc == LDAP_SASL_BIND_IN_PROGRESS && !NT_STATUS_IS_OK(nt_status));
246
/* we have a reference conter on ntlmssp_state, if we are signing
247
then the state will be kept by the signing engine */
249
if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
250
ads->ldap.out.max_unwrapped = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED - NTLMSSP_SIG_SIZE;
251
ads->ldap.out.sig_size = NTLMSSP_SIG_SIZE;
252
ads->ldap.in.min_wrapped = ads->ldap.out.sig_size;
253
ads->ldap.in.max_wrapped = ADS_SASL_WRAPPING_IN_MAX_WRAPPED;
254
status = ads_setup_sasl_wrapping(ads, &ads_sasl_ntlmssp_ops, ntlmssp_state);
255
if (!ADS_ERR_OK(status)) {
256
DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
257
ads_errstr(status)));
258
ntlmssp_end(&ntlmssp_state);
262
ntlmssp_end(&ntlmssp_state);
265
return ADS_ERROR(rc);
269
static ADS_STATUS ads_sasl_gssapi_wrap(ADS_STRUCT *ads, uint8 *buf, uint32 len)
271
gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data;
275
gss_buffer_desc unwrapped, wrapped;
276
int conf_req_flag, conf_state;
278
unwrapped.value = buf;
279
unwrapped.length = len;
281
/* for now request sign and seal */
282
conf_req_flag = (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL);
284
gss_rc = gss_wrap(&minor_status, context_handle,
285
conf_req_flag, GSS_C_QOP_DEFAULT,
286
&unwrapped, &conf_state,
288
status = ADS_ERROR_GSS(gss_rc, minor_status);
289
if (!ADS_ERR_OK(status)) return status;
291
if (conf_req_flag && conf_state == 0) {
292
return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED);
295
if ((ads->ldap.out.size - 4) < wrapped.length) {
296
return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR);
299
/* copy the wrapped blob to the right location */
300
memcpy(ads->ldap.out.buf + 4, wrapped.value, wrapped.length);
302
/* set how many bytes must be written to the underlying socket */
303
ads->ldap.out.left = 4 + wrapped.length;
305
gss_release_buffer(&minor_status, &wrapped);
310
static ADS_STATUS ads_sasl_gssapi_unwrap(ADS_STRUCT *ads)
312
gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data;
316
gss_buffer_desc unwrapped, wrapped;
319
wrapped.value = ads->ldap.in.buf + 4;
320
wrapped.length = ads->ldap.in.ofs - 4;
322
gss_rc = gss_unwrap(&minor_status, context_handle,
323
&wrapped, &unwrapped,
324
&conf_state, GSS_C_QOP_DEFAULT);
325
status = ADS_ERROR_GSS(gss_rc, minor_status);
326
if (!ADS_ERR_OK(status)) return status;
328
if (ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL && conf_state == 0) {
329
return ADS_ERROR_NT(NT_STATUS_ACCESS_DENIED);
332
if (wrapped.length < unwrapped.length) {
333
return ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR);
336
/* copy the wrapped blob to the right location */
337
memcpy(ads->ldap.in.buf + 4, unwrapped.value, unwrapped.length);
339
/* set how many bytes must be written to the underlying socket */
340
ads->ldap.in.left = unwrapped.length;
341
ads->ldap.in.ofs = 4;
343
gss_release_buffer(&minor_status, &unwrapped);
348
static void ads_sasl_gssapi_disconnect(ADS_STRUCT *ads)
350
gss_ctx_id_t context_handle = (gss_ctx_id_t)ads->ldap.wrap_private_data;
353
gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER);
355
ads->ldap.wrap_ops = NULL;
356
ads->ldap.wrap_private_data = NULL;
359
static const struct ads_saslwrap_ops ads_sasl_gssapi_ops = {
361
.wrap = ads_sasl_gssapi_wrap,
362
.unwrap = ads_sasl_gssapi_unwrap,
363
.disconnect = ads_sasl_gssapi_disconnect
367
perform a LDAP/SASL/SPNEGO/GSSKRB5 bind
369
static ADS_STATUS ads_sasl_spnego_gsskrb5_bind(ADS_STRUCT *ads, const gss_name_t serv_name)
375
gss_OID_desc krb5_mech_type =
376
{9, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02") };
377
gss_OID mech_type = &krb5_mech_type;
378
gss_OID actual_mech_type = GSS_C_NULL_OID;
379
const char *spnego_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL};
380
gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT;
381
gss_buffer_desc input_token, output_token;
382
uint32 req_flags, ret_flags;
383
uint32 req_tmp, ret_tmp;
386
struct berval cred, *scred = NULL;
388
input_token.value = NULL;
389
input_token.length = 0;
391
req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
392
switch (ads->ldap.wrap_type) {
393
case ADS_SASLWRAP_TYPE_SEAL:
394
req_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
396
case ADS_SASLWRAP_TYPE_SIGN:
397
req_flags |= GSS_C_INTEG_FLAG;
399
case ADS_SASLWRAP_TYPE_PLAIN:
403
/* Note: here we explicit ask for the krb5 mech_type */
404
gss_rc = gss_init_sec_context(&minor_status,
417
if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) {
418
status = ADS_ERROR_GSS(gss_rc, minor_status);
423
* As some gssapi krb5 mech implementations
424
* automaticly add GSS_C_INTEG_FLAG and GSS_C_CONF_FLAG
425
* to req_flags internaly, it's not possible to
426
* use plain or signing only connection via
427
* the gssapi interface.
429
* Because of this we need to check it the ret_flags
430
* has more flags as req_flags and correct the value
431
* of ads->ldap.wrap_type.
433
* I ads->auth.flags has ADS_AUTH_SASL_FORCE
434
* we need to give an error.
436
req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG);
437
ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG);
439
if (req_tmp == ret_tmp) {
440
/* everythings fine... */
442
} else if (req_flags & GSS_C_CONF_FLAG) {
444
* here we wanted sealing but didn't got it
445
* from the gssapi library
447
status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
450
} else if ((req_flags & GSS_C_INTEG_FLAG) &&
451
!(ret_flags & GSS_C_INTEG_FLAG)) {
453
* here we wanted siging but didn't got it
454
* from the gssapi library
456
status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
459
} else if (ret_flags & GSS_C_CONF_FLAG) {
461
* here we didn't want sealing
462
* but the gssapi library forces it
463
* so correct the needed wrap_type if
464
* the caller didn't forced siging only
466
if (ads->auth.flags & ADS_AUTH_SASL_FORCE) {
467
status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
471
ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL;
472
req_flags = ret_flags;
474
} else if (ret_flags & GSS_C_INTEG_FLAG) {
476
* here we didn't want signing
477
* but the gssapi library forces it
478
* so correct the needed wrap_type if
479
* the caller didn't forced plain
481
if (ads->auth.flags & ADS_AUTH_SASL_FORCE) {
482
status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
486
ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN;
487
req_flags = ret_flags;
490
* This could (should?) not happen
492
status = ADS_ERROR_NT(NT_STATUS_INTERNAL_ERROR);
497
/* and wrap that in a shiny SPNEGO wrapper */
498
unwrapped = data_blob_const(output_token.value, output_token.length);
499
wrapped = gen_negTokenTarg(spnego_mechs, unwrapped);
500
gss_release_buffer(&minor_status, &output_token);
501
if (unwrapped.length > wrapped.length) {
502
status = ADS_ERROR_NT(NT_STATUS_NO_MEMORY);
506
cred.bv_val = (char *)wrapped.data;
507
cred.bv_len = wrapped.length;
509
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL,
511
data_blob_free(&wrapped);
512
if (rc != LDAP_SUCCESS) {
513
status = ADS_ERROR(rc);
518
wrapped = data_blob_const(scred->bv_val, scred->bv_len);
520
wrapped = data_blob_null;
523
ok = spnego_parse_auth_response(wrapped, NT_STATUS_OK,
526
if (scred) ber_bvfree(scred);
528
status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
532
input_token.value = unwrapped.data;
533
input_token.length = unwrapped.length;
536
* As we asked for mutal authentication
537
* we need to pass the servers response
540
gss_rc = gss_init_sec_context(&minor_status,
553
data_blob_free(&unwrapped);
555
status = ADS_ERROR_GSS(gss_rc, minor_status);
559
gss_release_buffer(&minor_status, &output_token);
562
* If we the sign and seal options
563
* doesn't match after getting the response
564
* from the server, we don't want to use the connection
566
req_tmp = req_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG);
567
ret_tmp = ret_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG);
569
if (req_tmp != ret_tmp) {
570
/* everythings fine... */
571
status = ADS_ERROR_NT(NT_STATUS_INVALID_NETWORK_RESPONSE);
575
if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
576
uint32 max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED;
578
gss_rc = gss_wrap_size_limit(&minor_status, context_handle,
579
(ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL),
581
max_msg_size, &ads->ldap.out.max_unwrapped);
583
status = ADS_ERROR_GSS(gss_rc, minor_status);
587
ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped;
588
ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */
589
ads->ldap.in.max_wrapped = max_msg_size;
590
status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle);
591
if (!ADS_ERR_OK(status)) {
592
DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
593
ads_errstr(status)));
596
/* make sure we don't free context_handle */
597
context_handle = GSS_C_NO_CONTEXT;
600
status = ADS_SUCCESS;
603
if (context_handle != GSS_C_NO_CONTEXT)
604
gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER);
608
#endif /* HAVE_GSSAPI */
611
struct ads_service_principal {
618
static void ads_free_service_principal(struct ads_service_principal *p)
620
SAFE_FREE(p->string);
625
gss_release_name(&minor_status, &p->name);
631
static ADS_STATUS ads_generate_service_principal(ADS_STRUCT *ads,
632
const char *given_principal,
633
struct ads_service_principal *p)
637
gss_buffer_desc input_name;
638
/* GSS_KRB5_NT_PRINCIPAL_NAME */
639
gss_OID_desc nt_principal =
640
{10, CONST_DISCARD(char *, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01")};
647
/* I've seen a child Windows 2000 domain not send
648
the principal name back in the first round of
649
the SASL bind reply. So we guess based on server
650
name and realm. --jerry */
651
/* Also try best guess when we get the w2k8 ignore
652
principal back - gd */
654
if (!given_principal ||
655
strequal(given_principal, ADS_IGNORE_PRINCIPAL)) {
657
status = ads_guess_service_principal(ads, &p->string);
658
if (!ADS_ERR_OK(status)) {
662
p->string = SMB_STRDUP(given_principal);
664
return ADS_ERROR(LDAP_NO_MEMORY);
669
input_name.value = p->string;
670
input_name.length = strlen(p->string);
672
gss_rc = gss_import_name(&minor_status, &input_name, &nt_principal, &p->name);
674
ads_free_service_principal(p);
675
return ADS_ERROR_GSS(gss_rc, minor_status);
683
perform a LDAP/SASL/SPNEGO/KRB5 bind
685
static ADS_STATUS ads_sasl_spnego_rawkrb5_bind(ADS_STRUCT *ads, const char *principal)
687
DATA_BLOB blob = data_blob_null;
688
struct berval cred, *scred = NULL;
689
DATA_BLOB session_key = data_blob_null;
692
if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
693
return ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
696
rc = spnego_gen_negTokenTarg(principal, ads->auth.time_offset, &blob, &session_key, 0,
697
&ads->auth.tgs_expire);
700
return ADS_ERROR_KRB5(rc);
703
/* now send the auth packet and we should be done */
704
cred.bv_val = (char *)blob.data;
705
cred.bv_len = blob.length;
707
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred);
709
data_blob_free(&blob);
710
data_blob_free(&session_key);
714
return ADS_ERROR(rc);
717
static ADS_STATUS ads_sasl_spnego_krb5_bind(ADS_STRUCT *ads,
718
struct ads_service_principal *p)
722
* we only use the gsskrb5 based implementation
723
* when sasl sign or seal is requested.
725
* This has the following reasons:
726
* - it's likely that the gssapi krb5 mech implementation
727
* doesn't support to negotiate plain connections
728
* - the ads_sasl_spnego_rawkrb5_bind is more robust
729
* against clock skew errors
731
if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
732
return ads_sasl_spnego_gsskrb5_bind(ads, p->name);
735
return ads_sasl_spnego_rawkrb5_bind(ads, p->string);
737
#endif /* HAVE_KRB5 */
740
this performs a SASL/SPNEGO bind
742
static ADS_STATUS ads_sasl_spnego_bind(ADS_STRUCT *ads)
744
struct berval *scred=NULL;
748
char *given_principal = NULL;
749
char *OIDs[ASN1_MAX_OIDS];
751
bool got_kerberos_mechanism = False;
754
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSS-SPNEGO", NULL, NULL, NULL, &scred);
756
if (rc != LDAP_SASL_BIND_IN_PROGRESS) {
757
status = ADS_ERROR(rc);
761
blob = data_blob(scred->bv_val, scred->bv_len);
766
file_save("sasl_spnego.dat", blob.data, blob.length);
769
/* the server sent us the first part of the SPNEGO exchange in the negprot
771
if (!spnego_parse_negTokenInit(blob, OIDs, &given_principal)) {
772
data_blob_free(&blob);
773
status = ADS_ERROR(LDAP_OPERATIONS_ERROR);
776
data_blob_free(&blob);
778
/* make sure the server understands kerberos */
779
for (i=0;OIDs[i];i++) {
780
DEBUG(3,("ads_sasl_spnego_bind: got OID=%s\n", OIDs[i]));
782
if (strcmp(OIDs[i], OID_KERBEROS5_OLD) == 0 ||
783
strcmp(OIDs[i], OID_KERBEROS5) == 0) {
784
got_kerberos_mechanism = True;
787
talloc_free(OIDs[i]);
789
DEBUG(3,("ads_sasl_spnego_bind: got server principal name = %s\n", given_principal));
792
if (!(ads->auth.flags & ADS_AUTH_DISABLE_KERBEROS) &&
793
got_kerberos_mechanism)
795
struct ads_service_principal p;
797
status = ads_generate_service_principal(ads, given_principal, &p);
798
TALLOC_FREE(given_principal);
799
if (!ADS_ERR_OK(status)) {
803
status = ads_sasl_spnego_krb5_bind(ads, &p);
804
if (ADS_ERR_OK(status)) {
805
ads_free_service_principal(&p);
809
DEBUG(10,("ads_sasl_spnego_krb5_bind failed with: %s, "
810
"calling kinit\n", ads_errstr(status)));
812
status = ADS_ERROR_KRB5(ads_kinit_password(ads));
814
if (ADS_ERR_OK(status)) {
815
status = ads_sasl_spnego_krb5_bind(ads, &p);
816
if (!ADS_ERR_OK(status)) {
817
DEBUG(0,("kinit succeeded but "
818
"ads_sasl_spnego_krb5_bind failed: %s\n",
819
ads_errstr(status)));
823
ads_free_service_principal(&p);
825
/* only fallback to NTLMSSP if allowed */
826
if (ADS_ERR_OK(status) ||
827
!(ads->auth.flags & ADS_AUTH_ALLOW_NTLMSSP)) {
833
TALLOC_FREE(given_principal);
836
/* lets do NTLMSSP ... this has the big advantage that we don't need
837
to sync clocks, and we don't rely on special versions of the krb5
838
library for HMAC_MD4 encryption */
839
return ads_sasl_spnego_ntlmssp_bind(ads);
846
#define MAX_GSS_PASSES 3
848
/* this performs a SASL/gssapi bind
849
we avoid using cyrus-sasl to make Samba more robust. cyrus-sasl
850
is very dependent on correctly configured DNS whereas
851
this routine is much less fragile
852
see RFC2078 and RFC2222 for details
854
static ADS_STATUS ads_sasl_gssapi_do_bind(ADS_STRUCT *ads, const gss_name_t serv_name)
857
gss_ctx_id_t context_handle = GSS_C_NO_CONTEXT;
858
gss_OID mech_type = GSS_C_NULL_OID;
859
gss_buffer_desc output_token, input_token;
860
uint32 req_flags, ret_flags;
863
struct berval *scred = NULL;
867
uint32 max_msg_size = ADS_SASL_WRAPPING_OUT_MAX_WRAPPED;
868
uint8 wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
871
input_token.value = NULL;
872
input_token.length = 0;
875
* Note: here we always ask the gssapi for sign and seal
876
* as this is negotiated later after the mutal
879
req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
881
for (i=0; i < MAX_GSS_PASSES; i++) {
882
gss_rc = gss_init_sec_context(&minor_status,
899
if (gss_rc && gss_rc != GSS_S_CONTINUE_NEEDED) {
900
status = ADS_ERROR_GSS(gss_rc, minor_status);
904
cred.bv_val = (char *)output_token.value;
905
cred.bv_len = output_token.length;
907
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL,
909
if (rc != LDAP_SASL_BIND_IN_PROGRESS) {
910
status = ADS_ERROR(rc);
914
if (output_token.value) {
915
gss_release_buffer(&minor_status, &output_token);
919
input_token.value = scred->bv_val;
920
input_token.length = scred->bv_len;
922
input_token.value = NULL;
923
input_token.length = 0;
926
if (gss_rc == 0) break;
929
gss_rc = gss_unwrap(&minor_status,context_handle,&input_token,&output_token,
936
status = ADS_ERROR_GSS(gss_rc, minor_status);
940
p = (uint8 *)output_token.value;
943
file_save("sasl_gssapi.dat", output_token.value, output_token.length);
947
wrap_type = CVAL(p,0);
949
max_msg_size = RIVAL(p,0);
952
gss_release_buffer(&minor_status, &output_token);
954
if (!(wrap_type & ads->ldap.wrap_type)) {
956
* the server doesn't supports the wrap
959
DEBUG(0,("The ldap sasl wrap type doesn't match wanted[%d] server[%d]\n",
960
ads->ldap.wrap_type, wrap_type));
961
DEBUGADD(0,("You may want to set the 'client ldap sasl wrapping' option\n"));
962
status = ADS_ERROR_NT(NT_STATUS_NOT_SUPPORTED);
966
/* 0x58 is the minimum windows accepts */
967
if (max_msg_size < 0x58) {
971
output_token.length = 4;
972
output_token.value = SMB_MALLOC(output_token.length);
973
p = (uint8 *)output_token.value;
975
RSIVAL(p,0,max_msg_size);
976
SCVAL(p,0,ads->ldap.wrap_type);
979
* we used to add sprintf("dn:%s", ads->config.bind_path) here.
980
* but using ads->config.bind_path is the wrong! It should be
981
* the DN of the user object!
983
* w2k3 gives an error when we send an incorrect DN, but sending nothing
984
* is ok and matches the information flow used in GSS-SPNEGO.
987
gss_rc = gss_wrap(&minor_status, context_handle,0,GSS_C_QOP_DEFAULT,
988
&output_token, &conf_state,
991
status = ADS_ERROR_GSS(gss_rc, minor_status);
995
free(output_token.value);
997
cred.bv_val = (char *)input_token.value;
998
cred.bv_len = input_token.length;
1000
rc = ldap_sasl_bind_s(ads->ldap.ld, NULL, "GSSAPI", &cred, NULL, NULL,
1002
gss_release_buffer(&minor_status, &input_token);
1003
status = ADS_ERROR(rc);
1004
if (!ADS_ERR_OK(status)) {
1008
if (ads->ldap.wrap_type > ADS_SASLWRAP_TYPE_PLAIN) {
1009
gss_rc = gss_wrap_size_limit(&minor_status, context_handle,
1010
(ads->ldap.wrap_type == ADS_SASLWRAP_TYPE_SEAL),
1012
max_msg_size, &ads->ldap.out.max_unwrapped);
1014
status = ADS_ERROR_GSS(gss_rc, minor_status);
1018
ads->ldap.out.sig_size = max_msg_size - ads->ldap.out.max_unwrapped;
1019
ads->ldap.in.min_wrapped = 0x2C; /* taken from a capture with LDAP unbind */
1020
ads->ldap.in.max_wrapped = max_msg_size;
1021
status = ads_setup_sasl_wrapping(ads, &ads_sasl_gssapi_ops, context_handle);
1022
if (!ADS_ERR_OK(status)) {
1023
DEBUG(0, ("ads_setup_sasl_wrapping() failed: %s\n",
1024
ads_errstr(status)));
1027
/* make sure we don't free context_handle */
1028
context_handle = GSS_C_NO_CONTEXT;
1033
if (context_handle != GSS_C_NO_CONTEXT)
1034
gss_delete_sec_context(&minor_status, &context_handle, GSS_C_NO_BUFFER);
1041
static ADS_STATUS ads_sasl_gssapi_bind(ADS_STRUCT *ads)
1044
struct ads_service_principal p;
1046
status = ads_generate_service_principal(ads, NULL, &p);
1047
if (!ADS_ERR_OK(status)) {
1051
status = ads_sasl_gssapi_do_bind(ads, p.name);
1052
if (ADS_ERR_OK(status)) {
1053
ads_free_service_principal(&p);
1057
DEBUG(10,("ads_sasl_gssapi_do_bind failed with: %s, "
1058
"calling kinit\n", ads_errstr(status)));
1060
status = ADS_ERROR_KRB5(ads_kinit_password(ads));
1062
if (ADS_ERR_OK(status)) {
1063
status = ads_sasl_gssapi_do_bind(ads, p.name);
1066
ads_free_service_principal(&p);
1071
#endif /* HAVE_GSSAPI */
1073
/* mapping between SASL mechanisms and functions */
1076
ADS_STATUS (*fn)(ADS_STRUCT *);
1077
} sasl_mechanisms[] = {
1078
{"GSS-SPNEGO", ads_sasl_spnego_bind},
1080
{"GSSAPI", ads_sasl_gssapi_bind}, /* doesn't work with .NET RC1. No idea why */
1085
ADS_STATUS ads_sasl_bind(ADS_STRUCT *ads)
1087
const char *attrs[] = {"supportedSASLMechanisms", NULL};
1093
/* get a list of supported SASL mechanisms */
1094
status = ads_do_search(ads, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, &res);
1095
if (!ADS_ERR_OK(status)) return status;
1097
values = ldap_get_values(ads->ldap.ld, res, "supportedSASLMechanisms");
1099
if (ads->auth.flags & ADS_AUTH_SASL_SEAL) {
1100
ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SEAL;
1101
} else if (ads->auth.flags & ADS_AUTH_SASL_SIGN) {
1102
ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_SIGN;
1104
ads->ldap.wrap_type = ADS_SASLWRAP_TYPE_PLAIN;
1107
/* try our supported mechanisms in order */
1108
for (i=0;sasl_mechanisms[i].name;i++) {
1109
/* see if the server supports it */
1110
for (j=0;values && values[j];j++) {
1111
if (strcmp(values[j], sasl_mechanisms[i].name) == 0) {
1112
DEBUG(4,("Found SASL mechanism %s\n", values[j]));
1113
status = sasl_mechanisms[i].fn(ads);
1114
ldap_value_free(values);
1121
ldap_value_free(values);
1123
return ADS_ERROR(LDAP_AUTH_METHOD_NOT_SUPPORTED);
1126
#endif /* HAVE_LDAP */