From f1d7c6d2d2c9ed2e2e0b304ee16c1a78dd503d0c Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Thu, 20 Oct 2011 18:22:19 +0200 Subject: [PATCH 1/4] s3:idmap_autorid: use strings as parameter for range allocator this prepares for allocation of non-domain ranges that cannot be expressed by a SID (e.g. an allocation pool) --- source3/winbindd/idmap_autorid.c | 28 ++++++++++++++-------------- 1 files changed, 14 insertions(+), 14 deletions(-) diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c index 4028a46..0fcfc96 100644 --- a/source3/winbindd/idmap_autorid.c +++ b/source3/winbindd/idmap_autorid.c @@ -43,7 +43,7 @@ struct autorid_global_config { }; struct autorid_domain_config { - struct dom_sid sid; + fstring sid; uint32_t domainnum; struct autorid_global_config *globalcfg; }; @@ -56,15 +56,13 @@ static NTSTATUS idmap_autorid_get_domainrange(struct db_context *db, { NTSTATUS ret; uint32_t domainnum, hwm; - fstring sidstr; char *numstr; struct autorid_domain_config *cfg; cfg = (struct autorid_domain_config *)private_data; - dom_sid_string_buf(&(cfg->sid), sidstr, sizeof(sidstr)); - if (!dbwrap_fetch_uint32(db, sidstr, &domainnum)) { - DEBUG(10, ("Acquiring new range for domain %s\n", sidstr)); + if (!dbwrap_fetch_uint32(db, cfg->sid, &domainnum)) { + DEBUG(10, ("Acquiring new range for domain %s\n", cfg->sid)); /* fetch the current HWM */ if (!dbwrap_fetch_uint32(db, HWM, &hwm)) { @@ -90,7 +88,7 @@ static NTSTATUS idmap_autorid_get_domainrange(struct db_context *db, } /* store away the new mapping in both directions */ - ret = dbwrap_trans_store_uint32(db, sidstr, domainnum); + ret = dbwrap_trans_store_uint32(db, cfg->sid, domainnum); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("Fatal error while storing new " "domain->range assignment!\n")); @@ -104,8 +102,8 @@ static NTSTATUS idmap_autorid_get_domainrange(struct db_context *db, } ret = dbwrap_trans_store_bystring(db, numstr, - string_term_tdb_data(sidstr), - TDB_INSERT); + string_term_tdb_data(cfg->sid), TDB_INSERT); + talloc_free(numstr); if (!NT_STATUS_IS_OK(ret)) { DEBUG(1, ("Fatal error while storing " @@ -113,10 +111,10 @@ static NTSTATUS idmap_autorid_get_domainrange(struct db_context *db, goto error; } DEBUG(5, ("Acquired new range #%d for domain %s\n", - domainnum, sidstr)); + domainnum, cfg->sid)); } - DEBUG(10, ("Using range #%d for domain %s\n", domainnum, sidstr)); + DEBUG(10, ("Using range #%d for domain %s\n", domainnum, cfg->sid)); cfg->domainnum = domainnum; return NT_STATUS_OK; @@ -274,11 +272,12 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom, struct winbindd_tdc_domain *domain; struct autorid_domain_config domaincfg; uint32_t rid; + struct dom_sid domainsid; ZERO_STRUCT(domaincfg); - sid_copy(&domaincfg.sid, ids[i]->sid); - if (!sid_split_rid(&domaincfg.sid, &rid)) { + sid_copy(&domainsid, ids[i]->sid); + if (!sid_split_rid(&domainsid, &rid)) { DEBUG(4, ("Could not determine domain SID from %s, " "ignoring mapping request\n", sid_string_dbg(ids[i]->sid))); @@ -289,15 +288,16 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom, * Check if the domain is around */ domain = wcache_tdc_fetch_domainbysid(talloc_tos(), - &domaincfg.sid); + &domainsid); if (domain == NULL) { DEBUG(10, ("Ignoring unknown domain sid %s\n", - sid_string_dbg(&domaincfg.sid))); + sid_string_dbg(&domainsid))); continue; } TALLOC_FREE(domain); domaincfg.globalcfg = global; + sid_to_fstring(domaincfg.sid, &domainsid); ret = dbwrap_trans_do(autorid_db, idmap_autorid_get_domainrange, -- 1.7.1 From 939f508eaf316543573a22054f5a949c2eba86e3 Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Thu, 20 Oct 2011 18:39:30 +0200 Subject: [PATCH 2/4] s3:idmap_autorid: move HWM initialization into a function we will need some more HWM soon, so move out initialization and optimize the logic using the new interface of dbwrap_fetch_uint32 --- source3/winbindd/idmap_autorid.c | 35 ++++++++++++++++++++++++----------- 1 files changed, 24 insertions(+), 11 deletions(-) diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c index 0fcfc96..eb8abf3 100644 --- a/source3/winbindd/idmap_autorid.c +++ b/source3/winbindd/idmap_autorid.c @@ -326,12 +326,32 @@ static NTSTATUS idmap_autorid_sids_to_unixids(struct idmap_domain *dom, } +/* initialize the given HWM to 0 if it does not exist yet */ +static NTSTATUS idmap_autorid_init_hwm(const char *hwm) { + + NTSTATUS status; + int32_t hwmval; + + hwmval = dbwrap_fetch_int32(autorid_db, hwm); + if ((hwmval < 0)) { + status = dbwrap_trans_store_int32(autorid_db, hwm, 0); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0, + ("Unable to initialise HWM (%s) in autorid " + "database: %s\n", hwm, nt_errstr(status))); + return NT_STATUS_INTERNAL_DB_ERROR; + } + } + + return NT_STATUS_OK; +} + /* * open and initialize the database which stores the ranges for the domains */ static NTSTATUS idmap_autorid_db_init(void) { - int32_t hwm; + NTSTATUS status; if (autorid_db) { /* its already open */ @@ -349,16 +369,9 @@ static NTSTATUS idmap_autorid_db_init(void) } /* Initialize high water mark for the currently used range to 0 */ - hwm = dbwrap_fetch_int32(autorid_db, HWM); - if ((hwm < 0)) { - if (!NT_STATUS_IS_OK - (dbwrap_trans_store_int32(autorid_db, HWM, 0))) { - DEBUG(0, - ("Unable to initialise HWM in autorid " - "database\n")); - return NT_STATUS_INTERNAL_DB_ERROR; - } - } + + status = idmap_autorid_init_hwm(HWM); + NT_STATUS_NOT_OK_RETURN(status); return NT_STATUS_OK; } -- 1.7.1 From 5fb2dd80659ae724e543b98f33b6149b81303500 Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Thu, 20 Oct 2011 18:44:48 +0200 Subject: [PATCH 3/4] s3:idmap_autorid: add an allocation range to autorid this is needed to allocate gids for BUILTIN\Users and BUILTIN\Administrators and for local users/group that admins might want to create autorid will now allocate one range for this purpose and can so give out as many uids and gids as the configured rangesize allows --- source3/winbindd/idmap_autorid.c | 95 +++++++++++++++++++++++++++++++++++++- 1 files changed, 94 insertions(+), 1 deletions(-) diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c index eb8abf3..6bb35de 100644 --- a/source3/winbindd/idmap_autorid.c +++ b/source3/winbindd/idmap_autorid.c @@ -34,6 +34,9 @@ #define DBGC_CLASS DBGC_IDMAP #define HWM "NEXT RANGE" +#define ALLOC_HWM_UID "NEXT ALLOC UID" +#define ALLOC_HWM_GID "NEXT ALLOC GID" +#define ALLOC_RANGE "ALLOC" #define CONFIGKEY "CONFIG" struct autorid_global_config { @@ -162,6 +165,18 @@ static NTSTATUS idmap_autorid_id_to_sid(struct autorid_global_config *cfg, DEBUG(4, ("id %d belongs to range %d which does not have " "domain mapping, ignoring mapping request\n", map->xid.id, range)); + TALLOC_FREE(data.dptr); + map->status = ID_UNKNOWN; + return NT_STATUS_OK; + } + + if (strncmp((const char *)data.dptr, + ALLOC_RANGE, + strlen(ALLOC_RANGE)) == 0) { + /* this is from the alloc range, there is no mapping back */ + DEBUG(5, ("id %d belongs to alloc range, cannot map back\n", + map->xid.id)); + TALLOC_FREE(data.dptr); map->status = ID_UNKNOWN; return NT_STATUS_OK; } @@ -373,7 +388,12 @@ static NTSTATUS idmap_autorid_db_init(void) status = idmap_autorid_init_hwm(HWM); NT_STATUS_NOT_OK_RETURN(status); - return NT_STATUS_OK; + status = idmap_autorid_init_hwm(ALLOC_HWM_UID); + NT_STATUS_NOT_OK_RETURN(status); + + status = idmap_autorid_init_hwm(ALLOC_HWM_GID); + + return status; } static struct autorid_global_config *idmap_autorid_loadconfig(TALLOC_CTX * ctx) @@ -554,6 +574,78 @@ done: return status; } +static NTSTATUS idmap_autorid_allocate_id(struct idmap_domain *dom, + struct unixid *xid) { + + NTSTATUS ret; + struct autorid_global_config *globalcfg; + struct autorid_domain_config domaincfg; + uint32_t hwm; + const char *hwmkey; + + if (!strequal(dom->name, "*")) { + DEBUG(3, ("idmap_autorid_allocate_id: " + "Refusing creation of mapping for domain'%s'. " + "Currently only supported for the default " + "domain \"*\".\n", + dom->name)); + return NT_STATUS_NOT_IMPLEMENTED; + } + + if ((xid->type != ID_TYPE_UID) && (xid->type != ID_TYPE_GID)) { + return NT_STATUS_INVALID_PARAMETER; + } + + + globalcfg = talloc_get_type(dom->private_data, + struct autorid_global_config); + + /* fetch the range for the allocation pool */ + + ZERO_STRUCT(domaincfg); + + domaincfg.globalcfg = globalcfg; + fstrcpy(domaincfg.sid, ALLOC_RANGE); + + ret = dbwrap_trans_do(autorid_db, + idmap_autorid_get_domainrange, + &domaincfg); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(3, ("Could not determine range for allocation pool, " + "check previous messages for reason\n")); + return ret; + } + + /* fetch the current HWM */ + hwmkey = (xid->type==ID_TYPE_UID)?ALLOC_HWM_UID:ALLOC_HWM_GID; + + if (!dbwrap_fetch_uint32(autorid_db, hwmkey, &hwm)) { + DEBUG(1, ("Failed to fetch current allocation HWM value: %s\n", + nt_errstr(ret))); + return NT_STATUS_INTERNAL_ERROR; + } + + if (hwm >= globalcfg->rangesize) { + DEBUG(1, ("allocation range is depleted!\n")); + return NT_STATUS_NO_MEMORY; + } + + ret = dbwrap_change_uint32_atomic(autorid_db, hwmkey, &(xid->id), 1); + if (!NT_STATUS_IS_OK(ret)) { + DEBUG(1, ("Fatal error while allocating new ID!\n")); + return ret; + } + + xid->id = globalcfg->minvalue + + globalcfg->rangesize * domaincfg.domainnum + + xid->id; + + DEBUG(10, ("Returned new %s %d from allocation range\n", + (xid->type==ID_TYPE_UID)?"uid":"gid", xid->id)); + + return ret; +} + /* Close the idmap tdb instance */ @@ -561,6 +653,7 @@ static struct idmap_methods autorid_methods = { .init = idmap_autorid_initialize, .unixids_to_sids = idmap_autorid_unixids_to_sids, .sids_to_unixids = idmap_autorid_sids_to_unixids, + .allocate_id = idmap_autorid_allocate_id }; NTSTATUS idmap_autorid_init(void) -- 1.7.1 From a5cf0fb977bae9d10fc9b7e873fc477e3e58aa21 Mon Sep 17 00:00:00 2001 From: Christian Ambach Date: Thu, 20 Oct 2011 18:53:02 +0200 Subject: [PATCH 4/4] s3:idmap_autorid: document allocation pool document the need that excessive use of local users/group might require increasing the rangesize Autobuild-User: Christian Ambach Autobuild-Date: Fri Oct 21 18:04:50 CEST 2011 on sn-devel-104 --- docs-xml/manpages-3/idmap_autorid.8.xml | 7 ++++++- 1 files changed, 6 insertions(+), 1 deletions(-) diff --git a/docs-xml/manpages-3/idmap_autorid.8.xml b/docs-xml/manpages-3/idmap_autorid.8.xml index 87b9268..c437d0e 100644 --- a/docs-xml/manpages-3/idmap_autorid.8.xml +++ b/docs-xml/manpages-3/idmap_autorid.8.xml @@ -51,7 +51,12 @@ for regular users. As the parameter cannot be changed later, please plan accordingly for your expected number of users in a domain with safety margins. - + + One range will be used for local users and groups. + Thus the number of local users and groups that can be created is + limited by this option as well. If you plan to create a large amount + of local users or groups, you will need set this parameter accordingly. + The default value is 100000. -- 1.7.1