summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Christian Hesse <mail@eworm.de>2017-10-10 15:17:41 +0200
committerGravatar Christian Hesse <mail@eworm.de>2017-10-10 15:17:41 +0200
commit9b6b1520f273d46b3f8d229ee1be28a68e93bc15 (patch)
tree526e93ad5c89046f4624f3b943828d85ffefe8e4
parent93e4d8ba275fe28225cabfed8435f08b03a61fd8 (diff)
downloaddyndhcpd-9b6b1520f273d46b3f8d229ee1be28a68e93bc15.tar.gz
dyndhcpd-9b6b1520f273d46b3f8d229ee1be28a68e93bc15.tar.zst
start systemd service with dynamic usersystemd-v235
This requires systemd v235 and dhcpd built with '--enable-paranoia'.
-rw-r--r--config.def.h3
-rw-r--r--dyndhcpd.c58
-rw-r--r--systemd/dyndhcpd@.service6
3 files changed, 52 insertions, 15 deletions
diff --git a/config.def.h b/config.def.h
index a21c4f8..f277236 100644
--- a/config.def.h
+++ b/config.def.h
@@ -22,6 +22,9 @@
#define PIDFILE "/run/dhcpd-%s.pid"
#define LEASESFILE "/var/lib/dhcp/dhcp-%s.leases"
+/* default user */
+#define USER "dhcp"
+
#define FALLBACKCONFIG \
"# fallback dhcpd.conf for interface __INTERFACE__\n" \
"# generated by dyndhcpd/__VERSION__\n" \
diff --git a/dyndhcpd.c b/dyndhcpd.c
index 8d2ae0c..a3c205a 100644
--- a/dyndhcpd.c
+++ b/dyndhcpd.c
@@ -7,14 +7,18 @@
#include "dyndhcpd.h"
-const static char optstring[] = "c:hi:vV";
+const static char optstring[] = "c:hi:l:p:u:vVw:";
const static struct option options_long[] = {
/* name has_arg flag val */
{ "config", required_argument, NULL, 'c' },
{ "help", no_argument, NULL, 'h' },
{ "interface", required_argument, NULL, 'i' },
+ { "leases", required_argument, NULL, 'l' },
+ { "pidfile", required_argument, NULL, 'p' },
+ { "user", required_argument, NULL, 'u' },
{ "verbose", no_argument, NULL, 'v' },
{ "version", no_argument, NULL, 'V' },
+ { "write-config", required_argument, NULL, 'w' },
{ 0, 0, 0, 0 }
};
@@ -53,7 +57,7 @@ int main(int argc, char ** argv) {
char * configfilename = NULL;
size_t fsize, length = 0;
- char * pidfile = NULL, * leasesfile = NULL;
+ char * pidfile = NULL, * leasesfile = NULL, * username = NULL;
unsigned int version = 0, help = 0;
@@ -77,6 +81,15 @@ int main(int argc, char ** argv) {
return EXIT_FAILURE;
}
break;
+ case 'l':
+ leasesfile = strdup(optarg);
+ break;
+ case 'p':
+ pidfile = strdup(optarg);
+ break;
+ case 'u':
+ username = optarg;
+ break;
case 'v':
verbose++;
break;
@@ -84,6 +97,9 @@ int main(int argc, char ** argv) {
verbose++;
version++;
break;
+ case 'w':
+ configfilename = strdup(optarg);
+ break;
}
if (verbose > 0)
@@ -263,10 +279,14 @@ int main(int argc, char ** argv) {
config[length++] = 0;
/* get new filename and open file for writing */
- configfilename = malloc(strlen(CONFIG_OUTPUT) + strlen(interface) + 1);
- sprintf(configfilename, CONFIG_OUTPUT, interface);
+ if (configfilename == NULL) {
+ configfilename = malloc(strlen(CONFIG_OUTPUT) + strlen(interface) + 1);
+ sprintf(configfilename, CONFIG_OUTPUT, interface);
+ }
+
+ /* try to open the config file for writing */
if ((configfile = fopen(configfilename, "w")) == NULL) {
- fprintf(stderr, "Failed opening config file for writing.\n");
+ fprintf(stderr, "Failed opening config file '%s' for writing.\n", configfilename);
goto out;
}
@@ -274,26 +294,36 @@ int main(int argc, char ** argv) {
fputs(config, configfile);
fclose(configfile);
- /* get names for pid and leases file */
- pidfile = malloc(strlen(PIDFILE) + strlen(interface) + 1);
- sprintf(pidfile, PIDFILE, interface);
- leasesfile = malloc(strlen(LEASESFILE) + strlen(interface) + 1);
- sprintf(leasesfile, LEASESFILE, interface);
+ /* get name for pidfile */
+ if (pidfile == NULL) {
+ pidfile = malloc(strlen(PIDFILE) + strlen(interface) + 1);
+ sprintf(pidfile, PIDFILE, interface);
+ }
+
+ /* get name for leases file */
+ if (leasesfile == NULL) {
+ leasesfile = malloc(strlen(LEASESFILE) + strlen(interface) + 1);
+ sprintf(leasesfile, LEASESFILE, interface);
+ }
/* check if leases file exists, create it if it does not */
if (access(leasesfile, R_OK) == -1) {
if (verbose)
- printf("Creating leases file %s.\n", leasesfile);
+ printf("Creating leases file '%s'.\n", leasesfile);
fclose(fopen(leasesfile, "w"));
}
+ /* get use name */
+ if (username == NULL)
+ username = USER;
+
/* execute dhcp daemon, replace the current process
* dyndhcpd is cleared from memory here and code below is not execuded if
* everything goes well */
if (verbose > 1)
- printf("Running: dhcpd -f -q -4 -pf %s -lf %s -cf %s %s\n",
- pidfile, leasesfile, configfilename, interface);
- rc = execlp(DHCPDFILE, "dhcpd", "-f", "-q", "-4",
+ printf("Running: dhcpd -f -q -4 -user %s -pf %s -lf %s -cf %s %s\n",
+ username, pidfile, leasesfile, configfilename, interface);
+ rc = execlp(DHCPDFILE, "dhcpd", "-f", "-q", "-4", "-user", username,
"-pf", pidfile, "-lf", leasesfile, "-cf", configfilename, interface, NULL);
fprintf(stderr, "The dhcp daemon failed to execute.\n");
diff --git a/systemd/dyndhcpd@.service b/systemd/dyndhcpd@.service
index 8aceeb1..25c93cd 100644
--- a/systemd/dyndhcpd@.service
+++ b/systemd/dyndhcpd@.service
@@ -5,7 +5,11 @@ Requires=sys-subsystem-net-devices-%i.device
After=sys-subsystem-net-devices-%i.device
[Service]
-ExecStart=/usr/bin/dyndhcpd -i%i
+ExecStart=!/usr/bin/dyndhcpd --interface %i --user %p-%i --pidfile /run/%p@%i/dhcpd.pid --leases /var/lib/%p@%i/dhcp.leases --write-config /run/%p@%i/dhcpd.conf
+RuntimeDirectory=%p@%i
+StateDirectory=%p@%i
+User=%p-%i
+DynamicUser=on
ProtectSystem=full
ProtectHome=on
PrivateDevices=on