1
/* $OpenLDAP: pkg/ldap/libraries/libldap/gssapi.c,v 1.1.2.4 2009/04/29 01:53:02 quanah Exp $ */
2
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4
* Copyright 1998-2009 The OpenLDAP Foundation.
7
* Author: Stefan Metzmacher <metze@sernet.de>
9
* Redistribution and use in source and binary forms, with or without
10
* modification, are permitted only as authorized by the OpenLDAP
13
* A copy of this license is available in the file LICENSE in the
14
* top-level directory of the distribution or, alternatively, at
15
* <http://www.OpenLDAP.org/license.html>.
22
#include <ac/socket.h>
23
#include <ac/stdlib.h>
24
#include <ac/string.h>
28
#include <ac/unistd.h>
38
#ifdef HAVE_GSSAPI_GSSAPI_H
39
#include <gssapi/gssapi.h>
50
OM_uint32 minor_status )
53
gss_buffer_desc mech_msg = GSS_C_EMPTY_BUFFER;
54
gss_buffer_desc gss_msg = GSS_C_EMPTY_BUFFER;
55
gss_buffer_desc minor_msg = GSS_C_EMPTY_BUFFER;
56
OM_uint32 msg_ctx = 0;
66
#ifdef HAVE_GSS_OID_TO_STR
67
gss_oid_to_str(&min2, mech, &mech_msg);
69
gss_display_status(&min2, gss_rc, GSS_C_GSS_CODE,
70
mech, &msg_ctx, &gss_msg);
71
gss_display_status(&min2, minor_status, GSS_C_MECH_CODE,
72
mech, &msg_ctx, &minor_msg);
74
snprintf(buf, buf_len, "gss_rc[%d:%*s] mech[%*s] minor[%u:%*s]",
75
gss_rc, (int)gss_msg.length,
76
(const char *)(gss_msg.value?gss_msg.value:""),
78
(const char *)(mech_msg.value?mech_msg.value:""),
79
minor_status, (int)minor_msg.length,
80
(const char *)(minor_msg.value?minor_msg.value:""));
82
gss_release_buffer(&min2, &mech_msg);
83
gss_release_buffer(&min2, &gss_msg);
84
gss_release_buffer(&min2, &minor_msg);
86
buf[buf_len-1] = '\0';
93
struct sb_sasl_generic_data *p,
98
gss_ctx_id_t gss_ctx = (gss_ctx_id_t)p->ops_private;
100
OM_uint32 minor_status;
101
gss_OID ctx_mech = GSS_C_NO_OID;
102
OM_uint32 ctx_flags = 0;
103
int conf_req_flag = 0;
104
OM_uint32 max_input_size;
106
gss_inquire_context(&minor_status,
116
if (ctx_flags & (GSS_C_CONF_FLAG)) {
120
#if defined(HAVE_CYRUS_SASL)
121
#define SEND_PREALLOC_SIZE SASL_MIN_BUFF_SIZE
123
#define SEND_PREALLOC_SIZE 4096
125
#define SEND_MAX_WIRE_SIZE 0x00A00000
126
#define RECV_MAX_WIRE_SIZE 0x0FFFFFFF
127
#define FALLBACK_SEND_MAX_SIZE 0x009FFFB8 /* from MIT 1.5.x */
129
gss_rc = gss_wrap_size_limit(&minor_status, gss_ctx,
130
conf_req_flag, GSS_C_QOP_DEFAULT,
131
SEND_MAX_WIRE_SIZE, &max_input_size);
132
if ( gss_rc != GSS_S_COMPLETE ) {
134
ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
135
"sb_sasl_gssapi_init: failed to wrap size limit: %s\n",
136
gsserrstr( msg, sizeof(msg), ctx_mech, gss_rc, minor_status ) );
137
ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
138
"sb_sasl_gssapi_init: fallback to default wrap size limit\n");
140
* some libgssglue/libgssapi versions
141
* have a broken gss_wrap_size_limit()
144
max_input_size = FALLBACK_SEND_MAX_SIZE;
147
*min_send = SEND_PREALLOC_SIZE;
148
*max_send = max_input_size;
149
*max_recv = RECV_MAX_WIRE_SIZE;
153
sb_sasl_gssapi_encode(
154
struct sb_sasl_generic_data *p,
159
gss_ctx_id_t gss_ctx = (gss_ctx_id_t)p->ops_private;
161
OM_uint32 minor_status;
162
gss_buffer_desc unwrapped, wrapped;
163
gss_OID ctx_mech = GSS_C_NO_OID;
164
OM_uint32 ctx_flags = 0;
165
int conf_req_flag = 0;
170
unwrapped.value = buf;
171
unwrapped.length = len;
173
gss_inquire_context(&minor_status,
183
if (ctx_flags & (GSS_C_CONF_FLAG)) {
187
gss_rc = gss_wrap(&minor_status, gss_ctx,
188
conf_req_flag, GSS_C_QOP_DEFAULT,
189
&unwrapped, &conf_state,
191
if ( gss_rc != GSS_S_COMPLETE ) {
193
ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
194
"sb_sasl_gssapi_encode: failed to encode packet: %s\n",
195
gsserrstr( msg, sizeof(msg), ctx_mech, gss_rc, minor_status ) );
199
if ( conf_req_flag && conf_state == 0 ) {
200
ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
201
"sb_sasl_gssapi_encode: GSS_C_CONF_FLAG was ignored by our gss_wrap()\n" );
205
pkt_len = 4 + wrapped.length;
207
/* Grow the packet buffer if neccessary */
208
if ( dst->buf_size < pkt_len &&
209
ber_pvt_sb_grow_buffer( dst, pkt_len ) < 0 )
211
ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
212
"sb_sasl_gssapi_encode: failed to grow the buffer to %lu bytes\n",
217
dst->buf_end = pkt_len;
219
b = (unsigned char *)dst->buf_base;
221
b[0] = (unsigned char)(wrapped.length >> 24);
222
b[1] = (unsigned char)(wrapped.length >> 16);
223
b[2] = (unsigned char)(wrapped.length >> 8);
224
b[3] = (unsigned char)(wrapped.length >> 0);
226
/* copy the wrapped blob to the right location */
227
memcpy(b + 4, wrapped.value, wrapped.length);
229
gss_release_buffer(&minor_status, &wrapped);
235
sb_sasl_gssapi_decode(
236
struct sb_sasl_generic_data *p,
237
const Sockbuf_Buf *src,
240
gss_ctx_id_t gss_ctx = (gss_ctx_id_t)p->ops_private;
242
OM_uint32 minor_status;
243
gss_buffer_desc unwrapped, wrapped;
244
gss_OID ctx_mech = GSS_C_NO_OID;
245
OM_uint32 ctx_flags = 0;
246
int conf_req_flag = 0;
250
wrapped.value = src->buf_base + 4;
251
wrapped.length = src->buf_end - 4;
253
gss_inquire_context(&minor_status,
263
if (ctx_flags & (GSS_C_CONF_FLAG)) {
267
gss_rc = gss_unwrap(&minor_status, gss_ctx,
268
&wrapped, &unwrapped,
269
&conf_state, GSS_C_QOP_DEFAULT);
270
if ( gss_rc != GSS_S_COMPLETE ) {
272
ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
273
"sb_sasl_gssapi_decode: failed to decode packet: %s\n",
274
gsserrstr( msg, sizeof(msg), ctx_mech, gss_rc, minor_status ) );
278
if ( conf_req_flag && conf_state == 0 ) {
279
ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
280
"sb_sasl_gssapi_encode: GSS_C_CONF_FLAG was ignored by our peer\n" );
284
/* Grow the packet buffer if neccessary */
285
if ( dst->buf_size < unwrapped.length &&
286
ber_pvt_sb_grow_buffer( dst, unwrapped.length ) < 0 )
288
ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
289
"sb_sasl_gssapi_decode: failed to grow the buffer to %lu bytes\n",
294
dst->buf_end = unwrapped.length;
296
b = (unsigned char *)dst->buf_base;
298
/* copy the wrapped blob to the right location */
299
memcpy(b, unwrapped.value, unwrapped.length);
301
gss_release_buffer(&minor_status, &unwrapped);
307
sb_sasl_gssapi_reset_buf(
308
struct sb_sasl_generic_data *p,
311
ber_pvt_sb_buf_destroy( buf );
315
sb_sasl_gssapi_fini( struct sb_sasl_generic_data *p )
319
static const struct sb_sasl_generic_ops sb_sasl_gssapi_ops = {
321
sb_sasl_gssapi_encode,
322
sb_sasl_gssapi_decode,
323
sb_sasl_gssapi_reset_buf,
328
sb_sasl_gssapi_install(
330
gss_ctx_id_t gss_ctx )
332
struct sb_sasl_generic_install install_arg;
334
install_arg.ops = &sb_sasl_gssapi_ops;
335
install_arg.ops_private = gss_ctx;
337
return ldap_pvt_sasl_generic_install( sb, &install_arg );
341
sb_sasl_gssapi_remove( Sockbuf *sb )
343
ldap_pvt_sasl_generic_remove( sb );
351
OM_uint32 minor_status )
355
Debug( LDAP_DEBUG_ANY, "%s\n",
356
gsserrstr( msg, sizeof(msg), mech, gss_rc, minor_status ),
359
if (gss_rc == GSS_S_COMPLETE) {
360
ld->ld_errno = LDAP_SUCCESS;
361
} else if (GSS_CALLING_ERROR(gss_rc)) {
362
ld->ld_errno = LDAP_LOCAL_ERROR;
363
} else if (GSS_ROUTINE_ERROR(gss_rc)) {
364
ld->ld_errno = LDAP_INAPPROPRIATE_AUTH;
365
} else if (gss_rc == GSS_S_CONTINUE_NEEDED) {
366
ld->ld_errno = LDAP_SASL_BIND_IN_PROGRESS;
367
} else if (GSS_SUPPLEMENTARY_INFO(gss_rc)) {
368
ld->ld_errno = LDAP_AUTH_UNKNOWN;
369
} else if (GSS_ERROR(gss_rc)) {
370
ld->ld_errno = LDAP_AUTH_UNKNOWN;
372
ld->ld_errno = LDAP_OTHER;
380
ldap_gssapi_get_rootdse_infos (
383
char **pldapServiceName,
384
char **pdnsHostName )
386
/* we need to query the server for supported mechs anyway */
387
LDAPMessage *res, *e;
389
"supportedSASLMechanisms",
394
char **values, *mechlist;
395
char *ldapServiceName = NULL;
396
char *dnsHostName = NULL;
399
Debug( LDAP_DEBUG_TRACE, "ldap_gssapi_get_rootdse_infos\n", 0, 0, 0 );
401
rc = ldap_search_s( ld, "", LDAP_SCOPE_BASE,
402
NULL, attrs, 0, &res );
404
if ( rc != LDAP_SUCCESS ) {
408
e = ldap_first_entry( ld, res );
411
if ( ld->ld_errno == LDAP_SUCCESS ) {
412
ld->ld_errno = LDAP_NO_SUCH_OBJECT;
417
values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
418
if ( values == NULL ) {
420
ld->ld_errno = LDAP_NO_SUCH_ATTRIBUTE;
424
mechlist = ldap_charray2str( values, " " );
425
if ( mechlist == NULL ) {
426
LDAP_VFREE( values );
428
ld->ld_errno = LDAP_NO_MEMORY;
432
LDAP_VFREE( values );
434
values = ldap_get_values( ld, e, "ldapServiceName" );
435
if ( values == NULL ) {
436
goto get_dns_host_name;
439
ldapServiceName = ldap_charray2str( values, " " );
440
if ( ldapServiceName == NULL ) {
441
LDAP_FREE( mechlist );
442
LDAP_VFREE( values );
444
ld->ld_errno = LDAP_NO_MEMORY;
447
LDAP_VFREE( values );
451
values = ldap_get_values( ld, e, "dnsHostName" );
452
if ( values == NULL ) {
456
dnsHostName = ldap_charray2str( values, " " );
457
if ( dnsHostName == NULL ) {
458
LDAP_FREE( mechlist );
459
LDAP_FREE( ldapServiceName );
460
LDAP_VFREE( values );
462
ld->ld_errno = LDAP_NO_MEMORY;
465
LDAP_VFREE( values );
470
*pmechlist = mechlist;
471
*pldapServiceName = ldapServiceName;
472
*pdnsHostName = dnsHostName;
478
static int check_for_gss_spnego_support( LDAP *ld, const char *mechs_str )
481
char **mechs_list = NULL;
483
mechs_list = ldap_str2charray( mechs_str, " " );
484
if ( mechs_list == NULL ) {
485
ld->ld_errno = LDAP_NO_MEMORY;
489
rc = ldap_charray_inlist( mechs_list, "GSS-SPNEGO" );
490
ldap_charray_free( mechs_list );
492
ld->ld_errno = LDAP_STRONG_AUTH_NOT_SUPPORTED;
500
guess_service_principal(
502
const char *ldapServiceName,
503
const char *dnsHostName,
504
gss_name_t *principal )
506
gss_buffer_desc input_name;
507
/* GSS_KRB5_NT_PRINCIPAL_NAME */
508
gss_OID_desc nt_principal =
509
{10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"};
510
const char *host = ld->ld_defconn->lconn_server->lud_host;
511
OM_uint32 minor_status;
514
size_t svc_principal_size;
515
char *svc_principal = NULL;
516
const char *principal_fmt = NULL;
517
const char *str = NULL;
518
const char *givenstr = NULL;
519
const char *ignore = "not_defined_in_RFC4178@please_ignore";
520
int allow_remote = 0;
522
if (ldapServiceName) {
523
givenstr = strchr(ldapServiceName, ':');
524
if (givenstr && givenstr[1]) {
526
if (strcmp(givenstr, ignore) == 0) {
534
if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL ) {
538
if (allow_remote && givenstr) {
539
principal_fmt = "%s";
540
svc_principal_size = strlen(givenstr) + 1;
543
} else if (allow_remote && dnsHostName) {
544
principal_fmt = "ldap/%s";
545
svc_principal_size = strlen(dnsHostName) + strlen(principal_fmt);
549
principal_fmt = "ldap/%s";
550
svc_principal_size = strlen(host) + strlen(principal_fmt);
554
svc_principal = (char*) ldap_memalloc(svc_principal_size * sizeof(char));
555
if ( svc_principal == NULL ) {
556
ld->ld_errno = LDAP_NO_MEMORY;
560
ret = snprintf( svc_principal, svc_principal_size - 1, principal_fmt, str);
561
if (ret < 0 || (size_t)ret + 1 >= svc_principal_size) {
562
ld->ld_errno = LDAP_LOCAL_ERROR;
566
Debug( LDAP_DEBUG_TRACE, "principal for host[%s]: '%s'\n",
567
host, svc_principal, 0 );
569
input_name.value = svc_principal;
570
input_name.length = strlen( svc_principal );
572
gss_rc = gss_import_name( &minor_status, &input_name, &nt_principal, principal );
573
ldap_memfree( svc_principal );
574
if ( gss_rc != GSS_S_COMPLETE ) {
575
return map_gsserr2ldap( ld, GSS_C_NO_OID, gss_rc, minor_status );
581
void ldap_int_gssapi_close( LDAP *ld, LDAPConn *lc )
583
if ( lc && lc->lconn_gss_ctx ) {
584
OM_uint32 minor_status;
585
OM_uint32 ctx_flags = 0;
586
gss_ctx_id_t old_gss_ctx = GSS_C_NO_CONTEXT;
587
old_gss_ctx = (gss_ctx_id_t)lc->lconn_gss_ctx;
589
gss_inquire_context(&minor_status,
599
if (!( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT )) {
600
gss_delete_sec_context( &minor_status, &old_gss_ctx, GSS_C_NO_BUFFER );
602
lc->lconn_gss_ctx = GSS_C_NO_CONTEXT;
604
if (ctx_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG)) {
605
/* remove wrapping layer */
606
sb_sasl_gssapi_remove( lc->lconn_sb );
612
ldap_int_gssapi_setup(
615
gss_ctx_id_t gss_ctx)
617
OM_uint32 minor_status;
618
OM_uint32 ctx_flags = 0;
620
ldap_int_gssapi_close( ld, lc );
622
gss_inquire_context(&minor_status,
632
lc->lconn_gss_ctx = gss_ctx;
634
if (ctx_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG)) {
635
/* setup wrapping layer */
636
sb_sasl_gssapi_install( lc->lconn_sb, gss_ctx );
640
#ifdef LDAP_R_COMPILE
641
ldap_pvt_thread_mutex_t ldap_int_gssapi_mutex;
645
ldap_int_gss_spnego_bind_s( LDAP *ld )
649
OM_uint32 minor_status;
650
char *mechlist = NULL;
651
char *ldapServiceName = NULL;
652
char *dnsHostName = NULL;
653
gss_OID_set supported_mechs = GSS_C_NO_OID_SET;
654
int spnego_support = 0;
655
#define __SPNEGO_OID_LENGTH 6
656
#define __SPNEGO_OID "\053\006\001\005\005\002"
657
gss_OID_desc spnego_oid = {__SPNEGO_OID_LENGTH, __SPNEGO_OID};
658
gss_OID req_mech = GSS_C_NO_OID;
659
gss_OID ret_mech = GSS_C_NO_OID;
660
gss_ctx_id_t gss_ctx = GSS_C_NO_CONTEXT;
661
gss_name_t principal = GSS_C_NO_NAME;
664
gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER;
665
struct berval cred, *scred = NULL;
667
#ifdef LDAP_R_COMPILE
668
ldap_pvt_thread_mutex_lock( &ldap_int_gssapi_mutex );
671
/* get information from RootDSE entry */
672
rc = ldap_gssapi_get_rootdse_infos ( ld, &mechlist,
673
&ldapServiceName, &dnsHostName);
674
if ( rc != LDAP_SUCCESS ) {
678
/* check that the server supports GSS-SPNEGO */
679
rc = check_for_gss_spnego_support( ld, mechlist );
680
if ( rc != LDAP_SUCCESS ) {
684
/* prepare new gss_ctx_id_t */
685
rc = guess_service_principal( ld, ldapServiceName, dnsHostName, &principal );
686
if ( rc != LDAP_SUCCESS ) {
690
/* see if our gssapi library supports spnego */
691
gss_rc = gss_indicate_mechs( &minor_status, &supported_mechs );
692
if ( gss_rc != GSS_S_COMPLETE ) {
695
gss_rc = gss_test_oid_set_member( &minor_status,
696
&spnego_oid, supported_mechs, &spnego_support);
697
gss_release_oid_set( &minor_status, &supported_mechs);
698
if ( gss_rc != GSS_S_COMPLETE ) {
701
if ( spnego_support != 0 ) {
702
req_mech = &spnego_oid;
705
req_flags = ld->ld_options.gssapi_flags;
706
req_flags |= GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
709
* loop around gss_init_sec_context() and ldap_sasl_bind_s()
711
input_token.value = NULL;
712
input_token.length = 0;
713
gss_rc = gss_init_sec_context(&minor_status,
726
if ( gss_rc == GSS_S_COMPLETE ) {
727
rc = LDAP_INAPPROPRIATE_AUTH;
730
if ( gss_rc != GSS_S_CONTINUE_NEEDED ) {
734
cred.bv_val = (char *)output_token.value;
735
cred.bv_len = output_token.length;
736
rc = ldap_sasl_bind_s( ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred );
737
gss_release_buffer( &minor_status, &output_token );
738
if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
743
input_token.value = scred->bv_val;
744
input_token.length = scred->bv_len;
746
input_token.value = NULL;
747
input_token.length = 0;
750
gss_rc = gss_init_sec_context(&minor_status,
766
if ( gss_rc == GSS_S_COMPLETE ) {
767
gss_release_buffer( &minor_status, &output_token );
771
if ( gss_rc != GSS_S_CONTINUE_NEEDED ) {
776
ldap_int_gssapi_setup( ld, ld->ld_defconn, gss_ctx);
777
gss_ctx = GSS_C_NO_CONTEXT;
783
rc = map_gsserr2ldap( ld,
784
(ret_mech != GSS_C_NO_OID ? ret_mech : req_mech ),
785
gss_rc, minor_status );
787
#ifdef LDAP_R_COMPILE
788
ldap_pvt_thread_mutex_unlock( &ldap_int_gssapi_mutex );
790
LDAP_FREE( mechlist );
791
LDAP_FREE( ldapServiceName );
792
LDAP_FREE( dnsHostName );
793
gss_release_buffer( &minor_status, &output_token );
794
if ( gss_ctx != GSS_C_NO_CONTEXT ) {
795
gss_delete_sec_context( &minor_status, &gss_ctx, GSS_C_NO_BUFFER );
797
if ( principal != GSS_C_NO_NAME ) {
798
gss_release_name( &minor_status, &principal );
804
ldap_int_gssapi_config( struct ldapoptions *lo, int option, const char *arg )
812
} else if (strcasecmp(arg, "on") == 0) {
814
} else if (strcasecmp(arg, "yes") == 0) {
816
} else if (strcasecmp(arg, "true") == 0) {
821
lo->ldo_gssapi_flags |= GSS_C_INTEG_FLAG;
826
case LDAP_OPT_ENCRYPT:
829
} else if (strcasecmp(arg, "on") == 0) {
831
} else if (strcasecmp(arg, "yes") == 0) {
833
} else if (strcasecmp(arg, "true") == 0) {
838
lo->ldo_gssapi_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
843
case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
846
} else if (strcasecmp(arg, "on") == 0) {
848
} else if (strcasecmp(arg, "yes") == 0) {
850
} else if (strcasecmp(arg, "true") == 0) {
855
lo->ldo_gssapi_options |= LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL;
865
ldap_int_gssapi_get_option( LDAP *ld, int option, void *arg )
871
case LDAP_OPT_SSPI_FLAGS:
872
* (unsigned *) arg = (unsigned) ld->ld_options.gssapi_flags;
876
if ( ld->ld_options.gssapi_flags & GSS_C_INTEG_FLAG ) {
877
* (int *) arg = (int)-1;
879
* (int *) arg = (int)0;
883
case LDAP_OPT_ENCRYPT:
884
if ( ld->ld_options.gssapi_flags & GSS_C_CONF_FLAG ) {
885
* (int *) arg = (int)-1;
887
* (int *) arg = (int)0;
891
case LDAP_OPT_SASL_METHOD:
892
* (char **) arg = LDAP_STRDUP("GSS-SPNEGO");
895
case LDAP_OPT_SECURITY_CONTEXT:
896
if ( ld->ld_defconn && ld->ld_defconn->lconn_gss_ctx ) {
897
* (gss_ctx_id_t *) arg = (gss_ctx_id_t)ld->ld_defconn->lconn_gss_ctx;
899
* (gss_ctx_id_t *) arg = GSS_C_NO_CONTEXT;
903
case LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT:
904
if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT ) {
905
* (int *) arg = (int)-1;
907
* (int *) arg = (int)0;
911
case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
912
if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL ) {
913
* (int *) arg = (int)-1;
915
* (int *) arg = (int)0;
927
ldap_int_gssapi_set_option( LDAP *ld, int option, void *arg )
933
case LDAP_OPT_SSPI_FLAGS:
934
if ( arg != LDAP_OPT_OFF ) {
935
ld->ld_options.gssapi_flags = * (unsigned *)arg;
940
if ( arg != LDAP_OPT_OFF ) {
941
ld->ld_options.gssapi_flags |= GSS_C_INTEG_FLAG;
945
case LDAP_OPT_ENCRYPT:
946
if ( arg != LDAP_OPT_OFF ) {
947
ld->ld_options.gssapi_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
951
case LDAP_OPT_SASL_METHOD:
952
if ( arg != LDAP_OPT_OFF ) {
953
const char *m = (const char *)arg;
954
if ( strcmp( "GSS-SPNEGO", m ) != 0 ) {
955
/* we currently only support GSS-SPNEGO */
961
case LDAP_OPT_SECURITY_CONTEXT:
962
if ( arg != LDAP_OPT_OFF && ld->ld_defconn) {
963
ldap_int_gssapi_setup( ld, ld->ld_defconn,
968
case LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT:
969
if ( arg != LDAP_OPT_OFF ) {
970
ld->ld_options.ldo_gssapi_options |= LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT;
974
case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
975
if ( arg != LDAP_OPT_OFF ) {
976
ld->ld_options.ldo_gssapi_options |= LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL;
987
#else /* HAVE_GSSAPI */
988
#define ldap_int_gss_spnego_bind_s(ld) LDAP_NOT_SUPPORTED
989
#endif /* HAVE_GSSAPI */
995
LDAP_CONST char *creds )
997
return LDAP_NOT_SUPPORTED;
1003
LDAP_CONST char *dn,
1004
LDAP_CONST char *creds )
1007
return LDAP_NOT_SUPPORTED;
1010
if ( creds != NULL ) {
1011
return LDAP_NOT_SUPPORTED;
1014
return ldap_int_gss_spnego_bind_s(ld);