示例#1
0
/**
 *
 * This function receives a complete path (directory + filename) and creates
 * the directory portion if it does not exist. The point is that the caller
 * wants to ensure that the given filename can be opened after this function
 * returns. (at least it won't fail because of missing directories).
 **/
gboolean
create_containing_directory(gchar *name, gint dir_uid, gint dir_gid, gint dir_mode)
{
  gchar *dirname;
  struct stat st;
  gint rc;
  gchar *p;
  cap_t saved_caps;
  
  /* check that the directory exists */
  dirname = g_path_get_dirname(name);
  rc = stat(dirname, &st);
  g_free(dirname);
  
  if (rc == 0)
    {
      /* directory already exists */
      return TRUE;
    }
  else if (rc < 0 && errno != ENOENT)
    {
      /* some real error occurred */
      return FALSE;
    }
    
  /* directory does not exist */
  p = name + 1;
  
  p = strchr(p, '/');
  while (p) 
    {
      *p = 0;
      if (stat(name, &st) == 0) 
        {
          if (!S_ISDIR(st.st_mode))
            return FALSE;
        }
      else if (errno == ENOENT) 
        {
          if (mkdir(name, dir_mode < 0 ? 0700 : (mode_t) dir_mode) == -1)
            return FALSE;
          saved_caps = g_process_cap_save();
          g_process_cap_modify(CAP_CHOWN, TRUE);
          g_process_cap_modify(CAP_FOWNER, TRUE);
          set_permissions(name, dir_uid, dir_gid, dir_mode);
          g_process_cap_restore(saved_caps);
        }
      *p = '/';
      p = strchr(p + 1, '/');
    }
  return TRUE;
}
示例#2
0
static gboolean
afunix_sd_apply_perms_to_socket(AFUnixSourceDriver *self)
{
  cap_t saved_caps;

  saved_caps = g_process_cap_save();
  g_process_cap_modify(CAP_CHOWN, TRUE);
  g_process_cap_modify(CAP_FOWNER, TRUE);
  g_process_cap_modify(CAP_DAC_OVERRIDE, TRUE);
  file_perm_options_apply_file(&self->file_perm_options, self->filename);
  g_process_cap_restore(saved_caps);
  return TRUE;
}
示例#3
0
static inline void
_set_fd_permission(FilePermOptions *perm_opts, int fd)
{
  if (fd != -1)
    {
      g_fd_set_cloexec(fd, TRUE);

      g_process_cap_modify(CAP_CHOWN, TRUE);
      g_process_cap_modify(CAP_FOWNER, TRUE);

      if (perm_opts)
        file_perm_options_apply_fd(perm_opts, fd);
    }
}
示例#4
0
static gboolean
transport_mapper_privileged_bind(gint sock, GSockAddr *bind_addr)
{
  cap_t saved_caps;
  GIOStatus status;

  saved_caps = g_process_cap_save();
  g_process_cap_modify(CAP_NET_BIND_SERVICE, TRUE);
  g_process_cap_modify(CAP_DAC_OVERRIDE, TRUE);

  status = g_bind(sock, bind_addr);

  g_process_cap_restore(saved_caps);
  return status == G_IO_STATUS_NORMAL;
}
示例#5
0
static gboolean
afinet_dd_init(LogPipe *s)
{
  AFInetDestDriver *self G_GNUC_UNUSED = (AFInetDestDriver *) s;
  gboolean success;

  success = afsocket_dd_init(s);
#if ENABLE_SPOOF_SOURCE
  if (success)
    {
      if (self->spoof_source && !self->lnet_ctx)
        {
          gchar error[LIBNET_ERRBUF_SIZE];
          cap_t saved_caps;

          saved_caps = g_process_cap_save();
          g_process_cap_modify(CAP_NET_RAW, TRUE);
          self->lnet_ctx = libnet_init(self->super.dest_addr->sa.sa_family == AF_INET ? LIBNET_RAW4 : LIBNET_RAW6, NULL, error);
          g_process_cap_restore(saved_caps);
          if (!self->lnet_ctx)
            {
              msg_error("Error initializing raw socket, spoof-source support disabled",
                        evt_tag_str("error", NULL),
                        NULL);
            }
        }
    }
#endif

  return success;
}
示例#6
0
static gboolean
afsocket_open_socket(GSockAddr *bind_addr, int stream_or_dgram, int *fd)
{
  gint sock;

  if (stream_or_dgram)
    sock = socket(bind_addr->sa.sa_family, SOCK_STREAM, 0);
  else
    sock = socket(bind_addr->sa.sa_family, SOCK_DGRAM, 0);

  if (sock != -1)
    {
      cap_t saved_caps;

      g_fd_set_nonblock(sock, TRUE);
      g_fd_set_cloexec(sock, TRUE);
      saved_caps = g_process_cap_save();
      g_process_cap_modify(CAP_NET_BIND_SERVICE, TRUE);
      g_process_cap_modify(CAP_DAC_OVERRIDE, TRUE);
      if (g_bind(sock, bind_addr) != G_IO_STATUS_NORMAL)
        {
          gchar buf[256];

          g_process_cap_restore(saved_caps);
          msg_error("Error binding socket",
                    evt_tag_str("addr", g_sockaddr_format(bind_addr, buf, sizeof(buf), GSA_FULL)),
                    evt_tag_errno(EVT_TAG_OSERROR, errno),
                    NULL);
          close(sock);
          return FALSE;
        }
      g_process_cap_restore(saved_caps);

      *fd = sock;
      return TRUE;
    }
  else
    {
      msg_error("Error creating socket",
                evt_tag_errno(EVT_TAG_OSERROR, errno),
                NULL);
      return FALSE;
    }
}
示例#7
0
static gboolean
afinet_dd_init(LogPipe *s)
{
  AFInetDestDriver *self G_GNUC_UNUSED = (AFInetDestDriver *) s;

#if ENABLE_SPOOF_SOURCE
  if (self->spoof_source)
    self->super.connections_kept_alive_accross_reloads = TRUE;
#endif

  if (!afsocket_dd_init(s))
    return FALSE;

#if ENABLE_SPOOF_SOURCE
  if (self->super.transport_mapper->sock_type == SOCK_DGRAM)
    {
      if (self->spoof_source && !self->lnet_ctx)
        {
          gchar error[LIBNET_ERRBUF_SIZE];
          cap_t saved_caps;

          saved_caps = g_process_cap_save();
          g_process_cap_modify(CAP_NET_RAW, TRUE);
          self->lnet_ctx = libnet_init(self->super.bind_addr->sa.sa_family == AF_INET ? LIBNET_RAW4 : LIBNET_RAW6, NULL, error);
          g_process_cap_restore(saved_caps);
          if (!self->lnet_ctx)
            {
              msg_error("Error initializing raw socket, spoof-source support disabled",
                        evt_tag_str("error", NULL),
                        NULL);
            }
        }
    }
#endif

#if BUILD_WITH_SSL
  if (!self->tls_context && afinet_dd_is_tls_required(self))
    {
      msg_error("transport(tls) was specified, but tls() options missing",
                evt_tag_str("id", self->super.super.super.id),
                NULL);
      return FALSE;
    }
  else if (self->tls_context && !afinet_dd_is_tls_allowed(self))
    {
      msg_error("tls() options specified for a transport that doesn't allow TLS encryption",
                evt_tag_str("id", self->super.super.super.id),
                evt_tag_str("transport", self->super.transport_mapper->transport),
                NULL);
      return FALSE;
    }
#endif

  return TRUE;
}
示例#8
0
static inline gboolean
_obtain_capabilities(gchar *name, FileOpenOptions *open_opts, FilePermOptions *perm_opts, cap_t *act_caps)
{
  if (open_opts->needs_privileges)
    {
      g_process_cap_modify(CAP_DAC_READ_SEARCH, TRUE);
      g_process_cap_modify(CAP_SYSLOG, TRUE);
    }
  else
    {
      g_process_cap_modify(CAP_DAC_OVERRIDE, TRUE);
    }

  if (open_opts->create_dirs && perm_opts &&
      !file_perm_options_create_containing_directory(perm_opts, name))
    {
      return FALSE;
    }

  return TRUE;
}
示例#9
0
static gboolean
afinet_dd_init(LogPipe *s)
{
  AFInetDestDriver *self G_GNUC_UNUSED = (AFInetDestDriver *) s;

#if SYSLOG_NG_ENABLE_SPOOF_SOURCE
  if (self->spoof_source)
    self->super.connections_kept_alive_accross_reloads = TRUE;
#endif

  if (!afsocket_dd_init(s))
    return FALSE;

#if SYSLOG_NG_ENABLE_SPOOF_SOURCE
  if (self->super.transport_mapper->sock_type == SOCK_DGRAM)
    {
      if (self->spoof_source && !self->lnet_ctx)
        {
          gchar error[LIBNET_ERRBUF_SIZE];
          cap_t saved_caps;

          saved_caps = g_process_cap_save();
          g_process_cap_modify(CAP_NET_RAW, TRUE);
          self->lnet_ctx = libnet_init(self->super.bind_addr->sa.sa_family == AF_INET ? LIBNET_RAW4 : LIBNET_RAW6, NULL, error);
          g_process_cap_restore(saved_caps);
          if (!self->lnet_ctx)
            {
              msg_error("Error initializing raw socket, spoof-source support disabled",
                        evt_tag_str("error", NULL),
                        NULL);
            }
        }
    }
#endif

  return TRUE;
}
示例#10
0
  static gboolean
