[krbdev.mit.edu #6476] feature: krb5kdc as a wait service.

Roland C. Dowdeswell via RT rt-comment at krbdev.mit.edu
Wed Apr 22 12:17:49 EDT 2009


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)
 {





More information about the krb5-bugs mailing list