summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/auth/gensec/gensec_krb5.c124
1 files changed, 63 insertions, 61 deletions
diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c
index d999559a49..eff30bbfd1 100644
--- a/source4/auth/gensec/gensec_krb5.c
+++ b/source4/auth/gensec/gensec_krb5.c
@@ -84,9 +84,12 @@ static int gensec_krb5_destroy(void *ptr)
static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
{
+ krb5_error_code ret;
struct gensec_krb5_state *gensec_krb5_state;
+ struct cli_credentials *creds;
- if (!gensec_get_credentials(gensec_security)) {
+ creds = gensec_get_credentials(gensec_security);
+ if (!creds) {
return NT_STATUS_INVALID_PARAMETER;
}
@@ -96,7 +99,6 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
}
gensec_security->private_data = gensec_krb5_state;
-
gensec_krb5_state->smb_krb5_context = NULL;
gensec_krb5_state->auth_context = NULL;
gensec_krb5_state->ticket = NULL;
@@ -108,13 +110,37 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security)
talloc_set_destructor(gensec_krb5_state, gensec_krb5_destroy);
+ if (cli_credentials_get_krb5_context(creds, &gensec_krb5_state->smb_krb5_context)) {
+ talloc_free(gensec_krb5_state);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ ret = krb5_auth_con_init(gensec_krb5_state->smb_krb5_context->krb5_context, &gensec_krb5_state->auth_context);
+ if (ret) {
+ DEBUG(1,("gensec_krb5_start: krb5_auth_con_init failed (%s)\n",
+ smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context,
+ ret, gensec_krb5_state)));
+ talloc_free(gensec_krb5_state);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
+ ret = krb5_auth_con_setflags(gensec_krb5_state->smb_krb5_context->krb5_context,
+ gensec_krb5_state->auth_context,
+ KRB5_AUTH_CONTEXT_DO_SEQUENCE);
+ if (ret) {
+ DEBUG(1,("gensec_krb5_start: krb5_auth_con_setflags failed (%s)\n",
+ smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context,
+ ret, gensec_krb5_state)));
+ talloc_free(gensec_krb5_state);
+ return NT_STATUS_INTERNAL_ERROR;
+ }
+
return NT_STATUS_OK;
}
static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security)
{
NTSTATUS nt_status;
- krb5_error_code ret = 0;
struct gensec_krb5_state *gensec_krb5_state;
nt_status = gensec_krb5_start(gensec_security);
@@ -123,24 +149,6 @@ static NTSTATUS gensec_krb5_server_start(struct gensec_security *gensec_security
}
gensec_krb5_state = gensec_security->private_data;
-
- ret = smb_krb5_init_context(gensec_krb5_state,
- &gensec_krb5_state->smb_krb5_context);
- if (ret) {
- DEBUG(1,("gensec_krb5_start: krb5_init_context failed (%s)\n",
- error_message(ret)));
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- ret = krb5_auth_con_init(gensec_krb5_state->smb_krb5_context->krb5_context, &gensec_krb5_state->auth_context);
- if (ret) {
- DEBUG(1,("gensec_krb5_start: krb5_auth_con_init failed (%s)\n",
- smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context,
- ret, gensec_krb5_state)));
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- gensec_krb5_state = gensec_security->private_data;
gensec_krb5_state->state_position = GENSEC_KRB5_SERVER_START;
return NT_STATUS_OK;
@@ -167,6 +175,9 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
const char *hostname;
krb5_flags ap_req_options = AP_OPTS_USE_SUBKEY | AP_OPTS_MUTUAL_REQUIRED;
+ char *principal;
+ krb5_data in_data;
+
hostname = gensec_get_target_hostname(gensec_security);
if (!hostname) {
DEBUG(1, ("Could not determine hostname for target computer, cannot use kerberos\n"));
@@ -196,45 +207,31 @@ static NTSTATUS gensec_krb5_client_start(struct gensec_security *gensec_security
return NT_STATUS_UNSUCCESSFUL;
}
- gensec_krb5_state->smb_krb5_context = talloc_reference(gensec_krb5_state, ccache_container->smb_krb5_context);
-
- ret = krb5_auth_con_init(gensec_krb5_state->smb_krb5_context->krb5_context, &gensec_krb5_state->auth_context);
- if (ret) {
- DEBUG(1,("gensec_krb5_start: krb5_auth_con_init failed (%s)\n",
- smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context,
- ret, gensec_krb5_state)));
- return NT_STATUS_INTERNAL_ERROR;
- }
-
- if (ret == 0) {
- char *principal;
- krb5_data in_data;
- in_data.length = 0;
-
- principal = gensec_get_target_principal(gensec_security);
- if (principal && lp_client_use_spnego_principal()) {
- krb5_principal target_principal;
- ret = krb5_parse_name(gensec_krb5_state->smb_krb5_context->krb5_context, principal,
- &target_principal);
- if (ret == 0) {
- ret = krb5_mk_req_exact(gensec_krb5_state->smb_krb5_context->krb5_context,
- &gensec_krb5_state->auth_context,
- ap_req_options,
- target_principal,
- &in_data, ccache_container->ccache,
- &gensec_krb5_state->enc_ticket);
- krb5_free_principal(gensec_krb5_state->smb_krb5_context->krb5_context,
- target_principal);
- }
- } else {
- ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context,
- &gensec_krb5_state->auth_context,
- ap_req_options,
- gensec_get_target_service(gensec_security),
- hostname,
- &in_data, ccache_container->ccache,
- &gensec_krb5_state->enc_ticket);
+ in_data.length = 0;
+
+ principal = gensec_get_target_principal(gensec_security);
+ if (principal && lp_client_use_spnego_principal()) {
+ krb5_principal target_principal;
+ ret = krb5_parse_name(gensec_krb5_state->smb_krb5_context->krb5_context, principal,
+ &target_principal);
+ if (ret == 0) {
+ ret = krb5_mk_req_exact(gensec_krb5_state->smb_krb5_context->krb5_context,
+ &gensec_krb5_state->auth_context,
+ ap_req_options,
+ target_principal,
+ &in_data, ccache_container->ccache,
+ &gensec_krb5_state->enc_ticket);
+ krb5_free_principal(gensec_krb5_state->smb_krb5_context->krb5_context,
+ target_principal);
}
+ } else {
+ ret = krb5_mk_req(gensec_krb5_state->smb_krb5_context->krb5_context,
+ &gensec_krb5_state->auth_context,
+ ap_req_options,
+ gensec_get_target_service(gensec_security),
+ hostname,
+ &in_data, ccache_container->ccache,
+ &gensec_krb5_state->enc_ticket);
}
switch (ret) {
case 0:
@@ -625,9 +622,14 @@ static NTSTATUS gensec_krb5_unwrap(struct gensec_security *gensec_security,
static BOOL gensec_krb5_have_feature(struct gensec_security *gensec_security,
uint32_t feature)
{
+ struct gensec_krb5_state *gensec_krb5_state = gensec_security->private_data;
if (feature & GENSEC_FEATURE_SESSION_KEY) {
return True;
}
+ if (!gensec_krb5_state->gssapi &&
+ (feature & GENSEC_FEATURE_SEAL)) {
+ return True;
+ }
return False;
}
@@ -649,8 +651,6 @@ static const struct gensec_security_ops gensec_fake_gssapi_krb5_security_ops = {
.session_key = gensec_krb5_session_key,
.session_info = gensec_krb5_session_info,
.have_feature = gensec_krb5_have_feature,
- .wrap = gensec_krb5_wrap,
- .unwrap = gensec_krb5_unwrap,
.enabled = False
};
@@ -662,6 +662,8 @@ static const struct gensec_security_ops gensec_krb5_security_ops = {
.session_key = gensec_krb5_session_key,
.session_info = gensec_krb5_session_info,
.have_feature = gensec_krb5_have_feature,
+ .wrap = gensec_krb5_wrap,
+ .unwrap = gensec_krb5_unwrap,
.enabled = True
};