summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
authorAbhidnya Joshi <achirmul@in.ibm.com>2013-04-10 16:26:07 +0530
committerChristian Ambach <ambi@samba.org>2013-05-06 16:33:39 +0200
commitb384c55bf3fa230a945f36c493427f2341051cd1 (patch)
tree99dbb8c2bdb23b07748dd224ef933d7ce4e9c527 /source3
parente0a0280c4fcf85f28b488d3868be38123910271c (diff)
downloadsamba-b384c55bf3fa230a945f36c493427f2341051cd1.tar.gz
samba-b384c55bf3fa230a945f36c493427f2341051cd1.tar.bz2
samba-b384c55bf3fa230a945f36c493427f2341051cd1.zip
s3:winbindd/autorid multiple range support
when a mapping request for a RID comes in that is larger than the rangesize, allocate an extension range to be able to map this one This is especially important for large installations which might have large RIDs being used in a trusted domain that the administrator was not aware of when planning for autorid usage and so those objects could not be mapped up to now. As it is not possible to change the rangesize after the first start of autorid, this would lead to big trouble. Signed-off-by: Abhidnya Joshi <achirmul@in.ibm.com> Reviewed-by: Christian Ambach <ambi@samba.org> Reviewed-by: Michael Adam <obnox@samba.org>
Diffstat (limited to 'source3')
-rw-r--r--source3/winbindd/idmap_autorid.c55
1 files changed, 36 insertions, 19 deletions
diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c
index 07479168c7..87833ba18c 100644
--- a/source3/winbindd/idmap_autorid.c
+++ b/source3/winbindd/idmap_autorid.c
@@ -51,7 +51,9 @@ struct autorid_global_config {
struct autorid_domain_config {
fstring sid;
+ fstring keystr;
uint32_t domainnum;
+ uint32_t multiplier;
struct autorid_global_config *globalcfg;
};
@@ -68,14 +70,15 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
cfg = (struct autorid_domain_config *)private_data;
- ret = dbwrap_fetch_uint32_bystring(db, cfg->sid, &(cfg->domainnum));
+ ret = dbwrap_fetch_uint32_bystring(db, cfg->keystr, &(cfg->domainnum));
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_bystring(db, HWM, &hwm);
@@ -102,7 +105,7 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
}
/* store away the new mapping in both directions */
- ret = dbwrap_store_uint32_bystring(db, cfg->sid, domainnum);
+ ret = dbwrap_store_uint32_bystring(db, cfg->keystr, domainnum);
if (!NT_STATUS_IS_OK(ret)) {
DEBUG(1, ("Fatal error while storing new "
"domain->range assignment!\n"));
@@ -116,7 +119,7 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
}
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)) {
@@ -124,8 +127,9 @@ static NTSTATUS idmap_autorid_get_domainrange_action(struct db_context *db,
"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", domainnum, cfg->keystr,
+ cfg->multiplier));
cfg->domainnum = domainnum;
@@ -146,7 +150,14 @@ static NTSTATUS idmap_autorid_get_domainrange(struct autorid_domain_config *dom,
* if it is not found create a mapping in a transaction unless
* read-only mode has been set
*/
- ret = dbwrap_fetch_uint32_bystring(autorid_db, dom->sid,
+ 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->domainnum));
if (!NT_STATUS_IS_OK(ret)) {
@@ -157,8 +168,8 @@ static NTSTATUS idmap_autorid_get_domainrange(struct autorid_domain_config *dom,
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->domainnum, dom->sid, dom->multiplier));
return ret;
}
@@ -244,11 +255,13 @@ static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg,
struct id_map *map)
{
uint32_t range;
+ 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) {
@@ -298,16 +311,23 @@ static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg,
return idmap_autorid_map_id_to_sid(dom, map);
}
- ok = 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
@@ -331,15 +351,9 @@ static NTSTATUS idmap_autorid_sid_to_id(struct autorid_global_config *global,
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->domainnum) + rid -
+ (global->rangesize * domain->multiplier);
map->xid.type = ID_TYPE_BOTH;
/* We **really** should have some way of validating
@@ -563,6 +577,9 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom,
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? */