diff -Naur heimdal-1.0.1-orig/lib/krb5/acache.c heimdal-1.0.1/lib/krb5/acache.c --- heimdal-1.0.1-orig/lib/krb5/acache.c 2007-11-26 09:43:06.000000000 -0700 +++ heimdal-1.0.1/lib/krb5/acache.c 2007-11-26 09:56:59.000000000 -0700 @@ -550,6 +550,48 @@ return 0; } +/* Alternate method for initialization that works around * + * a MacOS 10.5 bug in the cc API set principal call. */ +static krb5_error_code +acc_initialize_2( krb5_context context, + krb5_ccache id, + krb5_principal primary_principal ) +{ + krb5_acc *a = ACACHE(id); + krb5_error_code ret; + int32_t error; + char *name; + + ret = krb5_unparse_name(context, primary_principal, &name); + if (ret) + return ret; + + if (a->ccache == NULL) + { + error = (*a->context->func->create_new_ccache)(a->context, + cc_credentials_v5, + name, + &a->ccache); + } + else + { + error = (*a->ccache->func->destroy)(a->ccache); + if( error ) + { + ret = translate_cc_error(context, error); + return ret; + } + a->ccache = NULL; + error = (*a->context->func->create_new_ccache)( a->context, + cc_credentials_v5, + name, + &a->ccache); + } + free(name); + ret = translate_cc_error(context, error); + return ret; +} + static krb5_error_code acc_initialize(krb5_context context, krb5_ccache id, @@ -561,6 +603,7 @@ krb5_error_code ret; int32_t error; char *name; + cc_string_t curr_owner; ret = krb5_unparse_name(context, primary_principal, &name); if (ret) @@ -587,10 +630,40 @@ (*ccred->func->release)(ccred); } (*iter->func->release)(iter); + + /* Mac OS 10.5 (at least in the seed) fails with an internal + * error when calling set principal. We don't actually need + * to set the principal if it is already correct, so we are + * going to get the principal and see if they are the same first + * if they are, then there is no reason to call set and then + * possibly fail. If it does fail try and work around the issue + * by destroying the cache and creating a new one with the given + * principal name. */ - error = (*a->ccache->func->set_principal)(a->ccache, + error = (*a->ccache->func->get_principal)(a->ccache, cc_credentials_v5, - name); + &curr_owner); + if( error ) { + return translate_cc_error(context, error); + } + if( strcasecmp( name, curr_owner->data ) != 0 ) { + error = (*a->ccache->func->set_principal)(a->ccache, + cc_credentials_v5, + name); + if( error == ccErrBadInternalMessage ) { + /* This is the MacOX 10.5 case where set principal * + * fails with an internal error. */ + free( name ); + (*curr_owner->func->release)(curr_owner); + return acc_initialize_2( context, + id, + primary_principal ); + } + else + if( error ) { + return translate_cc_error(context, error); + } + } } free(name); diff -Naur heimdal-1.0.1-orig/lib/krb5/krb5_ccapi.h heimdal-1.0.1/lib/krb5/krb5_ccapi.h --- heimdal-1.0.1-orig/lib/krb5/krb5_ccapi.h 2007-11-26 09:43:06.000000000 -0700 +++ heimdal-1.0.1/lib/krb5/krb5_ccapi.h 2007-11-26 10:00:26.000000000 -0700 @@ -80,7 +80,9 @@ ccErrServerInsecure, ccErrServerCantBecomeUID, - ccErrTimeOffsetNotSet /* 226 */ + ccErrTimeOffsetNotSet, /* 226 */ + ccErrBadInternalMessage, + ccErrNotImplemented }; typedef int32_t cc_int32;