auth: Add a new cli_credentials_ccache_init()
authorAndreas Schneider <asn@samba.org>
Sat, 1 Oct 2016 08:57:23 +0000 (10:57 +0200)
committerStefan Metzmacher <metze@samba.org>
Mon, 18 Feb 2019 12:39:20 +0000 (13:39 +0100)
Signed-off-by: Andreas Schneider <asn@samba.org>
auth/credentials/credentials.h
auth/credentials/credentials_internal.h
auth/credentials/credentials_krb5.c

index 9fe6a82b1ead5a56f06d830a39c3023d6ac5a956..f16c6f98085621fbc4bc9a9044d593d99bdc9b2e 100644 (file)
@@ -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);
index 68f1f25dce1c7952f3e45a075461b2082755daf0..faf6a92dec4ee2b00522e1c5b5c755ee18cbe9af 100644 (file)
@@ -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;
index d8ca6d9711588396f67ca521efa8124f1e034e74..ca5fd964933b364a9f0cf8d6a8c15181767ad99a 100644 (file)
@@ -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,