#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
{
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;
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);
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;
}
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;
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;
&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;
}
&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;
}
&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;
}
&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;
}
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;
&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;
}
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;
&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;
}
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;
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;
}
/* 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;
}
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;
&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;
}
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;
&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;
}
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;
&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;
}
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;
&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;
}
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
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
{
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;
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;
}