#define KRB5_PRIVATE 1
#include "k5-int.h"
#include "k5-thread.h"
#include <krb5/krb5.h>
#include <profile.h>
#include "kim_private.h"
#include "kim_os_private.h"
#if KIM_TO_KLL_SHIM
#include "KerberosLoginErrors.h"
#endif
MAKE_INIT_FUNCTION(kim_error_init);
MAKE_FINI_FUNCTION(kim_error_fini);
static int kim_error_init (void)
{
add_error_table (&et_KIM_error_table);
#if KIM_TO_KLL_SHIM
add_error_table (&et_KLL_error_table);
#endif
return 0;
}
static void kim_error_fini (void)
{
if (!INITIALIZER_RAN (kim_error_init) || PROGRAM_EXITING ()) {
return;
}
remove_error_table (&et_KIM_error_table);
#if KIM_TO_KLL_SHIM
remove_error_table (&et_KLL_error_table);
#endif
}
kim_error kim_library_init (void)
{
return CALL_INIT_FUNCTION (kim_error_init);
}
#pragma mark -
static k5_mutex_t g_allow_home_directory_access_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
static k5_mutex_t g_allow_automatic_prompting_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
static k5_mutex_t g_ui_environment_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
static k5_mutex_t g_application_name_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
kim_boolean g_allow_home_directory_access = TRUE;
kim_boolean g_allow_automatic_prompting = TRUE;
kim_ui_environment g_ui_environment = KIM_UI_ENVIRONMENT_AUTO;
kim_string g_application_name = NULL;
MAKE_INIT_FUNCTION(kim_thread_init);
MAKE_FINI_FUNCTION(kim_thread_fini);
static int kim_thread_init (void)
{
kim_error err = KIM_NO_ERROR;
if (!err) {
err = k5_mutex_finish_init (&g_allow_home_directory_access_mutex);
}
if (!err) {
err = k5_mutex_finish_init (&g_allow_automatic_prompting_mutex);
}
if (!err) {
err = k5_mutex_finish_init (&g_ui_environment_mutex);
}
if (!err) {
err = k5_mutex_finish_init (&g_application_name_mutex);
}
return err;
}
static void kim_thread_fini (void)
{
if (!INITIALIZER_RAN (kim_thread_init) || PROGRAM_EXITING ()) {
return;
}
k5_mutex_destroy (&g_allow_home_directory_access_mutex);
k5_mutex_destroy (&g_allow_automatic_prompting_mutex);
k5_mutex_destroy (&g_ui_environment_mutex);
k5_mutex_destroy (&g_application_name_mutex);
}
#pragma mark -- Allow Home Directory Access --
kim_error kim_library_set_allow_home_directory_access (kim_boolean in_allow_access)
{
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
kim_error mutex_err = KIM_NO_ERROR;
if (!err) {
mutex_err = k5_mutex_lock (&g_allow_home_directory_access_mutex);
if (mutex_err) { err = mutex_err; }
}
if (!err) {
g_allow_home_directory_access = in_allow_access;
}
if (!mutex_err) { k5_mutex_unlock (&g_allow_home_directory_access_mutex); }
return check_error (err);
}
static kim_error kim_library_get_allow_home_directory_access (kim_boolean *out_allow_access)
{
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
kim_error mutex_err = KIM_NO_ERROR;
if (!err && !out_allow_access) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
mutex_err = k5_mutex_lock (&g_allow_home_directory_access_mutex);;
if (mutex_err) { err = mutex_err; }
}
if (!err) {
*out_allow_access = g_allow_home_directory_access;
}
if (!mutex_err) { k5_mutex_unlock (&g_allow_home_directory_access_mutex); }
return check_error (err);
}
kim_boolean kim_library_allow_home_directory_access (void)
{
kim_boolean allow_access = FALSE;
kim_error err = kim_library_get_allow_home_directory_access (&allow_access);
return !err ? allow_access : FALSE;
}
#pragma mark -- Allow Automatic Prompting --
kim_error kim_library_set_allow_automatic_prompting (kim_boolean in_allow_automatic_prompting)
{
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
kim_error mutex_err = KIM_NO_ERROR;
if (!err) {
mutex_err = k5_mutex_lock (&g_allow_automatic_prompting_mutex);
if (mutex_err) { err = mutex_err; }
}
if (!err) {
g_allow_automatic_prompting = in_allow_automatic_prompting;
}
if (!mutex_err) { k5_mutex_unlock (&g_allow_automatic_prompting_mutex); }
return check_error (err);
}
static kim_error kim_library_get_allow_automatic_prompting (kim_boolean *out_allow_automatic_prompting)
{
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
kim_error mutex_err = KIM_NO_ERROR;
if (!err && !out_allow_automatic_prompting) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
mutex_err = k5_mutex_lock (&g_allow_automatic_prompting_mutex);;
if (mutex_err) { err = mutex_err; }
}
if (!err) {
*out_allow_automatic_prompting = g_allow_automatic_prompting;
}
if (!mutex_err) { k5_mutex_unlock (&g_allow_automatic_prompting_mutex); }
return check_error (err);
}
kim_boolean kim_library_allow_automatic_prompting (void)
{
kim_boolean allow_automatic_prompting = TRUE;
kim_error err = kim_library_get_allow_automatic_prompting (&allow_automatic_prompting);
if (err) { allow_automatic_prompting = TRUE; }
if (allow_automatic_prompting && getenv ("KERBEROSLOGIN_NEVER_PROMPT")) {
kim_debug_printf ("KERBEROSLOGIN_NEVER_PROMPT is set.");
allow_automatic_prompting = FALSE;
}
if (allow_automatic_prompting && getenv ("KIM_NEVER_PROMPT")) {
kim_debug_printf ("KIM_NEVER_PROMPT is set.");
allow_automatic_prompting = FALSE;
}
if (allow_automatic_prompting && !kim_os_library_caller_uses_gui ()) {
kim_debug_printf ("Caller is not using gui.");
allow_automatic_prompting = FALSE;
}
if (allow_automatic_prompting) {
kim_boolean kerberos_config_exists = FALSE;
char **files = NULL;
profile_t profile = NULL;
if (krb5_get_default_config_files (&files) == 0) {
if (profile_init ((const_profile_filespec_t *) files, &profile) == 0) {
kerberos_config_exists = TRUE;
}
}
if (!kerberos_config_exists) {
kim_debug_printf ("No valid config file.");
allow_automatic_prompting = FALSE;
}
if (profile) { profile_abandon (profile); }
if (files ) { krb5_free_config_files (files); }
}
return allow_automatic_prompting;
}
#pragma mark -- UI Environment --
kim_error kim_library_set_ui_environment (kim_ui_environment in_ui_environment)
{
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
kim_error mutex_err = KIM_NO_ERROR;
if (!err) {
mutex_err = k5_mutex_lock (&g_ui_environment_mutex);
if (mutex_err) { err = mutex_err; }
}
if (!err) {
g_ui_environment = in_ui_environment;
}
if (!mutex_err) { k5_mutex_unlock (&g_ui_environment_mutex); }
return check_error (err);
}
static kim_error kim_library_get_ui_environment (kim_ui_environment *out_ui_environment)
{
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
kim_error mutex_err = KIM_NO_ERROR;
if (!err && !out_ui_environment) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
mutex_err = k5_mutex_lock (&g_ui_environment_mutex);;
if (mutex_err) { err = mutex_err; }
}
if (!err) {
*out_ui_environment = g_ui_environment;
}
if (!mutex_err) { k5_mutex_unlock (&g_ui_environment_mutex); }
return check_error (err);
}
kim_ui_environment kim_library_ui_environment (void)
{
kim_error err = KIM_NO_ERROR;
kim_ui_environment ui_environment = KIM_UI_ENVIRONMENT_AUTO;
err = kim_library_get_ui_environment (&ui_environment);
if (!err && ui_environment == KIM_UI_ENVIRONMENT_AUTO) {
ui_environment = kim_os_library_get_ui_environment ();
}
return !err ? ui_environment : KIM_UI_ENVIRONMENT_NONE;
}
#pragma mark -- Application Name --
kim_error kim_library_set_application_name (kim_string in_application_name)
{
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
kim_error mutex_err = KIM_NO_ERROR;
if (!err) {
mutex_err = k5_mutex_lock (&g_application_name_mutex);
if (mutex_err) { err = mutex_err; }
}
if (!err) {
kim_string old_application_name = g_application_name;
if (in_application_name) {
err = kim_string_copy (&g_application_name, in_application_name);
} else {
g_application_name = NULL;
}
if (!err) { kim_string_free (&old_application_name); }
}
if (!mutex_err) { k5_mutex_unlock (&g_application_name_mutex); }
return check_error (err);
}
kim_error kim_library_get_application_name (kim_string *out_application_name)
{
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
kim_error mutex_err = KIM_NO_ERROR;
kim_string application_name = NULL;
if (!err && !out_application_name) { err = check_error (KIM_NULL_PARAMETER_ERR); }
if (!err) {
mutex_err = k5_mutex_lock (&g_application_name_mutex);
if (mutex_err) { err = mutex_err; }
}
if (!err && g_application_name) {
err = kim_string_copy (&application_name, g_application_name);
}
if (!mutex_err) { k5_mutex_unlock (&g_application_name_mutex); }
if (!err && !application_name) {
err = kim_os_library_get_caller_name (&application_name);
}
if (!err) {
*out_application_name = application_name;
application_name = NULL;
}
kim_string_free (&application_name);
return check_error (err);
}