Example #1
0
void
vsf_sysdep_adopt_capabilities(unsigned int caps)
{
  /* n.b. yes I know I should be using libcap!! */
  int retval;
  struct __user_cap_header_struct cap_head;
  struct __user_cap_data_struct cap_data;
  __u32 cap_mask = 0;
  if (!caps)
  {
    bug("asked to adopt no capabilities");
  }
  vsf_sysutil_memclr(&cap_head, sizeof(cap_head));
  vsf_sysutil_memclr(&cap_data, sizeof(cap_data));
  cap_head.version = _LINUX_CAPABILITY_VERSION;
  cap_head.pid = 0;
  if (caps & kCapabilityCAP_CHOWN)
  {
    cap_mask |= (1 << CAP_CHOWN);
  }
  if (caps & kCapabilityCAP_NET_BIND_SERVICE)
  {
    cap_mask |= (1 << CAP_NET_BIND_SERVICE);
  }
  cap_data.effective = cap_data.permitted = cap_mask;
  cap_data.inheritable = 0;
  retval = capset(&cap_head, &cap_data);
  if (retval != 0)
  {
    die("capset");
  }
}
Example #2
0
void
vsf_sysutil_setproctitle_internal(const char* p_buf)
{
  struct mystr proctitle_str = INIT_MYSTR;
  unsigned int to_copy;
  if (!s_proctitle_inited)
  {
    bug("vsf_sysutil_setproctitle: not initialized");
  }
  vsf_sysutil_memclr(s_p_proctitle, s_proctitle_space);
  if (s_proctitle_space < 32)
  {
    return;
  }
  str_alloc_text(&proctitle_str, "vsftpd: ");
  str_append_text(&proctitle_str, p_buf);
  to_copy = str_getlen(&proctitle_str);
  if (to_copy > s_proctitle_space - 1)
  {
    to_copy = s_proctitle_space - 1;
  }
  vsf_sysutil_memcpy(s_p_proctitle, str_getbuf(&proctitle_str), to_copy);
  str_free(&proctitle_str);
  s_p_proctitle[to_copy] = '\0';
}
Example #3
0
void
vsf_sysutil_setproctitle_init(int argc, const char* argv[])
{
  int i;
  char** p_env = environ;
  if (s_proctitle_inited)
  {
    bug("vsf_sysutil_setproctitle_init called twice");
  }
  s_proctitle_inited = 1;
  if (argv[0] == 0)
  {
    die("no argv[0] in vsf_sysutil_setproctitle_init");
  }
  for (i=0; i<argc; i++)
  {
    s_proctitle_space += vsf_sysutil_strlen(argv[i]) + 1;
    if (i > 0)
    {
      argv[i] = 0;
    }
  }
  while (*p_env != 0)
  {
    s_proctitle_space += vsf_sysutil_strlen(*p_env) + 1;
    p_env++;
  }
  /* Oops :-) */
  environ = 0;
  s_p_proctitle = (char*) argv[0];
  vsf_sysutil_memclr(s_p_proctitle, s_proctitle_space);
}
Example #4
0
void
vsf_remove_uwtmp(void)
{
  if (!s_uwtmp_inserted)
  {
    return;
  }
  s_uwtmp_inserted = 0;
  s_utent.ut_type = DEAD_PROCESS;
  vsf_sysutil_memclr(s_utent.ut_user, sizeof(s_utent.ut_user));
  vsf_sysutil_memclr(s_utent.ut_host, sizeof(s_utent.ut_host));
  s_utent.ut_tv.tv_sec = 0;
  setutxent();
  (void) pututxline(&s_utent);
  endutxent();
  s_utent.ut_tv.tv_sec = vsf_sysutil_get_time_sec();
  updwtmpx(WTMPX_FILE, &s_utent);
}
Example #5
0
struct hash*
hash_alloc(unsigned int buckets, unsigned int key_size,
           unsigned int value_size, hashfunc_t hash_func)
{
  unsigned int size;
  struct hash* p_hash = vsf_sysutil_malloc(sizeof(*p_hash));
  p_hash->buckets = buckets;
  p_hash->key_size = key_size;
  p_hash->value_size = value_size;
  p_hash->hash_func = hash_func;
  size = sizeof(struct hash_node*) * buckets;
  p_hash->p_nodes = vsf_sysutil_malloc(size);
  vsf_sysutil_memclr(p_hash->p_nodes, size);
  return p_hash;
}
Example #6
0
static int do_sendfile(const int out_fd, const int in_fd,
                       unsigned int num_send, filesize_t start_pos)
{
  /* Probably should one day be shared with instance in ftpdataio.c */
  static char* p_recvbuf;
  unsigned int total_written = 0;
  int retval;
  enum EVSFSysUtilError error;
  (void) start_pos;
  (void) error;
#if defined(VSF_SYSDEP_HAVE_LINUX_SENDFILE) || \
    defined(VSF_SYSDEP_HAVE_FREEBSD_SENDFILE) || \
    defined(VSF_SYSDEP_HAVE_HPUX_SENDFILE) || \
    defined(VSF_SYSDEP_HAVE_AIX_SENDFILE) || \
    defined(VSF_SYSDEP_HAVE_SOLARIS_SENDFILE)
  if (tunable_use_sendfile)
  {
    static int s_sendfile_checked;
    static int s_runtime_sendfile_works;
    if (!s_sendfile_checked || s_runtime_sendfile_works)
    {
      do
      {
  #ifdef VSF_SYSDEP_HAVE_LINUX_SENDFILE
        retval = sendfile(out_fd, in_fd, NULL, num_send);
  #elif defined(VSF_SYSDEP_HAVE_FREEBSD_SENDFILE)
        {
          /* XXX - start_pos will truncate on 32-bit machines - can we
           * say "start from current pos"?
           */
          off_t written = 0;
          retval = sendfile(in_fd, out_fd, start_pos, num_send, NULL,
                            &written, 0);
          /* Translate to Linux-like retval */
          if (written > 0)
          {
            retval = (int) written;
          }
        }
  #elif defined(VSF_SYSDEP_HAVE_SOLARIS_SENDFILE)
        {
          size_t written = 0;
          struct sendfilevec the_vec;
          vsf_sysutil_memclr(&the_vec, sizeof(the_vec));
          the_vec.sfv_fd = in_fd;
          the_vec.sfv_off = start_pos;
          the_vec.sfv_len = num_send;
          retval = sendfilev(out_fd, &the_vec, 1, &written);
          /* Translate to Linux-like retval */
          if (written > 0)
          {
            retval = (int) written;
          }
        }
  #elif defined(VSF_SYSDEP_HAVE_AIX_SENDFILE)
        {
          struct sf_parms sf_iobuf;
          vsf_sysutil_memclr(&sf_iobuf, sizeof(sf_iobuf));
          sf_iobuf.header_data = NULL;
          sf_iobuf.header_length = 0;
          sf_iobuf.trailer_data = NULL;
          sf_iobuf.trailer_length = 0;
          sf_iobuf.file_descriptor = in_fd;
          sf_iobuf.file_offset = start_pos;
          sf_iobuf.file_bytes = num_send;

          retval = send_file((int*)&out_fd, &sf_iobuf, 0);
          if (retval >= 0)
          {
            retval = sf_iobuf.bytes_sent;
          }
        }
  #else /* must be VSF_SYSDEP_HAVE_HPUX_SENDFILE */
        {
          retval = sendfile(out_fd, in_fd, start_pos, num_send, NULL, 0);
        }
  #endif /* VSF_SYSDEP_HAVE_LINUX_SENDFILE */
        error = vsf_sysutil_get_error();
        vsf_sysutil_check_pending_actions(kVSFSysUtilIO, retval, out_fd);
      }
      while (vsf_sysutil_retval_is_error(retval) &&
             error == kVSFSysUtilErrINTR);
      if (!s_sendfile_checked)
      {
        s_sendfile_checked = 1;
        if (!vsf_sysutil_retval_is_error(retval) ||
            error != kVSFSysUtilErrNOSYS)
        {
          s_runtime_sendfile_works = 1;
        }
      }
      if (!vsf_sysutil_retval_is_error(retval))
      {
        return retval;
      }
      if (s_runtime_sendfile_works && error != kVSFSysUtilErrINVAL &&
          error != kVSFSysUtilErrOPNOTSUPP)
      {
        return retval;
      }
      /* Fall thru to normal implementation. We won't check again. NOTE -
       * also falls through if sendfile() is OK but it returns EINVAL. For
       * Linux this means the file was not page cache backed. Original
       * complaint was trying to serve files from an NTFS filesystem!
       */
    }
  }
#endif /* VSF_SYSDEP_HAVE_LINUX_SENDFILE || VSF_SYSDEP_HAVE_FREEBSD_SENDFILE */
  if (p_recvbuf == 0)
  {
    vsf_secbuf_alloc(&p_recvbuf, VSFTP_DATA_BUFSIZE);
  }
  while (1)
  {
    unsigned int num_read;
    unsigned int num_written;
    unsigned int num_read_this_time = VSFTP_DATA_BUFSIZE;
    if (num_read_this_time > num_send)
    {
      num_read_this_time = num_send;
    }
    retval = vsf_sysutil_read(in_fd, p_recvbuf, num_read_this_time);
    if (retval < 0)
    {
      return retval;
    }
    else if (retval == 0)
    {
      return -1;
    }
    num_read = (unsigned int) retval;
    retval = vsf_sysutil_write_loop(out_fd, p_recvbuf, num_read);
    if (retval < 0)
    {
      return retval;
    }
    num_written = (unsigned int) retval;
    total_written += num_written;
    if (num_written != num_read)
    {
      return num_written;
    }
    if (num_written > num_send)
    {
      bug("num_written bigger than num_send in do_sendfile");
    }
    num_send -= num_written;
    if (num_send == 0)
    {
      /* Bingo! */
      return total_written;
    }
  }
}