break;
}
- gensec_gssapi_state->session_key = data_blob(NULL, 0);
- gensec_gssapi_state->pac = data_blob(NULL, 0);
-
ret = smb_krb5_init_context(gensec_gssapi_state,
NULL,
gensec_security->settings->lp_ctx,
return nt_status;
}
+static NTSTATUS gensec_gssapi_client_creds(struct gensec_security *gensec_security)
+{
+ struct gensec_gssapi_state *gensec_gssapi_state;
+ struct gssapi_creds_container *gcc;
+ struct cli_credentials *creds = gensec_get_credentials(gensec_security);
+ const char *error_string;
+ int ret;
+
+ gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state);
+
+ /* Only run this the first time the update() call is made */
+ if (gensec_gssapi_state->client_cred) {
+ return NT_STATUS_OK;
+ }
+
+ ret = cli_credentials_get_client_gss_creds(creds,
+ gensec_security->event_ctx,
+ gensec_security->settings->lp_ctx, &gcc, &error_string);
+ switch (ret) {
+ case 0:
+ break;
+ case EINVAL:
+ DEBUG(3, ("Cannot obtain client GSS credentials we need to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string));
+ return NT_STATUS_INVALID_PARAMETER;
+ case KRB5KDC_ERR_PREAUTH_FAILED:
+ case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
+ DEBUG(1, ("Wrong username or password: %s\n", error_string));
+ return NT_STATUS_LOGON_FAILURE;
+ case KRB5_KDC_UNREACH:
+ DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string));
+ return NT_STATUS_NO_LOGON_SERVERS;
+ case KRB5_CC_NOTFOUND:
+ case KRB5_CC_END:
+ DEBUG(2, ("Error obtaining ticket we require to contact %s: (possibly due to clock skew between us and the KDC) %s\n", gensec_gssapi_state->target_principal, error_string));
+ return NT_STATUS_TIME_DIFFERENCE_AT_DC;
+ default:
+ DEBUG(1, ("Aquiring initiator credentials failed: %s\n", error_string));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ gensec_gssapi_state->client_cred = gcc;
+ if (!talloc_reference(gensec_gssapi_state, gcc)) {
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ return NT_STATUS_OK;
+}
+
static NTSTATUS gensec_gssapi_client_start(struct gensec_security *gensec_security)
{
struct gensec_gssapi_state *gensec_gssapi_state;
struct cli_credentials *creds = gensec_get_credentials(gensec_security);
- krb5_error_code ret;
NTSTATUS nt_status;
gss_buffer_desc name_token;
gss_OID name_type;
OM_uint32 maj_stat, min_stat;
const char *hostname = gensec_get_target_hostname(gensec_security);
- struct gssapi_creds_container *gcc;
- const char *error_string;
if (!hostname) {
DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
return NT_STATUS_INVALID_PARAMETER;
}
- ret = cli_credentials_get_client_gss_creds(creds,
- gensec_security->event_ctx,
- gensec_security->settings->lp_ctx, &gcc, &error_string);
- switch (ret) {
- case 0:
- break;
- case KRB5KDC_ERR_PREAUTH_FAILED:
- case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
- DEBUG(1, ("Wrong username or password: %s\n", error_string));
- return NT_STATUS_LOGON_FAILURE;
- case KRB5_KDC_UNREACH:
- DEBUG(3, ("Cannot reach a KDC we require to contact %s : %s\n", gensec_gssapi_state->target_principal, error_string));
- return NT_STATUS_NO_LOGON_SERVERS;
- case KRB5_CC_NOTFOUND:
- case KRB5_CC_END:
- DEBUG(2, ("Error obtaining ticket we require to contact %s: (possibly due to clock skew between us and the KDC) %s\n", gensec_gssapi_state->target_principal, error_string));
- return NT_STATUS_TIME_DIFFERENCE_AT_DC;
- default:
- DEBUG(1, ("Aquiring initiator credentials failed: %s\n", error_string));
- return NT_STATUS_UNSUCCESSFUL;
- }
-
- gensec_gssapi_state->client_cred = gcc;
- if (!talloc_reference(gensec_gssapi_state, gcc)) {
- return NT_STATUS_NO_MEMORY;
- }
-
return NT_STATUS_OK;
}
{
struct gsskrb5_send_to_kdc send_to_kdc;
krb5_error_code ret;
+
+ nt_status = gensec_gssapi_client_creds(gensec_security);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ return nt_status;
+ }
+
send_to_kdc.func = smb_krb5_send_and_recv_func;
send_to_kdc.ptr = gensec_security->event_ctx;
}
static NTSTATUS gensec_gssapi_unseal_packet(struct gensec_security *gensec_security,
- TALLOC_CTX *mem_ctx,
uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
const DATA_BLOB *sig)
dump_data_pw("gensec_gssapi_unseal_packet: sig\n", sig->data, sig->length);
- in = data_blob_talloc(mem_ctx, NULL, sig->length + length);
+ in = data_blob_talloc(gensec_security, NULL, sig->length + length);
memcpy(in.data, sig->data, sig->length);
memcpy(in.data + sig->length, data, length);
&output_token,
&conf_state,
&qop_state);
+ talloc_free(in.data);
if (GSS_ERROR(maj_stat)) {
+ char *error_string = gssapi_error_string(NULL, maj_stat, min_stat, gensec_gssapi_state->gss_oid);
DEBUG(1, ("gensec_gssapi_unseal_packet: GSS UnWrap failed: %s\n",
- gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
+ error_string));
+ talloc_free(error_string);
return NT_STATUS_ACCESS_DENIED;
}
}
static NTSTATUS gensec_gssapi_check_packet(struct gensec_security *gensec_security,
- TALLOC_CTX *mem_ctx,
const uint8_t *data, size_t length,
const uint8_t *whole_pdu, size_t pdu_length,
const DATA_BLOB *sig)
&input_token,
&qop_state);
if (GSS_ERROR(maj_stat)) {
- DEBUG(1, ("GSS VerifyMic failed: %s\n",
- gssapi_error_string(mem_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid)));
+ char *error_string = gssapi_error_string(NULL, maj_stat, min_stat, gensec_gssapi_state->gss_oid);
+ DEBUG(1, ("GSS VerifyMic failed: %s\n", error_string));
+ talloc_free(error_string);
+
return NT_STATUS_ACCESS_DENIED;
}
* This breaks all the abstractions, but what do you expect...
*/
static NTSTATUS gensec_gssapi_session_key(struct gensec_security *gensec_security,
+ TALLOC_CTX *mem_ctx,
DATA_BLOB *session_key)
{
struct gensec_gssapi_state *gensec_gssapi_state
return NT_STATUS_NO_USER_SESSION_KEY;
}
- if (gensec_gssapi_state->session_key.data) {
- *session_key = gensec_gssapi_state->session_key;
- return NT_STATUS_OK;
- }
-
maj_stat = gsskrb5_get_subkey(&min_stat,
gensec_gssapi_state->gssapi_context,
&subkey);
DEBUG(10, ("Got KRB5 session key of length %d%s\n",
(int)KRB5_KEY_LENGTH(subkey),
(gensec_gssapi_state->sasl_state == STAGE_DONE)?" (done)":""));
- *session_key = data_blob_talloc(gensec_gssapi_state,
+ *session_key = data_blob_talloc(mem_ctx,
KRB5_KEY_DATA(subkey), KRB5_KEY_LENGTH(subkey));
krb5_free_keyblock(gensec_gssapi_state->smb_krb5_context->krb5_context, subkey);
- gensec_gssapi_state->session_key = *session_key;
dump_data_pw("KRB5 Session Key:\n", session_key->data, session_key->length);
return NT_STATUS_OK;
* this session. This uses either the PAC (if present) or a local
* database lookup */
static NTSTATUS gensec_gssapi_session_info(struct gensec_security *gensec_security,
+ TALLOC_CTX *mem_ctx_out,
struct auth_session_info **_session_info)
{
NTSTATUS nt_status;
return NT_STATUS_INVALID_PARAMETER;
}
- mem_ctx = talloc_named(gensec_gssapi_state, 0, "gensec_gssapi_session_info context");
+ mem_ctx = talloc_named(mem_ctx_out, 0, "gensec_gssapi_session_info context");
NT_STATUS_HAVE_NO_MEMORY(mem_ctx);
nt_status = gssapi_obtain_pac_blob(mem_ctx, gensec_gssapi_state->gssapi_context,
return nt_status;
}
- nt_status = gensec_gssapi_session_key(gensec_security, &session_info->session_key);
+ nt_status = gensec_gssapi_session_key(gensec_security, session_info, &session_info->session_key);
if (!NT_STATUS_IS_OK(nt_status)) {
talloc_free(mem_ctx);
return nt_status;
/* It has been taken from this place... */
gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;
}
- talloc_steal(gensec_gssapi_state, session_info);
+ *_session_info = talloc_steal(mem_ctx_out, session_info);
talloc_free(mem_ctx);
- *_session_info = session_info;
return NT_STATUS_OK;
}