X-Git-Url: http://git.marmaro.de/?a=blobdiff_plain;f=sbr%2Fmakedir.c;h=e4c3c26c15f60baea3645bf6ecadd814d0fe0400;hb=017a82124bf2ea39ced5aa4c8f969c18b3c2fb90;hp=6cf9e03c29303f90aab20eb9612228cbd78c5760;hpb=1691e80890e5d8ba258c51c214a3e91880e1db2b;p=mmh diff --git a/sbr/makedir.c b/sbr/makedir.c index 6cf9e03..e4c3c26 100644 --- a/sbr/makedir.c +++ b/sbr/makedir.c @@ -19,61 +19,97 @@ extern int errno; int makedir (char *dir) { - pid_t pid; - register char *cp; - register char *c; - char path[PATH_MAX]; + char path[PATH_MAX]; + char* folder_perms_ASCII; + int had_an_error = 0; + mode_t folder_perms, saved_umask; + pid_t pid; + register char* c; context_save(); /* save the context file */ fflush(stdout); - if (getuid () == geteuid ()) { - c = strncpy(path, dir, sizeof(path)); + if (!(folder_perms_ASCII = context_find ("folder-protect"))) + folder_perms_ASCII = foldprot; /* defaults to "0700" */ + + /* Call strtoul() with radix=0, which means it'll determine the base by + looking at the first digit. That way it'll know "0700" is an octal + constant (and if someone gets wacky and changes the representation to hex + it'll still work). */ + folder_perms = strtoul(folder_perms_ASCII, NULL, 0); - while ((c = strchr((c + 1), '/')) != NULL) { - *c = (char)0; - if (access(path, X_OK)) { - if (errno != ENOENT){ - advise (dir, "unable to create directory"); - return 0; - } - if (mkdir(path, 0775)) { - advise (dir, "unable to create directory"); - return 0; - } - } - *c = '/'; - } - - if (mkdir (dir, 0755) == -1) { + /* Folders have definite desired permissions that are set -- we don't want + to interact with the umask. Clear it temporarily. */ + saved_umask = umask(0); + + if (getuid () == geteuid ()) { + c = strncpy(path, dir, sizeof(path)); + + while (!had_an_error && (c = strchr((c + 1), '/')) != NULL) { + *c = (char)0; + if (access(path, X_OK)) { + if (errno != ENOENT){ advise (dir, "unable to create directory"); - return 0; + had_an_error = 1; + } + /* Create an outer directory. */ + if (mkdir(path, folder_perms)) { + advise (dir, "unable to create directory"); + had_an_error = 1; + } } - } else { - switch (pid = vfork()) { - case -1: - advise ("fork", "unable to"); - return 0; - - case 0: - setgid (getgid ()); - setuid (getuid ()); + *c = '/'; + } - execl ("/bin/mkdir", "mkdir", dir, NULL); - execl ("/usr/bin/mkdir", "mkdir", dir, NULL); - fprintf (stderr, "unable to exec "); - perror ("mkdir"); - _exit (-1); + if (!had_an_error) { + /* Create the innermost nested subdirectory of the path we're being + asked to create. */ + if (mkdir (dir, folder_perms) == -1) { + advise (dir, "unable to create directory"); + had_an_error = 1; + } + } + } + else { + /* Ummm, why do we want to avoid creating directories with the effective + user ID? None of the nmh tools are installed such that the effective + should be different from the real, and if some parent process made + the two be different, I don't see why it should be our job to enforce + the real UID. Also, why the heck do we call the mkdir executable + rather than the library function in this case?? If we do want to + call the mkdir executable, we should at least be giving it -p (and + change the single chmod() call below) so it can successfully create + nested directories like the above code can. - default: - if (pidXwait(pid, "mkdir")) + -- Dan Harkless */ + switch (pid = vfork()) { + case -1: + advise ("fork", "unable to"); return 0; - break; + + case 0: + setgid (getgid ()); + setuid (getuid ()); + + execl ("/bin/mkdir", "mkdir", dir, NULL); + execl ("/usr/bin/mkdir", "mkdir", dir, NULL); + fprintf (stderr, "unable to exec "); + perror ("mkdir"); + _exit (-1); + + default: + if (pidXwait(pid, "mkdir")) + return 0; + break; } + + chmod (dir, folder_perms); } - if (!(cp = context_find ("folder-protect"))) - cp = foldprot; - chmod (dir, atooi (cp)); - return 1; + umask(saved_umask); /* put the user's umask back */ + + if (had_an_error) + return 0; /* opposite of UNIX error return convention */ + else + return 1; }