+2007-11-16 Nicolas François <nicolas.francois@centraliens.net>
+
+ * lib/commonio.c (next_entry_by_name): New function.
+ * NEWS, lib/commonio.c (commonio_update): When an entry is updated, make
+ sure that there are no other entry with the same name. This fixes
+ an infinite loop in userdel and usermod when an (erroneous) group
+ file contains two entries with the same name.
+ (https://bugzilla.redhat.com/show_bug.cgi?id=240915)
+
2007-11-16 Nicolas François <nicolas.francois@centraliens.net>
* libmisc/salt.c: Make sure the salt string is terminated at the
(i.e. lookup in the local database for an user with an @). Thanks to
Mike Frysinger for the patch.
- Add support for uClibc with no l64a().
+- userdel/usermod: Fix infinite loop caused by erroneous group file
+ containing two entries with the same name. (The fix strategy differs
+ from
+ (https://bugzilla.redhat.com/show_bug.cgi?id=240915)
shadow-4.0.18.1 -> shadow-4.0.18.2 28-10-2007
static int write_all (const struct commonio_db *);
static struct commonio_entry *find_entry_by_name (struct commonio_db *,
const char *);
+static struct commonio_entry *next_entry_by_name (struct commonio_db *,
+ struct commonio_entry *pos,
+ const char *);
static int lock_count = 0;
static int nscd_need_reload = 0;
return errors == 0;
}
-
-static struct commonio_entry *find_entry_by_name (struct commonio_db *db,
- const char *name)
+static struct commonio_entry *next_entry_by_name (struct commonio_db *db,
+ struct commonio_entry *pos,
+ const char *name)
{
struct commonio_entry *p;
void *ep;
- for (p = db->head; p; p = p->next) {
+ if (NULL == pos)
+ return NULL;
+
+ for (p = pos; p; p = p->next) {
ep = p->eptr;
if (ep && strcmp (db->ops->getname (ep), name) == 0)
break;
return p;
}
+static struct commonio_entry *find_entry_by_name (struct commonio_db *db,
+ const char *name)
+{
+ return next_entry_by_name(db, db->head, name);
+}
+
int commonio_update (struct commonio_db *db, const void *eptr)
{
}
p = find_entry_by_name (db, db->ops->getname (eptr));
if (p) {
+ if (next_entry_by_name (db, p->next, db->ops->getname (eptr)))
+ {
+ fprintf (stderr, _("Multiple entries named '%s' in %s. Please fix this with pwck or grpck.\n"), db->ops->getname (eptr), db->filename);
+ return 0;
+ }
db->ops->free (p->eptr);
p->eptr = nentry;
p->changed = 1;