1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 #include <errno.h>
  28 #include <stdio.h>
  29 #include <stdlib.h>
  30 #include <unistd.h>
  31 #include <fcntl.h>
  32 #include <sys/types.h>
  33 #include <sys/stat.h>
  34 
  35 #define NUMUSERS        11
  36 #define NOOK            1
  37 
  38 char    *testname;
  39 
  40 void usage(int);
  41 
  42 
  43 /*
  44  * Prints out the usage message and exits with the
  45  * passed in exit code "ec"
  46  */
  47 void
  48 usage(int ret)
  49 {
  50         fprintf(stderr, "usage: %s [-h] [-d <dbg>] [-n <nfiles>]\n", testname);
  51         fprintf(stderr, "\t -d <dbg>      Information level: 0 - none \n"
  52             "\t                                  1 - debug \n");
  53         fprintf(stderr, "\t -n <nfiles>    Number of files to create\n");
  54         fprintf(stderr, "\t -h help (this message\n");
  55 
  56         exit(ret);
  57 }
  58 
  59 /*
  60  * Main test loop.
  61  */
  62 int
  63 main(int  argc, char *argv[])
  64 {
  65         extern int  optind;
  66         extern char *optarg;
  67 
  68         char  filename[256];
  69         int   file_flags = (O_CREAT|O_TRUNC|O_RDWR);
  70         int   fd = -1;
  71         int   i = 0;
  72         int   c;
  73         gid_t glist[NUMUSERS] = {0, 1, 2, 3, 4, 5, 8, 9,
  74                                 23456787, 23456788, 23456789};
  75         uid_t ulist[NUMUSERS] = {0, 1, 2, 3, 4, 5, 8, 9,
  76                                 10, 10, 1};
  77         gid_t gid = (gid_t)-1;
  78         uid_t uid = (uid_t)-1;
  79 
  80         /* default values */
  81         int   debug = 0;        /* silent execution, no error messages */
  82         int   NumFiles = 1000;  /* 1K files */
  83 
  84         if (getuid() != 0 && geteuid() != 0) {
  85                 fprintf(stderr, "ERROR: This program must be run as root.\n");
  86                 exit(NOOK);
  87         }
  88 
  89         testname = argv[0];
  90 
  91         while ((c = getopt(argc, argv, "hd:n:")) != -1) {
  92                 switch (c) {
  93 
  94                 /* number of testcase runs to perform */
  95                 case 'n':
  96                         NumFiles = atoi(optarg);
  97                         break;
  98 
  99                 case 'd':
 100                         switch (atoi(optarg)) {
 101                         case 0:
 102                                 debug = 0;
 103                                 break;
 104                         case 1:
 105                                 debug = 1;
 106                                 break;
 107                         default:
 108                                 usage(-1);
 109                         }
 110                         break;
 111 
 112                 case 'h':
 113                         usage(0);
 114                         break;
 115                 default:
 116                         usage(-1);
 117                 }
 118         }
 119 
 120         if (debug)
 121                 printf("DEBUG: NumFiles=%d\n", NumFiles);
 122 
 123         /* verify limits */
 124         if (NumFiles < 0) {
 125                 fprintf(stderr,
 126                     "%s ERROR: number of files must be positive.\n", testname);
 127                 exit(NOOK);
 128         }
 129 
 130         if (NumFiles >= 1000000) {
 131                 fprintf(stderr,
 132                     "%s ERROR: number of files must be < 1000000.\n", testname);
 133                 exit(NOOK);
 134         }
 135 
 136         if (debug)
 137                 printf("DEBUG: NUMUSERS=%d\n", NUMUSERS);
 138 
 139         /*      Start creating tests */
 140         for (i = 0; i < NumFiles; i++) {
 141                 /* create and open a file */
 142                 sprintf(filename, "fil%06d", i);
 143 
 144                 /* select and choose ids */
 145                 gid = glist[i % NUMUSERS];
 146                 if (setegid(gid) < 0) {
 147                         fprintf(stderr, "ERROR: failed to setegid(%d)\n", gid);
 148                         perror(" ");
 149                         exit(NOOK);
 150                 }
 151 
 152                 uid = ulist[i % NUMUSERS];
 153                 if (seteuid(uid) < 0) {
 154                         fprintf(stderr, "ERROR: failed to seteuid(%d)\n", uid);
 155                         perror(" ");
 156                         exit(NOOK);
 157                 }
 158 
 159                 if (debug) {
 160                         printf("DEBUG: in loop <i=%d> ...\n", i);
 161                         printf("DEBUG:   euid=%d, egid=%d\n", uid, gid);
 162                         printf("DEBUG:   open(%s, 0%o).\n", filename, 777);
 163                 }
 164                 /* create a file */
 165                 if ((fd = open(filename, file_flags, 0777)) < 0) {
 166                         fprintf(stderr,
 167                             "ERROR: failed to open(%s)\n", filename);
 168                         perror(" ");
 169                         exit(NOOK);
 170                 }
 171 
 172                 if (debug)
 173                         printf("DEBUG:   reset euid=0, egid=0\n");
 174                 /* return id to root */
 175                 if (setegid(0) < 0) {
 176                         fprintf(stderr, "ERROR: failed to re-setegid(0)\n");
 177                         perror(" ");
 178                         exit(NOOK);
 179                 }
 180 
 181                 if (seteuid(0) < 0) {
 182                         fprintf(stderr, "ERROR: failed to re-seteuid(0)\n");
 183                         perror(" ");
 184                         exit(NOOK);
 185                 }
 186 
 187                 if (debug)
 188                         printf("DEBUG:   closing <%s>\n", filename);
 189                 /* close the file */
 190                 if (close(fd) < 0) {
 191                         fprintf(stderr,
 192                             "ERROR: failed to close(%s)\n", filename);
 193                         perror(" ");
 194                         exit(NOOK);
 195                 }
 196         }
 197 
 198         printf("%s %d files were created successfully\n\n", testname, NumFiles);
 199 
 200         return (0);
 201 }