From e171c3bfa8c2ab0fe28c90f94b51cc75679863bc Mon Sep 17 00:00:00 2001 From: mdw Date: Mon, 8 Jun 1998 11:21:22 +0000 Subject: [PATCH] Fixed bug in password and group file reading: strtok doesn't handle double colons nicely. --- src/userdb.c | 129 ++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 74 insertions(+), 55 deletions(-) diff --git a/src/userdb.c b/src/userdb.c index 05ace82..9151b70 100644 --- a/src/userdb.c +++ b/src/userdb.c @@ -1,6 +1,6 @@ /* -*-c-*- * - * $Id: userdb.c,v 1.7 1998/04/23 13:27:46 mdw Exp $ + * $Id: userdb.c,v 1.8 1998/06/08 11:21:22 mdw Exp $ * * User database management * @@ -29,6 +29,10 @@ /*----- Revision history --------------------------------------------------* * * $Log: userdb.c,v $ + * Revision 1.8 1998/06/08 11:21:22 mdw + * Fixed bug in password and group file reading: strtok doesn't handle + * double colons nicely. + * * Revision 1.7 1998/04/23 13:27:46 mdw * Switch to using the ypstuff interface to YP server. * @@ -248,6 +252,39 @@ static void userdb__dumpUser(const struct passwd *pw) #endif +/* --- @userdb__split@ --- * + * + * Arguments: @char *p@ = pointer to string + * @char **v@ = pointer to vector to fill in + * @int sz@ = maximum number of fields to split + * + * Returns: Number of fields extracted. + * + * Use: Splits a string into fields at colon characters. + */ + +static int userdb__split(char *p, char **v, int sz) +{ + int count = 0; + + *v++ = p; sz--; count++; + if (!sz) + goto done; + while (*p) { + if (*p++ == ':') { + p[-1] = 0; + *v++ = p; sz--; count++; + if (!sz) + goto done; + } + } + while (sz--) + *v++ = 0; + +done: + return (count); +} + /* --- @userdb_copyUser@ --- * * * Arguments: @struct passwd *pw@ = pointer to block to copy @@ -293,30 +330,21 @@ struct passwd *userdb_copyUser(struct passwd *pw) static struct passwd *userdb__buildUser(char *s) { struct passwd *pw = xmalloc(sizeof(*pw)); + char *v[7]; - s = strtok(s, ":"); if (!s) goto tidy_0; pw->pw_name = xstrdup(s); - s = strtok(0, ":"); if (!s) goto tidy_1; pw->pw_passwd = xstrdup(s); - s = strtok(0, ":"); if (!s) goto tidy_2; pw->pw_uid = (uid_t)atol(s); - s = strtok(0, ":"); if (!s) goto tidy_2; pw->pw_gid = (gid_t)atol(s); - s = strtok(0, ":"); if (!s) goto tidy_2; pw->pw_gecos = xstrdup(s); - s = strtok(0, ":"); if (!s) goto tidy_3; pw->pw_dir = xstrdup(s); - s = strtok(0, ":"); if (!s) goto tidy_4; pw->pw_shell = xstrdup(s); - return (pw); - - /* --- Error handling --- */ - -tidy_4: - free(pw->pw_dir); -tidy_3: - free(pw->pw_gecos); -tidy_2: - free(pw->pw_passwd); -tidy_1: - free(pw->pw_name); -tidy_0: - free(pw); + if (userdb__split(s, v, 7) < 7) { + free(pw); + return (0); + } - return (0); + pw->pw_name = xstrdup(v[0]); + pw->pw_passwd = xstrdup(v[1]); + pw->pw_uid = (uid_t)atol(v[2]); + pw->pw_gid = (gid_t)atol(v[3]); + pw->pw_gecos = xstrdup(v[4]); + pw->pw_dir = xstrdup(v[5]); + pw->pw_shell = xstrdup(v[6]); + return (pw); } /* --- @userdb_freeUser@ --- * @@ -417,55 +445,46 @@ struct group *userdb_copyGroup(struct group *gr) static struct group *userdb__buildGroup(char *s) { struct group *gr = xmalloc(sizeof(*gr)); - char *p; + char *v[4]; int i; /* --- Do the easy bits --- */ - s = strtok(s, ":"); if (!s) goto tidy_0; gr->gr_name = xstrdup(s); - s = strtok(0, ":"); if (!s) goto tidy_1; gr->gr_passwd = xstrdup(s); - s = strtok(0, ":"); if (!s) goto tidy_2; gr->gr_gid = (gid_t)atol(s); - - /* --- Find the start of the member list --- */ - - s = strtok(0, ""); - if (!s) - goto tidy_2; + if (userdb__split(s, v, 4) < 3) { + free(gr); + return (0); + } + gr->gr_name = xstrdup(v[0]); + gr->gr_passwd = xstrdup(v[1]); + gr->gr_gid = (gid_t)atol(v[2]); /* --- Count the number of members --- */ - p = s; + s = v[3]; i = 0; - for (;;) { - i++; - if ((p = strpbrk(p, ",")) == 0) - break; - p++; + if (s && s[0]) { + for (;;) { + i++; + if ((s = strpbrk(s, ",")) == 0) + break; + s++; + } } /* --- Allocate the block and fill it --- */ gr->gr_mem = xmalloc((i + 1) * sizeof(char *)); i = 0; - s = strtok(s, ","); - do { - gr->gr_mem[i++] = xstrdup(s); - s = strtok(0, ","); - } while (s); + if (v[3]) { + s = strtok(v[3], ","); + while (s) { + gr->gr_mem[i++] = xstrdup(s); + s = strtok(0, ","); + } + } gr->gr_mem[i] = 0; return (gr); - - /* --- Various tidying-up things --- */ - -tidy_2: - free(gr->gr_passwd); -tidy_1: - free(gr->gr_name); -tidy_0: - free(gr); - - return (0); } /* --- @userdb_freeGroup@ --- * -- 2.11.0