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)