summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/gensec/gensec_gssapi.c126
1 files changed, 67 insertions, 59 deletions
diff --git a/source4/auth/gensec/gensec_gssapi.c b/source4/auth/gensec/gensec_gssapi.c
index 364c0c3499..ed407b623b 100644
--- a/source4/auth/gensec/gensec_gssapi.c
+++ b/source4/auth/gensec/gensec_gssapi.c
@@ -24,12 +24,16 @@
#include "includes.h"
#include "system/kerberos.h"
+#include "heimdal/lib/gssapi/gssapi.h"
#include "auth/kerberos/kerberos.h"
#include "librpc/gen_ndr/krb5pac.h"
#include "auth/auth.h"
#include "lib/ldb/include/ldb.h"
#include "auth/auth_sam.h"
#include "librpc/rpc/dcerpc.h"
+#include "auth/credentials/credentials.h"
+#include "auth/credentials/credentials_krb5.h"
+#include "auth/gensec/gensec.h"
enum gensec_gssapi_sasl_state
{
@@ -75,7 +79,8 @@ static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_securi
static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security);
static char *gssapi_error_string(TALLOC_CTX *mem_ctx,
- OM_uint32 maj_stat, OM_uint32 min_stat)
+ OM_uint32 maj_stat, OM_uint32 min_stat,
+ const gss_OID_desc *mech)
{
OM_uint32 disp_min_stat, disp_maj_stat;
gss_buffer_desc maj_error_message;
@@ -88,9 +93,9 @@ static char *gssapi_error_string(TALLOC_CTX *mem_ctx,
min_error_message.value = NULL;
disp_maj_stat = gss_display_status(&disp_min_stat, maj_stat, GSS_C_GSS_CODE,
- GSS_C_NULL_OID, &msg_ctx, &maj_error_message);
+ mech, &msg_ctx, &maj_error_message);
disp_maj_stat = gss_display_status(&disp_min_stat, min_stat, GSS_C_MECH_CODE,
- GSS_C_NULL_OID, &msg_ctx, &min_error_message);
+ mech, &msg_ctx, &min_error_message);
ret = talloc_asprintf(mem_ctx, "%s: %s", (char *)maj_error_message.value, (char *)min_error_message.value);
gss_release_buffer(&disp_min_stat, &maj_error_message);
@@ -304,7 +309,7 @@ static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_securi
if (maj_stat) {
DEBUG(2, ("GSS Import name of %s failed: %s\n",
(char *)name_token.value,
- gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat)));
+ gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_INVALID_PARAMETER;
}
@@ -374,7 +379,8 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
TALLOC_CTX *out_mem_ctx,
const DATA_BLOB in, DATA_BLOB *out)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
NTSTATUS nt_status = NT_STATUS_LOGON_FAILURE;
OM_uint32 maj_stat, min_stat;
OM_uint32 min_stat2;
@@ -477,23 +483,23 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
switch (min_stat) {
case KRB5_KDC_UNREACH:
DEBUG(3, ("Cannot reach a KDC we require: %s\n",
- gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat)));
+ gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN:
DEBUG(3, ("Server is not registered with our KDC: %s\n",
- gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat)));
+ gssapi_error_string(gensec_gssapi_state, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_INVALID_PARAMETER; /* Make SPNEGO ignore us, we can't go any further here */
case KRB5KRB_AP_ERR_MSG_TYPE:
/* garbage input, possibly from the auto-mech detection */
return NT_STATUS_INVALID_PARAMETER;
default:
DEBUG(1, ("GSS(krb5) Update failed: %s\n",
- gssapi_error_string(out_mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return nt_status;
}
} else {
DEBUG(1, ("GSS Update failed: %s\n",
- gssapi_error_string(out_mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return nt_status;
}
break;
@@ -526,7 +532,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
&qop_state);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("gensec_gssapi_update: GSS UnWrap of SASL protection negotiation failed: %s\n",
- gssapi_error_string(out_mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -578,7 +584,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
&output_token);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n",
- gssapi_error_string(out_mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -643,7 +649,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
&output_token);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n",
- gssapi_error_string(out_mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -676,7 +682,7 @@ static NTSTATUS gensec_gssapi_update(struct gensec_security *gensec_security,
&qop_state);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("gensec_gssapi_update: GSS UnWrap of SASL protection negotiation failed: %s\n",
- gssapi_error_string(out_mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(out_mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -734,7 +740,8 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security,
const DATA_BLOB *in,
DATA_BLOB *out)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
OM_uint32 maj_stat, min_stat;
gss_buffer_desc input_token, output_token;
int conf_state;
@@ -750,7 +757,7 @@ static NTSTATUS gensec_gssapi_wrap(struct gensec_security *gensec_security,
&output_token);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("gensec_gssapi_wrap: GSS Wrap failed: %s\n",
- gssapi_error_string(mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -780,7 +787,8 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security,
const DATA_BLOB *in,
DATA_BLOB *out)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
OM_uint32 maj_stat, min_stat;
gss_buffer_desc input_token, output_token;
int conf_state;
@@ -804,7 +812,7 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security,
&qop_state);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("gensec_gssapi_unwrap: GSS UnWrap failed: %s\n",
- gssapi_error_string(mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -822,7 +830,8 @@ static NTSTATUS gensec_gssapi_unwrap(struct gensec_security *gensec_security,
static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_security)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
OM_uint32 maj_stat, min_stat;
OM_uint32 max_input_size;
@@ -835,7 +844,7 @@ static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_securi
if (GSS_ERROR(maj_stat)) {
TALLOC_CTX *mem_ctx = talloc_new(NULL);
DEBUG(1, ("gensec_gssapi_max_input_size: determinaing signature size with gss_wrap_size_limit failed: %s\n",
- gssapi_error_string(mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
talloc_free(mem_ctx);
return 0;
}
@@ -846,7 +855,7 @@ static size_t gensec_gssapi_max_input_size(struct gensec_security *gensec_securi
/* Find out the maximum output size negotiated on this connection */
static size_t gensec_gssapi_max_wrapped_size(struct gensec_security *gensec_security)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);;
return gensec_gssapi_state->max_wrap_buf_size;
}
@@ -856,7 +865,8 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
OM_uint32 maj_stat, min_stat;
gss_buffer_desc input_token, output_token;
int conf_state;
@@ -874,7 +884,7 @@ static NTSTATUS gensec_gssapi_seal_packet(struct gensec_security *gensec_securit
&output_token);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("gensec_gssapi_seal_packet: GSS Wrap failed: %s\n",
- gssapi_error_string(mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -907,7 +917,8 @@ static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_secur
const uint8_t *whole_pdu, size_t pdu_length,
const DATA_BLOB *sig)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
OM_uint32 maj_stat, min_stat;
gss_buffer_desc input_token, output_token;
int conf_state;
@@ -932,7 +943,7 @@ static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_secur
&qop_state);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("gensec_gssapi_unseal_packet: GSS UnWrap failed: %s\n",
- gssapi_error_string(mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -957,7 +968,8 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit
const uint8_t *whole_pdu, size_t pdu_length,
DATA_BLOB *sig)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
OM_uint32 maj_stat, min_stat;
gss_buffer_desc input_token, output_token;
int conf_state;
@@ -975,7 +987,7 @@ static NTSTATUS gensec_gssapi_sign_packet(struct gensec_security *gensec_securit
&output_token);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("GSS Wrap failed: %s\n",
- gssapi_error_string(mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -1003,7 +1015,8 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi
const uint8_t *whole_pdu, size_t pdu_length,
const DATA_BLOB *sig)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
OM_uint32 maj_stat, min_stat;
gss_buffer_desc input_token, output_token;
int conf_state;
@@ -1028,7 +1041,7 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi
&qop_state);
if (GSS_ERROR(maj_stat)) {
DEBUG(1, ("GSS UnWrap failed: %s\n",
- gssapi_error_string(mem_ctx, maj_stat, min_stat)));
+ gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
return NT_STATUS_ACCESS_DENIED;
}
@@ -1045,7 +1058,8 @@ static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_securi
static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security,
uint32_t feature)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
if (feature & GENSEC_FEATURE_SIGN) {
/* If we are going GSSAPI SASL, then we honour the second negotiation */
if (gensec_gssapi_state->sasl
@@ -1090,43 +1104,34 @@ static BOOL gensec_gssapi_have_feature(struct gensec_security *gensec_security,
static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_security,
DATA_BLOB *session_key)
{
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
-
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
+ OM_uint32 maj_stat, min_stat;
+ krb5_keyblock *subkey;
+
if (gensec_gssapi_state->session_key.data) {
*session_key = gensec_gssapi_state->session_key;
return NT_STATUS_OK;
}
- /* Ensure we only call this for GSSAPI/krb5, otherwise things
- * could get very ugly */
- if ((gensec_gssapi_state->gss_oid->length == gss_mech_krb5->length)
- && (memcmp(gensec_gssapi_state->gss_oid->elements, gss_mech_krb5->elements,
- gensec_gssapi_state->gss_oid->length) == 0)) {
- OM_uint32 maj_stat, min_stat;
- gss_buffer_desc skey;
-
- maj_stat = gsskrb5_get_initiator_subkey(&min_stat,
- gensec_gssapi_state->gssapi_context,
- &skey);
-
- if (maj_stat == 0) {
- DEBUG(10, ("Got KRB5 session key of length %d\n",
- (int)skey.length));
- gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state,
- skey.value, skey.length);
- *session_key = gensec_gssapi_state->session_key;
- dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
-
- gss_release_buffer(&min_stat, &skey);
- return NT_STATUS_OK;
- }
+ maj_stat = gsskrb5_get_initiator_subkey(&min_stat,
+ gensec_gssapi_state->gssapi_context,
+ &subkey);
+ if (maj_stat != 0) {
+ DEBUG(1, ("NO session key for this mech\n"));
return NT_STATUS_NO_USER_SESSION_KEY;
}
- DEBUG(1, ("NO session key for this mech\n"));
- return NT_STATUS_NO_USER_SESSION_KEY;
-}
+ DEBUG(10, ("Got KRB5 session key of length %d\n",
+ (int)KRB5_KEY_LENGTH(subkey)));
+ gensec_gssapi_state->session_key = data_blob_talloc(gensec_gssapi_state,
+ KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey));
+ krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, subkey);
+ *session_key = gensec_gssapi_state->session_key;
+ dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
+ return NT_STATUS_OK;
+}
/* Get some basic (and authorization) information about the user on
* this session. This uses either the PAC (if present) or a local
@@ -1136,7 +1141,8 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
{
NTSTATUS nt_status;
TALLOC_CTX *mem_ctx;
- struct gensec_gssapi_state *gensec_gssapi_state = gensec_security->private_data;
+ struct gensec_gssapi_state *gensec_gssapi_state
+ = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
struct auth_serversupplied_info *server_info = NULL;
struct auth_session_info *session_info = NULL;
struct PAC_LOGON_INFO *logon_info;
@@ -1163,7 +1169,9 @@ static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_securi
gensec_gssapi_state->client_name,
&name_token,
NULL);
- if (maj_stat) {
+ if (GSS_ERROR(maj_stat)) {
+ DEBUG(1, ("GSS display_name failed: %s\n",
+ gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
talloc_free(mem_ctx);
return NT_STATUS_FOOBAR;
}