Ejemplo n.º 1
0
static int read_scoreboard_header(pr_scoreboard_header_t *sch) {
  int res = 0;

  /* No interruptions, please. */
  pr_signals_block();
 
  /* NOTE: reading a struct from a file using read(2) -- bad (in general). */
  while ((res = read(scoreboard_fd, sch, sizeof(pr_scoreboard_header_t))) !=
      sizeof(pr_scoreboard_header_t)) {
    int rd_errno = errno;

    if (res == 0) {
      pr_signals_unblock();
      errno = EIO;
      return -1;
    }

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

    pr_signals_unblock();
    errno = rd_errno;
    return -1;
  }

  pr_signals_unblock();

  /* Note: these errors will most likely occur only for inetd-run daemons.
   * Standalone daemons erase the scoreboard on startup.
   */
 
  if (sch->sch_magic != PR_SCOREBOARD_MAGIC) {
    pr_close_scoreboard();
    return PR_SCORE_ERR_BAD_MAGIC;
  }

  if (sch->sch_version < PR_SCOREBOARD_VERSION) {
    pr_close_scoreboard();
    return PR_SCORE_ERR_OLDER_VERSION;
  }

  if (sch->sch_version > PR_SCOREBOARD_VERSION) {
    pr_close_scoreboard();
    return PR_SCORE_ERR_NEWER_VERSION;
  }

  return 0;
}
Ejemplo n.º 2
0
END_TEST

START_TEST (scoreboard_open_close_test) {
  int res;
  const char *dir = "/tmp/prt-scoreboard/", *path = "/tmp/prt-scoreboard/test",
    *mutex_path = "/tmp/prt-scoreboard/test.lck",
    *symlink_path = "/tmp/prt-scoreboard/symlink";

  res = mkdir(dir, 0775);
  fail_unless(res == 0, "Failed to create directory '%s': %s", dir,
    strerror(errno));

  res = chmod(dir, 0775);
  if (res < 0) {
    int xerrno = errno;

    (void) rmdir(dir);
    fail("Failed to set perms on '%s' to 0775': %s", dir, strerror(xerrno));
  }

  res = pr_set_scoreboard(path);
  if (res < 0) {
    int xerrno = errno;

    (void) rmdir(dir);
    fail("Failed to set scoreboard to '%s': %s", path, strerror(xerrno));
  }

  (void) unlink(path);
  (void) unlink(mutex_path);

  if (symlink(symlink_path, path) == 0) {

    res = pr_open_scoreboard(O_RDWR);
    if (res == 0) {
      (void) unlink(path);
      (void) unlink(mutex_path);
      (void) unlink(symlink_path);
      (void) rmdir(dir);

      fail("Unexpectedly opened symlink scoreboard");
    }

    if (errno != EPERM) {
      int xerrno = errno;

      (void) unlink(symlink_path);
      (void) unlink(mutex_path);
      (void) unlink(path);
      (void) rmdir(dir);

      fail("Failed to set errno to EPERM (got %d)", xerrno);
    }

    (void) unlink(path);
    (void) unlink(mutex_path);
    (void) unlink(symlink_path);
  }

  res = pr_open_scoreboard(O_RDONLY);
  if (res == 0) {
    (void) unlink(path);
    (void) unlink(mutex_path);
    (void) rmdir(dir);

    fail("Unexpectedly opened scoreboard using O_RDONLY");
  }

  if (errno != EINVAL) {
    int xerrno = errno;

    (void) unlink(symlink_path);
    (void) unlink(mutex_path);
    (void) unlink(path);
    (void) rmdir(dir);

    fail("Failed to set errno to EINVAL (got %d)", xerrno);
  }

  res = pr_open_scoreboard(O_RDWR);
  if (res < 0) {
    int xerrno = errno;

    (void) unlink(mutex_path);
    (void) unlink(path);
    (void) rmdir(dir);

    fail("Failed to open scoreboard: %s", strerror(xerrno));
  }

  /* Now that we have a scoreboard, try opening it again using O_RDONLY. */
  pr_close_scoreboard(FALSE);

  res = pr_open_scoreboard(O_RDONLY);
  if (res == 0) {
    (void) unlink(mutex_path);
    (void) unlink(path);
    (void) rmdir(dir);

    fail("Unexpectedly opened scoreboard using O_RDONLY");
  }

  if (errno != EINVAL) {
    int xerrno = errno;

    (void) unlink(mutex_path);
    (void) unlink(path);
    (void) rmdir(dir);

    fail("Failed to set errno to EINVAL (got %d)", xerrno);
  }

  (void) unlink(mutex_path);
  (void) unlink(path);
  (void) rmdir(dir);
}
Ejemplo n.º 3
0
END_TEST

START_TEST (scoreboard_disabled_test) {
  register unsigned int i = 0;
  const char *paths[4] = {
    "/dev/null",
    "none",
    "off",
    NULL
  };
  const char *path;

  for (path = paths[i]; path != NULL; path = paths[i++]) { 
    int res;
    const char *field, *ok;
    pid_t scoreboard_pid;
    time_t scoreboard_uptime;
    pr_scoreboard_entry_t *score;

    res = pr_set_scoreboard(path);
    fail_unless(res == 0, "Failed set to scoreboard to '%s': %s", path,
      strerror(errno));

    ok = PR_RUN_DIR "/proftpd.scoreboard";

    path = pr_get_scoreboard();
    fail_unless(path != NULL, "Failed to get scoreboard path: %s",
      strerror(errno));
    fail_unless(strcmp(path, ok) == 0,
      "Expected path '%s', got '%s'", ok, path);

    res = pr_open_scoreboard(O_RDONLY);
    fail_unless(res == 0, "Failed to open '%s' scoreboard: %s", path,
      strerror(errno));

    res = pr_scoreboard_scrub();
    fail_unless(res == 0, "Failed to scrub '%s' scoreboard: %s", path,
      strerror(errno));

    scoreboard_pid = pr_scoreboard_get_daemon_pid();
    fail_unless(scoreboard_pid == 0,
      "Expected to get scoreboard PID 0, got %lu",
      (unsigned long) scoreboard_pid);

    scoreboard_uptime = pr_scoreboard_get_daemon_uptime();
    fail_unless(scoreboard_uptime == 0,
      "Expected to get scoreboard uptime 0, got %lu",
      (unsigned long) scoreboard_uptime);

    res = pr_scoreboard_entry_add();
    fail_unless(res == 0, "Failed to add entry to '%s' scoreboard: %s", path,
      strerror(errno));

    score = pr_scoreboard_entry_read();
    fail_unless(score == NULL, "Expected null entry");

    field = pr_scoreboard_entry_get(PR_SCORE_CMD_ARG);
    fail_unless(field == NULL, "Expected null CMD_ARG field");

    res = pr_scoreboard_entry_update(getpid(), PR_SCORE_CWD, "foo", NULL);
    fail_unless(res == 0, "Failed to update CWD field: %s", strerror(errno));

    res = pr_scoreboard_entry_del(FALSE);
    fail_unless(res == 0, "Failed to delete entry from '%s' scoreboard: %s",
      path, strerror(errno));

    res = pr_close_scoreboard(FALSE);
    fail_unless(res == 0, "Failed to close '%s' scoreboard: %s", path,
      strerror(errno));

    /* Internal hack: even calling pr_set_scoreboard() with a NULL
     * argument will set the Scoreboard API internal flag back to true.
     */
    pr_set_scoreboard(NULL);
  }
}