src/idmapped-mounts: use renameat instead of renameat2
[xfstests-dev.git] / src / runas.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) 2000-2001 Silicon Graphics, Inc.
4  * All Rights Reserved.
5  */
6
7 /*
8  * Run a command with a particular 
9  *    - effective user id
10  *    - effective group id
11  *    - supplementary group list
12  */
13  
14 #include "global.h"
15 #include <grp.h>
16
17
18
19 char *prog;
20
21 void usage(void)
22 {
23     fprintf(stderr, "usage: %s [-u uid] [-g gid] [-s gid] cmd\n"
24            "flags:\n"
25            "    -u - effective user-id\n"
26            "    -g - effective group-id\n"
27            "    -s - supplementary group-id\n", prog);
28            
29 }
30
31 #define SUP_MAX 20
32
33 int
34 main(int argc, char **argv)
35 {
36         int c;
37         uid_t uid = -1;
38         gid_t gid = -1;
39         char **cmd;
40         gid_t sgids[SUP_MAX];
41         int sup_cnt = 0;
42         char *p;
43
44         prog = basename(argv[0]);
45         for (p = prog; *p; p++) {
46                 if (*p == '/') {
47                         prog = p + 1;
48                 }
49         }
50
51
52         while ((c = getopt(argc, argv, "u:g:s:")) != -1) {
53                 switch (c) {
54                 case 'u':
55                         uid = atoi(optarg);
56                         break;
57                 case 'g':
58                         gid = atoi(optarg);
59                         break;
60                 case 's':
61                         if (sup_cnt+1 > SUP_MAX) {
62                             fprintf(stderr, "%s: too many sup groups\n", prog);
63                             exit(1);
64                         }
65                         sgids[sup_cnt++] = atoi(optarg);
66                         break;
67                 case '?':
68                         usage();
69                         exit(1);
70                 }
71         }
72
73         /* build up the cmd */
74         if (optind == argc) {
75             usage();
76             exit(1);
77         }
78         else {
79             char **p;
80             p = cmd = (char **)malloc(sizeof(char *) * (argc - optind + 1));
81             for ( ; optind < argc; optind++, p++) {
82                 *p = strdup(argv[optind]);
83             }
84             *p = NULL;
85         } 
86
87         if (gid != -1) {
88             if (setgid(gid) == -1) {
89                 fprintf(stderr, "%s: setgid(%d) failed: %s\n",
90                         prog, (int)gid, strerror(errno));
91                 exit(1);
92             }
93         }
94
95         if (gid != -1 || sup_cnt != 0) {
96             if (setgroups(sup_cnt, sgids) == -1) {
97                 fprintf(stderr, "%s: setgroups() failed: %s\n",
98                         prog, strerror(errno));
99                 exit(1);
100             }
101         }
102
103         if (uid != -1) {
104             if (setuid(uid) == -1) {
105                 fprintf(stderr, "%s: setuid(%d) failed: %s\n",
106                         prog, (int)uid, strerror(errno));
107                 exit(1);
108             }
109         }
110
111         execvp(cmd[0], cmd);
112         fprintf(stderr, "%s: %s\n", cmd[0], strerror(errno));
113         exit(1);
114 }