14960Swillf /*
25916Swillf * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
34960Swillf * Use is subject to license terms.
44960Swillf */
54960Swillf
64960Swillf #pragma ident "%Z%%M% %I% %E% SMI"
74960Swillf /*
84960Swillf * Copyright 2006 by the Massachusetts Institute of Technology.
94960Swillf * All Rights Reserved.
104960Swillf *
114960Swillf * Export of this software from the United States of America may
124960Swillf * require a specific license from the United States Government.
134960Swillf * It is the responsibility of any person or organization contemplating
144960Swillf * export to obtain such a license before exporting.
154960Swillf *
164960Swillf * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
174960Swillf * distribute this software and its documentation for any purpose and
184960Swillf * without fee is hereby granted, provided that the above copyright
194960Swillf * notice appear in all copies and that both that copyright notice and
204960Swillf * this permission notice appear in supporting documentation, and that
214960Swillf * the name of M.I.T. not be used in advertising or publicity pertaining
224960Swillf * to distribution of the software without specific, written prior
234960Swillf * permission. Furthermore if you modify this software you must label
244960Swillf * your software as modified software and not distribute it in such a
254960Swillf * fashion that it might be confused with the original M.I.T. software.
264960Swillf * M.I.T. makes no representations about the suitability of
274960Swillf * this software for any purpose. It is provided "as is" without express
284960Swillf * or implied warranty.
294960Swillf */
304960Swillf
314960Swillf /*
324960Swillf * This code was based on code donated to MIT by Novell for
334960Swillf * distribution under the MIT license.
344960Swillf */
354960Swillf
364960Swillf /*
374960Swillf * Include files
384960Swillf */
394960Swillf
404960Swillf #include <stdio.h>
414960Swillf #include <string.h>
424960Swillf #include <k5-int.h>
434960Swillf #include <osconf.h>
444960Swillf #include "kdb5.h"
454960Swillf #include <assert.h>
464960Swillf #include "k5-platform.h"
474960Swillf #include <libintl.h>
484960Swillf
494960Swillf /* Currently DB2 policy related errors are exported from DAL. But
504960Swillf other databases should set_err function to return string. */
514960Swillf #include "adb_err.h"
524960Swillf
534960Swillf /*
544960Swillf * Type definitions
554960Swillf */
564960Swillf #define KRB5_TL_DB_ARGS 0x7fff
574960Swillf
584960Swillf /*
594960Swillf * internal static variable
604960Swillf */
614960Swillf
624960Swillf static k5_mutex_t db_lock = K5_MUTEX_PARTIAL_INITIALIZER;
634960Swillf
644960Swillf #ifdef _KDB5_STATIC_LINK
654960Swillf #undef _KDB5_DYNAMIC_LINK
664960Swillf #else
674960Swillf #undef _KDB5_DYNAMIC_LINK
684960Swillf /* to avoid redefinition problem */
694960Swillf #define _KDB5_DYNAMIC_LINK
704960Swillf #endif
714960Swillf
724960Swillf static db_library lib_list;
734960Swillf
744960Swillf /*
754960Swillf * Helper Functions
764960Swillf */
774960Swillf
784960Swillf MAKE_INIT_FUNCTION(kdb_init_lock_list);
794960Swillf MAKE_FINI_FUNCTION(kdb_fini_lock_list);
804960Swillf
814960Swillf int
kdb_init_lock_list(void)824960Swillf kdb_init_lock_list(void)
834960Swillf {
844960Swillf return k5_mutex_finish_init(&db_lock);
854960Swillf }
864960Swillf
874960Swillf static int
kdb_lock_list()884960Swillf kdb_lock_list()
894960Swillf {
904960Swillf int err;
914960Swillf err = CALL_INIT_FUNCTION (kdb_init_lock_list);
924960Swillf if (err)
934960Swillf return err;
944960Swillf return k5_mutex_lock(&db_lock);
954960Swillf }
964960Swillf
974960Swillf void
kdb_fini_lock_list(void)984960Swillf kdb_fini_lock_list(void)
994960Swillf {
1004960Swillf if (INITIALIZER_RAN(kdb_init_lock_list))
1014960Swillf k5_mutex_destroy(&db_lock);
1024960Swillf }
1034960Swillf
1044960Swillf static int
kdb_unlock_list()1054960Swillf kdb_unlock_list()
1064960Swillf {
1074960Swillf return k5_mutex_unlock(&db_lock);
1084960Swillf }
1094960Swillf
1104960Swillf #define kdb_init_lib_lock(a) 0
1114960Swillf #define kdb_destroy_lib_lock(a) (void)0
1124960Swillf #define kdb_lock_lib_lock(a, b) 0
1134960Swillf #define kdb_unlock_lib_lock(a, b) (void)0
1144960Swillf
1154960Swillf /* Caller must free result*/
1164960Swillf
1174960Swillf static char *
kdb_get_conf_section(krb5_context kcontext)1184960Swillf kdb_get_conf_section(krb5_context kcontext)
1194960Swillf {
1204960Swillf krb5_error_code status = 0;
1214960Swillf char *result = NULL;
1224960Swillf char *value = NULL;
1234960Swillf
1244960Swillf if (kcontext->default_realm == NULL)
1254960Swillf return NULL;
1264960Swillf /* The profile has to have been initialized. If the profile was
1274960Swillf not initialized, expect nothing less than a crash. */
1284960Swillf status = profile_get_string(kcontext->profile,
1294960Swillf /* realms */
1304960Swillf KDB_REALM_SECTION,
1314960Swillf kcontext->default_realm,
1324960Swillf /* under the realm name, database_module */
1334960Swillf KDB_MODULE_POINTER,
1344960Swillf /* default value is the realm name itself */
1354960Swillf kcontext->default_realm,
1364960Swillf &value);
1374960Swillf
1384960Swillf if (status) {
1394960Swillf /* some problem */
1404960Swillf result = strdup(kcontext->default_realm);
1414960Swillf /* let NULL be handled by the caller */
1424960Swillf } else {
1434960Swillf result = strdup(value);
1444960Swillf /* free profile string */
1454960Swillf profile_release_string(value);
1464960Swillf }
1474960Swillf
1484960Swillf return result;
1494960Swillf }
1504960Swillf
1514960Swillf static char *
kdb_get_library_name(krb5_context kcontext)1524960Swillf kdb_get_library_name(krb5_context kcontext)
1534960Swillf {
1544960Swillf krb5_error_code status = 0;
1554960Swillf char *result = NULL;
1564960Swillf char *value = NULL;
1574960Swillf char *lib = NULL;
1584960Swillf
1594960Swillf status = profile_get_string(kcontext->profile,
1604960Swillf /* realms */
1614960Swillf KDB_REALM_SECTION,
1624960Swillf kcontext->default_realm,
1634960Swillf /* under the realm name, database_module */
1644960Swillf KDB_MODULE_POINTER,
1654960Swillf /* default value is the realm name itself */
1664960Swillf kcontext->default_realm,
1674960Swillf &value);
1684960Swillf if (status) {
1694960Swillf goto clean_n_exit;
1704960Swillf }
1714960Swillf
1724960Swillf #define DB2_NAME "db2"
1734960Swillf /* we got the module section. Get the library name from the module */
1744960Swillf status = profile_get_string(kcontext->profile, KDB_MODULE_SECTION, value,
1754960Swillf KDB_LIB_POINTER,
1764960Swillf /* default to db2 */
1774960Swillf DB2_NAME,
1784960Swillf &lib);
1794960Swillf
1804960Swillf if (status) {
1814960Swillf goto clean_n_exit;
1824960Swillf }
1834960Swillf
1844960Swillf result = strdup(lib);
1854960Swillf clean_n_exit:
1864960Swillf if (value) {
1874960Swillf /* free profile string */
1884960Swillf profile_release_string(value);
1894960Swillf }
1904960Swillf
1914960Swillf if (lib) {
1924960Swillf /* free profile string */
1934960Swillf profile_release_string(lib);
1944960Swillf }
1954960Swillf return result;
1964960Swillf }
1974960Swillf
1984960Swillf static void
kdb_setup_opt_functions(db_library lib)1994960Swillf kdb_setup_opt_functions(db_library lib)
2004960Swillf {
2014960Swillf if (lib->vftabl.set_master_key == NULL) {
2024960Swillf lib->vftabl.set_master_key = kdb_def_set_mkey;
2034960Swillf }
2044960Swillf
2054960Swillf if (lib->vftabl.get_master_key == NULL) {
2064960Swillf lib->vftabl.get_master_key = kdb_def_get_mkey;
2074960Swillf }
2084960Swillf
2094960Swillf if (lib->vftabl.fetch_master_key == NULL) {
2104960Swillf lib->vftabl.fetch_master_key = krb5_db_def_fetch_mkey;
2114960Swillf }
2124960Swillf
2134960Swillf if (lib->vftabl.verify_master_key == NULL) {
2144960Swillf lib->vftabl.verify_master_key = krb5_def_verify_master_key;
2154960Swillf }
2164960Swillf
2174960Swillf if (lib->vftabl.dbe_search_enctype == NULL) {
2184960Swillf lib->vftabl.dbe_search_enctype = krb5_dbe_def_search_enctype;
2194960Swillf }
2204960Swillf
2214960Swillf if (lib->vftabl.db_change_pwd == NULL) {
2224960Swillf lib->vftabl.db_change_pwd = krb5_dbe_def_cpw;
2234960Swillf }
2244960Swillf
2254960Swillf if (lib->vftabl.store_master_key == NULL) {
2264960Swillf lib->vftabl.store_master_key = krb5_def_store_mkey;
2274960Swillf }
2284960Swillf
2294960Swillf if (lib->vftabl.promote_db == NULL) {
2304960Swillf lib->vftabl.promote_db = krb5_def_promote_db;
2314960Swillf }
2324960Swillf }
2334960Swillf
2344960Swillf static int kdb_db2_pol_err_loaded = 0;
2354960Swillf #ifdef _KDB5_STATIC_LINK
2364960Swillf #define DEF_SYMBOL(a) extern kdb_vftabl krb5_db_vftabl_ ## a
2374960Swillf #define GET_SYMBOL(a) (krb5_db_vftabl_ ## a)
2384960Swillf static krb5_error_code
kdb_load_library(krb5_context kcontext,char * lib_name,db_library * lib)2394960Swillf kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib)
2404960Swillf {
2414960Swillf krb5_error_code status;
2424960Swillf void *vftabl_addr = NULL;
2434960Swillf char buf[KRB5_MAX_ERR_STR];
2444960Swillf
2454960Swillf if (!strcmp("kdb_db2", lib_name) && (kdb_db2_pol_err_loaded == 0)) {
2464960Swillf initialize_adb_error_table();
2474960Swillf kdb_db2_pol_err_loaded = 1;
2484960Swillf }
2494960Swillf
2504960Swillf *lib = calloc((size_t) 1, sizeof(**lib));
2514960Swillf if (*lib == NULL) {
2524960Swillf status = ENOMEM;
2534960Swillf goto clean_n_exit;
2544960Swillf }
2554960Swillf
2564960Swillf status = kdb_init_lib_lock(*lib);
2574960Swillf if (status) {
2584960Swillf goto clean_n_exit;
2594960Swillf }
2604960Swillf
2614960Swillf strcpy((*lib)->name, lib_name);
2624960Swillf
2634960Swillf #if !defined(KDB5_USE_LIB_KDB_DB2) && !defined(KDB5_USE_LIB_TEST)
2644960Swillf #error No database module defined
2654960Swillf #endif
2664960Swillf
2674960Swillf #ifdef KDB5_USE_LIB_KDB_DB2
2684960Swillf if (strcmp(lib_name, "kdb_db2") == 0) {
2694960Swillf DEF_SYMBOL(kdb_db2);
2704960Swillf vftabl_addr = (void *) &GET_SYMBOL(kdb_db2);
2714960Swillf } else
2724960Swillf #endif
2734960Swillf #ifdef KDB5_USE_LIB_TEST
2744960Swillf if (strcmp(lib_name, "test") == 0) {
2754960Swillf DEF_SYMBOL(test);
2764960Swillf vftabl_addr = (void *) &GET_SYMBOL(test);
2774960Swillf } else
2784960Swillf #endif
2794960Swillf {
2804960Swillf snprintf(buf, sizeof(buf), gettext("Program not built to support %s database type\n"),
2814960Swillf lib_name);
2824960Swillf status = KRB5_KDB_DBTYPE_NOSUP;
2834960Swillf krb5_db_set_err(kcontext, krb5_err_have_str, status, buf);
2844960Swillf goto clean_n_exit;
2854960Swillf }
2864960Swillf
2874960Swillf memcpy(&(*lib)->vftabl, vftabl_addr, sizeof(kdb_vftabl));
2884960Swillf
2894960Swillf kdb_setup_opt_functions(*lib);
2904960Swillf
2914960Swillf if ((status = (*lib)->vftabl.init_library())) {
2924960Swillf /* ERROR. library not initialized cleanly */
2934960Swillf snprintf(buf, sizeof(buf), gettext("%s library initialization failed, error code %ld\n"),
2944960Swillf lib_name, status);
2954960Swillf status = KRB5_KDB_DBTYPE_INIT;
2964960Swillf krb5_db_set_err(kcontext, krb5_err_have_str, status, buf);
2974960Swillf goto clean_n_exit;
2984960Swillf }
2994960Swillf
3004960Swillf clean_n_exit:
3014960Swillf if (status) {
3024960Swillf free(*lib), *lib = NULL;
3034960Swillf }
3044960Swillf return status;
3054960Swillf }
3064960Swillf
3074960Swillf #else /* KDB5_STATIC_LINK*/
3084960Swillf
3094960Swillf static char *db_dl_location[] = DEFAULT_KDB_LIB_PATH;
3104960Swillf #define db_dl_n_locations (sizeof(db_dl_location) / sizeof(db_dl_location[0]))
3114960Swillf
3124960Swillf static krb5_error_code
kdb_load_library(krb5_context kcontext,char * lib_name,db_library * lib)3134960Swillf kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib)
3144960Swillf {
3154960Swillf krb5_error_code status = 0;
3164960Swillf int ndx;
3174960Swillf void **vftabl_addrs = NULL;
3184960Swillf /* N.B.: If this is "const" but not "static", the Solaris 10
3194960Swillf native compiler has trouble building the library because of
3204960Swillf absolute relocations needed in read-only section ".rodata".
3214960Swillf When it's static, it goes into ".picdata", which is
3224960Swillf read-write. */
3234960Swillf static const char *const dbpath_names[] = {
3244960Swillf KDB_MODULE_SECTION, "db_module_dir", NULL,
3254960Swillf };
3264960Swillf const char *filebases[2];
3274960Swillf char **profpath = NULL;
3284960Swillf char **path = NULL;
3294960Swillf
3304960Swillf filebases[0] = lib_name;
3314960Swillf filebases[1] = NULL;
3324960Swillf
3334960Swillf if (!strcmp(DB2_NAME, lib_name) && (kdb_db2_pol_err_loaded == 0)) {
3344960Swillf initialize_adb_error_table();
3354960Swillf kdb_db2_pol_err_loaded = 1;
3364960Swillf }
3374960Swillf
3384960Swillf *lib = calloc((size_t) 1, sizeof(**lib));
3394960Swillf if (*lib == NULL) {
3404960Swillf status = ENOMEM;
3414960Swillf goto clean_n_exit;
3424960Swillf }
3434960Swillf
3444960Swillf status = kdb_init_lib_lock(*lib);
3454960Swillf if (status) {
3464960Swillf goto clean_n_exit;
3474960Swillf }
3484960Swillf
3494960Swillf strcpy((*lib)->name, lib_name);
3504960Swillf
3514960Swillf /* Fetch the list of directories specified in the config
3524960Swillf file(s) first. */
3534960Swillf status = profile_get_values(kcontext->profile, dbpath_names, &profpath);
3544960Swillf if (status != 0 && status != PROF_NO_RELATION)
3554960Swillf goto clean_n_exit;
3564960Swillf ndx = 0;
3574960Swillf if (profpath)
3584960Swillf while (profpath[ndx] != NULL)
3594960Swillf ndx++;
3604960Swillf
3614960Swillf path = calloc(ndx + db_dl_n_locations, sizeof (char *));
3624960Swillf if (path == NULL) {
3634960Swillf status = errno;
3644960Swillf goto clean_n_exit;
3654960Swillf }
3664960Swillf if (ndx)
3674960Swillf memcpy(path, profpath, ndx * sizeof(profpath[0]));
3684960Swillf memcpy(path + ndx, db_dl_location, db_dl_n_locations * sizeof(char *));
3694960Swillf status = 0;
3704960Swillf
3714960Swillf if ((status = krb5int_open_plugin_dirs ((const char **) path,
3724960Swillf filebases,
3734960Swillf &(*lib)->dl_dir_handle, &kcontext->err))) {
3744960Swillf const char *err_str = krb5_get_error_message(kcontext, status);
3754960Swillf status = KRB5_KDB_DBTYPE_NOTFOUND;
3764960Swillf krb5_set_error_message (kcontext, status,
3774960Swillf gettext("Unable to find requested database type: %s"), err_str);
3784960Swillf krb5_free_error_message (kcontext, err_str);
3794960Swillf goto clean_n_exit;
3804960Swillf }
3814960Swillf
3824960Swillf if ((status = krb5int_get_plugin_dir_data (&(*lib)->dl_dir_handle, "kdb_function_table",
3834960Swillf &vftabl_addrs, &kcontext->err))) {
3844960Swillf const char *err_str = krb5_get_error_message(kcontext, status);
3854960Swillf status = KRB5_KDB_DBTYPE_INIT;
3864960Swillf krb5_set_error_message (kcontext, status,
3874960Swillf gettext("plugin symbol 'kdb_function_table' lookup failed: %s"), err_str);
3884960Swillf krb5_free_error_message (kcontext, err_str);
3894960Swillf goto clean_n_exit;
3904960Swillf }
3914960Swillf
3924960Swillf if (vftabl_addrs[0] == NULL) {
3934960Swillf /* No plugins! */
3944960Swillf status = KRB5_KDB_DBTYPE_NOTFOUND;
3954960Swillf krb5_set_error_message (kcontext, status,
3964960Swillf gettext("Unable to load requested database module '%s': plugin symbol 'kdb_function_table' not found"),
3974960Swillf lib_name);
3984960Swillf goto clean_n_exit;
3994960Swillf }
4004960Swillf
4014960Swillf memcpy(&(*lib)->vftabl, vftabl_addrs[0], sizeof(kdb_vftabl));
4024960Swillf kdb_setup_opt_functions(*lib);
4034960Swillf
4044960Swillf if ((status = (*lib)->vftabl.init_library())) {
4054960Swillf /* ERROR. library not initialized cleanly */
4064960Swillf goto clean_n_exit;
4074960Swillf }
4084960Swillf
4094960Swillf clean_n_exit:
4104960Swillf if (vftabl_addrs != NULL) { krb5int_free_plugin_dir_data (vftabl_addrs); }
4114960Swillf /* Both of these DTRT with NULL. */
4124960Swillf profile_free_list(profpath);
4134960Swillf free(path);
4144960Swillf if (status) {
4154960Swillf if (*lib) {
4164960Swillf kdb_destroy_lib_lock(*lib);
4174960Swillf if (PLUGIN_DIR_OPEN((&(*lib)->dl_dir_handle))) {
4184960Swillf krb5int_close_plugin_dirs (&(*lib)->dl_dir_handle);
4194960Swillf }
4204960Swillf free(*lib);
4214960Swillf *lib = NULL;
4224960Swillf }
4234960Swillf }
4244960Swillf return status;
4254960Swillf }
4264960Swillf
4274960Swillf #endif /* end of _KDB5_STATIC_LINK */
4284960Swillf
4294960Swillf static krb5_error_code
kdb_find_library(krb5_context kcontext,char * lib_name,db_library * lib)4304960Swillf kdb_find_library(krb5_context kcontext, char *lib_name, db_library * lib)
4314960Swillf {
4324960Swillf /* lock here so that no two threads try to do the same at the same time */
4334960Swillf krb5_error_code status = 0;
4344960Swillf int locked = 0;
4354960Swillf db_library curr_elt, prev_elt = NULL;
4364960Swillf
4374960Swillf if ((status = kdb_lock_list()) != 0) {
4384960Swillf goto clean_n_exit;
4394960Swillf }
4404960Swillf locked = 1;
4414960Swillf
4424960Swillf curr_elt = lib_list;
4434960Swillf while (curr_elt != NULL) {
4444960Swillf if (strcmp(lib_name, curr_elt->name) == 0) {
4454960Swillf *lib = curr_elt;
4464960Swillf goto clean_n_exit;
4474960Swillf }
4484960Swillf prev_elt = curr_elt;
4494960Swillf curr_elt = curr_elt->next;
4504960Swillf }
4514960Swillf
4524960Swillf /* module not found. create and add to list */
4534960Swillf status = kdb_load_library(kcontext, lib_name, lib);
4544960Swillf if (status) {
4554960Swillf goto clean_n_exit;
4564960Swillf }
4574960Swillf
4584960Swillf if (prev_elt) {
4594960Swillf /* prev_elt points to the last element in the list */
4604960Swillf prev_elt->next = *lib;
4614960Swillf (*lib)->prev = prev_elt;
4624960Swillf } else {
4634960Swillf lib_list = *lib;
4644960Swillf }
4654960Swillf
4664960Swillf clean_n_exit:
4674960Swillf if (*lib) {
4684960Swillf (*lib)->reference_cnt++;
4694960Swillf }
4704960Swillf
4714960Swillf if (locked) {
4724960Swillf (void)kdb_unlock_list();
4734960Swillf }
4744960Swillf
4754960Swillf return status;
4764960Swillf }
4774960Swillf
4784960Swillf static krb5_error_code
kdb_free_library(db_library lib)4794960Swillf kdb_free_library(db_library lib)
4804960Swillf {
4814960Swillf krb5_error_code status = 0;
4824960Swillf int locked = 0;
4834960Swillf
4844960Swillf if ((status = kdb_lock_list()) != 0) {
4854960Swillf goto clean_n_exit;
4864960Swillf }
4874960Swillf locked = 1;
4884960Swillf
4894960Swillf lib->reference_cnt--;
4904960Swillf
4914960Swillf if (lib->reference_cnt == 0) {
4924960Swillf status = lib->vftabl.fini_library();
4934960Swillf if (status) {
4944960Swillf goto clean_n_exit;
4954960Swillf }
4964960Swillf
4974960Swillf /* close the library */
4984960Swillf if (PLUGIN_DIR_OPEN((&lib->dl_dir_handle))) {
4994960Swillf krb5int_close_plugin_dirs (&lib->dl_dir_handle);
5004960Swillf }
5014960Swillf
5024960Swillf kdb_destroy_lib_lock(lib);
5034960Swillf
5044960Swillf if (lib->prev == NULL) {
5054960Swillf /* first element in the list */
5064960Swillf lib_list = lib->next;
5074960Swillf } else {
5084960Swillf lib->prev->next = lib->next;
5094960Swillf }
5104960Swillf
5114960Swillf if (lib->next) {
5124960Swillf lib->next->prev = lib->prev;
5134960Swillf }
5144960Swillf free(lib);
5154960Swillf }
5164960Swillf
5174960Swillf clean_n_exit:
5184960Swillf if (locked) {
5194960Swillf (void)kdb_unlock_list();
5204960Swillf }
5214960Swillf
5224960Swillf return status;
5234960Swillf }
5244960Swillf
5254960Swillf static krb5_error_code
kdb_setup_lib_handle(krb5_context kcontext)5264960Swillf kdb_setup_lib_handle(krb5_context kcontext)
5274960Swillf {
5284960Swillf char *library = NULL;
5294960Swillf krb5_error_code status = 0;
5304960Swillf db_library lib = NULL;
5314960Swillf kdb5_dal_handle *dal_handle = NULL;
5324960Swillf
5334960Swillf dal_handle = calloc((size_t) 1, sizeof(kdb5_dal_handle));
5344960Swillf if (dal_handle == NULL) {
5354960Swillf status = ENOMEM;
5364960Swillf goto clean_n_exit;
5374960Swillf }
5384960Swillf
5394960Swillf library = kdb_get_library_name(kcontext);
5404960Swillf if (library == NULL) {
5414960Swillf status = KRB5_KDB_DBTYPE_NOTFOUND;
5424960Swillf goto clean_n_exit;
5434960Swillf }
5444960Swillf
5454960Swillf status = kdb_find_library(kcontext, library, &lib);
5464960Swillf if (status) {
5474960Swillf goto clean_n_exit;
5484960Swillf }
5494960Swillf
5504960Swillf dal_handle->lib_handle = lib;
5514960Swillf kcontext->db_context = (void *) dal_handle;
5524960Swillf
5534960Swillf clean_n_exit:
5544960Swillf free(library);
5554960Swillf
5564960Swillf if (status) {
5574960Swillf free(dal_handle);
5584960Swillf if (lib) {
5594960Swillf (void)kdb_free_library(lib);
5604960Swillf }
5614960Swillf }
5624960Swillf
5634960Swillf return status;
5644960Swillf }
5654960Swillf
5664960Swillf static krb5_error_code
kdb_free_lib_handle(krb5_context kcontext)5674960Swillf kdb_free_lib_handle(krb5_context kcontext)
5684960Swillf {
5694960Swillf krb5_error_code status = 0;
5704960Swillf
5714960Swillf status =
5724960Swillf kdb_free_library(((kdb5_dal_handle *) kcontext->db_context)->
5734960Swillf lib_handle);
5744960Swillf if (status) {
5754960Swillf goto clean_n_exit;
5764960Swillf }
5774960Swillf
5784960Swillf free(kcontext->db_context);
5794960Swillf kcontext->db_context = NULL;
5804960Swillf
5814960Swillf clean_n_exit:
5824960Swillf return status;
5834960Swillf }
5844960Swillf
5854960Swillf static void
get_errmsg(krb5_context kcontext,krb5_error_code err_code)5864960Swillf get_errmsg (krb5_context kcontext, krb5_error_code err_code)
5874960Swillf {
5884960Swillf kdb5_dal_handle *dal_handle;
5894960Swillf const char *e;
5904960Swillf if (err_code == 0)
5914960Swillf return;
5924960Swillf assert(kcontext != NULL);
5934960Swillf /* Must be called with dal_handle->lib_handle locked! */
5944960Swillf assert(kcontext->db_context != NULL);
5954960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
5964960Swillf if (dal_handle->lib_handle->vftabl.errcode_2_string == NULL)
5974960Swillf return;
5984960Swillf e = dal_handle->lib_handle->vftabl.errcode_2_string(kcontext, err_code);
5994960Swillf assert (e != NULL);
6004960Swillf krb5_set_error_message(kcontext, err_code, "%s", e);
6014960Swillf if (dal_handle->lib_handle->vftabl.release_errcode_string)
6024960Swillf dal_handle->lib_handle->vftabl.release_errcode_string(kcontext, e);
6034960Swillf }
6044960Swillf
6054960Swillf /*
6064960Swillf * External functions... DAL API
6074960Swillf */
6084960Swillf krb5_error_code
krb5_db_open(krb5_context kcontext,char ** db_args,int mode)6094960Swillf krb5_db_open(krb5_context kcontext, char **db_args, int mode)
6104960Swillf {
6114960Swillf krb5_error_code status = 0;
6124960Swillf char *section = NULL;
6134960Swillf kdb5_dal_handle *dal_handle;
6144960Swillf
6154960Swillf section = kdb_get_conf_section(kcontext);
6164960Swillf if (section == NULL) {
6174960Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR;
6184960Swillf krb5_set_error_message (kcontext, status,
6194960Swillf gettext("unable to determine configuration section for realm %s\n"),
6204960Swillf kcontext->default_realm ? kcontext->default_realm : "[UNSET]");
6214960Swillf goto clean_n_exit;
6224960Swillf }
6234960Swillf
6244960Swillf if (kcontext->db_context == NULL) {
6254960Swillf status = kdb_setup_lib_handle(kcontext);
6264960Swillf if (status) {
6274960Swillf goto clean_n_exit;
6284960Swillf }
6294960Swillf }
6304960Swillf
6314960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
6324960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
6334960Swillf if (status) {
634*6426Smp153739 /* Solaris Kerberos */
635*6426Smp153739 kdb_free_lib_handle(kcontext);
6364960Swillf goto clean_n_exit;
6374960Swillf }
6384960Swillf
6394960Swillf status =
6404960Swillf dal_handle->lib_handle->vftabl.init_module(kcontext, section, db_args,
6414960Swillf mode);
6424960Swillf get_errmsg(kcontext, status);
6434960Swillf
6444960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
6454960Swillf
646*6426Smp153739 /* Solaris Kerberos */
647*6426Smp153739 if (status)
648*6426Smp153739 kdb_free_lib_handle(kcontext);
649*6426Smp153739
6504960Swillf clean_n_exit:
6514960Swillf if (section)
6524960Swillf free(section);
6534960Swillf return status;
6544960Swillf }
6554960Swillf
6564960Swillf krb5_error_code
krb5_db_inited(krb5_context kcontext)6574960Swillf krb5_db_inited(krb5_context kcontext)
6584960Swillf {
6594960Swillf return !(kcontext && kcontext->db_context &&
6604960Swillf ((kdb5_dal_handle *) kcontext->db_context)->db_context);
6614960Swillf }
6624960Swillf
6634960Swillf krb5_error_code
krb5_db_create(krb5_context kcontext,char ** db_args)6644960Swillf krb5_db_create(krb5_context kcontext, char **db_args)
6654960Swillf {
6664960Swillf krb5_error_code status = 0;
6674960Swillf char *section = NULL;
6684960Swillf kdb5_dal_handle *dal_handle;
6694960Swillf
6704960Swillf section = kdb_get_conf_section(kcontext);
6714960Swillf if (section == NULL) {
6724960Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR;
6734960Swillf krb5_set_error_message (kcontext, status,
6744960Swillf gettext("unable to determine configuration section for realm %s\n"),
6754960Swillf kcontext->default_realm);
6764960Swillf goto clean_n_exit;
6774960Swillf }
6784960Swillf
6794960Swillf if (kcontext->db_context == NULL) {
6804960Swillf status = kdb_setup_lib_handle(kcontext);
6814960Swillf if (status) {
6824960Swillf goto clean_n_exit;
6834960Swillf }
6844960Swillf }
6854960Swillf
6864960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
6874960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
6884960Swillf if (status) {
6894960Swillf goto clean_n_exit;
6904960Swillf }
6914960Swillf
6924960Swillf status =
6934960Swillf dal_handle->lib_handle->vftabl.db_create(kcontext, section, db_args);
6944960Swillf get_errmsg(kcontext, status);
6954960Swillf
6964960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
6974960Swillf
6984960Swillf clean_n_exit:
6994960Swillf if (section)
7004960Swillf free(section);
7014960Swillf return status;
7024960Swillf }
7034960Swillf
7044960Swillf krb5_error_code
krb5_db_fini(krb5_context kcontext)7054960Swillf krb5_db_fini(krb5_context kcontext)
7064960Swillf {
7074960Swillf krb5_error_code status = 0;
7084960Swillf kdb5_dal_handle *dal_handle;
7094960Swillf
7104960Swillf if (kcontext->db_context == NULL) {
7114960Swillf /* module not loaded. So nothing to be done */
7124960Swillf goto clean_n_exit;
7134960Swillf }
7144960Swillf
7154960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
7164960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
7174960Swillf if (status) {
7184960Swillf goto clean_n_exit;
7194960Swillf }
7204960Swillf
7214960Swillf status = dal_handle->lib_handle->vftabl.fini_module(kcontext);
7224960Swillf get_errmsg(kcontext, status);
7234960Swillf
7244960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
7254960Swillf
7264960Swillf if (status) {
7274960Swillf goto clean_n_exit;
7284960Swillf }
7294960Swillf
7304960Swillf status = kdb_free_lib_handle(kcontext);
7314960Swillf
7324960Swillf clean_n_exit:
7334960Swillf return status;
7344960Swillf }
7354960Swillf
7364960Swillf krb5_error_code
krb5_db_destroy(krb5_context kcontext,char ** db_args)7374960Swillf krb5_db_destroy(krb5_context kcontext, char **db_args)
7384960Swillf {
7394960Swillf krb5_error_code status = 0;
7404960Swillf char *section = NULL;
7414960Swillf kdb5_dal_handle *dal_handle;
7424960Swillf
7434960Swillf section = kdb_get_conf_section(kcontext);
7444960Swillf if (section == NULL) {
7454960Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR;
7464960Swillf krb5_set_error_message (kcontext, status,
7474960Swillf gettext("unable to determine configuration section for realm %s\n"),
7484960Swillf kcontext->default_realm);
7494960Swillf goto clean_n_exit;
7504960Swillf }
7514960Swillf
7524960Swillf if (kcontext->db_context == NULL) {
7534960Swillf status = kdb_setup_lib_handle(kcontext);
7544960Swillf if (status) {
7554960Swillf goto clean_n_exit;
7564960Swillf }
7574960Swillf }
7584960Swillf
7594960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
7604960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
7614960Swillf if (status) {
7624960Swillf goto clean_n_exit;
7634960Swillf }
7644960Swillf
7654960Swillf status =
7664960Swillf dal_handle->lib_handle->vftabl.db_destroy(kcontext, section, db_args);
7674960Swillf get_errmsg(kcontext, status);
7684960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
7694960Swillf
7704960Swillf clean_n_exit:
7714960Swillf if (section)
7724960Swillf free(section);
7734960Swillf return status;
7744960Swillf }
7754960Swillf
7764960Swillf krb5_error_code
krb5_db_get_age(krb5_context kcontext,char * db_name,time_t * t)7774960Swillf krb5_db_get_age(krb5_context kcontext, char *db_name, time_t * t)
7784960Swillf {
7794960Swillf krb5_error_code status = 0;
7804960Swillf kdb5_dal_handle *dal_handle;
7814960Swillf
7824960Swillf if (kcontext->db_context == NULL) {
7834960Swillf status = kdb_setup_lib_handle(kcontext);
7844960Swillf if (status) {
7854960Swillf goto clean_n_exit;
7864960Swillf }
7874960Swillf }
7884960Swillf
7894960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
7904960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
7914960Swillf if (status) {
7924960Swillf goto clean_n_exit;
7934960Swillf }
7944960Swillf
7954960Swillf status = dal_handle->lib_handle->vftabl.db_get_age(kcontext, db_name, t);
7964960Swillf get_errmsg(kcontext, status);
7974960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
7984960Swillf
7994960Swillf clean_n_exit:
8004960Swillf return status;
8014960Swillf }
8024960Swillf
8034960Swillf krb5_error_code
krb5_db_set_option(krb5_context kcontext,int option,void * value)8044960Swillf krb5_db_set_option(krb5_context kcontext, int option, void *value)
8054960Swillf {
8064960Swillf krb5_error_code status = 0;
8074960Swillf kdb5_dal_handle *dal_handle;
8084960Swillf
8094960Swillf if (kcontext->db_context == NULL) {
8104960Swillf status = kdb_setup_lib_handle(kcontext);
8114960Swillf if (status) {
8124960Swillf goto clean_n_exit;
8134960Swillf }
8144960Swillf }
8154960Swillf
8164960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
8174960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
8184960Swillf if (status) {
8194960Swillf goto clean_n_exit;
8204960Swillf }
8214960Swillf
8224960Swillf status =
8234960Swillf dal_handle->lib_handle->vftabl.db_set_option(kcontext, option, value);
8244960Swillf get_errmsg(kcontext, status);
8254960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
8264960Swillf
8274960Swillf clean_n_exit:
8284960Swillf return status;
8294960Swillf }
8304960Swillf
8314960Swillf krb5_error_code
krb5_db_lock(krb5_context kcontext,int lock_mode)8324960Swillf krb5_db_lock(krb5_context kcontext, int lock_mode)
8334960Swillf {
8344960Swillf krb5_error_code status = 0;
8354960Swillf kdb5_dal_handle *dal_handle;
8364960Swillf
8374960Swillf if (kcontext->db_context == NULL) {
8384960Swillf status = kdb_setup_lib_handle(kcontext);
8394960Swillf if (status) {
8404960Swillf goto clean_n_exit;
8414960Swillf }
8424960Swillf }
8434960Swillf
8444960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
8454960Swillf /* acquire an exclusive lock, ensures no other thread uses this context */
8464960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, TRUE);
8474960Swillf if (status) {
8484960Swillf goto clean_n_exit;
8494960Swillf }
8504960Swillf
8514960Swillf status = dal_handle->lib_handle->vftabl.db_lock(kcontext, lock_mode);
8524960Swillf get_errmsg(kcontext, status);
8534960Swillf
8544960Swillf /* exclusive lock is still held, so no other thread could use this context */
8554960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
8564960Swillf
8574960Swillf clean_n_exit:
8584960Swillf return status;
8594960Swillf }
8604960Swillf
8614960Swillf krb5_error_code
krb5_db_unlock(krb5_context kcontext)8624960Swillf krb5_db_unlock(krb5_context kcontext)
8634960Swillf {
8644960Swillf krb5_error_code status = 0;
8654960Swillf kdb5_dal_handle *dal_handle;
8664960Swillf
8674960Swillf if (kcontext->db_context == NULL) {
8684960Swillf status = kdb_setup_lib_handle(kcontext);
8694960Swillf if (status) {
8704960Swillf goto clean_n_exit;
8714960Swillf }
8724960Swillf }
8734960Swillf
8744960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
8754960Swillf /* normal lock acquired and exclusive lock released */
8764960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
8774960Swillf if (status) {
8784960Swillf goto clean_n_exit;
8794960Swillf }
8804960Swillf
8814960Swillf status = dal_handle->lib_handle->vftabl.db_unlock(kcontext);
8824960Swillf get_errmsg(kcontext, status);
8834960Swillf
8844960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, TRUE);
8854960Swillf
8864960Swillf clean_n_exit:
8874960Swillf return status;
8884960Swillf }
8894960Swillf
8904960Swillf krb5_error_code
krb5_db_get_principal(krb5_context kcontext,krb5_const_principal search_for,krb5_db_entry * entries,int * nentries,krb5_boolean * more)8914960Swillf krb5_db_get_principal(krb5_context kcontext,
8924960Swillf krb5_const_principal search_for,
8934960Swillf krb5_db_entry * entries,
8944960Swillf int *nentries, krb5_boolean * more)
8954960Swillf {
8964960Swillf krb5_error_code status = 0;
8974960Swillf kdb5_dal_handle *dal_handle;
8984960Swillf
8994960Swillf if (kcontext->db_context == NULL) {
9004960Swillf status = kdb_setup_lib_handle(kcontext);
9014960Swillf if (status) {
9024960Swillf goto clean_n_exit;
9034960Swillf }
9044960Swillf }
9054960Swillf
9064960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
9074960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
9084960Swillf if (status) {
9094960Swillf goto clean_n_exit;
9104960Swillf }
9114960Swillf
9124960Swillf status =
9134960Swillf dal_handle->lib_handle->vftabl.db_get_principal(kcontext, search_for,
9144960Swillf entries, nentries,
9154960Swillf more);
9164960Swillf get_errmsg(kcontext, status);
9174960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
9184960Swillf
9194960Swillf clean_n_exit:
9204960Swillf return status;
9214960Swillf }
9224960Swillf
9234960Swillf krb5_error_code
krb5_db_get_principal_nolock(krb5_context kcontext,krb5_const_principal search_for,krb5_db_entry * entries,int * nentries,krb5_boolean * more)9244960Swillf krb5_db_get_principal_nolock(krb5_context kcontext,
9254960Swillf krb5_const_principal search_for,
9264960Swillf krb5_db_entry * entries,
9274960Swillf int *nentries, krb5_boolean * more)
9284960Swillf {
9294960Swillf krb5_error_code status = 0;
9304960Swillf kdb5_dal_handle *dal_handle;
9314960Swillf
9324960Swillf if (kcontext->db_context == NULL) {
9334960Swillf status = kdb_setup_lib_handle(kcontext);
9344960Swillf if (status) {
9354960Swillf goto clean_n_exit;
9364960Swillf }
9374960Swillf }
9384960Swillf
9394960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
9404960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
9414960Swillf if (status) {
9424960Swillf goto clean_n_exit;
9434960Swillf }
9444960Swillf
9454960Swillf status =
9464960Swillf dal_handle->lib_handle->vftabl.db_get_principal_nolock(kcontext,
9474960Swillf search_for,
9484960Swillf entries, nentries,
9494960Swillf more);
9504960Swillf get_errmsg(kcontext, status);
9514960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
9524960Swillf
9534960Swillf clean_n_exit:
9544960Swillf return status;
9554960Swillf }
9564960Swillf
9574960Swillf krb5_error_code
krb5_db_free_principal(krb5_context kcontext,krb5_db_entry * entry,int count)9584960Swillf krb5_db_free_principal(krb5_context kcontext, krb5_db_entry * entry, int count)
9594960Swillf {
9604960Swillf krb5_error_code status = 0;
9614960Swillf kdb5_dal_handle *dal_handle;
9624960Swillf
9634960Swillf if (kcontext->db_context == NULL) {
9644960Swillf status = kdb_setup_lib_handle(kcontext);
9654960Swillf if (status) {
9664960Swillf goto clean_n_exit;
9674960Swillf }
9684960Swillf }
9694960Swillf
9704960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
9714960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
9724960Swillf if (status) {
9734960Swillf goto clean_n_exit;
9744960Swillf }
9754960Swillf
9764960Swillf status =
9774960Swillf dal_handle->lib_handle->vftabl.db_free_principal(kcontext, entry,
9784960Swillf count);
9794960Swillf get_errmsg(kcontext, status);
9804960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
9814960Swillf
9824960Swillf clean_n_exit:
9834960Swillf return status;
9844960Swillf }
9854960Swillf
9864960Swillf krb5_error_code
krb5_db_put_principal(krb5_context kcontext,krb5_db_entry * entries,int * nentries)9874960Swillf krb5_db_put_principal(krb5_context kcontext,
9884960Swillf krb5_db_entry * entries, int *nentries)
9894960Swillf {
9904960Swillf krb5_error_code status = 0;
9914960Swillf kdb5_dal_handle *dal_handle;
9924960Swillf char **db_args = NULL;
9934960Swillf krb5_tl_data *prev, *curr, *next;
9944960Swillf int db_args_size = 0;
9954960Swillf
9964960Swillf if (kcontext->db_context == NULL) {
9974960Swillf status = kdb_setup_lib_handle(kcontext);
9984960Swillf if (status) {
9994960Swillf goto clean_n_exit;
10004960Swillf }
10014960Swillf }
10024960Swillf
10034960Swillf /* Giving db_args as part of tl data causes, db2 to store the
10044960Swillf tl_data as such. To prevent this, tl_data is collated and
10054960Swillf passed as a sepearte argument. Currently supports only one
10064960Swillf principal. but passing it as a seperate argument makes it
10074960Swillf difficult for kadmin remote to pass arguments to server. */
10084960Swillf prev = NULL, curr = entries->tl_data;
10094960Swillf while (curr) {
10104960Swillf if (curr->tl_data_type == KRB5_TL_DB_ARGS) {
10114960Swillf char **t;
10124960Swillf /* Since this is expected to be NULL terminated string and
10134960Swillf this could come from any client, do a check before
10144960Swillf passing it to db. */
10154960Swillf if (((char *) curr->tl_data_contents)[curr->tl_data_length - 1] !=
10164960Swillf '\0') {
10174960Swillf /* not null terminated. Dangerous input */
10184960Swillf status = EINVAL;
10194960Swillf goto clean_n_exit;
10204960Swillf }
10214960Swillf
10224960Swillf db_args_size++;
10234960Swillf t = realloc(db_args, sizeof(char *) * (db_args_size + 1)); /* 1 for NULL */
10244960Swillf if (t == NULL) {
10254960Swillf status = ENOMEM;
10264960Swillf goto clean_n_exit;
10274960Swillf }
10284960Swillf
10294960Swillf db_args = t;
10304960Swillf db_args[db_args_size - 1] = (char *) curr->tl_data_contents;
10314960Swillf db_args[db_args_size] = NULL;
10324960Swillf
10334960Swillf next = curr->tl_data_next;
10344960Swillf if (prev == NULL) {
10354960Swillf /* current node is the first in the linked list. remove it */
10364960Swillf entries->tl_data = curr->tl_data_next;
10374960Swillf } else {
10384960Swillf prev->tl_data_next = curr->tl_data_next;
10394960Swillf }
10404960Swillf entries->n_tl_data--;
10414960Swillf krb5_db_free(kcontext, curr);
10424960Swillf
10434960Swillf /* previous does not change */
10444960Swillf curr = next;
10454960Swillf } else {
10464960Swillf prev = curr;
10474960Swillf curr = curr->tl_data_next;
10484960Swillf }
10494960Swillf }
10504960Swillf
10514960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
10524960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
10534960Swillf if (status) {
10544960Swillf goto clean_n_exit;
10554960Swillf }
10564960Swillf
10574960Swillf status = dal_handle->lib_handle->vftabl.db_put_principal(kcontext, entries,
10584960Swillf nentries,
10594960Swillf db_args);
10604960Swillf get_errmsg(kcontext, status);
10614960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
10624960Swillf
10634960Swillf clean_n_exit:
10644960Swillf while (db_args_size) {
10654960Swillf if (db_args[db_args_size - 1])
10664960Swillf krb5_db_free(kcontext, db_args[db_args_size - 1]);
10674960Swillf
10684960Swillf db_args_size--;
10694960Swillf }
10704960Swillf
10714960Swillf if (db_args)
10724960Swillf free(db_args);
10734960Swillf
10744960Swillf return status;
10754960Swillf }
10764960Swillf
10774960Swillf krb5_error_code
krb5_db_delete_principal(krb5_context kcontext,krb5_principal search_for,int * nentries)10784960Swillf krb5_db_delete_principal(krb5_context kcontext,
10794960Swillf krb5_principal search_for, int *nentries)
10804960Swillf {
10814960Swillf krb5_error_code status = 0;
10824960Swillf kdb5_dal_handle *dal_handle;
10834960Swillf
10844960Swillf if (kcontext->db_context == NULL) {
10854960Swillf status = kdb_setup_lib_handle(kcontext);
10864960Swillf if (status) {
10874960Swillf goto clean_n_exit;
10884960Swillf }
10894960Swillf }
10904960Swillf
10914960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
10924960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
10934960Swillf if (status) {
10944960Swillf goto clean_n_exit;
10954960Swillf }
10964960Swillf
10974960Swillf status =
10984960Swillf dal_handle->lib_handle->vftabl.db_delete_principal(kcontext,
10994960Swillf search_for,
11004960Swillf nentries);
11014960Swillf get_errmsg(kcontext, status);
11024960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
11034960Swillf
11044960Swillf clean_n_exit:
11054960Swillf return status;
11064960Swillf }
11074960Swillf
11084960Swillf krb5_error_code
krb5_db_iterate(krb5_context kcontext,char * match_entry,int (* func)(krb5_pointer,krb5_db_entry *),krb5_pointer func_arg,char ** db_args)11094960Swillf krb5_db_iterate(krb5_context kcontext,
11104960Swillf char *match_entry,
11114960Swillf int (*func) (krb5_pointer, krb5_db_entry *),
11125916Swillf krb5_pointer func_arg,
11135916Swillf /* Solaris Kerberos: adding support for db_args */
11145916Swillf char **db_args)
11154960Swillf {
11164960Swillf krb5_error_code status = 0;
11174960Swillf kdb5_dal_handle *dal_handle;
11184960Swillf
11194960Swillf if (kcontext->db_context == NULL) {
11204960Swillf status = kdb_setup_lib_handle(kcontext);
11214960Swillf if (status) {
11224960Swillf goto clean_n_exit;
11234960Swillf }
11244960Swillf }
11254960Swillf
11264960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
11274960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
11284960Swillf if (status) {
11294960Swillf goto clean_n_exit;
11304960Swillf }
11314960Swillf
11325916Swillf /* Solaris Kerberos: adding support for db_args */
11334960Swillf status = dal_handle->lib_handle->vftabl.db_iterate(kcontext,
11344960Swillf match_entry,
11355916Swillf func, func_arg,
11365916Swillf db_args);
11374960Swillf get_errmsg(kcontext, status);
11384960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
11394960Swillf
11404960Swillf clean_n_exit:
11414960Swillf return status;
11424960Swillf }
11434960Swillf
11444960Swillf krb5_error_code
krb5_supported_realms(krb5_context kcontext,char ** realms)11454960Swillf krb5_supported_realms(krb5_context kcontext, char **realms)
11464960Swillf {
11474960Swillf krb5_error_code status = 0;
11484960Swillf kdb5_dal_handle *dal_handle;
11494960Swillf
11504960Swillf if (kcontext->db_context == NULL) {
11514960Swillf status = kdb_setup_lib_handle(kcontext);
11524960Swillf if (status) {
11534960Swillf goto clean_n_exit;
11544960Swillf }
11554960Swillf }
11564960Swillf
11574960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
11584960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
11594960Swillf if (status) {
11604960Swillf goto clean_n_exit;
11614960Swillf }
11624960Swillf
11634960Swillf status =
11644960Swillf dal_handle->lib_handle->vftabl.db_supported_realms(kcontext, realms);
11654960Swillf get_errmsg(kcontext, status);
11664960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
11674960Swillf
11684960Swillf clean_n_exit:
11694960Swillf return status;
11704960Swillf }
11714960Swillf
11724960Swillf krb5_error_code
krb5_free_supported_realms(krb5_context kcontext,char ** realms)11734960Swillf krb5_free_supported_realms(krb5_context kcontext, char **realms)
11744960Swillf {
11754960Swillf krb5_error_code status = 0;
11764960Swillf kdb5_dal_handle *dal_handle;
11774960Swillf
11784960Swillf if (kcontext->db_context == NULL) {
11794960Swillf status = kdb_setup_lib_handle(kcontext);
11804960Swillf if (status) {
11814960Swillf goto clean_n_exit;
11824960Swillf }
11834960Swillf }
11844960Swillf
11854960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
11864960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
11874960Swillf if (status) {
11884960Swillf goto clean_n_exit;
11894960Swillf }
11904960Swillf
11914960Swillf status =
11924960Swillf dal_handle->lib_handle->vftabl.db_free_supported_realms(kcontext,
11934960Swillf realms);
11944960Swillf get_errmsg(kcontext, status);
11954960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
11964960Swillf
11974960Swillf clean_n_exit:
11984960Swillf return status;
11994960Swillf }
12004960Swillf
12014960Swillf krb5_error_code
krb5_db_set_master_key_ext(krb5_context kcontext,char * pwd,krb5_keyblock * key)12024960Swillf krb5_db_set_master_key_ext(krb5_context kcontext,
12034960Swillf char *pwd, krb5_keyblock * key)
12044960Swillf {
12054960Swillf krb5_error_code status = 0;
12064960Swillf kdb5_dal_handle *dal_handle;
12074960Swillf
12084960Swillf if (kcontext->db_context == NULL) {
12094960Swillf status = kdb_setup_lib_handle(kcontext);
12104960Swillf if (status) {
12114960Swillf goto clean_n_exit;
12124960Swillf }
12134960Swillf }
12144960Swillf
12154960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
12164960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
12174960Swillf if (status) {
12184960Swillf goto clean_n_exit;
12194960Swillf }
12204960Swillf
12214960Swillf status = dal_handle->lib_handle->vftabl.set_master_key(kcontext, pwd, key);
12224960Swillf get_errmsg(kcontext, status);
12234960Swillf
12244960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
12254960Swillf
12264960Swillf clean_n_exit:
12274960Swillf return status;
12284960Swillf }
12294960Swillf
12304960Swillf krb5_error_code
krb5_db_set_mkey(krb5_context context,krb5_keyblock * key)12314960Swillf krb5_db_set_mkey(krb5_context context, krb5_keyblock * key)
12324960Swillf {
12334960Swillf return krb5_db_set_master_key_ext(context, NULL, key);
12344960Swillf }
12354960Swillf
12364960Swillf krb5_error_code
krb5_db_get_mkey(krb5_context kcontext,krb5_keyblock ** key)12374960Swillf krb5_db_get_mkey(krb5_context kcontext, krb5_keyblock ** key)
12384960Swillf {
12394960Swillf krb5_error_code status = 0;
12404960Swillf kdb5_dal_handle *dal_handle;
12414960Swillf
12424960Swillf if (kcontext->db_context == NULL) {
12434960Swillf status = kdb_setup_lib_handle(kcontext);
12444960Swillf if (status) {
12454960Swillf goto clean_n_exit;
12464960Swillf }
12474960Swillf }
12484960Swillf
12494960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
12504960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
12514960Swillf if (status) {
12524960Swillf goto clean_n_exit;
12534960Swillf }
12544960Swillf
12554960Swillf /* Lets use temp key and copy it later to avoid memory problems
12564960Swillf when freed by the caller. */
12574960Swillf status = dal_handle->lib_handle->vftabl.get_master_key(kcontext, key);
12584960Swillf get_errmsg(kcontext, status);
12594960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
12604960Swillf
12614960Swillf clean_n_exit:
12624960Swillf return status;
12634960Swillf }
12644960Swillf
12654960Swillf krb5_error_code
krb5_db_store_master_key(krb5_context kcontext,char * db_arg,krb5_principal mname,krb5_keyblock * key,char * master_pwd)12664960Swillf krb5_db_store_master_key(krb5_context kcontext,
12674960Swillf char *db_arg,
12684960Swillf krb5_principal mname,
12694960Swillf krb5_keyblock * key, char *master_pwd)
12704960Swillf {
12714960Swillf krb5_error_code status = 0;
12724960Swillf kdb5_dal_handle *dal_handle;
12734960Swillf
12744960Swillf if (kcontext->db_context == NULL) {
12754960Swillf status = kdb_setup_lib_handle(kcontext);
12764960Swillf if (status) {
12774960Swillf goto clean_n_exit;
12784960Swillf }
12794960Swillf }
12804960Swillf
12814960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
12824960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
12834960Swillf if (status) {
12844960Swillf goto clean_n_exit;
12854960Swillf }
12864960Swillf
12874960Swillf status = dal_handle->lib_handle->vftabl.store_master_key(kcontext,
12884960Swillf db_arg,
12894960Swillf mname,
12904960Swillf key, master_pwd);
12914960Swillf get_errmsg(kcontext, status);
12924960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
12934960Swillf
12944960Swillf clean_n_exit:
12954960Swillf return status;
12964960Swillf }
12974960Swillf
12984960Swillf char *krb5_mkey_pwd_prompt1 = KRB5_KDC_MKEY_1;
12994960Swillf char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2;
13004960Swillf
13014960Swillf krb5_error_code
krb5_db_fetch_mkey(krb5_context context,krb5_principal mname,krb5_enctype etype,krb5_boolean fromkeyboard,krb5_boolean twice,char * db_args,krb5_data * salt,krb5_keyblock * key)13024960Swillf krb5_db_fetch_mkey(krb5_context context,
13034960Swillf krb5_principal mname,
13044960Swillf krb5_enctype etype,
13054960Swillf krb5_boolean fromkeyboard,
13064960Swillf krb5_boolean twice,
13074960Swillf char *db_args, krb5_data * salt, krb5_keyblock * key)
13084960Swillf {
13094960Swillf krb5_error_code retval;
13104960Swillf char password[BUFSIZ];
13114960Swillf krb5_data pwd;
13124960Swillf unsigned int size = sizeof(password);
13134960Swillf int kvno;
13144960Swillf krb5_keyblock tmp_key;
13154960Swillf
13164960Swillf memset(&tmp_key, 0, sizeof(tmp_key));
13174960Swillf
13184960Swillf if (fromkeyboard) {
13194960Swillf krb5_data scratch;
13204960Swillf
13214960Swillf if ((retval = krb5_read_password(context, krb5_mkey_pwd_prompt1,
13224960Swillf twice ? krb5_mkey_pwd_prompt2 : 0,
13234960Swillf password, &size))) {
13244960Swillf goto clean_n_exit;
13254960Swillf }
13264960Swillf
13274960Swillf pwd.data = password;
13284960Swillf pwd.length = size;
13294960Swillf if (!salt) {
13304960Swillf retval = krb5_principal2salt(context, mname, &scratch);
13314960Swillf if (retval)
13324960Swillf goto clean_n_exit;
13334960Swillf }
13344960Swillf retval =
13354960Swillf krb5_c_string_to_key(context, etype, &pwd, salt ? salt : &scratch,
13364960Swillf key);
13374960Swillf
13384960Swillf if (!salt)
13394960Swillf krb5_xfree(scratch.data);
13404960Swillf memset(password, 0, sizeof(password)); /* erase it */
13414960Swillf
13424960Swillf } else {
13434960Swillf kdb5_dal_handle *dal_handle;
13444960Swillf
13454960Swillf if (context->db_context == NULL) {
13464960Swillf retval = kdb_setup_lib_handle(context);
13474960Swillf if (retval) {
13484960Swillf goto clean_n_exit;
13494960Swillf }
13504960Swillf }
13514960Swillf
13524960Swillf dal_handle = (kdb5_dal_handle *) context->db_context;
13534960Swillf retval = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
13544960Swillf if (retval) {
13554960Swillf goto clean_n_exit;
13564960Swillf }
13574960Swillf #if 0 /************** Begin IFDEF'ed OUT *******************************/
13584960Swillf /* Orig MIT */
13594960Swillf tmp_key.enctype = key->enctype;
13604960Swillf #else
13614960Swillf /* Solaris Kerberos: need to use etype */
13624960Swillf tmp_key.enctype = etype;
13634960Swillf #endif /**************** END IFDEF'ed OUT *******************************/
13644960Swillf retval = dal_handle->lib_handle->vftabl.fetch_master_key(context,
13654960Swillf mname,
13664960Swillf &tmp_key,
13674960Swillf &kvno,
13684960Swillf db_args);
13694960Swillf get_errmsg(context, retval);
13704960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
13714960Swillf
13724960Swillf if (retval) {
13734960Swillf goto clean_n_exit;
13744960Swillf }
13754960Swillf
13764960Swillf key->contents = malloc(tmp_key.length);
13774960Swillf if (key->contents == NULL) {
13784960Swillf retval = ENOMEM;
13794960Swillf goto clean_n_exit;
13804960Swillf }
13814960Swillf
13824960Swillf key->magic = tmp_key.magic;
13834960Swillf key->enctype = tmp_key.enctype;
13844960Swillf key->length = tmp_key.length;
13854960Swillf memcpy(key->contents, tmp_key.contents, tmp_key.length);
13864960Swillf }
13874960Swillf
13884960Swillf clean_n_exit:
13894960Swillf if (tmp_key.contents) {
13904960Swillf memset(tmp_key.contents, 0, tmp_key.length);
13914960Swillf krb5_db_free(context, tmp_key.contents);
13924960Swillf }
13934960Swillf return retval;
13944960Swillf }
13954960Swillf
13964960Swillf krb5_error_code
krb5_db_verify_master_key(krb5_context kcontext,krb5_principal mprinc,krb5_keyblock * mkey)13974960Swillf krb5_db_verify_master_key(krb5_context kcontext,
13984960Swillf krb5_principal mprinc, krb5_keyblock * mkey)
13994960Swillf {
14004960Swillf krb5_error_code status = 0;
14014960Swillf kdb5_dal_handle *dal_handle;
14024960Swillf
14034960Swillf if (kcontext->db_context == NULL) {
14044960Swillf status = kdb_setup_lib_handle(kcontext);
14054960Swillf if (status) {
14064960Swillf goto clean_n_exit;
14074960Swillf }
14084960Swillf }
14094960Swillf
14104960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
14114960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
14124960Swillf if (status) {
14134960Swillf goto clean_n_exit;
14144960Swillf }
14154960Swillf
14164960Swillf status = dal_handle->lib_handle->vftabl.verify_master_key(kcontext,
14174960Swillf mprinc, mkey);
14184960Swillf get_errmsg(kcontext, status);
14194960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
14204960Swillf
14214960Swillf clean_n_exit:
14224960Swillf return status;
14234960Swillf }
14244960Swillf
14254960Swillf void *
krb5_db_alloc(krb5_context kcontext,void * ptr,size_t size)14264960Swillf krb5_db_alloc(krb5_context kcontext, void *ptr, size_t size)
14274960Swillf {
14284960Swillf krb5_error_code status;
14294960Swillf kdb5_dal_handle *dal_handle;
14304960Swillf void *new_ptr = NULL;
14314960Swillf
14324960Swillf if (kcontext->db_context == NULL) {
14334960Swillf status = kdb_setup_lib_handle(kcontext);
14344960Swillf if (status) {
14354960Swillf goto clean_n_exit;
14364960Swillf }
14374960Swillf }
14384960Swillf
14394960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
14404960Swillf
14414960Swillf new_ptr = dal_handle->lib_handle->vftabl.db_alloc(kcontext, ptr, size);
14424960Swillf
14434960Swillf clean_n_exit:
14444960Swillf return new_ptr;
14454960Swillf }
14464960Swillf
14474960Swillf void
krb5_db_free(krb5_context kcontext,void * ptr)14484960Swillf krb5_db_free(krb5_context kcontext, void *ptr)
14494960Swillf {
14504960Swillf krb5_error_code status;
14514960Swillf kdb5_dal_handle *dal_handle;
14524960Swillf
14534960Swillf if (kcontext->db_context == NULL) {
14544960Swillf status = kdb_setup_lib_handle(kcontext);
14554960Swillf if (status) {
14564960Swillf goto clean_n_exit;
14574960Swillf }
14584960Swillf }
14594960Swillf
14604960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
14614960Swillf
14624960Swillf dal_handle->lib_handle->vftabl.db_free(kcontext, ptr);
14634960Swillf
14644960Swillf clean_n_exit:
14654960Swillf return;
14664960Swillf }
14674960Swillf
14684960Swillf /* has to be modified */
14694960Swillf
14704960Swillf krb5_error_code
krb5_dbe_find_enctype(krb5_context kcontext,krb5_db_entry * dbentp,krb5_int32 ktype,krb5_int32 stype,krb5_int32 kvno,krb5_key_data ** kdatap)14714960Swillf krb5_dbe_find_enctype(krb5_context kcontext,
14724960Swillf krb5_db_entry * dbentp,
14734960Swillf krb5_int32 ktype,
14744960Swillf krb5_int32 stype,
14754960Swillf krb5_int32 kvno, krb5_key_data ** kdatap)
14764960Swillf {
14774960Swillf krb5_int32 start = 0;
14784960Swillf return krb5_dbe_search_enctype(kcontext, dbentp, &start, ktype, stype,
14794960Swillf kvno, kdatap);
14804960Swillf }
14814960Swillf
14824960Swillf krb5_error_code
krb5_dbe_search_enctype(krb5_context kcontext,krb5_db_entry * dbentp,krb5_int32 * start,krb5_int32 ktype,krb5_int32 stype,krb5_int32 kvno,krb5_key_data ** kdatap)14834960Swillf krb5_dbe_search_enctype(krb5_context kcontext,
14844960Swillf krb5_db_entry * dbentp,
14854960Swillf krb5_int32 * start,
14864960Swillf krb5_int32 ktype,
14874960Swillf krb5_int32 stype,
14884960Swillf krb5_int32 kvno, krb5_key_data ** kdatap)
14894960Swillf {
14904960Swillf krb5_error_code status = 0;
14914960Swillf kdb5_dal_handle *dal_handle;
14924960Swillf
14934960Swillf if (kcontext->db_context == NULL) {
14944960Swillf status = kdb_setup_lib_handle(kcontext);
14954960Swillf if (status) {
14964960Swillf goto clean_n_exit;
14974960Swillf }
14984960Swillf }
14994960Swillf
15004960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
15014960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
15024960Swillf if (status) {
15034960Swillf goto clean_n_exit;
15044960Swillf }
15054960Swillf
15064960Swillf status = dal_handle->lib_handle->vftabl.dbe_search_enctype(kcontext,
15074960Swillf dbentp,
15084960Swillf start,
15094960Swillf ktype,
15104960Swillf stype,
15114960Swillf kvno, kdatap);
15124960Swillf get_errmsg(kcontext, status);
15134960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
15144960Swillf
15154960Swillf clean_n_exit:
15164960Swillf return status;
15174960Swillf }
15184960Swillf
15194960Swillf #define REALM_SEP_STRING "@"
15204960Swillf
15214960Swillf krb5_error_code
krb5_db_setup_mkey_name(krb5_context context,const char * keyname,const char * realm,char ** fullname,krb5_principal * principal)15224960Swillf krb5_db_setup_mkey_name(krb5_context context,
15234960Swillf const char *keyname,
15244960Swillf const char *realm,
15254960Swillf char **fullname, krb5_principal * principal)
15264960Swillf {
15274960Swillf krb5_error_code retval;
15284960Swillf size_t keylen;
15294960Swillf size_t rlen = strlen(realm);
15304960Swillf char *fname;
15314960Swillf
15324960Swillf if (!keyname)
15334960Swillf keyname = KRB5_KDB_M_NAME; /* XXX external? */
15344960Swillf
15354960Swillf keylen = strlen(keyname);
15364960Swillf
15374960Swillf fname = malloc(keylen + rlen + strlen(REALM_SEP_STRING) + 1);
15384960Swillf if (!fname)
15394960Swillf return ENOMEM;
15404960Swillf
15414960Swillf strcpy(fname, keyname);
15424960Swillf (void)strcat(fname, REALM_SEP_STRING);
15434960Swillf (void)strcat(fname, realm);
15444960Swillf
15454960Swillf if ((retval = krb5_parse_name(context, fname, principal)))
15464960Swillf return retval;
15474960Swillf if (fullname)
15484960Swillf *fullname = fname;
15494960Swillf else
15504960Swillf free(fname);
15514960Swillf return 0;
15524960Swillf }
15534960Swillf
15544960Swillf krb5_error_code
krb5_dbe_lookup_last_pwd_change(context,entry,stamp)15554960Swillf krb5_dbe_lookup_last_pwd_change(context, entry, stamp)
15564960Swillf krb5_context context;
15574960Swillf krb5_db_entry *entry;
15584960Swillf krb5_timestamp *stamp;
15594960Swillf {
15604960Swillf krb5_tl_data tl_data;
15614960Swillf krb5_error_code code;
15624960Swillf krb5_int32 tmp;
15634960Swillf
15644960Swillf tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
15654960Swillf
15664960Swillf if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
15674960Swillf return (code);
15684960Swillf
15694960Swillf if (tl_data.tl_data_length != 4) {
15704960Swillf *stamp = 0;
15714960Swillf return (0);
15724960Swillf }
15734960Swillf
15744960Swillf krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp);
15754960Swillf
15764960Swillf *stamp = (krb5_timestamp) tmp;
15774960Swillf
15784960Swillf return (0);
15794960Swillf }
15804960Swillf
15814960Swillf /*ARGSUSED*/
15824960Swillf krb5_error_code
krb5_dbe_lookup_tl_data(context,entry,ret_tl_data)15834960Swillf krb5_dbe_lookup_tl_data(context, entry, ret_tl_data)
15844960Swillf krb5_context context;
15854960Swillf krb5_db_entry *entry;
15864960Swillf krb5_tl_data *ret_tl_data;
15874960Swillf {
15884960Swillf krb5_tl_data *tl_data;
15894960Swillf
15904960Swillf for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
15914960Swillf if (tl_data->tl_data_type == ret_tl_data->tl_data_type) {
15924960Swillf *ret_tl_data = *tl_data;
15934960Swillf return (0);
15944960Swillf }
15954960Swillf }
15964960Swillf
15974960Swillf /* if the requested record isn't found, return zero bytes.
15984960Swillf * if it ever means something to have a zero-length tl_data,
15994960Swillf * this code and its callers will have to be changed */
16004960Swillf
16014960Swillf ret_tl_data->tl_data_length = 0;
16024960Swillf ret_tl_data->tl_data_contents = NULL;
16034960Swillf return (0);
16044960Swillf }
16054960Swillf
16064960Swillf krb5_error_code
krb5_dbe_create_key_data(context,entry)16074960Swillf krb5_dbe_create_key_data(context, entry)
16084960Swillf krb5_context context;
16094960Swillf krb5_db_entry *entry;
16104960Swillf {
16114960Swillf if ((entry->key_data =
16124960Swillf (krb5_key_data *) krb5_db_alloc(context, entry->key_data,
16134960Swillf (sizeof(krb5_key_data) *
16144960Swillf (entry->n_key_data + 1)))) == NULL)
16154960Swillf return (ENOMEM);
16164960Swillf
16174960Swillf memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data));
16184960Swillf entry->n_key_data++;
16194960Swillf
16204960Swillf return 0;
16214960Swillf }
16224960Swillf
16234960Swillf krb5_error_code
krb5_dbe_update_mod_princ_data(context,entry,mod_date,mod_princ)16244960Swillf krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ)
16254960Swillf krb5_context context;
16264960Swillf krb5_db_entry *entry;
16274960Swillf krb5_timestamp mod_date;
16284960Swillf krb5_const_principal mod_princ;
16294960Swillf {
16304960Swillf krb5_tl_data tl_data;
16314960Swillf
16324960Swillf krb5_error_code retval = 0;
16334960Swillf krb5_octet *nextloc = 0;
16344960Swillf char *unparse_mod_princ = 0;
16354960Swillf unsigned int unparse_mod_princ_size;
16364960Swillf
16374960Swillf if ((retval = krb5_unparse_name(context, mod_princ, &unparse_mod_princ)))
16384960Swillf return (retval);
16394960Swillf
16404960Swillf unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
16414960Swillf
16424960Swillf if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
16434960Swillf == NULL) {
16444960Swillf free(unparse_mod_princ);
16454960Swillf return (ENOMEM);
16464960Swillf }
16474960Swillf
16484960Swillf tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
16494960Swillf tl_data.tl_data_length = unparse_mod_princ_size + 4;
16504960Swillf tl_data.tl_data_contents = nextloc;
16514960Swillf
16524960Swillf /* Mod Date */
16534960Swillf krb5_kdb_encode_int32(mod_date, nextloc);
16544960Swillf
16554960Swillf /* Mod Princ */
16564960Swillf memcpy(nextloc + 4, unparse_mod_princ, unparse_mod_princ_size);
16574960Swillf
16584960Swillf retval = krb5_dbe_update_tl_data(context, entry, &tl_data);
16594960Swillf
16604960Swillf free(unparse_mod_princ);
16614960Swillf free(nextloc);
16624960Swillf
16634960Swillf return (retval);
16644960Swillf }
16654960Swillf
16664960Swillf krb5_error_code
krb5_dbe_lookup_mod_princ_data(context,entry,mod_time,mod_princ)16674960Swillf krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ)
16684960Swillf krb5_context context;
16694960Swillf krb5_db_entry *entry;
16704960Swillf krb5_timestamp *mod_time;
16714960Swillf krb5_principal *mod_princ;
16724960Swillf {
16734960Swillf krb5_tl_data tl_data;
16744960Swillf krb5_error_code code;
16754960Swillf
16764960Swillf tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
16774960Swillf
16784960Swillf if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
16794960Swillf return (code);
16804960Swillf
16814960Swillf if ((tl_data.tl_data_length < 5) ||
16824960Swillf (tl_data.tl_data_contents[tl_data.tl_data_length - 1] != '\0'))
16834960Swillf return (KRB5_KDB_TRUNCATED_RECORD);
16844960Swillf
16854960Swillf /* Mod Date */
16864960Swillf krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time);
16874960Swillf
16884960Swillf /* Mod Princ */
16894960Swillf if ((code = krb5_parse_name(context,
16904960Swillf (const char *) (tl_data.tl_data_contents + 4),
16914960Swillf mod_princ)))
16924960Swillf return (code);
16934960Swillf
16944960Swillf return (0);
16954960Swillf }
16964960Swillf
16974960Swillf krb5_error_code
krb5_dbe_update_last_pwd_change(context,entry,stamp)16984960Swillf krb5_dbe_update_last_pwd_change(context, entry, stamp)
16994960Swillf krb5_context context;
17004960Swillf krb5_db_entry *entry;
17014960Swillf krb5_timestamp stamp;
17024960Swillf {
17034960Swillf krb5_tl_data tl_data;
17044960Swillf krb5_octet buf[4]; /* this is the encoded size of an int32 */
17054960Swillf
17064960Swillf tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
17074960Swillf tl_data.tl_data_length = sizeof(buf);
17084960Swillf krb5_kdb_encode_int32((krb5_int32) stamp, buf);
17094960Swillf tl_data.tl_data_contents = buf;
17104960Swillf
17114960Swillf return (krb5_dbe_update_tl_data(context, entry, &tl_data));
17124960Swillf }
17134960Swillf
17144960Swillf krb5_error_code
krb5_dbe_update_tl_data(context,entry,new_tl_data)17154960Swillf krb5_dbe_update_tl_data(context, entry, new_tl_data)
17164960Swillf krb5_context context;
17174960Swillf krb5_db_entry *entry;
17184960Swillf krb5_tl_data *new_tl_data;
17194960Swillf {
17204960Swillf krb5_tl_data *tl_data = NULL;
17214960Swillf krb5_octet *tmp;
17224960Swillf
17234960Swillf /* copy the new data first, so we can fail cleanly if malloc()
17244960Swillf * fails */
17254960Swillf if ((tmp =
17264960Swillf (krb5_octet *) krb5_db_alloc(context, NULL,
17274960Swillf new_tl_data->tl_data_length)) == NULL)
17284960Swillf return (ENOMEM);
17294960Swillf
17304960Swillf /* Find an existing entry of the specified type and point at
17314960Swillf * it, or NULL if not found */
17324960Swillf
17334960Swillf if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) { /* db_args can be multiple */
17344960Swillf for (tl_data = entry->tl_data; tl_data;
17354960Swillf tl_data = tl_data->tl_data_next)
17364960Swillf if (tl_data->tl_data_type == new_tl_data->tl_data_type)
17374960Swillf break;
17384960Swillf }
17394960Swillf
17404960Swillf /* if necessary, chain a new record in the beginning and point at it */
17414960Swillf
17424960Swillf if (!tl_data) {
17434960Swillf if ((tl_data =
17444960Swillf (krb5_tl_data *) krb5_db_alloc(context, NULL,
17454960Swillf sizeof(krb5_tl_data)))
17464960Swillf == NULL) {
17474960Swillf free(tmp);
17484960Swillf return (ENOMEM);
17494960Swillf }
17504960Swillf memset(tl_data, 0, sizeof(krb5_tl_data));
17514960Swillf tl_data->tl_data_next = entry->tl_data;
17524960Swillf entry->tl_data = tl_data;
17534960Swillf entry->n_tl_data++;
17544960Swillf }
17554960Swillf
17564960Swillf /* fill in the record */
17574960Swillf
17584960Swillf if (tl_data->tl_data_contents)
17594960Swillf krb5_db_free(context, tl_data->tl_data_contents);
17604960Swillf
17614960Swillf tl_data->tl_data_type = new_tl_data->tl_data_type;
17624960Swillf tl_data->tl_data_length = new_tl_data->tl_data_length;
17634960Swillf tl_data->tl_data_contents = tmp;
17644960Swillf memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
17654960Swillf
17664960Swillf return (0);
17674960Swillf }
17684960Swillf
17694960Swillf /* change password functions */
17704960Swillf krb5_error_code
krb5_dbe_cpw(krb5_context kcontext,krb5_keyblock * master_key,krb5_key_salt_tuple * ks_tuple,int ks_tuple_count,char * passwd,int new_kvno,krb5_boolean keepold,krb5_db_entry * db_entry)17714960Swillf krb5_dbe_cpw(krb5_context kcontext,
17724960Swillf krb5_keyblock * master_key,
17734960Swillf krb5_key_salt_tuple * ks_tuple,
17744960Swillf int ks_tuple_count,
17754960Swillf char *passwd,
17764960Swillf int new_kvno, krb5_boolean keepold, krb5_db_entry * db_entry)
17774960Swillf {
17784960Swillf krb5_error_code status = 0;
17794960Swillf kdb5_dal_handle *dal_handle;
17804960Swillf
17814960Swillf if (kcontext->db_context == NULL) {
17824960Swillf status = kdb_setup_lib_handle(kcontext);
17834960Swillf if (status) {
17844960Swillf goto clean_n_exit;
17854960Swillf }
17864960Swillf }
17874960Swillf
17884960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
17894960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
17904960Swillf if (status) {
17914960Swillf goto clean_n_exit;
17924960Swillf }
17934960Swillf
17944960Swillf status = dal_handle->lib_handle->vftabl.db_change_pwd(kcontext,
17954960Swillf master_key,
17964960Swillf ks_tuple,
17974960Swillf ks_tuple_count,
17984960Swillf passwd,
17994960Swillf new_kvno,
18004960Swillf keepold, db_entry);
18014960Swillf get_errmsg(kcontext, status);
18024960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
18034960Swillf
18044960Swillf clean_n_exit:
18054960Swillf return status;
18064960Swillf }
18074960Swillf
18084960Swillf /* policy management functions */
18094960Swillf krb5_error_code
krb5_db_create_policy(krb5_context kcontext,osa_policy_ent_t policy)18104960Swillf krb5_db_create_policy(krb5_context kcontext, osa_policy_ent_t policy)
18114960Swillf {
18124960Swillf krb5_error_code status = 0;
18134960Swillf kdb5_dal_handle *dal_handle;
18144960Swillf
18154960Swillf if (kcontext->db_context == NULL) {
18164960Swillf status = kdb_setup_lib_handle(kcontext);
18174960Swillf if (status) {
18184960Swillf goto clean_n_exit;
18194960Swillf }
18204960Swillf }
18214960Swillf
18224960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
18234960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
18244960Swillf if (status) {
18254960Swillf goto clean_n_exit;
18264960Swillf }
18274960Swillf
18284960Swillf status = dal_handle->lib_handle->vftabl.db_create_policy(kcontext, policy);
18294960Swillf get_errmsg(kcontext, status);
18304960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
18314960Swillf
18324960Swillf clean_n_exit:
18334960Swillf return status;
18344960Swillf }
18354960Swillf
18364960Swillf krb5_error_code
krb5_db_get_policy(krb5_context kcontext,char * name,osa_policy_ent_t * policy,int * cnt)18374960Swillf krb5_db_get_policy(krb5_context kcontext, char *name,
18384960Swillf osa_policy_ent_t * policy, int *cnt)
18394960Swillf {
18404960Swillf krb5_error_code status = 0;
18414960Swillf kdb5_dal_handle *dal_handle;
18424960Swillf
18434960Swillf if (kcontext->db_context == NULL) {
18444960Swillf status = kdb_setup_lib_handle(kcontext);
18454960Swillf if (status) {
18464960Swillf goto clean_n_exit;
18474960Swillf }
18484960Swillf }
18494960Swillf
18504960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
18514960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
18524960Swillf if (status) {
18534960Swillf goto clean_n_exit;
18544960Swillf }
18554960Swillf
18564960Swillf status =
18574960Swillf dal_handle->lib_handle->vftabl.db_get_policy(kcontext, name, policy,
18584960Swillf cnt);
18594960Swillf get_errmsg(kcontext, status);
18604960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
18614960Swillf
18624960Swillf clean_n_exit:
18634960Swillf return status;
18644960Swillf }
18654960Swillf
18664960Swillf krb5_error_code
krb5_db_put_policy(krb5_context kcontext,osa_policy_ent_t policy)18674960Swillf krb5_db_put_policy(krb5_context kcontext, osa_policy_ent_t policy)
18684960Swillf {
18694960Swillf krb5_error_code status = 0;
18704960Swillf kdb5_dal_handle *dal_handle;
18714960Swillf
18724960Swillf if (kcontext->db_context == NULL) {
18734960Swillf status = kdb_setup_lib_handle(kcontext);
18744960Swillf if (status) {
18754960Swillf goto clean_n_exit;
18764960Swillf }
18774960Swillf }
18784960Swillf
18794960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
18804960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
18814960Swillf if (status) {
18824960Swillf goto clean_n_exit;
18834960Swillf }
18844960Swillf
18854960Swillf status = dal_handle->lib_handle->vftabl.db_put_policy(kcontext, policy);
18864960Swillf get_errmsg(kcontext, status);
18874960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
18884960Swillf
18894960Swillf clean_n_exit:
18904960Swillf return status;
18914960Swillf }
18924960Swillf
18934960Swillf krb5_error_code
krb5_db_iter_policy(krb5_context kcontext,char * match_entry,osa_adb_iter_policy_func func,void * data)18944960Swillf krb5_db_iter_policy(krb5_context kcontext, char *match_entry,
18954960Swillf osa_adb_iter_policy_func func, void *data)
18964960Swillf {
18974960Swillf krb5_error_code status = 0;
18984960Swillf kdb5_dal_handle *dal_handle;
18994960Swillf
19004960Swillf if (kcontext->db_context == NULL) {
19014960Swillf status = kdb_setup_lib_handle(kcontext);
19024960Swillf if (status) {
19034960Swillf goto clean_n_exit;
19044960Swillf }
19054960Swillf }
19064960Swillf
19074960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
19084960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
19094960Swillf if (status) {
19104960Swillf goto clean_n_exit;
19114960Swillf }
19124960Swillf
19134960Swillf status =
19144960Swillf dal_handle->lib_handle->vftabl.db_iter_policy(kcontext, match_entry,
19154960Swillf func, data);
19164960Swillf get_errmsg(kcontext, status);
19174960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
19184960Swillf
19194960Swillf clean_n_exit:
19204960Swillf return status;
19214960Swillf }
19224960Swillf
19234960Swillf krb5_error_code
krb5_db_delete_policy(krb5_context kcontext,char * policy)19244960Swillf krb5_db_delete_policy(krb5_context kcontext, char *policy)
19254960Swillf {
19264960Swillf krb5_error_code status = 0;
19274960Swillf kdb5_dal_handle *dal_handle;
19284960Swillf
19294960Swillf if (kcontext->db_context == NULL) {
19304960Swillf status = kdb_setup_lib_handle(kcontext);
19314960Swillf if (status) {
19324960Swillf goto clean_n_exit;
19334960Swillf }
19344960Swillf }
19354960Swillf
19364960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
19374960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
19384960Swillf if (status) {
19394960Swillf goto clean_n_exit;
19404960Swillf }
19414960Swillf
19424960Swillf status = dal_handle->lib_handle->vftabl.db_delete_policy(kcontext, policy);
19434960Swillf get_errmsg(kcontext, status);
19444960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
19454960Swillf
19464960Swillf clean_n_exit:
19474960Swillf return status;
19484960Swillf }
19494960Swillf
19504960Swillf void
krb5_db_free_policy(krb5_context kcontext,osa_policy_ent_t policy)19514960Swillf krb5_db_free_policy(krb5_context kcontext, osa_policy_ent_t policy)
19524960Swillf {
19534960Swillf krb5_error_code status = 0;
19544960Swillf kdb5_dal_handle *dal_handle;
19554960Swillf
19564960Swillf if (kcontext->db_context == NULL) {
19574960Swillf status = kdb_setup_lib_handle(kcontext);
19584960Swillf if (status) {
19594960Swillf goto clean_n_exit;
19604960Swillf }
19614960Swillf }
19624960Swillf
19634960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
19644960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
19654960Swillf if (status) {
19664960Swillf goto clean_n_exit;
19674960Swillf }
19684960Swillf
19694960Swillf dal_handle->lib_handle->vftabl.db_free_policy(kcontext, policy);
19704960Swillf get_errmsg(kcontext, status);
19714960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
19724960Swillf
19734960Swillf clean_n_exit:
19744960Swillf return;
19754960Swillf }
19764960Swillf
19774960Swillf krb5_error_code
krb5_db_promote(krb5_context kcontext,char ** db_args)19784960Swillf krb5_db_promote(krb5_context kcontext, char **db_args)
19794960Swillf {
19804960Swillf krb5_error_code status = 0;
19814960Swillf char *section = NULL;
19824960Swillf kdb5_dal_handle *dal_handle;
19834960Swillf
19844960Swillf section = kdb_get_conf_section(kcontext);
19854960Swillf if (section == NULL) {
19864960Swillf status = KRB5_KDB_SERVER_INTERNAL_ERR;
19874960Swillf krb5_set_error_message (kcontext, status,
19884960Swillf gettext("unable to determine configuration section for realm %s\n"),
19894960Swillf kcontext->default_realm);
19904960Swillf goto clean_n_exit;
19914960Swillf }
19924960Swillf
19934960Swillf if (kcontext->db_context == NULL) {
19944960Swillf status = kdb_setup_lib_handle(kcontext);
19954960Swillf if (status) {
19964960Swillf goto clean_n_exit;
19974960Swillf }
19984960Swillf }
19994960Swillf
20004960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
20014960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
20024960Swillf if (status) {
20034960Swillf goto clean_n_exit;
20044960Swillf }
20054960Swillf
20064960Swillf status =
20074960Swillf dal_handle->lib_handle->vftabl.promote_db(kcontext, section, db_args);
20084960Swillf get_errmsg(kcontext, status);
20094960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
20104960Swillf
20114960Swillf clean_n_exit:
20124960Swillf if (section)
20134960Swillf free(section);
20144960Swillf return status;
20154960Swillf }
20164960Swillf
20174960Swillf /*
20184960Swillf * Solaris Kerberos: support for iprop
20194960Swillf *
20204960Swillf * Not all KDB plugins support iprop.
20214960Swillf *
20224960Swillf * sets iprop_supported to 1 if iprop supportd, 0 otherwise.
20234960Swillf */
20244960Swillf krb5_error_code
krb5_db_supports_iprop(krb5_context kcontext,int * iprop_supported)20254960Swillf krb5_db_supports_iprop(krb5_context kcontext, int *iprop_supported)
20264960Swillf {
20274960Swillf krb5_error_code status = 0;
20284960Swillf kdb5_dal_handle *dal_handle;
20294960Swillf
20304960Swillf if (kcontext->db_context == NULL) {
20314960Swillf status = kdb_setup_lib_handle(kcontext);
20324960Swillf if (status) {
20334960Swillf goto clean_n_exit;
20344960Swillf }
20354960Swillf }
20364960Swillf
20374960Swillf dal_handle = (kdb5_dal_handle *) kcontext->db_context;
20384960Swillf status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
20394960Swillf if (status) {
20404960Swillf goto clean_n_exit;
20414960Swillf }
20424960Swillf
20434960Swillf *iprop_supported = dal_handle->lib_handle->vftabl.iprop_supported;
20444960Swillf kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
20454960Swillf
20464960Swillf clean_n_exit:
20474960Swillf return status;
20484960Swillf }
2049