diff options
Diffstat (limited to 'source3/winbindd/idmap_tdb.c')
-rw-r--r-- | source3/winbindd/idmap_tdb.c | 113 |
1 files changed, 68 insertions, 45 deletions
diff --git a/source3/winbindd/idmap_tdb.c b/source3/winbindd/idmap_tdb.c index 41ccc57930..6f7b72700e 100644 --- a/source3/winbindd/idmap_tdb.c +++ b/source3/winbindd/idmap_tdb.c @@ -398,14 +398,67 @@ static NTSTATUS idmap_tdb_alloc_init( const char *params ) Allocate a new id. **********************************/ -static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid) +struct idmap_tdb_allocate_id_context { + const char *hwmkey; + const char *hwmtype; + uint32_t high_hwm; + uint32_t hwm; +}; + +static NTSTATUS idmap_tdb_allocate_id_action(struct db_context *db, + void *private_data) { NTSTATUS ret; + struct idmap_tdb_allocate_id_context *state; + uint32_t hwm; + + state = (struct idmap_tdb_allocate_id_context *)private_data; + + hwm = dbwrap_fetch_int32(db, state->hwmkey); + if (hwm == -1) { + ret = NT_STATUS_INTERNAL_DB_ERROR; + goto done; + } + + /* check it is in the range */ + if (hwm > state->high_hwm) { + DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", + state->hwmtype, (unsigned long)state->high_hwm)); + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + /* fetch a new id and increment it */ + ret = dbwrap_trans_change_uint32_atomic(db, state->hwmkey, &hwm, 1); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(0, ("Fatal error while fetching a new %s value: %s\n!", + state->hwmtype, nt_errstr(ret))); + goto done; + } + + /* recheck it is in the range */ + if (hwm > state->high_hwm) { + DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", + state->hwmtype, (unsigned long)state->high_hwm)); + ret = NT_STATUS_UNSUCCESSFUL; + goto done; + } + + ret = NT_STATUS_OK; + state->hwm = hwm; + +done: + return ret; +} + +static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid) +{ const char *hwmkey; const char *hwmtype; uint32_t high_hwm; - uint32_t hwm; - int res; + uint32_t hwm = 0; + NTSTATUS status; + struct idmap_tdb_allocate_id_context state; /* Get current high water mark */ switch (xid->type) { @@ -427,52 +480,22 @@ static NTSTATUS idmap_tdb_allocate_id(struct unixid *xid) return NT_STATUS_INVALID_PARAMETER; } - res = idmap_alloc_db->transaction_start(idmap_alloc_db); - if (res != 0) { - DEBUG(1, (__location__ " Failed to start transaction.\n")); - return NT_STATUS_UNSUCCESSFUL; - } - - if ((hwm = dbwrap_fetch_int32(idmap_alloc_db, hwmkey)) == -1) { - idmap_alloc_db->transaction_cancel(idmap_alloc_db); - return NT_STATUS_INTERNAL_DB_ERROR; - } - - /* check it is in the range */ - if (hwm > high_hwm) { - DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", - hwmtype, (unsigned long)high_hwm)); - idmap_alloc_db->transaction_cancel(idmap_alloc_db); - return NT_STATUS_UNSUCCESSFUL; - } + state.hwm = hwm; + state.high_hwm = high_hwm; + state.hwmtype = hwmtype; + state.hwmkey = hwmkey; - /* fetch a new id and increment it */ - ret = dbwrap_change_uint32_atomic(idmap_alloc_db, hwmkey, &hwm, 1); - if (!NT_STATUS_IS_OK(ret)) { - DEBUG(0, ("Fatal error while fetching a new %s value: %s\n!", - hwmtype, nt_errstr(ret))); - idmap_alloc_db->transaction_cancel(idmap_alloc_db); - return ret; - } + status = dbwrap_trans_do(idmap_alloc_db, idmap_tdb_allocate_id_action, + &state); - /* recheck it is in the range */ - if (hwm > high_hwm) { - DEBUG(1, ("Fatal Error: %s range full!! (max: %lu)\n", - hwmtype, (unsigned long)high_hwm)); - idmap_alloc_db->transaction_cancel(idmap_alloc_db); - return NT_STATUS_UNSUCCESSFUL; - } - - res = idmap_alloc_db->transaction_commit(idmap_alloc_db); - if (res != 0) { - DEBUG(1, (__location__ " Failed to commit transaction.\n")); - return NT_STATUS_UNSUCCESSFUL; + if (NT_STATUS_IS_OK(status)) { + xid->id = state.hwm; + DEBUG(10,("New %s = %d\n", hwmtype, state.hwm)); + } else { + DEBUG(1, ("Error allocating a new %s\n", hwmtype)); } - xid->id = hwm; - DEBUG(10,("New %s = %d\n", hwmtype, hwm)); - - return NT_STATUS_OK; + return status; } /********************************** |