krb5_error_code krb5_db2_put_principal(krb5_context context, krb5_db_entry *entry, char **db_args) { int dbret; DB *db; DBT key, contents; krb5_data contdata, keydata; krb5_error_code retval; krb5_db2_context *dbc; krb5_clear_error_message (context); if (db_args) { /* DB2 does not support db_args DB arguments for principal */ krb5_set_error_message(context, EINVAL, _("Unsupported argument \"%s\" for db2"), db_args[0]); return EINVAL; } if (!inited(context)) return KRB5_KDB_DBNOTINITED; dbc = context->dal_handle->db_context; if ((retval = ctx_lock(context, dbc, KRB5_LOCKMODE_EXCLUSIVE))) return retval; db = dbc->db; retval = krb5_encode_princ_entry(context, &contdata, entry); if (retval) goto cleanup; contents.data = contdata.data; contents.size = contdata.length; retval = krb5_encode_princ_dbkey(context, &keydata, entry->princ); if (retval) { krb5_free_data_contents(context, &contdata); goto cleanup; } key.data = keydata.data; key.size = keydata.length; dbret = (*db->put)(db, &key, &contents, 0); retval = dbret ? errno : 0; krb5_free_data_contents(context, &keydata); krb5_free_data_contents(context, &contdata); cleanup: ctx_update_age(dbc); (void) krb5_db2_unlock(context); /* unlock database */ return (retval); }
/* * In the filesystem, promote the temporary database described by dbc_temp to * the real database described by dbc_real. Both must be exclusively locked. */ static krb5_error_code ctx_promote(krb5_context context, krb5_db2_context *dbc_temp, krb5_db2_context *dbc_real) { krb5_error_code retval; char *tdb = NULL, *tlock = NULL, *tpol = NULL, *tplock = NULL; char *rdb = NULL, *rlock = NULL, *rpol = NULL, *rplock = NULL; /* Generate all filenames of interest (including a few we don't need). */ retval = ctx_allfiles(dbc_temp, &tdb, &tlock, &tpol, &tplock); if (retval) return retval; retval = ctx_allfiles(dbc_real, &rdb, &rlock, &rpol, &rplock); if (retval) goto cleanup; /* Rename the principal and policy databases into place. */ if (rename(tdb, rdb)) { retval = errno; goto cleanup; } if (rename(tpol, rpol)) { retval = errno; goto cleanup; } ctx_update_age(dbc_real); /* Release and remove the temporary DB lockfiles. */ (void) unlink(tlock); (void) unlink(tplock); cleanup: free(tdb); free(tlock); free(tpol); free(tplock); free(rdb); free(rlock); free(rpol); free(rplock); return retval; }
krb5_error_code krb5_db2_delete_principal(krb5_context context, krb5_const_principal searchfor) { krb5_error_code retval; krb5_db_entry *entry; krb5_db2_context *dbc; DB *db; DBT key, contents; krb5_data keydata, contdata; int i, dbret; if (!inited(context)) return KRB5_KDB_DBNOTINITED; dbc = context->dal_handle->db_context; if ((retval = ctx_lock(context, dbc, KRB5_LOCKMODE_EXCLUSIVE))) return (retval); if ((retval = krb5_encode_princ_dbkey(context, &keydata, searchfor))) goto cleanup; key.data = keydata.data; key.size = keydata.length; db = dbc->db; dbret = (*db->get) (db, &key, &contents, 0); retval = errno; switch (dbret) { case 1: retval = KRB5_KDB_NOENTRY; /* Fall through. */ case -1: default: goto cleankey; case 0: ; } contdata.data = contents.data; contdata.length = contents.size; retval = krb5_decode_princ_entry(context, &contdata, &entry); if (retval) goto cleankey; /* Clear encrypted key contents */ for (i = 0; i < entry->n_key_data; i++) { if (entry->key_data[i].key_data_length[0]) { memset(entry->key_data[i].key_data_contents[0], 0, (unsigned) entry->key_data[i].key_data_length[0]); } } retval = krb5_encode_princ_entry(context, &contdata, entry); krb5_dbe_free(context, entry); if (retval) goto cleankey; contents.data = contdata.data; contents.size = contdata.length; dbret = (*db->put) (db, &key, &contents, 0); retval = dbret ? errno : 0; krb5_free_data_contents(context, &contdata); if (retval) goto cleankey; dbret = (*db->del) (db, &key, 0); retval = dbret ? errno : 0; cleankey: krb5_free_data_contents(context, &keydata); cleanup: ctx_update_age(dbc); (void) krb5_db2_unlock(context); /* unlock write lock */ return retval; }