Skip to content

Commit

Permalink
Imlement getgrgid_r/getgrnam_r
Browse files Browse the repository at this point in the history
Contributed by medmed
  • Loading branch information
th-otto committed Jun 25, 2024
1 parent 9a35264 commit b73c576
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 3 deletions.
5 changes: 4 additions & 1 deletion include/grp.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ __EXTERN struct group * getgrent __P ((void));
__EXTERN struct group * fgetgrent __P ((FILE *f));
#endif /* __USE_SVID */

__EXTERN struct group * getgrgid __P ((int gid));
__EXTERN struct group * getgrgid __P ((__gid_t gid));
__EXTERN struct group * getgrnam __P ((const char *name));

int getgrgid_r(__gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result);
int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result);

#ifdef __USE_BSD
__EXTERN int initgroups __P ((const char* __user, __gid_t __group));
__EXTERN int setgroups __P ((size_t __count, const __gid_t* __groups));
Expand Down
2 changes: 2 additions & 0 deletions pwdgrp/SRCFILES
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,7 @@ SRCFILES = \
getpwuid.c \
getpwuid_r.c \
grp.c \
getgrgid_r.c \
getgrnam_r.c \
initgroups.c \
putpwent.c
84 changes: 84 additions & 0 deletions pwdgrp/getgrgid_r.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
*
* MMedour - 2024/06/24 - getgrgid_r & getgrnam_r draft c implementation and validation
*
*/

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <grp.h>
#include <errno.h>

int getgrgid_r(gid_t gid, struct group *grp, char *buf, size_t buflen, struct group **result)
{
char **mem_ptr;
struct group *g;
size_t gr_size, len, mem_array_counter, mem_array_pos;

if (grp == NULL || buf == NULL)
{
__set_errno(EINVAL);
*result = NULL;
return -1;
}

g = getgrgid(gid);

if (g == NULL)
{
*result = NULL;
return -1;
}

/* Get the size needed to store getgrgid */
gr_size = 0;
gr_size += strlen(g->gr_name) + 1;
gr_size += strlen(g->gr_passwd) + 1;

mem_array_counter = 0;
for (mem_ptr = g->gr_mem; *mem_ptr; mem_ptr++)
{
gr_size += strlen(*mem_ptr) + 1;
mem_array_counter++;
}
gr_size += (mem_array_counter + 1) * (sizeof(char*));

if (gr_size > buflen)
{
__set_errno(ERANGE);
*result = NULL;
return -1;
}

grp->gr_gid = g->gr_gid;

gr_size = 0;
grp->gr_mem = (char**)&buf[gr_size];
gr_size += (mem_array_counter + 1) * (sizeof(char*));

grp->gr_name = &buf[gr_size];
len = strlen(g->gr_name) + 1;
memcpy(&buf[gr_size], g->gr_name, len);
gr_size += len;

grp->gr_passwd = &buf[gr_size];
len = strlen(g->gr_passwd) + 1;
memcpy(&buf[gr_size], g->gr_passwd, len);
gr_size += len;

mem_array_pos = 0;
for (mem_ptr = g->gr_mem; *mem_ptr; mem_ptr++)
{
len = strlen(*mem_ptr) + 1;
memcpy(&buf[gr_size], *mem_ptr, len);
grp->gr_mem[mem_array_pos] = &buf[gr_size];
mem_array_pos++;
gr_size += len;
}
grp->gr_mem[mem_array_pos] = NULL;

*result = grp;
return 0;
}
84 changes: 84 additions & 0 deletions pwdgrp/getgrnam_r.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
*
* MMedour - 2024/06/24 - getgrgid_r & getgrnam_r draft c implementation and validation
*
*/

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <grp.h>
#include <errno.h>

