/* Get some basic (and authorization) information about the user on * 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, struct auth_session_info **_session_info) { NTSTATUS nt_status; TALLOC_CTX *tmp_ctx; struct gensec_gssapi_state *gensec_gssapi_state = talloc_get_type(gensec_security->private_data, struct gensec_gssapi_state); struct auth_session_info *session_info = NULL; OM_uint32 maj_stat, min_stat; DATA_BLOB pac_blob, *pac_blob_ptr = NULL; gss_buffer_desc name_token; char *principal_string; tmp_ctx = talloc_named(mem_ctx, 0, "gensec_gssapi_session_info context"); NT_STATUS_HAVE_NO_MEMORY(tmp_ctx); maj_stat = gss_display_name (&min_stat, gensec_gssapi_state->client_name, &name_token, NULL); if (GSS_ERROR(maj_stat)) { DEBUG(1, ("GSS display_name failed: %s\n", gssapi_error_string(tmp_ctx, maj_stat, min_stat, gensec_gssapi_state->gss_oid))); talloc_free(tmp_ctx); return NT_STATUS_FOOBAR; } principal_string = talloc_strndup(tmp_ctx, (const char *)name_token.value, name_token.length); gss_release_buffer(&min_stat, &name_token); if (!principal_string) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } nt_status = gssapi_obtain_pac_blob(tmp_ctx, gensec_gssapi_state->gssapi_context, gensec_gssapi_state->client_name, &pac_blob); /* IF we have the PAC - otherwise we need to get this * data from elsewere - local ldb, or (TODO) lookup of some * kind... */ if (NT_STATUS_IS_OK(nt_status)) { pac_blob_ptr = &pac_blob; } nt_status = gensec_generate_session_info_pac(tmp_ctx, gensec_security, gensec_gssapi_state->smb_krb5_context, pac_blob_ptr, principal_string, gensec_get_remote_address(gensec_security), &session_info); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return nt_status; } nt_status = gensec_gssapi_session_key(gensec_security, session_info, &session_info->session_key); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return nt_status; } if (gensec_gssapi_state->gss_got_flags & GSS_C_DELEG_FLAG && gensec_gssapi_state->delegated_cred_handle != GSS_C_NO_CREDENTIAL) { krb5_error_code ret; const char *error_string; DEBUG(10, ("gensec_gssapi: delegated credentials supplied by client\n")); session_info->credentials = cli_credentials_init(session_info); if (!session_info->credentials) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } cli_credentials_set_conf(session_info->credentials, gensec_security->settings->lp_ctx); /* Just so we don't segfault trying to get at a username */ cli_credentials_set_anonymous(session_info->credentials); ret = cli_credentials_set_client_gss_creds(session_info->credentials, gensec_security->settings->lp_ctx, gensec_gssapi_state->delegated_cred_handle, CRED_SPECIFIED, &error_string); if (ret) { talloc_free(tmp_ctx); DEBUG(2,("Failed to get gss creds: %s\n", error_string)); return NT_STATUS_NO_MEMORY; } /* This credential handle isn't useful for password authentication, so ensure nobody tries to do that */ cli_credentials_set_kerberos_state(session_info->credentials, CRED_MUST_USE_KERBEROS); /* It has been taken from this place... */ gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL; } else { DEBUG(10, ("gensec_gssapi: NO delegated credentials supplied by client\n")); } *_session_info = talloc_steal(mem_ctx, session_info); talloc_free(tmp_ctx); return NT_STATUS_OK; }
static NTSTATUS gensec_krb5_session_info(struct gensec_security *gensec_security, TALLOC_CTX *mem_ctx, struct auth_session_info **_session_info) { NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL; struct gensec_krb5_state *gensec_krb5_state = (struct gensec_krb5_state *)gensec_security->private_data; krb5_context context = gensec_krb5_state->smb_krb5_context->krb5_context; struct auth_session_info *session_info = NULL; krb5_principal client_principal; char *principal_string; DATA_BLOB pac_blob, *pac_blob_ptr = NULL; krb5_data pac_data; krb5_error_code ret; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); if (!tmp_ctx) { return NT_STATUS_NO_MEMORY; } ret = krb5_ticket_get_client(context, gensec_krb5_state->ticket, &client_principal); if (ret) { DEBUG(5, ("krb5_ticket_get_client failed to get cleint principal: %s\n", smb_get_krb5_error_message(context, ret, tmp_ctx))); talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } ret = krb5_unparse_name(gensec_krb5_state->smb_krb5_context->krb5_context, client_principal, &principal_string); if (ret) { DEBUG(1, ("Unable to parse client principal: %s\n", smb_get_krb5_error_message(context, ret, tmp_ctx))); krb5_free_principal(context, client_principal); talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } ret = krb5_ticket_get_authorization_data_type(context, gensec_krb5_state->ticket, KRB5_AUTHDATA_WIN2K_PAC, &pac_data); if (ret) { /* NO pac */ DEBUG(5, ("krb5_ticket_get_authorization_data_type failed to find PAC: %s\n", smb_get_krb5_error_message(context, ret, tmp_ctx))); } else { /* Found pac */ pac_blob = data_blob_talloc(tmp_ctx, pac_data.data, pac_data.length); if (!pac_blob.data) { free(principal_string); krb5_free_principal(context, client_principal); talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } /* decode and verify the pac */ nt_status = kerberos_decode_pac(gensec_krb5_state, pac_blob, gensec_krb5_state->smb_krb5_context->krb5_context, NULL, gensec_krb5_state->keyblock, client_principal, gensec_krb5_state->ticket->ticket.authtime, NULL); if (!NT_STATUS_IS_OK(nt_status)) { free(principal_string); krb5_free_principal(context, client_principal); talloc_free(tmp_ctx); return nt_status; } pac_blob_ptr = &pac_blob; } nt_status = gensec_generate_session_info_pac(tmp_ctx, gensec_security, gensec_krb5_state->smb_krb5_context, pac_blob_ptr, principal_string, gensec_get_remote_address(gensec_security), &session_info); free(principal_string); krb5_free_principal(context, client_principal); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return nt_status; } nt_status = gensec_krb5_session_key(gensec_security, session_info, &session_info->session_key); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return nt_status; } *_session_info = talloc_steal(mem_ctx, session_info); talloc_free(tmp_ctx); return NT_STATUS_OK; }