diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/auth/gensec/gensec_krb5.c | 124 |
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 }; |