Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changes-entries/systemd-selinux.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*) mod_systemd: Log the SELinux context at startup if available and
enabled. [Joe Orton]
3 changes: 3 additions & 0 deletions changes-entries/systemd_socket_activation.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
*) mod_systemd: Systemd socket activation can now be enabled at
build time but disabled at run time, if mod_systemd is not
loaded. [Lubos Uhliarik <luhliari redhat.com>]
10 changes: 10 additions & 0 deletions include/ap_listen.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "apr_network_io.h"
#include "httpd.h"
#include "http_config.h"
#include "apr_optional.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -143,6 +144,15 @@ AP_DECLARE_NONSTD(const char *) ap_set_receive_buffer_size(cmd_parms *cmd,
void *dummy,
const char *arg);

#ifdef HAVE_SYSTEMD
APR_DECLARE_OPTIONAL_FN(int,
ap_find_systemd_socket, (process_rec *, apr_port_t));

APR_DECLARE_OPTIONAL_FN(int,
ap_systemd_listen_fds, (int));
#endif


#define LISTEN_COMMANDS \
AP_INIT_TAKE1("ListenBacklog", ap_set_listenbacklog, NULL, RSRC_CONF, \
"Maximum length of the queue of pending connections, as used by listen(2)"), \
Expand Down
5 changes: 5 additions & 0 deletions modules/arch/unix/config5.m4
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ APACHE_MODULE(systemd, Systemd support, , , no, [
AC_MSG_WARN([Your system does not support systemd.])
enable_systemd="no"
else
AC_CHECK_LIB(selinux, is_selinux_enabled, [
AC_DEFINE(HAVE_SELINUX, 1, [Defined if SELinux is supported])
APR_ADDTO(MOD_SYSTEMD_LDADD, [-lselinux])
])

APR_ADDTO(MOD_SYSTEMD_LDADD, [$SYSTEMD_LIBS])
fi
])
Expand Down
62 changes: 61 additions & 1 deletion modules/arch/unix/mod_systemd.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <stdint.h>
#include <ap_config.h>
#include "ap_mpm.h"
#include "ap_listen.h"
#include <http_core.h>
#include <httpd.h>
#include <http_log.h>
Expand All @@ -28,6 +29,10 @@
#include "scoreboard.h"
#include "mpm_common.h"

#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
#endif

#include "systemd/sd-daemon.h"

#if APR_HAVE_UNISTD_H
Expand All @@ -44,16 +49,37 @@ static int systemd_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
return OK;
}

#ifdef HAVE_SELINUX
static void log_selinux_context(void)
{
char *con;

if (is_selinux_enabled() && getcon(&con) == 0) {
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL,
APLOGNO(10497) "SELinux is enabled; "
"httpd running as context %s", con);
freecon(con);
}
}
#endif

/* Report the service is ready in post_config, which could be during
* startup or after a reload. The server could still hit a fatal
* startup error after this point during ap_run_mpm(), so this is
* perhaps too early, but by post_config listen() has been called on
* the TCP ports so new connections will not be rejected. There will
* always be a possible async failure event simultaneous to the
* service reporting "ready", so this should be good enough. */
static int systemd_post_config(apr_pool_t *p, apr_pool_t *plog,
static int systemd_post_config(apr_pool_t *pconf, apr_pool_t *plog,
apr_pool_t *ptemp, server_rec *main_server)
{
if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
return OK;

#ifdef HAVE_SELINUX
log_selinux_context();
#endif

sd_notify(0, "READY=1\n"
"STATUS=Configuration loaded.\n");
return OK;
Expand Down Expand Up @@ -96,8 +122,42 @@ static int systemd_monitor(apr_pool_t *p, server_rec *s)
return DECLINED;
}

static int ap_find_systemd_socket(process_rec * process, apr_port_t port) {
int fdcount, fd;
int sdc = sd_listen_fds(0);

if (sdc < 0) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02486)
"find_systemd_socket: Error parsing enviroment, sd_listen_fds returned %d",
sdc);
return -1;
}

if (sdc == 0) {
ap_log_perror(APLOG_MARK, APLOG_CRIT, sdc, process->pool, APLOGNO(02487)
"find_systemd_socket: At least one socket must be set.");
return -1;
}

fdcount = atoi(getenv("LISTEN_FDS"));
for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + fdcount; fd++) {
if (sd_is_socket_inet(fd, 0, 0, -1, port) > 0) {
return fd;
}
}

return -1;
}

static int ap_systemd_listen_fds(int unset_environment){
return sd_listen_fds(unset_environment);
}

static void systemd_register_hooks(apr_pool_t *p)
{
APR_REGISTER_OPTIONAL_FN(ap_systemd_listen_fds);
APR_REGISTER_OPTIONAL_FN(ap_find_systemd_socket);

/* Enable ap_extended_status. */
ap_hook_pre_config(systemd_pre_config, NULL, NULL, APR_HOOK_LAST);
/* Signal service is ready. */
Expand Down
Loading
Loading