Example #1
0
static void
handle_mdtm(struct vsf_session* p_sess)
{
  static struct vsf_sysutil_statbuf* s_p_statbuf;
  int retval;
  if (!vsf_access_check_file(&p_sess->ftp_arg_str))
  {
    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");
    return;
  }
  retval = str_stat(&p_sess->ftp_arg_str, &s_p_statbuf);
  if (retval != 0 || !vsf_sysutil_statbuf_is_regfile(s_p_statbuf))
  {
    vsf_cmdio_write(p_sess, FTP_FILEFAIL,
                    "Could not get file modification time.");
  }
  else
  {
    static struct mystr s_mdtm_res_str;
    str_alloc_text(&s_mdtm_res_str,
                   vsf_sysutil_statbuf_get_numeric_date(
                     s_p_statbuf, tunable_use_localtime));
    vsf_cmdio_write_str(p_sess, FTP_MDTMOK, &s_mdtm_res_str);
  }
}
Example #2
0
static void
handle_size(struct vsf_session* p_sess)
{
  /* Note - in ASCII mode, are supposed to return the size after taking into
   * account ASCII linefeed conversions. At least this is what wu-ftpd does in
   * version 2.6.1. Proftpd-1.2.0pre fails to do this.
   * I will not do it because it is a potential I/O DoS.
   */
  static struct vsf_sysutil_statbuf* s_p_statbuf;
  int retval;
  if (!vsf_access_check_file(&p_sess->ftp_arg_str))
  {
    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");
    return;
  }
  retval = str_stat(&p_sess->ftp_arg_str, &s_p_statbuf);
  if (retval != 0 || !vsf_sysutil_statbuf_is_regfile(s_p_statbuf))
  {
    vsf_cmdio_write(p_sess, FTP_FILEFAIL, "Could not get file size.");
  }
  else
  {
    static struct mystr s_size_res_str;
    str_alloc_filesize_t(&s_size_res_str,
                         vsf_sysutil_statbuf_get_size(s_p_statbuf));
    vsf_cmdio_write_str(p_sess, FTP_SIZEOK, &s_size_res_str);
  }
}
Example #3
0
static void
handle_rnfr(struct vsf_session* p_sess)
{
  static struct vsf_sysutil_statbuf* p_statbuf;
  int retval;
  /* Clear old value */
  str_free(&p_sess->rnfr_filename_str);
  if (!vsf_access_check_file(&p_sess->ftp_arg_str))
  {
    vsf_cmdio_write(p_sess, FTP_NOPERM, "Permission denied.");
    return;
  }
  /* Does it exist? */
  retval = str_stat(&p_sess->ftp_arg_str, &p_statbuf);
  if (retval == 0)
  {
    /* Yes */
    str_copy(&p_sess->rnfr_filename_str, &p_sess->ftp_arg_str);
    vsf_cmdio_write(p_sess, FTP_RNFROK, "Ready for RNTO.");
  }
  else
  {
    vsf_cmdio_write(p_sess, FTP_FILEFAIL, "RNFR command failed.");
  }
}
static void
handle_per_user_config(const struct mystr* p_user_str)
{
  struct mystr filename_str = INIT_MYSTR;
  struct vsf_sysutil_statbuf* p_statbuf = 0;
  struct str_locate_result loc_result;
  int retval;
  if (!tunable_user_config_dir)
  {
    return;
  }
  /* Security paranoia - ignore if user has a / in it. */
  loc_result = str_locate_char(p_user_str, '/');
  if (loc_result.found)
  {
    return;
  }
  str_alloc_text(&filename_str, tunable_user_config_dir);
  str_append_char(&filename_str, '/');
  str_append_str(&filename_str, p_user_str);
  retval = str_stat(&filename_str, &p_statbuf);
  if (!vsf_sysutil_retval_is_error(retval))
  {
    /* Security - file ownership check now in vsf_parseconf_load_file() */
    vsf_parseconf_load_file(str_getbuf(&filename_str), 1);
  }
  else if (vsf_sysutil_get_error() != kVSFSysUtilErrNOENT)
  {
    die("error opening per-user config file");
  }
  str_free(&filename_str);
  vsf_sysutil_free(p_statbuf);
}
Example #5
0
static void
handle_per_user_config(const struct mystr* p_user_str)
{
  struct mystr filename_str = INIT_MYSTR;
  struct vsf_sysutil_statbuf* p_statbuf = 0;
  struct str_locate_result loc_result;
  int retval;
  if (!tunable_user_config_dir)
  {
    return;
  }
  /* Security paranoia - ignore if user has a / in it. */
  loc_result = str_locate_char(p_user_str, '/');
  if (loc_result.found)
  {
    return;
  }
  str_alloc_text(&filename_str, tunable_user_config_dir);
  str_append_char(&filename_str, '/');
  str_append_str(&filename_str, p_user_str);
  retval = str_stat(&filename_str, &p_statbuf);
  /* Security - ignore unless owned by root */
  if (!vsf_sysutil_retval_is_error(retval) &&
      vsf_sysutil_statbuf_get_uid(p_statbuf) == VSFTP_ROOT_UID)
  {
    vsf_parseconf_load_file(str_getbuf(&filename_str), 1);
  }
  str_free(&filename_str);
  vsf_sysutil_free(p_statbuf);
}
Example #6
0
static void
get_unique_filename(struct mystr* p_outstr, const struct mystr* p_base_str)
{
  /* Use silly wu-ftpd algorithm for compatibility */
  static struct vsf_sysutil_statbuf* s_p_statbuf;
  unsigned int suffix = 1;
  int retval;
  while (1)
  {
    str_copy(p_outstr, p_base_str);
    str_append_char(p_outstr, '.');
    str_append_ulong(p_outstr, suffix);
    retval = str_stat(p_outstr, &s_p_statbuf);
    if (vsf_sysutil_retval_is_error(retval))
    {
      return;
    }
    ++suffix;
  }
}
Example #7
0
static void
handle_per_user_config(const struct mystr* p_user_str)
{
  if (tunable_user_config_dir)
  {
    struct mystr filename_str = INIT_MYSTR;
    struct vsf_sysutil_statbuf* p_statbuf = 0;
    int retval;
    str_alloc_text(&filename_str, tunable_user_config_dir);
    str_append_char(&filename_str, '/');
    str_append_str(&filename_str, p_user_str);
    retval = str_stat(&filename_str, &p_statbuf);
    /* Security - ignore unless owned by root */
    if (!vsf_sysutil_retval_is_error(retval) &&
        vsf_sysutil_statbuf_get_uid(p_statbuf) == VSFTP_ROOT_UID)
    {
      vsf_parseconf_load_file(str_getbuf(&filename_str));
    }
    str_free(&filename_str);
    vsf_sysutil_free(p_statbuf);
  }
}