[PATCH 02/22] libcsupport: Implement getgroups()

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Nov 18 14:37:08 UTC 2014


---
 cpukit/libcsupport/src/getgroups.c        | 57 +++++++++++++++++++++++++++++--
 testsuites/libtests/pwdgrp01/init.c       | 41 ++++++++++++++++++++++
 testsuites/libtests/pwdgrp01/pwdgrp01.doc |  2 ++
 testsuites/psxtests/psxid01/init.c        | 53 +++++++++++++++++++++++++---
 testsuites/psxtests/psxid01/psxid01.scn   | 15 ++++++--
 5 files changed, 157 insertions(+), 11 deletions(-)

diff --git a/cpukit/libcsupport/src/getgroups.c b/cpukit/libcsupport/src/getgroups.c
index 6bf58a7..73a42ce 100644
--- a/cpukit/libcsupport/src/getgroups.c
+++ b/cpukit/libcsupport/src/getgroups.c
@@ -10,15 +10,66 @@
 #endif
 
 #include <sys/types.h>
+#include <grp.h>
+#include <pwd.h>
+#include <string.h>
 #include <unistd.h>
 
+#include <rtems/seterr.h>
+
 /**
  *  4.2.3 Get Supplementary IDs, P1003.1b-1993, p. 86
  */
 int getgroups(
-  int    gidsetsize __attribute__((unused)),
-  gid_t  grouplist[] __attribute__((unused))
+  int    gidsetsize,
+  gid_t  grouplist[]
 )
 {
-  return 0;  /* no supplemental group ids */
+  int rv;
+  struct passwd pwd;
+  struct passwd *pwd_res;
+  char buf[256];
+  gid_t gid;
+  const char *user;
+  struct group *grp;
+
+  rv = getpwuid_r(getuid(), &pwd, &buf[0], sizeof(buf), &pwd_res);
+  if (rv != 0) {
+    return rv;
+  }
+
+  gid = pwd.pw_gid;
+  user = pwd.pw_name;
+
+  setgrent();
+
+  while ((grp = getgrent()) != NULL) {
+    char **mem = &grp->gr_mem[0];
+
+    if (grp->gr_gid == gid) {
+      continue;
+    }
+
+    while (*mem != NULL) {
+      if (strcmp(*mem, user) == 0) {
+        if (rv < gidsetsize) {
+          grouplist[rv] = grp->gr_gid;
+        }
+
+        ++rv;
+
+        break;
+      }
+
+      ++mem;
+    }
+  }
+
+  endgrent();
+
+  if (gidsetsize == 0 || rv <= gidsetsize) {
+    return rv;
+  } else {
+    rtems_set_errno_and_return_minus_one(EINVAL);
+  }
 }
diff --git a/testsuites/libtests/pwdgrp01/init.c b/testsuites/libtests/pwdgrp01/init.c
index f1be7bb..86f8e90 100644
--- a/testsuites/libtests/pwdgrp01/init.c
+++ b/testsuites/libtests/pwdgrp01/init.c
@@ -17,9 +17,12 @@
 #endif
 
 #include <sys/stat.h>
+#include <sys/types.h>
+#include <errno.h>
 #include <grp.h>
 #include <pwd.h>
 #include <stdio.h>
+#include <unistd.h>
 
 #include "tmacros.h"
 
@@ -69,6 +72,7 @@ static void test(void)
   struct passwd *pwd_res;
   struct group *grp_res;
   char buf[256];
+  gid_t grps[5];
 
   rv = mkdir("/etc", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
   rtems_test_assert(rv == 0);
@@ -80,7 +84,14 @@ static void test(void)
 
   create_file(
     "/etc/group",
+    "A::1:moop,u,v,w\n"
+    "B::2:moop\n"
     "blub:bar:3:moop\n"
+    "C::4:l,m,n,moop\n"
+    "D::5:moop,moop\n"
+    "E::6:x\n"
+    "E::7:y,z\n"
+    "F::8:s,moop,t\n"
   );
 
   memset(&pwd, 0xff, sizeof(pwd));
@@ -106,6 +117,34 @@ static void test(void)
   rtems_test_assert(rv == 0);
   rtems_test_assert(&grp == grp_res);
   assert_grp(grp_res);
+
+  rv = setuid(0);
+  rtems_test_assert(rv == 0);
+
+  errno = 0;
+  rv = getgroups(0, NULL);
+  rtems_test_assert(rv == -1);
+  rtems_test_assert(errno == EINVAL);
+
+  rv = setuid(1);
+  rtems_test_assert(rv == 0);
+
+  rv = getgroups(0, NULL);
+  rtems_test_assert(rv == 5);
+
+  errno = 0;
+  rv = getgroups(1, &grps[0]);
+  rtems_test_assert(rv == -1);
+  rtems_test_assert(errno == EINVAL);
+
+  memset(&grps[0], 0xff, sizeof(grps));
+  rv = getgroups(5, &grps[0]);
+  rtems_test_assert(rv == 5);
+  rtems_test_assert(grps[0] == 1);
+  rtems_test_assert(grps[1] == 2);
+  rtems_test_assert(grps[2] == 4);
+  rtems_test_assert(grps[3] == 5);
+  rtems_test_assert(grps[4] == 8);
 }
 
 static void Init(rtems_task_argument arg)
@@ -126,6 +165,8 @@ static void Init(rtems_task_argument arg)
 #define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 4
 
 #define CONFIGURE_MAXIMUM_TASKS 1
+#define CONFIGURE_MAXIMUM_POSIX_KEYS 1
+#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1
 
 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
 
