diff options
Diffstat (limited to 'source3/sam')
-rw-r--r-- | source3/sam/idmap_tdb.c | 38 |
1 files changed, 32 insertions, 6 deletions
diff --git a/source3/sam/idmap_tdb.c b/source3/sam/idmap_tdb.c index 278269e819..209f9066e0 100644 --- a/source3/sam/idmap_tdb.c +++ b/source3/sam/idmap_tdb.c @@ -48,6 +48,7 @@ static struct idmap_state { /* Allocate either a user or group id from the pool */ static NTSTATUS db_allocate_id(unid_t *id, int id_type) { + BOOL ret; int hwm; if (!id) return NT_STATUS_INVALID_PARAMETER; @@ -59,30 +60,55 @@ static NTSTATUS db_allocate_id(unid_t *id, int id_type) return NT_STATUS_INTERNAL_DB_ERROR; } + /* check it is in the range */ if (hwm > idmap_state.uid_high) { DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %u)\n", idmap_state.uid_high)); return NT_STATUS_UNSUCCESSFUL; } - (*id).uid = hwm++; + /* fetch a new id and increment it */ + ret = tdb_change_uint32_atomic(idmap_tdb, HWM_USER, &hwm, 1); + if (!ret) { + DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!")); + return NT_STATUS_UNSUCCESSFUL; + } + + /* recheck it is in the range */ + if (hwm > idmap_state.uid_high) { + DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %u)\n", idmap_state.uid_high)); + return NT_STATUS_UNSUCCESSFUL; + } + + (*id).uid = hwm; - /* Store new high water mark */ - tdb_store_int32(idmap_tdb, HWM_USER, hwm); break; case ID_GROUPID: if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) { return NT_STATUS_INTERNAL_DB_ERROR; } + /* check it is in the range */ if (hwm > idmap_state.gid_high) { DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %u)\n", idmap_state.gid_high)); return NT_STATUS_UNSUCCESSFUL; } - (*id).gid = hwm++; + /* fetch a new id and increment it */ + ret = tdb_change_uint32_atomic(idmap_tdb, HWM_USER, &hwm, 1); + + if (!ret) { + DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!")); + return NT_STATUS_UNSUCCESSFUL; + } + + /* recheck it is in the range */ + if (hwm > idmap_state.uid_high) { + DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %u)\n", idmap_state.uid_high)); + return NT_STATUS_UNSUCCESSFUL; + } + + (*id).gid = hwm; - /* Store new high water mark */ - tdb_store_int32(idmap_tdb, HWM_GROUP, hwm); break; default: return NT_STATUS_INVALID_PARAMETER; |