1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 only,
10 * as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License version 2 for more details (a copy is included
16 * in the LICENSE file that accompanied this code).
18 * You should have received a copy of the GNU General Public License
19 * version 2 along with this program; If not, see
20 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23 * CA 95054 USA or visit www.sun.com if you need additional information or
29 * Copyright 2008 Sun Microsystems, Inc. All rights reserved
30 * Use is subject to license terms.
33 * This file is part of Lustre, http://www.lustre.org/
34 * Lustre is a trademark of Sun Microsystems, Inc.
43 #include <sys/types.h>
51 #define NGROUPS_MAX 32
54 static const char usage[] =
55 "Usage: %s -u user_id [-g grp_id] [-G[gid0,gid1,...]] command\n"
56 " -u user_id switch to UID user_id\n"
57 " -g grp_id switch to GID grp_id\n"
58 " -G[gid0,gid1,...] set supplementary groups\n";
60 void Usage_and_abort(const char *name)
62 fprintf(stderr, usage, name);
66 int main(int argc, char **argv)
68 char **my_argv, *name = argv[0], *grp;
70 int gid_is_set = 0, uid_is_set = 0, num_supp = -1;
72 gid_t grp_id = 0, supp_groups[NGROUPS_MAX] = { 0 };
75 fprintf(stderr, "No parameter count\n");
76 Usage_and_abort(name);
80 while ((c = getopt(argc, argv, "+u:g:hG::")) != -1) {
83 if (!isdigit(optarg[0])) {
84 struct passwd *pw = getpwnam(optarg);
86 fprintf(stderr, "parameter '%s' bad\n",
88 Usage_and_abort(name);
92 user_id = (uid_t)atoi(optarg);
100 if (!isdigit(optarg[0])) {
101 struct group *gr = getgrnam(optarg);
103 fprintf(stderr, "getgrname %s failed\n",
105 Usage_and_abort(name);
109 grp_id = (gid_t)atoi(optarg);
116 if (optarg == NULL || !isdigit(optarg[0]))
118 while ((grp = strsep(&optarg, ",")) != NULL) {
119 printf("adding supp group %d\n", atoi(grp));
120 supp_groups[num_supp++] = atoi(grp);
121 if (num_supp >= NGROUPS_MAX)
128 Usage_and_abort(name);
134 fprintf(stderr, "Must specify uid to run.\n");
135 Usage_and_abort(name);
138 if (optind == argc) {
139 fprintf(stderr, "Must specify command to run.\n");
140 Usage_and_abort(name);
143 // assemble the command
144 my_argv = (char**)malloc(sizeof(char*)*(argc+1-optind));
145 if (my_argv == NULL) {
146 fprintf(stderr, "Error in allocating memory. (%s)\n",
151 for (i = optind; i < argc; i++) {
152 my_argv[i-optind] = argv[i];
153 //printf("%s\n",my_argv[i-optind]);
155 my_argv[i-optind] = NULL;
162 status = setregid(grp_id, grp_id);
164 fprintf(stderr, "Cannot change grp_ID to %d, errno=%d (%s)\n",
165 grp_id, errno, strerror(errno) );
170 status = setgroups(num_supp, supp_groups);
172 perror("setting supplementary groups");
178 status = setreuid(user_id, user_id );
180 fprintf(stderr,"Cannot change user_ID to %d, errno=%d (%s)\n",
181 user_id, errno, strerror(errno) );
185 fprintf(stderr, "running as UID %d, GID %d", user_id, grp_id);
186 for (i = 0; i < num_supp; i++)
187 fprintf(stderr, ":%d", supp_groups[i]);
188 fprintf(stderr, "\n");
190 for (i = 0; i < argc - optind; i++)
191 fprintf(stderr, " [%s]", my_argv[i]);
193 fprintf(stderr, "\n");
196 // The command to be run
197 execvp(my_argv[0], my_argv);
198 fprintf(stderr, "execvp fails running %s (%d): %s\n", my_argv[0],
199 errno, strerror(errno));