Skip to content

Commit

Permalink
Support Socket Activation for userproxy mode
Browse files Browse the repository at this point in the history
This way we can provide a user systemd unit that will automatically
starts gssproxy in user mode if someone tries to use the userproxy
socket.

Signed-off-by: Simo Sorce <simo@redhat.com>
  • Loading branch information
simo5 committed May 23, 2022
1 parent 07939ce commit 145c7ce
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ endif
GSS_PROXY_LIBS = $(KRB5_LIBS) $(GSSAPI_LIBS) $(GSSRPC_LIBS)

if BUILD_PROXY
GSS_PROXY_LIBS += $(POPT_LIBS) $(VERTO_LIBS) $(INI_LIBS)
GSS_PROXY_LIBS += $(POPT_LIBS) $(VERTO_LIBS) $(INI_LIBS) $(SYSTEMD_DAEMON_LIBS)

if BUILD_SELINUX
GSS_PROXY_LIBS += $(SELINUX_LIBS)
Expand Down
2 changes: 0 additions & 2 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -165,8 +165,6 @@ if test x$only_gss_module != xyes; then

if test x$initscript = xsystemd; then
WITH_SYSTEMD_UNIT_DIR
fi
if test x$HAVE_SYSTEMD_UNIT != x; then
AM_CHECK_SYSTEMD
fi
fi
Expand Down
26 changes: 22 additions & 4 deletions external/systemd.m4
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
dnl A macro to check presence of systemd on the system
AC_DEFUN([AM_CHECK_SYSTEMD],
[
PKG_CHECK_EXISTS(systemd,
[ HAVE_SYSTEMD=1, AC_SUBST(HAVE_SYSTEMD) ],
[AC_MSG_ERROR([Could not detect systemd presence])]
)
PKG_CHECK_EXISTS([systemd],
[HAVE_SYSTEMD=yes],
[HAVE_SYSTEMD=no])
dnl older system uses libsystemd
PKG_CHECK_EXISTS([libsystemd],
[HAVE_LIBSYSTEMD=yes],
[HAVE_LIBSYSTEMD=no])
dnl newer systemd splits libsystemd in slaler libs
AS_IF([test x$HAVE_LIBSYSTEMD = xyes],
[daemon_lib_name=libsystemd],
[daemon_lib_name=libsystemd-daemon])
AS_IF([test x$HAVE_SYSTEMD = xyes],
[PKG_CHECK_MODULES(
[SYSTEMD_DAEMON],
[$daemon_lib_name],
[AC_DEFINE_UNQUOTED([HAVE_SYSTEMD_DAEMON], 1,
[Build with $daemon_lib_name support])],
[AC_MSG_NOTICE([Build without $daemon_lib_name support])])],
[AC_MSG_NOTICE([Build without $daemon_lib_name support])])
])
4 changes: 4 additions & 0 deletions src/gp_proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,10 @@ int clear_bound_caps(void);

/* from gp_socket.c */
void free_unix_socket(verto_ctx *ctx, verto_ev *ev);
#ifdef HAVE_SYSTEMD_DAEMON
int init_activation_socket(struct gssproxy_ctx *gpctx,
struct gp_sock_ctx **sock_ctx);
#endif
struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx,
const char *file_name);
void accept_sock_conn(verto_ctx *vctx, verto_ev *ev);
Expand Down
53 changes: 53 additions & 0 deletions src/gp_socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
#include <sys/un.h>
#include <unistd.h>

#ifdef HAVE_SYSTEMD_DAEMON
#include <systemd/sd-daemon.h>
#endif

#define FRAGMENT_BIT (1 << 31)

struct unix_sock_conn {
Expand Down Expand Up @@ -171,6 +175,55 @@ void free_unix_socket(verto_ctx *ctx UNUSED, verto_ev *ev)
free(sock_ctx);
}

