/* Fill out the auth_session_info with a cli_credentials based on the * auth_session_info we were forwarded over named pipe forwarding. * * NOTE: The stucture members of session_info_transport are stolen * with talloc_move() into auth_session_info for long term use */ struct auth_session_info *auth_session_info_from_transport(TALLOC_CTX *mem_ctx, struct auth_session_info_transport *session_info_transport, struct loadparm_context *lp_ctx, const char **reason) { struct auth_session_info *session_info; session_info = talloc_steal(mem_ctx, session_info_transport->session_info); if (session_info_transport->exported_gssapi_credentials.length) { struct cli_credentials *creds; OM_uint32 minor_status; gss_buffer_desc cred_token; gss_cred_id_t cred_handle; const char *error_string; int ret; DEBUG(10, ("Delegated credentials supplied by client\n")); cred_token.value = session_info_transport->exported_gssapi_credentials.data; cred_token.length = session_info_transport->exported_gssapi_credentials.length; ret = gss_import_cred(&minor_status, &cred_token, &cred_handle); if (ret != GSS_S_COMPLETE) { *reason = "Internal error in gss_import_cred()"; return NULL; } creds = cli_credentials_init(session_info); if (!creds) { *reason = "Out of memory in cli_credentials_init()"; return NULL; } session_info->credentials = creds; cli_credentials_set_conf(creds, lp_ctx); /* Just so we don't segfault trying to get at a username */ cli_credentials_set_anonymous(creds); ret = cli_credentials_set_client_gss_creds(creds, lp_ctx, cred_handle, CRED_SPECIFIED, &error_string); if (ret) { *reason = talloc_asprintf(mem_ctx, "Failed to set pipe forwarded" "creds: %s\n", error_string); return NULL; } /* This credential handle isn't useful for password * authentication, so ensure nobody tries to do that */ cli_credentials_set_kerberos_state(creds, CRED_MUST_USE_KERBEROS); } return session_info; }
/* 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; }