diff -ur source/sam.orig/idmap.c source/sam.new/idmap.c --- source/sam.orig/idmap.c Wed Mar 24 22:33:34 2004 +++ source/sam.new/idmap.c Thu Mar 25 01:59:14 2004 @@ -253,17 +253,60 @@ } /************************************************************************** + Returns true if the specified ID exists in idmap or the local system. +**************************************************************************/ + +BOOL idmap_id_exists(unid_t id, int id_type) +{ + DOM_SID sid; + BOOL exists; + unsigned long ul_id = (unsigned long) ((id_type & ID_USERID) ? id.uid : id.gid); + + DEBUG(1,("idmap_id_exists: Checking if %s %u exists.\n", + ((id_type & ID_USERID) ? "uid" : "gid"), ul_id)); + + sid.sid_rev_num = 0; + + exists = NT_STATUS_IS_OK(idmap_get_sid_from_id(&sid, id, id_type)) + || sid.sid_rev_num; + + if (exists) { + DEBUG(1,("idmap_id_exists: %s %u exists in idmap mapping.\n", + ((id_type & ID_USERID) ? "uid" : "gid"), ul_id)); + } + else { + exists = (((id_type & ID_TYPEMASK) == ID_USERID) + ? getpwuid(id.uid) != NULL + : getgrgid(id.gid) != NULL); + + if (exists) { + DEBUG(1,("idmap_id_exists: %s %u exists in local filesys tem.\n", + ((id_type & ID_USERID) ? "uid" : "gid"), ul_id)) ; + } + } + + return exists; +} + +/************************************************************************** Alloocate a new UNIX uid/gid **************************************************************************/ NTSTATUS idmap_allocate_id(unid_t *id, int id_type) { - /* we have to allocate from the authoritative backend */ - - if ( remote_map ) - return remote_map->allocate_id( id, id_type ); + NTSTATUS status; + + /* loop to find an unused id in the idmap range */ + do { + /* we have to allocate from the authoritative backend */ + if ( remote_map ) + status = remote_map->allocate_id( id, id_type ); + else + status = cache_map->allocate_id( id, id_type ); + + } while (NT_STATUS_IS_OK(status) && idmap_id_exists(*id, id_type)); - return cache_map->allocate_id( id, id_type ); + return status; } /************************************************************************** diff -ur source/sam.orig/idmap_ldap.c source/sam.new/idmap_ldap.c --- source/sam.orig/idmap_ldap.c Wed Mar 24 22:33:34 2004 +++ source/sam.new/idmap_ldap.c Thu Mar 25 02:06:56 2004 @@ -523,7 +523,7 @@ count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result ); if (count != 1) { - DEBUG(0,("ldap_get_sid_from_id: mapping not found for %s: %lu\n" , + DEBUG(1,("ldap_get_sid_from_id: mapping not found for %s: %lu\n" , type, ((id_type & ID_USERID) ? (unsigned long)id.uid : (unsigned long)id.gid))); goto out; @@ -617,7 +617,7 @@ DEBUG(8,("ldap_get_id_from_sid: Allocating new id\n")); for (i = 0; i < LDAP_MAX_ALLOC_ID; i++) { - ret = ldap_allocate_id(id, *id_type); + ret = idmap_allocate_id(id, *id_type); if ( NT_STATUS_IS_OK(ret) ) break; } diff -ur source/sam.orig/idmap_tdb.c source/sam.new/idmap_tdb.c --- source/sam.orig/idmap_tdb.c Wed Mar 24 22:33:34 2004 +++ source/sam.new/idmap_tdb.c Thu Mar 25 02:08:44 2004 @@ -357,7 +357,7 @@ fstring ugid_str; /* Allocate a new id for this sid */ - ret = db_allocate_id(id, *id_type); + ret = idmap_allocate_id(id, *id_type); if (!NT_STATUS_IS_OK(ret)) break;