The Samba-Bugzilla – Attachment 454 Details for
Bug 1212
Existing uids/gids severely limit range of available ids
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Check idmap and local files before returning newly allocated ids.
sam.diff (text/plain), 11.08 KB, created by
John Klinger
on 2004-03-24 15:45:23 UTC
(
hide
)
Description:
Check idmap and local files before returning newly allocated ids.
Filename:
MIME Type:
Creator:
John Klinger
Created:
2004-03-24 15:45:23 UTC
Size:
11.08 KB
patch
obsolete
>diff -ru source/sam.orig/idmap.c source/sam/idmap.c >--- source/sam.orig/idmap.c Wed Mar 24 22:33:34 2004 >+++ source/sam/idmap.c Wed Mar 24 22:21:45 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 filesystem.\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 -ru source/sam.orig/idmap_ldap.c source/sam/idmap_ldap.c >--- source/sam.orig/idmap_ldap.c Wed Mar 24 22:33:34 2004 >+++ source/sam/idmap_ldap.c Wed Mar 24 22:21:45 2004 >@@ -398,81 +398,88 @@ > > attr_list = get_attr_list( idpool_attr_list ); > >- rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(), >- LDAP_SCOPE_SUBTREE, filter, >- attr_list, 0, &result); >- free_attr_list( attr_list ); >- >- if (rc != LDAP_SUCCESS) { >- DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL)); >- goto out; >- } >- >- count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); >- if (count != 1) { >- DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL)); >- goto out; >- } >- >- dn = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result); >- if (!dn) { >- goto out; >- } >- entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); >- >- if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, type, id_str)) { >- DEBUG(0,("ldap_allocate_id: %s attribute not found\n", >- type)); >- goto out; >- } >- >- /* this must succeed or else we wouldn't have initialized */ >+ do >+ { >+ result = NULL; >+ mods = NULL; >+ rc = smbldap_search(ldap_state.smbldap_state, lp_ldap_idmap_suffix(), >+ LDAP_SCOPE_SUBTREE, filter, >+ attr_list, 0, &result); >+ >+ if (rc != LDAP_SUCCESS) { >+ DEBUG(0,("ldap_allocate_id: %s object not found\n", LDAP_OBJ_IDPOOL)); >+ goto out; >+ } > >- lp_idmap_uid( &luid, &huid); >- lp_idmap_gid( &lgid, &hgid); >- >- /* make sure we still have room to grow */ >+ count = ldap_count_entries(ldap_state.smbldap_state->ldap_struct, result); >+ if (count != 1) { >+ DEBUG(0,("ldap_allocate_id: single %s object not found\n", LDAP_OBJ_IDPOOL)); >+ goto out; >+ } > >- if (id_type & ID_USERID) { >- id->uid = strtoul(id_str, NULL, 10); >- if (id->uid > huid ) { >- DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n", >- (unsigned long)huid)); >+ dn = smbldap_get_dn(ldap_state.smbldap_state->ldap_struct, result); >+ if (!dn) { > goto out; > } >- } >- else { >- id->gid = strtoul(id_str, NULL, 10); >- if (id->gid > hgid ) { >- DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n", >- (unsigned long)hgid)); >+ entry = ldap_first_entry(ldap_state.smbldap_state->ldap_struct, result); >+ >+ if (!smbldap_get_single_attribute(ldap_state.smbldap_state->ldap_struct, entry, type, id_str)) { >+ DEBUG(0,("ldap_allocate_id: %s attribute not found\n", >+ type)); > goto out; > } >- } > >- pstr_sprintf(new_id_str, "%lu", >- ((id_type & ID_USERID) ? (unsigned long)id->uid : >- (unsigned long)id->gid) + 1); >+ /* this must succeed or else we wouldn't have initialized */ >+ >+ lp_idmap_uid( &luid, &huid); >+ lp_idmap_gid( &lgid, &hgid); >+ >+ /* make sure we still have room to grow */ >+ >+ if (id_type & ID_USERID) { >+ id->uid = strtoul(id_str, NULL, 10); >+ if (id->uid > huid ) { >+ DEBUG(0,("ldap_allocate_id: Cannot allocate uid above %lu!\n", >+ (unsigned long)huid)); >+ goto out; >+ } >+ } >+ else { >+ id->gid = strtoul(id_str, NULL, 10); >+ if (id->gid > hgid ) { >+ DEBUG(0,("ldap_allocate_id: Cannot allocate gid above %lu!\n", >+ (unsigned long)hgid)); >+ goto out; >+ } >+ } >+ >+ pstr_sprintf(new_id_str, "%lu", >+ ((id_type & ID_USERID) ? (unsigned long)id->uid : >+ (unsigned long)id->gid) + 1); > >- smbldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str ); >- smbldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str ); >+ smbldap_set_mod( &mods, LDAP_MOD_DELETE, type, id_str ); >+ smbldap_set_mod( &mods, LDAP_MOD_ADD, type, new_id_str ); > >- if (mods == NULL) { >- DEBUG(0,("ldap_allocate_id: smbldap_set_mod() failed.\n")); >- goto out; >- } >+ if (mods == NULL) { >+ DEBUG(0,("ldap_allocate_id: smbldap_set_mod() failed.\n")); >+ goto out; >+ } > >- rc = smbldap_modify(ldap_state.smbldap_state, dn, mods); >+ rc = smbldap_modify(ldap_state.smbldap_state, dn, mods); > >- ldap_mods_free( mods, True ); >- if (rc != LDAP_SUCCESS) { >- DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n", >- type)); >- goto out; >- } >+ ldap_mods_free( mods, True ); >+ if (rc != LDAP_SUCCESS) { >+ DEBUG(0,("ldap_allocate_id: Failed to allocate new %s. ldap_modify() failed.\n", >+ type)); >+ goto out; >+ } >+ /* repeat if the id collides with an existing global or local id */ >+ } while (idmap_id_exists(*id, id_type)); >+ > > ret = NT_STATUS_OK; > out: >+ free_attr_list( attr_list ); > SAFE_FREE(dn); > if (result != NULL) > ldap_msgfree(result); >@@ -523,7 +530,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; >diff -ru source/sam.orig/idmap_tdb.c source/sam/idmap_tdb.c >--- source/sam.orig/idmap_tdb.c Wed Mar 24 22:33:34 2004 >+++ source/sam/idmap_tdb.c Wed Mar 24 22:21:45 2004 >@@ -95,64 +95,71 @@ > /* Get current high water mark */ > switch (id_type & ID_TYPEMASK) { > case ID_USERID: >- >- if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) { >- return NT_STATUS_INTERNAL_DB_ERROR; >- } >- >- /* check it is in the range */ >- if (hwm > idmap_state.uid_high) { >- DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n", >- (unsigned long)idmap_state.uid_high)); >- return NT_STATUS_UNSUCCESSFUL; >- } >- >- /* fetch a new id and increment it */ >- ret = tdb_change_uint32_atomic(idmap_tdb, HWM_USER, (unsigned int *)&hwm, 1); >- if (!ret) { >- DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!")); >- return NT_STATUS_UNSUCCESSFUL; >- } >- >- /* recheck it is in the range */ >- if (hwm > idmap_state.uid_high) { >- DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n", >- (unsigned long)idmap_state.uid_high)); >- return NT_STATUS_UNSUCCESSFUL; >- } >+ do >+ { >+ if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_USER)) == -1) { >+ return NT_STATUS_INTERNAL_DB_ERROR; >+ } >+ >+ /* check it is in the range */ >+ if (hwm > idmap_state.uid_high) { >+ DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n", >+ (unsigned long)idmap_state.uid_high)); >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ >+ /* fetch a new id and increment it */ >+ ret = tdb_change_uint32_atomic(idmap_tdb, HWM_USER, (unsigned int *)&hwm, 1); >+ if (!ret) { >+ DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!")); >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ >+ /* recheck it is in the range */ >+ if (hwm > idmap_state.uid_high) { >+ DEBUG(0, ("idmap Fatal Error: UID range full!! (max: %lu)\n", >+ (unsigned long)idmap_state.uid_high)); >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ (*id).uid = hwm; >+ /* repeat if the id collides with an existing global or local id */ >+ } while (idmap_id_exists(*id, id_type)); > >- (*id).uid = hwm; > DEBUG(10,("db_allocate_id: ID_USERID (*id).uid = %d\n", (unsigned int)hwm)); > > break; > case ID_GROUPID: >- if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) { >- return NT_STATUS_INTERNAL_DB_ERROR; >- } >- >- /* check it is in the range */ >- if (hwm > idmap_state.gid_high) { >- DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n", >- (unsigned long)idmap_state.gid_high)); >- return NT_STATUS_UNSUCCESSFUL; >- } >- >- /* fetch a new id and increment it */ >- ret = tdb_change_uint32_atomic(idmap_tdb, HWM_GROUP, (unsigned int *)&hwm, 1); >- >- if (!ret) { >- DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!")); >- return NT_STATUS_UNSUCCESSFUL; >- } >- >- /* recheck it is in the range */ >- if (hwm > idmap_state.gid_high) { >- DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n", >- (unsigned long)idmap_state.gid_high)); >- return NT_STATUS_UNSUCCESSFUL; >- } >- >- (*id).gid = hwm; >+ do >+ { >+ if ((hwm = tdb_fetch_int32(idmap_tdb, HWM_GROUP)) == -1) { >+ return NT_STATUS_INTERNAL_DB_ERROR; >+ } >+ >+ /* check it is in the range */ >+ if (hwm > idmap_state.gid_high) { >+ DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n", >+ (unsigned long)idmap_state.gid_high)); >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ >+ /* fetch a new id and increment it */ >+ ret = tdb_change_uint32_atomic(idmap_tdb, HWM_GROUP, (unsigned int *)&hwm, 1); >+ >+ if (!ret) { >+ DEBUG(0, ("idmap_tdb: Fatal error while fetching a new id\n!")); >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ >+ /* recheck it is in the range */ >+ if (hwm > idmap_state.gid_high) { >+ DEBUG(0, ("idmap Fatal Error: GID range full!! (max: %lu)\n", >+ (unsigned long)idmap_state.gid_high)); >+ return NT_STATUS_UNSUCCESSFUL; >+ } >+ (*id).gid = hwm; >+ /* repeat if the id collides with an existing global or local id */ >+ } while (idmap_id_exists(*id, id_type)); >+ > DEBUG(10,("db_allocate_id: ID_GROUPID (*id).gid = %d\n", (unsigned int)hwm)); > > break;
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 1212
:
454
|
455