auth/kerberos/gssapi_helper: add gssapi_krb5_export_ccache()
authorStefan Metzmacher <metze@samba.org>
Wed, 27 Nov 2019 13:09:43 +0000 (14:09 +0100)
committerStefan Metzmacher <metze@samba.org>
Thu, 6 Aug 2020 12:03:26 +0000 (14:03 +0200)
auth/kerberos/gssapi_helper.c
auth/kerberos/gssapi_helper.h

index 8697bc64838b1bff5ac0702700fe6e3164d2cf85..557dafdefb0fc2348d42f10a9518d49839a343f7 100644 (file)
@@ -399,6 +399,81 @@ NTSTATUS gssapi_check_packet(gss_ctx_id_t gssapi_context,
        return NT_STATUS_OK;
 }
 
+NTSTATUS gssapi_krb5_export_ccache(const char *ccache_name,
+                                  TALLOC_CTX *mem_ctx,
+                                  DATA_BLOB *creds_blob)
+{
+#ifdef HAVE_GSS_EXPORT_CRED
+       TALLOC_CTX *frame = talloc_stackframe();
+       krb5_context k5ctx = NULL;
+       krb5_ccache k5ccache = NULL;
+       gss_cred_id_t gss_creds = GSS_C_NO_CREDENTIAL;
+       gss_buffer_desc cred_token = GSS_C_EMPTY_BUFFER;
+       OM_uint32 gmaj;
+       OM_uint32 gmin;
+       OM_uint32 grel;
+       NTSTATUS status;
+       int ret;
+
+       *creds_blob = data_blob_null;
+
+       if (ccache_name == NULL) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       ret = smb_krb5_init_context_common(&k5ctx);
+       status = krb5_to_nt_status(ret);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       ret = krb5_cc_resolve(k5ctx, ccache_name, &k5ccache);
+       status = krb5_to_nt_status(ret);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return status;
+       }
+
+       gmaj = smb_gss_krb5_import_cred(&gmin,
+                                       k5ctx,
+                                       k5ccache,
+                                       NULL,
+                                       NULL,
+                                       &gss_creds);
+       krb5_cc_close(k5ctx, k5ccache);
+       if (gmaj != GSS_S_COMPLETE) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       gmaj = gss_export_cred(&gmin, gss_creds, &cred_token);
+       gss_release_cred(&grel, &gss_creds);
+       if (gmaj != GSS_S_COMPLETE) {
+               TALLOC_FREE(frame);
+               return NT_STATUS_INTERNAL_ERROR;
+       }
+
+       if (cred_token.length != 0) {
+               *creds_blob = data_blob_talloc(mem_ctx,
+                                              cred_token.value,
+                                              cred_token.length);
+               gss_release_buffer(&grel, &cred_token);
+               if (creds_blob->length == 0) {
+                       TALLOC_FREE(frame);
+                       return NT_STATUS_NO_MEMORY;
+               }
+       }
+
+       TALLOC_FREE(frame);
+       return NT_STATUS_OK;
+#else /* HAVE_GSS_EXPORT_CRED */
+       *creds_blob = data_blob_null;
+       return NT_STATUS_NOT_IMPLEMENTED;
+#endif
+}
+
 NTSTATUS gssapi_setup_server_principal(TALLOC_CTX *mem_ctx,
                                       const char *target_principal,
                                       const char *service,
index 6f5823d33c8ab3f38a9f6cdbc5dec530600d22ef..4c5a210555320b3dc9afa5f382c35e2b4958faba 100644 (file)
@@ -52,6 +52,10 @@ NTSTATUS gssapi_check_packet(gss_ctx_id_t gssapi_context,
                             const uint8_t *whole_pdu, size_t pdu_length,
                             const DATA_BLOB *sig);
 
+NTSTATUS gssapi_krb5_export_ccache(const char *ccache_name,
+                                  TALLOC_CTX *mem_ctx,
+                                  DATA_BLOB *creds_blob);
+
 NTSTATUS gssapi_setup_server_principal(TALLOC_CTX *mem_ctx,
                                       const char *target_principal,
                                       const char *service,