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)
118 idx = (key->key_data_ver == 1 ? 1 : 2);
119 for (i = 0; i < idx; i++) {
120 if (key->key_data_contents[i]) {
121 zap(key->key_data_contents[i], key->key_data_length[i]);
122 free(key->key_data_contents[i]);
129 krb5_dbe_free_key_list(krb5_context context, krb5_keylist_node *val)
131 krb5_keylist_node *temp = val, *prev;
133 while (temp != NULL) {
136 krb5_free_keyblock_contents(context, &(prev->keyblock));
142 krb5_dbe_free_actkvno_list(krb5_context context, krb5_actkvno_node *val)
144 krb5_actkvno_node *temp = val, *prev;
146 while (temp != NULL) {
154 krb5_dbe_free_mkey_aux_list(krb5_context context, krb5_mkey_aux_node *val)
156 krb5_mkey_aux_node *temp = val, *prev;
158 while (temp != NULL) {
161 krb5_dbe_free_key_data_contents(context, &prev->latest_mkey);
167 krb5_dbe_free_tl_data(krb5_context context, krb5_tl_data *tl_data)
170 if (tl_data->tl_data_contents)
171 free(tl_data->tl_data_contents);
176 #define kdb_init_lib_lock(a) 0
177 #define kdb_destroy_lib_lock(a) (void)0
178 #define kdb_lock_lib_lock(a, b) 0
179 #define kdb_unlock_lib_lock(a, b) (void)0
181 /* Caller must free result*/
184 kdb_get_conf_section(krb5_context kcontext)
186 krb5_error_code status = 0;
190 if (kcontext->default_realm == NULL)
192 /* The profile has to have been initialized. If the profile was
193 not initialized, expect nothing less than a crash. */
194 status = profile_get_string(kcontext->profile,
197 kcontext->default_realm,
198 /* under the realm name, database_module */
200 /* default value is the realm name itself */
201 kcontext->default_realm,
206 result = strdup(kcontext->default_realm);
207 /* let NULL be handled by the caller */
209 result = strdup(value);
210 /* free profile string */
211 profile_release_string(value);
218 kdb_get_library_name(krb5_context kcontext)
220 krb5_error_code status = 0;
225 status = profile_get_string(kcontext->profile,
228 kcontext->default_realm,
229 /* under the realm name, database_module */
231 /* default value is the realm name itself */
232 kcontext->default_realm,
238 #define DB2_NAME "db2"
239 /* we got the module section. Get the library name from the module */
240 status = profile_get_string(kcontext->profile, KDB_MODULE_SECTION, value,
250 result = strdup(lib);
253 /* free profile string */
254 profile_release_string(value);
258 /* free profile string */
259 profile_release_string(lib);
265 kdb_setup_opt_functions(db_library lib)
267 if (lib->vftabl.set_master_key == NULL) {
268 lib->vftabl.set_master_key = kdb_def_set_mkey;
271 if (lib->vftabl.set_master_key_list == NULL) {
272 lib->vftabl.set_master_key_list = kdb_def_set_mkey_list;
275 if (lib->vftabl.get_master_key == NULL) {
276 lib->vftabl.get_master_key = kdb_def_get_mkey;
279 if (lib->vftabl.get_master_key_list == NULL) {
280 lib->vftabl.get_master_key_list = kdb_def_get_mkey_list;
283 if (lib->vftabl.fetch_master_key == NULL) {
284 lib->vftabl.fetch_master_key = krb5_db_def_fetch_mkey;
287 if (lib->vftabl.verify_master_key == NULL) {
288 lib->vftabl.verify_master_key = krb5_def_verify_master_key;
291 if (lib->vftabl.fetch_master_key_list == NULL) {
292 lib->vftabl.fetch_master_key_list = krb5_def_fetch_mkey_list;
295 if (lib->vftabl.store_master_key_list == NULL) {
296 lib->vftabl.store_master_key_list = krb5_def_store_mkey_list;
299 if (lib->vftabl.dbe_search_enctype == NULL) {
300 lib->vftabl.dbe_search_enctype = krb5_dbe_def_search_enctype;
303 if (lib->vftabl.db_change_pwd == NULL) {
304 lib->vftabl.db_change_pwd = krb5_dbe_def_cpw;
307 if (lib->vftabl.store_master_key == NULL) {
308 lib->vftabl.store_master_key = krb5_def_store_mkey;
311 if (lib->vftabl.promote_db == NULL) {
312 lib->vftabl.promote_db = krb5_def_promote_db;
315 if (lib->vftabl.dbekd_decrypt_key_data == NULL) {
316 lib->vftabl.dbekd_decrypt_key_data = krb5_dbekd_def_decrypt_key_data;
319 if (lib->vftabl.dbekd_encrypt_key_data == NULL) {
320 lib->vftabl.dbekd_encrypt_key_data = krb5_dbekd_def_encrypt_key_data;
324 static int kdb_db2_pol_err_loaded = 0;
325 #ifdef _KDB5_STATIC_LINK
326 #define DEF_SYMBOL(a) extern kdb_vftabl krb5_db_vftabl_ ## a
327 #define GET_SYMBOL(a) (krb5_db_vftabl_ ## a)
328 static krb5_error_code
329 kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib)
331 krb5_error_code status;
332 void *vftabl_addr = NULL;
333 char buf[KRB5_MAX_ERR_STR];
335 if (!strcmp("kdb_db2", lib_name) && (kdb_db2_pol_err_loaded == 0)) {
336 initialize_adb_error_table();
337 kdb_db2_pol_err_loaded = 1;
340 *lib = calloc((size_t) 1, sizeof(**lib));
346 status = kdb_init_lib_lock(*lib);
351 strlcpy((*lib)->name, lib_name, sizeof((*lib)->name));
353 #if !defined(KDB5_USE_LIB_KDB_DB2) && !defined(KDB5_USE_LIB_TEST)
354 #error No database module defined
357 #ifdef KDB5_USE_LIB_KDB_DB2
358 if (strcmp(lib_name, "kdb_db2") == 0) {
360 vftabl_addr = (void *) &GET_SYMBOL(kdb_db2);
363 #ifdef KDB5_USE_LIB_TEST
364 if (strcmp(lib_name, "test") == 0) {
366 vftabl_addr = (void *) &GET_SYMBOL(test);
370 snprintf(buf, sizeof(buf),
371 "Program not built to support %s database type\n",
373 status = KRB5_KDB_DBTYPE_NOSUP;
374 krb5_db_set_err(kcontext, krb5_err_have_str, status, buf);
378 memcpy(&(*lib)->vftabl, vftabl_addr, sizeof(kdb_vftabl));
380 kdb_setup_opt_functions(*lib);
382 if ((status = (*lib)->vftabl.init_library())) {
383 /* ERROR. library not initialized cleanly */
384 snprintf(buf, sizeof(buf),
385 "%s library initialization failed, error code %ld\n",
387 status = KRB5_KDB_DBTYPE_INIT;
388 krb5_db_set_err(kcontext, krb5_err_have_str, status, buf);
394 free(*lib), *lib = NULL;
399 #else /* KDB5_STATIC_LINK*/
401 static char *db_dl_location[] = DEFAULT_KDB_LIB_PATH;
402 #define db_dl_n_locations (sizeof(db_dl_location) / sizeof(db_dl_location[0]))
404 static krb5_error_code
405 kdb_load_library(krb5_context kcontext, char *lib_name, db_library * lib)
407 krb5_error_code status = 0;
409 void **vftabl_addrs = NULL;
410 /* N.B.: If this is "const" but not "static", the Solaris 10
411 native compiler has trouble building the library because of
412 absolute relocations needed in read-only section ".rodata".
413 When it's static, it goes into ".picdata", which is
415 static const char *const dbpath_names[] = {
416 KDB_MODULE_SECTION, KRB5_CONF_DB_MODULE_DIR, NULL,
418 const char *filebases[2];
419 char **profpath = NULL;
422 filebases[0] = lib_name;
425 if (!strcmp(DB2_NAME, lib_name) && (kdb_db2_pol_err_loaded == 0)) {
426 initialize_adb_error_table();
427 kdb_db2_pol_err_loaded = 1;
430 *lib = calloc((size_t) 1, sizeof(**lib));
436 status = kdb_init_lib_lock(*lib);
441 strlcpy((*lib)->name, lib_name, sizeof((*lib)->name));
443 /* Fetch the list of directories specified in the config
445 status = profile_get_values(kcontext->profile, dbpath_names, &profpath);
446 if (status != 0 && status != PROF_NO_RELATION)
450 while (profpath[ndx] != NULL)
453 path = calloc(ndx + db_dl_n_locations, sizeof (char *));
459 memcpy(path, profpath, ndx * sizeof(profpath[0]));
460 memcpy(path + ndx, db_dl_location, db_dl_n_locations * sizeof(char *));
463 if ((status = krb5int_open_plugin_dirs ((const char **) path,
465 &(*lib)->dl_dir_handle, &kcontext->err))) {
466 const char *err_str = krb5_get_error_message(kcontext, status);
467 status = KRB5_KDB_DBTYPE_NOTFOUND;
468 krb5_set_error_message (kcontext, status,
469 "Unable to find requested database type: %s", err_str);
470 krb5_free_error_message (kcontext, err_str);
474 if ((status = krb5int_get_plugin_dir_data (&(*lib)->dl_dir_handle, "kdb_function_table",
475 &vftabl_addrs, &kcontext->err))) {
476 const char *err_str = krb5_get_error_message(kcontext, status);
477 status = KRB5_KDB_DBTYPE_INIT;
478 krb5_set_error_message (kcontext, status,
479 "plugin symbol 'kdb_function_table' lookup failed: %s", err_str);
480 krb5_free_error_message (kcontext, err_str);
484 if (vftabl_addrs[0] == NULL) {
486 status = KRB5_KDB_DBTYPE_NOTFOUND;
487 krb5_set_error_message (kcontext, status,
488 _("Unable to load requested database module '%s': plugin symbol 'kdb_function_table' not found"),
493 memcpy(&(*lib)->vftabl, vftabl_addrs[0], sizeof(kdb_vftabl));
494 kdb_setup_opt_functions(*lib);
496 if ((status = (*lib)->vftabl.init_library())) {
497 /* ERROR. library not initialized cleanly */
502 if (vftabl_addrs != NULL) { krb5int_free_plugin_dir_data (vftabl_addrs); }
503 /* Both of these DTRT with NULL. */
504 profile_free_list(profpath);
508 kdb_destroy_lib_lock(*lib);
509 if (PLUGIN_DIR_OPEN((&(*lib)->dl_dir_handle))) {
510 krb5int_close_plugin_dirs (&(*lib)->dl_dir_handle);
519 #endif /* end of _KDB5_STATIC_LINK */
521 static krb5_error_code
522 kdb_find_library(krb5_context kcontext, char *lib_name, db_library * lib)
524 /* lock here so that no two threads try to do the same at the same time */
525 krb5_error_code status = 0;
527 db_library curr_elt, prev_elt = NULL;
529 if ((status = kdb_lock_list()) != 0) {
535 while (curr_elt != NULL) {
536 if (strcmp(lib_name, curr_elt->name) == 0) {
541 curr_elt = curr_elt->next;
544 /* module not found. create and add to list */
545 status = kdb_load_library(kcontext, lib_name, lib);
551 /* prev_elt points to the last element in the list */
552 prev_elt->next = *lib;
553 (*lib)->prev = prev_elt;
560 (*lib)->reference_cnt++;
570 static krb5_error_code
571 kdb_free_library(db_library lib)
573 krb5_error_code status = 0;
576 if ((status = kdb_lock_list()) != 0) {
581 lib->reference_cnt--;
583 if (lib->reference_cnt == 0) {
584 status = lib->vftabl.fini_library();
589 /* close the library */
590 if (PLUGIN_DIR_OPEN((&lib->dl_dir_handle))) {
591 krb5int_close_plugin_dirs (&lib->dl_dir_handle);
594 kdb_destroy_lib_lock(lib);
596 if (lib->prev == NULL) {
597 /* first element in the list */
598 lib_list = lib->next;
600 lib->prev->next = lib->next;
604 lib->next->prev = lib->prev;
617 static krb5_error_code
618 kdb_setup_lib_handle(krb5_context kcontext)
620 char *library = NULL;
621 krb5_error_code status = 0;
622 db_library lib = NULL;
623 kdb5_dal_handle *dal_handle = NULL;
625 dal_handle = calloc((size_t) 1, sizeof(kdb5_dal_handle));
626 if (dal_handle == NULL) {
631 library = kdb_get_library_name(kcontext);
632 if (library == NULL) {
633 status = KRB5_KDB_DBTYPE_NOTFOUND;
637 status = kdb_find_library(kcontext, library, &lib);
642 dal_handle->lib_handle = lib;
643 kcontext->dal_handle = dal_handle;
651 kdb_free_library(lib);
658 static krb5_error_code
659 kdb_free_lib_handle(krb5_context kcontext)
661 krb5_error_code status = 0;
663 status = kdb_free_library(kcontext->dal_handle->lib_handle);
668 free(kcontext->dal_handle);
669 kcontext->dal_handle = NULL;
676 get_errmsg (krb5_context kcontext, krb5_error_code err_code)
678 kdb5_dal_handle *dal_handle;
682 assert(kcontext != NULL);
683 /* Must be called with dal_handle->lib_handle locked! */
684 assert(kcontext->dal_handle != NULL);
685 dal_handle = kcontext->dal_handle;
686 if (dal_handle->lib_handle->vftabl.errcode_2_string == NULL)
688 e = dal_handle->lib_handle->vftabl.errcode_2_string(kcontext, err_code);
690 krb5_set_error_message(kcontext, err_code, "%s", e);
691 if (dal_handle->lib_handle->vftabl.release_errcode_string)
692 dal_handle->lib_handle->vftabl.release_errcode_string(kcontext, e);
696 * External functions... DAL API
699 krb5_db_open(krb5_context kcontext, char **db_args, int mode)
701 krb5_error_code status = 0;
702 char *section = NULL;
703 kdb5_dal_handle *dal_handle;
705 section = kdb_get_conf_section(kcontext);
706 if (section == NULL) {
707 status = KRB5_KDB_SERVER_INTERNAL_ERR;
708 krb5_set_error_message (kcontext, status,
709 "unable to determine configuration section for realm %s\n",
710 kcontext->default_realm ? kcontext->default_realm : "[UNSET]");
714 if (kcontext->dal_handle == NULL) {
715 status = kdb_setup_lib_handle(kcontext);
721 dal_handle = kcontext->dal_handle;
722 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
728 dal_handle->lib_handle->vftabl.init_module(kcontext, section, db_args,
730 get_errmsg(kcontext, status);
732 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
741 krb5_db_inited(krb5_context kcontext)
743 return !(kcontext && kcontext->dal_handle &&
744 kcontext->dal_handle->db_context);
748 krb5_db_create(krb5_context kcontext, char **db_args)
750 krb5_error_code status = 0;
751 char *section = NULL;
752 kdb5_dal_handle *dal_handle;
754 section = kdb_get_conf_section(kcontext);
755 if (section == NULL) {
756 status = KRB5_KDB_SERVER_INTERNAL_ERR;
757 krb5_set_error_message (kcontext, status,
758 "unable to determine configuration section for realm %s\n",
759 kcontext->default_realm);
763 if (kcontext->dal_handle == NULL) {
764 status = kdb_setup_lib_handle(kcontext);
770 dal_handle = kcontext->dal_handle;
771 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
777 dal_handle->lib_handle->vftabl.db_create(kcontext, section, db_args);
778 get_errmsg(kcontext, status);
780 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
789 krb5_db_fini(krb5_context kcontext)
791 krb5_error_code status = 0;
792 kdb5_dal_handle *dal_handle;
794 if (kcontext->dal_handle == NULL) {
795 /* module not loaded. So nothing to be done */
799 dal_handle = kcontext->dal_handle;
800 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
805 status = dal_handle->lib_handle->vftabl.fini_module(kcontext);
806 get_errmsg(kcontext, status);
808 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
814 status = kdb_free_lib_handle(kcontext);
821 krb5_db_destroy(krb5_context kcontext, char **db_args)
823 krb5_error_code status = 0;
824 char *section = NULL;
825 kdb5_dal_handle *dal_handle;
827 section = kdb_get_conf_section(kcontext);
828 if (section == NULL) {
829 status = KRB5_KDB_SERVER_INTERNAL_ERR;
830 krb5_set_error_message (kcontext, status,
831 "unable to determine configuration section for realm %s\n",
832 kcontext->default_realm);
836 if (kcontext->dal_handle == NULL) {
837 status = kdb_setup_lib_handle(kcontext);
843 dal_handle = kcontext->dal_handle;
844 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
850 dal_handle->lib_handle->vftabl.db_destroy(kcontext, section, db_args);
851 get_errmsg(kcontext, status);
852 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
861 krb5_db_get_age(krb5_context kcontext, char *db_name, time_t * t)
863 krb5_error_code status = 0;
864 kdb5_dal_handle *dal_handle;
866 if (kcontext->dal_handle == NULL) {
867 status = kdb_setup_lib_handle(kcontext);
873 dal_handle = kcontext->dal_handle;
874 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
879 status = dal_handle->lib_handle->vftabl.db_get_age(kcontext, db_name, t);
880 get_errmsg(kcontext, status);
881 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
888 krb5_db_set_option(krb5_context kcontext, int option, void *value)
890 krb5_error_code status = 0;
891 kdb5_dal_handle *dal_handle;
893 if (kcontext->dal_handle == NULL) {
894 status = kdb_setup_lib_handle(kcontext);
900 dal_handle = kcontext->dal_handle;
901 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
907 dal_handle->lib_handle->vftabl.db_set_option(kcontext, option, value);
908 get_errmsg(kcontext, status);
909 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
916 krb5_db_lock(krb5_context kcontext, int lock_mode)
918 krb5_error_code status = 0;
919 kdb5_dal_handle *dal_handle;
921 if (kcontext->dal_handle == NULL) {
922 status = kdb_setup_lib_handle(kcontext);
928 dal_handle = kcontext->dal_handle;
929 /* acquire an exclusive lock, ensures no other thread uses this context */
930 status = kdb_lock_lib_lock(dal_handle->lib_handle, TRUE);
935 status = dal_handle->lib_handle->vftabl.db_lock(kcontext, lock_mode);
936 get_errmsg(kcontext, status);
938 /* exclusive lock is still held, so no other thread could use this context */
939 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
946 krb5_db_unlock(krb5_context kcontext)
948 krb5_error_code status = 0;
949 kdb5_dal_handle *dal_handle;
951 if (kcontext->dal_handle == NULL) {
952 status = kdb_setup_lib_handle(kcontext);
958 dal_handle = kcontext->dal_handle;
959 /* normal lock acquired and exclusive lock released */
960 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
965 status = dal_handle->lib_handle->vftabl.db_unlock(kcontext);
966 get_errmsg(kcontext, status);
968 kdb_unlock_lib_lock(dal_handle->lib_handle, TRUE);
975 krb5_db_get_principal(krb5_context kcontext,
976 krb5_const_principal search_for,
977 krb5_db_entry * entries,
978 int *nentries, krb5_boolean * more)
980 krb5_error_code status = 0;
981 kdb5_dal_handle *dal_handle;
983 if (kcontext->dal_handle == NULL) {
984 status = kdb_setup_lib_handle(kcontext);
990 dal_handle = kcontext->dal_handle;
991 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
997 dal_handle->lib_handle->vftabl.db_get_principal(kcontext, search_for, 0,
1000 get_errmsg(kcontext, status);
1001 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1008 krb5_db_get_principal_ext(krb5_context kcontext,
1009 krb5_const_principal search_for,
1011 krb5_db_entry * entries,
1012 int *nentries, krb5_boolean * more)
1014 krb5_error_code status = 0;
1015 kdb5_dal_handle *dal_handle;
1017 if (kcontext->dal_handle == NULL) {
1018 status = kdb_setup_lib_handle(kcontext);
1024 dal_handle = kcontext->dal_handle;
1025 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1031 dal_handle->lib_handle->vftabl.db_get_principal(kcontext, search_for,
1035 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1042 krb5_db_free_principal(krb5_context kcontext, krb5_db_entry * entry, int count)
1044 krb5_error_code status = 0;
1045 kdb5_dal_handle *dal_handle;
1047 if (kcontext->dal_handle == NULL) {
1048 status = kdb_setup_lib_handle(kcontext);
1054 dal_handle = kcontext->dal_handle;
1055 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1061 dal_handle->lib_handle->vftabl.db_free_principal(kcontext, entry,
1063 get_errmsg(kcontext, status);
1064 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1071 free_db_args(krb5_context kcontext, char **db_args)
1075 /* XXX Is this right? Or are we borrowing storage from
1077 for (i = 0; db_args[i]; i++)
1078 krb5_db_free(kcontext, db_args[i]);
1083 static krb5_error_code
1084 extract_db_args_from_tl_data(krb5_context kcontext,
1085 krb5_tl_data **start, krb5_int16 *count,
1088 char **db_args = NULL;
1089 int db_args_size = 0;
1090 krb5_tl_data *prev, *curr, *next;
1091 krb5_error_code status;
1093 /* Giving db_args as part of tl data causes db2 to store the
1094 tl_data as such. To prevent this, tl_data is collated and
1095 passed as a separate argument. Currently supports only one
1096 principal, but passing it as a separate argument makes it
1097 difficult for kadmin remote to pass arguments to server. */
1098 prev = NULL, curr = *start;
1100 if (curr->tl_data_type == KRB5_TL_DB_ARGS) {
1102 /* Since this is expected to be NULL terminated string and
1103 this could come from any client, do a check before
1104 passing it to db. */
1105 if (((char *) curr->tl_data_contents)[curr->tl_data_length - 1] !=
1107 /* Not null terminated. Dangerous input. */
1113 t = realloc(db_args, sizeof(char *) * (db_args_size + 1)); /* 1 for NULL */
1120 db_args[db_args_size - 1] = (char *) curr->tl_data_contents;
1121 db_args[db_args_size] = NULL;
1123 next = curr->tl_data_next;
1125 /* current node is the first in the linked list. remove it */
1126 *start = curr->tl_data_next;
1128 prev->tl_data_next = curr->tl_data_next;
1131 krb5_db_free(kcontext, curr);
1133 /* previous does not change */
1137 curr = curr->tl_data_next;
1143 free_db_args(kcontext, db_args);
1146 *db_argsp = db_args;
1151 krb5int_put_principal_no_log(krb5_context kcontext,
1152 krb5_db_entry *entries, int *nentries)
1154 kdb5_dal_handle *dal_handle;
1155 krb5_error_code status;
1158 status = extract_db_args_from_tl_data(kcontext, &entries->tl_data,
1159 &entries->n_tl_data,
1163 assert (kcontext->dal_handle != NULL); /* XXX */
1164 dal_handle = kcontext->dal_handle;
1166 status = dal_handle->lib_handle->vftabl.db_put_principal(kcontext, entries,
1169 get_errmsg(kcontext, status);
1170 free_db_args(kcontext, db_args);
1175 krb5_db_put_principal(krb5_context kcontext,
1176 krb5_db_entry * entries, int *nentries)
1178 krb5_error_code status = 0;
1179 kdb5_dal_handle *dal_handle;
1180 char **db_args = NULL;
1181 kdb_incr_update_t *upd, *fupd = 0;
1182 char *princ_name = NULL;
1183 kdb_log_context *log_ctx;
1185 int ulog_locked = 0;
1187 log_ctx = kcontext->kdblog_context;
1189 if (kcontext->dal_handle == NULL) {
1190 status = kdb_setup_lib_handle(kcontext);
1196 status = extract_db_args_from_tl_data(kcontext, &entries->tl_data,
1197 &entries->n_tl_data,
1202 dal_handle = kcontext->dal_handle;
1203 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1209 * We need the lock since ulog_conv_2logentry() does a get
1211 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
1212 if (!(upd = (kdb_incr_update_t *)
1213 malloc(sizeof (kdb_incr_update_t)* *nentries))) {
1219 (void) memset(upd, 0, sizeof(kdb_incr_update_t)* *nentries);
1221 if ((status = ulog_conv_2logentry(kcontext, entries, upd, *nentries))) {
1226 status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
1231 for (i = 0; i < *nentries; i++) {
1233 * We'll be sharing the same locks as db for logging
1236 if ((status = krb5_unparse_name(kcontext, entries->princ,
1240 upd->kdb_princ_name.utf8str_t_val = princ_name;
1241 upd->kdb_princ_name.utf8str_t_len = strlen(princ_name);
1243 if ((status = ulog_add_update(kcontext, upd)) != 0)
1249 status = dal_handle->lib_handle->vftabl.db_put_principal(kcontext, entries,
1252 get_errmsg(kcontext, status);
1253 if (status == 0 && fupd) {
1255 for (i = 0; i < *nentries; i++) {
1256 (void) ulog_finish_update(kcontext, upd);
1262 ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
1264 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1267 free_db_args(kcontext, db_args);
1269 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER))
1270 ulog_free_entries(fupd, *nentries);
1276 krb5int_delete_principal_no_log(krb5_context kcontext,
1277 krb5_principal search_for,
1280 kdb5_dal_handle *dal_handle;
1281 krb5_error_code status;
1283 assert (kcontext->dal_handle != NULL); /* XXX */
1285 dal_handle = kcontext->dal_handle;
1287 status = dal_handle->lib_handle->vftabl.db_delete_principal(kcontext,
1290 get_errmsg(kcontext, status);
1295 krb5_db_delete_principal(krb5_context kcontext,
1296 krb5_principal search_for, int *nentries)
1298 krb5_error_code status = 0;
1299 kdb5_dal_handle *dal_handle;
1300 kdb_incr_update_t upd;
1301 char *princ_name = NULL;
1302 kdb_log_context *log_ctx;
1304 log_ctx = kcontext->kdblog_context;
1306 if (kcontext->dal_handle == NULL) {
1307 status = kdb_setup_lib_handle(kcontext);
1313 dal_handle = kcontext->dal_handle;
1314 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1319 status = ulog_lock(kcontext, KRB5_LOCKMODE_EXCLUSIVE);
1321 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1326 * We'll be sharing the same locks as db for logging
1328 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER)) {
1329 if ((status = krb5_unparse_name(kcontext, search_for, &princ_name))) {
1330 ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
1331 (void) kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1335 (void) memset(&upd, 0, sizeof (kdb_incr_update_t));
1337 upd.kdb_princ_name.utf8str_t_val = princ_name;
1338 upd.kdb_princ_name.utf8str_t_len = strlen(princ_name);
1340 if ((status = ulog_delete_update(kcontext, &upd)) != 0) {
1341 ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
1343 (void) kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1350 status = dal_handle->lib_handle->vftabl.db_delete_principal(kcontext,
1353 get_errmsg(kcontext, status);
1356 * We need to commit our update upon success
1359 if (log_ctx && (log_ctx->iproprole == IPROP_MASTER))
1360 (void) ulog_finish_update(kcontext, &upd);
1362 ulog_lock(kcontext, KRB5_LOCKMODE_UNLOCK);
1363 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1370 krb5_db_iterate(krb5_context kcontext,
1372 int (*func) (krb5_pointer, krb5_db_entry *),
1373 krb5_pointer func_arg)
1375 krb5_error_code status = 0;
1376 kdb5_dal_handle *dal_handle;
1378 if (kcontext->dal_handle == NULL) {
1379 status = kdb_setup_lib_handle(kcontext);
1385 dal_handle = kcontext->dal_handle;
1386 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1391 status = dal_handle->lib_handle->vftabl.db_iterate(kcontext,
1394 get_errmsg(kcontext, status);
1395 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1402 krb5_supported_realms(krb5_context kcontext, char **realms)
1404 krb5_error_code status = 0;
1405 kdb5_dal_handle *dal_handle;
1407 if (kcontext->dal_handle == NULL) {
1408 status = kdb_setup_lib_handle(kcontext);
1414 dal_handle = kcontext->dal_handle;
1415 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1421 dal_handle->lib_handle->vftabl.db_supported_realms(kcontext, realms);
1422 get_errmsg(kcontext, status);
1423 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1430 krb5_free_supported_realms(krb5_context kcontext, char **realms)
1432 krb5_error_code status = 0;
1433 kdb5_dal_handle *dal_handle;
1435 if (kcontext->dal_handle == NULL) {
1436 status = kdb_setup_lib_handle(kcontext);
1442 dal_handle = kcontext->dal_handle;
1443 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1449 dal_handle->lib_handle->vftabl.db_free_supported_realms(kcontext,
1451 get_errmsg(kcontext, status);
1452 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1459 krb5_db_set_master_key_ext(krb5_context kcontext,
1460 char *pwd, krb5_keyblock * key)
1462 krb5_error_code status = 0;
1463 kdb5_dal_handle *dal_handle;
1465 if (kcontext->dal_handle == NULL) {
1466 status = kdb_setup_lib_handle(kcontext);
1472 dal_handle = kcontext->dal_handle;
1473 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1478 status = dal_handle->lib_handle->vftabl.set_master_key(kcontext, pwd, key);
1479 get_errmsg(kcontext, status);
1481 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1488 krb5_db_set_mkey(krb5_context context, krb5_keyblock * key)
1490 return krb5_db_set_master_key_ext(context, NULL, key);
1494 krb5_db_set_mkey_list(krb5_context kcontext,
1495 krb5_keylist_node * keylist)
1497 krb5_error_code status = 0;
1498 kdb5_dal_handle *dal_handle;
1500 if (kcontext->dal_handle == NULL) {
1501 status = kdb_setup_lib_handle(kcontext);
1507 dal_handle = kcontext->dal_handle;
1508 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1513 status = dal_handle->lib_handle->vftabl.set_master_key_list(kcontext, keylist);
1514 get_errmsg(kcontext, status);
1516 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1523 krb5_db_get_mkey(krb5_context kcontext, krb5_keyblock ** key)
1525 krb5_error_code status = 0;
1526 kdb5_dal_handle *dal_handle;
1528 if (kcontext->dal_handle == NULL) {
1529 status = kdb_setup_lib_handle(kcontext);
1535 dal_handle = kcontext->dal_handle;
1536 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1541 /* Let's use temp key and copy it later to avoid memory problems
1542 when freed by the caller. */
1543 status = dal_handle->lib_handle->vftabl.get_master_key(kcontext, key);
1544 get_errmsg(kcontext, status);
1545 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1552 krb5_db_get_mkey_list(krb5_context kcontext, krb5_keylist_node ** keylist)
1554 krb5_error_code status = 0;
1555 kdb5_dal_handle *dal_handle;
1557 if (kcontext->dal_handle == NULL) {
1558 status = kdb_setup_lib_handle(kcontext);
1564 dal_handle = kcontext->dal_handle;
1565 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1570 /* Let's use temp key and copy it later to avoid memory problems
1571 when freed by the caller. */
1572 status = dal_handle->lib_handle->vftabl.get_master_key_list(kcontext, keylist);
1573 get_errmsg(kcontext, status);
1574 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1581 krb5_db_fetch_mkey_list(krb5_context context,
1582 krb5_principal mname,
1583 const krb5_keyblock * mkey,
1585 krb5_keylist_node **mkey_list)
1587 kdb5_dal_handle *dal_handle;
1588 krb5_error_code status = 0;
1590 if (context->dal_handle == NULL) {
1591 status = kdb_setup_lib_handle(context);
1597 dal_handle = context->dal_handle;
1598 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1603 status = dal_handle->lib_handle->vftabl.fetch_master_key_list(context,
1608 get_errmsg(context, status);
1609 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1620 krb5_db_free_mkey_list(krb5_context context,
1621 krb5_keylist_node *mkey_list)
1623 krb5_keylist_node *cur, *prev;
1625 for (cur = mkey_list; cur != NULL;) {
1628 krb5_free_keyblock_contents(context, &prev->keyblock);
1636 krb5_db_store_master_key(krb5_context kcontext,
1638 krb5_principal mname,
1640 krb5_keyblock * key, char *master_pwd)
1642 krb5_error_code status = 0;
1643 kdb5_dal_handle *dal_handle;
1645 if (kcontext->dal_handle == NULL) {
1646 status = kdb_setup_lib_handle(kcontext);
1652 dal_handle = kcontext->dal_handle;
1653 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1658 status = dal_handle->lib_handle->vftabl.store_master_key(kcontext,
1663 get_errmsg(kcontext, status);
1664 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1671 krb5_db_store_master_key_list(krb5_context kcontext,
1673 krb5_principal mname,
1674 krb5_keylist_node *keylist,
1677 krb5_error_code status = 0;
1678 kdb5_dal_handle *dal_handle;
1680 if (kcontext->dal_handle == NULL) {
1681 status = kdb_setup_lib_handle(kcontext);
1687 dal_handle = kcontext->dal_handle;
1688 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1693 status = dal_handle->lib_handle->vftabl.store_master_key_list(kcontext,
1698 get_errmsg(kcontext, status);
1699 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1705 char *krb5_mkey_pwd_prompt1 = KRB5_KDC_MKEY_1;
1706 char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2;
1709 krb5_db_fetch_mkey(krb5_context context,
1710 krb5_principal mname,
1712 krb5_boolean fromkeyboard,
1717 krb5_keyblock * key)
1719 krb5_error_code retval;
1720 char password[BUFSIZ];
1722 unsigned int size = sizeof(password);
1723 krb5_keyblock tmp_key;
1725 memset(&tmp_key, 0, sizeof(tmp_key));
1730 if ((retval = krb5_read_password(context, krb5_mkey_pwd_prompt1,
1731 twice ? krb5_mkey_pwd_prompt2 : 0,
1732 password, &size))) {
1736 pwd.data = password;
1739 retval = krb5_principal2salt(context, mname, &scratch);
1744 krb5_c_string_to_key(context, etype, &pwd, salt ? salt : &scratch,
1747 * If a kvno pointer was passed in and it dereferences the IGNORE_VNO
1748 * value then it should be assigned the value of the kvno associated
1749 * with the current mkey princ key if that princ entry is available
1750 * otherwise assign 1 which is the default kvno value for the mkey
1753 if (kvno != NULL && *kvno == IGNORE_VNO) {
1757 krb5_db_entry master_entry;
1759 rc = krb5_db_get_principal(context, mname,
1760 &master_entry, &nentries, &more);
1762 if (rc == 0 && nentries == 1 && more == FALSE)
1763 *kvno = (krb5_kvno) master_entry.key_data->key_data_kvno;
1767 if (rc == 0 && nentries)
1768 krb5_db_free_principal(context, &master_entry, nentries);
1773 zap(password, sizeof(password)); /* erase it */
1776 kdb5_dal_handle *dal_handle;
1778 if (context->dal_handle == NULL) {
1779 retval = kdb_setup_lib_handle(context);
1785 dal_handle = context->dal_handle;
1786 retval = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1791 /* get the enctype from the stash */
1792 tmp_key.enctype = ENCTYPE_UNKNOWN;
1794 retval = dal_handle->lib_handle->vftabl.fetch_master_key(context,
1799 get_errmsg(context, retval);
1800 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1806 key->contents = malloc(tmp_key.length);
1807 if (key->contents == NULL) {
1812 key->magic = tmp_key.magic;
1813 key->enctype = tmp_key.enctype;
1814 key->length = tmp_key.length;
1815 memcpy(key->contents, tmp_key.contents, tmp_key.length);
1819 if (tmp_key.contents) {
1820 zap(tmp_key.contents, tmp_key.length);
1821 krb5_db_free(context, tmp_key.contents);
1827 krb5_db_verify_master_key(krb5_context kcontext,
1828 krb5_principal mprinc,
1830 krb5_keyblock * mkey)
1832 krb5_error_code status = 0;
1833 kdb5_dal_handle *dal_handle;
1835 if (kcontext->dal_handle == NULL) {
1836 status = kdb_setup_lib_handle(kcontext);
1842 dal_handle = kcontext->dal_handle;
1843 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
1848 status = dal_handle->lib_handle->vftabl.verify_master_key(kcontext,
1852 get_errmsg(kcontext, status);
1853 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
1860 krb5_dbe_fetch_act_key_list(krb5_context context,
1861 krb5_principal princ,
1862 krb5_actkvno_node **act_key_list)
1864 krb5_error_code retval = 0;
1865 krb5_db_entry entry;
1869 if (act_key_list == NULL)
1873 if ((retval = krb5_db_get_principal(context, princ, &entry,
1880 krb5_db_free_principal(context, &entry, nprinc);
1881 return (KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
1883 return(KRB5_KDB_NOMASTERKEY);
1886 krb5_db_free_principal(context, &entry, nprinc);
1887 return (KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
1890 retval = krb5_dbe_lookup_actkvno(context, &entry, act_key_list);
1892 if (*act_key_list == NULL) {
1893 krb5_actkvno_node *tmp_actkvno;
1895 * for mkey princ entries without KRB5_TL_ACTKVNO data provide a default
1898 tmp_actkvno = (krb5_actkvno_node *) malloc(sizeof(krb5_actkvno_node));
1899 if (tmp_actkvno == NULL)
1902 memset(tmp_actkvno, 0, sizeof(krb5_actkvno_node));
1903 tmp_actkvno->act_time = 0; /* earliest time possible */
1904 /* use most current key */
1905 tmp_actkvno->act_kvno = entry.key_data[0].key_data_kvno;
1906 *act_key_list = tmp_actkvno;
1909 krb5_db_free_principal(context, &entry, nprinc);
1914 * Locates the "active" mkey used when encrypting a princ's keys. Note, the
1915 * caller must NOT free the output act_mkey.
1919 krb5_dbe_find_act_mkey(krb5_context context,
1920 krb5_keylist_node *mkey_list,
1921 krb5_actkvno_node *act_mkey_list,
1922 krb5_kvno *act_kvno,
1923 krb5_keyblock **act_mkey)
1925 krb5_kvno tmp_act_kvno;
1926 krb5_error_code retval;
1927 krb5_keylist_node *cur_keyblock = mkey_list;
1928 krb5_actkvno_node *prev_actkvno, *cur_actkvno;
1930 krb5_boolean found = FALSE;
1932 if ((retval = krb5_timeofday(context, &now)))
1936 * The list should be sorted in time, early to later so if the first entry
1937 * is later than now, this is a problem. The fallback in this case is to
1938 * return the earlist activation entry.
1940 if (act_mkey_list->act_time > now) {
1941 while (cur_keyblock && cur_keyblock->kvno != act_mkey_list->act_kvno)
1942 cur_keyblock = cur_keyblock->next;
1944 *act_mkey = &cur_keyblock->keyblock;
1945 if (act_kvno != NULL)
1946 *act_kvno = cur_keyblock->kvno;
1949 return (KRB5_KDB_NOACTMASTERKEY);
1953 /* find the most current entry <= now */
1954 for (prev_actkvno = cur_actkvno = act_mkey_list; cur_actkvno != NULL;
1955 prev_actkvno = cur_actkvno, cur_actkvno = cur_actkvno->next) {
1957 if (cur_actkvno->act_time == now) {
1958 tmp_act_kvno = cur_actkvno->act_kvno;
1961 } else if (cur_actkvno->act_time > now && prev_actkvno->act_time <= now) {
1962 tmp_act_kvno = prev_actkvno->act_kvno;
1970 * The end of the list was encountered and all entries are < now so use
1973 if (prev_actkvno->act_time <= now) {
1974 tmp_act_kvno = prev_actkvno->act_kvno;
1976 /* XXX this shouldn't happen */
1977 return (KRB5_KDB_NOACTMASTERKEY);
1981 while (cur_keyblock && cur_keyblock->kvno != tmp_act_kvno)
1982 cur_keyblock = cur_keyblock->next;
1985 *act_mkey = &cur_keyblock->keyblock;
1986 if (act_kvno != NULL)
1987 *act_kvno = tmp_act_kvno;
1990 return (KRB5_KDB_NO_MATCHING_KEY);
1995 * Locates the mkey used to protect a princ's keys. Note, the caller must not
1996 * free the output key.
1999 krb5_dbe_find_mkey(krb5_context context,
2000 krb5_keylist_node * mkey_list,
2001 krb5_db_entry * entry,
2002 krb5_keyblock ** mkey)
2005 krb5_error_code retval;
2006 krb5_keylist_node *cur_keyblock = mkey_list;
2008 retval = krb5_dbe_lookup_mkvno(context, entry, &mkvno);
2012 while (cur_keyblock && cur_keyblock->kvno != mkvno)
2013 cur_keyblock = cur_keyblock->next;
2016 *mkey = &cur_keyblock->keyblock;
2019 return (KRB5_KDB_NO_MATCHING_KEY);
2024 krb5_db_alloc(krb5_context kcontext, void *ptr, size_t size)
2026 krb5_error_code status;
2027 kdb5_dal_handle *dal_handle;
2028 void *new_ptr = NULL;
2030 if (kcontext->dal_handle == NULL) {
2031 status = kdb_setup_lib_handle(kcontext);
2037 dal_handle = kcontext->dal_handle;
2039 new_ptr = dal_handle->lib_handle->vftabl.db_alloc(kcontext, ptr, size);
2046 krb5_db_free(krb5_context kcontext, void *ptr)
2048 krb5_error_code status;
2049 kdb5_dal_handle *dal_handle;
2051 if (kcontext->dal_handle == NULL) {
2052 status = kdb_setup_lib_handle(kcontext);
2058 dal_handle = kcontext->dal_handle;
2060 dal_handle->lib_handle->vftabl.db_free(kcontext, ptr);
2066 /* has to be modified */
2069 krb5_dbe_find_enctype(krb5_context kcontext,
2070 krb5_db_entry * dbentp,
2073 krb5_int32 kvno, krb5_key_data ** kdatap)
2075 krb5_int32 start = 0;
2076 return krb5_dbe_search_enctype(kcontext, dbentp, &start, ktype, stype,
2081 krb5_dbe_search_enctype(krb5_context kcontext,
2082 krb5_db_entry * dbentp,
2086 krb5_int32 kvno, krb5_key_data ** kdatap)
2088 krb5_error_code status = 0;
2089 kdb5_dal_handle *dal_handle;
2091 if (kcontext->dal_handle == NULL) {
2092 status = kdb_setup_lib_handle(kcontext);
2098 dal_handle = kcontext->dal_handle;
2099 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2104 status = dal_handle->lib_handle->vftabl.dbe_search_enctype(kcontext,
2110 get_errmsg(kcontext, status);
2111 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2117 #define REALM_SEP_STRING "@"
2120 krb5_db_setup_mkey_name(krb5_context context,
2121 const char *keyname,
2123 char **fullname, krb5_principal * principal)
2125 krb5_error_code retval;
2129 keyname = KRB5_KDB_M_NAME; /* XXX external? */
2131 if (asprintf(&fname, "%s%s%s", keyname, REALM_SEP_STRING, realm) < 0)
2134 if ((retval = krb5_parse_name(context, fname, principal)))
2144 krb5_dbe_lookup_last_pwd_change(context, entry, stamp)
2145 krb5_context context;
2146 krb5_db_entry *entry;
2147 krb5_timestamp *stamp;
2149 krb5_tl_data tl_data;
2150 krb5_error_code code;
2153 tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
2155 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2158 if (tl_data.tl_data_length != 4) {
2163 krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp);
2165 *stamp = (krb5_timestamp) tmp;
2171 krb5_dbe_lookup_tl_data(context, entry, ret_tl_data)
2172 krb5_context context;
2173 krb5_db_entry *entry;
2174 krb5_tl_data *ret_tl_data;
2176 krb5_tl_data *tl_data;
2178 for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) {
2179 if (tl_data->tl_data_type == ret_tl_data->tl_data_type) {
2180 *ret_tl_data = *tl_data;
2186 * If the requested record isn't found, return zero bytes. If it
2187 * ever means something to have a zero-length tl_data, this code
2188 * and its callers will have to be changed.
2191 ret_tl_data->tl_data_length = 0;
2192 ret_tl_data->tl_data_contents = NULL;
2197 krb5_dbe_create_key_data(context, entry)
2198 krb5_context context;
2199 krb5_db_entry *entry;
2201 if ((entry->key_data =
2202 (krb5_key_data *) krb5_db_alloc(context, entry->key_data,
2203 (sizeof(krb5_key_data) *
2204 (entry->n_key_data + 1)))) == NULL)
2207 memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data));
2208 entry->n_key_data++;
2214 krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ)
2215 krb5_context context;
2216 krb5_db_entry *entry;
2217 krb5_timestamp mod_date;
2218 krb5_const_principal mod_princ;
2220 krb5_tl_data tl_data;
2222 krb5_error_code retval = 0;
2223 krb5_octet *nextloc = 0;
2224 char *unparse_mod_princ = 0;
2225 unsigned int unparse_mod_princ_size;
2227 if ((retval = krb5_unparse_name(context, mod_princ, &unparse_mod_princ)))
2230 unparse_mod_princ_size = strlen(unparse_mod_princ) + 1;
2232 if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4))
2234 free(unparse_mod_princ);
2238 tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
2239 tl_data.tl_data_length = unparse_mod_princ_size + 4;
2240 tl_data.tl_data_contents = nextloc;
2243 krb5_kdb_encode_int32(mod_date, nextloc);
2246 memcpy(nextloc + 4, unparse_mod_princ, unparse_mod_princ_size);
2248 retval = krb5_dbe_update_tl_data(context, entry, &tl_data);
2250 free(unparse_mod_princ);
2257 krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ)
2258 krb5_context context;
2259 krb5_db_entry *entry;
2260 krb5_timestamp *mod_time;
2261 krb5_principal *mod_princ;
2263 krb5_tl_data tl_data;
2264 krb5_error_code code;
2269 tl_data.tl_data_type = KRB5_TL_MOD_PRINC;
2271 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2274 if ((tl_data.tl_data_length < 5) ||
2275 (tl_data.tl_data_contents[tl_data.tl_data_length - 1] != '\0'))
2276 return (KRB5_KDB_TRUNCATED_RECORD);
2279 krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time);
2282 if ((code = krb5_parse_name(context,
2283 (const char *) (tl_data.tl_data_contents + 4),
2291 krb5_dbe_lookup_mkvno(krb5_context context,
2292 krb5_db_entry *entry,
2295 krb5_tl_data tl_data;
2296 krb5_error_code code;
2299 tl_data.tl_data_type = KRB5_TL_MKVNO;
2301 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2304 if (tl_data.tl_data_length == 0) {
2305 *mkvno = 1; /* default for princs that lack the KRB5_TL_MKVNO data */
2307 } else if (tl_data.tl_data_length != 2) {
2308 return (KRB5_KDB_TRUNCATED_RECORD);
2311 krb5_kdb_decode_int16(tl_data.tl_data_contents, tmp);
2312 *mkvno = (krb5_kvno) tmp;
2317 krb5_dbe_update_mkvno(krb5_context context,
2318 krb5_db_entry * entry,
2321 krb5_tl_data tl_data;
2322 krb5_octet buf[2]; /* this is the encoded size of an int16 */
2323 krb5_int16 tmp_kvno = (krb5_int16) mkvno;
2325 tl_data.tl_data_type = KRB5_TL_MKVNO;
2326 tl_data.tl_data_length = sizeof(buf);
2327 krb5_kdb_encode_int16(tmp_kvno, buf);
2328 tl_data.tl_data_contents = buf;
2330 return (krb5_dbe_update_tl_data(context, entry, &tl_data));
2334 krb5_dbe_lookup_mkey_aux(krb5_context context,
2335 krb5_db_entry * entry,
2336 krb5_mkey_aux_node ** mkey_aux_data_list)
2338 krb5_tl_data tl_data;
2340 krb5_mkey_aux_node *head_data = NULL, *new_data = NULL,
2342 krb5_octet *curloc; /* current location pointer */
2343 krb5_error_code code;
2345 tl_data.tl_data_type = KRB5_TL_MKEY_AUX;
2346 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2349 if (tl_data.tl_data_contents == NULL) {
2350 *mkey_aux_data_list = NULL;
2353 /* get version to determine how to parse the data */
2354 krb5_kdb_decode_int16(tl_data.tl_data_contents, version);
2356 /* variable size, must be at least 10 bytes */
2357 if (tl_data.tl_data_length < 10)
2358 return (KRB5_KDB_TRUNCATED_RECORD);
2360 /* curloc points to first tuple entry in the tl_data_contents */
2361 curloc = tl_data.tl_data_contents + sizeof(version);
2363 while (curloc < (tl_data.tl_data_contents + tl_data.tl_data_length)) {
2365 new_data = (krb5_mkey_aux_node *) malloc(sizeof(krb5_mkey_aux_node));
2366 if (new_data == NULL) {
2367 krb5_dbe_free_mkey_aux_list(context, head_data);
2370 memset(new_data, 0, sizeof(krb5_mkey_aux_node));
2372 krb5_kdb_decode_int16(curloc, new_data->mkey_kvno);
2373 curloc += sizeof(krb5_ui_2);
2374 krb5_kdb_decode_int16(curloc, new_data->latest_mkey.key_data_kvno);
2375 curloc += sizeof(krb5_ui_2);
2376 krb5_kdb_decode_int16(curloc, new_data->latest_mkey.key_data_type[0]);
2377 curloc += sizeof(krb5_ui_2);
2378 krb5_kdb_decode_int16(curloc, new_data->latest_mkey.key_data_length[0]);
2379 curloc += sizeof(krb5_ui_2);
2381 new_data->latest_mkey.key_data_contents[0] = (krb5_octet *)
2382 malloc(new_data->latest_mkey.key_data_length[0]);
2384 if (new_data->latest_mkey.key_data_contents[0] == NULL) {
2385 krb5_dbe_free_mkey_aux_list(context, head_data);
2388 memcpy(new_data->latest_mkey.key_data_contents[0], curloc,
2389 new_data->latest_mkey.key_data_length[0]);
2390 curloc += new_data->latest_mkey.key_data_length[0];
2392 /* always using key data ver 1 for mkeys */
2393 new_data->latest_mkey.key_data_ver = 1;
2395 new_data->next = NULL;
2396 if (prev_data != NULL)
2397 prev_data->next = new_data;
2399 head_data = new_data;
2400 prev_data = new_data;
2403 krb5_set_error_message(context, KRB5_KDB_BAD_VERSION,
2404 "Illegal version number for KRB5_TL_MKEY_AUX %d\n",
2406 return (KRB5_KDB_BAD_VERSION);
2409 *mkey_aux_data_list = head_data;
2413 #if KRB5_TL_MKEY_AUX_VER == 1
2415 krb5_dbe_update_mkey_aux(krb5_context context,
2416 krb5_db_entry * entry,
2417 krb5_mkey_aux_node * mkey_aux_data_list)
2419 krb5_tl_data tl_data;
2420 krb5_int16 version, tmp_kvno;
2421 unsigned char *nextloc;
2422 krb5_mkey_aux_node *aux_data_entry;
2424 if (!mkey_aux_data_list) {
2425 /* delete the KRB5_TL_MKEY_AUX from the entry */
2426 krb5_dbe_delete_tl_data(context, entry, KRB5_TL_MKEY_AUX);
2430 memset(&tl_data, 0, sizeof(tl_data));
2431 tl_data.tl_data_type = KRB5_TL_MKEY_AUX;
2433 * determine out how much space to allocate. Note key_data_ver not stored
2434 * as this is hard coded to one and is accounted for in
2435 * krb5_dbe_lookup_mkey_aux.
2437 tl_data.tl_data_length = sizeof(version); /* version */
2438 for (aux_data_entry = mkey_aux_data_list; aux_data_entry != NULL;
2439 aux_data_entry = aux_data_entry->next) {
2441 tl_data.tl_data_length += (sizeof(krb5_ui_2) + /* mkey_kvno */
2442 sizeof(krb5_ui_2) + /* latest_mkey kvno */
2443 sizeof(krb5_ui_2) + /* latest_mkey enctype */
2444 sizeof(krb5_ui_2) + /* latest_mkey length */
2445 aux_data_entry->latest_mkey.key_data_length[0]);
2448 tl_data.tl_data_contents = (krb5_octet *) malloc(tl_data.tl_data_length);
2449 if (tl_data.tl_data_contents == NULL) {
2453 nextloc = tl_data.tl_data_contents;
2454 version = KRB5_TL_MKEY_AUX_VER;
2455 krb5_kdb_encode_int16(version, nextloc);
2456 nextloc += sizeof(krb5_ui_2);
2458 for (aux_data_entry = mkey_aux_data_list; aux_data_entry != NULL;
2459 aux_data_entry = aux_data_entry->next) {
2461 tmp_kvno = (krb5_int16) aux_data_entry->mkey_kvno;
2462 krb5_kdb_encode_int16(tmp_kvno, nextloc);
2463 nextloc += sizeof(krb5_ui_2);
2465 krb5_kdb_encode_int16(aux_data_entry->latest_mkey.key_data_kvno,
2467 nextloc += sizeof(krb5_ui_2);
2469 krb5_kdb_encode_int16(aux_data_entry->latest_mkey.key_data_type[0],
2471 nextloc += sizeof(krb5_ui_2);
2473 krb5_kdb_encode_int16(aux_data_entry->latest_mkey.key_data_length[0],
2475 nextloc += sizeof(krb5_ui_2);
2477 if (aux_data_entry->latest_mkey.key_data_length[0] > 0) {
2478 memcpy(nextloc, aux_data_entry->latest_mkey.key_data_contents[0],
2479 aux_data_entry->latest_mkey.key_data_length[0]);
2480 nextloc += aux_data_entry->latest_mkey.key_data_length[0];
2484 return (krb5_dbe_update_tl_data(context, entry, &tl_data));
2486 #endif /* KRB5_TL_MKEY_AUX_VER == 1 */
2488 #if KRB5_TL_ACTKVNO_VER == 1
2490 * If version of the KRB5_TL_ACTKVNO data is KRB5_TL_ACTKVNO_VER == 1 then size of
2491 * a actkvno tuple {act_kvno, act_time} entry is:
2493 #define ACTKVNO_TUPLE_SIZE (sizeof(krb5_int16) + sizeof(krb5_int32))
2494 #define act_kvno(cp) (cp) /* return pointer to start of act_kvno data */
2495 #define act_time(cp) ((cp) + sizeof(krb5_int16)) /* return pointer to start of act_time data */
2499 krb5_dbe_lookup_actkvno(krb5_context context,
2500 krb5_db_entry *entry,
2501 krb5_actkvno_node **actkvno_list)
2503 krb5_tl_data tl_data;
2504 krb5_error_code code;
2505 krb5_int16 version, tmp_kvno;
2506 krb5_actkvno_node *head_data = NULL, *new_data = NULL, *prev_data = NULL;
2507 unsigned int num_actkvno, i;
2508 krb5_octet *next_tuple;
2510 memset(&tl_data, 0, sizeof(tl_data));
2511 tl_data.tl_data_type = KRB5_TL_ACTKVNO;
2513 if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data)))
2516 if (tl_data.tl_data_contents == NULL) {
2517 *actkvno_list = NULL;
2520 /* get version to determine how to parse the data */
2521 krb5_kdb_decode_int16(tl_data.tl_data_contents, version);
2524 /* variable size, must be at least 8 bytes */
2525 if (tl_data.tl_data_length < 8)
2526 return (KRB5_KDB_TRUNCATED_RECORD);
2529 * Find number of tuple entries, remembering to account for version
2532 num_actkvno = (tl_data.tl_data_length - sizeof(version)) /
2535 /* next_tuple points to first tuple entry in the tl_data_contents */
2536 next_tuple = tl_data.tl_data_contents + sizeof(version);
2537 for (i = 0; i < num_actkvno; i++) {
2538 new_data = (krb5_actkvno_node *) malloc(sizeof(krb5_actkvno_node));
2539 if (new_data == NULL) {
2540 krb5_dbe_free_actkvno_list(context, head_data);
2543 memset(new_data, 0, sizeof(krb5_actkvno_node));
2545 /* using tmp_kvno to avoid type mismatch */
2546 krb5_kdb_decode_int16(act_kvno(next_tuple), tmp_kvno);
2547 new_data->act_kvno = (krb5_kvno) tmp_kvno;
2548 krb5_kdb_decode_int32(act_time(next_tuple), new_data->act_time);
2550 if (prev_data != NULL)
2551 prev_data->next = new_data;
2553 head_data = new_data;
2554 prev_data = new_data;
2555 next_tuple += ACTKVNO_TUPLE_SIZE;
2558 krb5_set_error_message (context, KRB5_KDB_BAD_VERSION,
2559 "Illegal version number for KRB5_TL_ACTKVNO %d\n",
2561 return (KRB5_KDB_BAD_VERSION);
2564 *actkvno_list = head_data;
2569 * Add KRB5_TL_ACTKVNO TL data entries to krb5_db_entry *entry
2571 #if KRB5_TL_ACTKVNO_VER == 1
2573 krb5_dbe_update_actkvno(krb5_context context,
2574 krb5_db_entry *entry,
2575 const krb5_actkvno_node *actkvno_list)
2577 krb5_error_code retval = 0;
2578 krb5_int16 version, tmp_kvno;
2579 krb5_tl_data new_tl_data;
2580 unsigned char *nextloc;
2581 const krb5_actkvno_node *cur_actkvno;
2584 if (actkvno_list == NULL) {
2588 memset(&new_tl_data, 0, sizeof(new_tl_data));
2589 /* allocate initial KRB5_TL_ACTKVNO tl_data entry */
2590 new_tl_data.tl_data_length = sizeof(version);
2591 new_tl_data.tl_data_contents = (krb5_octet *) malloc(new_tl_data.tl_data_length);
2592 if (new_tl_data.tl_data_contents == NULL)
2595 /* add the current version # for the data format used for KRB5_TL_ACTKVNO */
2596 version = KRB5_TL_ACTKVNO_VER;
2597 krb5_kdb_encode_int16(version, (unsigned char *) new_tl_data.tl_data_contents);
2599 for (cur_actkvno = actkvno_list; cur_actkvno != NULL;
2600 cur_actkvno = cur_actkvno->next) {
2602 new_tl_data.tl_data_length += ACTKVNO_TUPLE_SIZE;
2603 tmpptr = realloc(new_tl_data.tl_data_contents, new_tl_data.tl_data_length);
2604 if (tmpptr == NULL) {
2605 free(new_tl_data.tl_data_contents);
2608 new_tl_data.tl_data_contents = tmpptr;
2612 * Using realloc so tl_data_contents is required to correctly calculate
2613 * next location to store new tuple.
2615 nextloc = new_tl_data.tl_data_contents + new_tl_data.tl_data_length - ACTKVNO_TUPLE_SIZE;
2616 /* using tmp_kvno to avoid type mismatch issues */
2617 tmp_kvno = (krb5_int16) cur_actkvno->act_kvno;
2618 krb5_kdb_encode_int16(tmp_kvno, nextloc);
2619 nextloc += sizeof(krb5_ui_2);
2620 krb5_kdb_encode_int32((krb5_ui_4)cur_actkvno->act_time, nextloc);
2623 new_tl_data.tl_data_type = KRB5_TL_ACTKVNO;
2624 retval = krb5_dbe_update_tl_data(context, entry, &new_tl_data);
2625 free(new_tl_data.tl_data_contents);
2629 #endif /* KRB5_TL_ACTKVNO_VER == 1 */
2632 krb5_dbe_update_last_pwd_change(context, entry, stamp)
2633 krb5_context context;
2634 krb5_db_entry *entry;
2635 krb5_timestamp stamp;
2637 krb5_tl_data tl_data;
2638 krb5_octet buf[4]; /* this is the encoded size of an int32 */
2640 tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE;
2641 tl_data.tl_data_length = sizeof(buf);
2642 krb5_kdb_encode_int32((krb5_int32) stamp, buf);
2643 tl_data.tl_data_contents = buf;
2645 return (krb5_dbe_update_tl_data(context, entry, &tl_data));
2649 krb5_dbe_delete_tl_data(krb5_context context,
2650 krb5_db_entry *entry,
2651 krb5_int16 tl_data_type)
2653 krb5_tl_data *tl_data, *prev_tl_data, *free_tl_data;
2656 * Find existing entries of the specified type and remove them from the
2657 * entry's tl_data list.
2660 for (prev_tl_data = tl_data = entry->tl_data; tl_data != NULL;) {
2661 if (tl_data->tl_data_type == tl_data_type) {
2662 if (tl_data == entry->tl_data) {
2663 /* remove from head */
2664 entry->tl_data = tl_data->tl_data_next;
2665 prev_tl_data = entry->tl_data;
2666 } else if (tl_data->tl_data_next == NULL) {
2667 /* remove from tail */
2668 prev_tl_data->tl_data_next = NULL;
2670 /* remove in between */
2671 prev_tl_data->tl_data_next = tl_data->tl_data_next;
2673 free_tl_data = tl_data;
2674 tl_data = tl_data->tl_data_next;
2675 krb5_dbe_free_tl_data(context, free_tl_data);
2678 tl_data = tl_data->tl_data_next;
2679 prev_tl_data = tl_data;
2687 krb5_dbe_update_tl_data(context, entry, new_tl_data)
2688 krb5_context context;
2689 krb5_db_entry *entry;
2690 krb5_tl_data *new_tl_data;
2692 krb5_tl_data *tl_data = NULL;
2696 * Copy the new data first, so we can fail cleanly if malloc()
2700 (krb5_octet *) krb5_db_alloc(context, NULL,
2701 new_tl_data->tl_data_length)) == NULL)
2705 * Find an existing entry of the specified type and point at
2706 * it, or NULL if not found.
2709 if (new_tl_data->tl_data_type != KRB5_TL_DB_ARGS) { /* db_args can be multiple */
2710 for (tl_data = entry->tl_data; tl_data;
2711 tl_data = tl_data->tl_data_next)
2712 if (tl_data->tl_data_type == new_tl_data->tl_data_type)
2716 /* If necessary, chain a new record in the beginning and point at it. */
2720 (krb5_tl_data *) krb5_db_alloc(context, NULL,
2721 sizeof(krb5_tl_data)))
2726 memset(tl_data, 0, sizeof(krb5_tl_data));
2727 tl_data->tl_data_next = entry->tl_data;
2728 entry->tl_data = tl_data;
2732 /* fill in the record */
2734 if (tl_data->tl_data_contents)
2735 krb5_db_free(context, tl_data->tl_data_contents);
2737 tl_data->tl_data_type = new_tl_data->tl_data_type;
2738 tl_data->tl_data_length = new_tl_data->tl_data_length;
2739 tl_data->tl_data_contents = tmp;
2740 memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length);
2745 /* change password functions */
2747 krb5_dbe_cpw(krb5_context kcontext,
2748 krb5_keyblock * master_key,
2749 krb5_key_salt_tuple * ks_tuple,
2752 int new_kvno, krb5_boolean keepold, krb5_db_entry * db_entry)
2754 krb5_error_code status = 0;
2755 kdb5_dal_handle *dal_handle;
2757 if (kcontext->dal_handle == NULL) {
2758 status = kdb_setup_lib_handle(kcontext);
2764 dal_handle = kcontext->dal_handle;
2765 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2770 status = dal_handle->lib_handle->vftabl.db_change_pwd(kcontext,
2777 get_errmsg(kcontext, status);
2778 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2784 /* policy management functions */
2786 krb5_db_create_policy(krb5_context kcontext, osa_policy_ent_t policy)
2788 krb5_error_code status = 0;
2789 kdb5_dal_handle *dal_handle;
2791 if (kcontext->dal_handle == NULL) {
2792 status = kdb_setup_lib_handle(kcontext);
2798 dal_handle = kcontext->dal_handle;
2799 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2804 status = dal_handle->lib_handle->vftabl.db_create_policy(kcontext, policy);
2805 get_errmsg(kcontext, status);
2806 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2813 krb5_db_get_policy(krb5_context kcontext, char *name,
2814 osa_policy_ent_t * policy, int *cnt)
2816 krb5_error_code status = 0;
2817 kdb5_dal_handle *dal_handle;
2819 if (kcontext->dal_handle == NULL) {
2820 status = kdb_setup_lib_handle(kcontext);
2826 dal_handle = kcontext->dal_handle;
2827 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2833 dal_handle->lib_handle->vftabl.db_get_policy(kcontext, name, policy,
2835 get_errmsg(kcontext, status);
2836 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2843 krb5_db_put_policy(krb5_context kcontext, osa_policy_ent_t policy)
2845 krb5_error_code status = 0;
2846 kdb5_dal_handle *dal_handle;
2848 if (kcontext->dal_handle == NULL) {
2849 status = kdb_setup_lib_handle(kcontext);
2855 dal_handle = kcontext->dal_handle;
2856 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2861 status = dal_handle->lib_handle->vftabl.db_put_policy(kcontext, policy);
2862 get_errmsg(kcontext, status);
2863 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2870 krb5_db_iter_policy(krb5_context kcontext, char *match_entry,
2871 osa_adb_iter_policy_func func, void *data)
2873 krb5_error_code status = 0;
2874 kdb5_dal_handle *dal_handle;
2876 if (kcontext->dal_handle == NULL) {
2877 status = kdb_setup_lib_handle(kcontext);
2883 dal_handle = kcontext->dal_handle;
2884 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2890 dal_handle->lib_handle->vftabl.db_iter_policy(kcontext, match_entry,
2892 get_errmsg(kcontext, status);
2893 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2900 krb5_db_delete_policy(krb5_context kcontext, char *policy)
2902 krb5_error_code status = 0;
2903 kdb5_dal_handle *dal_handle;
2905 if (kcontext->dal_handle == NULL) {
2906 status = kdb_setup_lib_handle(kcontext);
2912 dal_handle = kcontext->dal_handle;
2913 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2918 status = dal_handle->lib_handle->vftabl.db_delete_policy(kcontext, policy);
2919 get_errmsg(kcontext, status);
2920 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2927 krb5_db_free_policy(krb5_context kcontext, osa_policy_ent_t policy)
2929 krb5_error_code status = 0;
2930 kdb5_dal_handle *dal_handle;
2932 if (kcontext->dal_handle == NULL) {
2933 status = kdb_setup_lib_handle(kcontext);
2939 dal_handle = kcontext->dal_handle;
2940 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2945 dal_handle->lib_handle->vftabl.db_free_policy(kcontext, policy);
2946 get_errmsg(kcontext, status);
2947 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2954 krb5_db_promote(krb5_context kcontext, char **db_args)
2956 krb5_error_code status = 0;
2957 char *section = NULL;
2958 kdb5_dal_handle *dal_handle;
2960 section = kdb_get_conf_section(kcontext);
2961 if (section == NULL) {
2962 status = KRB5_KDB_SERVER_INTERNAL_ERR;
2963 krb5_set_error_message (kcontext, status,
2964 "unable to determine configuration section for realm %s\n",
2965 kcontext->default_realm);
2969 if (kcontext->dal_handle == NULL) {
2970 status = kdb_setup_lib_handle(kcontext);
2976 dal_handle = kcontext->dal_handle;
2977 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
2983 dal_handle->lib_handle->vftabl.promote_db(kcontext, section, db_args);
2984 get_errmsg(kcontext, status);
2985 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
2994 krb5_dbekd_decrypt_key_data( krb5_context kcontext,
2995 const krb5_keyblock * mkey,
2996 const krb5_key_data * key_data,
2997 krb5_keyblock * dbkey,
2998 krb5_keysalt * keysalt)
3000 krb5_error_code status = 0;
3001 kdb5_dal_handle *dal_handle;
3003 if (kcontext->dal_handle == NULL) {
3004 status = kdb_setup_lib_handle(kcontext);
3010 dal_handle = kcontext->dal_handle;
3011 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
3017 dal_handle->lib_handle->vftabl.dbekd_decrypt_key_data(kcontext,
3018 mkey, key_data, dbkey, keysalt);
3019 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
3026 krb5_dbekd_encrypt_key_data( krb5_context kcontext,
3027 const krb5_keyblock * mkey,
3028 const krb5_keyblock * dbkey,
3029 const krb5_keysalt * keysalt,
3031 krb5_key_data * key_data)
3033 krb5_error_code status = 0;
3034 kdb5_dal_handle *dal_handle;
3036 if (kcontext->dal_handle == NULL) {
3037 status = kdb_setup_lib_handle(kcontext);
3043 dal_handle = kcontext->dal_handle;
3044 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
3050 dal_handle->lib_handle->vftabl.dbekd_encrypt_key_data(kcontext,
3051 mkey, dbkey, keysalt, keyver, key_data);
3052 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);
3059 krb5_db_get_context(krb5_context context, void **db_context)
3061 *db_context = KRB5_DB_GET_DB_CONTEXT(context);
3062 if (*db_context == NULL) {
3063 return KRB5_KDB_DBNOTINITED;
3070 krb5_db_set_context(krb5_context context, void *db_context)
3072 KRB5_DB_GET_DB_CONTEXT(context) = db_context;
3078 krb5_db_invoke(krb5_context kcontext,
3079 unsigned int method,
3080 const krb5_data *req,
3083 krb5_error_code status = 0;
3084 kdb5_dal_handle *dal_handle;
3086 if (kcontext->dal_handle == NULL) {
3087 status = kdb_setup_lib_handle(kcontext);
3093 dal_handle = kcontext->dal_handle;
3094 if (dal_handle->lib_handle->vftabl.db_invoke == NULL) {
3095 status = KRB5_KDB_DBTYPE_NOSUP;
3099 status = kdb_lock_lib_lock(dal_handle->lib_handle, FALSE);
3105 dal_handle->lib_handle->vftabl.db_invoke(kcontext,
3109 kdb_unlock_lib_lock(dal_handle->lib_handle, FALSE);