@@ -58,7 +58,21 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = STRING_LENGTH(gss_ntlm_o
5858
5959#if defined(GSS_SHIM )
6060
61- #define FOR_ALL_GSS_FUNCTIONS \
61+ #if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
62+
63+ #define FOR_ALL_OPTIONAL_GSS_FUNCTIONS \
64+ PER_FUNCTION_BLOCK(gss_set_cred_option) \
65+ PER_FUNCTION_BLOCK(GSS_KRB5_CRED_NO_CI_FLAGS_X)
66+
67+ #define GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE (gss_set_cred_option_ptr != NULL && GSS_KRB5_CRED_NO_CI_FLAGS_X_ptr != NULL)
68+
69+ #else
70+
71+ #define FOR_ALL_OPTIONAL_GSS_FUNCTIONS
72+
73+ #endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
74+
75+ #define FOR_ALL_REQUIRED_GSS_FUNCTIONS \
6276 PER_FUNCTION_BLOCK(gss_accept_sec_context) \
6377 PER_FUNCTION_BLOCK(gss_acquire_cred) \
6478 PER_FUNCTION_BLOCK(gss_acquire_cred_with_password) \
@@ -78,14 +92,11 @@ static gss_OID_desc gss_mech_ntlm_OID_desc = {.length = STRING_LENGTH(gss_ntlm_o
7892 PER_FUNCTION_BLOCK(gss_unwrap) \
7993 PER_FUNCTION_BLOCK(gss_wrap) \
8094 PER_FUNCTION_BLOCK(GSS_C_NT_USER_NAME) \
81- PER_FUNCTION_BLOCK(GSS_C_NT_HOSTBASED_SERVICE)
82-
83- #if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
95+ PER_FUNCTION_BLOCK(GSS_C_NT_HOSTBASED_SERVICE) \
8496
85- #define FOR_ALL_GSS_FUNCTIONS FOR_ALL_GSS_FUNCTIONS \
86- PER_FUNCTION_BLOCK(gss_set_cred_option)
87-
88- #endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
97+ #define FOR_ALL_GSS_FUNCTIONS \
98+ FOR_ALL_REQUIRED_GSS_FUNCTIONS \
99+ FOR_ALL_OPTIONAL_GSS_FUNCTIONS
89100
90101// define indirection pointers for all functions, like
91102// static TYPEOF(gss_accept_sec_context)* gss_accept_sec_context_ptr;
@@ -118,6 +129,7 @@ static void* volatile s_gssLib = NULL;
118129
119130#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
120131#define gss_set_cred_option (...) gss_set_cred_option_ptr(__VA_ARGS__)
132+ #define GSS_KRB5_CRED_NO_CI_FLAGS_X (*GSS_KRB5_CRED_NO_CI_FLAGS_X_ptr)
121133#endif //HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
122134
123135
@@ -138,19 +150,27 @@ static int32_t ensure_gss_shim_initialized()
138150 dlclose (lib );
139151 }
140152
141- // initialize indirection pointers for all functions, like:
153+ // initialize indirection pointers for all required functions, like:
142154 // gss_accept_sec_context_ptr = (TYPEOF(gss_accept_sec_context)*)dlsym(s_gssLib, "gss_accept_sec_context");
143155 // if (gss_accept_sec_context_ptr == NULL) { fprintf(stderr, "Cannot get symbol %s from %s \nError: %s\n", "gss_accept_sec_context", gss_lib_name, dlerror()); return -1; }
144156#define PER_FUNCTION_BLOCK (fn ) \
145157 fn##_ptr = (TYPEOF(fn)*)dlsym(s_gssLib, #fn); \
146158 if (fn##_ptr == NULL) { fprintf(stderr, "Cannot get symbol " #fn " from %s \nError: %s\n", gss_lib_name, dlerror()); return -1; }
147-
148- FOR_ALL_GSS_FUNCTIONS
159+ FOR_ALL_REQUIRED_GSS_FUNCTIONS
160+ #undef PER_FUNCTION_BLOCK
161+ // for optional functions skip the error check
162+ #define PER_FUNCTION_BLOCK (fn ) \
163+ fn##_ptr = (TYPEOF(fn)*)dlsym(s_gssLib, #fn);
164+ FOR_ALL_OPTIONAL_GSS_FUNCTIONS
149165#undef PER_FUNCTION_BLOCK
150166
151167 return 0 ;
152168}
153169
170+ #else // GSS_SHIM
171+
172+ #define GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE 1
173+
154174#endif // GSS_SHIM
155175
156176// transfers ownership of the underlying data from gssBuffer to PAL_GssBuffer
@@ -183,10 +203,20 @@ static uint32_t AcquireCredSpNego(uint32_t* minorStatus,
183203
184204 // call gss_set_cred_option with GSS_KRB5_CRED_NO_CI_FLAGS_X to support Kerberos Sign Only option from *nix client against a windows server
185205#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
186- if (majorStatus == GSS_S_COMPLETE )
206+ if (majorStatus == GSS_S_COMPLETE && GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE )
187207 {
188208 GssBuffer emptyBuffer = GSS_C_EMPTY_BUFFER ;
189- majorStatus = gss_set_cred_option (minorStatus , outputCredHandle , GSS_KRB5_CRED_NO_CI_FLAGS_X , & emptyBuffer );
209+ uint32_t tempMinorStatus ;
210+ majorStatus = gss_set_cred_option (& tempMinorStatus , outputCredHandle , GSS_KRB5_CRED_NO_CI_FLAGS_X , & emptyBuffer );
211+ if (majorStatus == GSS_S_UNAVAILABLE || majorStatus == GSS_S_COMPLETE )
212+ {
213+ // preserve the original majorStatus/minorStatus from gss_acquire_cred
214+ majorStatus = GSS_S_COMPLETE ;
215+ }
216+ else
217+ {
218+ * minorStatus = tempMinorStatus ;
219+ }
190220 }
191221#endif
192222
@@ -606,10 +636,20 @@ static uint32_t AcquireCredWithPassword(uint32_t* minorStatus,
606636
607637 // call gss_set_cred_option with GSS_KRB5_CRED_NO_CI_FLAGS_X to support Kerberos Sign Only option from *nix client against a windows server
608638#if HAVE_GSS_KRB5_CRED_NO_CI_FLAGS_X
609- if (majorStatus == GSS_S_COMPLETE )
639+ if (! isNtlm && majorStatus == GSS_S_COMPLETE && GSS_KRB5_CRED_NO_CI_FLAGS_X_AVAILABLE )
610640 {
611641 GssBuffer emptyBuffer = GSS_C_EMPTY_BUFFER ;
612- majorStatus = gss_set_cred_option (minorStatus , outputCredHandle , GSS_KRB5_CRED_NO_CI_FLAGS_X , & emptyBuffer );
642+ uint32_t tempMinorStatus ;
643+ majorStatus = gss_set_cred_option (& tempMinorStatus , outputCredHandle , GSS_KRB5_CRED_NO_CI_FLAGS_X , & emptyBuffer );
644+ if (majorStatus == GSS_S_UNAVAILABLE || majorStatus == GSS_S_COMPLETE )
645+ {
646+ // preserve the original majorStatus/minorStatus from gss_acquire_cred_with_password
647+ majorStatus = GSS_S_COMPLETE ;
648+ }
649+ else
650+ {
651+ * minorStatus = tempMinorStatus ;
652+ }
613653 }
614654#endif
615655
0 commit comments