2 * Copyright 2006, 2009 by the Massachusetts Institute of Technology.
5 * Export of this software from the United States of America may
6 * require a specific license from the United States Government.
7 * It is the responsibility of any person or organization contemplating
8 * export to obtain such a license before exporting.
10 * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
11 * distribute this software and its documentation for any purpose and
12 * without fee is hereby granted, provided that the above copyright
13 * notice appear in all copies and that both that copyright notice and
14 * this permission notice appear in supporting documentation, and that
15 * the name of M.I.T. not be used in advertising or publicity pertaining
16 * to distribution of the software without specific, written prior
17 * permission. Furthermore if you modify this software you must label
18 * your software as modified software and not distribute it in such a
19 * fashion that it might be confused with the original M.I.T. software.
20 * M.I.T. makes no representations about the suitability of
21 * this software for any purpose. It is provided "as is" without express
22 * or implied warranty.
26 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
27 * Use is subject to license terms.
31 * This code was based on code donated to MIT by Novell for
32 * distribution under the MIT license.
48 /* Currently DB2 policy related errors are exported from DAL. But
49 other databases should set_err function to return string. */
55 #define KRB5_TL_DB_ARGS 0x7fff
58 * internal static variable
61 static k5_mutex_t db_lock = K5_MUTEX_PARTIAL_INITIALIZER;
63 #ifdef _KDB5_STATIC_LINK
64 #undef _KDB5_DYNAMIC_LINK
66 #undef _KDB5_DYNAMIC_LINK
67 /* to avoid redefinition problem */
68 #define _KDB5_DYNAMIC_LINK
71 static db_library lib_list;
77 MAKE_INIT_FUNCTION(kdb_init_lock_list);
78 MAKE_FINI_FUNCTION(kdb_fini_lock_list);
81 kdb_init_lock_list(void)
83 return k5_mutex_finish_init(&db_lock);
90 err = CALL_INIT_FUNCTION (kdb_init_lock_list);
93 return k5_mutex_lock(&db_lock);
97 kdb_fini_lock_list(void)
99 if (INITIALIZER_RAN(kdb_init_lock_list))
100 k5_mutex_destroy(&db_lock);
106 return k5_mutex_unlock(&db_lock);
110 * XXX eventually this should be consolidated with krb5_free_key_data_contents
111 * so there is only a single version.
114 krb5_dbe_free_key_data_contents(krb5_context context, krb5_key_data *key)
119 idx = (key->key_data_ver == 1 ? 1 : 2);
120 for (i = 0; i < idx; i++) {
121 if (key->key_data_contents[i]) {
122 zap(key->key_data_contents[i], key->key_data_length[i]);
123 free(key->key_data_contents[i]);
131 krb5_dbe_free_key_list(krb5_context context, krb5_keylist_node *val)
133 krb5_keylist_node *temp = val, *prev;
135 while (temp != NULL) {
138 krb5_free_keyblock_contents(context, &(prev->keyblock));
144 krb5_dbe_free_actkvno_list(krb5_context context, krb5_actkvno_node *val)
146 krb5_actkvno_node *temp = val, *prev;
148 while (temp != NULL) {
156 krb5_dbe_free_mkey_aux_list(krb5_context context, krb5_mkey_aux_node *val)
158 krb5_mkey_aux_node *temp = val, *prev;
160 while (temp != NULL) {
163 krb5_dbe_free_key_data_contents(context, &prev->latest_mkey);
169 krb5_dbe_free_tl_data(krb5_context context, krb5_tl_data *tl_data)
172 if (tl_data->tl_data_contents)
173 free(tl_data->tl_data_contents);
178 #define kdb_init_lib_lock(a) 0
179 #define kdb_destroy_lib_lock(a) (void)0
180 #define kdb_lock_lib_lock(a, b) 0
181 #define kdb_unlock_lib_lock(a, b) (void)0
183 /* Caller must free result*/
186 kdb_get_conf_section(krb5_context kcontext)
188 krb5_error_code status = 0;
192 if (kcontext->default_realm == NULL)
194 /* The profile has to have been initialized. If the profile was
195 not initialized, expect nothing less than a crash. */
196 status = profile_get_string(kcontext->profile,
199 kcontext->default_realm,
200 /* under the realm name, database_module */
202 /* default value is the realm name itself */
203 kcontext->default_realm,
208 result = strdup(kcontext->default_realm);
209 /* let NULL be handled by the caller */
211 result = strdup(value);
212 /* free profile string */
213 profile_release_string(value);
220 kdb_get_library_name(krb5_context kcontext)
222 krb5_error_code status = 0;
227 status = profile_get_string(kcontext->profile,
230 kcontext->default_realm,
231 /* under the realm name, database_module */
233 /* default value is the realm name itself */
234 kcontext->default_realm,
240 #define DB2_NAME "db2"
241 /* we got the module section. Get the library name from the module */
242 status = profile_get_string(kcontext->profile, KDB_MODULE_SECTION, value,
252 result = strdup(lib);
255 /* free profile string */
256 profile_release_string(value);
260 /* free profile string */
261 profile_release_string(lib);
267 kdb_setup_opt_functions(db_library lib)
269 if (lib->vftabl.set_master_key == NULL) {
270 lib->vftabl.set_master_key = kdb_def_set_mkey;
273 if (lib->vftabl.set_master_key_list == NULL) {
274 lib->vftabl.set_master_key_list = kdb_def_set_mkey_list;
277 if (lib->vftabl.get_master_key == NULL) {
278 lib->vftabl.get_master_key = kdb_def_get_mkey;
281 if (lib->vftabl.get_master_key_list == NULL) {
282 lib->vftabl.get_master_key_list = kdb_def_get_mkey_list;
285 if (lib->vftabl.fetch_master_key == NULL) {
286 lib->vftabl.fetch_master_key = krb5_db_def_fetch_mkey;
289 if (lib->vftabl.verify_master_key == NULL) {
290 lib->vftabl.verify_master_key = krb5_def_verify_master_key;
293 if (lib->vftabl.fetch_master_key_list == NULL) {
294 lib->vftabl.fetch_master_key_list = krb5_def_fetch_mkey_list;
297 if (lib->vftabl.store_master_key_list == NULL) {
298 lib->vftabl.store_master_key_list = krb5_def_store_mkey_list;
301 if (lib->vftabl.dbe_search_enctype == NULL) {
302 lib->vftabl.dbe_search_enctype = krb5_dbe_def_search_enctype;
305 if (lib->vftabl.db_change_pwd == NULL) {
306 lib->vftabl.db_change_pwd = krb5_dbe_def_cpw;
309 if (lib->vftabl.store_master_key == NULL) {
310 lib->vftabl.store_master_key = krb5_def_store_mkey;
313 if (lib->vftabl.promote_db == NULL) {
314 lib->vftabl.promote_db = krb5_def_promote_db;
317 if (lib->vftabl.dbekd_decrypt_key_data == NULL) {
318 lib->vftabl.dbekd_decrypt_key_data = krb5_dbekd_def_decrypt_key_data;
321 if (lib->vftabl.dbekd_encrypt_key_data == NULL) {
322 lib->vftabl.dbekd_encrypt_key_data = krb5_dbekd_def_encrypt_key_data;
326 static int kdb_db2_pol_err_loaded = 0;
327 #ifdef _KDB5_STATIC_LINK
328 #define DEF_SYMBOL(a) extern kdb_vftabl krb5_db_vftabl_ ## a
329 #define GET_SYMBOL(a) (krb5_db_vftabl_ ## a)
330 static krb5_error_code
331 kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib)
333 krb5_error_code status;
334 void *vftabl_addr = NULL;
335 char buf[KRB5_MAX_ERR_STR];
337 if (!strcmp("kdb_db2", lib_name) && (kdb_db2_pol_err_loaded == 0)) {
338 initialize_adb_error_table();
339 kdb_db2_pol_err_loaded = 1;
342 *lib = calloc((size_t) 1, sizeof(**lib));
348 status = kdb_init_lib_lock(*lib);
353 strlcpy((*lib)->name, lib_name, sizeof((*lib)->name));
355 #if !defined(KDB5_USE_LIB_KDB_DB2) && !defined(KDB5_USE_LIB_TEST)
356 #error No database module defined
359 #ifdef KDB5_USE_LIB_KDB_DB2
360 if (strcmp(lib_name, "kdb_db2") == 0) {
362 vftabl_addr = (void *) &GET_SYMBOL(kdb_db2);
365 #ifdef KDB5_USE_LIB_TEST
366 if (strcmp(lib_name, "test") == 0) {
368 vftabl_addr = (void *) &GET_SYMBOL(test);
372 snprintf(buf, sizeof(buf),
373 "Program not built to support %s database type\n",
375 status = KRB5_KDB_DBTYPE_NOSUP;
376 krb5_db_set_err(kcontext, krb5_err_have_str, status, buf);
380 memcpy(&(*lib)->vftabl, vftabl_addr, sizeof(kdb_vftabl));
382 kdb_setup_opt_functions(*lib);
384 if ((status = (*lib)->vftabl.init_library())) {
385 /* ERROR. library not initialized cleanly */
386 snprintf(buf, sizeof(buf),
387 "%s library initialization failed, error code %ld\n",
389 status = KRB5_KDB_DBTYPE_INIT;
390 krb5_db_set_err(kcontext, krb5_err_have_str, status, buf);
396 free(*lib), *lib = NULL;
401 #else /* KDB5_STATIC_LINK*/
403 static char *db_dl_location[] = DEFAULT_KDB_LIB_PATH;
404 #define db_dl_n_locations (sizeof(db_dl_location) / sizeof(db_dl_location[0]))
406 static krb5_error_code
407 kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib)
409 krb5_error_code status = 0;
411 void **vftabl_addrs = NULL;
412 /* N.B.: If this is "const" but not "static", the Solaris 10
413 native compiler has trouble building the library because of
414 absolute relocations needed in read-only section ".rodata".
415 When it's static, it goes into ".picdata", which is
417 static const char *const dbpath_names[] = {
418 KDB_MODULE_SECTION, KRB5_CONF_DB_MODULE_DIR, NULL,
420 const char *filebases[2];
421 char **profpath = NULL;
424 filebases[0] = lib_name;
427 if (!strcmp(DB2_NAME, lib_name) && (kdb_db2_pol_err_loaded == 0)) {
428 initialize_adb_error_table();
429 kdb_db2_pol_err_loaded = 1;
432 *lib = calloc((size_t) 1, sizeof(**lib));
438 status = kdb_init_lib_lock(*lib);
443 strlcpy((*lib)->name, lib_name, sizeof((*lib)->name));
445 /* Fetch the list of directories specified in the config
447 status = profile_get_values(kcontext->profile, dbpath_names, &profpath);
448 if (status != 0 && status != PROF_NO_RELATION)
452 while (profpath[ndx] != NULL)
455 path = calloc(ndx + db_dl_n_locations, sizeof (char *));
461 memcpy(path, profpath, ndx * sizeof(profpath[0]));
462 memcpy(path + ndx, db_dl_location, db_dl_n_locations * sizeof(char *));
465 if ((status = krb5int_open_plugin_dirs ((const char **) path,
467 &(*lib)->dl_dir_handle, &kcontext->err))) {
468 const char *err_str = krb5_get_error_message(kcontext, status);
469 status = KRB5_KDB_DBTYPE_NOTFOUND;
470 krb5_set_error_message (kcontext, status,
471 "Unable to find requested database type: %s", err_str);
472 krb5_free_error_message (kcontext, err_str);
476 if ((status = krb5int_get_plugin_dir_data (&(*lib)->dl_dir_handle, "kdb_function_table",
477 &vftabl_addrs, &kcontext->err))) {
478 const char *err_str = krb5_get_error_message(kcontext, status);
479 status = KRB5_KDB_DBTYPE_INIT;
480 krb5_set_error_message (kcontext, status,
481 "plugin symbol 'kdb_function_table' lookup failed: %s", err_str);
482 krb5_free_error_message (kcontext, err_str);
486 if (vftabl_addrs[0] == NULL) {
488 status = KRB5_KDB_DBTYPE_NOTFOUND;
489 krb5_set_error_message (kcontext, status,
490 _("Unable to load requested database module '%s': plugin symbol 'kdb_function_table' not found"),
495 memcpy(&(*lib)->vftabl, vftabl_addrs[0], sizeof(kdb_vftabl));
496 kdb_setup_opt_functions(*lib);
498 if ((status = (*lib)->vftabl.init_library())) {
499 /* ERROR. library not initialized cleanly */
504 if (vftabl_addrs != NULL) { krb5int_free_plugin_dir_data (vftabl_addrs); }
505 /* Both of these DTRT with NULL. */
506 profile_free_list(profpath);
510 kdb_destroy_lib_lock(*lib);
511 if (PLUGIN_DIR_OPEN((&(*lib)->dl_dir_handle))) {
512 krb5int_close_plugin_dirs (&(*lib)->dl_dir_handle);
521 #endif /* end of _KDB5_STATIC_LINK */
523 static krb5_error_code
524 kdb_find_library(krb5_context kcontext, char *lib_name, db_library * lib)
526 /* lock here so that no two threads try to do the same at the same time */
527 krb5_error_code status = 0;
529 db_library curr_elt, prev_elt = NULL;
531 if ((status = kdb_lock_list()) != 0) {
537 while (curr_elt != NULL) {
538 if (strcmp(lib_name, curr_elt->name) == 0) {
543 curr_elt = curr_elt->next;
546 /* module not found. create and add to list */
547 status = kdb_load_library(kcontext, lib_name, lib);
553 /* prev_elt points to the last element in the list */
554 prev_elt->next = *lib;
555 (*lib)->prev = prev_elt;
562 (*lib)->reference_cnt++;
572 static krb5_error_code
573 kdb_free_library(db_library lib)
575 krb5_error_code status = 0;
578 if ((status = kdb_lock_list()) != 0) {
583 lib->reference_cnt--;
585 if (lib->reference_cnt == 0) {
586 status = lib->vftabl.fini_library();
591 /* close the library */
592 if (PLUGIN_DIR_OPEN((&lib->dl_dir_handle))) {
593 krb5int_close_plugin_dirs (&lib->dl_dir_handle);
596 kdb_destroy_lib_lock(lib);
598 if (lib->prev == NULL) {
599 /* first element in the list */
600 lib_list = lib->next;
602 lib->prev->next = lib->next;
606 lib->next->prev = lib->prev;
619 static krb5_error_code
620 kdb_setup_lib_handle(krb5_context kcontext)
622 char *library = NULL;
623 krb5_error_code status = 0;
624 db_library lib = NULL;
625 kdb5_dal_handle *dal_handle = NULL;
627 dal_handle = calloc((size_t) 1, sizeof(kdb5_dal_handle));
628 if (dal_handle == NULL) {
633 library = kdb_get_library_name(kcontext);
634 if (library == NULL) {
635 status = KRB5_KDB_DBTYPE_NOTFOUND;
639 status = kdb_find_library(kcontext, library, &lib);
644 dal_handle->lib_handle = lib;
645 kcontext->dal_handle = dal_handle;
653 kdb_free_library(lib);
660 static krb5_error_code
661 kdb_free_lib_handle(krb5_context kcontext)
663 krb5_error_code status = 0;
665 status = kdb_free_library(kcontext->dal_handle->lib_handle);
670 free(kcontext->dal_handle);
671 kcontext->dal_handle = NULL;
678 get_errmsg (krb5_context kcontext, krb5_error_code err_code)
680 kdb5_dal_handle *dal_handle;
684 assert(kcontext != NULL);
685 /* Must be called with dal_handle->lib_handle locked! */
686 assert(kcontext->dal_handle != NULL);
687 dal_handle = kcontext->dal_handle;
688 if (dal_handle->lib_handle->vftabl.errcode_2_string == NULL)
690 e = dal_handle->lib_handle->vftabl.errcode_2_string(kcontext, err_code);
692 krb5_set_error_message(kcontext, err_code, "%s", e);
693 if (dal_handle->lib_handle->vftabl.release_errcode_string)
694 dal_handle->lib_handle->vftabl.release_errcode_string(kcontext, e);
698 * External functions... DAL API
701 krb5_db_open(krb5_context kcontext, char **db_args, int mode)
703 krb5_error_code status = 0;
704 char *section = NULL;
705 kdb5_dal_handle *dal_handle;
707 section = kdb_get_conf_section(kcontext);
708 if (section == NULL) {
709 status = KRB5_KDB_SERVER_INTERNAL_ERR;
710 krb5_set_error_message (kcontext, status,
711 "unable to determine configuration section for realm %s\n",
712 kcontext->default_realm ? kcontext->default_realm : "[UNSET]");
716 if (kcontext->dal_handle == NULL) {
717 status = kdb_setup_lib_handle(kcontext);
723 dal_handle = kcontext->dal_handle;
724 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
730 dal_handle->lib_handle->vftabl.init_module(kcontext, section, db_args,
732 get_errmsg(kcontext, status);
734 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
743 krb5_db_inited(krb5_context kcontext)
745 return !(kcontext && kcontext->dal_handle &&
746 kcontext->dal_handle->db_context);
750 krb5_db_create(krb5_context kcontext, char **db_args)
752 krb5_error_code status = 0;
753 char *section = NULL;
754 kdb5_dal_handle *dal_handle;
756 section = kdb_get_conf_section(kcontext);
757 if (section == NULL) {
758 status = KRB5_KDB_SERVER_INTERNAL_ERR;
759 krb5_set_error_message (kcontext, status,
760 "unable to determine configuration section for realm %s\n",
761 kcontext->default_realm);
765 if (kcontext->dal_handle == NULL) {
766 status = kdb_setup_lib_handle(kcontext);
772 dal_handle = kcontext->dal_handle;
773 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
779 dal_handle->lib_handle->vftabl.db_create(kcontext, section, db_args);
780 get_errmsg(kcontext, status);
782 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
791 krb5_db_fini(krb5_context kcontext)
793 krb5_error_code status = 0;
794 kdb5_dal_handle *dal_handle;
796 if (kcontext->dal_handle == NULL) {
797 /* module not loaded. So nothing to be done */
801 dal_handle = kcontext->dal_handle;
802 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
807 status = dal_handle->lib_handle->vftabl.fini_module(kcontext);
808 get_errmsg(kcontext, status);
810 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
816 status = kdb_free_lib_handle(kcontext);
823 krb5_db_destroy(krb5_context kcontext, char **db_args)
825 krb5_error_code status = 0;
826 char *section = NULL;
827 kdb5_dal_handle *dal_handle;
829 section = kdb_get_conf_section(kcontext);
830 if (section == NULL) {
831 status = KRB5_KDB_SERVER_INTERNAL_ERR;
832 krb5_set_error_message (kcontext, status,
833 "unable to determine configuration section for realm %s\n",
834 kcontext->default_realm);
838 if (kcontext->dal_handle == NULL) {
839 status = kdb_setup_lib_handle(kcontext);
845 dal_handle = kcontext->dal_handle;
846 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
852 dal_handle->lib_handle->vftabl.db_destroy(kcontext, section, db_args);
853 get_errmsg(kcontext, status);
854 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
863 krb5_db_get_age(krb5_context kcontext, char *db_name, time_t * t)
865 krb5_error_code status = 0;
866 kdb5_dal_handle *dal_handle;
868 if (kcontext->dal_handle == NULL) {
869 status = kdb_setup_lib_handle(kcontext);
875 dal_handle = kcontext->dal_handle;
876 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
881 status = dal_handle->lib_handle->vftabl.db_get_age(kcontext, db_name, t);
882 get_errmsg(kcontext, status);
883 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
890 krb5_db_set_option(krb5_context kcontext, int option, void *value)
892 krb5_error_code status = 0;
893 kdb5_dal_handle *dal_handle;
895 if (kcontext->dal_handle == NULL) {
896 status = kdb_setup_lib_handle(kcontext);
902 dal_handle = kcontext->dal_handle;
903 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
909 dal_handle->lib_handle->vftabl.db_set_option(kcontext, option, value);
910 get_errmsg(kcontext, status);
911 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
918 krb5_db_lock(krb5_context kcontext, int lock_mode)
920 krb5_error_code status = 0;
921 kdb5_dal_handle *dal_handle;
923 if (kcontext->dal_handle == NULL) {
924 status = kdb_setup_lib_handle(kcontext);
930 dal_handle = kcontext->dal_handle;
931 /* acquire an exclusive lock, ensures no other thread uses this context */
932 status = kdb_lock_lib_lock(dal_handle->lib_handle, TRUE);
937 status = dal_handle->lib_handle->vftabl.db_lock(kcontext, lock_mode);
938 get_errmsg(kcontext, status);
940 /* exclusive lock is still held, so no other thread could use this context */
941 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
948 krb5_db_unlock(krb5_context kcontext)
950 krb5_error_code status = 0;
951 kdb5_dal_handle *dal_handle;
953 if (kcontext->dal_handle == NULL) {
954 status = kdb_setup_lib_handle(kcontext);
960 dal_handle = kcontext->dal_handle;
961 /* normal lock acquired and exclusive lock released */
962 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
967 status = dal_handle->lib_handle->vftabl.db_unlock(kcontext);
968 get_errmsg(kcontext, status);
970 kdb_unlock_lib_lock(dal_handle->lib_handle, TRUE);
977 krb5_db_get_principal(krb5_context kcontext,
978 krb5_const_principal search_for,
979 krb5_db_entry * entries,
980 int *nentries, krb5_boolean * more)
982 krb5_error_code status = 0;
983 kdb5_dal_handle *dal_handle;
985 if (kcontext->dal_handle == NULL) {
986 status = kdb_setup_lib_handle(kcontext);
992 dal_handle = kcontext->dal_handle;
993 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
999 dal_handle->lib_handle->vftabl.db_get_principal(kcontext, search_for, 0,
1002 get_errmsg(kcontext, status);
1003 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1010 krb5_db_get_principal_ext(krb5_context kcontext,
1011 krb5_const_principal search_for,
1013 krb5_db_entry * entries,
1014 int *nentries, krb5_boolean * more)
1016 krb5_error_code status = 0;
1017 kdb5_dal_handle *dal_handle;
1019 if (kcontext->dal_handle == NULL) {
1020 status = kdb_setup_lib_handle(kcontext);
1026 dal_handle = kcontext->dal_handle;
1027 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1033 dal_handle->lib_handle->vftabl.db_get_principal(kcontext, search_for,
1037 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1044 krb5_db_free_principal(krb5_context kcontext, krb5_db_entry * entry, int count)
1046 krb5_error_code status = 0;
1047 kdb5_dal_handle *dal_handle;
1049 if (kcontext->dal_handle == NULL) {
1050 status = kdb_setup_lib_handle(kcontext);
1056 dal_handle = kcontext->dal_handle;
1057 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1063 dal_handle->lib_handle->vftabl.db_free_principal(kcontext, entry,
1065 get_errmsg(kcontext, status);
1066 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1073 free_db_args(krb5_context kcontext, char **db_args)
1077 /* XXX Is this right? Or are we borrowing storage from
1079 for (i = 0; db_args[i]; i++)
1080 krb5_db_free(kcontext, db_args[i]);
1085 static krb5_error_code
1086 extract_db_args_from_tl_data(krb5_context kcontext,
1087 krb5_tl_data **start, krb5_int16 *count,
1090 char **db_args = NULL;
1091 int db_args_size = 0;
1092 krb5_tl_data *prev, *curr, *next;
1093 krb5_error_code status;
1095 /* Giving db_args as part of tl data causes db2 to store the
1096 tl_data as such. To prevent this, tl_data is collated and
1097 passed as a separate argument. Currently supports only one
1098 principal, but passing it as a separate argument makes it
1099 difficult for kadmin remote to pass arguments to server. */
1100 prev = NULL, curr = *start;
1102 if (curr->tl_data_type == KRB5_TL_DB_ARGS) {
1104 /* Since this is expected to be NULL terminated string and
1105 this could come from any client, do a check before
1106 passing it to db. */
1107 if (((char *) curr->tl_data_contents)[curr->tl_data_length - 1] !=
1109 /* Not null terminated. Dangerous input. */
1115 t = realloc(db_args, sizeof(char *) * (db_args_size + 1)); /* 1 for NULL */
1122 db_args[db_args_size - 1] = (char *) curr->tl_data_contents;
1123 db_args[db_args_size] = NULL;
1125 next = curr->tl_data_next;
1127 /* current node is the first in the linked list. remove it */
1128 *start = curr->tl_data_next;
1130 prev->tl_data_next = curr->tl_data_next;
1133 krb5_db_free(kcontext, curr);
1135 /* previous does not change */
1139 curr = curr->tl_data_next;
1145 free_db_args(kcontext, db_args);
1148 *db_argsp = db_args;
1153 krb5int_put_principal_no_log(krb5_context kcontext,
1154 krb5_db_entry *entries, int *nentries)
1156 kdb5_dal_handle *dal_handle;
1157 krb5_error_code status;
1160 status = extract_db_args_from_tl_data(kcontext, &entries->tl_data,
1161 &entries->n_tl_data,
1165 assert (kcontext->dal_handle != NULL); /* XXX */
1166 dal_handle = kcontext->dal_handle;
1168 status = dal_handle->lib_handle->vftabl.db_put_principal(kcontext, entries,
1171 get_errmsg(kcontext, status);
1172 free_db_args(kcontext, db_args);
1177 krb5_db_put_principal(krb5_context kcontext,
1178 krb5_db_entry * entries, int *nentries)
1180 krb5_error_code status = 0;
1181 kdb5_dal_handle *dal_handle;
1182 char **db_args = NULL;
1183 kdb_incr_update_t *upd, *fupd = 0;
1184 char *princ_name = NULL;
1185 kdb_log_context *log_ctx;
1187 int ulog_locked = 0;
1189 log_ctx = kcontext->kdblog_context;
1191 if (kcontext->dal_handle == NULL) {
1192 status = kdb_setup_lib_handle(kcontext);
1198 status = extract_db_args_from_tl_data(kcontext, &entries->tl_data,
1199 &entries->n_tl_data,
1204 dal_handle = kcontext->dal_handle;
1205 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1211 * We need the lock since ulog_conv_2logentry() does a get
1213 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
1214 if (!(upd = (kdb_incr_update_t *)
1215 malloc(sizeof (kdb_incr_update_t)* *nentries))) {
1221 (void) memset(upd, 0, sizeof(kdb_incr_update_t)* *nentries);
1223 if ((status = ulog_conv_2logentry(kcontext, entries, upd, *nentries))) {
1228 status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
1233 for (i = 0; i < *nentries; i++) {
1235 * We'll be sharing the same locks as db for logging
1238 if ((status = krb5_unparse_name(kcontext, entries->princ,
1242 upd->kdb_princ_name.utf8str_t_val = princ_name;
1243 upd->kdb_princ_name.utf8str_t_len = strlen(princ_name);
1245 if ((status = ulog_add_update(kcontext, upd)) != 0)
1251 status = dal_handle->lib_handle->vftabl.db_put_principal(kcontext, entries,
1254 get_errmsg(kcontext, status);
1255 if (status == 0 && fupd) {
1257 for (i = 0; i < *nentries; i++) {
1258 (void) ulog_finish_update(kcontext, upd);
1264 ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
1266 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1269 free_db_args(kcontext, db_args);
1271 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER))
1272 ulog_free_entries(fupd, *nentries);
1278 krb5int_delete_principal_no_log(krb5_context kcontext,
1279 krb5_principal search_for,
1282 kdb5_dal_handle *dal_handle;
1283 krb5_error_code status;
1285 assert (kcontext->dal_handle != NULL); /* XXX */
1287 dal_handle = kcontext->dal_handle;
1289 status = dal_handle->lib_handle->vftabl.db_delete_principal(kcontext,
1292 get_errmsg(kcontext, status);
1297 krb5_db_delete_principal(krb5_context kcontext,
1298 krb5_principal search_for, int *nentries)
1300 krb5_error_code status = 0;
1301 kdb5_dal_handle *dal_handle;
1302 kdb_incr_update_t upd;
1303 char *princ_name = NULL;
1304 kdb_log_context *log_ctx;
1306 log_ctx = kcontext->kdblog_context;
1308 if (kcontext->dal_handle == NULL) {
1309 status = kdb_setup_lib_handle(kcontext);
1315 dal_handle = kcontext->dal_handle;
1316 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1321 status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
1323 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1328 * We'll be sharing the same locks as db for logging
1330 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
1331 if ((status = krb5_unparse_name(kcontext, search_for, &princ_name))) {
1332 ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
1333 (void) kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1337 (void) memset(&upd, 0, sizeof (kdb_incr_update_t));
1339 upd.kdb_princ_name.utf8str_t_val = princ_name;
1340 upd.kdb_princ_name.utf8str_t_len = strlen(princ_name);
1342 if ((status = ulog_delete_update(kcontext, &upd)) != 0) {
1343 ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
1345 (void) kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1352 status = dal_handle->lib_handle->vftabl.db_delete_principal(kcontext,
1355 get_errmsg(kcontext, status);
1358 * We need to commit our update upon success
1361 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER))
1362 (void) ulog_finish_update(kcontext, &upd);
1364 ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
1365 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1372 krb5_db_iterate(krb5_context kcontext,
1374 int (*func) (krb5_pointer, krb5_db_entry *),
1375 krb5_pointer func_arg)
1377 krb5_error_code status = 0;
1378 kdb5_dal_handle *dal_handle;
1380 if (kcontext->dal_handle == NULL) {
1381 status = kdb_setup_lib_handle(kcontext);
1387 dal_handle = kcontext->dal_handle;
1388 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1393 status = dal_handle->lib_handle->vftabl.db_iterate(kcontext,
1396 get_errmsg(kcontext, status);
1397 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1404 krb5_supported_realms(krb5_context kcontext, char **realms)
1406 krb5_error_code status = 0;
1407 kdb5_dal_handle *dal_handle;
1409 if (kcontext->dal_handle == NULL) {
1410 status = kdb_setup_lib_handle(kcontext);
1416 dal_handle = kcontext->dal_handle;
1417 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1423 dal_handle->lib_handle->vftabl.db_supported_realms(kcontext, realms);
1424 get_errmsg(kcontext, status);
1425 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1432 krb5_free_supported_realms(krb5_context kcontext, char **realms)
1434 krb5_error_code status = 0;
1435 kdb5_dal_handle *dal_handle;
1437 if (kcontext->dal_handle == NULL) {
1438 status = kdb_setup_lib_handle(kcontext);
1444 dal_handle = kcontext->dal_handle;
1445 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1451 dal_handle->lib_handle->vftabl.db_free_supported_realms(kcontext,
1453 get_errmsg(kcontext, status);
1454 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1461 krb5_db_set_master_key_ext(krb5_context kcontext,
1462 char *pwd, krb5_keyblock * key)
1464 krb5_error_code status = 0;
1465 kdb5_dal_handle *dal_handle;
1467 if (kcontext->dal_handle == NULL) {
1468 status = kdb_setup_lib_handle(kcontext);
1474 dal_handle = kcontext->dal_handle;
1475 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1480 status = dal_handle->lib_handle->vftabl.set_master_key(kcontext, pwd, key);
1481 get_errmsg(kcontext, status);
1483 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1490 krb5_db_set_mkey(krb5_context context, krb5_keyblock * key)
1492 return krb5_db_set_master_key_ext(context, NULL, key);
1496 krb5_db_set_mkey_list(krb5_context kcontext,
1497 krb5_keylist_node * keylist)
1499 krb5_error_code status = 0;
1500 kdb5_dal_handle *dal_handle;
1502 if (kcontext->dal_handle == NULL) {
1503 status = kdb_setup_lib_handle(kcontext);
1509 dal_handle = kcontext->dal_handle;
1510 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1515 status = dal_handle->lib_handle->vftabl.set_master_key_list(kcontext, keylist);
1516 get_errmsg(kcontext, status);
1518 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1525 krb5_db_get_mkey(krb5_context kcontext, krb5_keyblock ** key)
1527 krb5_error_code status = 0;
1528 kdb5_dal_handle *dal_handle;
1530 if (kcontext->dal_handle == NULL) {
1531 status = kdb_setup_lib_handle(kcontext);
1537 dal_handle = kcontext->dal_handle;
1538 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1543 /* Let's use temp key and copy it later to avoid memory problems
1544 when freed by the caller. */
1545 status = dal_handle->lib_handle->vftabl.get_master_key(kcontext, key);
1546 get_errmsg(kcontext, status);
1547 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1554 krb5_db_get_mkey_list(krb5_context kcontext, krb5_keylist_node ** keylist)
1556 krb5_error_code status = 0;
1557 kdb5_dal_handle *dal_handle;
1559 if (kcontext->dal_handle == NULL) {
1560 status = kdb_setup_lib_handle(kcontext);
1566 dal_handle = kcontext->dal_handle;
1567 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1572 /* Let's use temp key and copy it later to avoid memory problems
1573 when freed by the caller. */
1574 status = dal_handle->lib_handle->vftabl.get_master_key_list(kcontext, keylist);
1575 get_errmsg(kcontext, status);
1576 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1583 krb5_db_fetch_mkey_list(krb5_context context,
1584 krb5_principal mname,
1585 const krb5_keyblock * mkey,
1587 krb5_keylist_node **mkey_list)
1589 kdb5_dal_handle *dal_handle;
1590 krb5_error_code status = 0;
1592 if (context->dal_handle == NULL) {
1593 status = kdb_setup_lib_handle(context);
1599 dal_handle = context->dal_handle;
1600 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1605 status = dal_handle->lib_handle->vftabl.fetch_master_key_list(context,
1610 get_errmsg(context, status);
1611 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1622 krb5_db_free_mkey_list(krb5_context context,
1623 krb5_keylist_node *mkey_list)
1625 krb5_keylist_node *cur, *prev;
1627 for (cur = mkey_list; cur != NULL;) {
1630 krb5_free_keyblock_contents(context, &prev->keyblock);
1638 krb5_db_store_master_key(krb5_context kcontext,
1640 krb5_principal mname,
1642 krb5_keyblock * key, char *master_pwd)
1644 krb5_error_code status = 0;
1645 kdb5_dal_handle *dal_handle;
1647 if (kcontext->dal_handle == NULL) {
1648 status = kdb_setup_lib_handle(kcontext);
1654 dal_handle = kcontext->dal_handle;
1655 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1660 status = dal_handle->lib_handle->vftabl.store_master_key(kcontext,
1665 get_errmsg(kcontext, status);
1666 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1673 krb5_db_store_master_key_list(krb5_context kcontext,
1675 krb5_principal mname,
1676 krb5_keylist_node *keylist,
1679 krb5_error_code status = 0;
1680 kdb5_dal_handle *dal_handle;
1682 if (kcontext->dal_handle == NULL) {
1683 status = kdb_setup_lib_handle(kcontext);
1689 dal_handle = kcontext->dal_handle;
1690 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1695 status = dal_handle->lib_handle->vftabl.store_master_key_list(kcontext,
1700 get_errmsg(kcontext, status);
1701 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1707 char *krb5_mkey_pwd_prompt1 = KRB5_KDC_MKEY_1;
1708 char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2;
1711 krb5_db_fetch_mkey(krb5_context context,
1712 krb5_principal mname,
1714 krb5_boolean fromkeyboard,
1719 krb5_keyblock * key)
1721 krb5_error_code retval;
1722 char password[BUFSIZ];
1724 unsigned int size = sizeof(password);
1725 krb5_keyblock tmp_key;
1727 memset(&tmp_key, 0, sizeof(tmp_key));
1732 if ((retval = krb5_read_password(context, krb5_mkey_pwd_prompt1,
1733 twice ? krb5_mkey_pwd_prompt2 : 0,
1734 password, &size))) {
1738 pwd.data = password;
1741 retval = krb5_principal2salt(context, mname, &scratch);
1746 krb5_c_string_to_key(context, etype, &pwd, salt ? salt : &scratch,
1749 * If a kvno pointer was passed in and it dereferences the IGNORE_VNO
1750 * value then it should be assigned the value of the kvno associated
1751 * with the current mkey princ key if that princ entry is available
1752 * otherwise assign 1 which is the default kvno value for the mkey
1755 if (kvno != NULL && *kvno == IGNORE_VNO) {
1759 krb5_db_entry master_entry;
1761 rc = krb5_db_get_principal(context, mname,
1762 &master_entry, &nentries, &more);
1764 if (rc == 0 && nentries == 1 && more == FALSE)
1765 *kvno = (krb5_kvno) master_entry.key_data->key_data_kvno;
1769 if (rc == 0 && nentries)
1770 krb5_db_free_principal(context, &master_entry, nentries);
1775 zap(password, sizeof(password)); /* erase it */
1778 kdb5_dal_handle *dal_handle;
1780 if (context->dal_handle == NULL) {
1781 retval = kdb_setup_lib_handle(context);
1787 dal_handle = context->dal_handle;
1788 retval = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1793 /* get the enctype from the stash */
1794 tmp_key.enctype = ENCTYPE_UNKNOWN;
1796 retval = dal_handle->lib_handle->vftabl.fetch_master_key(context,
1801 get_errmsg(context, retval);
1802 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1808 key->contents = malloc(tmp_key.length);
1809 if (key->contents == NULL) {
1814 key->magic = tmp_key.magic;
1815 key->enctype = tmp_key.enctype;
1816 key->length = tmp_key.length;
1817 memcpy(key->contents, tmp_key.contents, tmp_key.length);
1821 if (tmp_key.contents) {
1822 zap(tmp_key.contents, tmp_key.length);
1823 krb5_db_free(context, tmp_key.contents);
1829 krb5_db_verify_master_key(krb5_context kcontext,
1830 krb5_principal mprinc,
1832 krb5_keyblock * mkey)
1834 krb5_error_code status = 0;
1835 kdb5_dal_handle *dal_handle;
1837 if (kcontext->dal_handle == NULL) {
1838 status = kdb_setup_lib_handle(kcontext);
1844 dal_handle = kcontext->dal_handle;
1845 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1850 status = dal_handle->lib_handle->vftabl.verify_master_key(kcontext,
1854 get_errmsg(kcontext, status);
1855 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1862 krb5_dbe_fetch_act_key_list(krb5_context context,
1863 krb5_principal princ,
1864 krb5_actkvno_node **act_key_list)
1866 krb5_error_code retval = 0;
1867 krb5_db_entry entry;
1871 if (act_key_list == NULL)
1875 if ((retval = krb5_db_get_principal(context, princ, &entry,
1882 krb5_db_free_principal(context, &entry, nprinc);
1883 return (KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
1885 return(KRB5_KDB_NOMASTERKEY);
1888 krb5_db_free_principal(context, &entry, nprinc);
1889 return (KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
1892 retval = krb5_dbe_lookup_actkvno(context, &entry, act_key_list);
1894 if (*act_key_list == NULL) {
1895 krb5_actkvno_node *tmp_actkvno;
1897 * for mkey princ entries without KRB5_TL_ACTKVNO data provide a default
1900 tmp_actkvno = (krb5_actkvno_node *) malloc(sizeof(krb5_actkvno_node));
1901 if (tmp_actkvno == NULL)
1904 memset(tmp_actkvno, 0, sizeof(krb5_actkvno_node));
1905 tmp_actkvno->act_time = 0; /* earliest time possible */
1906 /* use most current key */
1907 tmp_actkvno->act_kvno = entry.key_data[0].key_data_kvno;
1908 *act_key_list = tmp_actkvno;
1911 krb5_db_free_principal(context, &entry, nprinc);
1916 * Locates the "active" mkey used when encrypting a princ's keys. Note, the
1917 * caller must NOT free the output act_mkey.
1921 krb5_dbe_find_act_mkey(krb5_context context,
1922 krb5_keylist_node *mkey_list,
1923 krb5_actkvno_node *act_mkey_list,
1924 krb5_kvno *act_kvno,
1925 krb5_keyblock **act_mkey)
1927 krb5_kvno tmp_act_kvno;
1928 krb5_error_code retval;
1929 krb5_keylist_node *cur_keyblock = mkey_list;
1930 krb5_actkvno_node *prev_actkvno, *cur_actkvno;
1932 krb5_boolean found = FALSE;
1934 if ((retval = krb5_timeofday(context, &now)))
1938 * The list should be sorted in time, early to later so if the first entry
1939 * is later than now, this is a problem. The fallback in this case is to
1940 * return the earlist activation entry.
1942 if (act_mkey_list->act_time > now) {
1943 while (cur_keyblock && cur_keyblock->kvno != act_mkey_list->act_kvno)
1944 cur_keyblock = cur_keyblock->next;
1946 *act_mkey = &cur_keyblock->keyblock;
1947 if (act_kvno != NULL)
1948 *act_kvno = cur_keyblock->kvno;
1951 return (KRB5_KDB_NOACTMASTERKEY);
1955 /* find the most current entry <= now */
1956 for (prev_actkvno = cur_actkvno = act_mkey_list; cur_actkvno != NULL;
1957 prev_actkvno = cur_actkvno, cur_actkvno = cur_actkvno->next) {
1959 if (cur_actkvno->act_time == now) {
1960 tmp_act_kvno = cur_actkvno->act_kvno;
1963 } else if (cur_actkvno->act_time > now && prev_actkvno->act_time <= now) {
1964 tmp_act_kvno = prev_actkvno->act_kvno;
1972 * The end of the list was encountered and all entries are < now so use
1975 if (prev_actkvno->act_time <= now) {
1976 tmp_act_kvno = prev_actkvno->act_kvno;
1978 /* XXX this shouldn't happen */
1979 return (KRB5_KDB_NOACTMASTERKEY);
1983 while (cur_keyblock && cur_keyblock->kvno != tmp_act_kvno)
1984 cur_keyblock = cur_keyblock->next;
1987 *act_mkey = &cur_keyblock->keyblock;
1988 if (act_kvno != NULL)
1989 *act_kvno = tmp_act_kvno;
1992 return (KRB5_KDB_NO_MATCHING_KEY);
1997 * Locates the mkey used to protect a princ's keys. Note, the caller must not
1998 * free the output key.
2001 krb5_dbe_find_mkey(krb5_context context,
2002 krb5_keylist_node * mkey_list,
2003 krb5_db_entry * entry,
2004 krb5_keyblock ** mkey)
2007 krb5_error_code retval;
2008 krb5_keylist_node *cur_keyblock = mkey_list;
2010 retval = krb5_dbe_lookup_mkvno(context, entry, &mkvno);
2014 while (cur_keyblock && cur_keyblock->kvno != mkvno)
2015 cur_keyblock = cur_keyblock->next;
2018 *mkey = &cur_keyblock->keyblock;
2021 return (KRB5_KDB_NO_MATCHING_KEY);
2026 krb5_db_alloc(krb5_context kcontext, void *ptr, size_t size)
2028 krb5_error_code status;
2029 kdb5_dal_handle *dal_handle;
2030 void *new_ptr = NULL;
2032 if (kcontext->dal_handle == NULL) {
2033 status = kdb_setup_lib_handle(kcontext);
2039 dal_handle = kcontext->dal_handle;
2041 new_ptr = dal_handle->lib_handle->vftabl.db_alloc(kcontext, ptr, size);
2048 krb5_db_free(krb5_context kcontext, void *ptr)
2050 krb5_error_code status;
2051 kdb5_dal_handle *dal_handle;
2053 if (kcontext->dal_handle == NULL) {
2054 status = kdb_setup_lib_handle(kcontext);
2060 dal_handle = kcontext->dal_handle;
2062 dal_handle->lib_handle->vftabl.db_free(kcontext, ptr);
2068 /* has to be modified */
2071 krb5_dbe_find_enctype(krb5_context kcontext,
2072 krb5_db_entry * dbentp,
2075 krb5_int32 kvno, krb5_key_data ** kdatap)
2077 krb5_int32 start = 0;
2078 return krb5_dbe_search_enctype(kcontext, dbentp, &start, ktype, stype,
2083 krb5_dbe_search_enctype(krb5_context kcontext,
2084 krb5_db_entry * dbentp,
2088 krb5_int32 kvno, krb5_key_data ** kdatap)
2090 krb5_error_code status = 0;
2091 kdb5_dal_handle *dal_handle;
2093 if (kcontext->dal_handle == NULL) {
2094 status = kdb_setup_lib_handle(kcontext);
2100 dal_handle = kcontext->dal_handle;
2101 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2106 status = dal_handle->lib_handle->vftabl.dbe_search_enctype(kcontext,
2112 get_errmsg(kcontext, status);
2113 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2119 #define REALM_SEP_STRING "@"
2122 krb5_db_setup_mkey_name(krb5_context context,
2123 const char *keyname,
2125 char **fullname, krb5_principal * principal)
2127 krb5_error_code retval;
2131 keyname = KRB5_KDB_M_NAME; /* XXX external? */
2133 if (asprintf(&fname, "%s%s%s", keyname, REALM_SEP_STRING, realm) < 0)
2136 if ((retval = krb5_parse_name(context, fname, principal)))
2146 krb5_dbe_lookup_last_pwd_change(context, entry, stamp)
2147 krb5_context context;
2148 krb5_db_entry *entry;
2149 krb5_timestamp *stamp;
2151 krb5_tl_data tl_data;
2152 krb5_error_code code;
2155 tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
2157 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2160 if (tl_data.tl_data_length != 4) {
2165 krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp);
2167 *stamp = (krb5_timestamp) tmp;
2173 krb5_dbe_lookup_tl_data(context, entry, ret_tl_data)
2174 krb5_context context;
2175 krb5_db_entry *entry;
2176 krb5_tl_data *ret_tl_data;
2178 krb5_tl_data *tl_data;
2180 for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
2181 if (tl_data->tl_data_type == ret_tl_data->tl_data_type) {
2182 *ret_tl_data = *tl_data;
2188 * If the requested record isn't found, return zero bytes. If it
2189 * ever means something to have a zero-length tl_data, this code
2190 * and its callers will have to be changed.
2193 ret_tl_data->tl_data_length = 0;
2194 ret_tl_data->tl_data_contents = NULL;
2199 krb5_dbe_create_key_data(context, entry)
2200 krb5_context context;
2201 krb5_db_entry *entry;
2203 if ((entry->key_data =
2204 (krb5_key_data *) krb5_db_alloc(context, entry->key_data,
2205 (sizeof(krb5_key_data) *
2206 (entry->n_key_data + 1)))) == NULL)
2209 memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data));
2210 entry->n_key_data++;
2216 krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ)
2217 krb5_context context;
2218 krb5_db_entry *entry;
2219 krb5_timestamp mod_date;
2220 krb5_const_principal mod_princ;
2222 krb5_tl_data tl_data;
2224 krb5_error_code retval = 0;
2225 krb5_octet *nextloc = 0;
2226 char *unparse_mod_princ = 0;
2227 unsigned int unparse_mod_princ_size;
2229 if ((retval = krb5_unparse_name(context, mod_princ, &unparse_mod_princ)))
2232 unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
2234 if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
2236 free(unparse_mod_princ);
2240 tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
2241 tl_data.tl_data_length = unparse_mod_princ_size + 4;
2242 tl_data.tl_data_contents = nextloc;
2245 krb5_kdb_encode_int32(mod_date, nextloc);
2248 memcpy(nextloc + 4, unparse_mod_princ, unparse_mod_princ_size);
2250 retval = krb5_dbe_update_tl_data(context, entry, &tl_data);
2252 free(unparse_mod_princ);
2259 krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ)
2260 krb5_context context;
2261 krb5_db_entry *entry;
2262 krb5_timestamp *mod_time;
2263 krb5_principal *mod_princ;
2265 krb5_tl_data tl_data;
2266 krb5_error_code code;
2271 tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
2273 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2276 if ((tl_data.tl_data_length < 5) ||
2277 (tl_data.tl_data_contents[tl_data.tl_data_length - 1] != '\0'))
2278 return (KRB5_KDB_TRUNCATED_RECORD);
2281 krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time);
2284 if ((code = krb5_parse_name(context,
2285 (const char *) (tl_data.tl_data_contents + 4),
2293 krb5_dbe_lookup_mkvno(krb5_context context,
2294 krb5_db_entry *entry,
2297 krb5_tl_data tl_data;
2298 krb5_error_code code;
2301 tl_data.tl_data_type = KRB5_TL_MKVNO;
2303 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2306 if (tl_data.tl_data_length == 0) {
2307 *mkvno = 1; /* default for princs that lack the KRB5_TL_MKVNO data */
2309 } else if (tl_data.tl_data_length != 2) {
2310 return (KRB5_KDB_TRUNCATED_RECORD);
2313 krb5_kdb_decode_int16(tl_data.tl_data_contents, tmp);
2314 *mkvno = (krb5_kvno) tmp;
2319 krb5_dbe_update_mkvno(krb5_context context,
2320 krb5_db_entry * entry,
2323 krb5_tl_data tl_data;
2324 krb5_octet buf[2]; /* this is the encoded size of an int16 */
2325 krb5_int16 tmp_kvno = (krb5_int16) mkvno;
2327 tl_data.tl_data_type = KRB5_TL_MKVNO;
2328 tl_data.tl_data_length = sizeof(buf);
2329 krb5_kdb_encode_int16(tmp_kvno, buf);
2330 tl_data.tl_data_contents = buf;
2332 return (krb5_dbe_update_tl_data(context, entry, &tl_data));
2336 krb5_dbe_lookup_mkey_aux(krb5_context context,
2337 krb5_db_entry * entry,
2338 krb5_mkey_aux_node ** mkey_aux_data_list)
2340 krb5_tl_data tl_data;
2342 krb5_mkey_aux_node *head_data = NULL, *new_data = NULL,
2344 krb5_octet *curloc; /* current location pointer */
2345 krb5_error_code code;
2347 tl_data.tl_data_type = KRB5_TL_MKEY_AUX;
2348 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2351 if (tl_data.tl_data_contents == NULL) {
2352 *mkey_aux_data_list = NULL;
2355 /* get version to determine how to parse the data */
2356 krb5_kdb_decode_int16(tl_data.tl_data_contents, version);
2358 /* variable size, must be at least 10 bytes */
2359 if (tl_data.tl_data_length < 10)
2360 return (KRB5_KDB_TRUNCATED_RECORD);
2362 /* curloc points to first tuple entry in the tl_data_contents */
2363 curloc = tl_data.tl_data_contents + sizeof(version);
2365 while (curloc < (tl_data.tl_data_contents + tl_data.tl_data_length)) {
2367 new_data = (krb5_mkey_aux_node *) malloc(sizeof(krb5_mkey_aux_node));
2368 if (new_data == NULL) {
2369 krb5_dbe_free_mkey_aux_list(context, head_data);
2372 memset(new_data, 0, sizeof(krb5_mkey_aux_node));
2374 krb5_kdb_decode_int16(curloc, new_data->mkey_kvno);
2375 curloc += sizeof(krb5_ui_2);
2376 krb5_kdb_decode_int16(curloc, new_data->latest_mkey.key_data_kvno);
2377 curloc += sizeof(krb5_ui_2);
2378 krb5_kdb_decode_int16(curloc, new_data->latest_mkey.key_data_type[0]);
2379 curloc += sizeof(krb5_ui_2);
2380 krb5_kdb_decode_int16(curloc, new_data->latest_mkey.key_data_length[0]);
2381 curloc += sizeof(krb5_ui_2);
2383 new_data->latest_mkey.key_data_contents[0] = (krb5_octet *)
2384 malloc(new_data->latest_mkey.key_data_length[0]);
2386 if (new_data->latest_mkey.key_data_contents[0] == NULL) {
2387 krb5_dbe_free_mkey_aux_list(context, head_data);
2391 memcpy(new_data->latest_mkey.key_data_contents[0], curloc,
2392 new_data->latest_mkey.key_data_length[0]);
2393 curloc += new_data->latest_mkey.key_data_length[0];
2395 /* always using key data ver 1 for mkeys */
2396 new_data->latest_mkey.key_data_ver = 1;
2398 new_data->next = NULL;
2399 if (prev_data != NULL)
2400 prev_data->next = new_data;
2402 head_data = new_data;
2403 prev_data = new_data;
2406 krb5_set_error_message(context, KRB5_KDB_BAD_VERSION,
2407 "Illegal version number for KRB5_TL_MKEY_AUX %d\n",
2409 return (KRB5_KDB_BAD_VERSION);
2412 *mkey_aux_data_list = head_data;
2416 #if KRB5_TL_MKEY_AUX_VER == 1
2418 krb5_dbe_update_mkey_aux(krb5_context context,
2419 krb5_db_entry * entry,
2420 krb5_mkey_aux_node * mkey_aux_data_list)
2422 krb5_tl_data tl_data;
2423 krb5_int16 version, tmp_kvno;
2424 unsigned char *nextloc;
2425 krb5_mkey_aux_node *aux_data_entry;
2427 if (!mkey_aux_data_list) {
2428 /* delete the KRB5_TL_MKEY_AUX from the entry */
2429 krb5_dbe_delete_tl_data(context, entry, KRB5_TL_MKEY_AUX);
2433 memset(&tl_data, 0, sizeof(tl_data));
2434 tl_data.tl_data_type = KRB5_TL_MKEY_AUX;
2436 * determine out how much space to allocate. Note key_data_ver not stored
2437 * as this is hard coded to one and is accounted for in
2438 * krb5_dbe_lookup_mkey_aux.
2440 tl_data.tl_data_length = sizeof(version); /* version */
2441 for (aux_data_entry = mkey_aux_data_list; aux_data_entry != NULL;
2442 aux_data_entry = aux_data_entry->next) {
2444 tl_data.tl_data_length += (sizeof(krb5_ui_2) + /* mkey_kvno */
2445 sizeof(krb5_ui_2) + /* latest_mkey kvno */
2446 sizeof(krb5_ui_2) + /* latest_mkey enctype */
2447 sizeof(krb5_ui_2) + /* latest_mkey length */
2448 aux_data_entry->latest_mkey.key_data_length[0]);
2451 tl_data.tl_data_contents = (krb5_octet *) malloc(tl_data.tl_data_length);
2452 if (tl_data.tl_data_contents == NULL) {
2456 nextloc = tl_data.tl_data_contents;
2457 version = KRB5_TL_MKEY_AUX_VER;
2458 krb5_kdb_encode_int16(version, nextloc);
2459 nextloc += sizeof(krb5_ui_2);
2461 for (aux_data_entry = mkey_aux_data_list; aux_data_entry != NULL;
2462 aux_data_entry = aux_data_entry->next) {
2464 tmp_kvno = (krb5_int16) aux_data_entry->mkey_kvno;
2465 krb5_kdb_encode_int16(tmp_kvno, nextloc);
2466 nextloc += sizeof(krb5_ui_2);
2468 krb5_kdb_encode_int16(aux_data_entry->latest_mkey.key_data_kvno,
2470 nextloc += sizeof(krb5_ui_2);
2472 krb5_kdb_encode_int16(aux_data_entry->latest_mkey.key_data_type[0],
2474 nextloc += sizeof(krb5_ui_2);
2476 krb5_kdb_encode_int16(aux_data_entry->latest_mkey.key_data_length[0],
2478 nextloc += sizeof(krb5_ui_2);
2480 if (aux_data_entry->latest_mkey.key_data_length[0] > 0) {
2481 memcpy(nextloc, aux_data_entry->latest_mkey.key_data_contents[0],
2482 aux_data_entry->latest_mkey.key_data_length[0]);
2483 nextloc += aux_data_entry->latest_mkey.key_data_length[0];
2487 return (krb5_dbe_update_tl_data(context, entry, &tl_data));
2489 #endif /* KRB5_TL_MKEY_AUX_VER == 1 */
2491 #if KRB5_TL_ACTKVNO_VER == 1
2493 * If version of the KRB5_TL_ACTKVNO data is KRB5_TL_ACTKVNO_VER == 1 then size of
2494 * a actkvno tuple {act_kvno, act_time} entry is:
2496 #define ACTKVNO_TUPLE_SIZE (sizeof(krb5_int16) + sizeof(krb5_int32))
2497 #define act_kvno(cp) (cp) /* return pointer to start of act_kvno data */
2498 #define act_time(cp) ((cp) + sizeof(krb5_int16)) /* return pointer to start of act_time data */
2502 krb5_dbe_lookup_actkvno(krb5_context context,
2503 krb5_db_entry *entry,
2504 krb5_actkvno_node **actkvno_list)
2506 krb5_tl_data tl_data;
2507 krb5_error_code code;
2508 krb5_int16 version, tmp_kvno;
2509 krb5_actkvno_node *head_data = NULL, *new_data = NULL, *prev_data = NULL;
2510 unsigned int num_actkvno, i;
2511 krb5_octet *next_tuple;
2513 memset(&tl_data, 0, sizeof(tl_data));
2514 tl_data.tl_data_type = KRB5_TL_ACTKVNO;
2516 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2519 if (tl_data.tl_data_contents == NULL) {
2520 *actkvno_list = NULL;
2523 /* get version to determine how to parse the data */
2524 krb5_kdb_decode_int16(tl_data.tl_data_contents, version);
2527 /* variable size, must be at least 8 bytes */
2528 if (tl_data.tl_data_length < 8)
2529 return (KRB5_KDB_TRUNCATED_RECORD);
2532 * Find number of tuple entries, remembering to account for version
2535 num_actkvno = (tl_data.tl_data_length - sizeof(version)) /
2538 /* next_tuple points to first tuple entry in the tl_data_contents */
2539 next_tuple = tl_data.tl_data_contents + sizeof(version);
2540 for (i = 0; i < num_actkvno; i++) {
2541 new_data = (krb5_actkvno_node *) malloc(sizeof(krb5_actkvno_node));
2542 if (new_data == NULL) {
2543 krb5_dbe_free_actkvno_list(context, head_data);
2546 memset(new_data, 0, sizeof(krb5_actkvno_node));
2548 /* using tmp_kvno to avoid type mismatch */
2549 krb5_kdb_decode_int16(act_kvno(next_tuple), tmp_kvno);
2550 new_data->act_kvno = (krb5_kvno) tmp_kvno;
2551 krb5_kdb_decode_int32(act_time(next_tuple), new_data->act_time);
2553 if (prev_data != NULL)
2554 prev_data->next = new_data;
2556 head_data = new_data;
2557 prev_data = new_data;
2558 next_tuple += ACTKVNO_TUPLE_SIZE;
2561 krb5_set_error_message (context, KRB5_KDB_BAD_VERSION,
2562 "Illegal version number for KRB5_TL_ACTKVNO %d\n",
2564 return (KRB5_KDB_BAD_VERSION);
2567 *actkvno_list = head_data;
2572 * Add KRB5_TL_ACTKVNO TL data entries to krb5_db_entry *entry
2574 #if KRB5_TL_ACTKVNO_VER == 1
2576 krb5_dbe_update_actkvno(krb5_context context,
2577 krb5_db_entry *entry,
2578 const krb5_actkvno_node *actkvno_list)
2580 krb5_error_code retval = 0;
2581 krb5_int16 version, tmp_kvno;
2582 krb5_tl_data new_tl_data;
2583 unsigned char *nextloc;
2584 const krb5_actkvno_node *cur_actkvno;
2587 if (actkvno_list == NULL) {
2591 memset(&new_tl_data, 0, sizeof(new_tl_data));
2592 /* allocate initial KRB5_TL_ACTKVNO tl_data entry */
2593 new_tl_data.tl_data_length = sizeof(version);
2594 new_tl_data.tl_data_contents = (krb5_octet *) malloc(new_tl_data.tl_data_length);
2595 if (new_tl_data.tl_data_contents == NULL)
2598 /* add the current version # for the data format used for KRB5_TL_ACTKVNO */
2599 version = KRB5_TL_ACTKVNO_VER;
2600 krb5_kdb_encode_int16(version, (unsigned char *) new_tl_data.tl_data_contents);
2602 for (cur_actkvno = actkvno_list; cur_actkvno != NULL;
2603 cur_actkvno = cur_actkvno->next) {
2605 new_tl_data.tl_data_length += ACTKVNO_TUPLE_SIZE;
2606 tmpptr = realloc(new_tl_data.tl_data_contents, new_tl_data.tl_data_length);
2607 if (tmpptr == NULL) {
2608 free(new_tl_data.tl_data_contents);
2611 new_tl_data.tl_data_contents = tmpptr;
2615 * Using realloc so tl_data_contents is required to correctly calculate
2616 * next location to store new tuple.
2618 nextloc = new_tl_data.tl_data_contents + new_tl_data.tl_data_length - ACTKVNO_TUPLE_SIZE;
2619 /* using tmp_kvno to avoid type mismatch issues */
2620 tmp_kvno = (krb5_int16) cur_actkvno->act_kvno;
2621 krb5_kdb_encode_int16(tmp_kvno, nextloc);
2622 nextloc += sizeof(krb5_ui_2);
2623 krb5_kdb_encode_int32((krb5_ui_4)cur_actkvno->act_time, nextloc);
2626 new_tl_data.tl_data_type = KRB5_TL_ACTKVNO;
2627 retval = krb5_dbe_update_tl_data(context, entry, &new_tl_data);
2628 free(new_tl_data.tl_data_contents);
2632 #endif /* KRB5_TL_ACTKVNO_VER == 1 */
2635 krb5_dbe_update_last_pwd_change(context, entry, stamp)
2636 krb5_context context;
2637 krb5_db_entry *entry;
2638 krb5_timestamp stamp;
2640 krb5_tl_data tl_data;
2641 krb5_octet buf[4]; /* this is the encoded size of an int32 */
2643 tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
2644 tl_data.tl_data_length = sizeof(buf);
2645 krb5_kdb_encode_int32((krb5_int32) stamp, buf);
2646 tl_data.tl_data_contents = buf;
2648 return (krb5_dbe_update_tl_data(context, entry, &tl_data));
2652 krb5_dbe_delete_tl_data(krb5_context context,
2653 krb5_db_entry *entry,
2654 krb5_int16 tl_data_type)
2656 krb5_tl_data *tl_data, *prev_tl_data, *free_tl_data;
2659 * Find existing entries of the specified type and remove them from the
2660 * entry's tl_data list.
2663 for (prev_tl_data = tl_data = entry->tl_data; tl_data != NULL;) {
2664 if (tl_data->tl_data_type == tl_data_type) {
2665 if (tl_data == entry->tl_data) {
2666 /* remove from head */
2667 entry->tl_data = tl_data->tl_data_next;
2668 prev_tl_data = entry->tl_data;
2669 } else if (tl_data->tl_data_next == NULL) {
2670 /* remove from tail */
2671 prev_tl_data->tl_data_next = NULL;
2673 /* remove in between */
2674 prev_tl_data->tl_data_next = tl_data->tl_data_next;
2676 free_tl_data = tl_data;
2677 tl_data = tl_data->tl_data_next;
2678 krb5_dbe_free_tl_data(context, free_tl_data);
2681 tl_data = tl_data->tl_data_next;
2682 prev_tl_data = tl_data;
2690 krb5_dbe_update_tl_data(context, entry, new_tl_data)
2691 krb5_context context;
2692 krb5_db_entry *entry;
2693 krb5_tl_data *new_tl_data;
2695 krb5_tl_data *tl_data = NULL;
2699 * Copy the new data first, so we can fail cleanly if malloc()
2703 (krb5_octet *) krb5_db_alloc(context, NULL,
2704 new_tl_data->tl_data_length)) == NULL)
2708 * Find an existing entry of the specified type and point at
2709 * it, or NULL if not found.
2712 if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) { /* db_args can be multiple */
2713 for (tl_data = entry->tl_data; tl_data;
2714 tl_data = tl_data->tl_data_next)
2715 if (tl_data->tl_data_type == new_tl_data->tl_data_type)
2719 /* If necessary, chain a new record in the beginning and point at it. */
2723 (krb5_tl_data *) krb5_db_alloc(context, NULL,
2724 sizeof(krb5_tl_data)))
2729 memset(tl_data, 0, sizeof(krb5_tl_data));
2730 tl_data->tl_data_next = entry->tl_data;
2731 entry->tl_data = tl_data;
2735 /* fill in the record */
2737 if (tl_data->tl_data_contents)
2738 krb5_db_free(context, tl_data->tl_data_contents);
2740 tl_data->tl_data_type = new_tl_data->tl_data_type;
2741 tl_data->tl_data_length = new_tl_data->tl_data_length;
2742 tl_data->tl_data_contents = tmp;
2743 memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
2748 /* change password functions */
2750 krb5_dbe_cpw(krb5_context kcontext,
2751 krb5_keyblock * master_key,
2752 krb5_key_salt_tuple * ks_tuple,
2755 int new_kvno, krb5_boolean keepold, krb5_db_entry * db_entry)
2757 krb5_error_code status = 0;
2758 kdb5_dal_handle *dal_handle;
2760 if (kcontext->dal_handle == NULL) {
2761 status = kdb_setup_lib_handle(kcontext);
2767 dal_handle = kcontext->dal_handle;
2768 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2773 status = dal_handle->lib_handle->vftabl.db_change_pwd(kcontext,
2780 get_errmsg(kcontext, status);
2781 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2787 /* policy management functions */
2789 krb5_db_create_policy(krb5_context kcontext, osa_policy_ent_t policy)
2791 krb5_error_code status = 0;
2792 kdb5_dal_handle *dal_handle;
2794 if (kcontext->dal_handle == NULL) {
2795 status = kdb_setup_lib_handle(kcontext);
2801 dal_handle = kcontext->dal_handle;
2802 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2807 status = dal_handle->lib_handle->vftabl.db_create_policy(kcontext, policy);
2808 get_errmsg(kcontext, status);
2809 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2816 krb5_db_get_policy(krb5_context kcontext, char *name,
2817 osa_policy_ent_t * policy, int *cnt)
2819 krb5_error_code status = 0;
2820 kdb5_dal_handle *dal_handle;
2822 if (kcontext->dal_handle == NULL) {
2823 status = kdb_setup_lib_handle(kcontext);
2829 dal_handle = kcontext->dal_handle;
2830 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2836 dal_handle->lib_handle->vftabl.db_get_policy(kcontext, name, policy,
2838 get_errmsg(kcontext, status);
2839 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2846 krb5_db_put_policy(krb5_context kcontext, osa_policy_ent_t policy)
2848 krb5_error_code status = 0;
2849 kdb5_dal_handle *dal_handle;
2851 if (kcontext->dal_handle == NULL) {
2852 status = kdb_setup_lib_handle(kcontext);
2858 dal_handle = kcontext->dal_handle;
2859 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2864 status = dal_handle->lib_handle->vftabl.db_put_policy(kcontext, policy);
2865 get_errmsg(kcontext, status);
2866 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2873 krb5_db_iter_policy(krb5_context kcontext, char *match_entry,
2874 osa_adb_iter_policy_func func, void *data)
2876 krb5_error_code status = 0;
2877 kdb5_dal_handle *dal_handle;
2879 if (kcontext->dal_handle == NULL) {
2880 status = kdb_setup_lib_handle(kcontext);
2886 dal_handle = kcontext->dal_handle;
2887 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2893 dal_handle->lib_handle->vftabl.db_iter_policy(kcontext, match_entry,
2895 get_errmsg(kcontext, status);
2896 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2903 krb5_db_delete_policy(krb5_context kcontext, char *policy)
2905 krb5_error_code status = 0;
2906 kdb5_dal_handle *dal_handle;
2908 if (kcontext->dal_handle == NULL) {
2909 status = kdb_setup_lib_handle(kcontext);
2915 dal_handle = kcontext->dal_handle;
2916 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2921 status = dal_handle->lib_handle->vftabl.db_delete_policy(kcontext, policy);
2922 get_errmsg(kcontext, status);
2923 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2930 krb5_db_free_policy(krb5_context kcontext, osa_policy_ent_t policy)
2932 krb5_error_code status = 0;
2933 kdb5_dal_handle *dal_handle;
2935 if (kcontext->dal_handle == NULL) {
2936 status = kdb_setup_lib_handle(kcontext);
2942 dal_handle = kcontext->dal_handle;
2943 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2948 dal_handle->lib_handle->vftabl.db_free_policy(kcontext, policy);
2949 get_errmsg(kcontext, status);
2950 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2957 krb5_db_promote(krb5_context kcontext, char **db_args)
2959 krb5_error_code status = 0;
2960 char *section = NULL;
2961 kdb5_dal_handle *dal_handle;
2963 section = kdb_get_conf_section(kcontext);
2964 if (section == NULL) {
2965 status = KRB5_KDB_SERVER_INTERNAL_ERR;
2966 krb5_set_error_message (kcontext, status,
2967 "unable to determine configuration section for realm %s\n",
2968 kcontext->default_realm);
2972 if (kcontext->dal_handle == NULL) {
2973 status = kdb_setup_lib_handle(kcontext);
2979 dal_handle = kcontext->dal_handle;
2980 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2986 dal_handle->lib_handle->vftabl.promote_db(kcontext, section, db_args);
2987 get_errmsg(kcontext, status);
2988 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2997 krb5_dbekd_decrypt_key_data( krb5_context kcontext,
2998 const krb5_keyblock * mkey,
2999 const krb5_key_data * key_data,
3000 krb5_keyblock * dbkey,
3001 krb5_keysalt * keysalt)
3003 krb5_error_code status = 0;
3004 kdb5_dal_handle *dal_handle;
3006 if (kcontext->dal_handle == NULL) {
3007 status = kdb_setup_lib_handle(kcontext);
3013 dal_handle = kcontext->dal_handle;
3014 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
3020 dal_handle->lib_handle->vftabl.dbekd_decrypt_key_data(kcontext,
3021 mkey, key_data, dbkey, keysalt);
3022 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
3029 krb5_dbekd_encrypt_key_data( krb5_context kcontext,
3030 const krb5_keyblock * mkey,
3031 const krb5_keyblock * dbkey,
3032 const krb5_keysalt * keysalt,
3034 krb5_key_data * key_data)
3036 krb5_error_code status = 0;
3037 kdb5_dal_handle *dal_handle;
3039 if (kcontext->dal_handle == NULL) {
3040 status = kdb_setup_lib_handle(kcontext);
3046 dal_handle = kcontext->dal_handle;
3047 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
3053 dal_handle->lib_handle->vftabl.dbekd_encrypt_key_data(kcontext,
3054 mkey, dbkey, keysalt, keyver, key_data);
3055 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
3062 krb5_db_get_context(krb5_context context, void **db_context)
3064 *db_context = KRB5_DB_GET_DB_CONTEXT(context);
3065 if (*db_context == NULL) {
3066 return KRB5_KDB_DBNOTINITED;
3073 krb5_db_set_context(krb5_context context, void *db_context)
3075 KRB5_DB_GET_DB_CONTEXT(context) = db_context;
3081 krb5_db_invoke(krb5_context kcontext,
3082 unsigned int method,
3083 const krb5_data *req,
3086 krb5_error_code status = 0;
3087 kdb5_dal_handle *dal_handle;
3089 if (kcontext->dal_handle == NULL) {
3090 status = kdb_setup_lib_handle(kcontext);
3096 dal_handle = kcontext->dal_handle;
3097 if (dal_handle->lib_handle->vftabl.db_invoke == NULL) {
3098 status = KRB5_KDB_DBTYPE_NOSUP;
3102 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
3108 dal_handle->lib_handle->vftabl.db_invoke(kcontext,
3112 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);