krb5_error_code krb5_db2_destroy(krb5_context context, char *conf_section, char **db_args) { krb5_error_code status = 0; krb5_db2_context *db_ctx; char *db_name; if (k5db2_inited(context)) { status = krb5_db2_fini(context); if (status != 0) return status; } krb5_clear_error_message(context); status = configure_context(context, conf_section, db_args); if (status != 0) return status; status = check_openable(context); if (status != 0) return status; db_ctx = context->dal_handle->db_context; db_name = gen_dbsuffix(db_ctx->db_name, db_ctx->tempdb ? "~" : ""); if (db_name == NULL) return ENOMEM; status = destroy_db(context, db_name); free(db_name); return status; }
krb5_error_code krb5_db2_create(krb5_context context, char *conf_section, char **db_args) { krb5_error_code status = 0; krb5_db2_context *db_ctx; krb5_clear_error_message(context); if (k5db2_inited(context)) return 0; status = configure_context(context, conf_section, db_args); if (status != 0) return status; status = check_openable(context); if (status == 0) return EEXIST; db_ctx = context->dal_handle->db_context; status = create_db(context, db_ctx->db_name); if (status != 0) return status; return krb5_db2_init(context); }
krb5_error_code krb5_db2_destroy(krb5_context context, char *conf_section, char **db_args) { krb5_error_code status; krb5_db2_context *dbc; char *dbname = NULL, *lockname = NULL, *polname = NULL, *plockname = NULL; if (inited(context)) { status = krb5_db2_fini(context); if (status != 0) return status; } krb5_clear_error_message(context); status = configure_context(context, conf_section, db_args); if (status != 0) return status; status = check_openable(context); if (status != 0) return status; dbc = context->dal_handle->db_context; status = ctx_allfiles(dbc, &dbname, &lockname, &polname, &plockname); if (status) goto cleanup; status = destroy_file(dbname); if (status) goto cleanup; status = unlink(lockname); if (status) goto cleanup; status = osa_adb_destroy_db(polname, plockname, OSA_ADB_POLICY_DB_MAGIC); if (status) return status; status = krb5_db2_fini(context); cleanup: free(dbname); free(lockname); free(polname); free(plockname); return status; }
krb5_error_code krb5_db2_open(krb5_context context, char *conf_section, char **db_args, int mode) { krb5_error_code status = 0; krb5_clear_error_message(context); if (k5db2_inited(context)) return 0; status = configure_context(context, conf_section, db_args); if (status != 0) return status; status = check_openable(context); if (status != 0) return status; return krb5_db2_init(context); }
/* * "Atomically" rename the database in a way that locks out read * access in the middle of the rename. * * Not perfect; if we crash in the middle of an update, we don't * necessarily know to complete the transaction the rename, but... * * Since the rename operation happens outside the init/fini bracket, we * have to go through the same stuff that we went through up in db_destroy. */ krb5_error_code krb5_db2_rename(krb5_context context, char *from, char *to, int merge_nra) { char *fromok; krb5_error_code retval; krb5_db2_context *s_context, *db_ctx; kdb5_dal_handle *dal_handle = context->dal_handle; s_context = dal_handle->db_context; dal_handle->db_context = NULL; if ((retval = k5db2_init_context(context))) return retval; db_ctx = (krb5_db2_context *) dal_handle->db_context; /* * Create the database if it does not already exist; the * files must exist because krb5_db2_lock, called below, * will fail otherwise. */ retval = create_db(context, to); if (retval != 0 && retval != EEXIST) goto errout; /* * Set the database to the target, so that other processes sharing * the target will stop their activity, and notice the new database. */ db_ctx->db_name = strdup(to); if (db_ctx->db_name == NULL) { retval = ENOMEM; goto errout; } retval = check_openable(context); if (retval) goto errout; retval = krb5_db2_init(context); if (retval) goto errout; db_ctx->db_lf_name = gen_dbsuffix(db_ctx->db_name, KDB2_LOCK_EXT); if (db_ctx->db_lf_name == NULL) { retval = ENOMEM; goto errout; } db_ctx->db_lf_file = open(db_ctx->db_lf_name, O_RDWR|O_CREAT, 0600); if (db_ctx->db_lf_file < 0) { retval = errno; goto errout; } set_cloexec_fd(db_ctx->db_lf_file); db_ctx->db_inited = 1; retval = krb5_db2_get_age(context, NULL, &db_ctx->db_lf_time); if (retval) goto errout; fromok = gen_dbsuffix(from, KDB2_LOCK_EXT); if (fromok == NULL) { retval = ENOMEM; goto errout; } if ((retval = krb5_db2_lock(context, KRB5_LOCKMODE_EXCLUSIVE))) goto errfromok; if ((retval = krb5_db2_start_update(context))) goto errfromok; if (merge_nra) { if ((retval = krb5_db2_begin_nra_merge(context, s_context, db_ctx))) goto errfromok; } if (rename(from, to)) { retval = errno; goto errfromok; } if (unlink(fromok)) { retval = errno; goto errfromok; } if (merge_nra) { krb5_db2_end_nra_merge(context, s_context, db_ctx); } retval = krb5_db2_end_update(context); if (retval) goto errfromok; { /* XXX moved so that NRA merge works */ /* Ugly brute force hack. Should be going through nice friendly helper routines for this, but it's a mess of jumbled so-called interfaces right now. */ char policy[2048], new_policy[2048]; assert (strlen(db_ctx->db_name) < 2000); snprintf(policy, sizeof(policy), "%s.kadm5", db_ctx->db_name); snprintf(new_policy, sizeof(new_policy), "%s~.kadm5", db_ctx->db_name); if (0 != rename(new_policy, policy)) { retval = errno; goto errfromok; } strlcat(new_policy, ".lock",sizeof(new_policy)); (void) unlink(new_policy); } errfromok: free_dbsuffix(fromok); errout: if (dal_handle->db_context) { if (db_ctx->db_lf_file >= 0) { krb5_db2_unlock(context); close(db_ctx->db_lf_file); } k5db2_clear_context((krb5_db2_context *) dal_handle->db_context); free(dal_handle->db_context); } dal_handle->db_context = s_context; (void) krb5_db2_unlock(context); /* unlock saved context db */ return retval; }