static bool internal_set_cred(struct remctl *r, gss_cred_id_t *gss_cred) { krb5_error_code code; OM_uint32 major, minor; if (r->krb_ctx == NULL) { code = krb5_init_context(&r->krb_ctx); if (code != 0) { internal_krb5_error(r, "opening ticket cache", code); return false; } } if (r->krb_ccache != NULL) krb5_cc_close(r->krb_ctx, r->krb_ccache); code = krb5_cc_resolve(r->krb_ctx, r->ccache, &r->krb_ccache); if (code != 0) { internal_krb5_error(r, "opening ticket cache", code); return false; } major = gss_krb5_import_cred(&minor, r->krb_ccache, NULL, NULL, gss_cred); if (major != GSS_S_COMPLETE) { internal_gssapi_error(r, "importing ticket cache", major, minor); return false; } return true; }
int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, struct gssapi_creds_container **_gcc) { int ret = 0; OM_uint32 maj_stat, min_stat; struct gssapi_creds_container *gcc; struct ccache_container *ccache; if (cred->client_gss_creds_obtained >= (MAX(cred->ccache_obtained, MAX(cred->principal_obtained, cred->username_obtained)))) { *_gcc = cred->client_gss_creds; return 0; } ret = cli_credentials_get_ccache(cred, &ccache); if (ret) { DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret))); return ret; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { return ENOMEM; } maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, &gcc->creds); if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } } if (ret == 0) { cred->client_gss_creds_obtained = cred->ccache_obtained; talloc_set_destructor(gcc, free_gssapi_creds); cred->client_gss_creds = gcc; *_gcc = gcc; } return ret; }
static gss_client_response *init_gss_creds(const char *credential_cache, gss_cred_id_t *cred) { OM_uint32 maj_stat; OM_uint32 min_stat; krb5_context context; krb5_error_code problem; gss_client_response *response = NULL; krb5_ccache ccache = NULL; *cred = GSS_C_NO_CREDENTIAL; if (credential_cache == NULL || strlen(credential_cache) == 0) { return NULL; } problem = krb5_init_context(&context); if (problem) { return other_error("unable to initialize krb5 context (%d)", (int)problem); } problem = krb5_cc_resolve(context, credential_cache, &ccache); if (problem) { response = krb5_ctx_error(context, problem); goto done; } maj_stat = gss_krb5_import_cred(&min_stat, ccache, NULL, NULL, cred); if (GSS_ERROR(maj_stat)) { response = gss_error(__func__, "gss_krb5_import_cred", maj_stat, min_stat); response->return_code = AUTH_GSS_ERROR; } done: if (response && ccache) { krb5_cc_close(context, ccache); } krb5_free_context(context); return response; }
static ADS_STATUS ads_init_gssapi_cred(ADS_STRUCT *ads, gss_cred_id_t *cred) { ADS_STATUS status; krb5_context kctx; krb5_error_code kerr; krb5_ccache kccache = NULL; uint32_t maj, min; *cred = GSS_C_NO_CREDENTIAL; if (!ads->auth.ccache_name) { return ADS_SUCCESS; } kerr = krb5_init_context(&kctx); if (kerr) { return ADS_ERROR_KRB5(kerr); } #ifdef HAVE_GSS_KRB5_IMPORT_CRED kerr = krb5_cc_resolve(kctx, ads->auth.ccache_name, &kccache); if (kerr) { status = ADS_ERROR_KRB5(kerr); goto done; } maj = gss_krb5_import_cred(&min, kccache, NULL, NULL, cred); if (maj != GSS_S_COMPLETE) { status = ADS_ERROR_GSS(maj, min); goto done; } #else /* We need to fallback to overriding the default creds. * This operation is not thread safe as it changes the process * environment variable, but we do not have any better option * with older kerberos libraries */ { const char *oldccname = NULL; oldccname = getenv("KRB5CCNAME"); setenv("KRB5CCNAME", ads->auth.ccache_name, 1); maj = gss_acquire_cred(&min, GSS_C_NO_NAME, GSS_C_INDEFINITE, NULL, GSS_C_INITIATE, cred, NULL, NULL); if (oldccname) { setenv("KRB5CCNAME", oldccname, 1); } else { unsetenv("KRB5CCNAME"); } if (maj != GSS_S_COMPLETE) { status = ADS_ERROR_GSS(maj, min); goto done; } } #endif status = ADS_SUCCESS; done: if (!ADS_ERR_OK(status) && kccache != NULL) { krb5_cc_close(kctx, kccache); } krb5_free_context(kctx); return status; }
static int32_t acquire_cred(struct client *c, krb5_principal principal, krb5_get_init_creds_opt *opt, int32_t *handle) { krb5_error_code ret; krb5_creds cred; krb5_ccache id; gss_cred_id_t gcred; OM_uint32 maj_stat, min_stat; *handle = 0; krb5_get_init_creds_opt_set_forwardable (opt, 1); krb5_get_init_creds_opt_set_renew_life (opt, 3600 * 24 * 30); memset(&cred, 0, sizeof(cred)); ret = krb5_get_init_creds_password (context, &cred, principal, NULL, NULL, NULL, 0, NULL, opt); if (ret) { logmessage(c, __FILE__, __LINE__, 0, "krb5_get_init_creds failed: %d", ret); return convert_krb5_to_gsm(ret); } ret = krb5_cc_new_unique(context, "MEMORY", NULL, &id); if (ret) krb5_err (context, 1, ret, "krb5_cc_initialize"); ret = krb5_cc_initialize (context, id, cred.client); if (ret) krb5_err (context, 1, ret, "krb5_cc_initialize"); ret = krb5_cc_store_cred (context, id, &cred); if (ret) krb5_err (context, 1, ret, "krb5_cc_store_cred"); krb5_free_cred_contents (context, &cred); maj_stat = gss_krb5_import_cred(&min_stat, id, NULL, NULL, &gcred); krb5_cc_close(context, id); if (maj_stat) { logmessage(c, __FILE__, __LINE__, 0, "krb5 import creds failed with: %d", maj_stat); return convert_gss_to_gsm(maj_stat); } *handle = add_handle(c, handle_cred, gcred); return 0; }
_PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, struct loadparm_context *lp_ctx, struct gssapi_creds_container **_gcc) { int ret = 0; OM_uint32 maj_stat, min_stat; struct gssapi_creds_container *gcc; struct keytab_container *ktc; struct smb_krb5_context *smb_krb5_context; TALLOC_CTX *mem_ctx; krb5_principal princ; const char *error_string; enum credentials_obtained obtained; mem_ctx = talloc_new(cred); if (!mem_ctx) { return ENOMEM; } ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context); if (ret) { return ret; } ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ, &obtained, &error_string); if (ret) { DEBUG(1,("cli_credentials_get_server_gss_creds: making krb5 principal failed (%s)\n", error_string)); talloc_free(mem_ctx); return ret; } if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, obtained))) { talloc_free(mem_ctx); *_gcc = cred->server_gss_creds; return 0; } ret = cli_credentials_get_keytab(cred, lp_ctx, &ktc); if (ret) { DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret))); return ret; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { talloc_free(mem_ctx); return ENOMEM; } if (ktc->password_based || obtained < CRED_SPECIFIED) { /* This creates a GSSAPI cred_id_t for match-by-key with only the keytab set */ maj_stat = gss_krb5_import_cred(&min_stat, NULL, NULL, ktc->keytab, &gcc->creds); } else { /* This creates a GSSAPI cred_id_t with the principal and keytab set, matching by name */ maj_stat = gss_krb5_import_cred(&min_stat, NULL, princ, ktc->keytab, &gcc->creds); } if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } } if (ret == 0) { cred->server_gss_creds_obtained = cred->keytab_obtained; talloc_set_destructor(gcc, free_gssapi_creds); cred->server_gss_creds = gcc; *_gcc = gcc; } talloc_free(mem_ctx); return ret; }
_PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, struct gssapi_creds_container **_gcc, const char **error_string) { int ret = 0; OM_uint32 maj_stat, min_stat; struct gssapi_creds_container *gcc; struct ccache_container *ccache; #ifdef SAMBA4_USES_HEIMDAL gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER; #endif krb5_enctype *etypes = NULL; if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold && cred->client_gss_creds_obtained > CRED_UNINITIALISED) { bool expired = false; OM_uint32 lifetime = 0; gss_cred_usage_t usage = 0; maj_stat = gss_inquire_cred(&min_stat, cred->client_gss_creds->creds, NULL, &lifetime, &usage, NULL); if (maj_stat == GSS_S_CREDENTIALS_EXPIRED) { DEBUG(3, ("Credentials for %s expired, must refresh credentials cache\n", cli_credentials_get_principal(cred, cred))); expired = true; } else if (maj_stat == GSS_S_COMPLETE && lifetime < 300) { DEBUG(3, ("Credentials for %s will expire shortly (%u sec), must refresh credentials cache\n", cli_credentials_get_principal(cred, cred), lifetime)); expired = true; } else if (maj_stat != GSS_S_COMPLETE) { *error_string = talloc_asprintf(cred, "inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n", gssapi_error_string(cred, maj_stat, min_stat, NULL)); return EINVAL; } if (expired) { cli_credentials_unconditionally_invalidate_client_gss_creds(cred); } else { DEBUG(5, ("GSSAPI credentials for %s will expire in %u secs\n", cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); *_gcc = cred->client_gss_creds; return 0; } } ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, &ccache, error_string); if (ret) { if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) { DEBUG(1, ("Failed to get kerberos credentials (kerberos required): %s\n", *error_string)); } else { DEBUG(4, ("Failed to get kerberos credentials: %s\n", *error_string)); } return ret; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { (*error_string) = error_message(ENOMEM); return ENOMEM; } maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, &gcc->creds); if ((maj_stat == GSS_S_FAILURE) && (min_stat == (OM_uint32)KRB5_CC_END || min_stat == (OM_uint32) KRB5_CC_NOTFOUND)) { /* This CCACHE is no good. Ensure we don't use it again */ cli_credentials_unconditionally_invalidate_ccache(cred); /* Now try again to get a ccache */ ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx, &ccache, error_string); if (ret) { DEBUG(1, ("Failed to re-get CCACHE for GSSAPI client: %s\n", error_message(ret))); return ret; } maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, &gcc->creds); } if (maj_stat) { talloc_free(gcc); if (min_stat) { ret = min_stat; } else { ret = EINVAL; } (*error_string) = talloc_asprintf(cred, "gss_krb5_import_cred failed: %s", error_message(ret)); return ret; } /* * transfer the enctypes from the smb_krb5_context to the gssapi layer * * We use 'our' smb_krb5_context to do the AS-REQ and it is possible * to configure the enctypes via the krb5.conf. * * And the gss_init_sec_context() creates it's own krb5_context and * the TGS-REQ had all enctypes in it and only the ones configured * and used for the AS-REQ, so it wasn't possible to disable the usage * of AES keys. */ min_stat = get_kerberos_allowed_etypes(ccache->smb_krb5_context->krb5_context, &etypes); if (min_stat == 0) { OM_uint32 num_ktypes; for (num_ktypes = 0; etypes[num_ktypes]; num_ktypes++); maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, gcc->creds, num_ktypes, (int32_t *) etypes); SAFE_FREE(etypes); if (maj_stat) { talloc_free(gcc); if (min_stat) { ret = min_stat; } else { ret = EINVAL; } (*error_string) = talloc_asprintf(cred, "gss_krb5_set_allowable_enctypes failed: %s", error_message(ret)); return ret; } } #ifdef SAMBA4_USES_HEIMDAL /* MIT lacks GSS_KRB5_CRED_NO_CI_FLAGS_X */ /* don't force GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG */ maj_stat = gss_set_cred_option(&min_stat, &gcc->creds, GSS_KRB5_CRED_NO_CI_FLAGS_X, &empty_buffer); if (maj_stat) { talloc_free(gcc); if (min_stat) { ret = min_stat; } else { ret = EINVAL; } (*error_string) = talloc_asprintf(cred, "gss_set_cred_option failed: %s", error_message(ret)); return ret; } #endif cred->client_gss_creds_obtained = cred->ccache_obtained; talloc_set_destructor(gcc, free_gssapi_creds); cred->client_gss_creds = gcc; *_gcc = gcc; return 0; }
int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, struct gssapi_creds_container **_gcc) { int ret = 0; OM_uint32 maj_stat, min_stat; struct gssapi_creds_container *gcc; struct keytab_container *ktc; struct smb_krb5_context *smb_krb5_context; TALLOC_CTX *mem_ctx; krb5_principal princ; if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, MAX(cred->principal_obtained, cred->username_obtained)))) { *_gcc = cred->server_gss_creds; return 0; } ret = cli_credentials_get_krb5_context(cred, &smb_krb5_context); if (ret) { return ret; } ret = cli_credentials_get_keytab(cred, &ktc); if (ret) { DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret))); return ret; } mem_ctx = talloc_new(cred); if (!mem_ctx) { return ENOMEM; } ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ); if (ret) { DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n", smb_get_krb5_error_message(smb_krb5_context->krb5_context, ret, mem_ctx))); talloc_free(mem_ctx); return ret; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { talloc_free(mem_ctx); return ENOMEM; } /* This creates a GSSAPI cred_id_t with the principal and keytab set */ maj_stat = gss_krb5_import_cred(&min_stat, NULL, princ, ktc->keytab, &gcc->creds); if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } } if (ret == 0) { cred->server_gss_creds_obtained = cred->keytab_obtained; talloc_set_destructor(gcc, free_gssapi_creds); cred->server_gss_creds = gcc; *_gcc = gcc; } talloc_free(mem_ctx); return ret; }
static void copy_import(void) { gss_cred_id_t cred1, cred2; OM_uint32 maj_stat, min_stat; gss_name_t name1, name2; OM_uint32 lifetime1, lifetime2; gss_cred_usage_t usage1, usage2; gss_OID_set mechs1, mechs2; krb5_ccache id; krb5_error_code ret; krb5_context context; int equal; maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME, GSS_C_INDEFINITE, GSS_C_NO_OID_SET, GSS_C_INITIATE, &cred1, NULL, NULL); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_acquire_cred"); maj_stat = gss_inquire_cred(&min_stat, cred1, &name1, &lifetime1, &usage1, &mechs1); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_inquire_cred"); ret = krb5_init_context(&context); if (ret) errx(1, "krb5_init_context"); ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id); if (ret) krb5_err(context, 1, ret, "krb5_cc_new_unique"); maj_stat = gss_krb5_copy_ccache(&min_stat, cred1, id); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_copy_ccache"); maj_stat = gss_krb5_import_cred(&min_stat, id, NULL, NULL, &cred2); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_krb5_import_cred"); maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2, &usage2, &mechs2); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_inquire_cred 2"); maj_stat = gss_compare_name(&min_stat, name1, name2, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); if (lifetime1 != lifetime2) errx(1, "lifetime not equal %lu != %lu", (unsigned long)lifetime1, (unsigned long)lifetime2); if (usage1 != usage2) { /* as long any of them is both are everything it ok */ if (usage1 != GSS_C_BOTH && usage2 != GSS_C_BOTH) errx(1, "usages disjoined"); } gss_release_name(&min_stat, &name2); gss_release_oid_set(&min_stat, &mechs2); maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2, &usage2, &mechs2); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_inquire_cred"); maj_stat = gss_compare_name(&min_stat, name1, name2, &equal); if (maj_stat != GSS_S_COMPLETE) errx(1, "gss_compare_name"); if (!equal) errx(1, "names not equal"); if (lifetime1 != lifetime2) errx(1, "lifetime not equal %lu != %lu", (unsigned long)lifetime1, (unsigned long)lifetime2); gss_release_cred(&min_stat, &cred1); gss_release_cred(&min_stat, &cred2); gss_release_name(&min_stat, &name1); gss_release_name(&min_stat, &name2); #if 0 compare(mechs1, mechs2); #endif gss_release_oid_set(&min_stat, &mechs1); gss_release_oid_set(&min_stat, &mechs2); krb5_cc_destroy(context, id); krb5_free_context(context); }
OM_uint32 Curl_gss_init_sec_context( struct connectdata *conn, OM_uint32 * minor_status, gss_ctx_id_t * context, gss_name_t target_name, gss_channel_bindings_t input_chan_bindings, gss_buffer_t input_token, gss_buffer_t output_token, OM_uint32 * ret_flags) { krb5_context krb_context = NULL; /* Kerberos context object */ krb5_ccache ccache = NULL; krb5_creds creds; krb5_get_init_creds_opt *opts = NULL; krb5_principal principal = NULL; krb5_keytab ktab = NULL; OM_uint32 min_stat, maj_stat; char *cachename = NULL; char *keytabfile = ""; OM_uint32 major_status; struct SessionHandle *data = conn->data; int ret; OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG; conn->data->curl_gss_creds = GSS_C_NO_CREDENTIAL; memset(&creds, 0, sizeof(creds)); if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) { #ifdef GSS_C_DELEG_POLICY_FLAG req_flags |= GSS_C_DELEG_POLICY_FLAG; #else infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not " "compiled in\n"); #endif } if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG) req_flags |= GSS_C_DELEG_FLAG; if((ret = krb5_init_context(&krb_context)) != 0) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } if ((ret = krb5_parse_name(krb_context, conn->user, &principal)) != 0) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } if ((ret = krb5_get_init_creds_opt_alloc (krb_context , &opts)) != 0) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } if (conn->bits.user_keytab) { infof(data, "KRB5_DATA: Keytab location is %s \n", conn->keytab_location); if ((ret = krb5_kt_resolve(krb_context, conn->keytab_location, &ktab)) != 0) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } if ((ret = krb5_get_init_creds_keytab(krb_context, &creds, principal, ktab, 0, NULL, opts)) != 0) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } } else if(conn->bits.user_passwd) { infof(data,"KRB5_DATA: Using the user password method \n"); if ((ret = krb5_get_init_creds_password(krb_context,&creds,principal,conn->passwd,NULL,NULL,0,NULL,opts)) != 0 ) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } } else if(conn->bits.credential_cache) { infof(data, "Resolving given credential cache \n"); infof(data, "KRB5_DATA: Credential cache location is %s \n", conn->credential_cache); if ((ret = krb5_cc_resolve(krb_context, conn->credential_cache, &ccache))!=0) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } } else if(conn->data->isIntermediateServer) { infof(data, "KRB5_DATA: Curl is carrying a gss credential \n"); major_status = gss_init_sec_context(minor_status, conn->data->deleg_gss_creds, /* cred_handle */ context, target_name, GSS_C_NO_OID, /* mech_type */ req_flags, 0, /* time_req */ input_chan_bindings, input_token, NULL, /* actual_mech_type */ output_token, ret_flags, NULL /* time_rec */); curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); return major_status; } else { infof(data, "KRB5_DATA: Passed no password/keytab location, using default credentials\n "); conn->data->curl_gss_creds = GSS_C_NO_CREDENTIAL; major_status = gss_init_sec_context(minor_status, conn->data->curl_gss_creds, /* cred_handle */ context, target_name, GSS_C_NO_OID, /* mech_type */ req_flags, 0, /* time_req */ input_chan_bindings, input_token, NULL, /* actual_mech_type */ output_token, ret_flags, NULL /* time_rec */); curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); return major_status; } if(!conn->bits.credential_cache) { infof(data, "Creating new credential cache, since none specified \n"); if((ret = krb5_cc_new_unique( krb_context, "MEMORY", NULL, &ccache)) != 0) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } infof(data, "Initializing credential cache \n"); if ((ret = krb5_cc_initialize(krb_context, ccache, principal))!=0) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } infof(data, "Storing credential within credential cache \n"); if ((ret = krb5_cc_store_cred(krb_context,ccache,&creds)) != 0) { curl_krb5_print_error_message(krb_context, ret, data); curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED ; } } infof(data, "Attempting to import the credential \n"); if ((maj_stat = gss_krb5_import_cred(&min_stat, ccache, principal, NULL, &conn->data->curl_gss_creds))!=0) { infof(data, "Importing krb5 credential into gss credentials failed\n"); curl_krb5_print_error_message(krb_context, min_stat, data); if(conn->bits.credential_cache) curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); else curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab); return CURLE_KERBEROS_AUTH_FAILED; } infof(data, "Able to convert the credential \n"); infof(data, "Attempting init sec context \n"); major_status = gss_init_sec_context(minor_status, conn->data->curl_gss_creds, /* cred_handle */ context, target_name, GSS_C_NO_OID, /* mech_type */ req_flags, 0, /* time_req */ input_chan_bindings, input_token, NULL, /* actual_mech_type */ output_token, ret_flags, NULL /* time_rec */); if(conn->bits.credential_cache) curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab); else curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab); return major_status; }
static OM_uint32 getDefaultCred(OM_uint32 *minor, const char *keytab_name, gss_OID_set mechs, gss_cred_id_t *impersonator_cred_handle) { OM_uint32 major = GSS_S_FAILURE, tmp_minor; if (keytab_name) { krb5_error_code code; krb5_context context = NULL; krb5_keytab keytab = NULL; krb5_principal keytab_principal = NULL; krb5_ccache ccache = NULL; code = krb5_init_context(&context); if (code) { displayStatus("krb5_init_context", major, code); return major; } code = krb5_kt_resolve(context, keytab_name, &keytab); if (code) { displayStatus("krb5_kt_resolve", major, code); goto out; } code = krb5_cc_default(context, &ccache); if (code) { displayStatus("krb5_cc_default", major, code); goto out; } code = krb5_cc_get_principal(context, ccache, &keytab_principal); if (code) { displayStatus("krb5_cc_get_principal", major, code); goto out; } major = gss_krb5_import_cred(minor, ccache, keytab_principal, keytab, impersonator_cred_handle); if (GSS_ERROR(major)) { displayStatus("gss_krb5_import_cred", major, *minor); goto out; } out: if (code) *minor = code; krb5_free_principal(context, keytab_principal); krb5_cc_close(context, ccache); krb5_kt_close(context, keytab); krb5_free_context(context); } else { gss_OID_set actual_mechs = GSS_C_NO_OID_SET; major = gss_acquire_cred(minor, GSS_C_NO_NAME, GSS_C_INDEFINITE, mechs, GSS_C_BOTH, impersonator_cred_handle, &actual_mechs, NULL); if (GSS_ERROR(major)) { displayStatus("gss_acquire_cred", major, *minor); } (void) gss_release_oid_set(&tmp_minor, &actual_mechs); } return major; }