2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2007 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;
251 wrapped.value = src->buf_base + 4;
252 wrapped.length = src->buf_end - 4;
254 gss_inquire_context(&minor_status,
264 if (ctx_flags & (GSS_C_CONF_FLAG)) {
268 gss_rc = gss_unwrap(&minor_status, gss_ctx,
269 &wrapped, &unwrapped,
270 &conf_state, GSS_C_QOP_DEFAULT);
271 if ( gss_rc != GSS_S_COMPLETE ) {
273 ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
274 "sb_sasl_gssapi_decode: failed to decode packet: %s\n",
275 gsserrstr( msg, sizeof(msg), ctx_mech, gss_rc, minor_status ) );
279 if ( conf_req_flag && conf_state == 0 ) {
280 ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
281 "sb_sasl_gssapi_encode: GSS_C_CONF_FLAG was ignored by our peer\n" );
285 /* Grow the packet buffer if neccessary */
286 if ( dst->buf_size < unwrapped.length &&
287 ber_pvt_sb_grow_buffer( dst, unwrapped.length ) < 0 )
289 ber_log_printf( LDAP_DEBUG_ANY, p->sbiod->sbiod_sb->sb_debug,
290 "sb_sasl_gssapi_decode: failed to grow the buffer to %lu bytes\n",
295 dst->buf_end = unwrapped.length;
297 b = (unsigned char *)dst->buf_base;
299 /* copy the wrapped blob to the right location */
300 memcpy(b, unwrapped.value, unwrapped.length);
302 gss_release_buffer(&minor_status, &unwrapped);
308 sb_sasl_gssapi_reset_buf(
309 struct sb_sasl_generic_data *p,
312 ber_pvt_sb_buf_destroy( buf );
316 sb_sasl_gssapi_fini( struct sb_sasl_generic_data *p )
320 static const struct sb_sasl_generic_ops sb_sasl_gssapi_ops = {
322 sb_sasl_gssapi_encode,
323 sb_sasl_gssapi_decode,
324 sb_sasl_gssapi_reset_buf,
329 sb_sasl_gssapi_install(
331 gss_ctx_id_t gss_ctx )
333 struct sb_sasl_generic_install install_arg;
335 install_arg.ops = &sb_sasl_gssapi_ops;
336 install_arg.ops_private = gss_ctx;
338 return ldap_pvt_sasl_generic_install( sb, &install_arg );
342 sb_sasl_gssapi_remove( Sockbuf *sb )
344 ldap_pvt_sasl_generic_remove( sb );
352 OM_uint32 minor_status )
355 OM_uint32 msg_ctx = 0;
358 Debug( LDAP_DEBUG_ANY, "%s\n",
359 gsserrstr( msg, sizeof(msg), mech, gss_rc, minor_status ),
362 if (gss_rc == GSS_S_COMPLETE) {
363 ld->ld_errno = LDAP_SUCCESS;
364 } else if (GSS_CALLING_ERROR(gss_rc)) {
365 ld->ld_errno = LDAP_LOCAL_ERROR;
366 } else if (GSS_ROUTINE_ERROR(gss_rc)) {
367 ld->ld_errno = LDAP_INAPPROPRIATE_AUTH;
368 } else if (gss_rc == GSS_S_CONTINUE_NEEDED) {
369 ld->ld_errno = LDAP_SASL_BIND_IN_PROGRESS;
370 } else if (GSS_SUPPLEMENTARY_INFO(gss_rc)) {
371 ld->ld_errno = LDAP_AUTH_UNKNOWN;
372 } else if (GSS_ERROR(gss_rc)) {
373 ld->ld_errno = LDAP_AUTH_UNKNOWN;
375 ld->ld_errno = LDAP_OTHER;
383 ldap_gssapi_get_rootdse_infos (
386 char **pldapServiceName,
387 char **pdnsHostName )
389 /* we need to query the server for supported mechs anyway */
390 LDAPMessage *res, *e;
392 "supportedSASLMechanisms",
397 char **values, *mechlist;
398 char *ldapServiceName = NULL;
399 char *dnsHostName = NULL;
402 Debug( LDAP_DEBUG_TRACE, "ldap_gssapi_get_rootdse_infos\n", 0, 0, 0 );
404 rc = ldap_search_s( ld, "", LDAP_SCOPE_BASE,
405 NULL, attrs, 0, &res );
407 if ( rc != LDAP_SUCCESS ) {
411 e = ldap_first_entry( ld, res );
414 if ( ld->ld_errno == LDAP_SUCCESS ) {
415 ld->ld_errno = LDAP_NO_SUCH_OBJECT;
420 values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
421 if ( values == NULL ) {
423 ld->ld_errno = LDAP_NO_SUCH_ATTRIBUTE;
427 mechlist = ldap_charray2str( values, " " );
428 if ( mechlist == NULL ) {
429 LDAP_VFREE( values );
431 ld->ld_errno = LDAP_NO_MEMORY;
435 LDAP_VFREE( values );
437 values = ldap_get_values( ld, e, "ldapServiceName" );
438 if ( values == NULL ) {
439 goto get_dns_host_name;
442 ldapServiceName = ldap_charray2str( values, " " );
443 if ( ldapServiceName == NULL ) {
444 LDAP_FREE( mechlist );
445 LDAP_VFREE( values );
447 ld->ld_errno = LDAP_NO_MEMORY;
450 LDAP_VFREE( values );
454 values = ldap_get_values( ld, e, "dnsHostName" );
455 if ( values == NULL ) {
459 dnsHostName = ldap_charray2str( values, " " );
460 if ( dnsHostName == NULL ) {
461 LDAP_FREE( mechlist );
462 LDAP_FREE( ldapServiceName );
463 LDAP_VFREE( values );
465 ld->ld_errno = LDAP_NO_MEMORY;
468 LDAP_VFREE( values );
473 *pmechlist = mechlist;
474 *pldapServiceName = ldapServiceName;
475 *pdnsHostName = dnsHostName;
481 static int check_for_gss_spnego_support( LDAP *ld, const char *mechs_str )
484 char **mechs_list = NULL;
486 mechs_list = ldap_str2charray( mechs_str, " " );
487 if ( mechs_list == NULL ) {
488 ld->ld_errno = LDAP_NO_MEMORY;
492 rc = ldap_charray_inlist( mechs_list, "GSS-SPNEGO" );
493 ldap_charray_free( mechs_list );
495 ld->ld_errno = LDAP_STRONG_AUTH_NOT_SUPPORTED;
503 guess_service_principal(
505 const char *ldapServiceName,
506 const char *dnsHostName,
507 gss_name_t *principal )
509 gss_buffer_desc input_name;
510 /* GSS_KRB5_NT_PRINCIPAL_NAME */
511 gss_OID_desc nt_principal =
512 {10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01"};
513 const char *host = ld->ld_defconn->lconn_server->lud_host;
514 OM_uint32 minor_status;
517 size_t svc_principal_size;
518 char *svc_principal = NULL;
519 const char *principal_fmt = NULL;
520 const char *str = NULL;
521 const char *givenstr = NULL;
522 const char *ignore = "not_defined_in_RFC4178@please_ignore";
523 int allow_remote = 0;
525 if (ldapServiceName) {
526 givenstr = strchr(ldapServiceName, ':');
527 if (givenstr && givenstr[1]) {
529 if (strcmp(givenstr, ignore) == 0) {
537 if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL ) {
541 if (allow_remote && givenstr) {
542 principal_fmt = "%s";
543 svc_principal_size = strlen(givenstr) + 1;
546 } else if (allow_remote && dnsHostName) {
547 principal_fmt = "ldap/%s";
548 svc_principal_size = strlen(dnsHostName) + strlen(principal_fmt);
552 principal_fmt = "ldap/%s";
553 svc_principal_size = strlen(host) + strlen(principal_fmt);
557 svc_principal = (char*) ldap_memalloc(svc_principal_size * sizeof(char));
559 ld->ld_errno = LDAP_NO_MEMORY;
563 ret = snprintf( svc_principal, svc_principal_size - 1, principal_fmt, str);
564 if (ret < 0 || ret >= svc_principal_size - 1) {
565 ld->ld_errno = LDAP_LOCAL_ERROR;
569 Debug( LDAP_DEBUG_TRACE, "principal for host[%s]: '%s'\n",
570 host, svc_principal, 0 );
572 input_name.value = svc_principal;
573 input_name.length = strlen( svc_principal );
575 gss_rc = gss_import_name( &minor_status, &input_name, &nt_principal, principal );
576 ldap_memfree( svc_principal );
577 if ( gss_rc != GSS_S_COMPLETE ) {
578 return map_gsserr2ldap( ld, GSS_C_NO_OID, gss_rc, minor_status );
584 void ldap_int_gssapi_close( LDAP *ld, LDAPConn *lc )
586 if ( lc && lc->lconn_gss_ctx ) {
587 OM_uint32 minor_status;
588 OM_uint32 ctx_flags = 0;
589 gss_ctx_id_t old_gss_ctx = GSS_C_NO_CONTEXT;
590 old_gss_ctx = (gss_ctx_id_t)lc->lconn_gss_ctx;
592 gss_inquire_context(&minor_status,
602 if (!( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT )) {
603 gss_delete_sec_context( &minor_status, &old_gss_ctx, GSS_C_NO_BUFFER );
605 lc->lconn_gss_ctx = GSS_C_NO_CONTEXT;
607 if (ctx_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG)) {
608 /* remove wrapping layer */
609 sb_sasl_gssapi_remove( lc->lconn_sb );
615 ldap_int_gssapi_setup(
618 gss_ctx_id_t gss_ctx)
620 OM_uint32 minor_status;
621 OM_uint32 ctx_flags = 0;
623 ldap_int_gssapi_close( ld, lc );
625 gss_inquire_context(&minor_status,
635 lc->lconn_gss_ctx = gss_ctx;
637 if (ctx_flags & (GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG)) {
638 /* setup wrapping layer */
639 sb_sasl_gssapi_install( lc->lconn_sb, gss_ctx );
643 #ifdef LDAP_R_COMPILE
644 ldap_pvt_thread_mutex_t ldap_int_gssapi_mutex;
648 ldap_int_gss_spnego_bind_s( LDAP *ld )
652 OM_uint32 minor_status;
653 char *mechlist = NULL;
654 char *ldapServiceName = NULL;
655 char *dnsHostName = NULL;
656 gss_OID_set supported_mechs = GSS_C_NO_OID_SET;
657 int spnego_support = 0;
658 #define __SPNEGO_OID_LENGTH 6
659 #define __SPNEGO_OID "\053\006\001\005\005\002"
660 gss_OID_desc spnego_oid = {__SPNEGO_OID_LENGTH, __SPNEGO_OID};
661 gss_OID req_mech = GSS_C_NO_OID;
662 gss_OID ret_mech = GSS_C_NO_OID;
663 gss_ctx_id_t gss_ctx = GSS_C_NO_CONTEXT;
664 gss_name_t principal = GSS_C_NO_NAME;
667 gss_buffer_desc input_token, output_token = GSS_C_EMPTY_BUFFER;
668 struct berval cred, *scred = NULL;
670 #ifdef LDAP_R_COMPILE
671 ldap_pvt_thread_mutex_lock( &ldap_int_gssapi_mutex );
674 /* get information from RootDSE entry */
675 rc = ldap_gssapi_get_rootdse_infos ( ld, &mechlist,
676 &ldapServiceName, &dnsHostName);
677 if ( rc != LDAP_SUCCESS ) {
681 /* check that the server supports GSS-SPNEGO */
682 rc = check_for_gss_spnego_support( ld, mechlist );
683 if ( rc != LDAP_SUCCESS ) {
687 /* prepare new gss_ctx_id_t */
688 rc = guess_service_principal( ld, ldapServiceName, dnsHostName, &principal );
689 if ( rc != LDAP_SUCCESS ) {
693 /* see if our gssapi library supports spnego */
694 gss_rc = gss_indicate_mechs( &minor_status, &supported_mechs );
695 if ( gss_rc != GSS_S_COMPLETE ) {
698 gss_rc = gss_test_oid_set_member( &minor_status,
699 &spnego_oid, supported_mechs, &spnego_support);
700 gss_release_oid_set( &minor_status, &supported_mechs);
701 if ( gss_rc != GSS_S_COMPLETE ) {
704 if ( spnego_support != 0 ) {
705 req_mech = &spnego_oid;
708 req_flags = ld->ld_options.gssapi_flags;
709 req_flags |= GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
712 * loop around gss_init_sec_context() and ldap_sasl_bind_s()
714 input_token.value = NULL;
715 input_token.length = 0;
716 gss_rc = gss_init_sec_context(&minor_status,
729 if ( gss_rc == GSS_S_COMPLETE ) {
730 rc = LDAP_INAPPROPRIATE_AUTH;
733 if ( gss_rc != GSS_S_CONTINUE_NEEDED ) {
737 cred.bv_val = (char *)output_token.value;
738 cred.bv_len = output_token.length;
739 rc = ldap_sasl_bind_s( ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred );
740 gss_release_buffer( &minor_status, &output_token );
741 if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
746 input_token.value = scred->bv_val;
747 input_token.length = scred->bv_len;
749 input_token.value = NULL;
750 input_token.length = 0;
753 gss_rc = gss_init_sec_context(&minor_status,
769 if ( gss_rc == GSS_S_COMPLETE ) {
770 gss_release_buffer( &minor_status, &output_token );
774 if ( gss_rc != GSS_S_CONTINUE_NEEDED ) {
779 ldap_int_gssapi_setup( ld, ld->ld_defconn, gss_ctx);
780 gss_ctx = GSS_C_NO_CONTEXT;
786 rc = map_gsserr2ldap( ld,
787 (ret_mech != GSS_C_NO_OID ? ret_mech : req_mech ),
788 gss_rc, minor_status );
790 #ifdef LDAP_R_COMPILE
791 ldap_pvt_thread_mutex_unlock( &ldap_int_gssapi_mutex );
793 LDAP_FREE( mechlist );
794 LDAP_FREE( ldapServiceName );
795 LDAP_FREE( dnsHostName );
796 gss_release_buffer( &minor_status, &output_token );
797 if ( gss_ctx != GSS_C_NO_CONTEXT ) {
798 gss_delete_sec_context( &minor_status, &gss_ctx, GSS_C_NO_BUFFER );
800 if ( principal != GSS_C_NO_NAME ) {
801 gss_release_name( &minor_status, &principal );
807 ldap_int_gssapi_config( struct ldapoptions *lo, int option, const char *arg )
815 } else if (strcasecmp(arg, "on") == 0) {
817 } else if (strcasecmp(arg, "yes") == 0) {
819 } else if (strcasecmp(arg, "true") == 0) {
824 lo->ldo_gssapi_flags |= GSS_C_INTEG_FLAG;
829 case LDAP_OPT_ENCRYPT:
832 } else if (strcasecmp(arg, "on") == 0) {
834 } else if (strcasecmp(arg, "yes") == 0) {
836 } else if (strcasecmp(arg, "true") == 0) {
841 lo->ldo_gssapi_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
846 case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
849 } else if (strcasecmp(arg, "on") == 0) {
851 } else if (strcasecmp(arg, "yes") == 0) {
853 } else if (strcasecmp(arg, "true") == 0) {
858 lo->ldo_gssapi_options |= LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL;
868 ldap_int_gssapi_get_option( LDAP *ld, int option, void *arg )
874 case LDAP_OPT_SSPI_FLAGS:
875 * (unsigned *) arg = (unsigned) ld->ld_options.gssapi_flags;
879 if ( ld->ld_options.gssapi_flags & GSS_C_INTEG_FLAG ) {
880 * (int *) arg = (int)-1;
882 * (int *) arg = (int)0;
886 case LDAP_OPT_ENCRYPT:
887 if ( ld->ld_options.gssapi_flags & GSS_C_CONF_FLAG ) {
888 * (int *) arg = (int)-1;
890 * (int *) arg = (int)0;
894 case LDAP_OPT_SASL_METHOD:
895 * (char **) arg = LDAP_STRDUP("GSS-SPNEGO");
898 case LDAP_OPT_SECURITY_CONTEXT:
899 if ( ld->ld_defconn && ld->ld_defconn->lconn_gss_ctx ) {
900 * (gss_ctx_id_t *) arg = (gss_ctx_id_t)ld->ld_defconn->lconn_gss_ctx;
902 * (gss_ctx_id_t *) arg = GSS_C_NO_CONTEXT;
906 case LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT:
907 if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT ) {
908 * (int *) arg = (int)-1;
910 * (int *) arg = (int)0;
914 case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
915 if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL ) {
916 * (int *) arg = (int)-1;
918 * (int *) arg = (int)0;
930 ldap_int_gssapi_set_option( LDAP *ld, int option, void *arg )
936 case LDAP_OPT_SSPI_FLAGS:
937 if ( arg != LDAP_OPT_OFF ) {
938 ld->ld_options.gssapi_flags = * (unsigned *)arg;
943 if ( arg != LDAP_OPT_OFF ) {
944 ld->ld_options.gssapi_flags |= GSS_C_INTEG_FLAG;
948 case LDAP_OPT_ENCRYPT:
949 if ( arg != LDAP_OPT_OFF ) {
950 ld->ld_options.gssapi_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
954 case LDAP_OPT_SASL_METHOD:
955 if ( arg != LDAP_OPT_OFF ) {
956 const char *m = (const char *)arg;
957 if ( strcmp( "GSS-SPNEGO", m ) != 0 ) {
958 /* we currently only support GSS-SPNEGO */
964 case LDAP_OPT_SECURITY_CONTEXT:
965 if ( arg != LDAP_OPT_OFF && ld->ld_defconn) {
966 ldap_int_gssapi_setup( ld, ld->ld_defconn,
971 case LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT:
972 if ( arg != LDAP_OPT_OFF ) {
973 ld->ld_options.ldo_gssapi_options |= LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT;
977 case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
978 if ( arg != LDAP_OPT_OFF ) {
979 ld->ld_options.ldo_gssapi_options |= LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL;
990 #else /* HAVE_GSSAPI */
991 #define ldap_int_gss_spnego_bind_s(ld) LDAP_NOT_SUPPORTED
992 #endif /* HAVE_GSSAPI */
998 LDAP_CONST char *creds )
999 { return LDAP_NOT_SUPPORTED; }
1004 LDAP_CONST char *dn,
1005 LDAP_CONST char *creds )
1008 return LDAP_NOT_SUPPORTED;
1011 if ( creds != NULL ) {
1012 return LDAP_NOT_SUPPORTED;
1015 return ldap_int_gss_spnego_bind_s(ld);