vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

capchroot.c (5106B)


      1 // $Id$
      2 
      3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
      4 // based on capchroot.cc by Jacques Gelinas
      5 //  
      6 // This program is free software; you can redistribute it and/or modify
      7 // it under the terms of the GNU General Public License as published by
      8 // the Free Software Foundation; either version 2, or (at your option)
      9 // any later version.
     10 //  
     11 // This program is distributed in the hope that it will be useful,
     12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 // GNU General Public License for more details.
     15 //  
     16 // You should have received a copy of the GNU General Public License
     17 // along with this program; if not, write to the Free Software
     18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     19 
     20 /*
     21 	This chroot command does very little. Once the chroot
     22 	system call is executed, it (option) remove the CAP_SYS_CHROOT
     23 	capability. Then it executes its argument
     24 */
     25 
     26 #ifdef HAVE_CONFIG_H
     27 #  include <config.h>
     28 #endif
     29 
     30 #include "vserver.h"
     31 #include "util.h"
     32 
     33 #include <stdio.h>
     34 #include <string.h>
     35 #include <pwd.h>
     36 #include <grp.h>
     37 #include <errno.h>
     38 #include <unistd.h>
     39 #include <stdbool.h>
     40 #include <stdlib.h>
     41 #include <getopt.h>
     42 #include <libgen.h>
     43 
     44 #define ENSC_WRAPPERS_PREFIX	"capchroot: "
     45 #define ENSC_WRAPPERS_UNISTD	1
     46 #define ENSC_WRAPPERS_VSERVER	1
     47 #include <wrappers.h>
     48 
     49 #define CMD_HELP		0x1000
     50 #define CMD_VERSION		0x1001
     51 #define CMD_NOCHROOT		0x2000
     52 #define CMD_SUID		0x2001
     53 
     54 int			wrapper_exit_code = 255;
     55 
     56 static struct option const
     57 CMDLINE_OPTIONS[] = {
     58   { "help",        no_argument,       0, CMD_HELP },
     59   { "version",     no_argument,       0, CMD_VERSION },
     60   { "nochroot",    no_argument,       0, CMD_NOCHROOT },
     61   { "suid",        required_argument, 0, CMD_SUID },
     62   {0,0,0,0}
     63 };
     64 
     65 static void
     66 showHelp(int fd, char const *cmd, int res)
     67 {
     68   VSERVER_DECLARE_CMD(cmd);
     69 
     70 #if !defined(VC_ENABLE_API_COMPAT) && !defined(VC_ENABLE_API_LEGACY)
     71   WRITE_MSG(1, "ERROR: tools were built without legacy API support; capchroot will not work!\n\n");
     72 #endif
     73   
     74   WRITE_MSG(fd, "Usage:  ");
     75   WRITE_STR(fd, cmd);
     76   WRITE_MSG(fd,
     77 	    " --nochroot [--suid <user>] [--] <directory> <command> <args>*\n"
     78 	    "\n"
     79 	    "Options:\n"
     80             "    --nochroot     ... remove the CAP_SYS_CHROOT capability\n"
     81             "                       after the chroot system call.\n"
     82 	    "    --suid <user>  ... switch to a different user (in the vserver\n"
     83 	    "                       context) before executing the command.\n"
     84 	    "\n"
     85 	    "Please report bugs to " PACKAGE_BUGREPORT "\n");
     86   exit(res);
     87 }
     88 
     89 static void
     90 showVersion()
     91 {
     92   WRITE_MSG(1,
     93 	    "capchroot " VERSION " -- a capability aware chroot\n"
     94 	    "This program is part of " PACKAGE_STRING "\n\n"
     95 	    "Copyright (C) 2004 Enrico Scholz\n"
     96 	    VERSION_COPYRIGHT_DISCLAIMER);
     97   exit(0);
     98 }
     99 
    100 static UNUSED void
    101 setUser(char const *user)
    102 {
    103   struct passwd		*p = 0;
    104   if (user!=0 && strcmp(user, "root")!=0 && strcmp(user, "0")!=0) {
    105     errno = 0;
    106     p     = getpwnam(user);
    107     if (p==0) {
    108       if (errno==0) errno = ENOENT;
    109       PERROR_Q(ENSC_WRAPPERS_PREFIX "getpwnam", user);
    110       exit(wrapper_exit_code);
    111     }
    112   }
    113 
    114   if (p!=0) {
    115     Esetgroups(1, &p->pw_gid);
    116     Esetgid(p->pw_gid);
    117     Esetuid(p->pw_uid);
    118 
    119     if (getuid()!=p->pw_uid || getgid()!=p->pw_gid) {
    120       WRITE_MSG(2, ENSC_WRAPPERS_PREFIX "Something went wrong while changing uid; expected uid/gid do not match the actual one\n");
    121       exit(wrapper_exit_code);
    122     }
    123   }
    124 }
    125     
    126 int main (int argc, char *argv[])
    127 {
    128   bool 			nochroot  = false;
    129   char const *		suid_user = 0;
    130   
    131   while (1) {
    132     int		c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0);
    133     if (c==-1) break;
    134 
    135     switch (c) {
    136       case CMD_HELP	:  showHelp(1, argv[0], 0);
    137       case CMD_VERSION	:  showVersion();
    138       case CMD_NOCHROOT	:  nochroot  = true;   break;
    139       case CMD_SUID	:  suid_user = optarg; break;
    140       default		:
    141 	WRITE_MSG(2, "Try '");
    142 	WRITE_STR(2, argv[0]);
    143 	WRITE_MSG(2, " --help' for more information.\n");
    144 	return EXIT_FAILURE;
    145 	break;
    146     }
    147   }
    148 
    149 #if defined(VC_ENABLE_API_COMPAT) || defined(VC_ENABLE_API_LEGACY)
    150   if (optind==argc)
    151     WRITE_MSG(2, "No directory specified; try '--help' for more information\n");
    152   else if (optind+1==argc)
    153     WRITE_MSG(2, "No command specified; try '--help' for more information\n");
    154   else {
    155       // We resolve the UID before doing the chroot.
    156       // If we do the getpwnam after the chroot, we will end
    157       // up loading shared object from the vserver.
    158       // This is causing two kind of problem: Incompatibilities
    159       // and also a security flaw. The shared objects in the vserver
    160       // may be tweaked to get control of the root server ...
    161     getpwnam("root");
    162     Echroot(argv[optind]);
    163     if (nochroot)
    164       Evc_new_s_context(VC_SAMECTX, 1<<VC_CAP_SYS_CHROOT,0);
    165     setUser(suid_user);
    166     EexecvpD(argv[optind+1], argv+optind+1);
    167   }
    168 #else
    169   WRITE_MSG(2, "capchroot: tools were built without legacy API support; can not continue\n");
    170 #endif
    171   
    172   return EXIT_FAILURE;
    173 }