kpasswd: add sd_notify start/stop signals

This commit adds optional integration with systemd's state
notifification system.

When built with libsystemd, kpasswdd notifies systemd once it is
ready to serve and when it begins a clean shutdown, as well as
publishing a status line reporting how many password change requests
have been processed.
This commit is contained in:
2026-07-22 04:41:40 +09:00
parent 4cba7c91d1
commit b795025613
2 changed files with 67 additions and 27 deletions
+4 -1
View File
@@ -24,7 +24,10 @@ kpasswdd_LDADD = \
$(LDADD) \
$(LIB_pidfile) \
$(LIB_dlopen) \
$(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB)
$(DB3LIB) $(DB1LIB) $(LMDBLIB) $(NDBMLIB) \
$(SYSTEMD_LIBS)
kpasswdd_CFLAGS = $(SYSTEMD_CFLAGS)
LDADD = $(top_builddir)/lib/krb5/libkrb5.la \
$(top_builddir)/lib/asn1/libasn1.la \
+63 -26
View File
@@ -41,6 +41,11 @@ RCSID("$Id$");
#include <hdb.h>
#include <kadm5/private.h>
#include <kadm5/kadm5_err.h>
#ifdef HAVE_SYSTEMD
#include <systemd/sd-daemon.h>
/* how often (seconds) to refresh the sd_notify STATUS line while idle */
#define STATUS_INTERVAL 30
#endif
static krb5_context context;
static krb5_log_facility *log_facility;
@@ -745,38 +750,70 @@ doit(krb5_keytab keytab, int port)
roken_detach_finish(NULL, daemon_child);
while (exit_flag == 0) {
krb5_ssize_t retx;
fd_set fdset = real_fdset;
{
struct timeval *tmoutp = NULL;
#ifdef HAVE_SYSTEMD
unsigned long nrequests = 0;
struct timeval tmout;
retx = select(maxfd + 1, &fdset, NULL, NULL, NULL);
if (retx < 0) {
if (errno == EINTR)
continue;
else
krb5_err(context, 1, errno, "select");
}
for (i = 0; i < n; ++i)
if (FD_ISSET(sockets[i], &fdset)) {
u_char buf[BUFSIZ];
socklen_t addrlen = sizeof(__ss);
tmoutp = &tmout;
sd_notify(0, "READY=1");
sd_notifyf(0, "STATUS=Serving; %lu password change request(s) processed",
nrequests);
#endif
retx = recvfrom(sockets[i], buf, sizeof(buf), 0,
sa, &addrlen);
if (retx < 0) {
if (errno == EINTR)
break;
else
krb5_err(context, 1, errno, "recvfrom");
}
while (exit_flag == 0) {
krb5_ssize_t retx;
fd_set fdset = real_fdset;
process(keytab, sockets[i],
&addrs.val[i],
sa, addrlen,
buf, retx);
#ifdef HAVE_SYSTEMD
tmout.tv_sec = STATUS_INTERVAL;
tmout.tv_usec = 0;
#endif
retx = select(maxfd + 1, &fdset, NULL, NULL, tmoutp);
if (retx < 0) {
if (errno == EINTR)
continue;
else
krb5_err(context, 1, errno, "select");
}
#ifdef HAVE_SYSTEMD
if (retx == 0) {
/* select timed out: refresh our systemd status line */
sd_notifyf(0, "STATUS=Serving; %lu password change request(s) "
"processed", nrequests);
continue;
}
#endif
for (i = 0; i < n; ++i)
if (FD_ISSET(sockets[i], &fdset)) {
u_char buf[BUFSIZ];
socklen_t addrlen = sizeof(__ss);
retx = recvfrom(sockets[i], buf, sizeof(buf), 0,
sa, &addrlen);
if (retx < 0) {
if (errno == EINTR)
break;
else
krb5_err(context, 1, errno, "recvfrom");
}
process(keytab, sockets[i],
&addrs.val[i],
sa, addrlen,
buf, retx);
#ifdef HAVE_SYSTEMD
nrequests++;
#endif
}
}
}
#ifdef HAVE_SYSTEMD
sd_notify(0, "STOPPING=1");
#endif
for (i = 0; i < n; ++i)
close(sockets[i]);
free(sockets);