[comp.unix.programmer] Checking change of directory

uaa1006@dircon.co.uk (Peter Miles) (05/28/91)

Has anyone done any work on keeping users within a certain directory 
tree?

I'm writing a "mini shell" which will only allow users a limited 
number of commands. I'm intending adding a 'cd' (change directory)
command which will only allow users to move to directories below 
their HOME dir. I do this currently by looking at the string
entered by the user, checking and rejecting any relative movements
(../. etc). Then I strcat the user's string onto the end of 
their home directory string. However, I'd like to be able to 
allow relative movements.

Is there any function available which, when given a string such 
as "../../etc" or whatever, can resolve this into the 
absolute path which I can then compare with the HOME dir and 
accept or reject?

I will also use this in various programs such as editors to
prevent users from reading in files from outside their HOME
directory tree. 

The Boss basically wants to stop people from being able to access 
files in each others directories, and not have to rely on people 
using chown/chmod correctly.

I know about chroot, but the problem with that is I want users 
to be able to run certain programs which require access to /etc, 
/dev etc. The system I'm using doesn't support symbolic links.

Please reply by mail and I'll summarize if there's interest.

                        -- Pete
-- 
Pete Miles			uaa1006@dircon.co.uk
				...ukc!dircon!uaa1006

martin@mwtech.UUCP (Martin Weitzel) (05/29/91)

In article <1991May28.124051.23538@dircon.co.uk> uaa1006@dircon.co.uk (Peter Miles) writes:
>
>Is there any function available which, when given a string such 
>as "../../etc" or whatever, can resolve this into the 
>absolute path which I can then compare with the HOME dir and 
>accept or reject?

If I don't miss anything important, you should be able to obtain the
desired information as follows:

	----------------------------------------------------------------------
	FILE *fp = popen("IFS='\t ';PATH='/bin:/usr/bin'; cd xxx && pwd", "r");
	/*                                                   ^^^
	 * Make the target directory appear here ------------^^^;
	 * check for embedded funny characters that may change the shell's
	 * parsing of this line. (To play safe, only allow alpha-numeric
	 * characters, underscore, and dot.) If the given directory doesn't
	 * exist, you may further want to suppress error messages from the
	 * shell by redirecting 2>/dev/null in the above command line.
	*/
	char buffer[200];
	/*          ^^^
	 * Set this ^^^ to whatever you think is appropriate.
	*/
	int err = 0;

	if (fp == (FILE *)0) err++;
	else {
		if (fgets(buffer, sizeof buffer, fp) == (char *)0) err++;
		else {
			int n = strlen(buffer);
			if (n == 0 || buffer[n-1] != '\n') err++;
			else buffer[n-1] = '\0';
		}
		if (pclose(fp) != 0) err++;
	}
	if (err) {
		/*
		 * Destination directory doesn't exist or user tries to trick
		 * you out with non-readable intermediate path components.
		*/
	}
	else {
		/*
		 * Absolute path to destination directory is now in buffer.
		*/
	}
	----------------------------------------------------------------------

I've three times checked the above and hope there are no silly typos.
-- 
Martin Weitzel, email: martin@mwtech.UUCP, voice: 49-(0)6151-6 56 83