From: Jacob Floyd Date: Sat, 11 Mar 2017 05:25:23 +0000 (-0600) Subject: Use systemd's sd_notify with option up_sdnotify X-Git-Tag: ppp-2.4.8~38 X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=commitdiff_plain;h=d34159f417620eb7c481bf53f29fe04c86ccd223 Use systemd's sd_notify with option up_sdnotify This adds an up_sdnotify option so that systemd services of Type=notify can have pppd send the READY=1 signal to systemd once a network protocol (typically IP) is up. To use up_sdnotify, pppd must be compiled with SYSTEMD=y. up_sdnotify is safe as a non-priveleged option because systemd will ignore any notifications that it is not expecting. If systemd starts pppd in a unit-file that is Type=notify, then (and only then) will it handle the READY=1 signal. If systemd didn't start the process, it ignroes any notifications unless the signaling process was started by a service that systemd is monitoring (directly or indirectly, such as a grandchild process in the same cgroup as a process that systemd started) AND that service is Type=notify, AND that service is explicitly configured to allow other processes to send a notification on behalf of that service by setting NotifyAccess=all. Also, the socket used is defined in an environment variable provided and deleted by systemd, allowing system and user services to use a different socket. I really don't think there's any way to use that socket (even via the sd_notify api of their library) to gain elevated privileges. Another reason that up_sdnotify is a non-priveleged option is for cases where ppp should be started as a system service under a non-priveleged account. There may be other issues with running ppp under other accounts, but systemd does not require root--or other privileged--access in order to use the notification feature. Instead the security for this feature is provided at the process level in that systemd knows which processes it did and did not start, and which processes those processes started (ie other processes in the systemd unit's cgroup), as explained above. Signed-off-by: Jacob Floyd --- diff --git a/pppd/Makefile.linux b/pppd/Makefile.linux index a74c914..b541fe8 100644 --- a/pppd/Makefile.linux +++ b/pppd/Makefile.linux @@ -60,6 +60,11 @@ HAVE_MULTILINK=y # Linux distributions: Please leave TDB ENABLED in your builds. USE_TDB=y +# Uncomment the next line to enable Type=notify services in systemd +# If enabled, and the user sets the up_sdnotify option, then +# pppd will not detach and will notify systemd when up. +#SYSTEMD=y + HAS_SHADOW=y #USE_PAM=y HAVE_INET6=y @@ -170,6 +175,11 @@ LIBS += -llock CFLAGS += -DLOCKLIB=1 endif +ifdef SYSTEMD +LIBS += -lsystemd +CFLAGS += -DSYSTEMD=1 +endif + ifdef PLUGIN CFLAGS += -DPLUGIN LDFLAGS += -Wl,-E diff --git a/pppd/auth.c b/pppd/auth.c index 4271af6..7457eda 100644 --- a/pppd/auth.c +++ b/pppd/auth.c @@ -100,6 +100,10 @@ #endif #include +#ifdef SYSTEMD +#include +#endif + #include "pppd.h" #include "fsm.h" #include "lcp.h" @@ -1099,8 +1103,15 @@ np_up(unit, proto) /* * Detach now, if the updetach option was given. */ - if (updetach && !nodetach) + if (updetach && !nodetach) { + dbglog("updetach is set. Now detaching."); detach(); +#ifdef SYSTEMD + } else if (nodetach && up_sdnotify) { + dbglog("up_sdnotify is set. Now notifying systemd: READY=1"); + sd_notify(0, "READY=1"); +#endif + } } ++num_np_up; } diff --git a/pppd/options.c b/pppd/options.c index 177488c..6e38d43 100644 --- a/pppd/options.c +++ b/pppd/options.c @@ -97,6 +97,9 @@ char devnam[MAXPATHLEN]; /* Device name */ bool nodetach = 0; /* Don't detach from controlling tty */ bool updetach = 0; /* Detach once link is up */ bool master_detach; /* Detach when we're (only) multilink master */ +#ifdef SYSTEMD +bool up_sdnotify = 0; /* Notify systemd once link is up */ +#endif int maxconnect = 0; /* Maximum connect time */ char user[MAXNAMELEN]; /* Username for PAP */ char passwd[MAXSECRETLEN]; /* Password for PAP */ @@ -209,6 +212,11 @@ option_t general_options[] = { "Don't detach from controlling tty", OPT_PRIO | 1 }, { "-detach", o_bool, &nodetach, "Don't detach from controlling tty", OPT_ALIAS | OPT_PRIOSUB | 1 }, +#ifdef SYSTEMD + { "up_sdnotify", o_bool, &up_sdnotify, + "Notify systemd once link is up (implies nodetach)", + OPT_PRIOSUB | OPT_A2COPY | 1, &nodetach }, +#endif { "updetach", o_bool, &updetach, "Detach from controlling tty once link is up", OPT_PRIOSUB | OPT_A2CLR | 1, &nodetach }, diff --git a/pppd/pppd.8 b/pppd/pppd.8 index 06e945f..76a2097 100644 --- a/pppd/pppd.8 +++ b/pppd/pppd.8 @@ -1100,6 +1100,15 @@ it has successfully established the ppp connection (to the point where the first network control protocol, usually the IP control protocol, has come up). .TP +.B up_sdnotify +Use this option to run pppd in systemd service units of Type=notify +(\fBup_sdnotify\fR implies \fBnodetach\fR). +When \fBup_sdnotify\fR is enabled, pppd will notify systemd once +it has successfully established the ppp connection (to the point where +the first network control protocl, usually the IP control protocol, +has come up). This option is only availble when pppd is compiled with +systemd support. +.TP .B usehostname Enforce the use of the hostname (with domain name appended, if given) as the name of the local system for authentication purposes (overrides diff --git a/pppd/pppd.h b/pppd/pppd.h index 1a1bf0b..6e3743f 100644 --- a/pppd/pppd.h +++ b/pppd/pppd.h @@ -295,6 +295,9 @@ extern int inspeed; /* Input/Output speed requested */ extern u_int32_t netmask; /* IP netmask to set on interface */ extern bool lockflag; /* Create lock file to lock the serial dev */ extern bool nodetach; /* Don't detach from controlling tty */ +#ifdef SYSTEMD +extern bool up_sdnotify; /* Notify systemd once link is up (implies nodetach) */ +#endif extern bool updetach; /* Detach from controlling tty when link up */ extern bool master_detach; /* Detach when multilink master without link */ extern char *initializer; /* Script to initialize physical link */