commit correct tested fix for gr_util.c

Approved by:	theraven
This commit is contained in:
Diane Bruce 2013-03-09 13:30:06 +00:00
parent ce589ae2a7
commit 5e87983769
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=248102

View File

@ -50,7 +50,7 @@ static char group_file[PATH_MAX];
static char tempname[PATH_MAX]; static char tempname[PATH_MAX];
static int initialized; static int initialized;
static size_t grmemlen(const struct group *, const char *, int *); static size_t grmemlen(const struct group *, const char *, int *);
static struct group *grcopy(const struct group *gr, struct group *newgr, const char *, int ndx); static struct group *grcopy(const struct group *gr, char *mem, const char *, int ndx);
/* /*
* Initialize statics * Initialize statics
@ -361,26 +361,30 @@ gr_equal(const struct group *gr1, const struct group *gr2)
if (gr1->gr_gid != gr2->gr_gid) if (gr1->gr_gid != gr2->gr_gid)
return (false); return (false);
/* Check all members in both groups. */ /* Check all members in both groups.
if (gr1->gr_mem == NULL || gr2->gr_mem == NULL) { * getgrnam can return gr_mem with a pointer to NULL.
if (gr1->gr_mem != gr2->gr_mem) * gr_dup and gr_add strip out this superfluous NULL, setting
return (false); * gr_mem to NULL for no members.
} else { */
for (gr1_ndx = 0; gr1->gr_mem[gr1_ndx] != NULL; gr1_ndx++) { if (gr1->gr_mem != NULL && gr2->gr_mem != NULL) {
for (gr2_ndx = 0;; gr2_ndx++) { int i;
if (gr2->gr_mem[gr2_ndx] == NULL)
return (false);
if (strcmp(gr1->gr_mem[gr1_ndx],
gr2->gr_mem[gr2_ndx]) == 0) {
break;
}
}
}
/* Check that group2 does not have more members than group1. */ for (i = 0; gr1->gr_mem[i] != NULL; i++) {
if (gr2->gr_mem[gr1_ndx] != NULL) if (strcmp(gr1->gr_mem[i], gr2->gr_mem[i]) != 0)
return (false); return (false);
}
} }
/* Count number of members in both structs */
gr2_ndx = 0;
if (gr2->gr_mem != NULL)
for(; gr2->gr_mem[gr2_ndx] != NULL; gr2_ndx++)
/* empty */;
gr1_ndx = 0;
if (gr1->gr_mem != NULL)
for(; gr1->gr_mem[gr1_ndx] != NULL; gr1_ndx++)
/* empty */;
if (gr1_ndx != gr2_ndx)
return (false);
return (true); return (true);
} }
@ -439,21 +443,21 @@ gr_dup(const struct group *gr)
struct group * struct group *
gr_add(const struct group *gr, const char *newmember) gr_add(const struct group *gr, const char *newmember)
{ {
struct group *newgr; char *mem;
size_t len; size_t len;
int num_mem; int num_mem;
num_mem = 0; num_mem = 0;
len = grmemlen(gr, newmember, &num_mem); len = grmemlen(gr, newmember, &num_mem);
/* Create new group and copy old group into it. */ /* Create new group and copy old group into it. */
if ((newgr = malloc(len)) == NULL) if ((mem = malloc(len)) == NULL)
return (NULL); return (NULL);
return (grcopy(gr, newgr, newmember, num_mem)); return (grcopy(gr, mem, newmember, num_mem));
} }
/* It is safer to walk the pointers given at gr_mem since there is no /* It is safer to walk the pointers given at gr_mem since there is no
* guarantee the gr_mem + strings are continguous in the given struct group * guarantee the gr_mem + strings are contiguous in the given struct group
* but compact the new group into the following form. * but compactify the new group into the following form.
* *
* The new struct is laid out like this in memory. The example given is * The new struct is laid out like this in memory. The example given is
* for a group with two members only. * for a group with two members only.
@ -474,23 +478,21 @@ gr_add(const struct group *gr, const char *newmember)
* } * }
*/ */
/* /*
* Copy the guts of a group plus given name to a preallocated group struct * Copy the contents of a group plus given name to a preallocated group struct
*/ */
static struct group * static struct group *
grcopy(const struct group *gr, struct group *newgr, const char *name, int ndx) grcopy(const struct group *gr, char *dst, const char *name, int ndx)
{ {
char *dst;
int i; int i;
struct group *newgr;
if (name != NULL) newgr = (struct group *)(void *)dst; /* avoid alignment warning */
ndx++; dst += sizeof(*newgr);
/* point new gr_mem to end of struct + 1 if there are names */ if (ndx != 0) {
if (ndx != 0) newgr->gr_mem = (char **)(void *)(dst); /* avoid alignment warning */
newgr->gr_mem = (char **)(newgr + 1); dst += (ndx + 1) * sizeof(*newgr->gr_mem);
else } else
newgr->gr_mem = NULL; newgr->gr_mem = NULL;
/* point dst after the end of all the gr_mem pointers in newgr */
dst = (char *)&newgr->gr_mem[ndx + 1];
if (gr->gr_name != NULL) { if (gr->gr_name != NULL) {
newgr->gr_name = dst; newgr->gr_name = dst;
dst = stpcpy(dst, gr->gr_name) + 1; dst = stpcpy(dst, gr->gr_name) + 1;
@ -502,17 +504,23 @@ grcopy(const struct group *gr, struct group *newgr, const char *name, int ndx)
} else } else
newgr->gr_passwd = NULL; newgr->gr_passwd = NULL;
newgr->gr_gid = gr->gr_gid; newgr->gr_gid = gr->gr_gid;
if (ndx != 0) { i = 0;
for (i = 0; gr->gr_mem[i] != NULL; i++) { /* Original group struct might have a NULL gr_mem */
if (gr->gr_mem != NULL) {
for (; gr->gr_mem[i] != NULL; i++) {
newgr->gr_mem[i] = dst; newgr->gr_mem[i] = dst;
dst = stpcpy(dst, gr->gr_mem[i]) + 1; dst = stpcpy(dst, gr->gr_mem[i]) + 1;
} }
if (name != NULL) {
newgr->gr_mem[i++] = dst;
dst = stpcpy(dst, name) + 1;
}
newgr->gr_mem[i] = NULL;
} }
/* If name is not NULL, newgr->gr_mem is known to be not NULL */
if (name != NULL) {
newgr->gr_mem[i++] = dst;
dst = stpcpy(dst, name) + 1;
}
/* if newgr->gr_mem is not NULL add NULL marker */
if (newgr->gr_mem != NULL)
newgr->gr_mem[i] = NULL;
return (newgr); return (newgr);
} }
@ -533,18 +541,22 @@ grmemlen(const struct group *gr, const char *name, int *num_mem)
len += strlen(gr->gr_name) + 1; len += strlen(gr->gr_name) + 1;
if (gr->gr_passwd != NULL) if (gr->gr_passwd != NULL)
len += strlen(gr->gr_passwd) + 1; len += strlen(gr->gr_passwd) + 1;
i = 0;
if (gr->gr_mem != NULL) { if (gr->gr_mem != NULL) {
for (len = i = 0; gr->gr_mem[i] != NULL; i++) { for (; gr->gr_mem[i] != NULL; i++) {
len += strlen(gr->gr_mem[i]) + 1; len += strlen(gr->gr_mem[i]) + 1;
len += sizeof(*gr->gr_mem); len += sizeof(*gr->gr_mem);
} }
*num_mem = i;
} }
if (name != NULL) { if (name != NULL) {
i++;
len += strlen(name) + 1; len += strlen(name) + 1;
if (gr->gr_mem == NULL) len += sizeof(*gr->gr_mem);
len += sizeof(*gr->gr_mem);
} }
/* Allow for NULL pointer */
if (i != 0)
len += sizeof(*gr->gr_mem);
*num_mem = i;
return(len); return(len);
} }