diff options
Diffstat (limited to 'source3/winbindd')
-rw-r--r-- | source3/winbindd/idmap_autorid.c | 97 |
1 files changed, 96 insertions, 1 deletions
diff --git a/source3/winbindd/idmap_autorid.c b/source3/winbindd/idmap_autorid.c index 503f8748b7..1a88fd4cb8 100644 --- a/source3/winbindd/idmap_autorid.c +++ b/source3/winbindd/idmap_autorid.c @@ -35,6 +35,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 { @@ -166,6 +169,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; } @@ -381,7 +396,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) @@ -564,6 +584,80 @@ 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; + + ret = dbwrap_fetch_uint32(autorid_db, hwmkey, &hwm); + + if (!NT_STATUS_IS_OK(ret)) { + 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 */ @@ -571,6 +665,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 samba_init_module(void) |