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; }
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; }
/** * * 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; }
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; }
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; }
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; } }
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; }
gboolean affile_open_file(gchar *name, FileOpenOptions *open_opts, FilePermOptions *perm_opts, gint *fd) { cap_t saved_caps; if (_path_is_spurious(name, spurious_paths)) { msg_error("Spurious path, logfile not created", evt_tag_str("path", name), NULL); return FALSE; } saved_caps = g_process_cap_save(); if (!_obtain_capabilities(name, open_opts, perm_opts, &saved_caps)) { g_process_cap_restore(saved_caps); return FALSE; } _validate_file_type(name, open_opts); *fd = _open_fd(name, open_opts, perm_opts); if (!is_file_device(name)) _set_fd_permission(perm_opts, *fd); 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); }
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; }