static char * FindSuitableExistingDirectory( const char *realRoot, // IN: e.g. $HOME/.cache/vmware/drag_and_drop/ const char *apparentRoot) // IN: e.g. /tmp/VMwareDnD/ { char *result = NULL; char **stagingDirList; int numStagingDirs = File_ListDirectory(realRoot, &stagingDirList); int i; for (i = 0; i < numStagingDirs && result == NULL; i++) { char *stagingDir = Unicode_Append(realRoot, stagingDirList[i]); char *apparentStagingDir = Unicode_Append(apparentRoot, stagingDirList[i]); char *temp = NULL; struct stat sb; if ( File_IsEmptyDirectory(stagingDir) && ( Posix_Symlink(stagingDir, apparentStagingDir) == 0 || ( Posix_Lstat(apparentStagingDir, &sb) == 0 && sb.st_uid == getuid() && (temp = Posix_ReadLink(apparentStagingDir)) != NULL && strcmp(stagingDir, temp) == 0))) { result = apparentStagingDir; apparentStagingDir = NULL; } free(stagingDir); free(apparentStagingDir); free(temp); } Util_FreeStringList(stagingDirList, numStagingDirs); return result; }
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; }