X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=chiark-utils.git;a=blobdiff_plain;f=cprogs%2Freally.c;h=4d1f316364ea84fe4c84b201dbb85ce619d88b98;hp=39fe8dddbe62036ac46cd22ece5483255047ce46;hb=50505a407d5558883e5242a12ec49d298f4344fe;hpb=856172213e27f81e1d3a1a3d5585dd21c706bf90 diff --git a/cprogs/really.c b/cprogs/really.c index 39fe8dd..4d1f316 100644 --- a/cprogs/really.c +++ b/cprogs/really.c @@ -1,4 +1,22 @@ -/**/ +/* + * really.c - program for gaining privilege + * + * Copyright (C) 1992-3 Ian Jackson + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2, + * or (at your option) any later version. + * + * This 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 for more details. + * + * You should have received a copy of the GNU General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ #include #include @@ -12,24 +30,36 @@ #include "myopt.h" void usagemessage(void) { - if (fputs("usage: really [] [ ...] [--]" + if (fputs("usage: really [ ...] [--]" " [ [ ...]]\n" - "user-options:\n" + "really-options specifying the user:\n" " if no options given, set the uid to 0;\n" " -u|--user also sets their default group list\n" " -i|--useronly } set the uid\n" " -I|--uidonly } but inherits the group list\n" - "group-options:\n" + "really-options specifying the group:\n" " -z|--groupsclear only groups specified are to be used\n" " -g|--group } add this to\n" - " -G|--gid } the group list\n", + " -G|--gid } the group list\n" + "other really-options:\n" + " -h|--help display this message" + " -R|--chroot chroot (but *not* chdir)", stderr) == EOF) { perror("write usage"); exit(-1); } } -static const char *opt_user, *opt_useronly; +static const char *opt_user, *opt_useronly, *opt_chroot; static int opt_groupsclear= 0, opt_ngids= 0, opt_uidonly= -1; static int opt_gids[512]; +static void af_uidonly(const struct cmdinfo *cip, const char *value) { + unsigned long ul; + char *ep; + + ul= strtoul(value,&ep,10); + if (*ep) { fprintf(stderr,"bad uid `%s'\n",value); exit(-1); } + opt_uidonly= ul; +} + static void af_group(const struct cmdinfo *cip, const char *value) { struct group *gr; @@ -58,10 +88,11 @@ static void af_help(const struct cmdinfo *cip, const char *value) { static const struct cmdinfo cmdinfos[]= { { "user", 'u', 1, 0, &opt_user, 0, }, { "useronly", 'i', 1, 0, &opt_useronly, 0 }, - { "uidonly", 'I', 1, &opt_uidonly, 0, 0 }, + { "uidonly", 'I', 1, 0, 0, af_uidonly }, { "groupsclear", 'z', 0, &opt_groupsclear, 0, 0, 1 }, { "group", 'g', 1, 0, 0, af_group }, { "gid", 'G', 1, 0, 0, af_gid }, + { "chroot", 'R', 1, 0, &opt_chroot, 0 }, { "help", 'h', 0, 0, 0, af_help }, { 0, 0 } }; @@ -76,7 +107,7 @@ static void checkroot(void) { #ifdef REALLY_CHECK_GID static void checkroot(void) { gid_t groups[512]; - int r; + int r, i; r= getgid(); if (r==REALLY_CHECK_GID) return; if (r<0) { perror("getgid check"); exit(-1); } @@ -119,6 +150,9 @@ int main(int argc, const char *const *argv) { if (!pw) { fprintf(stderr,"unknown user `%s'\n",cp); exit(-1); } opt_uidonly= pw->pw_uid; } + if (opt_chroot) { + if (chroot(opt_chroot)) { perror("chroot failed"); exit(-1); } + } orgmaingid= getgid(); orgmainuid= getuid(); if (orgmaingid<0) { perror("getgid failed"); exit(-1); }