[net.unix-wizards] so who has mkdir and rmdir for non-4.2 systems

guy@sun.UUCP (07/13/86)

> In article <1885@brl-smoke.ARPA>, gwyn@BRL.ARPA (VLD/VMB) writes:
> > < fragment of "mkdir" using "system">
> 
> The above can use a bit of idiot proofing--especially against meta
> characters in dirname.  Below is the version of "mkdir" that went out with
> the time zone stuff.
>
> <version of "mkdir", still using "system">

Well:

	1) the second version of "mkdir" should declare the path name
	   argument to "mkdir" as "register", since it's used enough
	   that it will make a difference.

	2) This applies to most non-4.2 systems, not just System V,
	   since they don't have "mkdir" or "rmdir" system calls either.
	   (It also *doesn't* apply to System V Release 3, since S5R3
	   *does* have "mkdir" and "rmdir".)

	3) Those non-4.2 systems have "fork" and the "exec" family of
	   routines.  Why not use them?  That keeps the shell out of
	   the path entirely, which means a) you don't have to worry
	   about what it does to metacharacters and b) it runs a bit faster.
	   You can use "execvp", which will do a path search for "mkdir",
	   and will even run it if it's a shell script.  On the other hand,
	   you can assume that it's in "/bin" or "/usr/bin", and that it's
	   an executable image, since both of those are true on any UNIX
	   system.

	4) If you really want to get fussy, you can worry about
	   figuring out *why* "mkdir" or "rmdir" fails, if it does, and
	   setting the error code in a 4.2BSD-compatible fashion.

	   You can also set it in a P1003-compatible fashion, but you probably
	   don't want to; there is only one place where P1003's and 4.2BSD's
	   error codes conflict, and P1003 is wrong and 4.2BSD is right in
	   that case.

	   The case in question is when "rmdir" is called with a path name
	   referring to a non-empty directory; P1003 specifies that "errno"
	   should be set to EEXIST in this case, while 4.2BSD returns
	   ENOTEMPTY.  If a program calls the UNIX "perror" routine after
	   "rmdir" fails", EEXIST will cause the message "File exists" to be
	   printed, while ENOTEMPTY will cause "Directory not empty" to be
	   printed.  The most logical user response to the first message
	   would be "Of *course* it exists, that's why I'm trying to remove
	   it!" while the most logical user response to the second message
	   would be "Oops, I guess I have to empty the directory out first."
	   The latter response is better, since it will either cause the
	   user to empty the directory, thus permitting it to be removed,
	   or cause the user to realize that the directory contains useful
	   files and should not be removed.

	   Since the P1003 standard is a Trial-Use standard, I presume
	   that it would be possible to fix this problem; I think recent
	   Sun comments on the standard have included a mention of this
	   problem.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)

kre@munnari.UUCP (07/13/86)

To emulate 4.[23]'s mkdir()/rmdir() correctly, you have to
be able to do the right thing when the invoking program is
setuid to someone.

That absolutely rules out using system("mkdir") or popen("mkdir")
as the mkdir program is setuid root, and it won't inherit the
correct "real" uid (the effective uid of the calling program).

I can't locate the right Sys V manual to be able to determine
if it can be done sensibly with fork()/exec*() and a setuid()
of some variety in between.

On v7, 4.1bsd, etc, this is a hard problem, don't expect to be
able to solve it quickly!

Neither of the posted mkdir()'s had the args right either.
4.[23]'s mkdir is mkdir(path, mode) not mkdir(path).  Of
course, its trivial to add a umask to fix this (nb: not
a chmod after the directory is made, or there will be a window
when it exists without the correct permissions, which could
be fatal).

Robert Elz		seismo!munnari!kre  kre%munnari.oz@seismo.css.gov

guy@sun.UUCP (07/14/86)

> To emulate 4.[23]'s mkdir()/rmdir() correctly, you have to
> be able to do the right thing when the invoking program is
> setuid to someone.
...
> I can't locate the right Sys V manual to be able to determine
> if it can be done sensibly with fork()/exec*() and a setuid()
> of some variety in between.

S5 doesn't make it any easier.  You need to be able to set the real UID of
the child process to match the effective UID, and it won't let you do that.

This causes worse problems than just making it impossible for set-UID
programs to run "mkdir" or "rmdir" with the proper permissions.  It means a
set-UID program - like, say, "uucico" - *can't* prevent itself from getting
zapped by a signal sent from a process running with the UID of the person
who started it; this means that in S5, if you do a "uucp", or "uux", or
anything that runs one of those commands, and it starts up a "uucico", you
can zap that "uucico" at any time!
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)