Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}