Exemplo n.º 1
0
/* 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;
}
Exemplo n.º 2
0
/* 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;
}
Exemplo n.º 3
0
/*
 * 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);
}