affile_open_file(gchar *name, gint flags,
    gint uid, gint gid, gint mode,
    gint dir_uid, gint dir_gid, gint dir_mode,
    gboolean create_dirs, gboolean privileged, gboolean is_pipe, gint *fd)
{
  cap_t saved_caps;
  struct stat st;

  if (strstr(name, "../") || strstr(name, "/..")) 
  {
    msg_error("Spurious path, logfile not created",
        evt_tag_str("path", name),
        NULL);
    return FALSE;
  }

  if (create_dirs && !create_containing_directory(name, dir_uid, dir_gid, dir_mode))
    return FALSE;

  saved_caps = g_process_cap_save();
  if (privileged)
  {
    g_process_cap_modify(CAP_DAC_READ_SEARCH, TRUE);
    g_process_cap_modify(CAP_SYS_ADMIN, TRUE);
  }
  *fd = -1;
  if (stat(name, &st) >= 0)
  {
    if (is_pipe && !S_ISFIFO(st.st_mode))
    {
      msg_warning("WARNING: you are using the pipe driver, underlying file is not a FIFO, it should be used by file()",
          evt_tag_str("filename", name),
          NULL);
    }
    else if (!is_pipe && S_ISFIFO(st.st_mode))
    {
      msg_warning("WARNING: you are using the file driver, underlying file is a FIFO, it should be used by pipe()",
          evt_tag_str("filename", name),
          NULL);
    }
  }
  *fd = open(name, flags, mode);

  if (is_pipe && *fd < 0 && errno == ENOENT)
  {
    if (mkfifo(name, 0666) >= 0)
      *fd = open(name, flags, 0666);
  }

  if (*fd != -1)
  {
    g_fd_set_cloexec(*fd, TRUE);

    g_process_cap_modify(CAP_CHOWN, TRUE);
    g_process_cap_modify(CAP_FOWNER, TRUE);
    if (uid >= 0)
      fchown(*fd, (uid_t) uid, -1);
    if (gid >= 0)
      fchown(*fd, -1, (gid_t) gid);
    if (mode >= 0)
      fchmod(*fd, (mode_t) mode);
  }
  g_process_cap_restore(saved_caps);
  msg_trace("affile_open_file",
      evt_tag_str("path", name),
      evt_tag_int("fd",*fd),
      NULL);

  return *fd != -1;
}