Whamcloud - gitweb
land b_smallfix 20040407_1414:
[fs/lustre-release.git] / lustre / tests / runas.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  */
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <unistd.h>
7 #include <string.h>
8 #include <errno.h>
9 #include <sys/types.h>
10 #include <grp.h>
11 #include <sys/wait.h>
12
13 #define DEBUG 0
14
15 static const char usage[] =
16 "Usage: %s -u user_id [-g grp_id ] [ -G ] command\n"
17 "  -u user_id      switch to UID user_id\n"
18 "  -g grp_id       switch to GID grp_id\n"
19 "  -G              clear supplementary groups\n";
20
21 void Usage_and_abort(const char *name)
22 {
23         fprintf(stderr, usage, name);
24         exit(-1);
25 }
26
27 int main(int argc, char **argv)
28 {
29         char **my_argv, *name = argv[0];
30         int status;
31         int c,i;
32         int gid_is_set = 0;
33         int uid_is_set = 0;
34         int clear_supp_groups = 0;
35         uid_t user_id = 0;
36         gid_t grp_id = 0;
37
38         if (argc == 1)
39                 Usage_and_abort(name);
40
41         // get UID and GID
42         while ((c = getopt (argc, argv, "+u:g:hG")) != -1) {
43                 switch (c) {
44                 case 'u':
45                         user_id = (uid_t)atoi(optarg);
46                         uid_is_set = 1;
47                         if (!gid_is_set)
48                                 grp_id = user_id;
49                         break;
50
51                 case 'g':
52                         grp_id = (gid_t)atoi(optarg);
53                         gid_is_set = 1;
54                         break;
55
56                 case 'G':
57                         clear_supp_groups = 1;
58                         break;
59
60                 default:
61                 case 'h':
62                         Usage_and_abort(name);
63                         break;
64                 }
65         }
66
67         if (!uid_is_set)
68                 Usage_and_abort(name);
69
70         if (optind == argc) {
71                 fputs("Must specify command to run.\n", stderr);
72                 Usage_and_abort(name);
73         }
74
75         // assemble the command
76         my_argv = (char**)malloc(sizeof(char*)*(argc+1-optind));
77         if (my_argv == NULL) {
78                 fprintf(stderr, "Error in allocating memory. (%s)\n",
79                         strerror(errno));
80                 exit(-1);
81         }
82
83         for (i = optind; i < argc; i++) {
84                 my_argv[i-optind] = argv[i];
85                 //printf("%s\n",my_argv[i-optind]);
86         }
87         my_argv[i-optind] = NULL;
88
89 #if DEBUG
90         system("whoami");
91 #endif
92
93         // set GID
94         status = setregid(grp_id, grp_id);
95         if (status == -1) {
96                  fprintf(stderr, "Cannot change grp_ID to %d, errno=%d (%s)\n",
97                          grp_id, errno, strerror(errno) );
98                  exit(-1);
99         }
100
101         if (clear_supp_groups) {
102                 status = setgroups(0, NULL);
103                 if (status == -1) {
104                         perror("clearing supplementary groups");
105                         exit(-1);
106                 }
107         }
108         
109         // set UID
110         status = setreuid(user_id, user_id );
111         if(status == -1) {
112                   fprintf(stderr,"Cannot change user_ID to %d, errno=%d (%s)\n",
113                            user_id, errno, strerror(errno) );
114                   exit(-1);
115         }
116
117         fprintf(stderr, "running as UID %d, GID %d%s:", user_id, grp_id,
118                 clear_supp_groups ? ", cleared groups" : "");
119
120         for (i = 0; i < argc - optind; i++)
121                  fprintf(stderr, " [%s]", my_argv[i]);
122
123         fprintf(stderr, "\n");
124         fflush(stderr);
125
126         // The command to be run
127         execvp(my_argv[0], my_argv);
128         fprintf(stderr, "execvp fails running %s\n", my_argv[0]);
129         exit(-1);
130 }
131