diff options
-rw-r--r-- | source3/librpc/rpc/dcerpc_gssapi.c | 51 | ||||
-rw-r--r-- | source3/librpc/rpc/dcerpc_gssapi.h | 3 | ||||
-rw-r--r-- | source3/librpc/rpc/dcerpc_spnego.c | 11 | ||||
-rw-r--r-- | source3/librpc/rpc/dcerpc_spnego.h | 3 | ||||
-rw-r--r-- | source3/rpc_client/cli_pipe.c | 11 |
5 files changed, 63 insertions, 16 deletions
diff --git a/source3/librpc/rpc/dcerpc_gssapi.c b/source3/librpc/rpc/dcerpc_gssapi.c index 2de46b5752..777f5f1cad 100644 --- a/source3/librpc/rpc/dcerpc_gssapi.c +++ b/source3/librpc/rpc/dcerpc_gssapi.c @@ -28,6 +28,21 @@ #include <gssapi/gssapi_krb5.h> #include <gssapi/gssapi_ext.h> +#ifndef GSS_KRB5_INQ_SSPI_SESSION_KEY_OID +#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH 11 +#define GSS_KRB5_INQ_SSPI_SESSION_KEY_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x05\x05" +#endif + +#ifndef GSS_KRB5_SESSION_KEY_ENCTYPE_OID +#define GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH 10 +#define GSS_KRB5_SESSION_KEY_ENCTYPE_OID "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x04" +#endif + +gss_OID_desc gse_sesskey_inq_oid = { GSS_KRB5_INQ_SSPI_SESSION_KEY_OID_LENGTH, + (void *)GSS_KRB5_INQ_SSPI_SESSION_KEY_OID }; +gss_OID_desc gse_sesskeytype_oid = { GSS_KRB5_SESSION_KEY_ENCTYPE_OID_LENGTH, + (void *)GSS_KRB5_SESSION_KEY_ENCTYPE_OID }; + static char *gse_errstr(TALLOC_CTX *mem_ctx, OM_uint32 maj, OM_uint32 min); struct gse_context { @@ -44,8 +59,6 @@ struct gse_context { gss_name_t server_name; gss_cred_id_t cli_creds; - DATA_BLOB session_key; - bool more_processing; }; @@ -348,9 +361,39 @@ bool gse_require_more_processing(struct gse_context *gse_ctx) return gse_ctx->more_processing; } -DATA_BLOB gse_get_session_key(struct gse_context *gse_ctx) +DATA_BLOB gse_get_session_key(TALLOC_CTX *mem_ctx, + struct gse_context *gse_ctx) { - return gse_ctx->session_key; + OM_uint32 gss_min, gss_maj; + gss_buffer_set_t set = GSS_C_NO_BUFFER_SET; + DATA_BLOB ret; + + gss_maj = gss_inquire_sec_context_by_oid( + &gss_min, gse_ctx->gss_ctx, + &gse_sesskey_inq_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 data_blob_null; + } + + if ((set == GSS_C_NO_BUFFER_SET) || + (set->count != 2) || + (memcmp(set->elements[1].value, + gse_sesskeytype_oid.elements, + gse_sesskeytype_oid.length) != 0)) { + DEBUG(0, ("gss_inquire_sec_context_by_oid returned unknown " + "OID for data in results:\n")); + dump_data(1, set->elements[1].value, + set->elements[1].length); + return data_blob_null; + } + + ret = data_blob_talloc(mem_ctx, set->elements[0].value, + set->elements[0].length); + + gss_maj = gss_release_buffer_set(&gss_min, &set); + return ret; } size_t gse_get_signature_length(struct gse_context *gse_ctx, diff --git a/source3/librpc/rpc/dcerpc_gssapi.h b/source3/librpc/rpc/dcerpc_gssapi.h index 3152033841..28bf9d1c27 100644 --- a/source3/librpc/rpc/dcerpc_gssapi.h +++ b/source3/librpc/rpc/dcerpc_gssapi.h @@ -43,7 +43,8 @@ NTSTATUS gse_get_client_auth_token(TALLOC_CTX *mem_ctx, DATA_BLOB *token_out); bool gse_require_more_processing(struct gse_context *gse_ctx); -DATA_BLOB gse_get_session_key(struct gse_context *gse_ctx); +DATA_BLOB gse_get_session_key(TALLOC_CTX *mem_ctx, + struct gse_context *gse_ctx); size_t gse_get_signature_length(struct gse_context *gse_ctx, int seal, size_t payload_size); diff --git a/source3/librpc/rpc/dcerpc_spnego.c b/source3/librpc/rpc/dcerpc_spnego.c index 5627a0d7e7..ec81a2c701 100644 --- a/source3/librpc/rpc/dcerpc_spnego.c +++ b/source3/librpc/rpc/dcerpc_spnego.c @@ -338,14 +338,19 @@ NTSTATUS spnego_get_negotiated_mech(struct spnego_context *sp_ctx, return NT_STATUS_OK; } -DATA_BLOB spnego_get_session_key(struct spnego_context *sp_ctx) +DATA_BLOB spnego_get_session_key(TALLOC_CTX *mem_ctx, + struct spnego_context *sp_ctx) { + DATA_BLOB sk; + switch (sp_ctx->auth_type) { case DCERPC_AUTH_TYPE_KRB5: - return gse_get_session_key(sp_ctx->mech_ctx.gssapi_state); + return gse_get_session_key(mem_ctx, + sp_ctx->mech_ctx.gssapi_state); case DCERPC_AUTH_TYPE_NTLMSSP: - return auth_ntlmssp_get_session_key( + sk = auth_ntlmssp_get_session_key( sp_ctx->mech_ctx.ntlmssp_state); + return data_blob_dup_talloc(mem_ctx, &sk); default: DEBUG(0, ("Unsupported type in request!\n")); return data_blob_null; diff --git a/source3/librpc/rpc/dcerpc_spnego.h b/source3/librpc/rpc/dcerpc_spnego.h index 58363fd072..9d37fd1e38 100644 --- a/source3/librpc/rpc/dcerpc_spnego.h +++ b/source3/librpc/rpc/dcerpc_spnego.h @@ -49,5 +49,6 @@ NTSTATUS spnego_get_negotiated_mech(struct spnego_context *sp_ctx, enum dcerpc_AuthType *auth_type, void **auth_context); -DATA_BLOB spnego_get_session_key(struct spnego_context *sp_ctx); +DATA_BLOB spnego_get_session_key(TALLOC_CTX *mem_ctx, + struct spnego_context *sp_ctx); #endif /* _DCERPC_SPENGO_H_ */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 1bee2f875b..2466418e39 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -3451,19 +3451,16 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, make_dup = true; break; case DCERPC_AUTH_TYPE_SPNEGO: - sk = spnego_get_session_key(a->a_u.spnego_state); - if (sk.length == 0) { - return NT_STATUS_NO_USER_SESSION_KEY; - } - make_dup = true; + sk = spnego_get_session_key(mem_ctx, a->a_u.spnego_state); + make_dup = false; break; case DCERPC_AUTH_TYPE_NTLMSSP: sk = auth_ntlmssp_get_session_key(a->a_u.auth_ntlmssp_state); make_dup = true; break; case DCERPC_AUTH_TYPE_KRB5: - sk = gse_get_session_key(a->a_u.gssapi_state); - make_dup = true; + sk = gse_get_session_key(mem_ctx, a->a_u.gssapi_state); + make_dup = false; break; case DCERPC_AUTH_TYPE_NONE: sk = data_blob_const(a->user_session_key.data, |