commit correct tested fix for gr_util.c
Approved by: theraven
This commit is contained in:
parent
ce589ae2a7
commit
5e87983769
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=248102
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user