The Samba-Bugzilla – Attachment 6453 Details for
Bug 8149
PAC unverified over DCE/RPC
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Proposed patch
0001-s3-gse-Use-gss_get_name_attribute-to-fetch-the-pac.patch (text/plain), 8.19 KB, created by
Andrew Bartlett
on 2011-05-19 00:03:15 UTC
(
hide
)
Description:
Proposed patch
Filename:
MIME Type:
Creator:
Andrew Bartlett
Created:
2011-05-19 00:03:15 UTC
Size:
8.19 KB
patch
obsolete
>>From 7377401c17ebeb43812b0be55cb48622fbae4e82 Mon Sep 17 00:00:00 2001 >From: Simo Sorce <idra@samba.org> >Date: Mon, 9 May 2011 11:33:41 -0400 >Subject: [PATCH] s3-gse: Use gss_get_name_attribute to fetch the pac > >This is the only way to be sure the pac signatures are correct. >It requires a fairly new version of MIT Kerberos, but that should be fine, it >is new functionality in 3.6 anyways. >--- > source3/configure.in | 1 + > source3/librpc/crypto/gse.c | 74 ++++++++++++++++++++++++------------ > source3/librpc/crypto/gse.h | 3 +- > source3/rpc_server/dcesrv_gssapi.c | 42 +-------------------- > 4 files changed, 53 insertions(+), 67 deletions(-) > >diff --git a/source3/configure.in b/source3/configure.in >index d8c59b675bd0793181e683da813b39a5ccd1043e..72568d838f2b751e566dd4c8f09bdbdea0b240d4 100644 >--- a/source3/configure.in >+++ b/source3/configure.in >@@ -3860,6 +3860,7 @@ if test x"$with_ads_support" != x"no"; then > AC_CHECK_FUNC_EXT(krb5_get_credentials_for_user, $KRB5_LIBS) > AC_CHECK_FUNC_EXT(krb5_get_host_realm, $KRB5_LIBS) > AC_CHECK_FUNC_EXT(krb5_free_host_realm, $KRB5_LIBS) >+ AC_CHECK_FUNC_EXT(gss_get_name_attribute, $KRB5_LIBS) > > # MIT krb5 1.8 does not expose this call (yet) > AC_CHECK_DECLS(krb5_get_credentials_for_user, [], [], [#include <krb5.h>]) >diff --git a/source3/librpc/crypto/gse.c b/source3/librpc/crypto/gse.c >index 064ccda2eb1d3cf222ce6f9462f77452c4c5a371..335dc1c53f149fb08af44e7d753c99149a02d961 100644 >--- a/source3/librpc/crypto/gse.c >+++ b/source3/librpc/crypto/gse.c >@@ -22,7 +22,10 @@ > #include "includes.h" > #include "gse.h" > >-#if defined(HAVE_KRB5) && defined(HAVE_GSSAPI_GSSAPI_EXT_H) && defined(HAVE_GSS_WRAP_IOV) >+#if defined(HAVE_KRB5) \ >+ && defined(HAVE_GSSAPI_GSSAPI_EXT_H) \ >+ && defined(HAVE_GSS_WRAP_IOV) \ >+ && defined(HAVE_GSS_GET_NAME_ATTRIBUTE) > > #include "smb_krb5.h" > #include "gse_krb5.h" >@@ -681,42 +684,62 @@ NTSTATUS gse_get_authz_data(struct gse_context *gse_ctx, > return NT_STATUS_OK; > } > >-NTSTATUS gse_get_authtime(struct gse_context *gse_ctx, time_t *authtime) >+NTSTATUS gse_get_pac_blob(struct gse_context *gse_ctx, >+ TALLOC_CTX *mem_ctx, DATA_BLOB *pac_blob) > { > OM_uint32 gss_min, gss_maj; >- gss_buffer_set_t set = GSS_C_NO_BUFFER_SET; >- int32_t tkttime; >+ gss_buffer_desc pac_buffer; >+ gss_buffer_desc pac_display_buffer; >+ gss_buffer_desc pac_name = { >+ .value = discard_const_p(char, "urn:mspac:"), >+ .length = sizeof("urn:mspac:") - 1 >+ }; >+ int more = -1; >+ int authenticated = false; >+ int complete = false; >+ NTSTATUS status; > > if (!gse_ctx->authenticated) { > return NT_STATUS_ACCESS_DENIED; > } > >- gss_maj = gss_inquire_sec_context_by_oid( >- &gss_min, gse_ctx->gss_ctx, >- &gse_authtime_oid, &set); >- if (gss_maj) { >- DEBUG(0, ("gss_inquire_sec_context_by_oid failed [%s]\n", >- gse_errstr(talloc_tos(), gss_maj, gss_min))); >- return NT_STATUS_NOT_FOUND; >- } >+ gss_maj = gss_get_name_attribute(&gss_min, >+ gse_ctx->client_name, &pac_name, >+ &authenticated, &complete, >+ &pac_buffer, &pac_display_buffer, >+ &more); > >- if ((set == GSS_C_NO_BUFFER_SET) || (set->count != 1) != 0) { >- DEBUG(0, ("gss_inquire_sec_context_by_oid returned unknown " >- "data in results.\n")); >- return NT_STATUS_INTERNAL_ERROR; >+ if (gss_maj != 0) { >+ DEBUG(0, ("obtaining PAC via GSSAPI gss_get_name_attribute " >+ "failed: %s\n", >+ gse_errstr(mem_ctx, gss_maj, gss_min))); >+ return NT_STATUS_ACCESS_DENIED; > } > >- if (set->elements[0].length != sizeof(int32_t)) { >- DEBUG(0, ("Invalid authtime size!\n")); >- return NT_STATUS_INTERNAL_ERROR; >- } >+ if (authenticated && complete) { >+ /* The PAC blob is returned directly */ >+ *pac_blob = data_blob_talloc(mem_ctx, >+ pac_buffer.value, >+ pac_buffer.length); >+ if (!pac_blob->data) { >+ status = NT_STATUS_NO_MEMORY; >+ } else { >+ status = NT_STATUS_OK; >+ } > >- tkttime = *((int32_t *)set->elements[0].value); >+ gss_maj = gss_release_buffer(&gss_min, &pac_buffer); >+ gss_maj = gss_release_buffer(&gss_min, &pac_display_buffer); >+ >+ return status; >+ } > >- gss_maj = gss_release_buffer_set(&gss_min, &set); >+ DEBUG(0, ("obtaining PAC via GSSAPI failed: authenticated: %s, " >+ "complete: %s, more: %s\n", >+ authenticated ? "true" : "false", >+ complete ? "true" : "false", >+ more ? "true" : "false")); > >- *authtime = (time_t)tkttime; >- return NT_STATUS_OK; >+ return NT_STATUS_ACCESS_DENIED; > } > > size_t gse_get_signature_length(struct gse_context *gse_ctx, >@@ -972,7 +995,8 @@ NTSTATUS gse_get_authz_data(struct gse_context *gse_ctx, > return NT_STATUS_NOT_IMPLEMENTED; > } > >-NTSTATUS gse_get_authtime(struct gse_context *gse_ctx, time_t *authtime) >+NTSTATUS gse_get_pac_blob(struct gse_context *gse_ctx, >+ TALLOC_CTX *mem_ctx, DATA_BLOB *pac) > { > return NT_STATUS_NOT_IMPLEMENTED; > } >diff --git a/source3/librpc/crypto/gse.h b/source3/librpc/crypto/gse.h >index a6d9a35a7ffdaf0c913e10625f78d0eedda4e931..d9e4a82e0ee3d62f0fd942d66d2fccf3badf8f39 100644 >--- a/source3/librpc/crypto/gse.h >+++ b/source3/librpc/crypto/gse.h >@@ -57,7 +57,8 @@ NTSTATUS gse_get_client_name(struct gse_context *gse_ctx, > TALLOC_CTX *mem_ctx, char **client_name); > NTSTATUS gse_get_authz_data(struct gse_context *gse_ctx, > TALLOC_CTX *mem_ctx, DATA_BLOB *pac); >-NTSTATUS gse_get_authtime(struct gse_context *gse_ctx, time_t *authtime); >+NTSTATUS gse_get_pac_blob(struct gse_context *gse_ctx, >+ TALLOC_CTX *mem_ctx, DATA_BLOB *pac); > > size_t gse_get_signature_length(struct gse_context *gse_ctx, > int seal, size_t payload_size); >diff --git a/source3/rpc_server/dcesrv_gssapi.c b/source3/rpc_server/dcesrv_gssapi.c >index f60f6ce245136a5f30de21f5d58d893f2da2a925..25d85a6730ccad8c5859f3af3897fa2d881c7266 100644 >--- a/source3/rpc_server/dcesrv_gssapi.c >+++ b/source3/rpc_server/dcesrv_gssapi.c >@@ -106,11 +106,8 @@ NTSTATUS gssapi_server_get_user_info(struct gse_context *gse_ctx, > { > TALLOC_CTX *tmp_ctx; > DATA_BLOB auth_data; >- time_t tgs_authtime; >- NTTIME tgs_authtime_nttime; > DATA_BLOB pac; > struct PAC_DATA *pac_data; >- struct PAC_LOGON_NAME *logon_name = NULL; > struct PAC_LOGON_INFO *logon_info = NULL; > enum ndr_err_code ndr_err; > unsigned int i; >@@ -122,14 +119,13 @@ NTSTATUS gssapi_server_get_user_info(struct gse_context *gse_ctx, > char *username; > struct passwd *pw; > NTSTATUS status; >- bool bret; > > tmp_ctx = talloc_new(mem_ctx); > if (!tmp_ctx) { > return NT_STATUS_NO_MEMORY; > } > >- status = gse_get_authz_data(gse_ctx, tmp_ctx, &auth_data); >+ status = gse_get_pac_blob(gse_ctx, tmp_ctx, &pac); > if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) { > /* TODO: Fetch user by principal name ? */ > status = NT_STATUS_ACCESS_DENIED; >@@ -139,24 +135,6 @@ NTSTATUS gssapi_server_get_user_info(struct gse_context *gse_ctx, > goto done; > } > >- bret = unwrap_pac(tmp_ctx, &auth_data, &pac); >- if (!bret) { >- DEBUG(1, ("Failed to unwrap PAC\n")); >- status = NT_STATUS_ACCESS_DENIED; >- goto done; >- } >- >- status = gse_get_client_name(gse_ctx, tmp_ctx, &princ_name); >- if (!NT_STATUS_IS_OK(status)) { >- goto done; >- } >- >- status = gse_get_authtime(gse_ctx, &tgs_authtime); >- if (!NT_STATUS_IS_OK(status)) { >- goto done; >- } >- unix_to_nt_time(&tgs_authtime_nttime, tgs_authtime); >- > pac_data = talloc_zero(tmp_ctx, struct PAC_DATA); > if (!pac_data) { > status = NT_STATUS_NO_MEMORY; >@@ -182,9 +160,6 @@ NTSTATUS gssapi_server_get_user_info(struct gse_context *gse_ctx, > } > logon_info = data_buf->info->logon_info.info; > break; >- case PAC_TYPE_LOGON_NAME: >- logon_name = &data_buf->info->logon_name; >- break; > default: > break; > } >@@ -194,21 +169,6 @@ NTSTATUS gssapi_server_get_user_info(struct gse_context *gse_ctx, > status = NT_STATUS_NOT_FOUND; > goto done; > } >- if (!logon_name) { >- DEBUG(1, ("Invalid PAC data, missing logon info!\n")); >- status = NT_STATUS_NOT_FOUND; >- goto done; >- } >- >- /* check time */ >- if (tgs_authtime_nttime != logon_name->logon_time) { >- DEBUG(1, ("Logon time mismatch between ticket and PAC!\n" >- "PAC Time = %s | Ticket Time = %s\n", >- nt_time_string(tmp_ctx, logon_name->logon_time), >- nt_time_string(tmp_ctx, tgs_authtime_nttime))); >- status = NT_STATUS_ACCESS_DENIED; >- goto done; >- } > > /* TODO: Should we check princ_name against account_name in > * logon_name ? Are they supposed to be identical, or can an >-- >1.7.4.4 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 8149
: 6453