#ifdef HAVE_SYSTEMD_DAEMON
int init_activation_socket(struct gssproxy_ctx *gpctx,
struct gp_sock_ctx **sock_ctx)
{
int num_fds;
int ret = 0;

num_fds = sd_listen_fds(0);
if (num_fds > 1) {
GPDEBUG("Received too many socket from systemd\n");
ret = E2BIG;
} else if (num_fds == 1) {
struct gp_sock_ctx *_sock_ctx;
int fd = -1;

_sock_ctx = calloc(1, sizeof(struct gp_sock_ctx));
if (!_sock_ctx) {
ret = ENOMEM;
goto done;
}

fd = SD_LISTEN_FDS_START + 0;

ret = set_status_flags(fd, O_NONBLOCK);
if (ret != 0) {
GPDEBUG("Failed to set O_NONBLOCK on %d!\n", fd);
safefree(_sock_ctx);
goto done;
}

ret = set_fd_flags(fd, FD_CLOEXEC);
if (ret != 0) {
GPDEBUG("Failed to set FD_CLOEXEC on %d!\n", fd);
safefree(_sock_ctx);
goto done;
}

_sock_ctx->gpctx = gpctx;
_sock_ctx->socket = "(Activated Socket)";
_sock_ctx->fd = fd;

*sock_ctx = _sock_ctx;
}

done:
return ret;
}
#endif

struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx,
const char *file_name)
{
Expand Down
46 changes: 39 additions & 7 deletions src/gssproxy.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,26 @@ find_service_by_name(struct gp_config *cfg, const char *name)
return ret;
}

static verto_ev *setup_socket(char *sock_name, verto_ctx *vctx)
static verto_ev *setup_socket(char *sock_name, verto_ctx *vctx,
bool with_activation)
{
struct gp_sock_ctx *sock_ctx;
struct gp_sock_ctx *sock_ctx = NULL;
verto_ev *ev;

sock_ctx = init_unix_socket(gpctx, sock_name);
#ifdef HAVE_SYSTEMD_DAEMON
if (with_activation) {
int ret;
/* try to se if available, fallback otherwise */
ret = init_activation_socket(gpctx, &sock_ctx);
if (ret) {
return NULL;
}
}
#endif
if (!sock_ctx) {
/* no activation, try regular socket creation */
sock_ctx = init_unix_socket(gpctx, sock_name);
}
if (!sock_ctx) {
return NULL;
}
Expand All @@ -65,15 +79,15 @@ static int init_sockets(verto_ctx *vctx, struct gp_config *old_config)

/* init main socket */
if (!old_config) {
ev = setup_socket(gpctx->config->socket_name, vctx);
ev = setup_socket(gpctx->config->socket_name, vctx, false);
if (!ev) {
return 1;
}

gpctx->sock_ev = ev;
} else if (strcmp(old_config->socket_name,
gpctx->config->socket_name) != 0) {
ev = setup_socket(gpctx->config->socket_name, vctx);
ev = setup_socket(gpctx->config->socket_name, vctx, false);
if (!ev) {
return 1;
}
Expand Down Expand Up @@ -112,7 +126,7 @@ static int init_sockets(verto_ctx *vctx, struct gp_config *old_config)
for (i = 0; i < gpctx->config->num_svcs; i++) {
svc = gpctx->config->svcs[i];
if (svc->socket != NULL && svc->ev == NULL) {
ev = setup_socket(svc->socket, vctx);
ev = setup_socket(svc->socket, vctx, false);
if (!ev) {
return 1;
}
Expand All @@ -122,6 +136,20 @@ static int init_sockets(verto_ctx *vctx, struct gp_config *old_config)
return 0;
}

static int init_userproxy_socket(verto_ctx *vctx)
{
verto_ev *ev;

/* init main socket */
ev = setup_socket(gpctx->config->socket_name, vctx, true);
if (!ev) {
return 1;
}

gpctx->sock_ev = ev;
return 0;
}

static void hup_handler(verto_ctx *vctx, verto_ev *ev UNUSED)
{
int ret;
Expand Down Expand Up @@ -291,7 +319,11 @@ int main(int argc, const char *argv[])
}
}

ret = init_sockets(vctx, NULL);
if (opt_userproxy) {
ret = init_userproxy_socket(vctx);
} else {
ret = init_sockets(vctx, NULL);
}
if (ret != 0) {
goto cleanup;
}
Expand Down

0 comments on commit 145c7ce

Please sign in to comment.