diff --git a/include/grp.h b/include/grp.h index 5fd152c..463ad95 100644 --- a/include/grp.h +++ b/include/grp.h @@ -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)); diff --git a/pwdgrp/SRCFILES b/pwdgrp/SRCFILES index a1e10fe..ef01a1a 100644 --- a/pwdgrp/SRCFILES +++ b/pwdgrp/SRCFILES @@ -15,5 +15,7 @@ SRCFILES = \ getpwuid.c \ getpwuid_r.c \ grp.c \ + getgrgid_r.c \ + getgrnam_r.c \ initgroups.c \ putpwent.c diff --git a/pwdgrp/getgrgid_r.c b/pwdgrp/getgrgid_r.c new file mode 100644 index 0000000..e48e1ba --- /dev/null +++ b/pwdgrp/getgrgid_r.c @@ -0,0 +1,84 @@ +/* + * + * MMedour - 2024/06/24 - getgrgid_r & getgrnam_r draft c implementation and validation + * + */ + +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/pwdgrp/getgrnam_r.c b/pwdgrp/getgrnam_r.c new file mode 100644 index 0000000..c923d71 --- /dev/null +++ b/pwdgrp/getgrnam_r.c @@ -0,0 +1,84 @@ +/* + * + * MMedour - 2024/06/24 - getgrgid_r & getgrnam_r draft c implementation and validation + * + */ + +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/pwdgrp/grp.c b/pwdgrp/grp.c index 4dcf3a0..7401161 100644 --- a/pwdgrp/grp.c +++ b/pwdgrp/grp.c @@ -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(); diff --git a/pwdgrp/test-grp.c b/pwdgrp/test-grp.c index 62ba4e4..c293325 100644 --- a/pwdgrp/test-grp.c +++ b/pwdgrp/test-grp.c @@ -4,6 +4,70 @@ #include #include #include +#include + +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[]) @@ -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; }