コード例 #1
0
ファイル: affile.c プロジェクト: kkcloudy/daemongroup
/*
 * Copyright (c) 2002, 2003, 2004 BalaBit IT Ltd, Budapest, Hungary
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published
 * by the Free Software Foundation.
 *
 * Note that this permission is granted for only version 2 of the GPL.
 *
 * As an additional exemption you are allowed to compile & link against the
 * OpenSSL libraries as published by the OpenSSL project. See the file
 * COPYING for details.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include "affile.h"
#include "driver.h"
#include "messages.h"
#include "macros.h"
#include "misc.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <stdlib.h>
#include <stdio.h>

#if !HAVE_O_LARGEFILE
#define O_LARGEFILE 0
#endif

#if 0/*start dongshu*/
static gboolean
affile_open_file(gchar *name, int flags,
	     int uid, int gid, int mode,
	     int dir_uid, int dir_gid, int dir_mode,
	     int create_dirs, int *fd)
{
  if (strstr(name, "../") || strstr(name, "/..")) 
    {
      msg_error("Spurious path, logfile not created",
                evt_tag_str("path", name),
                NULL);
      return FALSE;
    }

  *fd = open(name, flags, mode);
  if (create_dirs && *fd == -1 && errno == ENOENT) 
    {
      /* directory does not exist */
      char *p = name + 1;
      
      p = strchr(p, '/');
      while (p) 
	{
	  struct stat st;
	  *p = 0;
	  if (stat(name, &st) == 0) 
	    {
	      if (!S_ISDIR(st.st_mode))
		return FALSE;
	    }
	  else if (errno == ENOENT) 
	    {
	      if (mkdir(name, dir_mode) == -1)
		return 0;
	      if (dir_uid != -1 || dir_gid != -1)
		chown(name, dir_uid, dir_gid);
	      if (dir_mode != -1)
		/* CID 13888 (#1 of 1): Argument cannot be negative , no problem*/
		/* CID 10351 (#1 of 1): Unchecked return value from library no problem*/
		chmod(name, dir_mode);
	    }
	  *p = '/';
	  p = strchr(p + 1, '/');
	}
      *fd = open(name, flags, mode);
    }
  if (*fd != -1)
    {
      g_fd_set_cloexec(*fd, TRUE);
      if (uid != -1)
        fchown(*fd, uid, -1);
      if (gid != -1)
        fchown(*fd, -1, gid);
      if (mode != -1)
        fchmod(*fd, mode);
    }
  return *fd != -1;
}
コード例 #2
0
ファイル: afsocket-source.c プロジェクト: gyula/syslog-ng-3.5
static void
afsocket_sd_accept(gpointer s)
{
  AFSocketSourceDriver *self = (AFSocketSourceDriver *) s;
  GSockAddr *peer_addr;
  gchar buf1[256], buf2[256];
  gint new_fd;
  gboolean res;
  int accepts = 0;

  while (accepts < MAX_ACCEPTS_AT_A_TIME)
    {
      GIOStatus status;

      status = g_accept(self->fd, &new_fd, &peer_addr);
      if (status == G_IO_STATUS_AGAIN)
        {
          /* no more connections to accept */
          break;
        }
      else if (status != G_IO_STATUS_NORMAL)
        {
          msg_error("Error accepting new connection",
                    evt_tag_errno(EVT_TAG_OSERROR, errno),
                    NULL);
          return;
        }

      g_fd_set_nonblock(new_fd, TRUE);
      g_fd_set_cloexec(new_fd, TRUE);

      res = afsocket_sd_process_connection(self, peer_addr, self->bind_addr, new_fd);

      if (res)
        {
          if (peer_addr->sa.sa_family != AF_UNIX)
            msg_notice("Syslog connection accepted",
                        evt_tag_int("fd", new_fd),
                        evt_tag_str("client", g_sockaddr_format(peer_addr, buf1, sizeof(buf1), GSA_FULL)),
                        evt_tag_str("local", g_sockaddr_format(self->bind_addr, buf2, sizeof(buf2), GSA_FULL)),
                        NULL);
          else
            msg_verbose("Syslog connection accepted",
                        evt_tag_int("fd", new_fd),
                        evt_tag_str("client", g_sockaddr_format(peer_addr, buf1, sizeof(buf1), GSA_FULL)),
                        evt_tag_str("local", g_sockaddr_format(self->bind_addr, buf2, sizeof(buf2), GSA_FULL)),
                        NULL);
        }
      else
        {
          close(new_fd);
        }

      g_sockaddr_unref(peer_addr);
      accepts++;
    }
  return;
}
コード例 #3
0
ファイル: afprog.c プロジェクト: pzoleex/syslog-ng
static gboolean
afprogram_sd_init(LogPipe *s)
{
    AFProgramSourceDriver *self = (AFProgramSourceDriver *) s;
    GlobalConfig *cfg = log_pipe_get_config(s);
    gint fd;

    if (!log_src_driver_init_method(s))
        return FALSE;

    if (cfg)
        log_reader_options_init(&self->reader_options, cfg, self->super.super.group);

    msg_verbose("Starting source program",
                evt_tag_str("cmdline", self->process_info.cmdline->str));

    if (!afprogram_popen(&self->process_info, G_IO_IN, &fd))
        return FALSE;

    /* parent */
    child_manager_register(self->process_info.pid, afprogram_sd_exit, log_pipe_ref(&self->super.super.super),
                           (GDestroyNotify) log_pipe_unref);

    g_fd_set_nonblock(fd, TRUE);
    g_fd_set_cloexec(fd, TRUE);
    if (!self->reader)
    {
        LogTransport *transport;

        transport = log_transport_pipe_new(fd);
        self->reader = log_reader_new(s->cfg);
        log_reader_reopen(self->reader, log_proto_text_server_new(transport, &self->reader_options.proto_options.super),
                          poll_fd_events_new(fd));
        log_reader_set_options(self->reader,
                               s,
                               &self->reader_options,
                               STATS_LEVEL0,
                               SCS_PROGRAM,
                               self->super.super.id,
                               self->process_info.cmdline->str);
    }
    log_pipe_append((LogPipe *) self->reader, &self->super.super.super);
    if (!log_pipe_init((LogPipe *) self->reader))
    {
        msg_error("Error initializing program source, closing fd",
                  evt_tag_int("fd", fd));
        log_pipe_unref((LogPipe *) self->reader);
        self->reader = NULL;
        close(fd);
        return FALSE;
    }
    return TRUE;
}
コード例 #4
0
ファイル: affile-common.c プロジェクト: jbfuzier/syslog-ng
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);
    }
}
コード例 #5
0
ファイル: persist-state.c プロジェクト: Achint08/syslog-ng
static gboolean
_create_store(PersistState *self)
{
  self->fd = open(self->temp_filename, O_RDWR | O_CREAT | O_TRUNC, 0600);
  if (self->fd < 0)
    {
      msg_error("Error creating persistent state file",
                evt_tag_str("filename", self->temp_filename),
                evt_tag_errno("error", errno),
                NULL);
      return FALSE;
    }
  g_fd_set_cloexec(self->fd, TRUE);
  self->current_key_block = offsetof(PersistFileHeader, initial_key_store);
  self->current_key_ofs = 0;
  self->current_key_size = sizeof((((PersistFileHeader *) NULL))->initial_key_store);
  return _grow_store(self, PERSIST_FILE_INITIAL_SIZE);
}
コード例 #6
0
gboolean
transport_mapper_open_socket(TransportMapper *self,
                             SocketOptions *socket_options,
                             GSockAddr *bind_addr,
                             AFSocketDirection dir,
                             int *fd)
{
  gint sock;

  sock = socket(self->address_family, self->sock_type, self->sock_proto);
  if (sock < 0)
    {
      msg_error("Error creating socket",
                evt_tag_errno(EVT_TAG_OSERROR, errno),
                NULL);
      goto error;
    }

  g_fd_set_nonblock(sock, TRUE);
  g_fd_set_cloexec(sock, TRUE);

  if (!transport_mapper_privileged_bind(sock, bind_addr))
    {
      gchar buf[256];

      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);
      goto error_close;
    }

  if (!socket_options_setup_socket(socket_options, sock, bind_addr, dir))
    goto error_close;

  *fd = sock;
  return TRUE;

 error_close:
  close(sock);
 error:
  *fd = -1;
  return FALSE;
}
コード例 #7
0
ファイル: afsocket.c プロジェクト: ndzou/syslog-ng-3.3
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;
    }
}
コード例 #8
0
ファイル: afstreams.c プロジェクト: balabit/syslog-ng-3.3
static void
afstreams_init_door(int hook_type G_GNUC_UNUSED, gpointer user_data)
{
  AFStreamsSourceDriver *self = (AFStreamsSourceDriver *) user_data;
  struct stat st;
  gint fd;

  if (stat(self->door_filename->str, &st) == -1)
    {
      /* file does not exist, create it */
      fd = creat(self->door_filename->str, 0666);
      if (fd == -1)
        {
          msg_error("Error creating syslog door file",
                    evt_tag_str(EVT_TAG_FILENAME, self->door_filename->str),
                    evt_tag_errno(EVT_TAG_OSERROR, errno),
                    NULL);
          close(fd);
          return;
        }
    }
  fdetach(self->door_filename->str);
  self->door_fd = door_create(afstreams_sd_door_server_proc, NULL, 0);
  if (self->door_fd == -1)
    {
      msg_error("Error creating syslog door",
                evt_tag_str(EVT_TAG_FILENAME, self->door_filename->str),
                evt_tag_errno(EVT_TAG_OSERROR, errno),
                NULL);
      return;
    }
  g_fd_set_cloexec(self->door_fd, TRUE);
  if (fattach(self->door_fd, self->door_filename->str) == -1)
    {
      msg_error("Error attaching syslog door",
                evt_tag_str(EVT_TAG_FILENAME, self->door_filename->str),
                evt_tag_errno(EVT_TAG_OSERROR, errno),
                NULL);
      close(self->door_fd);
      self->door_fd = -1;
      return;
    }
}
コード例 #9
0
ファイル: afstreams.c プロジェクト: create-iv/syslog-ng
static gboolean
afstreams_sd_init(LogPipe *s)
{
  AFStreamsSourceDriver *self = (AFStreamsSourceDriver *) s;
  GlobalConfig *cfg = log_pipe_get_config(s);
  gint fd;

  if (!log_src_driver_init_method(s))
    return FALSE;

  log_reader_options_init(&self->reader_options, cfg, self->super.super.group);

  fd = open(self->dev_filename->str, O_RDONLY | O_NOCTTY | O_NONBLOCK);
  if (fd != -1)
    {
      struct strioctl ioc;

      g_fd_set_cloexec(fd, TRUE);
      memset(&ioc, 0, sizeof(ioc));
      ioc.ic_cmd = I_CONSLOG;
      if (ioctl(fd, I_STR, &ioc) < 0)
        {
          msg_error("Error in ioctl(I_STR, I_CONSLOG)",
                    evt_tag_str(EVT_TAG_FILENAME, self->dev_filename->str),
                    evt_tag_errno(EVT_TAG_OSERROR, errno));
          close(fd);
          return FALSE;
        }
      g_fd_set_nonblock(fd, TRUE);
      self->reader = log_reader_new(cfg);
      log_reader_reopen(self->reader, log_proto_dgram_server_new(log_transport_streams_new(fd), &self->reader_options.proto_options.super), poll_fd_events_new(fd));
      log_reader_set_options(self->reader,
                             s,
                             &self->reader_options,
                             STATS_LEVEL1,
                             SCS_SUN_STREAMS,
                             self->super.super.id,
                             self->dev_filename->str);
      log_pipe_append((LogPipe *) self->reader, s);

      if (self->door_filename)
        {

          /* door creation is deferred, because it creates threads which is
           * not inherited through forks, and syslog-ng forks during
           * startup, but _after_ the configuration was initialized */

          register_application_hook(AH_POST_DAEMONIZED, afstreams_init_door, self);
        }
      if (!log_pipe_init((LogPipe *) self->reader))
        {
          msg_error("Error initializing log_reader, closing fd",
                    evt_tag_int("fd", fd));
          log_pipe_unref((LogPipe *) self->reader);
          self->reader = NULL;
          close(fd);
          return FALSE;
        }

    }
  else
    {
      msg_error("Error opening syslog device",
                evt_tag_str(EVT_TAG_FILENAME, self->dev_filename->str),
                evt_tag_errno(EVT_TAG_OSERROR, errno));
      return FALSE;
    }
  return TRUE;
}
コード例 #10
0
ファイル: affile.c プロジェクト: kkcloudy/daemongroup
static gboolean
affile_open_file(gchar *name, int flags,
	     int uid, int gid, int mode,
	     int dir_uid, int dir_gid, int dir_mode,
	     int create_dirs, int *fd, int switch_enable)
{
	int sw_fd;
	
	if (strstr(name, "../") || strstr(name, "/..")) 
	{
		msg_error("Spurious path, logfile not created",
							evt_tag_str("path", name),
							NULL);
		return FALSE;
	}

	if (switch_enable == 0){
		*fd = open(name, flags, mode);
	}
	else{
		affile_open_switch_file(name, flags, mode, &sw_fd, fd);
	}
		
	if (create_dirs && *fd == -1 && errno == ENOENT) /*如果指定目录不存在则创建*/
	{
		/* directory does not exist */
		char *p = name + 1;
		
		p = strchr(p, '/');
		while (p) 
		{
			struct stat st;
			*p = 0;
			if (stat(name, &st) == 0) 
			{
				if (!S_ISDIR(st.st_mode))
					return FALSE;
			}
			else if (errno == ENOENT) 
			{
				if (mkdir(name, dir_mode) == -1)
					return 0;
				if (dir_uid != -1 || dir_gid != -1)
					chown(name, dir_uid, dir_gid);
				if (dir_mode != -1)
					chmod(name, dir_mode);
			}
			*p = '/';
			p = strchr(p + 1, '/');
		}
		if (switch_enable == 0){
			*fd = open(name, flags, mode);
		}
		else{
			affile_open_switch_file(name, flags, mode, &sw_fd, fd);
		}
	}
	if (*fd != -1)
	{
		g_fd_set_cloexec(*fd, TRUE);
		if (uid != -1)
			fchown(*fd, uid, -1);
		if (gid != -1)
			fchown(*fd, -1, gid);
		if (mode != -1)
			fchmod(*fd, mode);
	}
	
	if(switch_enable != 0){
		g_fd_set_cloexec(sw_fd, TRUE);
		if (uid != -1)
			fchown(sw_fd, uid, -1);
		if (gid != -1)
			fchown(sw_fd, -1, gid);
		if (mode != -1)
			fchmod(sw_fd, mode);
		close(sw_fd);
	}
	
	return *fd != -1;
}
コード例 #11
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;
}
コード例 #12
0
ファイル: afunix-source.c プロジェクト: gyula/syslog-ng-3.5
static gboolean
afunix_sd_acquire_named_socket(AFSocketSourceDriver *s, gint *result_fd,
                               const gchar *filename)
{
  AFUnixSourceDriver *self = (AFUnixSourceDriver *) s;
  gint fd, fds;

  *result_fd = -1;
  fd = -1;
  fds = sd_listen_fds(0);

  if (fds == 0)
    return TRUE;

  msg_debug("Systemd socket activation",
	    evt_tag_int("systemd-sockets", fds),
	    evt_tag_str("systemd-listen-pid", getenv("LISTEN_PID")),
	    evt_tag_str("systemd-listen-fds", getenv("LISTEN_FDS")),
	    NULL);

  if (fds < 0)
    {
      msg_error("Failed to acquire systemd sockets, incorrectly set LISTEN_FDS environment variable?",
		NULL);
      return FALSE;
    }
  else if (fds > 0)
    {
      for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fds; fd++)
	{
	  /* check if any type is available */
	  if (sd_is_socket_unix(fd, 0, -1, filename, 0))
	    {
	      /* check if it matches our idea of the socket type */
	      if (sd_is_socket_unix(fd, self->super.transport_mapper->sock_type, -1, filename, 0))
                {
                  *result_fd = fd;
                  break;
                }
              else
                {
                  msg_error("The systemd supplied UNIX domain socket is of a different type, check the configured driver and the matching systemd unit file",
		            evt_tag_str("filename", filename),
		            evt_tag_int("systemd-sock-fd", fd),
			    evt_tag_str("expecting", self->super.transport_mapper->sock_type == SOCK_STREAM ? "unix-stream()" : "unix-dgram()"),
                            NULL);
                  return FALSE;
                }
            }
          else
            {

              /* systemd passed an fd we didn't really care about. This is
               * not an error, but might be worth mentioning it at the debug
               * level.
               */

              msg_debug("Ignoring systemd supplied fd as it is not a UNIX domain socket",
		        evt_tag_str("filename", filename),
		        evt_tag_int("systemd-sock-fd", fd),
		        NULL);
            }
	}
    }

  if (*result_fd != -1)
    {
      g_fd_set_nonblock(*result_fd, TRUE);
      g_fd_set_cloexec(*result_fd, TRUE);
      msg_verbose("Acquired systemd socket",
		  evt_tag_str("filename", filename),
		  evt_tag_int("systemd-sock-fd", *result_fd),
		  NULL);
      return TRUE;
    }
  return TRUE;
}