krb5_error_code osa_adb_rename_db(char *filefrom, char *lockfrom, char *fileto, char *lockto, int magic) { osa_adb_db_t fromdb, todb; krb5_error_code ret; /* make sure todb exists */ if ((ret = osa_adb_create_db(fileto, lockto, magic)) && ret != EEXIST) return ret; if ((ret = osa_adb_init_db(&fromdb, filefrom, lockfrom, magic))) return ret; if ((ret = osa_adb_init_db(&todb, fileto, lockto, magic))) { (void) osa_adb_fini_db(fromdb, magic); return ret; } if ((ret = osa_adb_get_lock(fromdb, KRB5_DB_LOCKMODE_PERMANENT))) { (void) osa_adb_fini_db(fromdb, magic); (void) osa_adb_fini_db(todb, magic); return ret; } if ((ret = osa_adb_get_lock(todb, KRB5_DB_LOCKMODE_PERMANENT))) { (void) osa_adb_fini_db(fromdb, magic); (void) osa_adb_fini_db(todb, magic); return ret; } if ((rename(filefrom, fileto) < 0)) { (void) osa_adb_fini_db(fromdb, magic); (void) osa_adb_fini_db(todb, magic); return errno; } /* * Do not release the lock on fromdb because it is being renamed * out of existence; no one can ever use it again. */ if ((ret = osa_adb_release_lock(todb))) { (void) osa_adb_fini_db(fromdb, magic); (void) osa_adb_fini_db(todb, magic); return ret; } (void) osa_adb_fini_db(fromdb, magic); (void) osa_adb_fini_db(todb, magic); return 0; }
krb5_error_code krb5_db2_init(krb5_context context) { char *filename = NULL; krb5_db2_context *db_ctx; krb5_error_code retval; char policy_db_name[1024], policy_lock_name[1024]; if (k5db2_inited(context)) return 0; /* Check for presence of our context, if not present, allocate one. */ if ((retval = k5db2_init_context(context))) return (retval); db_ctx = context->dal_handle->db_context; db_ctx->db = NULL; if (!(filename = gen_dbsuffix(db_ctx->db_name, db_ctx->tempdb ?KDB2_TEMP_LOCK_EXT:KDB2_LOCK_EXT))) return ENOMEM; db_ctx->db_lf_name = filename; /* so it gets freed by clear_context */ /* * should be opened read/write so that write locking can work with * POSIX systems */ if ((db_ctx->db_lf_file = open(filename, O_RDWR, 0666)) < 0) { if ((db_ctx->db_lf_file = open(filename, O_RDONLY, 0666)) < 0) { retval = errno; goto err_out; } } set_cloexec_fd(db_ctx->db_lf_file); db_ctx->db_inited++; if ((retval = krb5_db2_get_age(context, NULL, &db_ctx->db_lf_time))) goto err_out; snprintf(policy_db_name, sizeof(policy_db_name), "%s%s.kadm5", db_ctx->db_name, db_ctx->tempdb ? "~" : ""); snprintf(policy_lock_name, sizeof(policy_lock_name), "%s.lock", policy_db_name); if ((retval = osa_adb_init_db(&db_ctx->policy_db, policy_db_name, policy_lock_name, OSA_ADB_POLICY_DB_MAGIC))) { goto err_out; } return 0; err_out: db_ctx->db = NULL; k5db2_clear_context(db_ctx); return (retval); }
/* Initialize the lock file and policy database fields of dbc. The db_name and * tempdb fields must already be set. */ static krb5_error_code ctx_init(krb5_db2_context *dbc) { krb5_error_code retval; char *polname = NULL, *plockname = NULL; retval = ctx_dbsuffix(dbc, SUFFIX_LOCK, &dbc->db_lf_name); if (retval) return retval; /* * should be opened read/write so that write locking can work with * POSIX systems */ if ((dbc->db_lf_file = open(dbc->db_lf_name, O_RDWR, 0666)) < 0) { if ((dbc->db_lf_file = open(dbc->db_lf_name, O_RDONLY, 0666)) < 0) { retval = errno; goto cleanup; } } set_cloexec_fd(dbc->db_lf_file); dbc->db_inited++; retval = ctx_dbsuffix(dbc, SUFFIX_POLICY, &polname); if (retval) goto cleanup; retval = ctx_dbsuffix(dbc, SUFFIX_POLICY_LOCK, &plockname); if (retval) goto cleanup; retval = osa_adb_init_db(&dbc->policy_db, polname, plockname, OSA_ADB_POLICY_DB_MAGIC); cleanup: free(polname); free(plockname); if (retval) ctx_clear(dbc); return retval; }
/* Initialize dbc by locking and creating the DB. If the DB already exists, * clear it out if dbc->tempdb is set; otherwise return EEXIST. */ static krb5_error_code ctx_create_db(krb5_context context, krb5_db2_context *dbc) { krb5_error_code retval = 0; char *dbname = NULL, *polname = NULL, *plockname = NULL; retval = ctx_allfiles(dbc, &dbname, &dbc->db_lf_name, &polname, &plockname); if (retval) return retval; dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC, 0600); if (dbc->db_lf_file < 0) { retval = errno; goto cleanup; } retval = krb5_lock_file(context, dbc->db_lf_file, KRB5_LOCKMODE_EXCLUSIVE | KRB5_LOCKMODE_DONTBLOCK); if (retval != 0) goto cleanup; set_cloexec_fd(dbc->db_lf_file); dbc->db_lock_mode = KRB5_LOCKMODE_EXCLUSIVE; dbc->db_locks_held = 1; if (dbc->tempdb) { /* Temporary DBs are locked for their whole lifetime. Since we have * the lock, any remnant files can be safely destroyed. */ (void) destroy_file(dbname); (void) unlink(polname); (void) unlink(plockname); } dbc->db = open_db(dbc, O_RDWR | O_CREAT | O_EXCL, 0600); if (dbc->db == NULL) { retval = errno; goto cleanup; } /* Create the policy database, initialize a handle to it, and lock it. */ retval = osa_adb_create_db(polname, plockname, OSA_ADB_POLICY_DB_MAGIC); if (retval) goto cleanup; retval = osa_adb_init_db(&dbc->policy_db, polname, plockname, OSA_ADB_POLICY_DB_MAGIC); if (retval) goto cleanup; retval = osa_adb_get_lock(dbc->policy_db, KRB5_DB_LOCKMODE_EXCLUSIVE); if (retval) goto cleanup; dbc->db_inited = 1; cleanup: if (retval) { if (dbc->db != NULL) dbc->db->close(dbc->db); if (dbc->db_locks_held > 0) { (void) krb5_lock_file(context, dbc->db_lf_file, KRB5_LOCKMODE_UNLOCK); } if (dbc->db_lf_file >= 0) close(dbc->db_lf_file); ctx_clear(dbc); } free(dbname); free(polname); free(plockname); return retval; }