Whamcloud - gitweb
- added test_3b which emulates recursive mount. Does not pass yet.
[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 <ctype.h>
10 #include <sys/types.h>
11 #include <grp.h>
12 #include <sys/wait.h>
13
14 #define DEBUG 0
15
16 #ifndef NGROUPS_MAX
17 #define NGROUPS_MAX 32
18 #endif
19
20 static const char usage[] =
21 "Usage: %s -u user_id [-g grp_id] [-G[gid0,gid1,...]] command\n"
22 "  -u user_id           switch to UID user_id\n"
23 "  -g grp_id            switch to GID grp_id\n"
24 "  -G[gid0,gid1,...]    set supplementary groups\n";
25
26 void Usage_and_abort(const char *name)
27 {
28         fprintf(stderr, usage, name);
29         exit(-1);
30 }
31
32 int main(int argc, char **argv)
33 {
34         char **my_argv, *name = argv[0], *grp;
35         int status, c, i;
36         int gid_is_set = 0, uid_is_set = 0, num_supp = -1;
37         uid_t user_id = 0;
38         gid_t grp_id = 0, supp_groups[NGROUPS_MAX] = { 0 };
39
40         if (argc == 1)
41                 Usage_and_abort(name);
42
43         // get UID and GID
44         while ((c = getopt(argc, argv, "+u:g:hG::")) != -1) {
45                 switch (c) {
46                 case 'u':
47                         user_id = (uid_t)atoi(optarg);
48                         uid_is_set = 1;
49                         if (!gid_is_set)
50                                 grp_id = user_id;
51                         break;
52
53                 case 'g':
54                         grp_id = (gid_t)atoi(optarg);
55                         gid_is_set = 1;
56                         break;
57
58                 case 'G':
59                         num_supp = 0;
60                         if (optarg == NULL || !isdigit(optarg[0]))
61                                 break;
62                         while ((grp = strsep(&optarg, ",")) != NULL) {
63                                 printf("adding supp group %d\n", atoi(grp));
64                                 supp_groups[num_supp++] = atoi(grp);
65                                 if (num_supp >= NGROUPS_MAX)
66                                         break;
67                         }
68                         break;
69
70                 default:
71                 case 'h':
72                         Usage_and_abort(name);
73                         break;
74                 }
75         }
76
77         if (!uid_is_set)
78                 Usage_and_abort(name);
79
80         if (optind == argc) {
81                 fputs("Must specify command to run.\n", stderr);
82                 Usage_and_abort(name);
83         }
84
85         // assemble the command
86         my_argv = (char**)malloc(sizeof(char*)*(argc+1-optind));
87         if (my_argv == NULL) {
88                 fprintf(stderr, "Error in allocating memory. (%s)\n",
89                         strerror(errno));
90                 exit(-1);
91         }
92
93         for (i = optind; i < argc; i++) {
94                 my_argv[i-optind] = argv[i];
95                 //printf("%s\n",my_argv[i-optind]);
96         }
97         my_argv[i-optind] = NULL;
98
99 #if DEBUG
100         system("whoami");
101 #endif
102
103         // set GID
104         status = setregid(grp_id, grp_id);
105         if (status == -1) {
106                  fprintf(stderr, "Cannot change grp_ID to %d, errno=%d (%s)\n",
107                          grp_id, errno, strerror(errno) );
108                  exit(-1);
109         }
110
111         if (num_supp >= 0) {
112                 status = setgroups(num_supp, supp_groups);
113                 if (status == -1) {
114                         perror("setting supplementary groups");
115                         exit(-1);
116                 }
117         }
118
119         // set UID
120         status = setreuid(user_id, user_id );
121         if(status == -1) {
122                   fprintf(stderr,"Cannot change user_ID to %d, errno=%d (%s)\n",
123                            user_id, errno, strerror(errno) );
124                   exit(-1);
125         }
126
127         fprintf(stderr, "running as UID %d, GID %d", user_id, grp_id);
128         for (i = 0; i < num_supp; i++)
129                 fprintf(stderr, ":%d", supp_groups[i]);
130         fprintf(stderr, "\n");
131
132         for (i = 0; i < argc - optind; i++)
133                  fprintf(stderr, " [%s]", my_argv[i]);
134
135         fprintf(stderr, "\n");
136         fflush(stderr);
137
138         // The command to be run
139         execvp(my_argv[0], my_argv);
140         fprintf(stderr, "execvp fails running %s\n", my_argv[0]);
141         exit(-1);
142 }
143