4
* Copyright 2006-2008 Massachusetts Institute of Technology.
7
* Export of this software from the United States of America may
8
* require a specific license from the United States Government.
9
* It is the responsibility of any person or organization contemplating
10
* export to obtain such a license before exporting.
12
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13
* distribute this software and its documentation for any purpose and
14
* without fee is hereby granted, provided that the above copyright
15
* notice appear in all copies and that both that copyright notice and
16
* this permission notice appear in supporting documentation, and that
17
* the name of M.I.T. not be used in advertising or publicity pertaining
18
* to distribution of the software without specific, written prior
19
* permission. Furthermore if you modify this software you must label
20
* your software as modified software and not distribute it in such a
21
* fashion that it might be confused with the original M.I.T. software.
22
* M.I.T. makes no representations about the suitability of
23
* this software for any purpose. It is provided "as is" without express
24
* or implied warranty.
27
#define KRB5_PRIVATE 1
30
#include "k5-thread.h"
31
#include <krb5/krb5.h>
34
#include "kim_private.h"
35
#include "kim_os_private.h"
38
#include "KerberosLoginErrors.h"
41
MAKE_INIT_FUNCTION(kim_error_init);
42
MAKE_FINI_FUNCTION(kim_error_fini);
44
/* ------------------------------------------------------------------------ */
46
static int kim_error_init (void)
48
add_error_table (&et_KIM_error_table);
50
add_error_table (&et_KLL_error_table);
55
/* ------------------------------------------------------------------------ */
57
static void kim_error_fini (void)
59
if (!INITIALIZER_RAN (kim_error_init) || PROGRAM_EXITING ()) {
63
remove_error_table (&et_KIM_error_table);
65
remove_error_table (&et_KLL_error_table);
69
/* ------------------------------------------------------------------------ */
71
kim_error kim_library_init (void)
73
return CALL_INIT_FUNCTION (kim_error_init);
78
static k5_mutex_t g_allow_home_directory_access_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
79
static k5_mutex_t g_allow_automatic_prompting_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
80
static k5_mutex_t g_ui_environment_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
81
static k5_mutex_t g_application_name_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
83
kim_boolean g_allow_home_directory_access = TRUE;
84
kim_boolean g_allow_automatic_prompting = TRUE;
85
kim_ui_environment g_ui_environment = KIM_UI_ENVIRONMENT_AUTO;
86
kim_string g_application_name = NULL;
88
MAKE_INIT_FUNCTION(kim_thread_init);
89
MAKE_FINI_FUNCTION(kim_thread_fini);
91
/* ------------------------------------------------------------------------ */
93
static int kim_thread_init (void)
95
kim_error err = KIM_NO_ERROR;
98
err = k5_mutex_finish_init (&g_allow_home_directory_access_mutex);
102
err = k5_mutex_finish_init (&g_allow_automatic_prompting_mutex);
106
err = k5_mutex_finish_init (&g_ui_environment_mutex);
110
err = k5_mutex_finish_init (&g_application_name_mutex);
116
/* ------------------------------------------------------------------------ */
118
static void kim_thread_fini (void)
120
if (!INITIALIZER_RAN (kim_thread_init) || PROGRAM_EXITING ()) {
124
k5_mutex_destroy (&g_allow_home_directory_access_mutex);
125
k5_mutex_destroy (&g_allow_automatic_prompting_mutex);
126
k5_mutex_destroy (&g_ui_environment_mutex);
127
k5_mutex_destroy (&g_application_name_mutex);
130
#pragma mark -- Allow Home Directory Access --
132
/* ------------------------------------------------------------------------ */
134
kim_error kim_library_set_allow_home_directory_access (kim_boolean in_allow_access)
136
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
137
kim_error mutex_err = KIM_NO_ERROR;
140
mutex_err = k5_mutex_lock (&g_allow_home_directory_access_mutex);
141
if (mutex_err) { err = mutex_err; }
145
g_allow_home_directory_access = in_allow_access;
148
if (!mutex_err) { k5_mutex_unlock (&g_allow_home_directory_access_mutex); }
149
return check_error (err);
152
/* ------------------------------------------------------------------------ */
154
static kim_error kim_library_get_allow_home_directory_access (kim_boolean *out_allow_access)
156
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
157
kim_error mutex_err = KIM_NO_ERROR;
159
if (!err && !out_allow_access) { err = check_error (KIM_NULL_PARAMETER_ERR); }
162
mutex_err = k5_mutex_lock (&g_allow_home_directory_access_mutex);;
163
if (mutex_err) { err = mutex_err; }
167
*out_allow_access = g_allow_home_directory_access;
170
if (!mutex_err) { k5_mutex_unlock (&g_allow_home_directory_access_mutex); }
171
return check_error (err);
174
/* ------------------------------------------------------------------------ */
176
kim_boolean kim_library_allow_home_directory_access (void)
178
kim_boolean allow_access = FALSE;
179
kim_error err = kim_library_get_allow_home_directory_access (&allow_access);
181
return !err ? allow_access : FALSE;
185
#pragma mark -- Allow Automatic Prompting --
188
/* ------------------------------------------------------------------------ */
190
kim_error kim_library_set_allow_automatic_prompting (kim_boolean in_allow_automatic_prompting)
192
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
193
kim_error mutex_err = KIM_NO_ERROR;
196
mutex_err = k5_mutex_lock (&g_allow_automatic_prompting_mutex);
197
if (mutex_err) { err = mutex_err; }
201
g_allow_automatic_prompting = in_allow_automatic_prompting;
204
if (!mutex_err) { k5_mutex_unlock (&g_allow_automatic_prompting_mutex); }
205
return check_error (err);
208
/* ------------------------------------------------------------------------ */
210
static kim_error kim_library_get_allow_automatic_prompting (kim_boolean *out_allow_automatic_prompting)
212
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
213
kim_error mutex_err = KIM_NO_ERROR;
215
if (!err && !out_allow_automatic_prompting) { err = check_error (KIM_NULL_PARAMETER_ERR); }
218
mutex_err = k5_mutex_lock (&g_allow_automatic_prompting_mutex);;
219
if (mutex_err) { err = mutex_err; }
223
*out_allow_automatic_prompting = g_allow_automatic_prompting;
226
if (!mutex_err) { k5_mutex_unlock (&g_allow_automatic_prompting_mutex); }
227
return check_error (err);
230
/* ------------------------------------------------------------------------ */
232
kim_boolean kim_library_allow_automatic_prompting (void)
234
kim_boolean allow_automatic_prompting = TRUE;
235
kim_error err = kim_library_get_allow_automatic_prompting (&allow_automatic_prompting);
236
if (err) { allow_automatic_prompting = TRUE; }
238
if (allow_automatic_prompting && getenv ("KERBEROSLOGIN_NEVER_PROMPT")) {
239
kim_debug_printf ("KERBEROSLOGIN_NEVER_PROMPT is set.");
240
allow_automatic_prompting = FALSE;
243
if (allow_automatic_prompting && getenv ("KIM_NEVER_PROMPT")) {
244
kim_debug_printf ("KIM_NEVER_PROMPT is set.");
245
allow_automatic_prompting = FALSE;
248
if (allow_automatic_prompting && !kim_os_library_caller_uses_gui ()) {
249
kim_debug_printf ("Caller is not using gui.");
250
allow_automatic_prompting = FALSE;
253
if (allow_automatic_prompting) {
254
/* Make sure there is at least 1 config file. We don't support DNS
255
* domain-realm lookup, so if there is no config, Kerberos won't work. */
257
kim_boolean kerberos_config_exists = FALSE;
259
profile_t profile = NULL;
261
if (krb5_get_default_config_files (&files) == 0) {
262
if (profile_init ((const_profile_filespec_t *) files, &profile) == 0) {
263
kerberos_config_exists = TRUE;
267
if (!kerberos_config_exists) {
268
kim_debug_printf ("No valid config file.");
269
allow_automatic_prompting = FALSE;
272
if (profile) { profile_abandon (profile); }
273
if (files ) { krb5_free_config_files (files); }
276
return allow_automatic_prompting;
279
#pragma mark -- UI Environment --
281
/* ------------------------------------------------------------------------ */
283
kim_error kim_library_set_ui_environment (kim_ui_environment in_ui_environment)
285
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
286
kim_error mutex_err = KIM_NO_ERROR;
289
mutex_err = k5_mutex_lock (&g_ui_environment_mutex);
290
if (mutex_err) { err = mutex_err; }
294
g_ui_environment = in_ui_environment;
297
if (!mutex_err) { k5_mutex_unlock (&g_ui_environment_mutex); }
298
return check_error (err);
301
/* ------------------------------------------------------------------------ */
303
static kim_error kim_library_get_ui_environment (kim_ui_environment *out_ui_environment)
305
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
306
kim_error mutex_err = KIM_NO_ERROR;
308
if (!err && !out_ui_environment) { err = check_error (KIM_NULL_PARAMETER_ERR); }
311
mutex_err = k5_mutex_lock (&g_ui_environment_mutex);;
312
if (mutex_err) { err = mutex_err; }
316
*out_ui_environment = g_ui_environment;
319
if (!mutex_err) { k5_mutex_unlock (&g_ui_environment_mutex); }
320
return check_error (err);
323
/* ------------------------------------------------------------------------ */
325
kim_ui_environment kim_library_ui_environment (void)
327
kim_error err = KIM_NO_ERROR;
328
kim_ui_environment ui_environment = KIM_UI_ENVIRONMENT_AUTO;
330
err = kim_library_get_ui_environment (&ui_environment);
332
if (!err && ui_environment == KIM_UI_ENVIRONMENT_AUTO) {
333
ui_environment = kim_os_library_get_ui_environment ();
336
return !err ? ui_environment : KIM_UI_ENVIRONMENT_NONE;
339
#pragma mark -- Application Name --
341
/* ------------------------------------------------------------------------ */
343
kim_error kim_library_set_application_name (kim_string in_application_name)
345
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
346
kim_error mutex_err = KIM_NO_ERROR;
349
mutex_err = k5_mutex_lock (&g_application_name_mutex);
350
if (mutex_err) { err = mutex_err; }
354
kim_string old_application_name = g_application_name;
356
if (in_application_name) {
357
err = kim_string_copy (&g_application_name, in_application_name);
359
g_application_name = NULL;
362
if (!err) { kim_string_free (&old_application_name); }
365
if (!mutex_err) { k5_mutex_unlock (&g_application_name_mutex); }
366
return check_error (err);
369
/* ------------------------------------------------------------------------ */
371
kim_error kim_library_get_application_name (kim_string *out_application_name)
373
kim_error err = CALL_INIT_FUNCTION (kim_thread_init);
374
kim_error mutex_err = KIM_NO_ERROR;
375
kim_string application_name = NULL;
377
if (!err && !out_application_name) { err = check_error (KIM_NULL_PARAMETER_ERR); }
380
mutex_err = k5_mutex_lock (&g_application_name_mutex);
381
if (mutex_err) { err = mutex_err; }
384
if (!err && g_application_name) {
385
err = kim_string_copy (&application_name, g_application_name);
388
if (!mutex_err) { k5_mutex_unlock (&g_application_name_mutex); }
390
if (!err && !application_name) {
391
err = kim_os_library_get_caller_name (&application_name);
395
*out_application_name = application_name;
396
application_name = NULL;
400
kim_string_free (&application_name);
402
return check_error (err);