コード例 #1
0
ファイル: scoreboard.c プロジェクト: Nakor78/proftpd
int util_open_scoreboard(int flags) {
  int res;
  struct stat st;

  /* Prevent writing to a symlink while avoiding a race condition: open
   * the file name O_RDWR|O_CREAT first, then check to see if it's a symlink.
   * If so, close the file and error out.  If not, truncate as necessary,
   * and continue.
   */
  util_scoreboard_fd = open(util_scoreboard_file, flags);
  if (util_scoreboard_fd < 0)
    return -1;

  if (fstat(util_scoreboard_fd, &st) < 0) {
    close(util_scoreboard_fd);
    util_scoreboard_fd = -1;
    return -1;
  }

  if (S_ISLNK(st.st_mode)) {
    close(util_scoreboard_fd);
    util_scoreboard_fd = -1;
    errno = EPERM;
    return -1;
  }

  /* Check the header of this scoreboard file. */
  res = read_scoreboard_header(&util_header);
  if (res < 0)
    return res;

  return 0;
}
コード例 #2
0
ファイル: scoreboard.c プロジェクト: OPSF/uClinux
int pr_open_scoreboard(int flags) {
  int res;
  struct stat st;

  /* Try to prevent a file descriptor leak by only opening the scoreboard
   * file if the scoreboard file descriptor is not already positive, i.e.
   * if the scoreboard has not already been opened.
   */
  if (scoreboard_fd >= 0 && scoreboard_opener == getpid()) {
    pr_log_debug(DEBUG7, "scoreboard already opened");
    return 0;
  }

  pr_log_debug(DEBUG7, "opening scoreboard '%s'", scoreboard_file);

  /* Prevent writing to a symlink while avoiding a race condition: open
   * the file name O_RDWR|O_CREAT first, then check to see if it's a symlink.
   * If so, close the file and error out.  If not, truncate as necessary,
   * and continue.
   */
  
  while ((scoreboard_fd = open(scoreboard_file, flags|O_CREAT,
      PR_SCOREBOARD_MODE)) < 0) {
    if (errno == EINTR) {
      pr_signals_handle();
      continue;

    } else
      return -1;
  }

  /* Make certain that the scoreboard mode will be read-only for everyone
   * except the user owner (this allows for non-root-running daemons to
   * still modify the scoreboard).
   */
  while (fchmod(scoreboard_fd, 0644) < 0) {
    if (errno == EINTR) {
      pr_signals_handle();
      continue;

    } else
      break;
  }

  while (fstat(scoreboard_fd, &st) < 0) {
    int st_errno = errno;

    if (errno == EINTR) {
      pr_signals_handle();
      continue;
    }

    while (close(scoreboard_fd) < 0) {
      if (errno == EINTR) {
        pr_signals_handle();
        continue;

      } else
        break;
    }

    /* Either way, the scoreboard fd should be marked as closed. */
    scoreboard_fd = -1;

    errno = st_errno;
    return -1;
  }

  if (S_ISLNK(st.st_mode)) {
    while (close(scoreboard_fd) < 0) {
      if (errno == EINTR) {
        pr_signals_handle();
        continue;

      } else
        break;
    }

    errno = EPERM;
    scoreboard_fd = -1;
    return -1;
  }

  scoreboard_opener = getpid();

  /* Check the header of this scoreboard file. */
  if ((res = read_scoreboard_header(&header)) == -1) {

    /* If this file is newly created, it needs to have the header
     * written.
     */
    header.sch_magic = PR_SCOREBOARD_MAGIC;
    header.sch_version = PR_SCOREBOARD_VERSION;

    if (ServerType == SERVER_STANDALONE) {
      header.sch_pid = getpid();
      header.sch_uptime = time(NULL);

    } else {
      header.sch_pid = 0;
      header.sch_uptime = 0;
    }

    /* Write-lock the scoreboard file. */
    if (wlock_scoreboard() < 0)
      return -1;

    while (write(scoreboard_fd, &header, sizeof(header)) != sizeof(header)) {
      int wr_errno = errno;

      if (errno == EINTR) {
        pr_signals_handle();
        continue;
      }

      unlock_scoreboard();

      errno = wr_errno;
      return -1;
    }

    unlock_scoreboard();
    return 0;

  } else
    return res;

  return 0;
}