From 3a8313a8de46021161fa0127dedf75bd89ac0988 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Sat, 1 Oct 2016 10:57:23 +0200 Subject: [PATCH] auth: Add a new cli_credentials_ccache_init() Signed-off-by: Andreas Schneider --- auth/credentials/credentials.h | 3 + auth/credentials/credentials_internal.h | 2 + auth/credentials/credentials_krb5.c | 95 +++++++++++++++++++++++++ 3 files changed, 100 insertions(+) diff --git a/auth/credentials/credentials.h b/auth/credentials/credentials.h index 9fe6a82b1ead..f16c6f980856 100644 --- a/auth/credentials/credentials.h +++ b/auth/credentials/credentials.h @@ -163,6 +163,9 @@ void cli_credentials_set_netlogon_creds( const struct netlogon_creds_CredentialState *netlogon_creds); NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred, struct smb_krb5_context *smb_krb5_context); +bool cli_credentials_ccache_init(struct cli_credentials *cred, + struct loadparm_context *lp_ctx, + const char *ccache_name); NTSTATUS cli_credentials_set_stored_principal(struct cli_credentials *cred, struct loadparm_context *lp_ctx, const char *serviceprincipal); diff --git a/auth/credentials/credentials_internal.h b/auth/credentials/credentials_internal.h index 68f1f25dce1c..faf6a92dec4e 100644 --- a/auth/credentials/credentials_internal.h +++ b/auth/credentials/credentials_internal.h @@ -32,6 +32,7 @@ struct cli_credentials { enum credentials_obtained domain_obtained; enum credentials_obtained realm_obtained; enum credentials_obtained ccache_obtained; + enum credentials_obtained krb5_ccache_obtained; enum credentials_obtained client_gss_creds_obtained; enum credentials_obtained principal_obtained; enum credentials_obtained keytab_obtained; @@ -67,6 +68,7 @@ struct cli_credentials { DATA_BLOB nt_response; struct ccache_container *ccache; + struct ccache_container *krb5_ccache; struct gssapi_creds_container *client_gss_creds; struct keytab_container *keytab; struct gssapi_creds_container *server_gss_creds; diff --git a/auth/credentials/credentials_krb5.c b/auth/credentials/credentials_krb5.c index d8ca6d971158..ca5fd964933b 100644 --- a/auth/credentials/credentials_krb5.c +++ b/auth/credentials/credentials_krb5.c @@ -230,6 +230,101 @@ _PUBLIC_ NTSTATUS cli_credentials_set_krb5_context(struct cli_credentials *cred, return NT_STATUS_OK; } +/** + * @brief Initialize a Kerberos credential cache for later use. + * + * This functions initializes a Kerberos credential cache. If ccache_name is not + * specified it will either use the default credential cache or create a memory + * credential cache. This depends on the authentication credentials specified, + * username and password. + * + * @param[in] cred The credentials structure to init the cache on. + * + * @param[in] lp_ctx The loadparm context to use. + * + * @param[in] ccache_name The name of the credential cache to open or + * NULL. + * + * @return true on success, false if an error occcured. + */ +_PUBLIC_ bool cli_credentials_ccache_init(struct cli_credentials *cred, + struct loadparm_context *lp_ctx, + const char *ccache_name) +{ + TALLOC_CTX *tmp_ctx; + krb5_error_code code; + enum credentials_obtained principal_obtained = CRED_UNINITIALISED; + struct ccache_container *ccc = NULL; + const char *principal; + const char *password = NULL; + bool use_memory_ccache = false; + bool ok = false; + + if (cred->krb5_ccache_obtained != CRED_UNINITIALISED) { + return false; + } + + tmp_ctx = talloc_new(cred); + if (tmp_ctx == NULL) { + return false; + } + + principal = cli_credentials_get_principal_and_obtained(cred, + tmp_ctx, + &principal_obtained); + if (principal == NULL) { + goto done; + } + + ccc = talloc_zero(tmp_ctx, struct ccache_container); + if (ccc == NULL) { + goto done; + } + + code = cli_credentials_get_krb5_context(cred, + lp_ctx, + &ccc->smb_krb5_context); + if (principal_obtained == CRED_SPECIFIED) { + password = cli_credentials_get_password(cred); + if (password != NULL) { + use_memory_ccache = true; + } + } + + if (ccache_name == NULL && use_memory_ccache) { + ccache_name = talloc_asprintf(tmp_ctx, "MEMORY:cli_creds/%p", ccc); + if (ccache_name == NULL) { + goto done; + } + } + + if (ccache_name != NULL) { + code = krb5_cc_resolve(ccc->smb_krb5_context->krb5_context, + ccache_name, + &ccc->ccache); + } else { + code = krb5_cc_default(ccc->smb_krb5_context->krb5_context, + &ccc->ccache); + } + if (code != 0) { + goto done; + } + + if (use_memory_ccache) { + talloc_set_destructor(ccc, free_mccache); + } else { + talloc_set_destructor(ccc, free_dccache); + } + + cred->krb5_ccache = talloc_steal(cred, ccc); + cred->krb5_ccache_obtained = CRED_SPECIFIED; + + ok = true; +done: + talloc_free(tmp_ctx); + return ok; +} + static int cli_credentials_set_from_ccache(struct cli_credentials *cred, struct ccache_container *ccache, enum credentials_obtained obtained, -- 2.34.1