/
githubmirror
/
gssproxy
Обзор
Документация
Войти
/
githubmirror
/
gssproxy
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/client/gpm_display_status.c
122 строки
4 KB
Simo Sorce
Use pthread keys for thread local storage
21 сен 2018, 00:45
21 сен 2018, 00:45
0faccc1
Код
Авторство
О чём код?
/* Copyright (C) 2011 the GSS-PROXY contributors, see COPYING for license */ #include "gssapi_gpm.h" #include <pthread.h> static pthread_key_t gpm_last_status; static void gpm_destroy_last_status(void *arg) { gssx_status *status = (gssx_status *)arg; xdr_free((xdrproc_t)xdr_gssx_status, (char *)status); free(status); } void gpm_display_status_init_once(void) { (void)pthread_key_create(&gpm_last_status, gpm_destroy_last_status); } /* Portable thread local storage for return status. */ void gpm_save_status(gssx_status *status) { gssx_status *last_status; int ret; last_status = (gssx_status *)pthread_getspecific(gpm_last_status); if (last_status != NULL) { /* store NULL first so we do not risk a double free if we are * racing on a pthread_cancel */ pthread_setspecific(gpm_last_status, NULL); gpm_destroy_last_status(last_status); } ret = gp_copy_gssx_status_alloc(status, &last_status); if (ret == 0) { pthread_setspecific(gpm_last_status, last_status); } } gssx_status *gpm_get_saved_status(void) { return (gssx_status *)pthread_getspecific(gpm_last_status); } /* This funciton is used to record internal mech errors that are * generated by the proxy client code */ void gpm_save_internal_status(uint32_t err, char *err_str) { gssx_status status; memset(&status, 0, sizeof(gssx_status)); #define STD_MAJ_ERROR_STR "Internal gssproxy error" status.major_status = GSS_S_FAILURE; status.major_status_string.utf8string_val = strdup(STD_MAJ_ERROR_STR); status.major_status_string.utf8string_len = sizeof(STD_MAJ_ERROR_STR); status.minor_status = err; status.minor_status_string.utf8string_val = err_str; status.minor_status_string.utf8string_len = strlen(err_str) + 1; gpm_save_status(&status); } OM_uint32 gpm_display_status(OM_uint32 *minor_status, OM_uint32 status_value, int status_type, const gss_OID mech_type UNUSED, OM_uint32 *message_context, gss_buffer_t status_string) { gssx_status *last_status = gpm_get_saved_status(); utf8string tmp; int ret; switch(status_type) { case GSS_C_GSS_CODE: if (last_status && last_status->major_status == status_value && last_status->major_status_string.utf8string_len) { ret = gp_copy_utf8string(&last_status->major_status_string, &tmp); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } status_string->value = tmp.utf8string_val; status_string->length = tmp.utf8string_len; *minor_status = 0; return GSS_S_COMPLETE; } else { /* if we do not have it, make it clear */ return GSS_S_UNAVAILABLE; } case GSS_C_MECH_CODE: if (last_status && last_status->minor_status == status_value && last_status->minor_status_string.utf8string_len) { if (*message_context) { /* we do not support multiple messages for now */ *minor_status = EINVAL; return GSS_S_FAILURE; } ret = gp_copy_utf8string(&last_status->minor_status_string, &tmp); if (ret) { *minor_status = ret; return GSS_S_FAILURE; } status_string->value = tmp.utf8string_val; status_string->length = tmp.utf8string_len; } else { /* if we do not have it, make it clear */ return GSS_S_UNAVAILABLE; } *minor_status = 0; return GSS_S_COMPLETE; default: *minor_status = EINVAL; return GSS_S_BAD_STATUS; } }