(oops i hit send too early)
the attached patch should fix it for you.
fixes a bug in xuserset which makes it go into an infinite loop.
the user entries are read from the pwd database and stored in a local
structure.
Signed-off-by: Abhishek Kulkarni <[EMAIL PROTECTED]>
On Mon, 2008-11-24 at 15:49 -0500, Daniel Gruner wrote:
> The latest version in the repository (734) has a bug in xuserset when used as:
>
> xuserset add -a -u
>
> where it goes into an infinite loop repeating this:
>
> xp_user_add: n0000: Error 5: root:user exists
> xp_user_add: n0001: Error 5: root:user exists
> xp_user_add: n0000: Error 5: root:user exists
> xp_user_add: n0001: Error 5: root:user exists
>
> This had happened before, and was fixed then...
>
> This is from the Nov 3 thread:
>
> arrgh, it works fine on my home machine too..
> but i think i have caught the bug. so getpwent() should loop over the
> passwd database (contents of /etc/passwd) but in xp_user_add, there's
> again a call to getpwnam() which could possibly reset the passwd database
> and getpwent() again returns "root" entry in the next iteration.
> this is not triggered for all libc versions and the one included in
> RHEL5.2 seems to break it open badly. I run most of my tests on
> Ubuntu/Fedora which I have started to believe is a bad choice to test this
> stuff.
>
>
> Daniel
Index: utils/xuserset.c
===================================================================
--- utils/xuserset.c (revision 734)
+++ utils/xuserset.c (working copy)
@@ -105,6 +105,13 @@
int allflag = 0, passwdfile = 0;
struct passwd *pw;
struct group *gr;
+ struct pwent {
+ char *pw_name;
+ uid_t pw_uid;
+ gid_t pw_gid;
+ char *pw_key;
+ struct pwent *next;
+ } *users, *head;
while((c = getopt(argc, argv, "aA:dhup")) != -1) {
switch(c) {
@@ -197,22 +204,31 @@
} else if (!strcmp("add", cmd)) {
if (passwdfile) {
setpwent();
+ head = NULL;
while ((pw = getpwent()) != NULL) {
snprintf(ukeypath, sizeof(ukeypath), "%s/.ssh/id_rsa.pub", pw->pw_dir);
- if (get_user_key(ukeypath, userkey, sizeof(userkey)) < 0) {
- sp_suerror("get_user_key", errno);
- continue;
+ if (!access(ukeypath, R_OK)) {
+ users = (struct pwent *)malloc(sizeof(struct pwent));
+ users->pw_name = strdup(pw->pw_name);
+ users->pw_uid = pw->pw_uid;
+ users->pw_gid = pw->pw_gid;
+ users->pw_key = strdup(ukeypath);
+ users->next = head;
+ head = users;
}
-
- if ((gr = getgrgid(pw->pw_gid)) == NULL) {
- sp_suerror("get_user_key", errno);
+ }
+ endpwent();
+
+ for(; users; users = users->next) {
+ if (get_user_key(users->pw_key, userkey, sizeof(userkey)) < 0)
continue;
- }
-
- xp_user_add(nds, adminkey, pw->pw_name, pw->pw_uid,
+
+ if ((gr = getgrgid(users->pw_gid)) == NULL)
+ continue;
+
+ xp_user_add(nds, adminkey, users->pw_name, users->pw_uid,
gr->gr_name, userkey);
}
- endpwent();
} else {
if ((argc - optind) < 4)
usage(argv[0]);