X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Ftests%2Frunas.c;h=ff799eb0c42527b71688a4252213f39e0698fbdb;hp=3d29f1baabed528436763d7c807a66e4b830d772;hb=61138e82b52b19ab2a73398c2a238410ed559198;hpb=a4346f1ee87f221d8541ad31b2efb3bba41a4df4 diff --git a/lustre/tests/runas.c b/lustre/tests/runas.c index 3d29f1b..ff799eb 100644 --- a/lustre/tests/runas.c +++ b/lustre/tests/runas.c @@ -1,133 +1,237 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: +/* + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; If not, see + * http://www.gnu.org/licenses/gpl-2.0.html + * + * GPL HEADER END */ +/* + * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. + * Use is subject to license terms. + */ +/* + * This file is part of Lustre, http://www.lustre.org/ + */ + #include #include #include #include #include +#include #include +#include +#include #include #define DEBUG 0 -void -Usage_and_abort() -{ - fprintf(stderr, "Usage: runas -u user_id [ -g grp_id ]" \ - " command_to_be_run \n"); - exit(-1); -} - -// Usage: runas -u user_id [ -g grp_id ] "command_to_be_run" -// return: the return value of "command_to_be_run" -// NOTE: returning -1 might be the return code of this program itself or -// the "command_to_be_run" +#ifndef NGROUPS_MAX +#define NGROUPS_MAX 32 +#endif -// ROOT runs "runas" for free -// Other users run "runas" requires chmod 6755 "command_to_be_run" +static const char usage[] = +"Usage: %s -u user_id [-g grp_id] [-v euid] [-j egid] [-G[gid0,gid1,...]] command\n" +" -u user_id switch to UID user_id\n" +" -g grp_id switch to GID grp_id\n" +" -v euid switch euid to UID\n" +" -j egid switch egid to GID\n" +" -G[gid0,gid1,...] set supplementary groups\n"; -int -main(int argc, char**argv) +void Usage_and_abort(const char *name) { - char command[1024]; - char *cmd_ptr; - int status; - int c,i; - int gid_is_set = 0; - int uid_is_set = 0; - uid_t user_id; - gid_t grp_id; - - if(argc == 1) { - Usage_and_abort(); - } - - // get UID and GID - while ((c = getopt (argc, argv, "u:g:h")) != -1) { - switch (c) { - case 'u': - user_id = (uid_t)atoi(optarg); - uid_is_set = 1; - if(!gid_is_set) { - grp_id = user_id; - } - break; - - case 'g': - grp_id = (gid_t)atoi(optarg); - gid_is_set = 1; - break; - - case 'h': - Usage_and_abort (); - break; - - default: - // fprintf(stderr, "Bad parameters.\n"); - // Usage_and_abort (); - } - } - - if (!uid_is_set){ - Usage_and_abort (); - } - - - if(optind == argc) { - fprintf(stderr, "Bad parameters.\n"); - Usage_and_abort(); - } - - - // assemble the command - cmd_ptr = command ; - for (i = optind; i < argc; i++) - cmd_ptr += sprintf(cmd_ptr, "%s ", argv[i]); - - -#if DEBUG - system("whoami"); -#endif + fprintf(stderr, usage, name); + exit(-1); +} - // set GID - status = setregid(grp_id, grp_id ); - if( status == -1) { - fprintf(stderr, "Cannot change grp_ID to %d, errno=%d (%s)\n", - grp_id, errno, strerror(errno) ); - exit(-1); - } - - // set UID - status = setreuid(user_id, user_id ); - if(status == -1) { - fprintf(stderr,"Cannot change user_ID to %d, errno=%d (%s)\n", - user_id, errno, strerror(errno) ); - exit(-1); - } +int main(int argc, char **argv) +{ + char **my_argv, *name = argv[0], *grp; + int status, c, i; + int gid_is_set = 0, uid_is_set = 0, num_supp = -1; + uid_t user_id = 0; + gid_t grp_id = 0, supp_groups[NGROUPS_MAX] = { 0 }; + int euid_is_set = 0, egid_is_set = 0; + uid_t euid = 0; + gid_t egid = 0; + + if (argc == 1) { + fprintf(stderr, "No parameter count\n"); + Usage_and_abort(name); + } + + /* get UID and GID */ + while ((c = getopt(argc, argv, "+u:g:v:j:hG::")) != -1) { + switch (c) { + case 'u': + if (!isdigit(optarg[0])) { + struct passwd *pw = getpwnam(optarg); + + if (!pw) { + fprintf(stderr, "parameter '%s' bad\n", + optarg); + Usage_and_abort(name); + } + user_id = pw->pw_uid; + } else { + user_id = (uid_t)atoi(optarg); + } + uid_is_set = 1; + if (!gid_is_set) + grp_id = user_id; + break; + + case 'g': + if (!isdigit(optarg[0])) { + struct group *gr = getgrnam(optarg); + + if (!gr) { + fprintf(stderr, "getgrname %s failed\n", + optarg); + Usage_and_abort(name); + } + grp_id = gr->gr_gid; + } else { + grp_id = (gid_t)atoi(optarg); + } + gid_is_set = 1; + break; + + case 'v': + if (!isdigit(optarg[0])) { + struct passwd *pw = getpwnam(optarg); + + if (!pw) { + fprintf(stderr, "parameter '%s' bad\n", + optarg); + Usage_and_abort(name); + } + euid = pw->pw_uid; + } else { + euid = (uid_t)atoi(optarg); + } + euid_is_set = 1; + break; + + case 'j': + if (!isdigit(optarg[0])) { + struct group *gr = getgrnam(optarg); + + if (!gr) { + fprintf(stderr, "getgrname %s failed\n", + optarg); + Usage_and_abort(name); + } + egid = gr->gr_gid; + } else { + egid = (gid_t)atoi(optarg); + } + egid_is_set = 1; + break; + + case 'G': + num_supp = 0; + if (!optarg || !isdigit(optarg[0])) + break; + while ((grp = strsep(&optarg, ",")) != NULL) { + printf("adding supp group %d\n", atoi(grp)); + supp_groups[num_supp++] = atoi(grp); + if (num_supp >= NGROUPS_MAX) + break; + } + break; + + default: + case 'h': + Usage_and_abort(name); + break; + } + } + + if (!uid_is_set) { + fprintf(stderr, "Must specify uid to run.\n"); + Usage_and_abort(name); + } + + if (optind == argc) { + fprintf(stderr, "Must specify command to run.\n"); + Usage_and_abort(name); + } + + /* assemble the command */ + my_argv = (char **)malloc(sizeof(char *) * (argc + 1 - optind)); + if (!my_argv) { + fprintf(stderr, "Error in allocating memory. (%s)\n", + strerror(errno)); + exit(-1); + } + + for (i = optind; i < argc; i++) + my_argv[i - optind] = argv[i]; + + my_argv[i - optind] = NULL; #if DEBUG - system("whoami"); + system("whoami"); #endif - fprintf(stdout, "running as USER(%d), Grp (%d): \"%s\" \n", - user_id, grp_id, command ); - - // run the command - status = system(command); - - // pass the return code of command_to_be_run out of this wrapper - if (status == -1) { - fprintf(stderr, "%s: system() command failed to run\n", - argv[0]); - } - else{ - status = WEXITSTATUS(status); - fprintf(stderr, "[%s #%d] \"%s\" returns %d (%s).\n", argv[0], - user_id, argv[optind], status, strerror(status)); - - } - - return(status); + /* set GID */ + if (!egid_is_set) + egid = grp_id; + status = setregid(grp_id, egid); + if (status == -1) { + fprintf(stderr, "Cannot change gid to %d/%d, errno=%d (%s)\n", + grp_id, egid, errno, strerror(errno)); + exit(-1); + } + + if (num_supp >= 0) { + status = setgroups(num_supp, supp_groups); + if (status == -1) { + perror("setting supplementary groups"); + exit(-1); + } + } + + /* set UID */ + if (!euid_is_set) + euid = user_id; + status = setreuid(user_id, euid); + if (status == -1) { + fprintf(stderr, "Cannot change uid to %d/%d, errno=%d (%s)\n", + user_id, euid, errno, strerror(errno)); + exit(-1); + } + + fprintf(stderr, "running as uid/gid/euid/egid %d/%d/%d/%d, groups:", + user_id, grp_id, euid, egid); + for (i = 0; i < num_supp; i++) + fprintf(stderr, " %d", supp_groups[i]); + fprintf(stderr, "\n"); + + for (i = 0; i < argc - optind; i++) + fprintf(stderr, " [%s]", my_argv[i]); + + fprintf(stderr, "\n"); + fflush(stderr); + + /* The command to be run */ + execvp(my_argv[0], my_argv); + fprintf(stderr, "execvp fails running %s (%d): %s\n", my_argv[0], + errno, strerror(errno)); + exit(-1); } -