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,