summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/librpc/rpc/dcerpc_gssapi.c51
-rw-r--r--source3/librpc/rpc/dcerpc_gssapi.h3
-rw-r--r--source3/librpc/rpc/dcerpc_spnego.c11
-rw-r--r--source3/librpc/rpc/dcerpc_spnego.h3
-rw-r--r--source3/rpc_client/cli_pipe.c11
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,