154925bf6Swillf /* 2*2dd2efa5Swillf * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 354925bf6Swillf * Use is subject to license terms. 454925bf6Swillf */ 554925bf6Swillf 654925bf6Swillf #pragma ident "%Z%%M% %I% %E% SMI" 754925bf6Swillf /* 854925bf6Swillf * Copyright 2006 by the Massachusetts Institute of Technology. 954925bf6Swillf * All Rights Reserved. 1054925bf6Swillf * 1154925bf6Swillf * Export of this software from the United States of America may 1254925bf6Swillf * require a specific license from the United States Government. 1354925bf6Swillf * It is the responsibility of any person or organization contemplating 1454925bf6Swillf * export to obtain such a license before exporting. 1554925bf6Swillf * 1654925bf6Swillf * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 1754925bf6Swillf * distribute this software and its documentation for any purpose and 1854925bf6Swillf * without fee is hereby granted, provided that the above copyright 1954925bf6Swillf * notice appear in all copies and that both that copyright notice and 2054925bf6Swillf * this permission notice appear in supporting documentation, and that 2154925bf6Swillf * the name of M.I.T. not be used in advertising or publicity pertaining 2254925bf6Swillf * to distribution of the software without specific, written prior 2354925bf6Swillf * permission. Furthermore if you modify this software you must label 2454925bf6Swillf * your software as modified software and not distribute it in such a 2554925bf6Swillf * fashion that it might be confused with the original M.I.T. software. 2654925bf6Swillf * M.I.T. makes no representations about the suitability of 2754925bf6Swillf * this software for any purpose. It is provided "as is" without express 2854925bf6Swillf * or implied warranty. 2954925bf6Swillf */ 3054925bf6Swillf 3154925bf6Swillf /* 3254925bf6Swillf * This code was based on code donated to MIT by Novell for 3354925bf6Swillf * distribution under the MIT license. 3454925bf6Swillf */ 3554925bf6Swillf 3654925bf6Swillf /* 3754925bf6Swillf * Include files 3854925bf6Swillf */ 3954925bf6Swillf 4054925bf6Swillf #include <stdio.h> 4154925bf6Swillf #include <string.h> 4254925bf6Swillf #include <k5-int.h> 4354925bf6Swillf #include <osconf.h> 4454925bf6Swillf #include "kdb5.h" 4554925bf6Swillf #include <assert.h> 4654925bf6Swillf #include "k5-platform.h" 4754925bf6Swillf #include <libintl.h> 4854925bf6Swillf 4954925bf6Swillf /* Currently DB2 policy related errors are exported from DAL. But 5054925bf6Swillf other databases should set_err function to return string. */ 5154925bf6Swillf #include "adb_err.h" 5254925bf6Swillf 5354925bf6Swillf /* 5454925bf6Swillf * Type definitions 5554925bf6Swillf */ 5654925bf6Swillf #define KRB5_TL_DB_ARGS 0x7fff 5754925bf6Swillf 5854925bf6Swillf /* 5954925bf6Swillf * internal static variable 6054925bf6Swillf */ 6154925bf6Swillf 6254925bf6Swillf static k5_mutex_t db_lock = K5_MUTEX_PARTIAL_INITIALIZER; 6354925bf6Swillf 6454925bf6Swillf #ifdef _KDB5_STATIC_LINK 6554925bf6Swillf #undef _KDB5_DYNAMIC_LINK 6654925bf6Swillf #else 6754925bf6Swillf #undef _KDB5_DYNAMIC_LINK 6854925bf6Swillf /* to avoid redefinition problem */ 6954925bf6Swillf #define _KDB5_DYNAMIC_LINK 7054925bf6Swillf #endif 7154925bf6Swillf 7254925bf6Swillf static db_library lib_list; 7354925bf6Swillf 7454925bf6Swillf /* 7554925bf6Swillf * Helper Functions 7654925bf6Swillf */ 7754925bf6Swillf 7854925bf6Swillf MAKE_INIT_FUNCTION(kdb_init_lock_list); 7954925bf6Swillf MAKE_FINI_FUNCTION(kdb_fini_lock_list); 8054925bf6Swillf 8154925bf6Swillf int 8254925bf6Swillf kdb_init_lock_list(void) 8354925bf6Swillf { 8454925bf6Swillf return k5_mutex_finish_init(&db_lock); 8554925bf6Swillf } 8654925bf6Swillf 8754925bf6Swillf static int 8854925bf6Swillf kdb_lock_list() 8954925bf6Swillf { 9054925bf6Swillf int err; 9154925bf6Swillf err = CALL_INIT_FUNCTION (kdb_init_lock_list); 9254925bf6Swillf if (err) 9354925bf6Swillf return err; 9454925bf6Swillf return k5_mutex_lock(&db_lock); 9554925bf6Swillf } 9654925bf6Swillf 9754925bf6Swillf void 9854925bf6Swillf kdb_fini_lock_list(void) 9954925bf6Swillf { 10054925bf6Swillf if (INITIALIZER_RAN(kdb_init_lock_list)) 10154925bf6Swillf k5_mutex_destroy(&db_lock); 10254925bf6Swillf } 10354925bf6Swillf 10454925bf6Swillf static int 10554925bf6Swillf kdb_unlock_list() 10654925bf6Swillf { 10754925bf6Swillf return k5_mutex_unlock(&db_lock); 10854925bf6Swillf } 10954925bf6Swillf 11054925bf6Swillf #define kdb_init_lib_lock(a) 0 11154925bf6Swillf #define kdb_destroy_lib_lock(a) (void)0 11254925bf6Swillf #define kdb_lock_lib_lock(a, b) 0 11354925bf6Swillf #define kdb_unlock_lib_lock(a, b) (void)0 11454925bf6Swillf 11554925bf6Swillf /* Caller must free result*/ 11654925bf6Swillf 11754925bf6Swillf static char * 11854925bf6Swillf kdb_get_conf_section(krb5_context kcontext) 11954925bf6Swillf { 12054925bf6Swillf krb5_error_code status = 0; 12154925bf6Swillf char *result = NULL; 12254925bf6Swillf char *value = NULL; 12354925bf6Swillf 12454925bf6Swillf if (kcontext->default_realm == NULL) 12554925bf6Swillf return NULL; 12654925bf6Swillf /* The profile has to have been initialized. If the profile was 12754925bf6Swillf not initialized, expect nothing less than a crash. */ 12854925bf6Swillf status = profile_get_string(kcontext->profile, 12954925bf6Swillf /* realms */ 13054925bf6Swillf KDB_REALM_SECTION, 13154925bf6Swillf kcontext->default_realm, 13254925bf6Swillf /* under the realm name, database_module */ 13354925bf6Swillf KDB_MODULE_POINTER, 13454925bf6Swillf /* default value is the realm name itself */ 13554925bf6Swillf kcontext->default_realm, 13654925bf6Swillf &value); 13754925bf6Swillf 13854925bf6Swillf if (status) { 13954925bf6Swillf /* some problem */ 14054925bf6Swillf result = strdup(kcontext->default_realm); 14154925bf6Swillf /* let NULL be handled by the caller */ 14254925bf6Swillf } else { 14354925bf6Swillf result = strdup(value); 14454925bf6Swillf /* free profile string */ 14554925bf6Swillf profile_release_string(value); 14654925bf6Swillf } 14754925bf6Swillf 14854925bf6Swillf return result; 14954925bf6Swillf } 15054925bf6Swillf 15154925bf6Swillf static char * 15254925bf6Swillf kdb_get_library_name(krb5_context kcontext) 15354925bf6Swillf { 15454925bf6Swillf krb5_error_code status = 0; 15554925bf6Swillf char *result = NULL; 15654925bf6Swillf char *value = NULL; 15754925bf6Swillf char *lib = NULL; 15854925bf6Swillf 15954925bf6Swillf status = profile_get_string(kcontext->profile, 16054925bf6Swillf /* realms */ 16154925bf6Swillf KDB_REALM_SECTION, 16254925bf6Swillf kcontext->default_realm, 16354925bf6Swillf /* under the realm name, database_module */ 16454925bf6Swillf KDB_MODULE_POINTER, 16554925bf6Swillf /* default value is the realm name itself */ 16654925bf6Swillf kcontext->default_realm, 16754925bf6Swillf &value); 16854925bf6Swillf if (status) { 16954925bf6Swillf goto clean_n_exit; 17054925bf6Swillf } 17154925bf6Swillf 17254925bf6Swillf #define DB2_NAME "db2" 17354925bf6Swillf /* we got the module section. Get the library name from the module */ 17454925bf6Swillf status = profile_get_string(kcontext->profile, KDB_MODULE_SECTION, value, 17554925bf6Swillf KDB_LIB_POINTER, 17654925bf6Swillf /* default to db2 */ 17754925bf6Swillf DB2_NAME, 17854925bf6Swillf &lib); 17954925bf6Swillf 18054925bf6Swillf if (status) { 18154925bf6Swillf goto clean_n_exit; 18254925bf6Swillf } 18354925bf6Swillf 18454925bf6Swillf result = strdup(lib); 18554925bf6Swillf clean_n_exit: 18654925bf6Swillf if (value) { 18754925bf6Swillf /* free profile string */ 18854925bf6Swillf profile_release_string(value); 18954925bf6Swillf } 19054925bf6Swillf 19154925bf6Swillf if (lib) { 19254925bf6Swillf /* free profile string */ 19354925bf6Swillf profile_release_string(lib); 19454925bf6Swillf } 19554925bf6Swillf return result; 19654925bf6Swillf } 19754925bf6Swillf 19854925bf6Swillf static void 19954925bf6Swillf kdb_setup_opt_functions(db_library lib) 20054925bf6Swillf { 20154925bf6Swillf if (lib->vftabl.set_master_key == NULL) { 20254925bf6Swillf lib->vftabl.set_master_key = kdb_def_set_mkey; 20354925bf6Swillf } 20454925bf6Swillf 20554925bf6Swillf if (lib->vftabl.get_master_key == NULL) { 20654925bf6Swillf lib->vftabl.get_master_key = kdb_def_get_mkey; 20754925bf6Swillf } 20854925bf6Swillf 20954925bf6Swillf if (lib->vftabl.fetch_master_key == NULL) { 21054925bf6Swillf lib->vftabl.fetch_master_key = krb5_db_def_fetch_mkey; 21154925bf6Swillf } 21254925bf6Swillf 21354925bf6Swillf if (lib->vftabl.verify_master_key == NULL) { 21454925bf6Swillf lib->vftabl.verify_master_key = krb5_def_verify_master_key; 21554925bf6Swillf } 21654925bf6Swillf 21754925bf6Swillf if (lib->vftabl.dbe_search_enctype == NULL) { 21854925bf6Swillf lib->vftabl.dbe_search_enctype = krb5_dbe_def_search_enctype; 21954925bf6Swillf } 22054925bf6Swillf 22154925bf6Swillf if (lib->vftabl.db_change_pwd == NULL) { 22254925bf6Swillf lib->vftabl.db_change_pwd = krb5_dbe_def_cpw; 22354925bf6Swillf } 22454925bf6Swillf 22554925bf6Swillf if (lib->vftabl.store_master_key == NULL) { 22654925bf6Swillf lib->vftabl.store_master_key = krb5_def_store_mkey; 22754925bf6Swillf } 22854925bf6Swillf 22954925bf6Swillf if (lib->vftabl.promote_db == NULL) { 23054925bf6Swillf lib->vftabl.promote_db = krb5_def_promote_db; 23154925bf6Swillf } 23254925bf6Swillf } 23354925bf6Swillf 23454925bf6Swillf static int kdb_db2_pol_err_loaded = 0; 23554925bf6Swillf #ifdef _KDB5_STATIC_LINK 23654925bf6Swillf #define DEF_SYMBOL(a) extern kdb_vftabl krb5_db_vftabl_ ## a 23754925bf6Swillf #define GET_SYMBOL(a) (krb5_db_vftabl_ ## a) 23854925bf6Swillf static krb5_error_code 23954925bf6Swillf kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib) 24054925bf6Swillf { 24154925bf6Swillf krb5_error_code status; 24254925bf6Swillf void *vftabl_addr = NULL; 24354925bf6Swillf char buf[KRB5_MAX_ERR_STR]; 24454925bf6Swillf 24554925bf6Swillf if (!strcmp("kdb_db2", lib_name) && (kdb_db2_pol_err_loaded == 0)) { 24654925bf6Swillf initialize_adb_error_table(); 24754925bf6Swillf kdb_db2_pol_err_loaded = 1; 24854925bf6Swillf } 24954925bf6Swillf 25054925bf6Swillf *lib = calloc((size_t) 1, sizeof(**lib)); 25154925bf6Swillf if (*lib == NULL) { 25254925bf6Swillf status = ENOMEM; 25354925bf6Swillf goto clean_n_exit; 25454925bf6Swillf } 25554925bf6Swillf 25654925bf6Swillf status = kdb_init_lib_lock(*lib); 25754925bf6Swillf if (status) { 25854925bf6Swillf goto clean_n_exit; 25954925bf6Swillf } 26054925bf6Swillf 26154925bf6Swillf strcpy((*lib)->name, lib_name); 26254925bf6Swillf 26354925bf6Swillf #if !defined(KDB5_USE_LIB_KDB_DB2) && !defined(KDB5_USE_LIB_TEST) 26454925bf6Swillf #error No database module defined 26554925bf6Swillf #endif 26654925bf6Swillf 26754925bf6Swillf #ifdef KDB5_USE_LIB_KDB_DB2 26854925bf6Swillf if (strcmp(lib_name, "kdb_db2") == 0) { 26954925bf6Swillf DEF_SYMBOL(kdb_db2); 27054925bf6Swillf vftabl_addr = (void *) &GET_SYMBOL(kdb_db2); 27154925bf6Swillf } else 27254925bf6Swillf #endif 27354925bf6Swillf #ifdef KDB5_USE_LIB_TEST 27454925bf6Swillf if (strcmp(lib_name, "test") == 0) { 27554925bf6Swillf DEF_SYMBOL(test); 27654925bf6Swillf vftabl_addr = (void *) &GET_SYMBOL(test); 27754925bf6Swillf } else 27854925bf6Swillf #endif 27954925bf6Swillf { 28054925bf6Swillf snprintf(buf, sizeof(buf), gettext("Program not built to support %s database type\n"), 28154925bf6Swillf lib_name); 28254925bf6Swillf status = KRB5_KDB_DBTYPE_NOSUP; 28354925bf6Swillf krb5_db_set_err(kcontext, krb5_err_have_str, status, buf); 28454925bf6Swillf goto clean_n_exit; 28554925bf6Swillf } 28654925bf6Swillf 28754925bf6Swillf memcpy(&(*lib)->vftabl, vftabl_addr, sizeof(kdb_vftabl)); 28854925bf6Swillf 28954925bf6Swillf kdb_setup_opt_functions(*lib); 29054925bf6Swillf 29154925bf6Swillf if ((status = (*lib)->vftabl.init_library())) { 29254925bf6Swillf /* ERROR. library not initialized cleanly */ 29354925bf6Swillf snprintf(buf, sizeof(buf), gettext("%s library initialization failed, error code %ld\n"), 29454925bf6Swillf lib_name, status); 29554925bf6Swillf status = KRB5_KDB_DBTYPE_INIT; 29654925bf6Swillf krb5_db_set_err(kcontext, krb5_err_have_str, status, buf); 29754925bf6Swillf goto clean_n_exit; 29854925bf6Swillf } 29954925bf6Swillf 30054925bf6Swillf clean_n_exit: 30154925bf6Swillf if (status) { 30254925bf6Swillf free(*lib), *lib = NULL; 30354925bf6Swillf } 30454925bf6Swillf return status; 30554925bf6Swillf } 30654925bf6Swillf 30754925bf6Swillf #else /* KDB5_STATIC_LINK*/ 30854925bf6Swillf 30954925bf6Swillf static char *db_dl_location[] = DEFAULT_KDB_LIB_PATH; 31054925bf6Swillf #define db_dl_n_locations (sizeof(db_dl_location) / sizeof(db_dl_location[0])) 31154925bf6Swillf 31254925bf6Swillf static krb5_error_code 31354925bf6Swillf kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib) 31454925bf6Swillf { 31554925bf6Swillf krb5_error_code status = 0; 31654925bf6Swillf int ndx; 31754925bf6Swillf void **vftabl_addrs = NULL; 31854925bf6Swillf /* N.B.: If this is "const" but not "static", the Solaris 10 31954925bf6Swillf native compiler has trouble building the library because of 32054925bf6Swillf absolute relocations needed in read-only section ".rodata". 32154925bf6Swillf When it's static, it goes into ".picdata", which is 32254925bf6Swillf read-write. */ 32354925bf6Swillf static const char *const dbpath_names[] = { 32454925bf6Swillf KDB_MODULE_SECTION, "db_module_dir", NULL, 32554925bf6Swillf }; 32654925bf6Swillf const char *filebases[2]; 32754925bf6Swillf char **profpath = NULL; 32854925bf6Swillf char **path = NULL; 32954925bf6Swillf 33054925bf6Swillf filebases[0] = lib_name; 33154925bf6Swillf filebases[1] = NULL; 33254925bf6Swillf 33354925bf6Swillf if (!strcmp(DB2_NAME, lib_name) && (kdb_db2_pol_err_loaded == 0)) { 33454925bf6Swillf initialize_adb_error_table(); 33554925bf6Swillf kdb_db2_pol_err_loaded = 1; 33654925bf6Swillf } 33754925bf6Swillf 33854925bf6Swillf *lib = calloc((size_t) 1, sizeof(**lib)); 33954925bf6Swillf if (*lib == NULL) { 34054925bf6Swillf status = ENOMEM; 34154925bf6Swillf goto clean_n_exit; 34254925bf6Swillf } 34354925bf6Swillf 34454925bf6Swillf status = kdb_init_lib_lock(*lib); 34554925bf6Swillf if (status) { 34654925bf6Swillf goto clean_n_exit; 34754925bf6Swillf } 34854925bf6Swillf 34954925bf6Swillf strcpy((*lib)->name, lib_name); 35054925bf6Swillf 35154925bf6Swillf /* Fetch the list of directories specified in the config 35254925bf6Swillf file(s) first. */ 35354925bf6Swillf status = profile_get_values(kcontext->profile, dbpath_names, &profpath); 35454925bf6Swillf if (status != 0 && status != PROF_NO_RELATION) 35554925bf6Swillf goto clean_n_exit; 35654925bf6Swillf ndx = 0; 35754925bf6Swillf if (profpath) 35854925bf6Swillf while (profpath[ndx] != NULL) 35954925bf6Swillf ndx++; 36054925bf6Swillf 36154925bf6Swillf path = calloc(ndx + db_dl_n_locations, sizeof (char *)); 36254925bf6Swillf if (path == NULL) { 36354925bf6Swillf status = errno; 36454925bf6Swillf goto clean_n_exit; 36554925bf6Swillf } 36654925bf6Swillf if (ndx) 36754925bf6Swillf memcpy(path, profpath, ndx * sizeof(profpath[0])); 36854925bf6Swillf memcpy(path + ndx, db_dl_location, db_dl_n_locations * sizeof(char *)); 36954925bf6Swillf status = 0; 37054925bf6Swillf 37154925bf6Swillf if ((status = krb5int_open_plugin_dirs ((const char **) path, 37254925bf6Swillf filebases, 37354925bf6Swillf &(*lib)->dl_dir_handle, &kcontext->err))) { 37454925bf6Swillf const char *err_str = krb5_get_error_message(kcontext, status); 37554925bf6Swillf status = KRB5_KDB_DBTYPE_NOTFOUND; 37654925bf6Swillf krb5_set_error_message (kcontext, status, 37754925bf6Swillf gettext("Unable to find requested database type: %s"), err_str); 37854925bf6Swillf krb5_free_error_message (kcontext, err_str); 37954925bf6Swillf goto clean_n_exit; 38054925bf6Swillf } 38154925bf6Swillf 38254925bf6Swillf if ((status = krb5int_get_plugin_dir_data (&(*lib)->dl_dir_handle, "kdb_function_table", 38354925bf6Swillf &vftabl_addrs, &kcontext->err))) { 38454925bf6Swillf const char *err_str = krb5_get_error_message(kcontext, status); 38554925bf6Swillf status = KRB5_KDB_DBTYPE_INIT; 38654925bf6Swillf krb5_set_error_message (kcontext, status, 38754925bf6Swillf gettext("plugin symbol 'kdb_function_table' lookup failed: %s"), err_str); 38854925bf6Swillf krb5_free_error_message (kcontext, err_str); 38954925bf6Swillf goto clean_n_exit; 39054925bf6Swillf } 39154925bf6Swillf 39254925bf6Swillf if (vftabl_addrs[0] == NULL) { 39354925bf6Swillf /* No plugins! */ 39454925bf6Swillf status = KRB5_KDB_DBTYPE_NOTFOUND; 39554925bf6Swillf krb5_set_error_message (kcontext, status, 39654925bf6Swillf gettext("Unable to load requested database module '%s': plugin symbol 'kdb_function_table' not found"), 39754925bf6Swillf lib_name); 39854925bf6Swillf goto clean_n_exit; 39954925bf6Swillf } 40054925bf6Swillf 40154925bf6Swillf memcpy(&(*lib)->vftabl, vftabl_addrs[0], sizeof(kdb_vftabl)); 40254925bf6Swillf kdb_setup_opt_functions(*lib); 40354925bf6Swillf 40454925bf6Swillf if ((status = (*lib)->vftabl.init_library())) { 40554925bf6Swillf /* ERROR. library not initialized cleanly */ 40654925bf6Swillf goto clean_n_exit; 40754925bf6Swillf } 40854925bf6Swillf 40954925bf6Swillf clean_n_exit: 41054925bf6Swillf if (vftabl_addrs != NULL) { krb5int_free_plugin_dir_data (vftabl_addrs); } 41154925bf6Swillf /* Both of these DTRT with NULL. */ 41254925bf6Swillf profile_free_list(profpath); 41354925bf6Swillf free(path); 41454925bf6Swillf if (status) { 41554925bf6Swillf if (*lib) { 41654925bf6Swillf kdb_destroy_lib_lock(*lib); 41754925bf6Swillf if (PLUGIN_DIR_OPEN((&(*lib)->dl_dir_handle))) { 41854925bf6Swillf krb5int_close_plugin_dirs (&(*lib)->dl_dir_handle); 41954925bf6Swillf } 42054925bf6Swillf free(*lib); 42154925bf6Swillf *lib = NULL; 42254925bf6Swillf } 42354925bf6Swillf } 42454925bf6Swillf return status; 42554925bf6Swillf } 42654925bf6Swillf 42754925bf6Swillf #endif /* end of _KDB5_STATIC_LINK */ 42854925bf6Swillf 42954925bf6Swillf static krb5_error_code 43054925bf6Swillf kdb_find_library(krb5_context kcontext, char *lib_name, db_library * lib) 43154925bf6Swillf { 43254925bf6Swillf /* lock here so that no two threads try to do the same at the same time */ 43354925bf6Swillf krb5_error_code status = 0; 43454925bf6Swillf int locked = 0; 43554925bf6Swillf db_library curr_elt, prev_elt = NULL; 43654925bf6Swillf 43754925bf6Swillf if ((status = kdb_lock_list()) != 0) { 43854925bf6Swillf goto clean_n_exit; 43954925bf6Swillf } 44054925bf6Swillf locked = 1; 44154925bf6Swillf 44254925bf6Swillf curr_elt = lib_list; 44354925bf6Swillf while (curr_elt != NULL) { 44454925bf6Swillf if (strcmp(lib_name, curr_elt->name) == 0) { 44554925bf6Swillf *lib = curr_elt; 44654925bf6Swillf goto clean_n_exit; 44754925bf6Swillf } 44854925bf6Swillf prev_elt = curr_elt; 44954925bf6Swillf curr_elt = curr_elt->next; 45054925bf6Swillf } 45154925bf6Swillf 45254925bf6Swillf /* module not found. create and add to list */ 45354925bf6Swillf status = kdb_load_library(kcontext, lib_name, lib); 45454925bf6Swillf if (status) { 45554925bf6Swillf goto clean_n_exit; 45654925bf6Swillf } 45754925bf6Swillf 45854925bf6Swillf if (prev_elt) { 45954925bf6Swillf /* prev_elt points to the last element in the list */ 46054925bf6Swillf prev_elt->next = *lib; 46154925bf6Swillf (*lib)->prev = prev_elt; 46254925bf6Swillf } else { 46354925bf6Swillf lib_list = *lib; 46454925bf6Swillf } 46554925bf6Swillf 46654925bf6Swillf clean_n_exit: 46754925bf6Swillf if (*lib) { 46854925bf6Swillf (*lib)->reference_cnt++; 46954925bf6Swillf } 47054925bf6Swillf 47154925bf6Swillf if (locked) { 47254925bf6Swillf (void)kdb_unlock_list(); 47354925bf6Swillf } 47454925bf6Swillf 47554925bf6Swillf return status; 47654925bf6Swillf } 47754925bf6Swillf 47854925bf6Swillf static krb5_error_code 47954925bf6Swillf kdb_free_library(db_library lib) 48054925bf6Swillf { 48154925bf6Swillf krb5_error_code status = 0; 48254925bf6Swillf int locked = 0; 48354925bf6Swillf 48454925bf6Swillf if ((status = kdb_lock_list()) != 0) { 48554925bf6Swillf goto clean_n_exit; 48654925bf6Swillf } 48754925bf6Swillf locked = 1; 48854925bf6Swillf 48954925bf6Swillf lib->reference_cnt--; 49054925bf6Swillf 49154925bf6Swillf if (lib->reference_cnt == 0) { 49254925bf6Swillf status = lib->vftabl.fini_library(); 49354925bf6Swillf if (status) { 49454925bf6Swillf goto clean_n_exit; 49554925bf6Swillf } 49654925bf6Swillf 49754925bf6Swillf /* close the library */ 49854925bf6Swillf if (PLUGIN_DIR_OPEN((&lib->dl_dir_handle))) { 49954925bf6Swillf krb5int_close_plugin_dirs (&lib->dl_dir_handle); 50054925bf6Swillf } 50154925bf6Swillf 50254925bf6Swillf kdb_destroy_lib_lock(lib); 50354925bf6Swillf 50454925bf6Swillf if (lib->prev == NULL) { 50554925bf6Swillf /* first element in the list */ 50654925bf6Swillf lib_list = lib->next; 50754925bf6Swillf } else { 50854925bf6Swillf lib->prev->next = lib->next; 50954925bf6Swillf } 51054925bf6Swillf 51154925bf6Swillf if (lib->next) { 51254925bf6Swillf lib->next->prev = lib->prev; 51354925bf6Swillf } 51454925bf6Swillf free(lib); 51554925bf6Swillf } 51654925bf6Swillf 51754925bf6Swillf clean_n_exit: 51854925bf6Swillf if (locked) { 51954925bf6Swillf (void)kdb_unlock_list(); 52054925bf6Swillf } 52154925bf6Swillf 52254925bf6Swillf return status; 52354925bf6Swillf } 52454925bf6Swillf 52554925bf6Swillf static krb5_error_code 52654925bf6Swillf kdb_setup_lib_handle(krb5_context kcontext) 52754925bf6Swillf { 52854925bf6Swillf char *library = NULL; 52954925bf6Swillf krb5_error_code status = 0; 53054925bf6Swillf db_library lib = NULL; 53154925bf6Swillf kdb5_dal_handle *dal_handle = NULL; 53254925bf6Swillf 53354925bf6Swillf dal_handle = calloc((size_t) 1, sizeof(kdb5_dal_handle)); 53454925bf6Swillf if (dal_handle == NULL) { 53554925bf6Swillf status = ENOMEM; 53654925bf6Swillf goto clean_n_exit; 53754925bf6Swillf } 53854925bf6Swillf 53954925bf6Swillf library = kdb_get_library_name(kcontext); 54054925bf6Swillf if (library == NULL) { 54154925bf6Swillf status = KRB5_KDB_DBTYPE_NOTFOUND; 54254925bf6Swillf goto clean_n_exit; 54354925bf6Swillf } 54454925bf6Swillf 54554925bf6Swillf status = kdb_find_library(kcontext, library, &lib); 54654925bf6Swillf if (status) { 54754925bf6Swillf goto clean_n_exit; 54854925bf6Swillf } 54954925bf6Swillf 55054925bf6Swillf dal_handle->lib_handle = lib; 55154925bf6Swillf kcontext->db_context = (void *) dal_handle; 55254925bf6Swillf 55354925bf6Swillf clean_n_exit: 55454925bf6Swillf free(library); 55554925bf6Swillf 55654925bf6Swillf if (status) { 55754925bf6Swillf free(dal_handle); 55854925bf6Swillf if (lib) { 55954925bf6Swillf (void)kdb_free_library(lib); 56054925bf6Swillf } 56154925bf6Swillf } 56254925bf6Swillf 56354925bf6Swillf return status; 56454925bf6Swillf } 56554925bf6Swillf 56654925bf6Swillf static krb5_error_code 56754925bf6Swillf kdb_free_lib_handle(krb5_context kcontext) 56854925bf6Swillf { 56954925bf6Swillf krb5_error_code status = 0; 57054925bf6Swillf 57154925bf6Swillf status = 57254925bf6Swillf kdb_free_library(((kdb5_dal_handle *) kcontext->db_context)-> 57354925bf6Swillf lib_handle); 57454925bf6Swillf if (status) { 57554925bf6Swillf goto clean_n_exit; 57654925bf6Swillf } 57754925bf6Swillf 57854925bf6Swillf free(kcontext->db_context); 57954925bf6Swillf kcontext->db_context = NULL; 58054925bf6Swillf 58154925bf6Swillf clean_n_exit: 58254925bf6Swillf return status; 58354925bf6Swillf } 58454925bf6Swillf 58554925bf6Swillf static void 58654925bf6Swillf get_errmsg (krb5_context kcontext, krb5_error_code err_code) 58754925bf6Swillf { 58854925bf6Swillf kdb5_dal_handle *dal_handle; 58954925bf6Swillf const char *e; 59054925bf6Swillf if (err_code == 0) 59154925bf6Swillf return; 59254925bf6Swillf assert(kcontext != NULL); 59354925bf6Swillf /* Must be called with dal_handle->lib_handle locked! */ 59454925bf6Swillf assert(kcontext->db_context != NULL); 59554925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 59654925bf6Swillf if (dal_handle->lib_handle->vftabl.errcode_2_string == NULL) 59754925bf6Swillf return; 59854925bf6Swillf e = dal_handle->lib_handle->vftabl.errcode_2_string(kcontext, err_code); 59954925bf6Swillf assert (e != NULL); 60054925bf6Swillf krb5_set_error_message(kcontext, err_code, "%s", e); 60154925bf6Swillf if (dal_handle->lib_handle->vftabl.release_errcode_string) 60254925bf6Swillf dal_handle->lib_handle->vftabl.release_errcode_string(kcontext, e); 60354925bf6Swillf } 60454925bf6Swillf 60554925bf6Swillf /* 60654925bf6Swillf * External functions... DAL API 60754925bf6Swillf */ 60854925bf6Swillf krb5_error_code 60954925bf6Swillf krb5_db_open(krb5_context kcontext, char **db_args, int mode) 61054925bf6Swillf { 61154925bf6Swillf krb5_error_code status = 0; 61254925bf6Swillf char *section = NULL; 61354925bf6Swillf kdb5_dal_handle *dal_handle; 61454925bf6Swillf 61554925bf6Swillf section = kdb_get_conf_section(kcontext); 61654925bf6Swillf if (section == NULL) { 61754925bf6Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR; 61854925bf6Swillf krb5_set_error_message (kcontext, status, 61954925bf6Swillf gettext("unable to determine configuration section for realm %s\n"), 62054925bf6Swillf kcontext->default_realm ? kcontext->default_realm : "[UNSET]"); 62154925bf6Swillf goto clean_n_exit; 62254925bf6Swillf } 62354925bf6Swillf 62454925bf6Swillf if (kcontext->db_context == NULL) { 62554925bf6Swillf status = kdb_setup_lib_handle(kcontext); 62654925bf6Swillf if (status) { 62754925bf6Swillf goto clean_n_exit; 62854925bf6Swillf } 62954925bf6Swillf } 63054925bf6Swillf 63154925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 63254925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 63354925bf6Swillf if (status) { 63454925bf6Swillf goto clean_n_exit; 63554925bf6Swillf } 63654925bf6Swillf 63754925bf6Swillf status = 63854925bf6Swillf dal_handle->lib_handle->vftabl.init_module(kcontext, section, db_args, 63954925bf6Swillf mode); 64054925bf6Swillf get_errmsg(kcontext, status); 64154925bf6Swillf 64254925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 64354925bf6Swillf 64454925bf6Swillf clean_n_exit: 64554925bf6Swillf if (section) 64654925bf6Swillf free(section); 64754925bf6Swillf return status; 64854925bf6Swillf } 64954925bf6Swillf 65054925bf6Swillf krb5_error_code 65154925bf6Swillf krb5_db_inited(krb5_context kcontext) 65254925bf6Swillf { 65354925bf6Swillf return !(kcontext && kcontext->db_context && 65454925bf6Swillf ((kdb5_dal_handle *) kcontext->db_context)->db_context); 65554925bf6Swillf } 65654925bf6Swillf 65754925bf6Swillf krb5_error_code 65854925bf6Swillf krb5_db_create(krb5_context kcontext, char **db_args) 65954925bf6Swillf { 66054925bf6Swillf krb5_error_code status = 0; 66154925bf6Swillf char *section = NULL; 66254925bf6Swillf kdb5_dal_handle *dal_handle; 66354925bf6Swillf 66454925bf6Swillf section = kdb_get_conf_section(kcontext); 66554925bf6Swillf if (section == NULL) { 66654925bf6Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR; 66754925bf6Swillf krb5_set_error_message (kcontext, status, 66854925bf6Swillf gettext("unable to determine configuration section for realm %s\n"), 66954925bf6Swillf kcontext->default_realm); 67054925bf6Swillf goto clean_n_exit; 67154925bf6Swillf } 67254925bf6Swillf 67354925bf6Swillf if (kcontext->db_context == NULL) { 67454925bf6Swillf status = kdb_setup_lib_handle(kcontext); 67554925bf6Swillf if (status) { 67654925bf6Swillf goto clean_n_exit; 67754925bf6Swillf } 67854925bf6Swillf } 67954925bf6Swillf 68054925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 68154925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 68254925bf6Swillf if (status) { 68354925bf6Swillf goto clean_n_exit; 68454925bf6Swillf } 68554925bf6Swillf 68654925bf6Swillf status = 68754925bf6Swillf dal_handle->lib_handle->vftabl.db_create(kcontext, section, db_args); 68854925bf6Swillf get_errmsg(kcontext, status); 68954925bf6Swillf 69054925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 69154925bf6Swillf 69254925bf6Swillf clean_n_exit: 69354925bf6Swillf if (section) 69454925bf6Swillf free(section); 69554925bf6Swillf return status; 69654925bf6Swillf } 69754925bf6Swillf 69854925bf6Swillf krb5_error_code 69954925bf6Swillf krb5_db_fini(krb5_context kcontext) 70054925bf6Swillf { 70154925bf6Swillf krb5_error_code status = 0; 70254925bf6Swillf kdb5_dal_handle *dal_handle; 70354925bf6Swillf 70454925bf6Swillf if (kcontext->db_context == NULL) { 70554925bf6Swillf /* module not loaded. So nothing to be done */ 70654925bf6Swillf goto clean_n_exit; 70754925bf6Swillf } 70854925bf6Swillf 70954925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 71054925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 71154925bf6Swillf if (status) { 71254925bf6Swillf goto clean_n_exit; 71354925bf6Swillf } 71454925bf6Swillf 71554925bf6Swillf status = dal_handle->lib_handle->vftabl.fini_module(kcontext); 71654925bf6Swillf get_errmsg(kcontext, status); 71754925bf6Swillf 71854925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 71954925bf6Swillf 72054925bf6Swillf if (status) { 72154925bf6Swillf goto clean_n_exit; 72254925bf6Swillf } 72354925bf6Swillf 72454925bf6Swillf status = kdb_free_lib_handle(kcontext); 72554925bf6Swillf 72654925bf6Swillf clean_n_exit: 72754925bf6Swillf return status; 72854925bf6Swillf } 72954925bf6Swillf 73054925bf6Swillf krb5_error_code 73154925bf6Swillf krb5_db_destroy(krb5_context kcontext, char **db_args) 73254925bf6Swillf { 73354925bf6Swillf krb5_error_code status = 0; 73454925bf6Swillf char *section = NULL; 73554925bf6Swillf kdb5_dal_handle *dal_handle; 73654925bf6Swillf 73754925bf6Swillf section = kdb_get_conf_section(kcontext); 73854925bf6Swillf if (section == NULL) { 73954925bf6Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR; 74054925bf6Swillf krb5_set_error_message (kcontext, status, 74154925bf6Swillf gettext("unable to determine configuration section for realm %s\n"), 74254925bf6Swillf kcontext->default_realm); 74354925bf6Swillf goto clean_n_exit; 74454925bf6Swillf } 74554925bf6Swillf 74654925bf6Swillf if (kcontext->db_context == NULL) { 74754925bf6Swillf status = kdb_setup_lib_handle(kcontext); 74854925bf6Swillf if (status) { 74954925bf6Swillf goto clean_n_exit; 75054925bf6Swillf } 75154925bf6Swillf } 75254925bf6Swillf 75354925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 75454925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 75554925bf6Swillf if (status) { 75654925bf6Swillf goto clean_n_exit; 75754925bf6Swillf } 75854925bf6Swillf 75954925bf6Swillf status = 76054925bf6Swillf dal_handle->lib_handle->vftabl.db_destroy(kcontext, section, db_args); 76154925bf6Swillf get_errmsg(kcontext, status); 76254925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 76354925bf6Swillf 76454925bf6Swillf clean_n_exit: 76554925bf6Swillf if (section) 76654925bf6Swillf free(section); 76754925bf6Swillf return status; 76854925bf6Swillf } 76954925bf6Swillf 77054925bf6Swillf krb5_error_code 77154925bf6Swillf krb5_db_get_age(krb5_context kcontext, char *db_name, time_t * t) 77254925bf6Swillf { 77354925bf6Swillf krb5_error_code status = 0; 77454925bf6Swillf kdb5_dal_handle *dal_handle; 77554925bf6Swillf 77654925bf6Swillf if (kcontext->db_context == NULL) { 77754925bf6Swillf status = kdb_setup_lib_handle(kcontext); 77854925bf6Swillf if (status) { 77954925bf6Swillf goto clean_n_exit; 78054925bf6Swillf } 78154925bf6Swillf } 78254925bf6Swillf 78354925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 78454925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 78554925bf6Swillf if (status) { 78654925bf6Swillf goto clean_n_exit; 78754925bf6Swillf } 78854925bf6Swillf 78954925bf6Swillf status = dal_handle->lib_handle->vftabl.db_get_age(kcontext, db_name, t); 79054925bf6Swillf get_errmsg(kcontext, status); 79154925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 79254925bf6Swillf 79354925bf6Swillf clean_n_exit: 79454925bf6Swillf return status; 79554925bf6Swillf } 79654925bf6Swillf 79754925bf6Swillf krb5_error_code 79854925bf6Swillf krb5_db_set_option(krb5_context kcontext, int option, void *value) 79954925bf6Swillf { 80054925bf6Swillf krb5_error_code status = 0; 80154925bf6Swillf kdb5_dal_handle *dal_handle; 80254925bf6Swillf 80354925bf6Swillf if (kcontext->db_context == NULL) { 80454925bf6Swillf status = kdb_setup_lib_handle(kcontext); 80554925bf6Swillf if (status) { 80654925bf6Swillf goto clean_n_exit; 80754925bf6Swillf } 80854925bf6Swillf } 80954925bf6Swillf 81054925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 81154925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 81254925bf6Swillf if (status) { 81354925bf6Swillf goto clean_n_exit; 81454925bf6Swillf } 81554925bf6Swillf 81654925bf6Swillf status = 81754925bf6Swillf dal_handle->lib_handle->vftabl.db_set_option(kcontext, option, value); 81854925bf6Swillf get_errmsg(kcontext, status); 81954925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 82054925bf6Swillf 82154925bf6Swillf clean_n_exit: 82254925bf6Swillf return status; 82354925bf6Swillf } 82454925bf6Swillf 82554925bf6Swillf krb5_error_code 82654925bf6Swillf krb5_db_lock(krb5_context kcontext, int lock_mode) 82754925bf6Swillf { 82854925bf6Swillf krb5_error_code status = 0; 82954925bf6Swillf kdb5_dal_handle *dal_handle; 83054925bf6Swillf 83154925bf6Swillf if (kcontext->db_context == NULL) { 83254925bf6Swillf status = kdb_setup_lib_handle(kcontext); 83354925bf6Swillf if (status) { 83454925bf6Swillf goto clean_n_exit; 83554925bf6Swillf } 83654925bf6Swillf } 83754925bf6Swillf 83854925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 83954925bf6Swillf /* acquire an exclusive lock, ensures no other thread uses this context */ 84054925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, TRUE); 84154925bf6Swillf if (status) { 84254925bf6Swillf goto clean_n_exit; 84354925bf6Swillf } 84454925bf6Swillf 84554925bf6Swillf status = dal_handle->lib_handle->vftabl.db_lock(kcontext, lock_mode); 84654925bf6Swillf get_errmsg(kcontext, status); 84754925bf6Swillf 84854925bf6Swillf /* exclusive lock is still held, so no other thread could use this context */ 84954925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 85054925bf6Swillf 85154925bf6Swillf clean_n_exit: 85254925bf6Swillf return status; 85354925bf6Swillf } 85454925bf6Swillf 85554925bf6Swillf krb5_error_code 85654925bf6Swillf krb5_db_unlock(krb5_context kcontext) 85754925bf6Swillf { 85854925bf6Swillf krb5_error_code status = 0; 85954925bf6Swillf kdb5_dal_handle *dal_handle; 86054925bf6Swillf 86154925bf6Swillf if (kcontext->db_context == NULL) { 86254925bf6Swillf status = kdb_setup_lib_handle(kcontext); 86354925bf6Swillf if (status) { 86454925bf6Swillf goto clean_n_exit; 86554925bf6Swillf } 86654925bf6Swillf } 86754925bf6Swillf 86854925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 86954925bf6Swillf /* normal lock acquired and exclusive lock released */ 87054925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 87154925bf6Swillf if (status) { 87254925bf6Swillf goto clean_n_exit; 87354925bf6Swillf } 87454925bf6Swillf 87554925bf6Swillf status = dal_handle->lib_handle->vftabl.db_unlock(kcontext); 87654925bf6Swillf get_errmsg(kcontext, status); 87754925bf6Swillf 87854925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, TRUE); 87954925bf6Swillf 88054925bf6Swillf clean_n_exit: 88154925bf6Swillf return status; 88254925bf6Swillf } 88354925bf6Swillf 88454925bf6Swillf krb5_error_code 88554925bf6Swillf krb5_db_get_principal(krb5_context kcontext, 88654925bf6Swillf krb5_const_principal search_for, 88754925bf6Swillf krb5_db_entry * entries, 88854925bf6Swillf int *nentries, krb5_boolean * more) 88954925bf6Swillf { 89054925bf6Swillf krb5_error_code status = 0; 89154925bf6Swillf kdb5_dal_handle *dal_handle; 89254925bf6Swillf 89354925bf6Swillf if (kcontext->db_context == NULL) { 89454925bf6Swillf status = kdb_setup_lib_handle(kcontext); 89554925bf6Swillf if (status) { 89654925bf6Swillf goto clean_n_exit; 89754925bf6Swillf } 89854925bf6Swillf } 89954925bf6Swillf 90054925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 90154925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 90254925bf6Swillf if (status) { 90354925bf6Swillf goto clean_n_exit; 90454925bf6Swillf } 90554925bf6Swillf 90654925bf6Swillf status = 90754925bf6Swillf dal_handle->lib_handle->vftabl.db_get_principal(kcontext, search_for, 90854925bf6Swillf entries, nentries, 90954925bf6Swillf more); 91054925bf6Swillf get_errmsg(kcontext, status); 91154925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 91254925bf6Swillf 91354925bf6Swillf clean_n_exit: 91454925bf6Swillf return status; 91554925bf6Swillf } 91654925bf6Swillf 91754925bf6Swillf krb5_error_code 91854925bf6Swillf krb5_db_get_principal_nolock(krb5_context kcontext, 91954925bf6Swillf krb5_const_principal search_for, 92054925bf6Swillf krb5_db_entry * entries, 92154925bf6Swillf int *nentries, krb5_boolean * more) 92254925bf6Swillf { 92354925bf6Swillf krb5_error_code status = 0; 92454925bf6Swillf kdb5_dal_handle *dal_handle; 92554925bf6Swillf 92654925bf6Swillf if (kcontext->db_context == NULL) { 92754925bf6Swillf status = kdb_setup_lib_handle(kcontext); 92854925bf6Swillf if (status) { 92954925bf6Swillf goto clean_n_exit; 93054925bf6Swillf } 93154925bf6Swillf } 93254925bf6Swillf 93354925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 93454925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 93554925bf6Swillf if (status) { 93654925bf6Swillf goto clean_n_exit; 93754925bf6Swillf } 93854925bf6Swillf 93954925bf6Swillf status = 94054925bf6Swillf dal_handle->lib_handle->vftabl.db_get_principal_nolock(kcontext, 94154925bf6Swillf search_for, 94254925bf6Swillf entries, nentries, 94354925bf6Swillf more); 94454925bf6Swillf get_errmsg(kcontext, status); 94554925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 94654925bf6Swillf 94754925bf6Swillf clean_n_exit: 94854925bf6Swillf return status; 94954925bf6Swillf } 95054925bf6Swillf 95154925bf6Swillf krb5_error_code 95254925bf6Swillf krb5_db_free_principal(krb5_context kcontext, krb5_db_entry * entry, int count) 95354925bf6Swillf { 95454925bf6Swillf krb5_error_code status = 0; 95554925bf6Swillf kdb5_dal_handle *dal_handle; 95654925bf6Swillf 95754925bf6Swillf if (kcontext->db_context == NULL) { 95854925bf6Swillf status = kdb_setup_lib_handle(kcontext); 95954925bf6Swillf if (status) { 96054925bf6Swillf goto clean_n_exit; 96154925bf6Swillf } 96254925bf6Swillf } 96354925bf6Swillf 96454925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 96554925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 96654925bf6Swillf if (status) { 96754925bf6Swillf goto clean_n_exit; 96854925bf6Swillf } 96954925bf6Swillf 97054925bf6Swillf status = 97154925bf6Swillf dal_handle->lib_handle->vftabl.db_free_principal(kcontext, entry, 97254925bf6Swillf count); 97354925bf6Swillf get_errmsg(kcontext, status); 97454925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 97554925bf6Swillf 97654925bf6Swillf clean_n_exit: 97754925bf6Swillf return status; 97854925bf6Swillf } 97954925bf6Swillf 98054925bf6Swillf krb5_error_code 98154925bf6Swillf krb5_db_put_principal(krb5_context kcontext, 98254925bf6Swillf krb5_db_entry * entries, int *nentries) 98354925bf6Swillf { 98454925bf6Swillf krb5_error_code status = 0; 98554925bf6Swillf kdb5_dal_handle *dal_handle; 98654925bf6Swillf char **db_args = NULL; 98754925bf6Swillf krb5_tl_data *prev, *curr, *next; 98854925bf6Swillf int db_args_size = 0; 98954925bf6Swillf 99054925bf6Swillf if (kcontext->db_context == NULL) { 99154925bf6Swillf status = kdb_setup_lib_handle(kcontext); 99254925bf6Swillf if (status) { 99354925bf6Swillf goto clean_n_exit; 99454925bf6Swillf } 99554925bf6Swillf } 99654925bf6Swillf 99754925bf6Swillf /* Giving db_args as part of tl data causes, db2 to store the 99854925bf6Swillf tl_data as such. To prevent this, tl_data is collated and 99954925bf6Swillf passed as a sepearte argument. Currently supports only one 100054925bf6Swillf principal. but passing it as a seperate argument makes it 100154925bf6Swillf difficult for kadmin remote to pass arguments to server. */ 100254925bf6Swillf prev = NULL, curr = entries->tl_data; 100354925bf6Swillf while (curr) { 100454925bf6Swillf if (curr->tl_data_type == KRB5_TL_DB_ARGS) { 100554925bf6Swillf char **t; 100654925bf6Swillf /* Since this is expected to be NULL terminated string and 100754925bf6Swillf this could come from any client, do a check before 100854925bf6Swillf passing it to db. */ 100954925bf6Swillf if (((char *) curr->tl_data_contents)[curr->tl_data_length - 1] != 101054925bf6Swillf '\0') { 101154925bf6Swillf /* not null terminated. Dangerous input */ 101254925bf6Swillf status = EINVAL; 101354925bf6Swillf goto clean_n_exit; 101454925bf6Swillf } 101554925bf6Swillf 101654925bf6Swillf db_args_size++; 101754925bf6Swillf t = realloc(db_args, sizeof(char *) * (db_args_size + 1)); /* 1 for NULL */ 101854925bf6Swillf if (t == NULL) { 101954925bf6Swillf status = ENOMEM; 102054925bf6Swillf goto clean_n_exit; 102154925bf6Swillf } 102254925bf6Swillf 102354925bf6Swillf db_args = t; 102454925bf6Swillf db_args[db_args_size - 1] = (char *) curr->tl_data_contents; 102554925bf6Swillf db_args[db_args_size] = NULL; 102654925bf6Swillf 102754925bf6Swillf next = curr->tl_data_next; 102854925bf6Swillf if (prev == NULL) { 102954925bf6Swillf /* current node is the first in the linked list. remove it */ 103054925bf6Swillf entries->tl_data = curr->tl_data_next; 103154925bf6Swillf } else { 103254925bf6Swillf prev->tl_data_next = curr->tl_data_next; 103354925bf6Swillf } 103454925bf6Swillf entries->n_tl_data--; 103554925bf6Swillf krb5_db_free(kcontext, curr); 103654925bf6Swillf 103754925bf6Swillf /* previous does not change */ 103854925bf6Swillf curr = next; 103954925bf6Swillf } else { 104054925bf6Swillf prev = curr; 104154925bf6Swillf curr = curr->tl_data_next; 104254925bf6Swillf } 104354925bf6Swillf } 104454925bf6Swillf 104554925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 104654925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 104754925bf6Swillf if (status) { 104854925bf6Swillf goto clean_n_exit; 104954925bf6Swillf } 105054925bf6Swillf 105154925bf6Swillf status = dal_handle->lib_handle->vftabl.db_put_principal(kcontext, entries, 105254925bf6Swillf nentries, 105354925bf6Swillf db_args); 105454925bf6Swillf get_errmsg(kcontext, status); 105554925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 105654925bf6Swillf 105754925bf6Swillf clean_n_exit: 105854925bf6Swillf while (db_args_size) { 105954925bf6Swillf if (db_args[db_args_size - 1]) 106054925bf6Swillf krb5_db_free(kcontext, db_args[db_args_size - 1]); 106154925bf6Swillf 106254925bf6Swillf db_args_size--; 106354925bf6Swillf } 106454925bf6Swillf 106554925bf6Swillf if (db_args) 106654925bf6Swillf free(db_args); 106754925bf6Swillf 106854925bf6Swillf return status; 106954925bf6Swillf } 107054925bf6Swillf 107154925bf6Swillf krb5_error_code 107254925bf6Swillf krb5_db_delete_principal(krb5_context kcontext, 107354925bf6Swillf krb5_principal search_for, int *nentries) 107454925bf6Swillf { 107554925bf6Swillf krb5_error_code status = 0; 107654925bf6Swillf kdb5_dal_handle *dal_handle; 107754925bf6Swillf 107854925bf6Swillf if (kcontext->db_context == NULL) { 107954925bf6Swillf status = kdb_setup_lib_handle(kcontext); 108054925bf6Swillf if (status) { 108154925bf6Swillf goto clean_n_exit; 108254925bf6Swillf } 108354925bf6Swillf } 108454925bf6Swillf 108554925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 108654925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 108754925bf6Swillf if (status) { 108854925bf6Swillf goto clean_n_exit; 108954925bf6Swillf } 109054925bf6Swillf 109154925bf6Swillf status = 109254925bf6Swillf dal_handle->lib_handle->vftabl.db_delete_principal(kcontext, 109354925bf6Swillf search_for, 109454925bf6Swillf nentries); 109554925bf6Swillf get_errmsg(kcontext, status); 109654925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 109754925bf6Swillf 109854925bf6Swillf clean_n_exit: 109954925bf6Swillf return status; 110054925bf6Swillf } 110154925bf6Swillf 110254925bf6Swillf krb5_error_code 110354925bf6Swillf krb5_db_iterate(krb5_context kcontext, 110454925bf6Swillf char *match_entry, 110554925bf6Swillf int (*func) (krb5_pointer, krb5_db_entry *), 1106*2dd2efa5Swillf krb5_pointer func_arg, 1107*2dd2efa5Swillf /* Solaris Kerberos: adding support for db_args */ 1108*2dd2efa5Swillf char **db_args) 110954925bf6Swillf { 111054925bf6Swillf krb5_error_code status = 0; 111154925bf6Swillf kdb5_dal_handle *dal_handle; 111254925bf6Swillf 111354925bf6Swillf if (kcontext->db_context == NULL) { 111454925bf6Swillf status = kdb_setup_lib_handle(kcontext); 111554925bf6Swillf if (status) { 111654925bf6Swillf goto clean_n_exit; 111754925bf6Swillf } 111854925bf6Swillf } 111954925bf6Swillf 112054925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 112154925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 112254925bf6Swillf if (status) { 112354925bf6Swillf goto clean_n_exit; 112454925bf6Swillf } 112554925bf6Swillf 1126*2dd2efa5Swillf /* Solaris Kerberos: adding support for db_args */ 112754925bf6Swillf status = dal_handle->lib_handle->vftabl.db_iterate(kcontext, 112854925bf6Swillf match_entry, 1129*2dd2efa5Swillf func, func_arg, 1130*2dd2efa5Swillf db_args); 113154925bf6Swillf get_errmsg(kcontext, status); 113254925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 113354925bf6Swillf 113454925bf6Swillf clean_n_exit: 113554925bf6Swillf return status; 113654925bf6Swillf } 113754925bf6Swillf 113854925bf6Swillf krb5_error_code 113954925bf6Swillf krb5_supported_realms(krb5_context kcontext, char **realms) 114054925bf6Swillf { 114154925bf6Swillf krb5_error_code status = 0; 114254925bf6Swillf kdb5_dal_handle *dal_handle; 114354925bf6Swillf 114454925bf6Swillf if (kcontext->db_context == NULL) { 114554925bf6Swillf status = kdb_setup_lib_handle(kcontext); 114654925bf6Swillf if (status) { 114754925bf6Swillf goto clean_n_exit; 114854925bf6Swillf } 114954925bf6Swillf } 115054925bf6Swillf 115154925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 115254925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 115354925bf6Swillf if (status) { 115454925bf6Swillf goto clean_n_exit; 115554925bf6Swillf } 115654925bf6Swillf 115754925bf6Swillf status = 115854925bf6Swillf dal_handle->lib_handle->vftabl.db_supported_realms(kcontext, realms); 115954925bf6Swillf get_errmsg(kcontext, status); 116054925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 116154925bf6Swillf 116254925bf6Swillf clean_n_exit: 116354925bf6Swillf return status; 116454925bf6Swillf } 116554925bf6Swillf 116654925bf6Swillf krb5_error_code 116754925bf6Swillf krb5_free_supported_realms(krb5_context kcontext, char **realms) 116854925bf6Swillf { 116954925bf6Swillf krb5_error_code status = 0; 117054925bf6Swillf kdb5_dal_handle *dal_handle; 117154925bf6Swillf 117254925bf6Swillf if (kcontext->db_context == NULL) { 117354925bf6Swillf status = kdb_setup_lib_handle(kcontext); 117454925bf6Swillf if (status) { 117554925bf6Swillf goto clean_n_exit; 117654925bf6Swillf } 117754925bf6Swillf } 117854925bf6Swillf 117954925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 118054925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 118154925bf6Swillf if (status) { 118254925bf6Swillf goto clean_n_exit; 118354925bf6Swillf } 118454925bf6Swillf 118554925bf6Swillf status = 118654925bf6Swillf dal_handle->lib_handle->vftabl.db_free_supported_realms(kcontext, 118754925bf6Swillf realms); 118854925bf6Swillf get_errmsg(kcontext, status); 118954925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 119054925bf6Swillf 119154925bf6Swillf clean_n_exit: 119254925bf6Swillf return status; 119354925bf6Swillf } 119454925bf6Swillf 119554925bf6Swillf krb5_error_code 119654925bf6Swillf krb5_db_set_master_key_ext(krb5_context kcontext, 119754925bf6Swillf char *pwd, krb5_keyblock * key) 119854925bf6Swillf { 119954925bf6Swillf krb5_error_code status = 0; 120054925bf6Swillf kdb5_dal_handle *dal_handle; 120154925bf6Swillf 120254925bf6Swillf if (kcontext->db_context == NULL) { 120354925bf6Swillf status = kdb_setup_lib_handle(kcontext); 120454925bf6Swillf if (status) { 120554925bf6Swillf goto clean_n_exit; 120654925bf6Swillf } 120754925bf6Swillf } 120854925bf6Swillf 120954925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 121054925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 121154925bf6Swillf if (status) { 121254925bf6Swillf goto clean_n_exit; 121354925bf6Swillf } 121454925bf6Swillf 121554925bf6Swillf status = dal_handle->lib_handle->vftabl.set_master_key(kcontext, pwd, key); 121654925bf6Swillf get_errmsg(kcontext, status); 121754925bf6Swillf 121854925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 121954925bf6Swillf 122054925bf6Swillf clean_n_exit: 122154925bf6Swillf return status; 122254925bf6Swillf } 122354925bf6Swillf 122454925bf6Swillf krb5_error_code 122554925bf6Swillf krb5_db_set_mkey(krb5_context context, krb5_keyblock * key) 122654925bf6Swillf { 122754925bf6Swillf return krb5_db_set_master_key_ext(context, NULL, key); 122854925bf6Swillf } 122954925bf6Swillf 123054925bf6Swillf krb5_error_code 123154925bf6Swillf krb5_db_get_mkey(krb5_context kcontext, krb5_keyblock ** key) 123254925bf6Swillf { 123354925bf6Swillf krb5_error_code status = 0; 123454925bf6Swillf kdb5_dal_handle *dal_handle; 123554925bf6Swillf 123654925bf6Swillf if (kcontext->db_context == NULL) { 123754925bf6Swillf status = kdb_setup_lib_handle(kcontext); 123854925bf6Swillf if (status) { 123954925bf6Swillf goto clean_n_exit; 124054925bf6Swillf } 124154925bf6Swillf } 124254925bf6Swillf 124354925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 124454925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 124554925bf6Swillf if (status) { 124654925bf6Swillf goto clean_n_exit; 124754925bf6Swillf } 124854925bf6Swillf 124954925bf6Swillf /* Lets use temp key and copy it later to avoid memory problems 125054925bf6Swillf when freed by the caller. */ 125154925bf6Swillf status = dal_handle->lib_handle->vftabl.get_master_key(kcontext, key); 125254925bf6Swillf get_errmsg(kcontext, status); 125354925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 125454925bf6Swillf 125554925bf6Swillf clean_n_exit: 125654925bf6Swillf return status; 125754925bf6Swillf } 125854925bf6Swillf 125954925bf6Swillf krb5_error_code 126054925bf6Swillf krb5_db_store_master_key(krb5_context kcontext, 126154925bf6Swillf char *db_arg, 126254925bf6Swillf krb5_principal mname, 126354925bf6Swillf krb5_keyblock * key, char *master_pwd) 126454925bf6Swillf { 126554925bf6Swillf krb5_error_code status = 0; 126654925bf6Swillf kdb5_dal_handle *dal_handle; 126754925bf6Swillf 126854925bf6Swillf if (kcontext->db_context == NULL) { 126954925bf6Swillf status = kdb_setup_lib_handle(kcontext); 127054925bf6Swillf if (status) { 127154925bf6Swillf goto clean_n_exit; 127254925bf6Swillf } 127354925bf6Swillf } 127454925bf6Swillf 127554925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 127654925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 127754925bf6Swillf if (status) { 127854925bf6Swillf goto clean_n_exit; 127954925bf6Swillf } 128054925bf6Swillf 128154925bf6Swillf status = dal_handle->lib_handle->vftabl.store_master_key(kcontext, 128254925bf6Swillf db_arg, 128354925bf6Swillf mname, 128454925bf6Swillf key, master_pwd); 128554925bf6Swillf get_errmsg(kcontext, status); 128654925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 128754925bf6Swillf 128854925bf6Swillf clean_n_exit: 128954925bf6Swillf return status; 129054925bf6Swillf } 129154925bf6Swillf 129254925bf6Swillf char *krb5_mkey_pwd_prompt1 = KRB5_KDC_MKEY_1; 129354925bf6Swillf char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2; 129454925bf6Swillf 129554925bf6Swillf krb5_error_code 129654925bf6Swillf krb5_db_fetch_mkey(krb5_context context, 129754925bf6Swillf krb5_principal mname, 129854925bf6Swillf krb5_enctype etype, 129954925bf6Swillf krb5_boolean fromkeyboard, 130054925bf6Swillf krb5_boolean twice, 130154925bf6Swillf char *db_args, krb5_data * salt, krb5_keyblock * key) 130254925bf6Swillf { 130354925bf6Swillf krb5_error_code retval; 130454925bf6Swillf char password[BUFSIZ]; 130554925bf6Swillf krb5_data pwd; 130654925bf6Swillf unsigned int size = sizeof(password); 130754925bf6Swillf int kvno; 130854925bf6Swillf krb5_keyblock tmp_key; 130954925bf6Swillf 131054925bf6Swillf memset(&tmp_key, 0, sizeof(tmp_key)); 131154925bf6Swillf 131254925bf6Swillf if (fromkeyboard) { 131354925bf6Swillf krb5_data scratch; 131454925bf6Swillf 131554925bf6Swillf if ((retval = krb5_read_password(context, krb5_mkey_pwd_prompt1, 131654925bf6Swillf twice ? krb5_mkey_pwd_prompt2 : 0, 131754925bf6Swillf password, &size))) { 131854925bf6Swillf goto clean_n_exit; 131954925bf6Swillf } 132054925bf6Swillf 132154925bf6Swillf pwd.data = password; 132254925bf6Swillf pwd.length = size; 132354925bf6Swillf if (!salt) { 132454925bf6Swillf retval = krb5_principal2salt(context, mname, &scratch); 132554925bf6Swillf if (retval) 132654925bf6Swillf goto clean_n_exit; 132754925bf6Swillf } 132854925bf6Swillf retval = 132954925bf6Swillf krb5_c_string_to_key(context, etype, &pwd, salt ? salt : &scratch, 133054925bf6Swillf key); 133154925bf6Swillf 133254925bf6Swillf if (!salt) 133354925bf6Swillf krb5_xfree(scratch.data); 133454925bf6Swillf memset(password, 0, sizeof(password)); /* erase it */ 133554925bf6Swillf 133654925bf6Swillf } else { 133754925bf6Swillf kdb5_dal_handle *dal_handle; 133854925bf6Swillf 133954925bf6Swillf if (context->db_context == NULL) { 134054925bf6Swillf retval = kdb_setup_lib_handle(context); 134154925bf6Swillf if (retval) { 134254925bf6Swillf goto clean_n_exit; 134354925bf6Swillf } 134454925bf6Swillf } 134554925bf6Swillf 134654925bf6Swillf dal_handle = (kdb5_dal_handle *) context->db_context; 134754925bf6Swillf retval = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 134854925bf6Swillf if (retval) { 134954925bf6Swillf goto clean_n_exit; 135054925bf6Swillf } 135154925bf6Swillf #if 0 /************** Begin IFDEF'ed OUT *******************************/ 135254925bf6Swillf /* Orig MIT */ 135354925bf6Swillf tmp_key.enctype = key->enctype; 135454925bf6Swillf #else 135554925bf6Swillf /* Solaris Kerberos: need to use etype */ 135654925bf6Swillf tmp_key.enctype = etype; 135754925bf6Swillf #endif /**************** END IFDEF'ed OUT *******************************/ 135854925bf6Swillf retval = dal_handle->lib_handle->vftabl.fetch_master_key(context, 135954925bf6Swillf mname, 136054925bf6Swillf &tmp_key, 136154925bf6Swillf &kvno, 136254925bf6Swillf db_args); 136354925bf6Swillf get_errmsg(context, retval); 136454925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 136554925bf6Swillf 136654925bf6Swillf if (retval) { 136754925bf6Swillf goto clean_n_exit; 136854925bf6Swillf } 136954925bf6Swillf 137054925bf6Swillf key->contents = malloc(tmp_key.length); 137154925bf6Swillf if (key->contents == NULL) { 137254925bf6Swillf retval = ENOMEM; 137354925bf6Swillf goto clean_n_exit; 137454925bf6Swillf } 137554925bf6Swillf 137654925bf6Swillf key->magic = tmp_key.magic; 137754925bf6Swillf key->enctype = tmp_key.enctype; 137854925bf6Swillf key->length = tmp_key.length; 137954925bf6Swillf memcpy(key->contents, tmp_key.contents, tmp_key.length); 138054925bf6Swillf } 138154925bf6Swillf 138254925bf6Swillf clean_n_exit: 138354925bf6Swillf if (tmp_key.contents) { 138454925bf6Swillf memset(tmp_key.contents, 0, tmp_key.length); 138554925bf6Swillf krb5_db_free(context, tmp_key.contents); 138654925bf6Swillf } 138754925bf6Swillf return retval; 138854925bf6Swillf } 138954925bf6Swillf 139054925bf6Swillf krb5_error_code 139154925bf6Swillf krb5_db_verify_master_key(krb5_context kcontext, 139254925bf6Swillf krb5_principal mprinc, krb5_keyblock * mkey) 139354925bf6Swillf { 139454925bf6Swillf krb5_error_code status = 0; 139554925bf6Swillf kdb5_dal_handle *dal_handle; 139654925bf6Swillf 139754925bf6Swillf if (kcontext->db_context == NULL) { 139854925bf6Swillf status = kdb_setup_lib_handle(kcontext); 139954925bf6Swillf if (status) { 140054925bf6Swillf goto clean_n_exit; 140154925bf6Swillf } 140254925bf6Swillf } 140354925bf6Swillf 140454925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 140554925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 140654925bf6Swillf if (status) { 140754925bf6Swillf goto clean_n_exit; 140854925bf6Swillf } 140954925bf6Swillf 141054925bf6Swillf status = dal_handle->lib_handle->vftabl.verify_master_key(kcontext, 141154925bf6Swillf mprinc, mkey); 141254925bf6Swillf get_errmsg(kcontext, status); 141354925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 141454925bf6Swillf 141554925bf6Swillf clean_n_exit: 141654925bf6Swillf return status; 141754925bf6Swillf } 141854925bf6Swillf 141954925bf6Swillf void * 142054925bf6Swillf krb5_db_alloc(krb5_context kcontext, void *ptr, size_t size) 142154925bf6Swillf { 142254925bf6Swillf krb5_error_code status; 142354925bf6Swillf kdb5_dal_handle *dal_handle; 142454925bf6Swillf void *new_ptr = NULL; 142554925bf6Swillf 142654925bf6Swillf if (kcontext->db_context == NULL) { 142754925bf6Swillf status = kdb_setup_lib_handle(kcontext); 142854925bf6Swillf if (status) { 142954925bf6Swillf goto clean_n_exit; 143054925bf6Swillf } 143154925bf6Swillf } 143254925bf6Swillf 143354925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 143454925bf6Swillf 143554925bf6Swillf new_ptr = dal_handle->lib_handle->vftabl.db_alloc(kcontext, ptr, size); 143654925bf6Swillf 143754925bf6Swillf clean_n_exit: 143854925bf6Swillf return new_ptr; 143954925bf6Swillf } 144054925bf6Swillf 144154925bf6Swillf void 144254925bf6Swillf krb5_db_free(krb5_context kcontext, void *ptr) 144354925bf6Swillf { 144454925bf6Swillf krb5_error_code status; 144554925bf6Swillf kdb5_dal_handle *dal_handle; 144654925bf6Swillf 144754925bf6Swillf if (kcontext->db_context == NULL) { 144854925bf6Swillf status = kdb_setup_lib_handle(kcontext); 144954925bf6Swillf if (status) { 145054925bf6Swillf goto clean_n_exit; 145154925bf6Swillf } 145254925bf6Swillf } 145354925bf6Swillf 145454925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 145554925bf6Swillf 145654925bf6Swillf dal_handle->lib_handle->vftabl.db_free(kcontext, ptr); 145754925bf6Swillf 145854925bf6Swillf clean_n_exit: 145954925bf6Swillf return; 146054925bf6Swillf } 146154925bf6Swillf 146254925bf6Swillf /* has to be modified */ 146354925bf6Swillf 146454925bf6Swillf krb5_error_code 146554925bf6Swillf krb5_dbe_find_enctype(krb5_context kcontext, 146654925bf6Swillf krb5_db_entry * dbentp, 146754925bf6Swillf krb5_int32 ktype, 146854925bf6Swillf krb5_int32 stype, 146954925bf6Swillf krb5_int32 kvno, krb5_key_data ** kdatap) 147054925bf6Swillf { 147154925bf6Swillf krb5_int32 start = 0; 147254925bf6Swillf return krb5_dbe_search_enctype(kcontext, dbentp, &start, ktype, stype, 147354925bf6Swillf kvno, kdatap); 147454925bf6Swillf } 147554925bf6Swillf 147654925bf6Swillf krb5_error_code 147754925bf6Swillf krb5_dbe_search_enctype(krb5_context kcontext, 147854925bf6Swillf krb5_db_entry * dbentp, 147954925bf6Swillf krb5_int32 * start, 148054925bf6Swillf krb5_int32 ktype, 148154925bf6Swillf krb5_int32 stype, 148254925bf6Swillf krb5_int32 kvno, krb5_key_data ** kdatap) 148354925bf6Swillf { 148454925bf6Swillf krb5_error_code status = 0; 148554925bf6Swillf kdb5_dal_handle *dal_handle; 148654925bf6Swillf 148754925bf6Swillf if (kcontext->db_context == NULL) { 148854925bf6Swillf status = kdb_setup_lib_handle(kcontext); 148954925bf6Swillf if (status) { 149054925bf6Swillf goto clean_n_exit; 149154925bf6Swillf } 149254925bf6Swillf } 149354925bf6Swillf 149454925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 149554925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 149654925bf6Swillf if (status) { 149754925bf6Swillf goto clean_n_exit; 149854925bf6Swillf } 149954925bf6Swillf 150054925bf6Swillf status = dal_handle->lib_handle->vftabl.dbe_search_enctype(kcontext, 150154925bf6Swillf dbentp, 150254925bf6Swillf start, 150354925bf6Swillf ktype, 150454925bf6Swillf stype, 150554925bf6Swillf kvno, kdatap); 150654925bf6Swillf get_errmsg(kcontext, status); 150754925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 150854925bf6Swillf 150954925bf6Swillf clean_n_exit: 151054925bf6Swillf return status; 151154925bf6Swillf } 151254925bf6Swillf 151354925bf6Swillf #define REALM_SEP_STRING "@" 151454925bf6Swillf 151554925bf6Swillf krb5_error_code 151654925bf6Swillf krb5_db_setup_mkey_name(krb5_context context, 151754925bf6Swillf const char *keyname, 151854925bf6Swillf const char *realm, 151954925bf6Swillf char **fullname, krb5_principal * principal) 152054925bf6Swillf { 152154925bf6Swillf krb5_error_code retval; 152254925bf6Swillf size_t keylen; 152354925bf6Swillf size_t rlen = strlen(realm); 152454925bf6Swillf char *fname; 152554925bf6Swillf 152654925bf6Swillf if (!keyname) 152754925bf6Swillf keyname = KRB5_KDB_M_NAME; /* XXX external? */ 152854925bf6Swillf 152954925bf6Swillf keylen = strlen(keyname); 153054925bf6Swillf 153154925bf6Swillf fname = malloc(keylen + rlen + strlen(REALM_SEP_STRING) + 1); 153254925bf6Swillf if (!fname) 153354925bf6Swillf return ENOMEM; 153454925bf6Swillf 153554925bf6Swillf strcpy(fname, keyname); 153654925bf6Swillf (void)strcat(fname, REALM_SEP_STRING); 153754925bf6Swillf (void)strcat(fname, realm); 153854925bf6Swillf 153954925bf6Swillf if ((retval = krb5_parse_name(context, fname, principal))) 154054925bf6Swillf return retval; 154154925bf6Swillf if (fullname) 154254925bf6Swillf *fullname = fname; 154354925bf6Swillf else 154454925bf6Swillf free(fname); 154554925bf6Swillf return 0; 154654925bf6Swillf } 154754925bf6Swillf 154854925bf6Swillf krb5_error_code 154954925bf6Swillf krb5_dbe_lookup_last_pwd_change(context, entry, stamp) 155054925bf6Swillf krb5_context context; 155154925bf6Swillf krb5_db_entry *entry; 155254925bf6Swillf krb5_timestamp *stamp; 155354925bf6Swillf { 155454925bf6Swillf krb5_tl_data tl_data; 155554925bf6Swillf krb5_error_code code; 155654925bf6Swillf krb5_int32 tmp; 155754925bf6Swillf 155854925bf6Swillf tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; 155954925bf6Swillf 156054925bf6Swillf if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) 156154925bf6Swillf return (code); 156254925bf6Swillf 156354925bf6Swillf if (tl_data.tl_data_length != 4) { 156454925bf6Swillf *stamp = 0; 156554925bf6Swillf return (0); 156654925bf6Swillf } 156754925bf6Swillf 156854925bf6Swillf krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp); 156954925bf6Swillf 157054925bf6Swillf *stamp = (krb5_timestamp) tmp; 157154925bf6Swillf 157254925bf6Swillf return (0); 157354925bf6Swillf } 157454925bf6Swillf 157554925bf6Swillf /*ARGSUSED*/ 157654925bf6Swillf krb5_error_code 157754925bf6Swillf krb5_dbe_lookup_tl_data(context, entry, ret_tl_data) 157854925bf6Swillf krb5_context context; 157954925bf6Swillf krb5_db_entry *entry; 158054925bf6Swillf krb5_tl_data *ret_tl_data; 158154925bf6Swillf { 158254925bf6Swillf krb5_tl_data *tl_data; 158354925bf6Swillf 158454925bf6Swillf for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { 158554925bf6Swillf if (tl_data->tl_data_type == ret_tl_data->tl_data_type) { 158654925bf6Swillf *ret_tl_data = *tl_data; 158754925bf6Swillf return (0); 158854925bf6Swillf } 158954925bf6Swillf } 159054925bf6Swillf 159154925bf6Swillf /* if the requested record isn't found, return zero bytes. 159254925bf6Swillf * if it ever means something to have a zero-length tl_data, 159354925bf6Swillf * this code and its callers will have to be changed */ 159454925bf6Swillf 159554925bf6Swillf ret_tl_data->tl_data_length = 0; 159654925bf6Swillf ret_tl_data->tl_data_contents = NULL; 159754925bf6Swillf return (0); 159854925bf6Swillf } 159954925bf6Swillf 160054925bf6Swillf krb5_error_code 160154925bf6Swillf krb5_dbe_create_key_data(context, entry) 160254925bf6Swillf krb5_context context; 160354925bf6Swillf krb5_db_entry *entry; 160454925bf6Swillf { 160554925bf6Swillf if ((entry->key_data = 160654925bf6Swillf (krb5_key_data *) krb5_db_alloc(context, entry->key_data, 160754925bf6Swillf (sizeof(krb5_key_data) * 160854925bf6Swillf (entry->n_key_data + 1)))) == NULL) 160954925bf6Swillf return (ENOMEM); 161054925bf6Swillf 161154925bf6Swillf memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data)); 161254925bf6Swillf entry->n_key_data++; 161354925bf6Swillf 161454925bf6Swillf return 0; 161554925bf6Swillf } 161654925bf6Swillf 161754925bf6Swillf krb5_error_code 161854925bf6Swillf krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ) 161954925bf6Swillf krb5_context context; 162054925bf6Swillf krb5_db_entry *entry; 162154925bf6Swillf krb5_timestamp mod_date; 162254925bf6Swillf krb5_const_principal mod_princ; 162354925bf6Swillf { 162454925bf6Swillf krb5_tl_data tl_data; 162554925bf6Swillf 162654925bf6Swillf krb5_error_code retval = 0; 162754925bf6Swillf krb5_octet *nextloc = 0; 162854925bf6Swillf char *unparse_mod_princ = 0; 162954925bf6Swillf unsigned int unparse_mod_princ_size; 163054925bf6Swillf 163154925bf6Swillf if ((retval = krb5_unparse_name(context, mod_princ, &unparse_mod_princ))) 163254925bf6Swillf return (retval); 163354925bf6Swillf 163454925bf6Swillf unparse_mod_princ_size = strlen(unparse_mod_princ) + 1; 163554925bf6Swillf 163654925bf6Swillf if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4)) 163754925bf6Swillf == NULL) { 163854925bf6Swillf free(unparse_mod_princ); 163954925bf6Swillf return (ENOMEM); 164054925bf6Swillf } 164154925bf6Swillf 164254925bf6Swillf tl_data.tl_data_type = KRB5_TL_MOD_PRINC; 164354925bf6Swillf tl_data.tl_data_length = unparse_mod_princ_size + 4; 164454925bf6Swillf tl_data.tl_data_contents = nextloc; 164554925bf6Swillf 164654925bf6Swillf /* Mod Date */ 164754925bf6Swillf krb5_kdb_encode_int32(mod_date, nextloc); 164854925bf6Swillf 164954925bf6Swillf /* Mod Princ */ 165054925bf6Swillf memcpy(nextloc + 4, unparse_mod_princ, unparse_mod_princ_size); 165154925bf6Swillf 165254925bf6Swillf retval = krb5_dbe_update_tl_data(context, entry, &tl_data); 165354925bf6Swillf 165454925bf6Swillf free(unparse_mod_princ); 165554925bf6Swillf free(nextloc); 165654925bf6Swillf 165754925bf6Swillf return (retval); 165854925bf6Swillf } 165954925bf6Swillf 166054925bf6Swillf krb5_error_code 166154925bf6Swillf krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ) 166254925bf6Swillf krb5_context context; 166354925bf6Swillf krb5_db_entry *entry; 166454925bf6Swillf krb5_timestamp *mod_time; 166554925bf6Swillf krb5_principal *mod_princ; 166654925bf6Swillf { 166754925bf6Swillf krb5_tl_data tl_data; 166854925bf6Swillf krb5_error_code code; 166954925bf6Swillf 167054925bf6Swillf tl_data.tl_data_type = KRB5_TL_MOD_PRINC; 167154925bf6Swillf 167254925bf6Swillf if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) 167354925bf6Swillf return (code); 167454925bf6Swillf 167554925bf6Swillf if ((tl_data.tl_data_length < 5) || 167654925bf6Swillf (tl_data.tl_data_contents[tl_data.tl_data_length - 1] != '\0')) 167754925bf6Swillf return (KRB5_KDB_TRUNCATED_RECORD); 167854925bf6Swillf 167954925bf6Swillf /* Mod Date */ 168054925bf6Swillf krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time); 168154925bf6Swillf 168254925bf6Swillf /* Mod Princ */ 168354925bf6Swillf if ((code = krb5_parse_name(context, 168454925bf6Swillf (const char *) (tl_data.tl_data_contents + 4), 168554925bf6Swillf mod_princ))) 168654925bf6Swillf return (code); 168754925bf6Swillf 168854925bf6Swillf return (0); 168954925bf6Swillf } 169054925bf6Swillf 169154925bf6Swillf krb5_error_code 169254925bf6Swillf krb5_dbe_update_last_pwd_change(context, entry, stamp) 169354925bf6Swillf krb5_context context; 169454925bf6Swillf krb5_db_entry *entry; 169554925bf6Swillf krb5_timestamp stamp; 169654925bf6Swillf { 169754925bf6Swillf krb5_tl_data tl_data; 169854925bf6Swillf krb5_octet buf[4]; /* this is the encoded size of an int32 */ 169954925bf6Swillf 170054925bf6Swillf tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; 170154925bf6Swillf tl_data.tl_data_length = sizeof(buf); 170254925bf6Swillf krb5_kdb_encode_int32((krb5_int32) stamp, buf); 170354925bf6Swillf tl_data.tl_data_contents = buf; 170454925bf6Swillf 170554925bf6Swillf return (krb5_dbe_update_tl_data(context, entry, &tl_data)); 170654925bf6Swillf } 170754925bf6Swillf 170854925bf6Swillf krb5_error_code 170954925bf6Swillf krb5_dbe_update_tl_data(context, entry, new_tl_data) 171054925bf6Swillf krb5_context context; 171154925bf6Swillf krb5_db_entry *entry; 171254925bf6Swillf krb5_tl_data *new_tl_data; 171354925bf6Swillf { 171454925bf6Swillf krb5_tl_data *tl_data = NULL; 171554925bf6Swillf krb5_octet *tmp; 171654925bf6Swillf 171754925bf6Swillf /* copy the new data first, so we can fail cleanly if malloc() 171854925bf6Swillf * fails */ 171954925bf6Swillf if ((tmp = 172054925bf6Swillf (krb5_octet *) krb5_db_alloc(context, NULL, 172154925bf6Swillf new_tl_data->tl_data_length)) == NULL) 172254925bf6Swillf return (ENOMEM); 172354925bf6Swillf 172454925bf6Swillf /* Find an existing entry of the specified type and point at 172554925bf6Swillf * it, or NULL if not found */ 172654925bf6Swillf 172754925bf6Swillf if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) { /* db_args can be multiple */ 172854925bf6Swillf for (tl_data = entry->tl_data; tl_data; 172954925bf6Swillf tl_data = tl_data->tl_data_next) 173054925bf6Swillf if (tl_data->tl_data_type == new_tl_data->tl_data_type) 173154925bf6Swillf break; 173254925bf6Swillf } 173354925bf6Swillf 173454925bf6Swillf /* if necessary, chain a new record in the beginning and point at it */ 173554925bf6Swillf 173654925bf6Swillf if (!tl_data) { 173754925bf6Swillf if ((tl_data = 173854925bf6Swillf (krb5_tl_data *) krb5_db_alloc(context, NULL, 173954925bf6Swillf sizeof(krb5_tl_data))) 174054925bf6Swillf == NULL) { 174154925bf6Swillf free(tmp); 174254925bf6Swillf return (ENOMEM); 174354925bf6Swillf } 174454925bf6Swillf memset(tl_data, 0, sizeof(krb5_tl_data)); 174554925bf6Swillf tl_data->tl_data_next = entry->tl_data; 174654925bf6Swillf entry->tl_data = tl_data; 174754925bf6Swillf entry->n_tl_data++; 174854925bf6Swillf } 174954925bf6Swillf 175054925bf6Swillf /* fill in the record */ 175154925bf6Swillf 175254925bf6Swillf if (tl_data->tl_data_contents) 175354925bf6Swillf krb5_db_free(context, tl_data->tl_data_contents); 175454925bf6Swillf 175554925bf6Swillf tl_data->tl_data_type = new_tl_data->tl_data_type; 175654925bf6Swillf tl_data->tl_data_length = new_tl_data->tl_data_length; 175754925bf6Swillf tl_data->tl_data_contents = tmp; 175854925bf6Swillf memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length); 175954925bf6Swillf 176054925bf6Swillf return (0); 176154925bf6Swillf } 176254925bf6Swillf 176354925bf6Swillf /* change password functions */ 176454925bf6Swillf krb5_error_code 176554925bf6Swillf krb5_dbe_cpw(krb5_context kcontext, 176654925bf6Swillf krb5_keyblock * master_key, 176754925bf6Swillf krb5_key_salt_tuple * ks_tuple, 176854925bf6Swillf int ks_tuple_count, 176954925bf6Swillf char *passwd, 177054925bf6Swillf int new_kvno, krb5_boolean keepold, krb5_db_entry * db_entry) 177154925bf6Swillf { 177254925bf6Swillf krb5_error_code status = 0; 177354925bf6Swillf kdb5_dal_handle *dal_handle; 177454925bf6Swillf 177554925bf6Swillf if (kcontext->db_context == NULL) { 177654925bf6Swillf status = kdb_setup_lib_handle(kcontext); 177754925bf6Swillf if (status) { 177854925bf6Swillf goto clean_n_exit; 177954925bf6Swillf } 178054925bf6Swillf } 178154925bf6Swillf 178254925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 178354925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 178454925bf6Swillf if (status) { 178554925bf6Swillf goto clean_n_exit; 178654925bf6Swillf } 178754925bf6Swillf 178854925bf6Swillf status = dal_handle->lib_handle->vftabl.db_change_pwd(kcontext, 178954925bf6Swillf master_key, 179054925bf6Swillf ks_tuple, 179154925bf6Swillf ks_tuple_count, 179254925bf6Swillf passwd, 179354925bf6Swillf new_kvno, 179454925bf6Swillf keepold, db_entry); 179554925bf6Swillf get_errmsg(kcontext, status); 179654925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 179754925bf6Swillf 179854925bf6Swillf clean_n_exit: 179954925bf6Swillf return status; 180054925bf6Swillf } 180154925bf6Swillf 180254925bf6Swillf /* policy management functions */ 180354925bf6Swillf krb5_error_code 180454925bf6Swillf krb5_db_create_policy(krb5_context kcontext, osa_policy_ent_t policy) 180554925bf6Swillf { 180654925bf6Swillf krb5_error_code status = 0; 180754925bf6Swillf kdb5_dal_handle *dal_handle; 180854925bf6Swillf 180954925bf6Swillf if (kcontext->db_context == NULL) { 181054925bf6Swillf status = kdb_setup_lib_handle(kcontext); 181154925bf6Swillf if (status) { 181254925bf6Swillf goto clean_n_exit; 181354925bf6Swillf } 181454925bf6Swillf } 181554925bf6Swillf 181654925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 181754925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 181854925bf6Swillf if (status) { 181954925bf6Swillf goto clean_n_exit; 182054925bf6Swillf } 182154925bf6Swillf 182254925bf6Swillf status = dal_handle->lib_handle->vftabl.db_create_policy(kcontext, policy); 182354925bf6Swillf get_errmsg(kcontext, status); 182454925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 182554925bf6Swillf 182654925bf6Swillf clean_n_exit: 182754925bf6Swillf return status; 182854925bf6Swillf } 182954925bf6Swillf 183054925bf6Swillf krb5_error_code 183154925bf6Swillf krb5_db_get_policy(krb5_context kcontext, char *name, 183254925bf6Swillf osa_policy_ent_t * policy, int *cnt) 183354925bf6Swillf { 183454925bf6Swillf krb5_error_code status = 0; 183554925bf6Swillf kdb5_dal_handle *dal_handle; 183654925bf6Swillf 183754925bf6Swillf if (kcontext->db_context == NULL) { 183854925bf6Swillf status = kdb_setup_lib_handle(kcontext); 183954925bf6Swillf if (status) { 184054925bf6Swillf goto clean_n_exit; 184154925bf6Swillf } 184254925bf6Swillf } 184354925bf6Swillf 184454925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 184554925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 184654925bf6Swillf if (status) { 184754925bf6Swillf goto clean_n_exit; 184854925bf6Swillf } 184954925bf6Swillf 185054925bf6Swillf status = 185154925bf6Swillf dal_handle->lib_handle->vftabl.db_get_policy(kcontext, name, policy, 185254925bf6Swillf cnt); 185354925bf6Swillf get_errmsg(kcontext, status); 185454925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 185554925bf6Swillf 185654925bf6Swillf clean_n_exit: 185754925bf6Swillf return status; 185854925bf6Swillf } 185954925bf6Swillf 186054925bf6Swillf krb5_error_code 186154925bf6Swillf krb5_db_put_policy(krb5_context kcontext, osa_policy_ent_t policy) 186254925bf6Swillf { 186354925bf6Swillf krb5_error_code status = 0; 186454925bf6Swillf kdb5_dal_handle *dal_handle; 186554925bf6Swillf 186654925bf6Swillf if (kcontext->db_context == NULL) { 186754925bf6Swillf status = kdb_setup_lib_handle(kcontext); 186854925bf6Swillf if (status) { 186954925bf6Swillf goto clean_n_exit; 187054925bf6Swillf } 187154925bf6Swillf } 187254925bf6Swillf 187354925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 187454925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 187554925bf6Swillf if (status) { 187654925bf6Swillf goto clean_n_exit; 187754925bf6Swillf } 187854925bf6Swillf 187954925bf6Swillf status = dal_handle->lib_handle->vftabl.db_put_policy(kcontext, policy); 188054925bf6Swillf get_errmsg(kcontext, status); 188154925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 188254925bf6Swillf 188354925bf6Swillf clean_n_exit: 188454925bf6Swillf return status; 188554925bf6Swillf } 188654925bf6Swillf 188754925bf6Swillf krb5_error_code 188854925bf6Swillf krb5_db_iter_policy(krb5_context kcontext, char *match_entry, 188954925bf6Swillf osa_adb_iter_policy_func func, void *data) 189054925bf6Swillf { 189154925bf6Swillf krb5_error_code status = 0; 189254925bf6Swillf kdb5_dal_handle *dal_handle; 189354925bf6Swillf 189454925bf6Swillf if (kcontext->db_context == NULL) { 189554925bf6Swillf status = kdb_setup_lib_handle(kcontext); 189654925bf6Swillf if (status) { 189754925bf6Swillf goto clean_n_exit; 189854925bf6Swillf } 189954925bf6Swillf } 190054925bf6Swillf 190154925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 190254925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 190354925bf6Swillf if (status) { 190454925bf6Swillf goto clean_n_exit; 190554925bf6Swillf } 190654925bf6Swillf 190754925bf6Swillf status = 190854925bf6Swillf dal_handle->lib_handle->vftabl.db_iter_policy(kcontext, match_entry, 190954925bf6Swillf func, data); 191054925bf6Swillf get_errmsg(kcontext, status); 191154925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 191254925bf6Swillf 191354925bf6Swillf clean_n_exit: 191454925bf6Swillf return status; 191554925bf6Swillf } 191654925bf6Swillf 191754925bf6Swillf krb5_error_code 191854925bf6Swillf krb5_db_delete_policy(krb5_context kcontext, char *policy) 191954925bf6Swillf { 192054925bf6Swillf krb5_error_code status = 0; 192154925bf6Swillf kdb5_dal_handle *dal_handle; 192254925bf6Swillf 192354925bf6Swillf if (kcontext->db_context == NULL) { 192454925bf6Swillf status = kdb_setup_lib_handle(kcontext); 192554925bf6Swillf if (status) { 192654925bf6Swillf goto clean_n_exit; 192754925bf6Swillf } 192854925bf6Swillf } 192954925bf6Swillf 193054925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 193154925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 193254925bf6Swillf if (status) { 193354925bf6Swillf goto clean_n_exit; 193454925bf6Swillf } 193554925bf6Swillf 193654925bf6Swillf status = dal_handle->lib_handle->vftabl.db_delete_policy(kcontext, policy); 193754925bf6Swillf get_errmsg(kcontext, status); 193854925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 193954925bf6Swillf 194054925bf6Swillf clean_n_exit: 194154925bf6Swillf return status; 194254925bf6Swillf } 194354925bf6Swillf 194454925bf6Swillf void 194554925bf6Swillf krb5_db_free_policy(krb5_context kcontext, osa_policy_ent_t policy) 194654925bf6Swillf { 194754925bf6Swillf krb5_error_code status = 0; 194854925bf6Swillf kdb5_dal_handle *dal_handle; 194954925bf6Swillf 195054925bf6Swillf if (kcontext->db_context == NULL) { 195154925bf6Swillf status = kdb_setup_lib_handle(kcontext); 195254925bf6Swillf if (status) { 195354925bf6Swillf goto clean_n_exit; 195454925bf6Swillf } 195554925bf6Swillf } 195654925bf6Swillf 195754925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 195854925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 195954925bf6Swillf if (status) { 196054925bf6Swillf goto clean_n_exit; 196154925bf6Swillf } 196254925bf6Swillf 196354925bf6Swillf dal_handle->lib_handle->vftabl.db_free_policy(kcontext, policy); 196454925bf6Swillf get_errmsg(kcontext, status); 196554925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 196654925bf6Swillf 196754925bf6Swillf clean_n_exit: 196854925bf6Swillf return; 196954925bf6Swillf } 197054925bf6Swillf 197154925bf6Swillf krb5_error_code 197254925bf6Swillf krb5_db_promote(krb5_context kcontext, char **db_args) 197354925bf6Swillf { 197454925bf6Swillf krb5_error_code status = 0; 197554925bf6Swillf char *section = NULL; 197654925bf6Swillf kdb5_dal_handle *dal_handle; 197754925bf6Swillf 197854925bf6Swillf section = kdb_get_conf_section(kcontext); 197954925bf6Swillf if (section == NULL) { 198054925bf6Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR; 198154925bf6Swillf krb5_set_error_message (kcontext, status, 198254925bf6Swillf gettext("unable to determine configuration section for realm %s\n"), 198354925bf6Swillf kcontext->default_realm); 198454925bf6Swillf goto clean_n_exit; 198554925bf6Swillf } 198654925bf6Swillf 198754925bf6Swillf if (kcontext->db_context == NULL) { 198854925bf6Swillf status = kdb_setup_lib_handle(kcontext); 198954925bf6Swillf if (status) { 199054925bf6Swillf goto clean_n_exit; 199154925bf6Swillf } 199254925bf6Swillf } 199354925bf6Swillf 199454925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 199554925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 199654925bf6Swillf if (status) { 199754925bf6Swillf goto clean_n_exit; 199854925bf6Swillf } 199954925bf6Swillf 200054925bf6Swillf status = 200154925bf6Swillf dal_handle->lib_handle->vftabl.promote_db(kcontext, section, db_args); 200254925bf6Swillf get_errmsg(kcontext, status); 200354925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 200454925bf6Swillf 200554925bf6Swillf clean_n_exit: 200654925bf6Swillf if (section) 200754925bf6Swillf free(section); 200854925bf6Swillf return status; 200954925bf6Swillf } 201054925bf6Swillf 201154925bf6Swillf /* 201254925bf6Swillf * Solaris Kerberos: support for iprop 201354925bf6Swillf * 201454925bf6Swillf * Not all KDB plugins support iprop. 201554925bf6Swillf * 201654925bf6Swillf * sets iprop_supported to 1 if iprop supportd, 0 otherwise. 201754925bf6Swillf */ 201854925bf6Swillf krb5_error_code 201954925bf6Swillf krb5_db_supports_iprop(krb5_context kcontext, int *iprop_supported) 202054925bf6Swillf { 202154925bf6Swillf krb5_error_code status = 0; 202254925bf6Swillf kdb5_dal_handle *dal_handle; 202354925bf6Swillf 202454925bf6Swillf if (kcontext->db_context == NULL) { 202554925bf6Swillf status = kdb_setup_lib_handle(kcontext); 202654925bf6Swillf if (status) { 202754925bf6Swillf goto clean_n_exit; 202854925bf6Swillf } 202954925bf6Swillf } 203054925bf6Swillf 203154925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 203254925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 203354925bf6Swillf if (status) { 203454925bf6Swillf goto clean_n_exit; 203554925bf6Swillf } 203654925bf6Swillf 203754925bf6Swillf *iprop_supported = dal_handle->lib_handle->vftabl.iprop_supported; 203854925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 203954925bf6Swillf 204054925bf6Swillf clean_n_exit: 204154925bf6Swillf return status; 204254925bf6Swillf } 2043