Use systemd's sd_notify with option up_sdnotify
authorJacob Floyd <cognifloyd@gmail.com>
Sat, 11 Mar 2017 05:25:23 +0000 (23:25 -0600)
committerJacob Floyd <cognifloyd@gmail.com>
Tue, 27 Feb 2018 19:22:23 +0000 (13:22 -0600)
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 <cognifloyd@gmail.com>
pppd/Makefile.linux
pppd/auth.c
pppd/options.c
pppd/pppd.8
pppd/pppd.h

index a74c914fd3acf84dbcaac360e6f5cabd3582f802..b541fe89a4fa21b264f70a02cb26b4c70efcd21a 100644 (file)
@@ -60,6 +60,11 @@ HAVE_MULTILINK=y
 # Linux distributions: Please leave TDB ENABLED in your builds.
 USE_TDB=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
 HAS_SHADOW=y
 #USE_PAM=y
 HAVE_INET6=y
@@ -170,6 +175,11 @@ LIBS     += -llock
 CFLAGS   += -DLOCKLIB=1
 endif
 
 CFLAGS   += -DLOCKLIB=1
 endif
 
+ifdef SYSTEMD
+LIBS += -lsystemd
+CFLAGS   += -DSYSTEMD=1
+endif
+
 ifdef PLUGIN
 CFLAGS += -DPLUGIN
 LDFLAGS        += -Wl,-E
 ifdef PLUGIN
 CFLAGS += -DPLUGIN
 LDFLAGS        += -Wl,-E
index 4271af687102dc62e3c2e3b47d3fc8ab1d70d0f8..7457eda227bf19c2d09b79dd4e0b031da6bc1bf9 100644 (file)
 #endif
 #include <time.h>
 
 #endif
 #include <time.h>
 
+#ifdef SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
 #include "pppd.h"
 #include "fsm.h"
 #include "lcp.h"
 #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.
         */
        /*
         * Detach now, if the updetach option was given.
         */
-       if (updetach && !nodetach)
+       if (updetach && !nodetach) {
+           dbglog("updetach is set. Now detaching.");
            detach();
            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;
 }
     }
     ++num_np_up;
 }
index 177488ca681392c3971e432642c7e97a0638a894..6e38d43ee900b20a4d5069d4ff8c877dfb930c3f 100644 (file)
@@ -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 */
 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 */
 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 },
       "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 },
     { "updetach", o_bool, &updetach,
       "Detach from controlling tty once link is up",
       OPT_PRIOSUB | OPT_A2CLR | 1, &nodetach },
index 06e945fce998080090da52837d1d3b69306c19a7..76a209766f2afc89b8e43187d87c05271f740ae5 100644 (file)
@@ -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
 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
 .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
index 1a1bf0b99582fa323cb0ee587d79c248642a7896..6e3743fd9c97de74caf9638e717aa60525bebabb 100644 (file)
@@ -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 */
 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 */
 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 */