Skip Menu |
 

To: krb5-bugs@mit.edu
Subject: feature: krb5kdc as a wait service.
Date: Wed, 22 Apr 2009 00:41:34 -0400
From: Roland Dowdeswell <elric@imrryr.org>
Download (untitled) / with headers
text/plain 3.5KiB
Sometimes it is nice to be able to start daemons as a wait service from
inetd or similar program. This provides some benefits mainly revolving
around being restarted if things go awry.

I attach a small patch which allows for krb5kdc to be started as
a TCP or UDP wait service.

--
Roland Dowdeswell http://Imrryr.ORG/~elric/

Index: main.c
===================================================================
RCS file: /ms/dev/kerberos/mitkrb5/cvs-dirs/mitkrb5-1.4/mitkrb5/src/kdc/main.c,v
retrieving revision 1.2
retrieving revision 1.4
diff -u -r1.2 -r1.4
--- main.c 29 Mar 2005 14:43:21 -0000 1.2
+++ main.c 29 Jan 2007 19:06:18 -0000 1.4
@@ -66,6 +66,7 @@
void finish_realms (char *);

static int nofork = 0;
+static int nowait = 1;
static int rkey_init_done = 0;

#ifdef POSIX_SIGNALS
@@ -464,7 +465,7 @@
* Loop through the option list. Each time we encounter a realm name,
* use the previously scanned options to fill in for defaults.
*/
- while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n4:X3")) != -1) {
+ while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:nw4:X3")) != -1) {
switch(c) {
case 'r': /* realm name for db */
if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) {
@@ -513,6 +514,10 @@
default_tcp_ports = strdup(optarg);
#endif
break;
+ case 'w':
+ nowait = 0;
+ nofork = 1;
+ break;
case '4':
#ifdef KRB5_KRB4_COMPAT
if (v4mode)
@@ -670,7 +675,13 @@
return 1;
}

- if ((retval = setup_network(argv[0]))) {
+ if (nowait && (retval = setup_network(argv[0]))) {
+ com_err(argv[0], retval, "while initializing network");
+ finish_realms(argv[0]);
+ return 1;
+ }
+
+ if (!nowait && (retval = setup_network_inetd_wait(*argv))) {
com_err(argv[0], retval, "while initializing network");
finish_realms(argv[0]);
return 1;
Index: network.c
===================================================================
RCS file: /ms/dev/kerberos/mitkrb5/cvs-dirs/mitkrb5-1.4/mitkrb5/src/kdc/network.c,v
retrieving revision 1.5
retrieving revision 1.7
diff -u -r1.5 -r1.7
--- network.c 21 Jul 2005 13:12:34 -0000 1.5
+++ network.c 1 Feb 2007 01:18:56 -0000 1.7
@@ -63,6 +63,14 @@
#include <sys/filio.h> /* FIONBIO */
#endif

+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#ifndef _PATH_DEVNULL
+#define _PATH_DEVNULL "/dev/null"
+#endif
+
#include "fake-addrinfo.h"

/* Misc utility routines. */
@@ -675,6 +683,51 @@

return 0;
}
+
+
+krb5_error_code
+setup_network_inetd_wait(const char *prog)
+{
+ socklen_t len;
+ struct socksetup data;
+ int devnull = open(_PATH_DEVNULL, O_RDWR, 0);
+ int fd;
+ int type;
+
+ data.prog = prog;
+ data.retval = 0;
+
+ fd = dup(STDIN_FILENO);
+
+ /*
+ * Unfortunately, we duplicate code from daemon(3) but can't
+ * reuse it. We definitely want to bounce the fds about 2 for
+ * obvious reasons.
+ */
+ (void) chdir("/");
+ if (devnull != -1) {
+ (void) dup2(devnull, 0);
+ (void) dup2(devnull, 1);
+ (void) dup2(devnull, 2);
+ if (devnull > 2)
+ (void) close(devnull);
+ }
+
+ len = sizeof(type);
+ if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &type, &len)) {
+ krb5_klog_syslog(LOG_ERR, "getsockopt(2) error: %m");
+ return -1; /* XXXrcd: wrong error. */
+ }
+
+ FD_SET(fd, &sstate.rfds);
+ if (fd >= sstate.max)
+ sstate.max = fd + 1;
+ krb5_klog_syslog(LOG_INFO, "listening on fd %d (inetd, type %d)", fd, type);
+ if (type == SOCK_DGRAM)
+ return !add_udp_fd(&data, fd);
+ return !add_tcp_listener_fd(&data, fd);
+}
+

static void init_addr(krb5_fulladdr *faddr, struct sockaddr *sa)
{
I like this as a feature idea. Unfortunately, there have been
significant changes to the KDC network code since krb5 1.4 (both before
and after this patch was submitted). If you have the time to rewrite the
patch against the current trunk, we'll review and possibly integrate it;
otherwise we might implement it internally at some point but can't make
any promises.

As discussed on krbdev, the -w option is being consumed by the worker
processes feature, but -i (for "inetd") is not taken.