struct autorid_domain_config {
fstring sid;
- uint32_t domainnum;
+ fstring keystr;
+ uint32_t rangenum;
+ uint32_t multiplier;
struct autorid_global_config *globalcfg;
};
void *private_data)
{
NTSTATUS ret;
- uint32_t domainnum, hwm;
+ uint32_t rangenum, hwm;
char *numstr;
struct autorid_domain_config *cfg;
cfg = (struct autorid_domain_config *)private_data;
- ret = dbwrap_fetch_uint32(db, cfg->sid, &(cfg->domainnum));
+ ret = dbwrap_fetch_uint32_bystring(db, cfg->keystr,
+ &(cfg->rangenum));
if (NT_STATUS_IS_OK(ret)) {
/* entry is already present*/
return ret;
}
- DEBUG(10, ("Acquiring new range for domain %s\n", cfg->sid));
+ DEBUG(10, ("Acquiring new range for domain %s (multiplier=%"PRIu32")\n",
+ cfg->sid, cfg->multiplier));
/* fetch the current HWM */
- ret = dbwrap_fetch_uint32(db, HWM, &hwm);
+ ret = dbwrap_fetch_uint32_bystring(db, HWM, &hwm);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(1, ("Fatal error while fetching current "
"HWM value: %s\n", nt_errstr(ret)));
}
/* increase the HWM */
- ret = dbwrap_change_uint32_atomic(db, HWM, &domainnum, 1);
+ ret = dbwrap_change_uint32_atomic_bystring(db, HWM, &rangenum, 1);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(1, ("Fatal error while fetching a new "
"domain range value!\n"));
}
/* store away the new mapping in both directions */
- ret = dbwrap_store_uint32(db, cfg->sid, domainnum);
+ ret = dbwrap_store_uint32_bystring(db, cfg->keystr, rangenum);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(1, ("Fatal error while storing new "
"domain->range assignment!\n"));
goto error;
}
- numstr = talloc_asprintf(db, "%u", domainnum);
+ numstr = talloc_asprintf(db, "%u", rangenum);
if (!numstr) {
ret = NT_STATUS_NO_MEMORY;
goto error;
}
ret = dbwrap_store_bystring(db, numstr,
- string_term_tdb_data(cfg->sid), TDB_INSERT);
+ string_term_tdb_data(cfg->keystr), TDB_INSERT);
talloc_free(numstr);
if (!NT_STATUS_IS_OK(ret)) {
"new domain->range assignment!\n"));
goto error;
}
- DEBUG(5, ("Acquired new range #%d for domain %s\n",
- domainnum, cfg->sid));
+ DEBUG(5, ("Acquired new range #%d for domain %s "
+ "(multiplier=%"PRIu32")\n", rangenum, cfg->keystr,
+ cfg->multiplier));
- cfg->domainnum = domainnum;
+ cfg->rangenum = rangenum;
return NT_STATUS_OK;
* if it is not found create a mapping in a transaction unless
* read-only mode has been set
*/
- ret = dbwrap_fetch_uint32(autorid_db, dom->sid, &(dom->domainnum));
+ if (dom->multiplier > 0) {
+ snprintf(dom->keystr, FSTRING_LEN, "%s#%"PRIu32, dom->sid,
+ dom->multiplier);
+ } else {
+ fstrcpy(dom->keystr, dom->sid);
+ }
+
+ ret = dbwrap_fetch_uint32_bystring(autorid_db, dom->keystr,
+ &(dom->rangenum));
if (!NT_STATUS_IS_OK(ret)) {
if (read_only) {
idmap_autorid_get_domainrange_action, dom);
}
- DEBUG(10, ("Using range #%d for domain %s\n", dom->domainnum,
- dom->sid));
+ DEBUG(10, ("Using range #%d for domain %s (multiplier=%"PRIu32")\n",
+ dom->rangenum, dom->sid, dom->multiplier));
return ret;
}
}
xid->id = globalcfg->minvalue +
- globalcfg->rangesize * domaincfg.domainnum +
+ globalcfg->rangesize * domaincfg.rangenum +
xid->id;
DEBUG(10, ("Returned new %s %d from allocation range\n",
struct id_map *map)
{
uint32_t range;
- TDB_DATA data;
+ uint32_t multiplier = 0;
+ TDB_DATA data = tdb_null;
char *keystr;
struct dom_sid sid;
NTSTATUS status;
+ bool ok;
+ const char *q = NULL;
/* can this be one of our ids? */
if (map->xid.id < cfg->minvalue) {
return idmap_autorid_map_id_to_sid(dom, map);
}
- string_to_sid(&sid, (const char *)data.dptr);
+ ok = dom_sid_parse_endp((const char *)data.dptr, &sid, &q);
TALLOC_FREE(data.dptr);
+ if (!ok) {
+ map->status = ID_UNKNOWN;
+ return NT_STATUS_OK;
+ }
+ if (q != NULL)
+ if (sscanf(q+1, "%"SCNu32, &multiplier) != 1) {
+ DEBUG(10, ("Multiplier not found! "
+ "ignoring mapping request\n"));
+ map->status = ID_UNKNOWN;
+ return NT_STATUS_OK;
+ }
sid_compose(map->sid, &sid,
(map->xid.id - cfg->minvalue -
- range * cfg->rangesize));
+ range * cfg->rangesize + (cfg->rangesize * multiplier)));
/* We **really** should have some way of validating
the SID exists and is the correct type here. But
that is a deficiency in the idmap_rid design. */
map->status = ID_MAPPED;
+ map->xid.type = ID_TYPE_BOTH;
+
return NT_STATUS_OK;
}
sid_peek_rid(map->sid, &rid);
- /* if the rid is higher than the size of the range, we cannot map it */
- if (rid >= global->rangesize) {
- map->status = ID_UNKNOWN;
- DEBUG(2, ("RID %d is larger then size of range (%d), "
- "user cannot be mapped\n", rid, global->rangesize));
- return NT_STATUS_UNSUCCESSFUL;
- }
map->xid.id = global->minvalue +
- (global->rangesize * domain->domainnum)+rid;
+ (global->rangesize * domain->rangenum) + rid -
+ (global->rangesize * domain->multiplier);
+ map->xid.type = ID_TYPE_BOTH;
/* We **really** should have some way of validating
the SID exists and is the correct type here. But
sid_string_dbg(map->sid)));
/* create new mapping */
- dbwrap_transaction_start(ctx->db);
+ res = dbwrap_transaction_start(ctx->db);
+ if (res != 0) {
+ DEBUG(2, ("transaction_start failed\n"));
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
ret = idmap_tdb_common_new_mapping(dom, map);
domaincfg.globalcfg = global;
sid_to_fstring(domaincfg.sid, &domainsid);
+ /* Calculate multiplier for multi-range support */
+ domaincfg.multiplier = rid / (global->rangesize);
+
ret = idmap_autorid_get_domainrange(&domaincfg, dom->read_only);
/* read-only mode and a new domain range would be required? */
NTSTATUS status;
uint32_t hwmval;
- status = dbwrap_fetch_uint32(autorid_db, hwm, &hwmval);
+ status = dbwrap_fetch_uint32_bystring(autorid_db, hwm, &hwmval);
if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
- status = dbwrap_trans_store_int32(autorid_db, hwm, 0);
+ status = dbwrap_trans_store_int32_bystring(autorid_db, hwm, 0);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,
("Unable to initialise HWM (%s) in autorid "
/* read previously stored config and current HWM */
storedconfig = idmap_autorid_loadconfig(talloc_tos());
- status = dbwrap_fetch_uint32(autorid_db, HWM, &hwm);
+ status = dbwrap_fetch_uint32_bystring(autorid_db, HWM, &hwm);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(1, ("Fatal error while fetching current "
"HWM value: %s\n", nt_errstr(status)));