Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 14 Nov 1996 14:07:35 -0500
From:      "Brian J. McGovern" <mcgovern@spoon.beta.com>
To:        questions@freebsd.org
Subject:   chroot problems...
Message-ID:  <199611141907.OAA17106@spoon.beta.com>

next in thread | raw e-mail | index | archive | help
Hi, I'm tinking with an application that I will be using as a pseudo-shell for
users to dial up and pick up and drop off some files on a FreeBSD server. In
order to maximize security, I decided to cd in to their home directory,
then chroot to that directory.

In their home directory, I have created a directory called bin,
statically linked csh, ls, more, rz, and sz. The program has been set
set-uid root. On execution, it changes directories and chroot's with no
error (error codes are 0). However, if I try to run (for instance)
/bin/csh, bin/csh, bin/ls, or /bin/ls using a call to system()
(ie - system("/bin/csh") ), it returns an error code 4. 

In any event, I can't seem to figure out what this is implying (as when I do
a getcwd, it seems to work. I haven't tried changing directories to bin,
but it anyone could shed some light on my mistakes, I'd appreciate it. Below
is a terribly hacked piece of code. I apologize to those to try to read it,
but its the results of several hours with the chainsaw.

	-Brian

PS - BTW, all of the functions work fine when I try not to chroot, and do
it in the "normal" filesystem.


/* This program is a 'shell' to ease the use of remote communications,
   and to assist in the security thereof. It will allow people to move
   files via Zmodem, Ymodem, and Xmodem protocols, as well as have
   sufficient hooks to add more protocols as needed */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <pwd.h>
#include <unistd.h>
#include <errno.h>

int show_directory_to_user(void)
  {
    int x;
    unsigned char wait[2];
    printf("The files you have on E.D.E's system...\n");
    sleep(1);
    x=system("/bin/ls");
    if (x != 0);
      printf("ls failed, error code: %d\n",errno);
    return x;
  }


int check_pathname(char *pathname)
  {
    if (strchr(pathname,'`') != NULL)  /* The format is to check for a bad char, */
      return 1;			       /* and if found, return a non-zero value */
    if (strchr(pathname,'/') != NULL)
      return 1;
    if (strchr(pathname,'\"') != NULL)
      return 1;
    if (strchr(pathname,'\\') != NULL)
      return 1;
    return 0;
  }

void get_pathname(unsigned char *buffer, int length)
  {
    bzero(buffer,length);
    printf("A filename is required for this operation. Please enter\n");
    printf("it here ----> ");
    fflush(stdin);
    fgets(buffer,length,stdin);
  }
  
void main(void)
  {
    char pathname[128];
    unsigned int i;		   
    int ready_to_go = 0;	
    unsigned char filename_needed; 
    unsigned char show_directory;  
    unsigned char menuitem[3];     
				
    unsigned char filename[64];	   
				

    unsigned char command_path[64]; 
    unsigned char command_execute[128];
    struct passwd *user_password;
/* here is the broken part */
    user_password = getpwuid(getuid()); /* get our info */
    printf("Changing root to %s\n",user_password->pw_dir); 
    chdir(user_password->pw_dir); /* Change dir to our home dir */
    i = chroot(user_password->pw_dir); /* Set the root here */
    getcwd(pathname,128); /* Get the directory. It shows / when printed */
    printf("Current dir: %s\n",pathname);
    if (i != 0)
      printf("CHROOT failed!\n"); /*doesn't happen so long as its suid-root */
    system("/bin/csh"); /* Doesn't open a shell */
    filename_needed = 0;	  
				
    show_directory = 0;		  
    bzero(menuitem,4);		  

    while (atoi(menuitem) != 99)
      {
        ready_to_go = 0;
        for (i=0;i<25;i++) /* Quick routine to "clear" the screen on all */
	  printf("\n");    /* terminals, by pushing things "off" the top */

  /* The user menu */
        printf("E.D.E. File transfer system\n\n");
	printf("UPLOAD = you to E.D.E.   DOWNLOAD = E.D.E. to you\n\n\n");	
        printf("1.) UPLOAD   file with Zmodem\n");
	printf("2.) UPLOAD   file with Ymodem\n");
	printf("3.) UPLOAD   file with Xmodem\n\n");
	printf("4.) DOWNLOAD file with Zmodem\n");
	printf("5.) DOWNLOAD file with Ymodem\n");
	printf("6.) DOWNLOAD file with Xmodem\n");
	printf("\n\n99.) Log off system (disconnect)\n");
	printf("\n\nPlease select your choice---> ");
	fflush(stdin);
	fgets(menuitem,3,stdin);

	switch (atoi(menuitem))
	  {
	    case 0:
	      {
	        break;
	      }
	    case 1:
	      {
	        filename_needed = 0;
		show_directory = 0;
		strcpy(command_path,"/bin/rz");
                break;
	      }
	    case 2:
	      {
	        filename_needed = 0;
		show_directory = 0;
		strcpy(command_path,"/bin/rb");
                break;
	      }
	    case 3:
	      {
	        filename_needed = 1;
		show_directory = 0;
		strcpy(command_path,"/bin/rx");
		break;
	      }
	    case 4:
	      {
	        filename_needed = 1;
		show_directory = 1;
		strcpy(command_path,"/bin/sz -w 1024");
		break;
	      }
	    case 5:
	      {
	        filename_needed = 1;
		show_directory = 1;
		strcpy(command_path,"/bin/sb");
                break;
	      }
	    case 6:
	      {
	        filename_needed = 1;
		show_directory = 1;
		strcpy(command_path,"/bin/sx");
		break;
	      }
            case 98:
              {
                strcpy(command_path,"/bin/csh");
                break;
	      }
            case 99:
	      {
	        exit(0);
		break;
	      }
	  }
	if (show_directory != 0)
	  show_directory_to_user();
	if (filename_needed != 0)
	  {
	    get_pathname(filename,sizeof(filename));
	    if (check_pathname(filename) != 0)
	      ready_to_go = 0;
	    else
	      ready_to_go = 1;
	  }
	else
	  ready_to_go = 1;
	if (ready_to_go == 1)
	  {
	    if (filename_needed == 1)
	      sprintf(command_execute,"%s %s",command_path, filename);
	    else
	      sprintf(command_execute,"%s",command_path);
	    printf("Executing command %s\n",command_execute);
	    system(command_execute);
	  }
      }
  }




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199611141907.OAA17106>