/* Used by the slave to update its hash db from the incr update log. */ krb5_error_code ulog_replay(krb5_context context, kdb_incr_result_t *incr_ret, char **db_args) { krb5_db_entry *entry = NULL; kdb_incr_update_t *upd = NULL, *fupd; int i, no_of_updates; krb5_error_code retval; krb5_principal dbprinc; char *dbprincstr; kdb_log_context *log_ctx; kdb_hlog_t *ulog = NULL; INIT_ULOG(context); /* Lock the DB before the ulog to avoid deadlock. */ retval = krb5_db_open(context, db_args, KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN); if (retval) return retval; retval = krb5_db_lock(context, KRB5_DB_LOCKMODE_EXCLUSIVE); if (retval) return retval; retval = lock_ulog(context, KRB5_LOCKMODE_EXCLUSIVE); if (retval) { krb5_db_unlock(context); return retval; } no_of_updates = incr_ret->updates.kdb_ulog_t_len; upd = incr_ret->updates.kdb_ulog_t_val; fupd = upd; for (i = 0; i < no_of_updates; i++) { if (!upd->kdb_commit) continue; /* If (unexpectedly) this update does not follow the last one we * stored, discard any previous ulog state. */ if (ulog->kdb_num != 0 && upd->kdb_entry_sno != ulog->kdb_last_sno + 1) reset_header(ulog); if (upd->kdb_deleted) { dbprincstr = k5memdup0(upd->kdb_princ_name.utf8str_t_val, upd->kdb_princ_name.utf8str_t_len, &retval); if (dbprincstr == NULL) goto cleanup; retval = krb5_parse_name(context, dbprincstr, &dbprinc); free(dbprincstr); if (retval) goto cleanup; retval = krb5int_delete_principal_no_log(context, dbprinc); krb5_free_principal(context, dbprinc); if (retval == KRB5_KDB_NOENTRY) retval = 0; if (retval) goto cleanup; } else { entry = k5alloc(sizeof(krb5_db_entry), &retval); if (entry == NULL) goto cleanup; retval = ulog_conv_2dbentry(context, &entry, upd); if (retval) goto cleanup; retval = krb5int_put_principal_no_log(context, entry); krb5_db_free_principal(context, entry); if (retval) goto cleanup; } retval = store_update(log_ctx, upd); if (retval) goto cleanup; upd++; } cleanup: if (fupd) ulog_free_entries(fupd, no_of_updates); if (retval) { reset_header(ulog); sync_header(ulog); } unlock_ulog(context); krb5_db_unlock(context); return retval; }
/* Used by the slave to update its hash db from* the incr update log. Must be * called with lock held. */ krb5_error_code ulog_replay(krb5_context context, kdb_incr_result_t *incr_ret, char **db_args) { krb5_db_entry *entry = NULL; kdb_incr_update_t *upd = NULL, *fupd; int i, no_of_updates; krb5_error_code retval; krb5_principal dbprinc; kdb_last_t errlast, *last; char *dbprincstr; kdb_log_context *log_ctx; kdb_hlog_t *ulog = NULL; INIT_ULOG(context); no_of_updates = incr_ret->updates.kdb_ulog_t_len; upd = incr_ret->updates.kdb_ulog_t_val; fupd = upd; /* We reset last_sno and last_time to 0, if krb5_db2_db_put_principal or * krb5_db2_db_delete_principal fail. */ errlast.last_sno = (unsigned int)0; errlast.last_time.seconds = (unsigned int)0; errlast.last_time.useconds = (unsigned int)0; last = &errlast; retval = krb5_db_open(context, db_args, KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_ADMIN); if (retval) goto cleanup; for (i = 0; i < no_of_updates; i++) { if (!upd->kdb_commit) continue; if (upd->kdb_deleted) { dbprincstr = k5memdup0(upd->kdb_princ_name.utf8str_t_val, upd->kdb_princ_name.utf8str_t_len, &retval); if (dbprincstr == NULL) goto cleanup; retval = krb5_parse_name(context, dbprincstr, &dbprinc); free(dbprincstr); if (retval) goto cleanup; retval = krb5int_delete_principal_no_log(context, dbprinc); krb5_free_principal(context, dbprinc); if (retval) goto cleanup; } else { entry = k5alloc(sizeof(krb5_db_entry), &retval); if (entry == NULL) goto cleanup; retval = ulog_conv_2dbentry(context, &entry, upd); if (retval) goto cleanup; retval = krb5int_put_principal_no_log(context, entry); krb5_db_free_principal(context, entry); if (retval) goto cleanup; } upd++; } last = &incr_ret->lastentry; cleanup: if (fupd) ulog_free_entries(fupd, no_of_updates); /* Record a new last serial number and timestamp in the ulog header. */ ulog->kdb_last_sno = last->last_sno; ulog->kdb_last_time = last->last_time; ulog_sync_header(ulog); return retval; }
/* * Used by the slave or master (during ulog_check) to update it's hash db from * the incr update log. * * Must be called with lock held. */ krb5_error_code ulog_replay(krb5_context context, kdb_incr_result_t *incr_ret, char **db_args) { krb5_db_entry *entry = NULL; kdb_incr_update_t *upd = NULL, *fupd; int i, no_of_updates; krb5_error_code retval; krb5_principal dbprinc = NULL; kdb_last_t errlast; char *dbprincstr = NULL; kdb_log_context *log_ctx; kdb_hlog_t *ulog = NULL; INIT_ULOG(context); no_of_updates = incr_ret->updates.kdb_ulog_t_len; upd = incr_ret->updates.kdb_ulog_t_val; fupd = upd; /* * We reset last_sno and last_time to 0, if krb5_db2_db_put_principal * or krb5_db2_db_delete_principal fail. */ errlast.last_sno = (unsigned int)0; errlast.last_time.seconds = (unsigned int)0; errlast.last_time.useconds = (unsigned int)0; if ((retval = krb5_db_open(context, db_args, KRB5_KDB_OPEN_RW|KRB5_KDB_SRV_TYPE_ADMIN))) goto cleanup; for (i = 0; i < no_of_updates; i++) { if (!upd->kdb_commit) continue; if (upd->kdb_deleted) { dbprincstr = malloc((upd->kdb_princ_name.utf8str_t_len + 1) * sizeof (char)); if (dbprincstr == NULL) { retval = ENOMEM; goto cleanup; } (void) strncpy(dbprincstr, (char *)upd->kdb_princ_name.utf8str_t_val, (upd->kdb_princ_name.utf8str_t_len + 1)); dbprincstr[upd->kdb_princ_name.utf8str_t_len] = 0; if ((retval = krb5_parse_name(context, dbprincstr, &dbprinc))) { goto cleanup; } free(dbprincstr); retval = krb5int_delete_principal_no_log(context, dbprinc); if (dbprinc) { krb5_free_principal(context, dbprinc); dbprinc = NULL; } if (retval) goto cleanup; } else { entry = (krb5_db_entry *)malloc(sizeof (krb5_db_entry)); if (!entry) { retval = errno; goto cleanup; } (void) memset(entry, 0, sizeof (krb5_db_entry)); if ((retval = ulog_conv_2dbentry(context, &entry, upd))) goto cleanup; retval = krb5int_put_principal_no_log(context, entry); if (entry) { krb5_db_free_principal(context, entry); entry = NULL; } if (retval) goto cleanup; } upd++; } cleanup: if (fupd) ulog_free_entries(fupd, no_of_updates); if (log_ctx && (log_ctx->iproprole == IPROP_SLAVE)) { if (retval) ulog_finish_update_slave(ulog, errlast); else ulog_finish_update_slave(ulog, incr_ret->lastentry); } return (retval); }