maart@cs.vu.nl (Maarten Litmaath) (07/22/89)
Let's return to the original article. tony@ajfcal.UUCP (Tony Field) wrote: \... \I have a shell script that is running an effective uid of "news". The \script calls a process that has a real uid of a "user". The process can \create directories with mkdir that belong to "user", however it cannot \create a file. \ \If the process is setuid to root, then I can create the directores and \the files, however the owner becomes "root", and I would prefer the \owner be "news". Apparently the current directory is unwritable for `news'. Yet Tony wants to create files and directories owned by that very uid. We conclude: the directory should be writable for `news'. Letting `root' create the entries and chown()ing them is a kludge. On the other hand we don't want to `chmod 777 <current directory>'. The solution seems to be: make the directory writable for the GROUP `news' and let the shell script run SETUID `news' AND SETGID `news'. But wait! If we want to make a directory, our effective uid of `news' still gets overwritten by 0, because /bin/mkdir is setuid root. Right. We can solve this by invoking a setuid root wrapper, ONLY executable for the GROUP `news'. (Yup, another kludge. Who sees a way out?) This wrapper will set the real uid to `news', and execute the specified command in turn. In our problem we only want to execute /bin/mkdir, but it's good practice to set things up in a more general fashion: #define NEWS 6 /* uid of news */ main(argc, argv) int argc; char **argv; { if (argc == 1) exit(0); if (setuid(NEWS) == -1) { /* eff. gid is still `news' */ perror("setuid"); exit(1); } execvp(argv[1], &argv[1]); perror(argv[1]); exit(1); } Invoke like: $ donews mkdir foo bar baz or execl("donews", "donews", "mkdir", "foo", "bar", "baz", (char *) 0); Boy, does SysV miss setuid(geteuid()) and mkdir(2)! :-( -- "I HATE arbitrary limits, especially when |Maarten Litmaath @ VU Amsterdam: they're small." (Stephen Savitzky) |maart@cs.vu.nl, mcvax!botter!maart