1*54925bf6Swillf /* 2*54925bf6Swillf * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 3*54925bf6Swillf * Use is subject to license terms. 4*54925bf6Swillf */ 5*54925bf6Swillf 6*54925bf6Swillf #pragma ident "%Z%%M% %I% %E% SMI" 7*54925bf6Swillf /* 8*54925bf6Swillf * Copyright 2006 by the Massachusetts Institute of Technology. 9*54925bf6Swillf * All Rights Reserved. 10*54925bf6Swillf * 11*54925bf6Swillf * Export of this software from the United States of America may 12*54925bf6Swillf * require a specific license from the United States Government. 13*54925bf6Swillf * It is the responsibility of any person or organization contemplating 14*54925bf6Swillf * export to obtain such a license before exporting. 15*54925bf6Swillf * 16*54925bf6Swillf * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 17*54925bf6Swillf * distribute this software and its documentation for any purpose and 18*54925bf6Swillf * without fee is hereby granted, provided that the above copyright 19*54925bf6Swillf * notice appear in all copies and that both that copyright notice and 20*54925bf6Swillf * this permission notice appear in supporting documentation, and that 21*54925bf6Swillf * the name of M.I.T. not be used in advertising or publicity pertaining 22*54925bf6Swillf * to distribution of the software without specific, written prior 23*54925bf6Swillf * permission. Furthermore if you modify this software you must label 24*54925bf6Swillf * your software as modified software and not distribute it in such a 25*54925bf6Swillf * fashion that it might be confused with the original M.I.T. software. 26*54925bf6Swillf * M.I.T. makes no representations about the suitability of 27*54925bf6Swillf * this software for any purpose. It is provided "as is" without express 28*54925bf6Swillf * or implied warranty. 29*54925bf6Swillf */ 30*54925bf6Swillf 31*54925bf6Swillf /* 32*54925bf6Swillf * This code was based on code donated to MIT by Novell for 33*54925bf6Swillf * distribution under the MIT license. 34*54925bf6Swillf */ 35*54925bf6Swillf 36*54925bf6Swillf /* 37*54925bf6Swillf * Include files 38*54925bf6Swillf */ 39*54925bf6Swillf 40*54925bf6Swillf #include <stdio.h> 41*54925bf6Swillf #include <string.h> 42*54925bf6Swillf #include <k5-int.h> 43*54925bf6Swillf #include <osconf.h> 44*54925bf6Swillf #include "kdb5.h" 45*54925bf6Swillf #include <assert.h> 46*54925bf6Swillf #include "k5-platform.h" 47*54925bf6Swillf #include <libintl.h> 48*54925bf6Swillf 49*54925bf6Swillf /* Currently DB2 policy related errors are exported from DAL. But 50*54925bf6Swillf other databases should set_err function to return string. */ 51*54925bf6Swillf #include "adb_err.h" 52*54925bf6Swillf 53*54925bf6Swillf /* 54*54925bf6Swillf * Type definitions 55*54925bf6Swillf */ 56*54925bf6Swillf #define KRB5_TL_DB_ARGS 0x7fff 57*54925bf6Swillf 58*54925bf6Swillf /* 59*54925bf6Swillf * internal static variable 60*54925bf6Swillf */ 61*54925bf6Swillf 62*54925bf6Swillf static k5_mutex_t db_lock = K5_MUTEX_PARTIAL_INITIALIZER; 63*54925bf6Swillf 64*54925bf6Swillf #ifdef _KDB5_STATIC_LINK 65*54925bf6Swillf #undef _KDB5_DYNAMIC_LINK 66*54925bf6Swillf #else 67*54925bf6Swillf #undef _KDB5_DYNAMIC_LINK 68*54925bf6Swillf /* to avoid redefinition problem */ 69*54925bf6Swillf #define _KDB5_DYNAMIC_LINK 70*54925bf6Swillf #endif 71*54925bf6Swillf 72*54925bf6Swillf static db_library lib_list; 73*54925bf6Swillf 74*54925bf6Swillf /* 75*54925bf6Swillf * Helper Functions 76*54925bf6Swillf */ 77*54925bf6Swillf 78*54925bf6Swillf MAKE_INIT_FUNCTION(kdb_init_lock_list); 79*54925bf6Swillf MAKE_FINI_FUNCTION(kdb_fini_lock_list); 80*54925bf6Swillf 81*54925bf6Swillf int 82*54925bf6Swillf kdb_init_lock_list(void) 83*54925bf6Swillf { 84*54925bf6Swillf return k5_mutex_finish_init(&db_lock); 85*54925bf6Swillf } 86*54925bf6Swillf 87*54925bf6Swillf static int 88*54925bf6Swillf kdb_lock_list() 89*54925bf6Swillf { 90*54925bf6Swillf int err; 91*54925bf6Swillf err = CALL_INIT_FUNCTION (kdb_init_lock_list); 92*54925bf6Swillf if (err) 93*54925bf6Swillf return err; 94*54925bf6Swillf return k5_mutex_lock(&db_lock); 95*54925bf6Swillf } 96*54925bf6Swillf 97*54925bf6Swillf void 98*54925bf6Swillf kdb_fini_lock_list(void) 99*54925bf6Swillf { 100*54925bf6Swillf if (INITIALIZER_RAN(kdb_init_lock_list)) 101*54925bf6Swillf k5_mutex_destroy(&db_lock); 102*54925bf6Swillf } 103*54925bf6Swillf 104*54925bf6Swillf static int 105*54925bf6Swillf kdb_unlock_list() 106*54925bf6Swillf { 107*54925bf6Swillf return k5_mutex_unlock(&db_lock); 108*54925bf6Swillf } 109*54925bf6Swillf 110*54925bf6Swillf #define kdb_init_lib_lock(a) 0 111*54925bf6Swillf #define kdb_destroy_lib_lock(a) (void)0 112*54925bf6Swillf #define kdb_lock_lib_lock(a, b) 0 113*54925bf6Swillf #define kdb_unlock_lib_lock(a, b) (void)0 114*54925bf6Swillf 115*54925bf6Swillf /* Caller must free result*/ 116*54925bf6Swillf 117*54925bf6Swillf static char * 118*54925bf6Swillf kdb_get_conf_section(krb5_context kcontext) 119*54925bf6Swillf { 120*54925bf6Swillf krb5_error_code status = 0; 121*54925bf6Swillf char *result = NULL; 122*54925bf6Swillf char *value = NULL; 123*54925bf6Swillf 124*54925bf6Swillf if (kcontext->default_realm == NULL) 125*54925bf6Swillf return NULL; 126*54925bf6Swillf /* The profile has to have been initialized. If the profile was 127*54925bf6Swillf not initialized, expect nothing less than a crash. */ 128*54925bf6Swillf status = profile_get_string(kcontext->profile, 129*54925bf6Swillf /* realms */ 130*54925bf6Swillf KDB_REALM_SECTION, 131*54925bf6Swillf kcontext->default_realm, 132*54925bf6Swillf /* under the realm name, database_module */ 133*54925bf6Swillf KDB_MODULE_POINTER, 134*54925bf6Swillf /* default value is the realm name itself */ 135*54925bf6Swillf kcontext->default_realm, 136*54925bf6Swillf &value); 137*54925bf6Swillf 138*54925bf6Swillf if (status) { 139*54925bf6Swillf /* some problem */ 140*54925bf6Swillf result = strdup(kcontext->default_realm); 141*54925bf6Swillf /* let NULL be handled by the caller */ 142*54925bf6Swillf } else { 143*54925bf6Swillf result = strdup(value); 144*54925bf6Swillf /* free profile string */ 145*54925bf6Swillf profile_release_string(value); 146*54925bf6Swillf } 147*54925bf6Swillf 148*54925bf6Swillf return result; 149*54925bf6Swillf } 150*54925bf6Swillf 151*54925bf6Swillf static char * 152*54925bf6Swillf kdb_get_library_name(krb5_context kcontext) 153*54925bf6Swillf { 154*54925bf6Swillf krb5_error_code status = 0; 155*54925bf6Swillf char *result = NULL; 156*54925bf6Swillf char *value = NULL; 157*54925bf6Swillf char *lib = NULL; 158*54925bf6Swillf 159*54925bf6Swillf status = profile_get_string(kcontext->profile, 160*54925bf6Swillf /* realms */ 161*54925bf6Swillf KDB_REALM_SECTION, 162*54925bf6Swillf kcontext->default_realm, 163*54925bf6Swillf /* under the realm name, database_module */ 164*54925bf6Swillf KDB_MODULE_POINTER, 165*54925bf6Swillf /* default value is the realm name itself */ 166*54925bf6Swillf kcontext->default_realm, 167*54925bf6Swillf &value); 168*54925bf6Swillf if (status) { 169*54925bf6Swillf goto clean_n_exit; 170*54925bf6Swillf } 171*54925bf6Swillf 172*54925bf6Swillf #define DB2_NAME "db2" 173*54925bf6Swillf /* we got the module section. Get the library name from the module */ 174*54925bf6Swillf status = profile_get_string(kcontext->profile, KDB_MODULE_SECTION, value, 175*54925bf6Swillf KDB_LIB_POINTER, 176*54925bf6Swillf /* default to db2 */ 177*54925bf6Swillf DB2_NAME, 178*54925bf6Swillf &lib); 179*54925bf6Swillf 180*54925bf6Swillf if (status) { 181*54925bf6Swillf goto clean_n_exit; 182*54925bf6Swillf } 183*54925bf6Swillf 184*54925bf6Swillf result = strdup(lib); 185*54925bf6Swillf clean_n_exit: 186*54925bf6Swillf if (value) { 187*54925bf6Swillf /* free profile string */ 188*54925bf6Swillf profile_release_string(value); 189*54925bf6Swillf } 190*54925bf6Swillf 191*54925bf6Swillf if (lib) { 192*54925bf6Swillf /* free profile string */ 193*54925bf6Swillf profile_release_string(lib); 194*54925bf6Swillf } 195*54925bf6Swillf return result; 196*54925bf6Swillf } 197*54925bf6Swillf 198*54925bf6Swillf static void 199*54925bf6Swillf kdb_setup_opt_functions(db_library lib) 200*54925bf6Swillf { 201*54925bf6Swillf if (lib->vftabl.set_master_key == NULL) { 202*54925bf6Swillf lib->vftabl.set_master_key = kdb_def_set_mkey; 203*54925bf6Swillf } 204*54925bf6Swillf 205*54925bf6Swillf if (lib->vftabl.get_master_key == NULL) { 206*54925bf6Swillf lib->vftabl.get_master_key = kdb_def_get_mkey; 207*54925bf6Swillf } 208*54925bf6Swillf 209*54925bf6Swillf if (lib->vftabl.fetch_master_key == NULL) { 210*54925bf6Swillf lib->vftabl.fetch_master_key = krb5_db_def_fetch_mkey; 211*54925bf6Swillf } 212*54925bf6Swillf 213*54925bf6Swillf if (lib->vftabl.verify_master_key == NULL) { 214*54925bf6Swillf lib->vftabl.verify_master_key = krb5_def_verify_master_key; 215*54925bf6Swillf } 216*54925bf6Swillf 217*54925bf6Swillf if (lib->vftabl.dbe_search_enctype == NULL) { 218*54925bf6Swillf lib->vftabl.dbe_search_enctype = krb5_dbe_def_search_enctype; 219*54925bf6Swillf } 220*54925bf6Swillf 221*54925bf6Swillf if (lib->vftabl.db_change_pwd == NULL) { 222*54925bf6Swillf lib->vftabl.db_change_pwd = krb5_dbe_def_cpw; 223*54925bf6Swillf } 224*54925bf6Swillf 225*54925bf6Swillf if (lib->vftabl.store_master_key == NULL) { 226*54925bf6Swillf lib->vftabl.store_master_key = krb5_def_store_mkey; 227*54925bf6Swillf } 228*54925bf6Swillf 229*54925bf6Swillf if (lib->vftabl.promote_db == NULL) { 230*54925bf6Swillf lib->vftabl.promote_db = krb5_def_promote_db; 231*54925bf6Swillf } 232*54925bf6Swillf } 233*54925bf6Swillf 234*54925bf6Swillf static int kdb_db2_pol_err_loaded = 0; 235*54925bf6Swillf #ifdef _KDB5_STATIC_LINK 236*54925bf6Swillf #define DEF_SYMBOL(a) extern kdb_vftabl krb5_db_vftabl_ ## a 237*54925bf6Swillf #define GET_SYMBOL(a) (krb5_db_vftabl_ ## a) 238*54925bf6Swillf static krb5_error_code 239*54925bf6Swillf kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib) 240*54925bf6Swillf { 241*54925bf6Swillf krb5_error_code status; 242*54925bf6Swillf void *vftabl_addr = NULL; 243*54925bf6Swillf char buf[KRB5_MAX_ERR_STR]; 244*54925bf6Swillf 245*54925bf6Swillf if (!strcmp("kdb_db2", lib_name) && (kdb_db2_pol_err_loaded == 0)) { 246*54925bf6Swillf initialize_adb_error_table(); 247*54925bf6Swillf kdb_db2_pol_err_loaded = 1; 248*54925bf6Swillf } 249*54925bf6Swillf 250*54925bf6Swillf *lib = calloc((size_t) 1, sizeof(**lib)); 251*54925bf6Swillf if (*lib == NULL) { 252*54925bf6Swillf status = ENOMEM; 253*54925bf6Swillf goto clean_n_exit; 254*54925bf6Swillf } 255*54925bf6Swillf 256*54925bf6Swillf status = kdb_init_lib_lock(*lib); 257*54925bf6Swillf if (status) { 258*54925bf6Swillf goto clean_n_exit; 259*54925bf6Swillf } 260*54925bf6Swillf 261*54925bf6Swillf strcpy((*lib)->name, lib_name); 262*54925bf6Swillf 263*54925bf6Swillf #if !defined(KDB5_USE_LIB_KDB_DB2) && !defined(KDB5_USE_LIB_TEST) 264*54925bf6Swillf #error No database module defined 265*54925bf6Swillf #endif 266*54925bf6Swillf 267*54925bf6Swillf #ifdef KDB5_USE_LIB_KDB_DB2 268*54925bf6Swillf if (strcmp(lib_name, "kdb_db2") == 0) { 269*54925bf6Swillf DEF_SYMBOL(kdb_db2); 270*54925bf6Swillf vftabl_addr = (void *) &GET_SYMBOL(kdb_db2); 271*54925bf6Swillf } else 272*54925bf6Swillf #endif 273*54925bf6Swillf #ifdef KDB5_USE_LIB_TEST 274*54925bf6Swillf if (strcmp(lib_name, "test") == 0) { 275*54925bf6Swillf DEF_SYMBOL(test); 276*54925bf6Swillf vftabl_addr = (void *) &GET_SYMBOL(test); 277*54925bf6Swillf } else 278*54925bf6Swillf #endif 279*54925bf6Swillf { 280*54925bf6Swillf snprintf(buf, sizeof(buf), gettext("Program not built to support %s database type\n"), 281*54925bf6Swillf lib_name); 282*54925bf6Swillf status = KRB5_KDB_DBTYPE_NOSUP; 283*54925bf6Swillf krb5_db_set_err(kcontext, krb5_err_have_str, status, buf); 284*54925bf6Swillf goto clean_n_exit; 285*54925bf6Swillf } 286*54925bf6Swillf 287*54925bf6Swillf memcpy(&(*lib)->vftabl, vftabl_addr, sizeof(kdb_vftabl)); 288*54925bf6Swillf 289*54925bf6Swillf kdb_setup_opt_functions(*lib); 290*54925bf6Swillf 291*54925bf6Swillf if ((status = (*lib)->vftabl.init_library())) { 292*54925bf6Swillf /* ERROR. library not initialized cleanly */ 293*54925bf6Swillf snprintf(buf, sizeof(buf), gettext("%s library initialization failed, error code %ld\n"), 294*54925bf6Swillf lib_name, status); 295*54925bf6Swillf status = KRB5_KDB_DBTYPE_INIT; 296*54925bf6Swillf krb5_db_set_err(kcontext, krb5_err_have_str, status, buf); 297*54925bf6Swillf goto clean_n_exit; 298*54925bf6Swillf } 299*54925bf6Swillf 300*54925bf6Swillf clean_n_exit: 301*54925bf6Swillf if (status) { 302*54925bf6Swillf free(*lib), *lib = NULL; 303*54925bf6Swillf } 304*54925bf6Swillf return status; 305*54925bf6Swillf } 306*54925bf6Swillf 307*54925bf6Swillf #else /* KDB5_STATIC_LINK*/ 308*54925bf6Swillf 309*54925bf6Swillf static char *db_dl_location[] = DEFAULT_KDB_LIB_PATH; 310*54925bf6Swillf #define db_dl_n_locations (sizeof(db_dl_location) / sizeof(db_dl_location[0])) 311*54925bf6Swillf 312*54925bf6Swillf static krb5_error_code 313*54925bf6Swillf kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib) 314*54925bf6Swillf { 315*54925bf6Swillf krb5_error_code status = 0; 316*54925bf6Swillf int ndx; 317*54925bf6Swillf void **vftabl_addrs = NULL; 318*54925bf6Swillf /* N.B.: If this is "const" but not "static", the Solaris 10 319*54925bf6Swillf native compiler has trouble building the library because of 320*54925bf6Swillf absolute relocations needed in read-only section ".rodata". 321*54925bf6Swillf When it's static, it goes into ".picdata", which is 322*54925bf6Swillf read-write. */ 323*54925bf6Swillf static const char *const dbpath_names[] = { 324*54925bf6Swillf KDB_MODULE_SECTION, "db_module_dir", NULL, 325*54925bf6Swillf }; 326*54925bf6Swillf const char *filebases[2]; 327*54925bf6Swillf char **profpath = NULL; 328*54925bf6Swillf char **path = NULL; 329*54925bf6Swillf 330*54925bf6Swillf filebases[0] = lib_name; 331*54925bf6Swillf filebases[1] = NULL; 332*54925bf6Swillf 333*54925bf6Swillf if (!strcmp(DB2_NAME, lib_name) && (kdb_db2_pol_err_loaded == 0)) { 334*54925bf6Swillf initialize_adb_error_table(); 335*54925bf6Swillf kdb_db2_pol_err_loaded = 1; 336*54925bf6Swillf } 337*54925bf6Swillf 338*54925bf6Swillf *lib = calloc((size_t) 1, sizeof(**lib)); 339*54925bf6Swillf if (*lib == NULL) { 340*54925bf6Swillf status = ENOMEM; 341*54925bf6Swillf goto clean_n_exit; 342*54925bf6Swillf } 343*54925bf6Swillf 344*54925bf6Swillf status = kdb_init_lib_lock(*lib); 345*54925bf6Swillf if (status) { 346*54925bf6Swillf goto clean_n_exit; 347*54925bf6Swillf } 348*54925bf6Swillf 349*54925bf6Swillf strcpy((*lib)->name, lib_name); 350*54925bf6Swillf 351*54925bf6Swillf /* Fetch the list of directories specified in the config 352*54925bf6Swillf file(s) first. */ 353*54925bf6Swillf status = profile_get_values(kcontext->profile, dbpath_names, &profpath); 354*54925bf6Swillf if (status != 0 && status != PROF_NO_RELATION) 355*54925bf6Swillf goto clean_n_exit; 356*54925bf6Swillf ndx = 0; 357*54925bf6Swillf if (profpath) 358*54925bf6Swillf while (profpath[ndx] != NULL) 359*54925bf6Swillf ndx++; 360*54925bf6Swillf 361*54925bf6Swillf path = calloc(ndx + db_dl_n_locations, sizeof (char *)); 362*54925bf6Swillf if (path == NULL) { 363*54925bf6Swillf status = errno; 364*54925bf6Swillf goto clean_n_exit; 365*54925bf6Swillf } 366*54925bf6Swillf if (ndx) 367*54925bf6Swillf memcpy(path, profpath, ndx * sizeof(profpath[0])); 368*54925bf6Swillf memcpy(path + ndx, db_dl_location, db_dl_n_locations * sizeof(char *)); 369*54925bf6Swillf status = 0; 370*54925bf6Swillf 371*54925bf6Swillf if ((status = krb5int_open_plugin_dirs ((const char **) path, 372*54925bf6Swillf filebases, 373*54925bf6Swillf &(*lib)->dl_dir_handle, &kcontext->err))) { 374*54925bf6Swillf const char *err_str = krb5_get_error_message(kcontext, status); 375*54925bf6Swillf status = KRB5_KDB_DBTYPE_NOTFOUND; 376*54925bf6Swillf krb5_set_error_message (kcontext, status, 377*54925bf6Swillf gettext("Unable to find requested database type: %s"), err_str); 378*54925bf6Swillf krb5_free_error_message (kcontext, err_str); 379*54925bf6Swillf goto clean_n_exit; 380*54925bf6Swillf } 381*54925bf6Swillf 382*54925bf6Swillf if ((status = krb5int_get_plugin_dir_data (&(*lib)->dl_dir_handle, "kdb_function_table", 383*54925bf6Swillf &vftabl_addrs, &kcontext->err))) { 384*54925bf6Swillf const char *err_str = krb5_get_error_message(kcontext, status); 385*54925bf6Swillf status = KRB5_KDB_DBTYPE_INIT; 386*54925bf6Swillf krb5_set_error_message (kcontext, status, 387*54925bf6Swillf gettext("plugin symbol 'kdb_function_table' lookup failed: %s"), err_str); 388*54925bf6Swillf krb5_free_error_message (kcontext, err_str); 389*54925bf6Swillf goto clean_n_exit; 390*54925bf6Swillf } 391*54925bf6Swillf 392*54925bf6Swillf if (vftabl_addrs[0] == NULL) { 393*54925bf6Swillf /* No plugins! */ 394*54925bf6Swillf status = KRB5_KDB_DBTYPE_NOTFOUND; 395*54925bf6Swillf krb5_set_error_message (kcontext, status, 396*54925bf6Swillf gettext("Unable to load requested database module '%s': plugin symbol 'kdb_function_table' not found"), 397*54925bf6Swillf lib_name); 398*54925bf6Swillf goto clean_n_exit; 399*54925bf6Swillf } 400*54925bf6Swillf 401*54925bf6Swillf memcpy(&(*lib)->vftabl, vftabl_addrs[0], sizeof(kdb_vftabl)); 402*54925bf6Swillf kdb_setup_opt_functions(*lib); 403*54925bf6Swillf 404*54925bf6Swillf if ((status = (*lib)->vftabl.init_library())) { 405*54925bf6Swillf /* ERROR. library not initialized cleanly */ 406*54925bf6Swillf goto clean_n_exit; 407*54925bf6Swillf } 408*54925bf6Swillf 409*54925bf6Swillf clean_n_exit: 410*54925bf6Swillf if (vftabl_addrs != NULL) { krb5int_free_plugin_dir_data (vftabl_addrs); } 411*54925bf6Swillf /* Both of these DTRT with NULL. */ 412*54925bf6Swillf profile_free_list(profpath); 413*54925bf6Swillf free(path); 414*54925bf6Swillf if (status) { 415*54925bf6Swillf if (*lib) { 416*54925bf6Swillf kdb_destroy_lib_lock(*lib); 417*54925bf6Swillf if (PLUGIN_DIR_OPEN((&(*lib)->dl_dir_handle))) { 418*54925bf6Swillf krb5int_close_plugin_dirs (&(*lib)->dl_dir_handle); 419*54925bf6Swillf } 420*54925bf6Swillf free(*lib); 421*54925bf6Swillf *lib = NULL; 422*54925bf6Swillf } 423*54925bf6Swillf } 424*54925bf6Swillf return status; 425*54925bf6Swillf } 426*54925bf6Swillf 427*54925bf6Swillf #endif /* end of _KDB5_STATIC_LINK */ 428*54925bf6Swillf 429*54925bf6Swillf static krb5_error_code 430*54925bf6Swillf kdb_find_library(krb5_context kcontext, char *lib_name, db_library * lib) 431*54925bf6Swillf { 432*54925bf6Swillf /* lock here so that no two threads try to do the same at the same time */ 433*54925bf6Swillf krb5_error_code status = 0; 434*54925bf6Swillf int locked = 0; 435*54925bf6Swillf db_library curr_elt, prev_elt = NULL; 436*54925bf6Swillf 437*54925bf6Swillf if ((status = kdb_lock_list()) != 0) { 438*54925bf6Swillf goto clean_n_exit; 439*54925bf6Swillf } 440*54925bf6Swillf locked = 1; 441*54925bf6Swillf 442*54925bf6Swillf curr_elt = lib_list; 443*54925bf6Swillf while (curr_elt != NULL) { 444*54925bf6Swillf if (strcmp(lib_name, curr_elt->name) == 0) { 445*54925bf6Swillf *lib = curr_elt; 446*54925bf6Swillf goto clean_n_exit; 447*54925bf6Swillf } 448*54925bf6Swillf prev_elt = curr_elt; 449*54925bf6Swillf curr_elt = curr_elt->next; 450*54925bf6Swillf } 451*54925bf6Swillf 452*54925bf6Swillf /* module not found. create and add to list */ 453*54925bf6Swillf status = kdb_load_library(kcontext, lib_name, lib); 454*54925bf6Swillf if (status) { 455*54925bf6Swillf goto clean_n_exit; 456*54925bf6Swillf } 457*54925bf6Swillf 458*54925bf6Swillf if (prev_elt) { 459*54925bf6Swillf /* prev_elt points to the last element in the list */ 460*54925bf6Swillf prev_elt->next = *lib; 461*54925bf6Swillf (*lib)->prev = prev_elt; 462*54925bf6Swillf } else { 463*54925bf6Swillf lib_list = *lib; 464*54925bf6Swillf } 465*54925bf6Swillf 466*54925bf6Swillf clean_n_exit: 467*54925bf6Swillf if (*lib) { 468*54925bf6Swillf (*lib)->reference_cnt++; 469*54925bf6Swillf } 470*54925bf6Swillf 471*54925bf6Swillf if (locked) { 472*54925bf6Swillf (void)kdb_unlock_list(); 473*54925bf6Swillf } 474*54925bf6Swillf 475*54925bf6Swillf return status; 476*54925bf6Swillf } 477*54925bf6Swillf 478*54925bf6Swillf static krb5_error_code 479*54925bf6Swillf kdb_free_library(db_library lib) 480*54925bf6Swillf { 481*54925bf6Swillf krb5_error_code status = 0; 482*54925bf6Swillf int locked = 0; 483*54925bf6Swillf 484*54925bf6Swillf if ((status = kdb_lock_list()) != 0) { 485*54925bf6Swillf goto clean_n_exit; 486*54925bf6Swillf } 487*54925bf6Swillf locked = 1; 488*54925bf6Swillf 489*54925bf6Swillf lib->reference_cnt--; 490*54925bf6Swillf 491*54925bf6Swillf if (lib->reference_cnt == 0) { 492*54925bf6Swillf status = lib->vftabl.fini_library(); 493*54925bf6Swillf if (status) { 494*54925bf6Swillf goto clean_n_exit; 495*54925bf6Swillf } 496*54925bf6Swillf 497*54925bf6Swillf /* close the library */ 498*54925bf6Swillf if (PLUGIN_DIR_OPEN((&lib->dl_dir_handle))) { 499*54925bf6Swillf krb5int_close_plugin_dirs (&lib->dl_dir_handle); 500*54925bf6Swillf } 501*54925bf6Swillf 502*54925bf6Swillf kdb_destroy_lib_lock(lib); 503*54925bf6Swillf 504*54925bf6Swillf if (lib->prev == NULL) { 505*54925bf6Swillf /* first element in the list */ 506*54925bf6Swillf lib_list = lib->next; 507*54925bf6Swillf } else { 508*54925bf6Swillf lib->prev->next = lib->next; 509*54925bf6Swillf } 510*54925bf6Swillf 511*54925bf6Swillf if (lib->next) { 512*54925bf6Swillf lib->next->prev = lib->prev; 513*54925bf6Swillf } 514*54925bf6Swillf free(lib); 515*54925bf6Swillf } 516*54925bf6Swillf 517*54925bf6Swillf clean_n_exit: 518*54925bf6Swillf if (locked) { 519*54925bf6Swillf (void)kdb_unlock_list(); 520*54925bf6Swillf } 521*54925bf6Swillf 522*54925bf6Swillf return status; 523*54925bf6Swillf } 524*54925bf6Swillf 525*54925bf6Swillf static krb5_error_code 526*54925bf6Swillf kdb_setup_lib_handle(krb5_context kcontext) 527*54925bf6Swillf { 528*54925bf6Swillf char *library = NULL; 529*54925bf6Swillf krb5_error_code status = 0; 530*54925bf6Swillf db_library lib = NULL; 531*54925bf6Swillf kdb5_dal_handle *dal_handle = NULL; 532*54925bf6Swillf 533*54925bf6Swillf dal_handle = calloc((size_t) 1, sizeof(kdb5_dal_handle)); 534*54925bf6Swillf if (dal_handle == NULL) { 535*54925bf6Swillf status = ENOMEM; 536*54925bf6Swillf goto clean_n_exit; 537*54925bf6Swillf } 538*54925bf6Swillf 539*54925bf6Swillf library = kdb_get_library_name(kcontext); 540*54925bf6Swillf if (library == NULL) { 541*54925bf6Swillf status = KRB5_KDB_DBTYPE_NOTFOUND; 542*54925bf6Swillf goto clean_n_exit; 543*54925bf6Swillf } 544*54925bf6Swillf 545*54925bf6Swillf status = kdb_find_library(kcontext, library, &lib); 546*54925bf6Swillf if (status) { 547*54925bf6Swillf goto clean_n_exit; 548*54925bf6Swillf } 549*54925bf6Swillf 550*54925bf6Swillf dal_handle->lib_handle = lib; 551*54925bf6Swillf kcontext->db_context = (void *) dal_handle; 552*54925bf6Swillf 553*54925bf6Swillf clean_n_exit: 554*54925bf6Swillf free(library); 555*54925bf6Swillf 556*54925bf6Swillf if (status) { 557*54925bf6Swillf free(dal_handle); 558*54925bf6Swillf if (lib) { 559*54925bf6Swillf (void)kdb_free_library(lib); 560*54925bf6Swillf } 561*54925bf6Swillf } 562*54925bf6Swillf 563*54925bf6Swillf return status; 564*54925bf6Swillf } 565*54925bf6Swillf 566*54925bf6Swillf static krb5_error_code 567*54925bf6Swillf kdb_free_lib_handle(krb5_context kcontext) 568*54925bf6Swillf { 569*54925bf6Swillf krb5_error_code status = 0; 570*54925bf6Swillf 571*54925bf6Swillf status = 572*54925bf6Swillf kdb_free_library(((kdb5_dal_handle *) kcontext->db_context)-> 573*54925bf6Swillf lib_handle); 574*54925bf6Swillf if (status) { 575*54925bf6Swillf goto clean_n_exit; 576*54925bf6Swillf } 577*54925bf6Swillf 578*54925bf6Swillf free(kcontext->db_context); 579*54925bf6Swillf kcontext->db_context = NULL; 580*54925bf6Swillf 581*54925bf6Swillf clean_n_exit: 582*54925bf6Swillf return status; 583*54925bf6Swillf } 584*54925bf6Swillf 585*54925bf6Swillf static void 586*54925bf6Swillf get_errmsg (krb5_context kcontext, krb5_error_code err_code) 587*54925bf6Swillf { 588*54925bf6Swillf kdb5_dal_handle *dal_handle; 589*54925bf6Swillf const char *e; 590*54925bf6Swillf if (err_code == 0) 591*54925bf6Swillf return; 592*54925bf6Swillf assert(kcontext != NULL); 593*54925bf6Swillf /* Must be called with dal_handle->lib_handle locked! */ 594*54925bf6Swillf assert(kcontext->db_context != NULL); 595*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 596*54925bf6Swillf if (dal_handle->lib_handle->vftabl.errcode_2_string == NULL) 597*54925bf6Swillf return; 598*54925bf6Swillf e = dal_handle->lib_handle->vftabl.errcode_2_string(kcontext, err_code); 599*54925bf6Swillf assert (e != NULL); 600*54925bf6Swillf krb5_set_error_message(kcontext, err_code, "%s", e); 601*54925bf6Swillf if (dal_handle->lib_handle->vftabl.release_errcode_string) 602*54925bf6Swillf dal_handle->lib_handle->vftabl.release_errcode_string(kcontext, e); 603*54925bf6Swillf } 604*54925bf6Swillf 605*54925bf6Swillf /* 606*54925bf6Swillf * External functions... DAL API 607*54925bf6Swillf */ 608*54925bf6Swillf krb5_error_code 609*54925bf6Swillf krb5_db_open(krb5_context kcontext, char **db_args, int mode) 610*54925bf6Swillf { 611*54925bf6Swillf krb5_error_code status = 0; 612*54925bf6Swillf char *section = NULL; 613*54925bf6Swillf kdb5_dal_handle *dal_handle; 614*54925bf6Swillf 615*54925bf6Swillf section = kdb_get_conf_section(kcontext); 616*54925bf6Swillf if (section == NULL) { 617*54925bf6Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR; 618*54925bf6Swillf krb5_set_error_message (kcontext, status, 619*54925bf6Swillf gettext("unable to determine configuration section for realm %s\n"), 620*54925bf6Swillf kcontext->default_realm ? kcontext->default_realm : "[UNSET]"); 621*54925bf6Swillf goto clean_n_exit; 622*54925bf6Swillf } 623*54925bf6Swillf 624*54925bf6Swillf if (kcontext->db_context == NULL) { 625*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 626*54925bf6Swillf if (status) { 627*54925bf6Swillf goto clean_n_exit; 628*54925bf6Swillf } 629*54925bf6Swillf } 630*54925bf6Swillf 631*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 632*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 633*54925bf6Swillf if (status) { 634*54925bf6Swillf goto clean_n_exit; 635*54925bf6Swillf } 636*54925bf6Swillf 637*54925bf6Swillf status = 638*54925bf6Swillf dal_handle->lib_handle->vftabl.init_module(kcontext, section, db_args, 639*54925bf6Swillf mode); 640*54925bf6Swillf get_errmsg(kcontext, status); 641*54925bf6Swillf 642*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 643*54925bf6Swillf 644*54925bf6Swillf clean_n_exit: 645*54925bf6Swillf if (section) 646*54925bf6Swillf free(section); 647*54925bf6Swillf return status; 648*54925bf6Swillf } 649*54925bf6Swillf 650*54925bf6Swillf krb5_error_code 651*54925bf6Swillf krb5_db_inited(krb5_context kcontext) 652*54925bf6Swillf { 653*54925bf6Swillf return !(kcontext && kcontext->db_context && 654*54925bf6Swillf ((kdb5_dal_handle *) kcontext->db_context)->db_context); 655*54925bf6Swillf } 656*54925bf6Swillf 657*54925bf6Swillf krb5_error_code 658*54925bf6Swillf krb5_db_create(krb5_context kcontext, char **db_args) 659*54925bf6Swillf { 660*54925bf6Swillf krb5_error_code status = 0; 661*54925bf6Swillf char *section = NULL; 662*54925bf6Swillf kdb5_dal_handle *dal_handle; 663*54925bf6Swillf 664*54925bf6Swillf section = kdb_get_conf_section(kcontext); 665*54925bf6Swillf if (section == NULL) { 666*54925bf6Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR; 667*54925bf6Swillf krb5_set_error_message (kcontext, status, 668*54925bf6Swillf gettext("unable to determine configuration section for realm %s\n"), 669*54925bf6Swillf kcontext->default_realm); 670*54925bf6Swillf goto clean_n_exit; 671*54925bf6Swillf } 672*54925bf6Swillf 673*54925bf6Swillf if (kcontext->db_context == NULL) { 674*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 675*54925bf6Swillf if (status) { 676*54925bf6Swillf goto clean_n_exit; 677*54925bf6Swillf } 678*54925bf6Swillf } 679*54925bf6Swillf 680*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 681*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 682*54925bf6Swillf if (status) { 683*54925bf6Swillf goto clean_n_exit; 684*54925bf6Swillf } 685*54925bf6Swillf 686*54925bf6Swillf status = 687*54925bf6Swillf dal_handle->lib_handle->vftabl.db_create(kcontext, section, db_args); 688*54925bf6Swillf get_errmsg(kcontext, status); 689*54925bf6Swillf 690*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 691*54925bf6Swillf 692*54925bf6Swillf clean_n_exit: 693*54925bf6Swillf if (section) 694*54925bf6Swillf free(section); 695*54925bf6Swillf return status; 696*54925bf6Swillf } 697*54925bf6Swillf 698*54925bf6Swillf krb5_error_code 699*54925bf6Swillf krb5_db_fini(krb5_context kcontext) 700*54925bf6Swillf { 701*54925bf6Swillf krb5_error_code status = 0; 702*54925bf6Swillf kdb5_dal_handle *dal_handle; 703*54925bf6Swillf 704*54925bf6Swillf if (kcontext->db_context == NULL) { 705*54925bf6Swillf /* module not loaded. So nothing to be done */ 706*54925bf6Swillf goto clean_n_exit; 707*54925bf6Swillf } 708*54925bf6Swillf 709*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 710*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 711*54925bf6Swillf if (status) { 712*54925bf6Swillf goto clean_n_exit; 713*54925bf6Swillf } 714*54925bf6Swillf 715*54925bf6Swillf status = dal_handle->lib_handle->vftabl.fini_module(kcontext); 716*54925bf6Swillf get_errmsg(kcontext, status); 717*54925bf6Swillf 718*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 719*54925bf6Swillf 720*54925bf6Swillf if (status) { 721*54925bf6Swillf goto clean_n_exit; 722*54925bf6Swillf } 723*54925bf6Swillf 724*54925bf6Swillf status = kdb_free_lib_handle(kcontext); 725*54925bf6Swillf 726*54925bf6Swillf clean_n_exit: 727*54925bf6Swillf return status; 728*54925bf6Swillf } 729*54925bf6Swillf 730*54925bf6Swillf krb5_error_code 731*54925bf6Swillf krb5_db_destroy(krb5_context kcontext, char **db_args) 732*54925bf6Swillf { 733*54925bf6Swillf krb5_error_code status = 0; 734*54925bf6Swillf char *section = NULL; 735*54925bf6Swillf kdb5_dal_handle *dal_handle; 736*54925bf6Swillf 737*54925bf6Swillf section = kdb_get_conf_section(kcontext); 738*54925bf6Swillf if (section == NULL) { 739*54925bf6Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR; 740*54925bf6Swillf krb5_set_error_message (kcontext, status, 741*54925bf6Swillf gettext("unable to determine configuration section for realm %s\n"), 742*54925bf6Swillf kcontext->default_realm); 743*54925bf6Swillf goto clean_n_exit; 744*54925bf6Swillf } 745*54925bf6Swillf 746*54925bf6Swillf if (kcontext->db_context == NULL) { 747*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 748*54925bf6Swillf if (status) { 749*54925bf6Swillf goto clean_n_exit; 750*54925bf6Swillf } 751*54925bf6Swillf } 752*54925bf6Swillf 753*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 754*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 755*54925bf6Swillf if (status) { 756*54925bf6Swillf goto clean_n_exit; 757*54925bf6Swillf } 758*54925bf6Swillf 759*54925bf6Swillf status = 760*54925bf6Swillf dal_handle->lib_handle->vftabl.db_destroy(kcontext, section, db_args); 761*54925bf6Swillf get_errmsg(kcontext, status); 762*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 763*54925bf6Swillf 764*54925bf6Swillf clean_n_exit: 765*54925bf6Swillf if (section) 766*54925bf6Swillf free(section); 767*54925bf6Swillf return status; 768*54925bf6Swillf } 769*54925bf6Swillf 770*54925bf6Swillf krb5_error_code 771*54925bf6Swillf krb5_db_get_age(krb5_context kcontext, char *db_name, time_t * t) 772*54925bf6Swillf { 773*54925bf6Swillf krb5_error_code status = 0; 774*54925bf6Swillf kdb5_dal_handle *dal_handle; 775*54925bf6Swillf 776*54925bf6Swillf if (kcontext->db_context == NULL) { 777*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 778*54925bf6Swillf if (status) { 779*54925bf6Swillf goto clean_n_exit; 780*54925bf6Swillf } 781*54925bf6Swillf } 782*54925bf6Swillf 783*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 784*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 785*54925bf6Swillf if (status) { 786*54925bf6Swillf goto clean_n_exit; 787*54925bf6Swillf } 788*54925bf6Swillf 789*54925bf6Swillf status = dal_handle->lib_handle->vftabl.db_get_age(kcontext, db_name, t); 790*54925bf6Swillf get_errmsg(kcontext, status); 791*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 792*54925bf6Swillf 793*54925bf6Swillf clean_n_exit: 794*54925bf6Swillf return status; 795*54925bf6Swillf } 796*54925bf6Swillf 797*54925bf6Swillf krb5_error_code 798*54925bf6Swillf krb5_db_set_option(krb5_context kcontext, int option, void *value) 799*54925bf6Swillf { 800*54925bf6Swillf krb5_error_code status = 0; 801*54925bf6Swillf kdb5_dal_handle *dal_handle; 802*54925bf6Swillf 803*54925bf6Swillf if (kcontext->db_context == NULL) { 804*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 805*54925bf6Swillf if (status) { 806*54925bf6Swillf goto clean_n_exit; 807*54925bf6Swillf } 808*54925bf6Swillf } 809*54925bf6Swillf 810*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 811*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 812*54925bf6Swillf if (status) { 813*54925bf6Swillf goto clean_n_exit; 814*54925bf6Swillf } 815*54925bf6Swillf 816*54925bf6Swillf status = 817*54925bf6Swillf dal_handle->lib_handle->vftabl.db_set_option(kcontext, option, value); 818*54925bf6Swillf get_errmsg(kcontext, status); 819*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 820*54925bf6Swillf 821*54925bf6Swillf clean_n_exit: 822*54925bf6Swillf return status; 823*54925bf6Swillf } 824*54925bf6Swillf 825*54925bf6Swillf krb5_error_code 826*54925bf6Swillf krb5_db_lock(krb5_context kcontext, int lock_mode) 827*54925bf6Swillf { 828*54925bf6Swillf krb5_error_code status = 0; 829*54925bf6Swillf kdb5_dal_handle *dal_handle; 830*54925bf6Swillf 831*54925bf6Swillf if (kcontext->db_context == NULL) { 832*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 833*54925bf6Swillf if (status) { 834*54925bf6Swillf goto clean_n_exit; 835*54925bf6Swillf } 836*54925bf6Swillf } 837*54925bf6Swillf 838*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 839*54925bf6Swillf /* acquire an exclusive lock, ensures no other thread uses this context */ 840*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, TRUE); 841*54925bf6Swillf if (status) { 842*54925bf6Swillf goto clean_n_exit; 843*54925bf6Swillf } 844*54925bf6Swillf 845*54925bf6Swillf status = dal_handle->lib_handle->vftabl.db_lock(kcontext, lock_mode); 846*54925bf6Swillf get_errmsg(kcontext, status); 847*54925bf6Swillf 848*54925bf6Swillf /* exclusive lock is still held, so no other thread could use this context */ 849*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 850*54925bf6Swillf 851*54925bf6Swillf clean_n_exit: 852*54925bf6Swillf return status; 853*54925bf6Swillf } 854*54925bf6Swillf 855*54925bf6Swillf krb5_error_code 856*54925bf6Swillf krb5_db_unlock(krb5_context kcontext) 857*54925bf6Swillf { 858*54925bf6Swillf krb5_error_code status = 0; 859*54925bf6Swillf kdb5_dal_handle *dal_handle; 860*54925bf6Swillf 861*54925bf6Swillf if (kcontext->db_context == NULL) { 862*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 863*54925bf6Swillf if (status) { 864*54925bf6Swillf goto clean_n_exit; 865*54925bf6Swillf } 866*54925bf6Swillf } 867*54925bf6Swillf 868*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 869*54925bf6Swillf /* normal lock acquired and exclusive lock released */ 870*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 871*54925bf6Swillf if (status) { 872*54925bf6Swillf goto clean_n_exit; 873*54925bf6Swillf } 874*54925bf6Swillf 875*54925bf6Swillf status = dal_handle->lib_handle->vftabl.db_unlock(kcontext); 876*54925bf6Swillf get_errmsg(kcontext, status); 877*54925bf6Swillf 878*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, TRUE); 879*54925bf6Swillf 880*54925bf6Swillf clean_n_exit: 881*54925bf6Swillf return status; 882*54925bf6Swillf } 883*54925bf6Swillf 884*54925bf6Swillf krb5_error_code 885*54925bf6Swillf krb5_db_get_principal(krb5_context kcontext, 886*54925bf6Swillf krb5_const_principal search_for, 887*54925bf6Swillf krb5_db_entry * entries, 888*54925bf6Swillf int *nentries, krb5_boolean * more) 889*54925bf6Swillf { 890*54925bf6Swillf krb5_error_code status = 0; 891*54925bf6Swillf kdb5_dal_handle *dal_handle; 892*54925bf6Swillf 893*54925bf6Swillf if (kcontext->db_context == NULL) { 894*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 895*54925bf6Swillf if (status) { 896*54925bf6Swillf goto clean_n_exit; 897*54925bf6Swillf } 898*54925bf6Swillf } 899*54925bf6Swillf 900*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 901*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 902*54925bf6Swillf if (status) { 903*54925bf6Swillf goto clean_n_exit; 904*54925bf6Swillf } 905*54925bf6Swillf 906*54925bf6Swillf status = 907*54925bf6Swillf dal_handle->lib_handle->vftabl.db_get_principal(kcontext, search_for, 908*54925bf6Swillf entries, nentries, 909*54925bf6Swillf more); 910*54925bf6Swillf get_errmsg(kcontext, status); 911*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 912*54925bf6Swillf 913*54925bf6Swillf clean_n_exit: 914*54925bf6Swillf return status; 915*54925bf6Swillf } 916*54925bf6Swillf 917*54925bf6Swillf krb5_error_code 918*54925bf6Swillf krb5_db_get_principal_nolock(krb5_context kcontext, 919*54925bf6Swillf krb5_const_principal search_for, 920*54925bf6Swillf krb5_db_entry * entries, 921*54925bf6Swillf int *nentries, krb5_boolean * more) 922*54925bf6Swillf { 923*54925bf6Swillf krb5_error_code status = 0; 924*54925bf6Swillf kdb5_dal_handle *dal_handle; 925*54925bf6Swillf 926*54925bf6Swillf if (kcontext->db_context == NULL) { 927*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 928*54925bf6Swillf if (status) { 929*54925bf6Swillf goto clean_n_exit; 930*54925bf6Swillf } 931*54925bf6Swillf } 932*54925bf6Swillf 933*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 934*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 935*54925bf6Swillf if (status) { 936*54925bf6Swillf goto clean_n_exit; 937*54925bf6Swillf } 938*54925bf6Swillf 939*54925bf6Swillf status = 940*54925bf6Swillf dal_handle->lib_handle->vftabl.db_get_principal_nolock(kcontext, 941*54925bf6Swillf search_for, 942*54925bf6Swillf entries, nentries, 943*54925bf6Swillf more); 944*54925bf6Swillf get_errmsg(kcontext, status); 945*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 946*54925bf6Swillf 947*54925bf6Swillf clean_n_exit: 948*54925bf6Swillf return status; 949*54925bf6Swillf } 950*54925bf6Swillf 951*54925bf6Swillf krb5_error_code 952*54925bf6Swillf krb5_db_free_principal(krb5_context kcontext, krb5_db_entry * entry, int count) 953*54925bf6Swillf { 954*54925bf6Swillf krb5_error_code status = 0; 955*54925bf6Swillf kdb5_dal_handle *dal_handle; 956*54925bf6Swillf 957*54925bf6Swillf if (kcontext->db_context == NULL) { 958*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 959*54925bf6Swillf if (status) { 960*54925bf6Swillf goto clean_n_exit; 961*54925bf6Swillf } 962*54925bf6Swillf } 963*54925bf6Swillf 964*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 965*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 966*54925bf6Swillf if (status) { 967*54925bf6Swillf goto clean_n_exit; 968*54925bf6Swillf } 969*54925bf6Swillf 970*54925bf6Swillf status = 971*54925bf6Swillf dal_handle->lib_handle->vftabl.db_free_principal(kcontext, entry, 972*54925bf6Swillf count); 973*54925bf6Swillf get_errmsg(kcontext, status); 974*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 975*54925bf6Swillf 976*54925bf6Swillf clean_n_exit: 977*54925bf6Swillf return status; 978*54925bf6Swillf } 979*54925bf6Swillf 980*54925bf6Swillf krb5_error_code 981*54925bf6Swillf krb5_db_put_principal(krb5_context kcontext, 982*54925bf6Swillf krb5_db_entry * entries, int *nentries) 983*54925bf6Swillf { 984*54925bf6Swillf krb5_error_code status = 0; 985*54925bf6Swillf kdb5_dal_handle *dal_handle; 986*54925bf6Swillf char **db_args = NULL; 987*54925bf6Swillf krb5_tl_data *prev, *curr, *next; 988*54925bf6Swillf int db_args_size = 0; 989*54925bf6Swillf 990*54925bf6Swillf if (kcontext->db_context == NULL) { 991*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 992*54925bf6Swillf if (status) { 993*54925bf6Swillf goto clean_n_exit; 994*54925bf6Swillf } 995*54925bf6Swillf } 996*54925bf6Swillf 997*54925bf6Swillf /* Giving db_args as part of tl data causes, db2 to store the 998*54925bf6Swillf tl_data as such. To prevent this, tl_data is collated and 999*54925bf6Swillf passed as a sepearte argument. Currently supports only one 1000*54925bf6Swillf principal. but passing it as a seperate argument makes it 1001*54925bf6Swillf difficult for kadmin remote to pass arguments to server. */ 1002*54925bf6Swillf prev = NULL, curr = entries->tl_data; 1003*54925bf6Swillf while (curr) { 1004*54925bf6Swillf if (curr->tl_data_type == KRB5_TL_DB_ARGS) { 1005*54925bf6Swillf char **t; 1006*54925bf6Swillf /* Since this is expected to be NULL terminated string and 1007*54925bf6Swillf this could come from any client, do a check before 1008*54925bf6Swillf passing it to db. */ 1009*54925bf6Swillf if (((char *) curr->tl_data_contents)[curr->tl_data_length - 1] != 1010*54925bf6Swillf '\0') { 1011*54925bf6Swillf /* not null terminated. Dangerous input */ 1012*54925bf6Swillf status = EINVAL; 1013*54925bf6Swillf goto clean_n_exit; 1014*54925bf6Swillf } 1015*54925bf6Swillf 1016*54925bf6Swillf db_args_size++; 1017*54925bf6Swillf t = realloc(db_args, sizeof(char *) * (db_args_size + 1)); /* 1 for NULL */ 1018*54925bf6Swillf if (t == NULL) { 1019*54925bf6Swillf status = ENOMEM; 1020*54925bf6Swillf goto clean_n_exit; 1021*54925bf6Swillf } 1022*54925bf6Swillf 1023*54925bf6Swillf db_args = t; 1024*54925bf6Swillf db_args[db_args_size - 1] = (char *) curr->tl_data_contents; 1025*54925bf6Swillf db_args[db_args_size] = NULL; 1026*54925bf6Swillf 1027*54925bf6Swillf next = curr->tl_data_next; 1028*54925bf6Swillf if (prev == NULL) { 1029*54925bf6Swillf /* current node is the first in the linked list. remove it */ 1030*54925bf6Swillf entries->tl_data = curr->tl_data_next; 1031*54925bf6Swillf } else { 1032*54925bf6Swillf prev->tl_data_next = curr->tl_data_next; 1033*54925bf6Swillf } 1034*54925bf6Swillf entries->n_tl_data--; 1035*54925bf6Swillf krb5_db_free(kcontext, curr); 1036*54925bf6Swillf 1037*54925bf6Swillf /* previous does not change */ 1038*54925bf6Swillf curr = next; 1039*54925bf6Swillf } else { 1040*54925bf6Swillf prev = curr; 1041*54925bf6Swillf curr = curr->tl_data_next; 1042*54925bf6Swillf } 1043*54925bf6Swillf } 1044*54925bf6Swillf 1045*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1046*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1047*54925bf6Swillf if (status) { 1048*54925bf6Swillf goto clean_n_exit; 1049*54925bf6Swillf } 1050*54925bf6Swillf 1051*54925bf6Swillf status = dal_handle->lib_handle->vftabl.db_put_principal(kcontext, entries, 1052*54925bf6Swillf nentries, 1053*54925bf6Swillf db_args); 1054*54925bf6Swillf get_errmsg(kcontext, status); 1055*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1056*54925bf6Swillf 1057*54925bf6Swillf clean_n_exit: 1058*54925bf6Swillf while (db_args_size) { 1059*54925bf6Swillf if (db_args[db_args_size - 1]) 1060*54925bf6Swillf krb5_db_free(kcontext, db_args[db_args_size - 1]); 1061*54925bf6Swillf 1062*54925bf6Swillf db_args_size--; 1063*54925bf6Swillf } 1064*54925bf6Swillf 1065*54925bf6Swillf if (db_args) 1066*54925bf6Swillf free(db_args); 1067*54925bf6Swillf 1068*54925bf6Swillf return status; 1069*54925bf6Swillf } 1070*54925bf6Swillf 1071*54925bf6Swillf krb5_error_code 1072*54925bf6Swillf krb5_db_delete_principal(krb5_context kcontext, 1073*54925bf6Swillf krb5_principal search_for, int *nentries) 1074*54925bf6Swillf { 1075*54925bf6Swillf krb5_error_code status = 0; 1076*54925bf6Swillf kdb5_dal_handle *dal_handle; 1077*54925bf6Swillf 1078*54925bf6Swillf if (kcontext->db_context == NULL) { 1079*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1080*54925bf6Swillf if (status) { 1081*54925bf6Swillf goto clean_n_exit; 1082*54925bf6Swillf } 1083*54925bf6Swillf } 1084*54925bf6Swillf 1085*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1086*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1087*54925bf6Swillf if (status) { 1088*54925bf6Swillf goto clean_n_exit; 1089*54925bf6Swillf } 1090*54925bf6Swillf 1091*54925bf6Swillf status = 1092*54925bf6Swillf dal_handle->lib_handle->vftabl.db_delete_principal(kcontext, 1093*54925bf6Swillf search_for, 1094*54925bf6Swillf nentries); 1095*54925bf6Swillf get_errmsg(kcontext, status); 1096*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1097*54925bf6Swillf 1098*54925bf6Swillf clean_n_exit: 1099*54925bf6Swillf return status; 1100*54925bf6Swillf } 1101*54925bf6Swillf 1102*54925bf6Swillf krb5_error_code 1103*54925bf6Swillf krb5_db_iterate(krb5_context kcontext, 1104*54925bf6Swillf char *match_entry, 1105*54925bf6Swillf int (*func) (krb5_pointer, krb5_db_entry *), 1106*54925bf6Swillf krb5_pointer func_arg) 1107*54925bf6Swillf { 1108*54925bf6Swillf krb5_error_code status = 0; 1109*54925bf6Swillf kdb5_dal_handle *dal_handle; 1110*54925bf6Swillf 1111*54925bf6Swillf if (kcontext->db_context == NULL) { 1112*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1113*54925bf6Swillf if (status) { 1114*54925bf6Swillf goto clean_n_exit; 1115*54925bf6Swillf } 1116*54925bf6Swillf } 1117*54925bf6Swillf 1118*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1119*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1120*54925bf6Swillf if (status) { 1121*54925bf6Swillf goto clean_n_exit; 1122*54925bf6Swillf } 1123*54925bf6Swillf 1124*54925bf6Swillf status = dal_handle->lib_handle->vftabl.db_iterate(kcontext, 1125*54925bf6Swillf match_entry, 1126*54925bf6Swillf func, func_arg); 1127*54925bf6Swillf get_errmsg(kcontext, status); 1128*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1129*54925bf6Swillf 1130*54925bf6Swillf clean_n_exit: 1131*54925bf6Swillf return status; 1132*54925bf6Swillf } 1133*54925bf6Swillf 1134*54925bf6Swillf krb5_error_code 1135*54925bf6Swillf krb5_supported_realms(krb5_context kcontext, char **realms) 1136*54925bf6Swillf { 1137*54925bf6Swillf krb5_error_code status = 0; 1138*54925bf6Swillf kdb5_dal_handle *dal_handle; 1139*54925bf6Swillf 1140*54925bf6Swillf if (kcontext->db_context == NULL) { 1141*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1142*54925bf6Swillf if (status) { 1143*54925bf6Swillf goto clean_n_exit; 1144*54925bf6Swillf } 1145*54925bf6Swillf } 1146*54925bf6Swillf 1147*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1148*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1149*54925bf6Swillf if (status) { 1150*54925bf6Swillf goto clean_n_exit; 1151*54925bf6Swillf } 1152*54925bf6Swillf 1153*54925bf6Swillf status = 1154*54925bf6Swillf dal_handle->lib_handle->vftabl.db_supported_realms(kcontext, realms); 1155*54925bf6Swillf get_errmsg(kcontext, status); 1156*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1157*54925bf6Swillf 1158*54925bf6Swillf clean_n_exit: 1159*54925bf6Swillf return status; 1160*54925bf6Swillf } 1161*54925bf6Swillf 1162*54925bf6Swillf krb5_error_code 1163*54925bf6Swillf krb5_free_supported_realms(krb5_context kcontext, char **realms) 1164*54925bf6Swillf { 1165*54925bf6Swillf krb5_error_code status = 0; 1166*54925bf6Swillf kdb5_dal_handle *dal_handle; 1167*54925bf6Swillf 1168*54925bf6Swillf if (kcontext->db_context == NULL) { 1169*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1170*54925bf6Swillf if (status) { 1171*54925bf6Swillf goto clean_n_exit; 1172*54925bf6Swillf } 1173*54925bf6Swillf } 1174*54925bf6Swillf 1175*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1176*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1177*54925bf6Swillf if (status) { 1178*54925bf6Swillf goto clean_n_exit; 1179*54925bf6Swillf } 1180*54925bf6Swillf 1181*54925bf6Swillf status = 1182*54925bf6Swillf dal_handle->lib_handle->vftabl.db_free_supported_realms(kcontext, 1183*54925bf6Swillf realms); 1184*54925bf6Swillf get_errmsg(kcontext, status); 1185*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1186*54925bf6Swillf 1187*54925bf6Swillf clean_n_exit: 1188*54925bf6Swillf return status; 1189*54925bf6Swillf } 1190*54925bf6Swillf 1191*54925bf6Swillf krb5_error_code 1192*54925bf6Swillf krb5_db_set_master_key_ext(krb5_context kcontext, 1193*54925bf6Swillf char *pwd, krb5_keyblock * key) 1194*54925bf6Swillf { 1195*54925bf6Swillf krb5_error_code status = 0; 1196*54925bf6Swillf kdb5_dal_handle *dal_handle; 1197*54925bf6Swillf 1198*54925bf6Swillf if (kcontext->db_context == NULL) { 1199*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1200*54925bf6Swillf if (status) { 1201*54925bf6Swillf goto clean_n_exit; 1202*54925bf6Swillf } 1203*54925bf6Swillf } 1204*54925bf6Swillf 1205*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1206*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1207*54925bf6Swillf if (status) { 1208*54925bf6Swillf goto clean_n_exit; 1209*54925bf6Swillf } 1210*54925bf6Swillf 1211*54925bf6Swillf status = dal_handle->lib_handle->vftabl.set_master_key(kcontext, pwd, key); 1212*54925bf6Swillf get_errmsg(kcontext, status); 1213*54925bf6Swillf 1214*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1215*54925bf6Swillf 1216*54925bf6Swillf clean_n_exit: 1217*54925bf6Swillf return status; 1218*54925bf6Swillf } 1219*54925bf6Swillf 1220*54925bf6Swillf krb5_error_code 1221*54925bf6Swillf krb5_db_set_mkey(krb5_context context, krb5_keyblock * key) 1222*54925bf6Swillf { 1223*54925bf6Swillf return krb5_db_set_master_key_ext(context, NULL, key); 1224*54925bf6Swillf } 1225*54925bf6Swillf 1226*54925bf6Swillf krb5_error_code 1227*54925bf6Swillf krb5_db_get_mkey(krb5_context kcontext, krb5_keyblock ** key) 1228*54925bf6Swillf { 1229*54925bf6Swillf krb5_error_code status = 0; 1230*54925bf6Swillf kdb5_dal_handle *dal_handle; 1231*54925bf6Swillf 1232*54925bf6Swillf if (kcontext->db_context == NULL) { 1233*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1234*54925bf6Swillf if (status) { 1235*54925bf6Swillf goto clean_n_exit; 1236*54925bf6Swillf } 1237*54925bf6Swillf } 1238*54925bf6Swillf 1239*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1240*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1241*54925bf6Swillf if (status) { 1242*54925bf6Swillf goto clean_n_exit; 1243*54925bf6Swillf } 1244*54925bf6Swillf 1245*54925bf6Swillf /* Lets use temp key and copy it later to avoid memory problems 1246*54925bf6Swillf when freed by the caller. */ 1247*54925bf6Swillf status = dal_handle->lib_handle->vftabl.get_master_key(kcontext, key); 1248*54925bf6Swillf get_errmsg(kcontext, status); 1249*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1250*54925bf6Swillf 1251*54925bf6Swillf clean_n_exit: 1252*54925bf6Swillf return status; 1253*54925bf6Swillf } 1254*54925bf6Swillf 1255*54925bf6Swillf krb5_error_code 1256*54925bf6Swillf krb5_db_store_master_key(krb5_context kcontext, 1257*54925bf6Swillf char *db_arg, 1258*54925bf6Swillf krb5_principal mname, 1259*54925bf6Swillf krb5_keyblock * key, char *master_pwd) 1260*54925bf6Swillf { 1261*54925bf6Swillf krb5_error_code status = 0; 1262*54925bf6Swillf kdb5_dal_handle *dal_handle; 1263*54925bf6Swillf 1264*54925bf6Swillf if (kcontext->db_context == NULL) { 1265*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1266*54925bf6Swillf if (status) { 1267*54925bf6Swillf goto clean_n_exit; 1268*54925bf6Swillf } 1269*54925bf6Swillf } 1270*54925bf6Swillf 1271*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1272*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1273*54925bf6Swillf if (status) { 1274*54925bf6Swillf goto clean_n_exit; 1275*54925bf6Swillf } 1276*54925bf6Swillf 1277*54925bf6Swillf status = dal_handle->lib_handle->vftabl.store_master_key(kcontext, 1278*54925bf6Swillf db_arg, 1279*54925bf6Swillf mname, 1280*54925bf6Swillf key, master_pwd); 1281*54925bf6Swillf get_errmsg(kcontext, status); 1282*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1283*54925bf6Swillf 1284*54925bf6Swillf clean_n_exit: 1285*54925bf6Swillf return status; 1286*54925bf6Swillf } 1287*54925bf6Swillf 1288*54925bf6Swillf char *krb5_mkey_pwd_prompt1 = KRB5_KDC_MKEY_1; 1289*54925bf6Swillf char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2; 1290*54925bf6Swillf 1291*54925bf6Swillf krb5_error_code 1292*54925bf6Swillf krb5_db_fetch_mkey(krb5_context context, 1293*54925bf6Swillf krb5_principal mname, 1294*54925bf6Swillf krb5_enctype etype, 1295*54925bf6Swillf krb5_boolean fromkeyboard, 1296*54925bf6Swillf krb5_boolean twice, 1297*54925bf6Swillf char *db_args, krb5_data * salt, krb5_keyblock * key) 1298*54925bf6Swillf { 1299*54925bf6Swillf krb5_error_code retval; 1300*54925bf6Swillf char password[BUFSIZ]; 1301*54925bf6Swillf krb5_data pwd; 1302*54925bf6Swillf unsigned int size = sizeof(password); 1303*54925bf6Swillf int kvno; 1304*54925bf6Swillf krb5_keyblock tmp_key; 1305*54925bf6Swillf 1306*54925bf6Swillf memset(&tmp_key, 0, sizeof(tmp_key)); 1307*54925bf6Swillf 1308*54925bf6Swillf if (fromkeyboard) { 1309*54925bf6Swillf krb5_data scratch; 1310*54925bf6Swillf 1311*54925bf6Swillf if ((retval = krb5_read_password(context, krb5_mkey_pwd_prompt1, 1312*54925bf6Swillf twice ? krb5_mkey_pwd_prompt2 : 0, 1313*54925bf6Swillf password, &size))) { 1314*54925bf6Swillf goto clean_n_exit; 1315*54925bf6Swillf } 1316*54925bf6Swillf 1317*54925bf6Swillf pwd.data = password; 1318*54925bf6Swillf pwd.length = size; 1319*54925bf6Swillf if (!salt) { 1320*54925bf6Swillf retval = krb5_principal2salt(context, mname, &scratch); 1321*54925bf6Swillf if (retval) 1322*54925bf6Swillf goto clean_n_exit; 1323*54925bf6Swillf } 1324*54925bf6Swillf retval = 1325*54925bf6Swillf krb5_c_string_to_key(context, etype, &pwd, salt ? salt : &scratch, 1326*54925bf6Swillf key); 1327*54925bf6Swillf 1328*54925bf6Swillf if (!salt) 1329*54925bf6Swillf krb5_xfree(scratch.data); 1330*54925bf6Swillf memset(password, 0, sizeof(password)); /* erase it */ 1331*54925bf6Swillf 1332*54925bf6Swillf } else { 1333*54925bf6Swillf kdb5_dal_handle *dal_handle; 1334*54925bf6Swillf 1335*54925bf6Swillf if (context->db_context == NULL) { 1336*54925bf6Swillf retval = kdb_setup_lib_handle(context); 1337*54925bf6Swillf if (retval) { 1338*54925bf6Swillf goto clean_n_exit; 1339*54925bf6Swillf } 1340*54925bf6Swillf } 1341*54925bf6Swillf 1342*54925bf6Swillf dal_handle = (kdb5_dal_handle *) context->db_context; 1343*54925bf6Swillf retval = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1344*54925bf6Swillf if (retval) { 1345*54925bf6Swillf goto clean_n_exit; 1346*54925bf6Swillf } 1347*54925bf6Swillf #if 0 /************** Begin IFDEF'ed OUT *******************************/ 1348*54925bf6Swillf /* Orig MIT */ 1349*54925bf6Swillf tmp_key.enctype = key->enctype; 1350*54925bf6Swillf #else 1351*54925bf6Swillf /* Solaris Kerberos: need to use etype */ 1352*54925bf6Swillf tmp_key.enctype = etype; 1353*54925bf6Swillf #endif /**************** END IFDEF'ed OUT *******************************/ 1354*54925bf6Swillf retval = dal_handle->lib_handle->vftabl.fetch_master_key(context, 1355*54925bf6Swillf mname, 1356*54925bf6Swillf &tmp_key, 1357*54925bf6Swillf &kvno, 1358*54925bf6Swillf db_args); 1359*54925bf6Swillf get_errmsg(context, retval); 1360*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1361*54925bf6Swillf 1362*54925bf6Swillf if (retval) { 1363*54925bf6Swillf goto clean_n_exit; 1364*54925bf6Swillf } 1365*54925bf6Swillf 1366*54925bf6Swillf key->contents = malloc(tmp_key.length); 1367*54925bf6Swillf if (key->contents == NULL) { 1368*54925bf6Swillf retval = ENOMEM; 1369*54925bf6Swillf goto clean_n_exit; 1370*54925bf6Swillf } 1371*54925bf6Swillf 1372*54925bf6Swillf key->magic = tmp_key.magic; 1373*54925bf6Swillf key->enctype = tmp_key.enctype; 1374*54925bf6Swillf key->length = tmp_key.length; 1375*54925bf6Swillf memcpy(key->contents, tmp_key.contents, tmp_key.length); 1376*54925bf6Swillf } 1377*54925bf6Swillf 1378*54925bf6Swillf clean_n_exit: 1379*54925bf6Swillf if (tmp_key.contents) { 1380*54925bf6Swillf memset(tmp_key.contents, 0, tmp_key.length); 1381*54925bf6Swillf krb5_db_free(context, tmp_key.contents); 1382*54925bf6Swillf } 1383*54925bf6Swillf return retval; 1384*54925bf6Swillf } 1385*54925bf6Swillf 1386*54925bf6Swillf krb5_error_code 1387*54925bf6Swillf krb5_db_verify_master_key(krb5_context kcontext, 1388*54925bf6Swillf krb5_principal mprinc, krb5_keyblock * mkey) 1389*54925bf6Swillf { 1390*54925bf6Swillf krb5_error_code status = 0; 1391*54925bf6Swillf kdb5_dal_handle *dal_handle; 1392*54925bf6Swillf 1393*54925bf6Swillf if (kcontext->db_context == NULL) { 1394*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1395*54925bf6Swillf if (status) { 1396*54925bf6Swillf goto clean_n_exit; 1397*54925bf6Swillf } 1398*54925bf6Swillf } 1399*54925bf6Swillf 1400*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1401*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1402*54925bf6Swillf if (status) { 1403*54925bf6Swillf goto clean_n_exit; 1404*54925bf6Swillf } 1405*54925bf6Swillf 1406*54925bf6Swillf status = dal_handle->lib_handle->vftabl.verify_master_key(kcontext, 1407*54925bf6Swillf mprinc, mkey); 1408*54925bf6Swillf get_errmsg(kcontext, status); 1409*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1410*54925bf6Swillf 1411*54925bf6Swillf clean_n_exit: 1412*54925bf6Swillf return status; 1413*54925bf6Swillf } 1414*54925bf6Swillf 1415*54925bf6Swillf void * 1416*54925bf6Swillf krb5_db_alloc(krb5_context kcontext, void *ptr, size_t size) 1417*54925bf6Swillf { 1418*54925bf6Swillf krb5_error_code status; 1419*54925bf6Swillf kdb5_dal_handle *dal_handle; 1420*54925bf6Swillf void *new_ptr = NULL; 1421*54925bf6Swillf 1422*54925bf6Swillf if (kcontext->db_context == NULL) { 1423*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1424*54925bf6Swillf if (status) { 1425*54925bf6Swillf goto clean_n_exit; 1426*54925bf6Swillf } 1427*54925bf6Swillf } 1428*54925bf6Swillf 1429*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1430*54925bf6Swillf 1431*54925bf6Swillf new_ptr = dal_handle->lib_handle->vftabl.db_alloc(kcontext, ptr, size); 1432*54925bf6Swillf 1433*54925bf6Swillf clean_n_exit: 1434*54925bf6Swillf return new_ptr; 1435*54925bf6Swillf } 1436*54925bf6Swillf 1437*54925bf6Swillf void 1438*54925bf6Swillf krb5_db_free(krb5_context kcontext, void *ptr) 1439*54925bf6Swillf { 1440*54925bf6Swillf krb5_error_code status; 1441*54925bf6Swillf kdb5_dal_handle *dal_handle; 1442*54925bf6Swillf 1443*54925bf6Swillf if (kcontext->db_context == NULL) { 1444*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1445*54925bf6Swillf if (status) { 1446*54925bf6Swillf goto clean_n_exit; 1447*54925bf6Swillf } 1448*54925bf6Swillf } 1449*54925bf6Swillf 1450*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1451*54925bf6Swillf 1452*54925bf6Swillf dal_handle->lib_handle->vftabl.db_free(kcontext, ptr); 1453*54925bf6Swillf 1454*54925bf6Swillf clean_n_exit: 1455*54925bf6Swillf return; 1456*54925bf6Swillf } 1457*54925bf6Swillf 1458*54925bf6Swillf /* has to be modified */ 1459*54925bf6Swillf 1460*54925bf6Swillf krb5_error_code 1461*54925bf6Swillf krb5_dbe_find_enctype(krb5_context kcontext, 1462*54925bf6Swillf krb5_db_entry * dbentp, 1463*54925bf6Swillf krb5_int32 ktype, 1464*54925bf6Swillf krb5_int32 stype, 1465*54925bf6Swillf krb5_int32 kvno, krb5_key_data ** kdatap) 1466*54925bf6Swillf { 1467*54925bf6Swillf krb5_int32 start = 0; 1468*54925bf6Swillf return krb5_dbe_search_enctype(kcontext, dbentp, &start, ktype, stype, 1469*54925bf6Swillf kvno, kdatap); 1470*54925bf6Swillf } 1471*54925bf6Swillf 1472*54925bf6Swillf krb5_error_code 1473*54925bf6Swillf krb5_dbe_search_enctype(krb5_context kcontext, 1474*54925bf6Swillf krb5_db_entry * dbentp, 1475*54925bf6Swillf krb5_int32 * start, 1476*54925bf6Swillf krb5_int32 ktype, 1477*54925bf6Swillf krb5_int32 stype, 1478*54925bf6Swillf krb5_int32 kvno, krb5_key_data ** kdatap) 1479*54925bf6Swillf { 1480*54925bf6Swillf krb5_error_code status = 0; 1481*54925bf6Swillf kdb5_dal_handle *dal_handle; 1482*54925bf6Swillf 1483*54925bf6Swillf if (kcontext->db_context == NULL) { 1484*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1485*54925bf6Swillf if (status) { 1486*54925bf6Swillf goto clean_n_exit; 1487*54925bf6Swillf } 1488*54925bf6Swillf } 1489*54925bf6Swillf 1490*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1491*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1492*54925bf6Swillf if (status) { 1493*54925bf6Swillf goto clean_n_exit; 1494*54925bf6Swillf } 1495*54925bf6Swillf 1496*54925bf6Swillf status = dal_handle->lib_handle->vftabl.dbe_search_enctype(kcontext, 1497*54925bf6Swillf dbentp, 1498*54925bf6Swillf start, 1499*54925bf6Swillf ktype, 1500*54925bf6Swillf stype, 1501*54925bf6Swillf kvno, kdatap); 1502*54925bf6Swillf get_errmsg(kcontext, status); 1503*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1504*54925bf6Swillf 1505*54925bf6Swillf clean_n_exit: 1506*54925bf6Swillf return status; 1507*54925bf6Swillf } 1508*54925bf6Swillf 1509*54925bf6Swillf #define REALM_SEP_STRING "@" 1510*54925bf6Swillf 1511*54925bf6Swillf krb5_error_code 1512*54925bf6Swillf krb5_db_setup_mkey_name(krb5_context context, 1513*54925bf6Swillf const char *keyname, 1514*54925bf6Swillf const char *realm, 1515*54925bf6Swillf char **fullname, krb5_principal * principal) 1516*54925bf6Swillf { 1517*54925bf6Swillf krb5_error_code retval; 1518*54925bf6Swillf size_t keylen; 1519*54925bf6Swillf size_t rlen = strlen(realm); 1520*54925bf6Swillf char *fname; 1521*54925bf6Swillf 1522*54925bf6Swillf if (!keyname) 1523*54925bf6Swillf keyname = KRB5_KDB_M_NAME; /* XXX external? */ 1524*54925bf6Swillf 1525*54925bf6Swillf keylen = strlen(keyname); 1526*54925bf6Swillf 1527*54925bf6Swillf fname = malloc(keylen + rlen + strlen(REALM_SEP_STRING) + 1); 1528*54925bf6Swillf if (!fname) 1529*54925bf6Swillf return ENOMEM; 1530*54925bf6Swillf 1531*54925bf6Swillf strcpy(fname, keyname); 1532*54925bf6Swillf (void)strcat(fname, REALM_SEP_STRING); 1533*54925bf6Swillf (void)strcat(fname, realm); 1534*54925bf6Swillf 1535*54925bf6Swillf if ((retval = krb5_parse_name(context, fname, principal))) 1536*54925bf6Swillf return retval; 1537*54925bf6Swillf if (fullname) 1538*54925bf6Swillf *fullname = fname; 1539*54925bf6Swillf else 1540*54925bf6Swillf free(fname); 1541*54925bf6Swillf return 0; 1542*54925bf6Swillf } 1543*54925bf6Swillf 1544*54925bf6Swillf krb5_error_code 1545*54925bf6Swillf krb5_dbe_lookup_last_pwd_change(context, entry, stamp) 1546*54925bf6Swillf krb5_context context; 1547*54925bf6Swillf krb5_db_entry *entry; 1548*54925bf6Swillf krb5_timestamp *stamp; 1549*54925bf6Swillf { 1550*54925bf6Swillf krb5_tl_data tl_data; 1551*54925bf6Swillf krb5_error_code code; 1552*54925bf6Swillf krb5_int32 tmp; 1553*54925bf6Swillf 1554*54925bf6Swillf tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; 1555*54925bf6Swillf 1556*54925bf6Swillf if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) 1557*54925bf6Swillf return (code); 1558*54925bf6Swillf 1559*54925bf6Swillf if (tl_data.tl_data_length != 4) { 1560*54925bf6Swillf *stamp = 0; 1561*54925bf6Swillf return (0); 1562*54925bf6Swillf } 1563*54925bf6Swillf 1564*54925bf6Swillf krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp); 1565*54925bf6Swillf 1566*54925bf6Swillf *stamp = (krb5_timestamp) tmp; 1567*54925bf6Swillf 1568*54925bf6Swillf return (0); 1569*54925bf6Swillf } 1570*54925bf6Swillf 1571*54925bf6Swillf /*ARGSUSED*/ 1572*54925bf6Swillf krb5_error_code 1573*54925bf6Swillf krb5_dbe_lookup_tl_data(context, entry, ret_tl_data) 1574*54925bf6Swillf krb5_context context; 1575*54925bf6Swillf krb5_db_entry *entry; 1576*54925bf6Swillf krb5_tl_data *ret_tl_data; 1577*54925bf6Swillf { 1578*54925bf6Swillf krb5_tl_data *tl_data; 1579*54925bf6Swillf 1580*54925bf6Swillf for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { 1581*54925bf6Swillf if (tl_data->tl_data_type == ret_tl_data->tl_data_type) { 1582*54925bf6Swillf *ret_tl_data = *tl_data; 1583*54925bf6Swillf return (0); 1584*54925bf6Swillf } 1585*54925bf6Swillf } 1586*54925bf6Swillf 1587*54925bf6Swillf /* if the requested record isn't found, return zero bytes. 1588*54925bf6Swillf * if it ever means something to have a zero-length tl_data, 1589*54925bf6Swillf * this code and its callers will have to be changed */ 1590*54925bf6Swillf 1591*54925bf6Swillf ret_tl_data->tl_data_length = 0; 1592*54925bf6Swillf ret_tl_data->tl_data_contents = NULL; 1593*54925bf6Swillf return (0); 1594*54925bf6Swillf } 1595*54925bf6Swillf 1596*54925bf6Swillf krb5_error_code 1597*54925bf6Swillf krb5_dbe_create_key_data(context, entry) 1598*54925bf6Swillf krb5_context context; 1599*54925bf6Swillf krb5_db_entry *entry; 1600*54925bf6Swillf { 1601*54925bf6Swillf if ((entry->key_data = 1602*54925bf6Swillf (krb5_key_data *) krb5_db_alloc(context, entry->key_data, 1603*54925bf6Swillf (sizeof(krb5_key_data) * 1604*54925bf6Swillf (entry->n_key_data + 1)))) == NULL) 1605*54925bf6Swillf return (ENOMEM); 1606*54925bf6Swillf 1607*54925bf6Swillf memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data)); 1608*54925bf6Swillf entry->n_key_data++; 1609*54925bf6Swillf 1610*54925bf6Swillf return 0; 1611*54925bf6Swillf } 1612*54925bf6Swillf 1613*54925bf6Swillf krb5_error_code 1614*54925bf6Swillf krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ) 1615*54925bf6Swillf krb5_context context; 1616*54925bf6Swillf krb5_db_entry *entry; 1617*54925bf6Swillf krb5_timestamp mod_date; 1618*54925bf6Swillf krb5_const_principal mod_princ; 1619*54925bf6Swillf { 1620*54925bf6Swillf krb5_tl_data tl_data; 1621*54925bf6Swillf 1622*54925bf6Swillf krb5_error_code retval = 0; 1623*54925bf6Swillf krb5_octet *nextloc = 0; 1624*54925bf6Swillf char *unparse_mod_princ = 0; 1625*54925bf6Swillf unsigned int unparse_mod_princ_size; 1626*54925bf6Swillf 1627*54925bf6Swillf if ((retval = krb5_unparse_name(context, mod_princ, &unparse_mod_princ))) 1628*54925bf6Swillf return (retval); 1629*54925bf6Swillf 1630*54925bf6Swillf unparse_mod_princ_size = strlen(unparse_mod_princ) + 1; 1631*54925bf6Swillf 1632*54925bf6Swillf if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4)) 1633*54925bf6Swillf == NULL) { 1634*54925bf6Swillf free(unparse_mod_princ); 1635*54925bf6Swillf return (ENOMEM); 1636*54925bf6Swillf } 1637*54925bf6Swillf 1638*54925bf6Swillf tl_data.tl_data_type = KRB5_TL_MOD_PRINC; 1639*54925bf6Swillf tl_data.tl_data_length = unparse_mod_princ_size + 4; 1640*54925bf6Swillf tl_data.tl_data_contents = nextloc; 1641*54925bf6Swillf 1642*54925bf6Swillf /* Mod Date */ 1643*54925bf6Swillf krb5_kdb_encode_int32(mod_date, nextloc); 1644*54925bf6Swillf 1645*54925bf6Swillf /* Mod Princ */ 1646*54925bf6Swillf memcpy(nextloc + 4, unparse_mod_princ, unparse_mod_princ_size); 1647*54925bf6Swillf 1648*54925bf6Swillf retval = krb5_dbe_update_tl_data(context, entry, &tl_data); 1649*54925bf6Swillf 1650*54925bf6Swillf free(unparse_mod_princ); 1651*54925bf6Swillf free(nextloc); 1652*54925bf6Swillf 1653*54925bf6Swillf return (retval); 1654*54925bf6Swillf } 1655*54925bf6Swillf 1656*54925bf6Swillf krb5_error_code 1657*54925bf6Swillf krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ) 1658*54925bf6Swillf krb5_context context; 1659*54925bf6Swillf krb5_db_entry *entry; 1660*54925bf6Swillf krb5_timestamp *mod_time; 1661*54925bf6Swillf krb5_principal *mod_princ; 1662*54925bf6Swillf { 1663*54925bf6Swillf krb5_tl_data tl_data; 1664*54925bf6Swillf krb5_error_code code; 1665*54925bf6Swillf 1666*54925bf6Swillf tl_data.tl_data_type = KRB5_TL_MOD_PRINC; 1667*54925bf6Swillf 1668*54925bf6Swillf if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) 1669*54925bf6Swillf return (code); 1670*54925bf6Swillf 1671*54925bf6Swillf if ((tl_data.tl_data_length < 5) || 1672*54925bf6Swillf (tl_data.tl_data_contents[tl_data.tl_data_length - 1] != '\0')) 1673*54925bf6Swillf return (KRB5_KDB_TRUNCATED_RECORD); 1674*54925bf6Swillf 1675*54925bf6Swillf /* Mod Date */ 1676*54925bf6Swillf krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time); 1677*54925bf6Swillf 1678*54925bf6Swillf /* Mod Princ */ 1679*54925bf6Swillf if ((code = krb5_parse_name(context, 1680*54925bf6Swillf (const char *) (tl_data.tl_data_contents + 4), 1681*54925bf6Swillf mod_princ))) 1682*54925bf6Swillf return (code); 1683*54925bf6Swillf 1684*54925bf6Swillf return (0); 1685*54925bf6Swillf } 1686*54925bf6Swillf 1687*54925bf6Swillf krb5_error_code 1688*54925bf6Swillf krb5_dbe_update_last_pwd_change(context, entry, stamp) 1689*54925bf6Swillf krb5_context context; 1690*54925bf6Swillf krb5_db_entry *entry; 1691*54925bf6Swillf krb5_timestamp stamp; 1692*54925bf6Swillf { 1693*54925bf6Swillf krb5_tl_data tl_data; 1694*54925bf6Swillf krb5_octet buf[4]; /* this is the encoded size of an int32 */ 1695*54925bf6Swillf 1696*54925bf6Swillf tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; 1697*54925bf6Swillf tl_data.tl_data_length = sizeof(buf); 1698*54925bf6Swillf krb5_kdb_encode_int32((krb5_int32) stamp, buf); 1699*54925bf6Swillf tl_data.tl_data_contents = buf; 1700*54925bf6Swillf 1701*54925bf6Swillf return (krb5_dbe_update_tl_data(context, entry, &tl_data)); 1702*54925bf6Swillf } 1703*54925bf6Swillf 1704*54925bf6Swillf krb5_error_code 1705*54925bf6Swillf krb5_dbe_update_tl_data(context, entry, new_tl_data) 1706*54925bf6Swillf krb5_context context; 1707*54925bf6Swillf krb5_db_entry *entry; 1708*54925bf6Swillf krb5_tl_data *new_tl_data; 1709*54925bf6Swillf { 1710*54925bf6Swillf krb5_tl_data *tl_data = NULL; 1711*54925bf6Swillf krb5_octet *tmp; 1712*54925bf6Swillf 1713*54925bf6Swillf /* copy the new data first, so we can fail cleanly if malloc() 1714*54925bf6Swillf * fails */ 1715*54925bf6Swillf if ((tmp = 1716*54925bf6Swillf (krb5_octet *) krb5_db_alloc(context, NULL, 1717*54925bf6Swillf new_tl_data->tl_data_length)) == NULL) 1718*54925bf6Swillf return (ENOMEM); 1719*54925bf6Swillf 1720*54925bf6Swillf /* Find an existing entry of the specified type and point at 1721*54925bf6Swillf * it, or NULL if not found */ 1722*54925bf6Swillf 1723*54925bf6Swillf if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) { /* db_args can be multiple */ 1724*54925bf6Swillf for (tl_data = entry->tl_data; tl_data; 1725*54925bf6Swillf tl_data = tl_data->tl_data_next) 1726*54925bf6Swillf if (tl_data->tl_data_type == new_tl_data->tl_data_type) 1727*54925bf6Swillf break; 1728*54925bf6Swillf } 1729*54925bf6Swillf 1730*54925bf6Swillf /* if necessary, chain a new record in the beginning and point at it */ 1731*54925bf6Swillf 1732*54925bf6Swillf if (!tl_data) { 1733*54925bf6Swillf if ((tl_data = 1734*54925bf6Swillf (krb5_tl_data *) krb5_db_alloc(context, NULL, 1735*54925bf6Swillf sizeof(krb5_tl_data))) 1736*54925bf6Swillf == NULL) { 1737*54925bf6Swillf free(tmp); 1738*54925bf6Swillf return (ENOMEM); 1739*54925bf6Swillf } 1740*54925bf6Swillf memset(tl_data, 0, sizeof(krb5_tl_data)); 1741*54925bf6Swillf tl_data->tl_data_next = entry->tl_data; 1742*54925bf6Swillf entry->tl_data = tl_data; 1743*54925bf6Swillf entry->n_tl_data++; 1744*54925bf6Swillf } 1745*54925bf6Swillf 1746*54925bf6Swillf /* fill in the record */ 1747*54925bf6Swillf 1748*54925bf6Swillf if (tl_data->tl_data_contents) 1749*54925bf6Swillf krb5_db_free(context, tl_data->tl_data_contents); 1750*54925bf6Swillf 1751*54925bf6Swillf tl_data->tl_data_type = new_tl_data->tl_data_type; 1752*54925bf6Swillf tl_data->tl_data_length = new_tl_data->tl_data_length; 1753*54925bf6Swillf tl_data->tl_data_contents = tmp; 1754*54925bf6Swillf memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length); 1755*54925bf6Swillf 1756*54925bf6Swillf return (0); 1757*54925bf6Swillf } 1758*54925bf6Swillf 1759*54925bf6Swillf /* change password functions */ 1760*54925bf6Swillf krb5_error_code 1761*54925bf6Swillf krb5_dbe_cpw(krb5_context kcontext, 1762*54925bf6Swillf krb5_keyblock * master_key, 1763*54925bf6Swillf krb5_key_salt_tuple * ks_tuple, 1764*54925bf6Swillf int ks_tuple_count, 1765*54925bf6Swillf char *passwd, 1766*54925bf6Swillf int new_kvno, krb5_boolean keepold, krb5_db_entry * db_entry) 1767*54925bf6Swillf { 1768*54925bf6Swillf krb5_error_code status = 0; 1769*54925bf6Swillf kdb5_dal_handle *dal_handle; 1770*54925bf6Swillf 1771*54925bf6Swillf if (kcontext->db_context == NULL) { 1772*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1773*54925bf6Swillf if (status) { 1774*54925bf6Swillf goto clean_n_exit; 1775*54925bf6Swillf } 1776*54925bf6Swillf } 1777*54925bf6Swillf 1778*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1779*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1780*54925bf6Swillf if (status) { 1781*54925bf6Swillf goto clean_n_exit; 1782*54925bf6Swillf } 1783*54925bf6Swillf 1784*54925bf6Swillf status = dal_handle->lib_handle->vftabl.db_change_pwd(kcontext, 1785*54925bf6Swillf master_key, 1786*54925bf6Swillf ks_tuple, 1787*54925bf6Swillf ks_tuple_count, 1788*54925bf6Swillf passwd, 1789*54925bf6Swillf new_kvno, 1790*54925bf6Swillf keepold, db_entry); 1791*54925bf6Swillf get_errmsg(kcontext, status); 1792*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1793*54925bf6Swillf 1794*54925bf6Swillf clean_n_exit: 1795*54925bf6Swillf return status; 1796*54925bf6Swillf } 1797*54925bf6Swillf 1798*54925bf6Swillf /* policy management functions */ 1799*54925bf6Swillf krb5_error_code 1800*54925bf6Swillf krb5_db_create_policy(krb5_context kcontext, osa_policy_ent_t policy) 1801*54925bf6Swillf { 1802*54925bf6Swillf krb5_error_code status = 0; 1803*54925bf6Swillf kdb5_dal_handle *dal_handle; 1804*54925bf6Swillf 1805*54925bf6Swillf if (kcontext->db_context == NULL) { 1806*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1807*54925bf6Swillf if (status) { 1808*54925bf6Swillf goto clean_n_exit; 1809*54925bf6Swillf } 1810*54925bf6Swillf } 1811*54925bf6Swillf 1812*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1813*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1814*54925bf6Swillf if (status) { 1815*54925bf6Swillf goto clean_n_exit; 1816*54925bf6Swillf } 1817*54925bf6Swillf 1818*54925bf6Swillf status = dal_handle->lib_handle->vftabl.db_create_policy(kcontext, policy); 1819*54925bf6Swillf get_errmsg(kcontext, status); 1820*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1821*54925bf6Swillf 1822*54925bf6Swillf clean_n_exit: 1823*54925bf6Swillf return status; 1824*54925bf6Swillf } 1825*54925bf6Swillf 1826*54925bf6Swillf krb5_error_code 1827*54925bf6Swillf krb5_db_get_policy(krb5_context kcontext, char *name, 1828*54925bf6Swillf osa_policy_ent_t * policy, int *cnt) 1829*54925bf6Swillf { 1830*54925bf6Swillf krb5_error_code status = 0; 1831*54925bf6Swillf kdb5_dal_handle *dal_handle; 1832*54925bf6Swillf 1833*54925bf6Swillf if (kcontext->db_context == NULL) { 1834*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1835*54925bf6Swillf if (status) { 1836*54925bf6Swillf goto clean_n_exit; 1837*54925bf6Swillf } 1838*54925bf6Swillf } 1839*54925bf6Swillf 1840*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1841*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1842*54925bf6Swillf if (status) { 1843*54925bf6Swillf goto clean_n_exit; 1844*54925bf6Swillf } 1845*54925bf6Swillf 1846*54925bf6Swillf status = 1847*54925bf6Swillf dal_handle->lib_handle->vftabl.db_get_policy(kcontext, name, policy, 1848*54925bf6Swillf cnt); 1849*54925bf6Swillf get_errmsg(kcontext, status); 1850*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1851*54925bf6Swillf 1852*54925bf6Swillf clean_n_exit: 1853*54925bf6Swillf return status; 1854*54925bf6Swillf } 1855*54925bf6Swillf 1856*54925bf6Swillf krb5_error_code 1857*54925bf6Swillf krb5_db_put_policy(krb5_context kcontext, osa_policy_ent_t policy) 1858*54925bf6Swillf { 1859*54925bf6Swillf krb5_error_code status = 0; 1860*54925bf6Swillf kdb5_dal_handle *dal_handle; 1861*54925bf6Swillf 1862*54925bf6Swillf if (kcontext->db_context == NULL) { 1863*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1864*54925bf6Swillf if (status) { 1865*54925bf6Swillf goto clean_n_exit; 1866*54925bf6Swillf } 1867*54925bf6Swillf } 1868*54925bf6Swillf 1869*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1870*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1871*54925bf6Swillf if (status) { 1872*54925bf6Swillf goto clean_n_exit; 1873*54925bf6Swillf } 1874*54925bf6Swillf 1875*54925bf6Swillf status = dal_handle->lib_handle->vftabl.db_put_policy(kcontext, policy); 1876*54925bf6Swillf get_errmsg(kcontext, status); 1877*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1878*54925bf6Swillf 1879*54925bf6Swillf clean_n_exit: 1880*54925bf6Swillf return status; 1881*54925bf6Swillf } 1882*54925bf6Swillf 1883*54925bf6Swillf krb5_error_code 1884*54925bf6Swillf krb5_db_iter_policy(krb5_context kcontext, char *match_entry, 1885*54925bf6Swillf osa_adb_iter_policy_func func, void *data) 1886*54925bf6Swillf { 1887*54925bf6Swillf krb5_error_code status = 0; 1888*54925bf6Swillf kdb5_dal_handle *dal_handle; 1889*54925bf6Swillf 1890*54925bf6Swillf if (kcontext->db_context == NULL) { 1891*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1892*54925bf6Swillf if (status) { 1893*54925bf6Swillf goto clean_n_exit; 1894*54925bf6Swillf } 1895*54925bf6Swillf } 1896*54925bf6Swillf 1897*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1898*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1899*54925bf6Swillf if (status) { 1900*54925bf6Swillf goto clean_n_exit; 1901*54925bf6Swillf } 1902*54925bf6Swillf 1903*54925bf6Swillf status = 1904*54925bf6Swillf dal_handle->lib_handle->vftabl.db_iter_policy(kcontext, match_entry, 1905*54925bf6Swillf func, data); 1906*54925bf6Swillf get_errmsg(kcontext, status); 1907*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1908*54925bf6Swillf 1909*54925bf6Swillf clean_n_exit: 1910*54925bf6Swillf return status; 1911*54925bf6Swillf } 1912*54925bf6Swillf 1913*54925bf6Swillf krb5_error_code 1914*54925bf6Swillf krb5_db_delete_policy(krb5_context kcontext, char *policy) 1915*54925bf6Swillf { 1916*54925bf6Swillf krb5_error_code status = 0; 1917*54925bf6Swillf kdb5_dal_handle *dal_handle; 1918*54925bf6Swillf 1919*54925bf6Swillf if (kcontext->db_context == NULL) { 1920*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1921*54925bf6Swillf if (status) { 1922*54925bf6Swillf goto clean_n_exit; 1923*54925bf6Swillf } 1924*54925bf6Swillf } 1925*54925bf6Swillf 1926*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1927*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1928*54925bf6Swillf if (status) { 1929*54925bf6Swillf goto clean_n_exit; 1930*54925bf6Swillf } 1931*54925bf6Swillf 1932*54925bf6Swillf status = dal_handle->lib_handle->vftabl.db_delete_policy(kcontext, policy); 1933*54925bf6Swillf get_errmsg(kcontext, status); 1934*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1935*54925bf6Swillf 1936*54925bf6Swillf clean_n_exit: 1937*54925bf6Swillf return status; 1938*54925bf6Swillf } 1939*54925bf6Swillf 1940*54925bf6Swillf void 1941*54925bf6Swillf krb5_db_free_policy(krb5_context kcontext, osa_policy_ent_t policy) 1942*54925bf6Swillf { 1943*54925bf6Swillf krb5_error_code status = 0; 1944*54925bf6Swillf kdb5_dal_handle *dal_handle; 1945*54925bf6Swillf 1946*54925bf6Swillf if (kcontext->db_context == NULL) { 1947*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1948*54925bf6Swillf if (status) { 1949*54925bf6Swillf goto clean_n_exit; 1950*54925bf6Swillf } 1951*54925bf6Swillf } 1952*54925bf6Swillf 1953*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1954*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1955*54925bf6Swillf if (status) { 1956*54925bf6Swillf goto clean_n_exit; 1957*54925bf6Swillf } 1958*54925bf6Swillf 1959*54925bf6Swillf dal_handle->lib_handle->vftabl.db_free_policy(kcontext, policy); 1960*54925bf6Swillf get_errmsg(kcontext, status); 1961*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 1962*54925bf6Swillf 1963*54925bf6Swillf clean_n_exit: 1964*54925bf6Swillf return; 1965*54925bf6Swillf } 1966*54925bf6Swillf 1967*54925bf6Swillf krb5_error_code 1968*54925bf6Swillf krb5_db_promote(krb5_context kcontext, char **db_args) 1969*54925bf6Swillf { 1970*54925bf6Swillf krb5_error_code status = 0; 1971*54925bf6Swillf char *section = NULL; 1972*54925bf6Swillf kdb5_dal_handle *dal_handle; 1973*54925bf6Swillf 1974*54925bf6Swillf section = kdb_get_conf_section(kcontext); 1975*54925bf6Swillf if (section == NULL) { 1976*54925bf6Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR; 1977*54925bf6Swillf krb5_set_error_message (kcontext, status, 1978*54925bf6Swillf gettext("unable to determine configuration section for realm %s\n"), 1979*54925bf6Swillf kcontext->default_realm); 1980*54925bf6Swillf goto clean_n_exit; 1981*54925bf6Swillf } 1982*54925bf6Swillf 1983*54925bf6Swillf if (kcontext->db_context == NULL) { 1984*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 1985*54925bf6Swillf if (status) { 1986*54925bf6Swillf goto clean_n_exit; 1987*54925bf6Swillf } 1988*54925bf6Swillf } 1989*54925bf6Swillf 1990*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 1991*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 1992*54925bf6Swillf if (status) { 1993*54925bf6Swillf goto clean_n_exit; 1994*54925bf6Swillf } 1995*54925bf6Swillf 1996*54925bf6Swillf status = 1997*54925bf6Swillf dal_handle->lib_handle->vftabl.promote_db(kcontext, section, db_args); 1998*54925bf6Swillf get_errmsg(kcontext, status); 1999*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 2000*54925bf6Swillf 2001*54925bf6Swillf clean_n_exit: 2002*54925bf6Swillf if (section) 2003*54925bf6Swillf free(section); 2004*54925bf6Swillf return status; 2005*54925bf6Swillf } 2006*54925bf6Swillf 2007*54925bf6Swillf /* 2008*54925bf6Swillf * Solaris Kerberos: support for iprop 2009*54925bf6Swillf * 2010*54925bf6Swillf * Not all KDB plugins support iprop. 2011*54925bf6Swillf * 2012*54925bf6Swillf * sets iprop_supported to 1 if iprop supportd, 0 otherwise. 2013*54925bf6Swillf */ 2014*54925bf6Swillf krb5_error_code 2015*54925bf6Swillf krb5_db_supports_iprop(krb5_context kcontext, int *iprop_supported) 2016*54925bf6Swillf { 2017*54925bf6Swillf krb5_error_code status = 0; 2018*54925bf6Swillf kdb5_dal_handle *dal_handle; 2019*54925bf6Swillf 2020*54925bf6Swillf if (kcontext->db_context == NULL) { 2021*54925bf6Swillf status = kdb_setup_lib_handle(kcontext); 2022*54925bf6Swillf if (status) { 2023*54925bf6Swillf goto clean_n_exit; 2024*54925bf6Swillf } 2025*54925bf6Swillf } 2026*54925bf6Swillf 2027*54925bf6Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context; 2028*54925bf6Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE); 2029*54925bf6Swillf if (status) { 2030*54925bf6Swillf goto clean_n_exit; 2031*54925bf6Swillf } 2032*54925bf6Swillf 2033*54925bf6Swillf *iprop_supported = dal_handle->lib_handle->vftabl.iprop_supported; 2034*54925bf6Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE); 2035*54925bf6Swillf 2036*54925bf6Swillf clean_n_exit: 2037*54925bf6Swillf return status; 2038*54925bf6Swillf } 2039