static Bool FileAcceptableSafeTmpDir(const char *dirname, // IN: int userId) // IN: { Bool result; static const mode_t mode = 0700; result = (Posix_Mkdir(dirname, mode) == 0); if (!result) { int error = errno; if (EEXIST == error) { struct stat st; /* * The name already exists. Check that it is what we want: a * directory owned by the current effective user with permissions * 'mode'. It is crucial to use lstat() instead of stat() here, * because we do not want the name to be a symlink (created by * another user) pointing to a directory owned by the current * effective user with permissions 'mode'. */ if (0 == Posix_Lstat(dirname, &st)) { /* * Our directory inherited S_ISGID if its parent had it. So it * is important to ignore that bit, and it is safe to do so * because that bit does not affect the owner's permissions. */ if (S_ISDIR(st.st_mode) && (st.st_uid == userId) && ((st.st_mode & 05777) == mode)) { result = TRUE; } } } } return result; }
int File_MakeTempEx2(ConstUnicode dir, // IN: Bool createTempFile, // IN: File_MakeTempCreateNameFunc *createNameFunc, // IN: void *createNameFuncData, // IN: Unicode *presult) // OUT: { uint32 i; int fd = -1; uint32 var = 0; Unicode path = NULL; if ((dir == NULL) || (createNameFunc == NULL)) { errno = EFAULT; return -1; } ASSERT(presult); *presult = NULL; for (i = 0; i < (MAX_INT32 / 2); i++) { Unicode fileName; /* construct suffixed pathname to use */ Unicode_Free(path); path = NULL; /* * Files and directories are kept separate (odd and even respectfully). * This way the available exclusion mechanisms work properly - O_EXCL * on files, mkdir on directories - and races are avoided. * * Not attempting an open on a directory is a good thing... */ FileTempNum(createTempFile, &var); fileName = (*createNameFunc)(var, createNameFuncData); ASSERT(fileName); /* construct base full pathname to use */ path = Unicode_Join(dir, DIRSEPS, fileName, NULL); Unicode_Free(fileName); if (createTempFile) { fd = Posix_Open(path, O_CREAT | O_EXCL | O_BINARY | O_RDWR, 0600); } else { fd = Posix_Mkdir(path, 0700); } if (fd != -1) { *presult = path; path = NULL; break; } if (errno != EEXIST) { Log(LGPFX" Failed to create temporary %s \"%s\": %s.\n", createTempFile ? "file" : "directory", UTF8(path), strerror(errno)); goto exit; } } if (fd == -1) { Warning(LGPFX" Failed to create temporary %s \"%s\": " "The name space is full.\n", createTempFile ? "file" : "directory", UTF8(path)); errno = EAGAIN; } exit: Unicode_Free(path); return fd; }