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>