Home | History | Annotate | Download | only in getgroups
      1 /*
      2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
      3  *
      4  * This program is free software; you can redistribute it and/or modify it
      5  * under the terms of version 2 of the GNU General Public License as
      6  * published by the Free Software Foundation.
      7  *
      8  * This program is distributed in the hope that it would be useful, but
      9  * WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
     11  *
     12  * Further, this software is distributed without any warranty that it is
     13  * free of the rightful claim of any third person regarding infringement
     14  * or the like.  Any license provided herein, whether implied or
     15  * otherwise, applies only to this software file.  Patent licenses, if
     16  * any, provided herein do not apply to combinations of this program with
     17  * other software, or any other product whatsoever.
     18  *
     19  * You should have received a copy of the GNU General Public License along
     20  * with this program; if not, write the Free Software Foundation, Inc.,
     21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
     22  *
     23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
     24  * Mountain View, CA  94043, or:
     25  *
     26  * http://www.sgi.com
     27  *
     28  * For further information regarding this notice, see:
     29  *
     30  * http://oss.sgi.com/projects/GenInfo/NoticeExplan/
     31  */
     32 
     33 /*
     34   AUTHOR: Barrie Kletscher
     35   Rewrote :  11-92 by Richard Logan
     36   CO-PILOT: Dave Baumgartner
     37 
     38   TEST ITEMS:
     39    1. Check to see if getgroups(-1, gidset) fails and sets errno to EINVAL
     40    2. Check to see if getgroups(0, gidset) does not return -1 and gidset is
     41       not modified.
     42    3. Check to see if getgroups(x, gigset) fails and sets errno to EINVAL,
     43       where x is one less then what is returned by getgroups(0, gidset).
     44    4. Check to see if getgroups() succeeds and gidset contains
     45       group id returned from getgid().
     46 */
     47 
     48 #include <unistd.h>
     49 #include <signal.h>
     50 #include <string.h>
     51 #include <errno.h>
     52 #include <grp.h>
     53 #include <sys/param.h>
     54 #include <sys/types.h>
     55 
     56 #include "test.h"
     57 #include "compat_16.h"
     58 
     59 static void setup(void);
     60 static void cleanup(void);
     61 
     62 TCID_DEFINE(getgroups01);
     63 int TST_TOTAL = 4;
     64 
     65 static GID_T gidset[NGROUPS];
     66 static GID_T cmpset[NGROUPS];
     67 
     68 int main(int ac, char **av)
     69 {
     70 	int lc;
     71 	GID_T group;
     72 	int i;
     73 	int entries;
     74 
     75 	tst_parse_opts(ac, av, NULL, NULL);
     76 
     77 	setup();
     78 
     79 	for (lc = 0; TEST_LOOPING(lc); lc++) {
     80 
     81 		tst_count = 0;
     82 
     83 		TEST(GETGROUPS(cleanup, -1, gidset));
     84 
     85 		if (TEST_RETURN == 0) {
     86 			tst_resm(TFAIL, "getgroups succeeded unexpectedly");
     87 		} else {
     88 			if (errno == EINVAL)
     89 				tst_resm(TPASS,
     90 					 "getgroups failed as expected with EINVAL");
     91 			else
     92 				tst_resm(TFAIL | TTERRNO,
     93 					 "getgroups didn't fail as expected with EINVAL");
     94 		}
     95 
     96 		/*
     97 		 * Check that if ngrps is zero that the number of groups is
     98 		 * return and the the gidset array is not modified.
     99 		 * This is a POSIX special case.
    100 		 */
    101 		memset(gidset, 052, NGROUPS * sizeof(GID_T));
    102 		memset(cmpset, 052, NGROUPS * sizeof(GID_T));
    103 
    104 		TEST(GETGROUPS(cleanup, 0, gidset));
    105 		if (TEST_RETURN == -1) {
    106 			tst_resm(TFAIL | TTERRNO, "getgroups failed unexpectedly");
    107 		} else {
    108 			if (memcmp(cmpset, gidset, NGROUPS * sizeof(GID_T)) != 0)
    109 				tst_resm(TFAIL,
    110 					 "getgroups modified the gidset array");
    111 			else
    112 				tst_resm(TPASS,
    113 					 "getgroups did not modify the gidset "
    114 					 "array");
    115 		}
    116 
    117 		/*
    118 		 * Check to see that is -1 is returned and errno is set to
    119 		 * EINVAL when ngroups is not big enough to hold all groups.
    120 		 */
    121 		if (TEST_RETURN <= 1) {
    122 			tst_resm(TCONF,
    123 				 "getgroups returned %ld; unable to test that using ngrps >=1 but less than number of grps",
    124 				 TEST_RETURN);
    125 		} else {
    126 			TEST(GETGROUPS(cleanup, TEST_RETURN - 1, gidset));
    127 			if (TEST_RETURN == -1) {
    128 				if (errno == EINVAL)
    129 					tst_resm(TPASS,
    130 						 "getgroups failed as "
    131 						 "expected with EINVAL");
    132 				else
    133 					tst_resm(TFAIL | TERRNO,
    134 						 "getgroups didn't fail "
    135 						 "with EINVAL");
    136 			} else {
    137 				tst_resm(TFAIL,
    138 					 "getgroups succeeded unexpectedly with %ld",
    139 					 TEST_RETURN);
    140 			}
    141 		}
    142 
    143 		TEST(GETGROUPS(cleanup, NGROUPS, gidset));
    144 		if ((entries = TEST_RETURN) == -1) {
    145 			tst_resm(TFAIL | TTERRNO,
    146 				 "getgroups failed unexpectedly");
    147 		} else {
    148 
    149 			group = getgid();
    150 
    151 			for (i = 0; i < entries; i++) {
    152 				if (gidset[i] == group) {
    153 					tst_resm(TPASS,
    154 						 "getgroups(NGROUPS,gidset) "
    155 						 "returned %d contains gid %d "
    156 						 "(from getgid)",
    157 						 entries, group);
    158 					break;
    159 				}
    160 			}
    161 
    162 			if (i == entries) {
    163 				tst_resm(TFAIL,
    164 					 "getgroups(NGROUPS,gidset) ret %d, does "
    165 					 "not contain gid %d (from getgid)",
    166 					 entries, group);
    167 			}
    168 		}
    169 
    170 	}
    171 
    172 	cleanup();
    173 	tst_exit();
    174 }
    175 
    176 static void setup(void)
    177 {
    178 	tst_sig(FORK, DEF_HANDLER, cleanup);
    179 
    180 	TEST_PAUSE;
    181 
    182 	gid_t init_gidset[3] = {0, 1, 2};
    183 	setgroups(3, init_gidset);
    184 }
    185 
    186 static void cleanup(void)
    187 {
    188 }
    189