2009-07-18 Peter Vrabec <pvrabec@redhat.com>

* NEWS, libmisc/find_new_gid.c, libmisc/find_new_uid.c: Since
	system accounts are allocated from SYS_?ID_MIN to SYS_?ID_MAX in
	reverse order, accounts are packed close to SYS_?ID_MAX if
	SYS_?ID_MIN is already used but there are still dome gaps.
This commit is contained in:
nekral-guest
2009-07-18 00:35:35 +00:00
parent b0bcb01888
commit 56c7096000
4 changed files with 117 additions and 76 deletions

View File

@@ -52,7 +52,7 @@ int find_new_gid (bool sys_group,
/*@null@*/gid_t const *preferred_gid)
{
const struct group *grp;
gid_t gid_min, gid_max, group_id;
gid_t gid_min, gid_max, group_id, id;
bool *used_gids;
assert (gid != NULL);
@@ -61,7 +61,7 @@ int find_new_gid (bool sys_group,
gid_min = (gid_t) getdef_ulong ("GID_MIN", 1000UL);
gid_max = (gid_t) getdef_ulong ("GID_MAX", 60000UL);
} else {
gid_min = (gid_t) getdef_ulong ("SYS_GID_MIN", 1UL);
gid_min = (gid_t) getdef_ulong ("SYS_GID_MIN", 101UL);
gid_max = (gid_t) getdef_ulong ("GID_MIN", 1000UL) - 1;
gid_max = (gid_t) getdef_ulong ("SYS_GID_MAX", (unsigned long) gid_max);
}
@@ -80,7 +80,6 @@ int find_new_gid (bool sys_group,
return 0;
}
group_id = gid_min;
/*
* Search the entire group file,
@@ -90,19 +89,33 @@ int find_new_gid (bool sys_group,
* but we also check the local database (gr_rewind/gr_next) in case
* some groups were created but the changes were not committed yet.
*/
if (sys_group ) {
if (sys_group) {
/* setgrent / getgrent / endgrent can be very slow with
* LDAP configurations (and many accounts).
* Since there is a limited amount of IDs to be tested
* for system accounts, we just check the existence
* of IDs with getgrgid.
*/
for (group_id = gid_min; group_id <= gid_max; group_id++) {
if (getgrgid (group_id) != NULL) {
group_id = gid_max;
for (id = gid_max; id >= gid_min; id--) {
if (getgrgid (id) != NULL) {
group_id = id - 1;
used_gids[id] = true;
}
}
gr_rewind ();
while ((grp = gr_next ()) != NULL) {
if ((grp->gr_gid <= group_id) && (grp->gr_gid >= gid_min)) {
group_id = grp->gr_gid - 1;
}
/* create index of used GIDs */
if (grp->gr_gid <= gid_max) {
used_gids[grp->gr_gid] = true;
}
}
} else {
group_id = gid_min;
setgrent ();
while ((grp = getgrent ()) != NULL) {
if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) {
@@ -114,32 +127,16 @@ int find_new_gid (bool sys_group,
}
}
endgrent ();
}
gr_rewind ();
while ((grp = gr_next ()) != NULL) {
if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) {
group_id = grp->gr_gid + 1;
}
/* create index of used GIDs */
if (grp->gr_gid <= gid_max) {
used_gids[grp->gr_gid] = true;
}
}
/* find free system account in reverse order */
if (sys_group) {
for (group_id = gid_max; group_id >= gid_min; group_id--) {
if (false == used_gids[group_id]) {
break;
gr_rewind ();
while ((grp = gr_next ()) != NULL) {
if ((grp->gr_gid >= group_id) && (grp->gr_gid <= gid_max)) {
group_id = grp->gr_gid + 1;
}
/* create index of used GIDs */
if (grp->gr_gid <= gid_max) {
used_gids[grp->gr_gid] = true;
}
}
if ( group_id < gid_min ) {
fprintf (stderr,
_("%s: Can't get unique GID (no more available GIDs)\n"),
Prog);
SYSLOG ((LOG_WARN,
"no more available GID on the system"));
return -1;
}
}
@@ -148,16 +145,36 @@ int find_new_gid (bool sys_group,
* will give us GID_MAX+1 even if not unique. Search for the first
* free GID starting with GID_MIN.
*/
if (group_id == gid_max + 1) {
for (group_id = gid_min; group_id < gid_max; group_id++) {
if (false == used_gids[group_id]) {
break;
if (sys_group) {
if (group_id == gid_min - 1) {
for (group_id = gid_max; group_id >= gid_min; group_id--) {
if (false == used_gids[group_id]) {
break;
}
}
if ( group_id < gid_min ) {
fprintf (stderr,
_("%s: Can't get unique system GID (no more available GIDs)\n"),
Prog);
SYSLOG ((LOG_WARN,
"no more available GID on the system"));
return -1;
}
}
if (group_id == gid_max) {
fprintf (stderr, _("%s: Can't get unique GID (no more available GIDs)\n"), Prog);
SYSLOG ((LOG_WARN, "no more available GID on the system"));
return -1;
} else {
if (group_id == gid_max + 1) {
for (group_id = gid_min; group_id < gid_max; group_id++) {
if (false == used_gids[group_id]) {
break;
}
}
if (group_id == gid_max) {
fprintf (stderr,
_("%s: Can't get unique GID (no more available GIDs)\n"),
Prog);
SYSLOG ((LOG_WARN, "no more available GID on the system"));
return -1;
}
}
}