int getgrnam_r(const char *name, struct group *grp, char *buf, size_t buflen, struct group **result)
{
char **mem_ptr;
struct group *g;
size_t gr_size, len, mem_array_counter, mem_array_pos;

if (grp == NULL || buf == NULL)
{
__set_errno(EINVAL);
*result = NULL;
return -1;
}

g = getgrnam(name);

if (g == NULL)
{
*result = NULL;
return -1;
}

/* Get the size needed to store getgrgid */
gr_size = 0;
gr_size += strlen(g->gr_name) + 1;
gr_size += strlen(g->gr_passwd) + 1;

mem_array_counter = 0;
for (mem_ptr = g->gr_mem; *mem_ptr; mem_ptr++)
{
gr_size += strlen(*mem_ptr) + 1;
mem_array_counter++;
}
gr_size += (mem_array_counter + 1) * (sizeof(char*));

if (gr_size > buflen)
{
__set_errno(ERANGE);
*result = NULL;
return -1;
}

grp->gr_gid = g->gr_gid;

gr_size = 0;
grp->gr_mem = (char**)&buf[gr_size];
gr_size += (mem_array_counter + 1) * (sizeof(char*));

grp->gr_name = &buf[gr_size];
len = strlen(g->gr_name) + 1;
memcpy(&buf[gr_size], g->gr_name, len);
gr_size += len;

grp->gr_passwd = &buf[gr_size];
len = strlen(g->gr_passwd) + 1;
memcpy(&buf[gr_size], g->gr_passwd, len);
gr_size += len;

mem_array_pos = 0;
for(mem_ptr = g->gr_mem;*mem_ptr;mem_ptr++)
{
len = strlen(*mem_ptr) + 1;
memcpy(&buf[gr_size], *mem_ptr, len);
grp->gr_mem[mem_array_pos] = &buf[gr_size];
mem_array_pos++;
gr_size += len;
}
grp->gr_mem[mem_array_pos] = NULL;

*result = grp;
return 0;
}
2 changes: 1 addition & 1 deletion pwdgrp/grp.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ struct group *getgrent(void)
} /* End of getgrent() */

/* Get first group with matching numerical group ID from file */
struct group *getgrgid(int gid)
struct group *getgrgid(gid_t gid)
{
setgrent();

Expand Down
76 changes: 75 additions & 1 deletion pwdgrp/test-grp.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,70 @@
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>

static int test_getgrnam_r(const char *name)
{
struct group groupbuf;
char **group1mem;
struct group *group;
char *buf;
long size;
gid_t gid;
char *end;

printf ("group %s:\n", name);
size = sysconf (_SC_GETGR_R_SIZE_MAX);
if (size == -1) {
fprintf (stderr, "error: could not get _SC_GETGR_R_SIZE_MAX\n");
return 0;
}

buf = malloc ((size_t) size);
if (buf == NULL) {
fprintf (stderr, "error: malloc() failed\n");
return 0;
}

gid = (gid_t)strtol(name, &end, 10);
if (*end == '\0')
{
if (getgrgid_r (gid, &groupbuf, buf, (size_t) size, &group) != 0) {
fprintf (stderr,
"error: getgrgid_r failed with errno=%d\n", errno);
free (buf);
return 0;
}
} else
{
if (getgrnam_r (name, &groupbuf, buf, (size_t) size, &group) != 0) {
fprintf (stderr,
"error: getgrnam_r failed with errno=%d\n", errno);
free (buf);
return 0;
}
}

if (group == NULL) {
fprintf (stderr, "error: group not found: %s\n", name);
free (buf);
return 0;
}

printf ("###\tgroup->gr_gid -> %d\n", group->gr_gid);
printf ("###\tgroup->gr_name -> %s\n", group->gr_name);
printf ("###\tgroup->gr_passwd -> %s\n", group->gr_passwd);
printf ("###\tgroup->gr_mem ->\n");

for(group1mem = group->gr_mem; *group1mem != NULL; group1mem++)
{
printf ("###\t\t -> %s\n", *group1mem);
}

free (buf);
return 1;
}


int
main (int argc, char *argv[])
Expand Down Expand Up @@ -37,5 +101,15 @@ main (int argc, char *argv[])
}
}

exit (my_passwd && my_group ? EXIT_SUCCESS : EXIT_FAILURE);
if (my_passwd == NULL || my_group == NULL)
return EXIT_FAILURE;

if (argc >= 2)
{
printf("\n");
if (!test_getgrnam_r(argv[1]))
return EXIT_FAILURE;
}

return EXIT_SUCCESS;
}

0 comments on commit b73c576

Please sign in to comment.