- if (argc < 3){
- fprintf (stderr,"capchroot version %s\n",VERSION);
- fprintf (stderr
- ,"capchroot --nochroot directory [ --suid user ] command argument\n"
- "\n"
- "--nochroot remove the CAP_SYS_CHROOT capability\n"
- " after the chroot system call.\n"
- "--suid switch to a different user (in the vserver context)\n"
- " before executing the command.\n");
- }else{
- const char *uid = NULL;
- bool nochroot = false;
- int dir;
- for (dir=1; dir<argc; dir++){
- const char *arg = argv[dir];
- if (arg[0] != '-' && arg[1] != '-'){
- break;
- }else if (strcmp(arg,"--nochroot")==0){
- nochroot = true;
- }else if (strcmp(arg,"--suid")==0){
- dir++;
- uid = argv[dir];
- }
-
- }
- // We resolve the UID before doing the chroot.
- // If we do the getpwnam after the chroot, we will end
- // up loading shared object from the vserver.
- // This is causing two kind of problem: Incompatibilities
- // and also a security flaw. The shared objects in the vserver
- // may be tweaked to get control of the root server ...
- getpwnam ("root");
- if (chroot(argv[dir]) == -1){
- fprintf (stderr,"Can't chroot to directory %s (%s)\n",argv[dir]
- ,strerror(errno));
- }else{
- struct passwd *p = NULL;
- int cmd = dir + 1;
-
- if (nochroot){
- vc_new_s_context (-2,1<<CAP_SYS_CHROOT,0);
- }
-
- if (uid != NULL && strcmp(uid,"root")!=0){
- p = getpwnam(uid);
- if (p == NULL){
- fprintf (stderr,"User not found: %s\n",uid);
- exit (-1);
- }
- }
- if (p != NULL) {
- setgroups (0,NULL);
- setgid(p->pw_gid);
- setuid(p->pw_uid);
- }
- if (cmd >= argc){
- fprintf (stderr,"capchroot: No command to execute, do nothing\n");
- }else{
- execvp (argv[cmd],argv+cmd);
- fprintf (stderr,"Can't execute %s (%s)\n",argv[cmd]
- ,strerror(errno));
- }
- }
- }
- return -1;