int cli_credentials_get_ccache(struct cli_credentials *cred, struct ccache_container **ccc) { krb5_error_code ret; if (cred->ccache_obtained >= (MAX(cred->principal_obtained, cred->username_obtained))) { *ccc = cred->ccache; return 0; } if (cli_credentials_is_anonymous(cred)) { return EINVAL; } ret = cli_credentials_new_ccache(cred, NULL); if (ret) { return ret; } ret = kinit_to_ccache(cred, cred, cred->ccache->smb_krb5_context, cred->ccache->ccache); if (ret) { return ret; } ret = cli_credentials_set_from_ccache(cred, cred->principal_obtained); if (ret) { return ret; } *ccc = cred->ccache; return ret; }
int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, struct loadparm_context *lp_ctx, gss_cred_id_t gssapi_cred, enum credentials_obtained obtained, const char **error_string) { int ret; OM_uint32 maj_stat, min_stat; struct ccache_container *ccc; struct gssapi_creds_container *gcc; if (cred->client_gss_creds_obtained > obtained) { return 0; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { (*error_string) = error_message(ENOMEM); return ENOMEM; } ret = cli_credentials_new_ccache(cred, lp_ctx, NULL, &ccc, error_string); if (ret != 0) { return ret; } maj_stat = gss_krb5_copy_ccache(&min_stat, gssapi_cred, ccc->ccache); if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } if (ret) { (*error_string) = error_message(ENOMEM); } } if (ret == 0) { ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string); } cred->ccache = ccc; cred->ccache_obtained = obtained; if (ret == 0) { gcc->creds = gssapi_cred; talloc_set_destructor(gcc, free_gssapi_creds); /* set the clinet_gss_creds_obtained here, as it just got set to UNINITIALISED by the calls above */ cred->client_gss_creds_obtained = obtained; cred->client_gss_creds = gcc; } return ret; }
int cli_credentials_set_client_gss_creds(struct cli_credentials *cred, gss_cred_id_t gssapi_cred, enum credentials_obtained obtained) { int ret; OM_uint32 maj_stat, min_stat; struct ccache_container *ccc; struct gssapi_creds_container *gcc; if (cred->client_gss_creds_obtained > obtained) { return 0; } gcc = talloc(cred, struct gssapi_creds_container); if (!gcc) { return ENOMEM; } ret = cli_credentials_new_ccache(cred, &ccc); if (ret != 0) { return ret; } maj_stat = gss_krb5_copy_ccache(&min_stat, gssapi_cred, ccc->ccache); if (maj_stat) { if (min_stat) { ret = min_stat; } else { ret = EINVAL; } } if (ret == 0) { ret = cli_credentials_set_from_ccache(cred, obtained); } if (ret == 0) { gcc->creds = gssapi_cred; talloc_set_destructor(gcc, free_gssapi_creds); cred->client_gss_creds_obtained = obtained; cred->client_gss_creds = gcc; } return ret; }
_PUBLIC_ int cli_credentials_get_named_ccache(struct cli_credentials *cred, struct tevent_context *event_ctx, struct loadparm_context *lp_ctx, char *ccache_name, struct ccache_container **ccc, const char **error_string) { krb5_error_code ret; enum credentials_obtained obtained; if (cred->machine_account_pending) { cli_credentials_set_machine_account(cred, lp_ctx); } if (cred->ccache_obtained >= cred->ccache_threshold && cred->ccache_obtained > CRED_UNINITIALISED) { time_t lifetime; bool expired = false; ret = smb_krb5_cc_get_lifetime(cred->ccache->smb_krb5_context->krb5_context, cred->ccache->ccache, &lifetime); if (ret == KRB5_CC_END) { /* If we have a particular ccache set, without * an initial ticket, then assume there is a * good reason */ } else if (ret == 0) { if (lifetime == 0) { DEBUG(3, ("Ticket in credentials cache for %s expired, will refresh\n", cli_credentials_get_principal(cred, cred))); expired = true; } else if (lifetime < 300) { DEBUG(3, ("Ticket in credentials cache for %s will shortly expire (%u secs), will refresh\n", cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); expired = true; } } else { (*error_string) = talloc_asprintf(cred, "failed to get ccache lifetime: %s\n", smb_get_krb5_error_message(cred->ccache->smb_krb5_context->krb5_context, ret, cred)); return ret; } DEBUG(5, ("Ticket in credentials cache for %s will expire in %u secs\n", cli_credentials_get_principal(cred, cred), (unsigned int)lifetime)); if (!expired) { *ccc = cred->ccache; return 0; } } if (cli_credentials_is_anonymous(cred)) { (*error_string) = "Cannot get anonymous kerberos credentials"; return EINVAL; } ret = cli_credentials_new_ccache(cred, lp_ctx, ccache_name, ccc, error_string); if (ret) { return ret; } ret = kinit_to_ccache(cred, cred, (*ccc)->smb_krb5_context, event_ctx, (*ccc)->ccache, &obtained, error_string); if (ret) { return ret; } ret = cli_credentials_set_from_ccache(cred, *ccc, obtained, error_string); cred->ccache = *ccc; cred->ccache_obtained = cred->principal_obtained; if (ret) { return ret; } cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained); return 0; }
_PUBLIC_ int cli_credentials_set_ccache(struct cli_credentials *cred, struct loadparm_context *lp_ctx, const char *name, enum credentials_obtained obtained, const char **error_string) { krb5_error_code ret; krb5_principal princ; struct ccache_container *ccc; if (cred->ccache_obtained > obtained) { return 0; } ccc = talloc(cred, struct ccache_container); if (!ccc) { (*error_string) = error_message(ENOMEM); return ENOMEM; } ret = cli_credentials_get_krb5_context(cred, lp_ctx, &ccc->smb_krb5_context); if (ret) { (*error_string) = error_message(ret); talloc_free(ccc); return ret; } if (!talloc_reference(ccc, ccc->smb_krb5_context)) { talloc_free(ccc); (*error_string) = error_message(ENOMEM); return ENOMEM; } if (name) { ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache); if (ret) { (*error_string) = talloc_asprintf(cred, "failed to read krb5 ccache: %s: %s\n", name, smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)); talloc_free(ccc); return ret; } } else { ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache); if (ret) { (*error_string) = talloc_asprintf(cred, "failed to read default krb5 ccache: %s\n", smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc)); talloc_free(ccc); return ret; } } talloc_set_destructor(ccc, free_dccache); ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ); if (ret == 0) { krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ); ret = cli_credentials_set_from_ccache(cred, ccc, obtained, error_string); if (ret) { (*error_string) = error_message(ret); return ret; } cred->ccache = ccc; cred->ccache_obtained = obtained; talloc_steal(cred, ccc); cli_credentials_invalidate_client_gss_creds(cred, cred->ccache_obtained); return 0; } return 0; }
int cli_credentials_set_ccache(struct cli_credentials *cred, const char *name, enum credentials_obtained obtained) { krb5_error_code ret; krb5_principal princ; struct ccache_container *ccc; if (cred->ccache_obtained > obtained) { return 0; } ccc = talloc(cred, struct ccache_container); if (!ccc) { return ENOMEM; } ret = cli_credentials_get_krb5_context(cred, &ccc->smb_krb5_context); if (ret) { talloc_free(ccc); return ret; } talloc_reference(ccc, ccc->smb_krb5_context); if (name) { ret = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, name, &ccc->ccache); if (ret) { DEBUG(1,("failed to read krb5 ccache: %s: %s\n", name, smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); talloc_free(ccc); return ret; } } else { ret = krb5_cc_default(ccc->smb_krb5_context->krb5_context, &ccc->ccache); if (ret) { DEBUG(3,("failed to read default krb5 ccache: %s\n", smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); talloc_free(ccc); return ret; } } talloc_set_destructor(ccc, free_dccache); ret = krb5_cc_get_principal(ccc->smb_krb5_context->krb5_context, ccc->ccache, &princ); if (ret) { DEBUG(3,("failed to get principal from default ccache: %s\n", smb_get_krb5_error_message(ccc->smb_krb5_context->krb5_context, ret, ccc))); talloc_free(ccc); return ret; } krb5_free_principal(ccc->smb_krb5_context->krb5_context, princ); cred->ccache = ccc; talloc_steal(cred, ccc); ret = cli_credentials_set_from_ccache(cred, obtained); if (ret) { return ret; } return 0; }