2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 1998-2012 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 = STRLENOF("ldap/") + strlen(dnsHostName) + 1;
549 principal_fmt = "ldap/%s";
550 svc_principal_size = STRLENOF("ldap/") + strlen(host) + 1;
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, principal_fmt, str );
561 if (ret < 0 || (size_t)ret >= 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 = (size_t)ret;
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 LDAP_MUTEX_LOCK( &ldap_int_gssapi_mutex );
669 /* get information from RootDSE entry */
670 rc = ldap_gssapi_get_rootdse_infos ( ld, &mechlist,
671 &ldapServiceName, &dnsHostName);
672 if ( rc != LDAP_SUCCESS ) {
676 /* check that the server supports GSS-SPNEGO */
677 rc = check_for_gss_spnego_support( ld, mechlist );
678 if ( rc != LDAP_SUCCESS ) {
682 /* prepare new gss_ctx_id_t */
683 rc = guess_service_principal( ld, ldapServiceName, dnsHostName, &principal );
684 if ( rc != LDAP_SUCCESS ) {
688 /* see if our gssapi library supports spnego */
689 gss_rc = gss_indicate_mechs( &minor_status, &supported_mechs );
690 if ( gss_rc != GSS_S_COMPLETE ) {
693 gss_rc = gss_test_oid_set_member( &minor_status,
694 &spnego_oid, supported_mechs, &spnego_support);
695 gss_release_oid_set( &minor_status, &supported_mechs);
696 if ( gss_rc != GSS_S_COMPLETE ) {
699 if ( spnego_support != 0 ) {
700 req_mech = &spnego_oid;
703 req_flags = ld->ld_options.ldo_gssapi_flags;
704 req_flags |= GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
707 * loop around gss_init_sec_context() and ldap_sasl_bind_s()
709 input_token.value = NULL;
710 input_token.length = 0;
711 gss_rc = gss_init_sec_context(&minor_status,
724 if ( gss_rc == GSS_S_COMPLETE ) {
725 rc = LDAP_INAPPROPRIATE_AUTH;
728 if ( gss_rc != GSS_S_CONTINUE_NEEDED ) {
732 cred.bv_val = (char *)output_token.value;
733 cred.bv_len = output_token.length;
734 rc = ldap_sasl_bind_s( ld, NULL, "GSS-SPNEGO", &cred, NULL, NULL, &scred );
735 gss_release_buffer( &minor_status, &output_token );
736 if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
741 input_token.value = scred->bv_val;
742 input_token.length = scred->bv_len;
744 input_token.value = NULL;
745 input_token.length = 0;
748 gss_rc = gss_init_sec_context(&minor_status,
764 if ( gss_rc == GSS_S_COMPLETE ) {
765 gss_release_buffer( &minor_status, &output_token );
769 if ( gss_rc != GSS_S_CONTINUE_NEEDED ) {
774 ldap_int_gssapi_setup( ld, ld->ld_defconn, gss_ctx);
775 gss_ctx = GSS_C_NO_CONTEXT;
781 rc = map_gsserr2ldap( ld,
782 (ret_mech != GSS_C_NO_OID ? ret_mech : req_mech ),
783 gss_rc, minor_status );
785 LDAP_MUTEX_UNLOCK( &ldap_int_gssapi_mutex );
786 LDAP_FREE( mechlist );
787 LDAP_FREE( ldapServiceName );
788 LDAP_FREE( dnsHostName );
789 gss_release_buffer( &minor_status, &output_token );
790 if ( gss_ctx != GSS_C_NO_CONTEXT ) {
791 gss_delete_sec_context( &minor_status, &gss_ctx, GSS_C_NO_BUFFER );
793 if ( principal != GSS_C_NO_NAME ) {
794 gss_release_name( &minor_status, &principal );
800 ldap_int_gssapi_config( struct ldapoptions *lo, int option, const char *arg )
808 } else if (strcasecmp(arg, "on") == 0) {
810 } else if (strcasecmp(arg, "yes") == 0) {
812 } else if (strcasecmp(arg, "true") == 0) {
817 lo->ldo_gssapi_flags |= GSS_C_INTEG_FLAG;
822 case LDAP_OPT_ENCRYPT:
825 } else if (strcasecmp(arg, "on") == 0) {
827 } else if (strcasecmp(arg, "yes") == 0) {
829 } else if (strcasecmp(arg, "true") == 0) {
834 lo->ldo_gssapi_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
839 case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
842 } else if (strcasecmp(arg, "on") == 0) {
844 } else if (strcasecmp(arg, "yes") == 0) {
846 } else if (strcasecmp(arg, "true") == 0) {
851 lo->ldo_gssapi_options |= LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL;
861 ldap_int_gssapi_get_option( LDAP *ld, int option, void *arg )
867 case LDAP_OPT_SSPI_FLAGS:
868 * (unsigned *) arg = (unsigned) ld->ld_options.ldo_gssapi_flags;
872 if ( ld->ld_options.ldo_gssapi_flags & GSS_C_INTEG_FLAG ) {
873 * (int *) arg = (int)-1;
875 * (int *) arg = (int)0;
879 case LDAP_OPT_ENCRYPT:
880 if ( ld->ld_options.ldo_gssapi_flags & GSS_C_CONF_FLAG ) {
881 * (int *) arg = (int)-1;
883 * (int *) arg = (int)0;
887 case LDAP_OPT_SASL_METHOD:
888 * (char **) arg = LDAP_STRDUP("GSS-SPNEGO");
891 case LDAP_OPT_SECURITY_CONTEXT:
892 if ( ld->ld_defconn && ld->ld_defconn->lconn_gss_ctx ) {
893 * (gss_ctx_id_t *) arg = (gss_ctx_id_t)ld->ld_defconn->lconn_gss_ctx;
895 * (gss_ctx_id_t *) arg = GSS_C_NO_CONTEXT;
899 case LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT:
900 if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT ) {
901 * (int *) arg = (int)-1;
903 * (int *) arg = (int)0;
907 case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
908 if ( ld->ld_options.ldo_gssapi_options & LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL ) {
909 * (int *) arg = (int)-1;
911 * (int *) arg = (int)0;
923 ldap_int_gssapi_set_option( LDAP *ld, int option, void *arg )
929 case LDAP_OPT_SSPI_FLAGS:
930 if ( arg != LDAP_OPT_OFF ) {
931 ld->ld_options.ldo_gssapi_flags = * (unsigned *)arg;
936 if ( arg != LDAP_OPT_OFF ) {
937 ld->ld_options.ldo_gssapi_flags |= GSS_C_INTEG_FLAG;
941 case LDAP_OPT_ENCRYPT:
942 if ( arg != LDAP_OPT_OFF ) {
943 ld->ld_options.ldo_gssapi_flags |= GSS_C_INTEG_FLAG | GSS_C_CONF_FLAG;
947 case LDAP_OPT_SASL_METHOD:
948 if ( arg != LDAP_OPT_OFF ) {
949 const char *m = (const char *)arg;
950 if ( strcmp( "GSS-SPNEGO", m ) != 0 ) {
951 /* we currently only support GSS-SPNEGO */
957 case LDAP_OPT_SECURITY_CONTEXT:
958 if ( arg != LDAP_OPT_OFF && ld->ld_defconn) {
959 ldap_int_gssapi_setup( ld, ld->ld_defconn,
964 case LDAP_OPT_X_GSSAPI_DO_NOT_FREE_CONTEXT:
965 if ( arg != LDAP_OPT_OFF ) {
966 ld->ld_options.ldo_gssapi_options |= LDAP_GSSAPI_OPT_DO_NOT_FREE_GSS_CONTEXT;
970 case LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL:
971 if ( arg != LDAP_OPT_OFF ) {
972 ld->ld_options.ldo_gssapi_options |= LDAP_GSSAPI_OPT_ALLOW_REMOTE_PRINCIPAL;
983 #else /* HAVE_GSSAPI */
984 #define ldap_int_gss_spnego_bind_s(ld) LDAP_NOT_SUPPORTED
985 #endif /* HAVE_GSSAPI */
991 LDAP_CONST char *creds )
993 return LDAP_NOT_SUPPORTED;
1000 LDAP_CONST char *creds )
1003 return LDAP_NOT_SUPPORTED;
1006 if ( creds != NULL ) {
1007 return LDAP_NOT_SUPPORTED;
1010 return ldap_int_gss_spnego_bind_s(ld);