GNOME Bugzilla – Bug 312806
e-d-s configure fails to properly detect kerberos 5
Last modified: 2009-10-15 03:50:51 UTC
Version details: 1.3.6.1 Distribution/Version: Yellow Dog Linux 4.0.1 The e-d-s configuration file fails to properly detect KERBEROS 5: configure --with-krb5=/usr ==> KERBEROS 5 not found The source of the problem is test code within configure that compiles, but segfaults when run [gcc-3.3.3 & gcc-4.0.1 on PPC]: % cat krb5_test.c /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char krb5_init_context (); int main () { krb5_init_context (); ; return 0; } % gcc -g -o krb5_test krb5_test.c -lkrb5 -lk5crypto -lcom_err -lgssapi_krb5 % ./krb5_test ==> segfault The fix is: /* Override any gcc2 internal prototype to avoid an error. */ #ifdef __cplusplus extern "C" #endif /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ char krb5_init_context (); struct _krb5_context; typedef struct _krb5_context * krb5_context; int main () { krb5_context context; krb5_init_context (&context); ; return 0; }
can you pass NULL instead? the typedef is pointless, and doesn't actually do what you expect it to anyway, it means you just pass the address of a single pointer, not a structure.
What we are basically attempting to do is probe a library to see if a function, krb5_init_context(), has been defined. The "correct" thing to do, based upon the actual declaration of that function, is: #include <krb5.h> int main () { krb5_context context; krb5_init_context (&context); ; return 0; } Anything else is slight-of-hand to trick GCC. krb5_init_text() needs to be passed a valid address to avoid a segfault. Consider: char krb5_init_context(); int main () { char not_zed; krb5_init_context (¬_zed); ; return 0; } This code also "works", meaning it both compiles and runs. Your choice... -Joseph
but the code is being executed. it is crashing because it isn't getting an argument it should. if you're passing a valid pointer to the code, but pointing to a resource of the wrong size, then it is exactly the same problem, it is just by luck that it isn't crashing.
Agreed... As I said... Using anything other than the "correct" solution that includes <krb5.h> is a slight-of-hand attempt to fool the compiler. That's not a good idea. Why not use the "correct" test? -Joseph
Took a look at the krb5 source code: [from src/lib/krb5/krb/init_ctx.c] krb5_error_code KRB5_CALLCONV krb5_init_context(krb5_context *context) { return init_common (context, FALSE); } context is an out-value, which is why the slight-of-hand version of the test code worked. It would have certainly failed if you attempted to do anything with that out-value. -Joseph -Joseph
thats why i asked, can you pass NULL... if not, then char context[some arbitrarily large-enough value] will be safer than char context;
Why not use the "correct" test code? -Joseph
Bumping version to a stable release.
Kerberos configuration works fine here. Can this be closed?
Thanks for taking the time to report this bug; however, closing due to lack of response of the reporter, sorry. if you still see this issue with a current release of evolution (2.28.x or later), please reopen. thanks in advance.