diff --git a/testsuites/libtests/pwdgrp01/pwdgrp01.doc b/testsuites/libtests/pwdgrp01/pwdgrp01.doc
index eaba717..36b81d1 100644
--- a/testsuites/libtests/pwdgrp01/pwdgrp01.doc
+++ b/testsuites/libtests/pwdgrp01/pwdgrp01.doc
@@ -9,6 +9,7 @@ directives:
   - getpwuid_r
   - getgrnam_r
   - getgrgid_r
+  - getgroups
 
 concepts:
 
@@ -17,3 +18,4 @@ concepts:
     custom /etc/passwd.
   - Ensure that getgrnam_r() and getgrgid_r() return the values specified by
     custom /etc/group.
+  - Ensure that getgroups() returns the values specified by custom /etc/group.
diff --git a/testsuites/psxtests/psxid01/init.c b/testsuites/psxtests/psxid01/init.c
index 4224840..5aa0399 100644
--- a/testsuites/psxtests/psxid01/init.c
+++ b/testsuites/psxtests/psxid01/init.c
@@ -34,9 +34,11 @@ void test_gid(void)
   int sc;
 
   gid = getegid();
+  rtems_test_assert( gid == 0 );
   printf( "getegid = %d\n", gid );
 
   gid = getgid();
+  rtems_test_assert( gid == 0 );
   printf( "getgid = %d\n", gid );
 
   puts( "setgid(5)" );
@@ -44,11 +46,34 @@ void test_gid(void)
   rtems_test_assert( sc == 0 );
 
   gid = getegid();
+  rtems_test_assert( gid == 0 );
   printf( "getegid = %d\n", gid );
 
   gid = getgid();
+  rtems_test_assert( gid == 5 );
   printf( "getgid = %d\n", gid );
 
+  puts( "setegid(5)" );
+  sc = setegid(5);
+  rtems_test_assert( sc == 0 );
+
+  gid = getegid();
+  rtems_test_assert( gid == 5 );
+  printf( "getegid = %d\n", gid );
+
+  gid = getgid();
+  rtems_test_assert( gid == 5 );
+  printf( "getgid = %d\n", gid );
+
+  puts( "setgid(0)" );
+  sc = setgid(0);
+  rtems_test_assert( sc == 0 );
+
+  puts( "setegid(0)" );
+  sc = setegid(0);
+  rtems_test_assert( sc == 0 );
+
+  errno = 0;
   puts( "setpgid(getpid(), 10) - ENOSYS" );
   sc = setpgid( getpid(), 10 );
   rtems_test_assert( sc == -1 );
@@ -61,9 +86,11 @@ void test_uid(void)
   int sc;
 
   uid = geteuid();
+  rtems_test_assert( uid == 0 );
   printf( "geteuid = %d\n", uid );
 
   uid = getuid();
+  rtems_test_assert( uid == 0 );
   printf( "getuid = %d\n", uid );
 
   puts( "setuid(5)" );
@@ -71,11 +98,32 @@ void test_uid(void)
   rtems_test_assert( sc == 0 );
 
   uid = geteuid();
+  rtems_test_assert( uid == 0 );
   printf( "geteuid = %d\n", uid );
 
   uid = getuid();
+  rtems_test_assert( uid == 5 );
   printf( "getuid = %d\n", uid );
 
+  puts( "seteuid(5)" );
+  sc = seteuid(5);
+  rtems_test_assert( sc == 0 );
+
+  uid = geteuid();
+  rtems_test_assert( uid == 5 );
+  printf( "geteuid = %d\n", uid );
+
+  uid = getuid();
+  rtems_test_assert( uid == 5 );
+  printf( "getuid = %d\n", uid );
+
+  puts( "seteuid(0)" );
+  sc = seteuid(0);
+  rtems_test_assert( sc == 0 );
+
+  puts( "setuid(0)" );
+  sc = setuid(0);
+  rtems_test_assert( sc == 0 );
 }
 
 pid_t __getpid(void);
@@ -106,11 +154,6 @@ void test_pid(void)
   puts( "getpgrp - return local node - OK" );
   pid = getpgrp();
   printf( "getpgrp returned %d\n", pid ); 
-
-  puts( "getgroups - return 0 - OK" );
-  sc = getgroups( 0, NULL );
-  rtems_test_assert( sc == 0 );
-  
 }
 
 void test_getlogin(void)
diff --git a/testsuites/psxtests/psxid01/psxid01.scn b/testsuites/psxtests/psxid01/psxid01.scn
index 8b9143d..e0ea2a0 100644
--- a/testsuites/psxtests/psxid01/psxid01.scn
+++ b/testsuites/psxtests/psxid01/psxid01.scn
@@ -1,9 +1,14 @@
-*** TEST ID 01 ***
+*** BEGIN OF TEST PSXID 1 ***
 getegid = 0
 getgid = 0
 setgid(5)
 getegid = 0
 getgid = 5
+setegid(5)
+getegid = 5
+getgid = 5
+setgid(0)
+setegid(0)
 setpgid(getpid(), 10) - ENOSYS
 
 geteuid = 0
@@ -11,6 +16,11 @@ getuid = 0
 setuid(5)
 geteuid = 0
 getuid = 5
+seteuid(5)
+geteuid = 5
+getuid = 5
+seteuid(0)
+setuid(0)
 
 getpid = 1
 __getpid = 1
@@ -18,7 +28,6 @@ getppid = 0
 setsid - EPERM
 getpgrp - return local node - OK
 getpgrp returned 1
-getgroups - return 0 - OK
 
 setuid(5)
 getlogin() -- ()
@@ -26,4 +35,4 @@ setuid(0)
 getlogin() -- (root)
 getlogin_r(NULL, LOGIN_NAME_MAX) -- EFAULT
 getlogin_r(buffer, 0) -- ERANGE
-*** END OF TEST ID 01 ***
+*** END OF TEST PSXID 1 ***
-- 
1.8.4.5



More information about the devel mailing list