I had a request to add DRAC support to Cyrus IMAPd in Debian, so I applied
the already excelent patches in contrib/drac_auth.patch and cleaned them up
a little bit (and made the default to be DRAC disabled).

Here it is, patch against stock 2.1.4.  They look clean and well-done enough
to be made part of standard Cyrus IMHO, to be enabled by anyone who wants to
compile DRAC support in.

-- 
  "One disk to rule them all, One disk to find them. One disk to bring
  them all and in the darkness grind them. In the Land of Redmond
  where the shadows lie." -- The Silicon Valley Tarot
  Henrique Holschuh
diff -ru cyrus-imapd-2.1.4.orig/acconfig.h cyrus-imapd-2.1.4/acconfig.h
--- cyrus-imapd-2.1.4.orig/acconfig.h   Mon Apr 15 16:35:49 2002
+++ cyrus-imapd-2.1.4/acconfig.h        Sun May 19 15:29:20 2002
@@ -101,6 +101,9 @@
 /* do we have SASL support for APOP? */
 #undef HAVE_APOP
 
+/* the Dynamic Relay Authorization Control package */
+#undef DRAC_AUTH
+
 /* do we have OpenSSL? */
 #undef HAVE_SSL
 
diff -ru cyrus-imapd-2.1.4.orig/configure.in cyrus-imapd-2.1.4/configure.in
--- cyrus-imapd-2.1.4.orig/configure.in Mon Apr 15 16:35:48 2002
+++ cyrus-imapd-2.1.4/configure.in      Sun May 19 15:29:20 2002
@@ -865,6 +865,19 @@
 SNMP_SUBDIRS=""
 AC_SUBST(SNMP_SUBDIRS)
 
+dnl
+dnl Test for DRAC
+dnl
+DRACLIBS=
+AC_ARG_WITH(drac, [  --with-drac=DIR         use DRAC library in <DIR> [no] ],
+       if test -d "$withval"; then
+               LDFLAGS="$LDFLAGS -L${withval}"
+               AC_CHECK_LIB(drac, dracauth,
+                       AC_DEFINE(DRAC_AUTH)
+                       DRACLIBS="-ldrac")
+       fi)
+AC_SUBST(DRACLIBS)
+
 CMU_SOCKETS
 CMU_LIBWRAP
 CMU_UCDSNMP
Only in cyrus-imapd-2.1.4: configure.in.orig
diff -ru cyrus-imapd-2.1.4.orig/imap/Makefile.in cyrus-imapd-2.1.4/imap/Makefile.in
--- cyrus-imapd-2.1.4.orig/imap/Makefile.in     Thu Apr 18 14:35:26 2002
+++ cyrus-imapd-2.1.4/imap/Makefile.in  Sun May 19 15:29:20 2002
@@ -67,6 +67,7 @@
 SIEVE_LIBS = @SIEVE_LIBS@
 IMAP_COM_ERR_LIBS = @IMAP_COM_ERR_LIBS@
 LIB_WRAP = @LIB_WRAP@
+DRAC_LIBS = @DRACLIBS@
 LIBS = $(IMAP_LIBS) $(IMAP_COM_ERR_LIBS)
 DEPLIBS = ../acap/libacap.a ../lib/libcyrus.a @DEPLIBS@
 
@@ -201,15 +202,15 @@
 
 imapd: xversion $(IMAPDOBJS) libimap.a $(DEPLIBS) $(SERVICE)
        $(CC) $(LDFLAGS) -o imapd \
-        $(SERVICE) $(IMAPDOBJS) libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
+        $(SERVICE) $(IMAPDOBJS) libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) $(DRAC_LIBS)
 
 imapd.pure: $(IMAPDOBJS) libimap.a $(DEPLIBS) $(SERVICE)
        $(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o imapd.pure \
-        $(SERVICE) $(IMAPDOBJS) libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
+        $(SERVICE) $(IMAPDOBJS) libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) $(DRAC_LIBS)
 
 imapd.quant: $(IMAPDOBJS) libimap.a $(DEPLIBS) $(SERVICE)
        $(QUANTIFY) $(QUANTOPT) $(CC) $(LDFLAGS) -o imapd.quant \
-        $(SERVICE) $(IMAPDOBJS) libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
+        $(SERVICE) $(IMAPDOBJS) libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) $(DRAC_LIBS)
 
 proxyd: $(PROXYDOBJS) libimap.a $(DEPLIBS) $(SERVICE)
        $(CC) $(LDFLAGS) -o proxyd \
@@ -235,7 +236,7 @@
 
 pop3d: pop3d.o tls.o libimap.a $(DEPLIBS) $(SERVICE)
        $(CC) $(LDFLAGS) -o pop3d pop3d.o tls.o $(SERVICE) \
-        libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP)
+        libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) $(DRAC_LIBS)
 
 pop3proxyd: pop3proxyd.o tls.o libimap.a $(DEPLIBS) $(SERVICE)
        $(CC) $(LDFLAGS) -o pop3proxyd pop3proxyd.o tls.o $(SERVICE) \
diff -ru cyrus-imapd-2.1.4.orig/imap/imapd.c cyrus-imapd-2.1.4/imap/imapd.c
--- cyrus-imapd-2.1.4.orig/imap/imapd.c Thu Apr 25 15:15:14 2002
+++ cyrus-imapd-2.1.4/imap/imapd.c      Sun May 19 15:29:20 2002
@@ -120,6 +120,18 @@
 static SSL *tls_conn = NULL;
 #endif /* HAVE_SSL */
 
+#ifdef DRAC_AUTH
+static struct {
+    int interval;              /* dracd "ping" interval; 0 = disabled */
+    unsigned long clientaddr;
+    struct prot_waitevent *event;
+} drac;
+
+extern int dracconn(char *server, char **errmsg);
+extern int dracsend(unsigned long userip, char **errmsg);
+extern int dracdisc(char **errmsg);
+#endif /* DRAC_AUTH */
+
 /* current sub-user state */
 static struct mailbox mboxstruct;
 static struct mailbox *imapd_mailbox;
@@ -529,6 +541,23 @@
     /* setup for sending IMAP IDLE notifications */
     idle_enabled();
 
+#ifdef DRAC_AUTH
+    /* setup for sending DRAC "pings" */
+    drac.event = NULL;
+    drac.interval = config_getint("dracinterval", 0);
+    if (drac.interval < 0) drac.interval = 0;
+    if (drac.interval) {
+       char *err;
+
+       if (dracconn((char*) config_getstring("drachost", "localhost"), &err) != 0) {
+           /* disable DRAC */
+           drac.interval = 0;
+           syslog(LOG_ERR, "dracconn: %s", err);
+           syslog(LOG_ERR, "DRAC notifications disabled");
+       }
+    }
+#endif /* DRAC_AUTH */
+
     /* create connection to the SNMP listener, if available. */
     snmp_connect(); /* ignore return code */
     snmp_set_str(SERVER_NAME_VERSION,CYRUS_VERSION);
@@ -611,6 +640,12 @@
                  imapd_haveaddr = 1;
              }
        }
+
+#ifdef DRAC_AUTH
+       drac.clientaddr = imapd_remoteaddr.sin_addr.s_addr;
+    } else {
+       drac.clientaddr = 0;
+#endif /* DRAC_AUTH */
     }
 
     /* create the SASL connection */
@@ -653,6 +688,11 @@
     prot_flush(imapd_out);
     snmp_increment(ACTIVE_CONNECTIONS, -1);
 
+#ifdef DRAC_AUTH
+    if (drac.event) prot_removewaitevent(imapd_in, drac.event);
+    drac.event = NULL;
+#endif /* DRAC_AUTH */
+
     /* cleanup */
     imapd_reset();
 
@@ -731,6 +771,10 @@
        snmp_increment(ACTIVE_CONNECTIONS, -1);
     }
 
+#ifdef DRAC_AUTH
+    if (drac.interval) (void) dracdisc((char **)NULL);
+#endif /* DRAC_AUTH */
+
     exit(code);
 }
 
@@ -753,6 +797,35 @@
 
 }
 
+#ifdef DRAC_AUTH
+/*
+ * Ping dracd every 'drac.interval' minutes
+ * to let it know that we are still connected
+ */
+struct prot_waitevent *drac_ping(struct protstream *s,
+                                struct prot_waitevent *ev, void *rock)
+{
+    char *err;
+    static int nfailure = 0;
+
+    if (dracsend(drac.clientaddr, &err) != 0) {
+       syslog(LOG_ERR, "dracsend: %s", err);
+       if (++nfailure >= 3) {
+           /* can't contact dracd for 3 consecutive tries - disable DRAC */
+           prot_removewaitevent(s, ev);
+           drac.event = NULL;
+           syslog(LOG_ERR, "DRAC notifications disabled");
+           return NULL;
+       }
+    }
+    else
+       nfailure = 0;
+
+    ev->mark = time(NULL) + (drac.interval * 60);
+    return ev;
+}
+#endif /* DRAC_AUTH */
+
 /*
  * Top-level command loop parsing
  */
@@ -1774,6 +1847,11 @@
 
     prot_printf(imapd_out, "%s OK %s\r\n", tag, reply);
 
+#ifdef DRAC_AUTH
+    if (drac.interval && drac.clientaddr)
+       drac.event = prot_addwaitevent(imapd_in, 0 /* now */, drac_ping, NULL);
+#endif /* DRAC_AUTH */
+
     /* Create telemetry log */
     imapd_logfd = telemetry_log(imapd_userid, imapd_in, imapd_out);
 
@@ -1928,6 +2006,11 @@
 
     prot_setsasl(imapd_in,  imapd_saslconn);
     prot_setsasl(imapd_out, imapd_saslconn);
+
+#ifdef DRAC_AUTH
+    if (drac.interval && drac.clientaddr)
+       drac.event = prot_addwaitevent(imapd_in, 0 /* now */, drac_ping, NULL);
+#endif /* DRAC_AUTH */
 
     /* Create telemetry log */
     imapd_logfd = telemetry_log(imapd_userid, imapd_in, imapd_out);
Only in cyrus-imapd-2.1.4/imap: imapd.c.orig
diff -ru cyrus-imapd-2.1.4.orig/imap/pop3d.c cyrus-imapd-2.1.4/imap/pop3d.c
--- cyrus-imapd-2.1.4.orig/imap/pop3d.c Wed Apr 10 15:02:42 2002
+++ cyrus-imapd-2.1.4/imap/pop3d.c      Sun May 19 15:29:20 2002
@@ -101,6 +101,10 @@
 
 extern int errno;
 
+#ifdef DRAC_AUTH
+static int drac_enabled;
+extern int dracauth(char *server, unsigned long userip, char **errmsg);
+#endif /* DRAC_AUTH */
 
 
 #ifdef HAVE_SSL
@@ -428,6 +432,10 @@
     prot_settimeout(popd_in, timeout*60);
     prot_setflushonread(popd_in, popd_out);
 
+#ifdef DRAC_AUTH
+    drac_enabled = (config_getint("dracinterval", 0) > 0);
+#endif /* DRAC_AUTH */
+
     if (kflag) kpop();
 
     /* we were connected on pop3s port so we should do 
@@ -1404,6 +1412,20 @@
     }
     popd_mailbox = &mboxstruct;
     proc_register("pop3d", popd_clienthost, popd_userid, popd_mailbox->name);
+
+#ifdef DRAC_AUTH
+    if (drac_enabled) {
+       char *err;
+
+       if (dracauth((char*) config_getstring("drachost", "localhost"),
+                    popd_remoteaddr.sin_addr.s_addr, &err) != 0) {
+           /* disable DRAC */
+           drac_enabled = 0;
+           syslog(LOG_ERR, "dracauth: %s", err);
+           syslog(LOG_ERR, "DRAC notifications disabled");
+       }
+    }
+#endif /* DRAC_AUTH */
 
     /* Create telemetry log */
     telemetry_log(popd_userid, popd_in, popd_out);
Only in cyrus-imapd-2.1.4/imap: pop3d.c.orig
diff -ru cyrus-imapd-2.1.4.orig/imap/version.c cyrus-imapd-2.1.4/imap/version.c
--- cyrus-imapd-2.1.4.orig/imap/version.c       Thu Mar 21 18:10:04 2002
+++ cyrus-imapd-2.1.4/imap/version.c    Sun May 19 15:29:20 2002
@@ -130,6 +130,10 @@
     snprintf(env_buf + strlen(env_buf), MAXIDVALUELEN - strlen(env_buf),
             "; %s", SIEVE_VERSION);
 #endif
+#ifdef DRAC_AUTH
+    snprintf(env_buf + strlen(env_buf), MAXIDVALUELEN - strlen(env_buf),
+            "; DRAC");
+#endif
 #ifdef HAVE_LIBWRAP
     snprintf(env_buf + strlen(env_buf), MAXIDVALUELEN - strlen(env_buf),
             "; TCP Wrappers");
diff -ru cyrus-imapd-2.1.4.orig/man/imapd.conf.5 cyrus-imapd-2.1.4/man/imapd.conf.5
--- cyrus-imapd-2.1.4.orig/man/imapd.conf.5     Thu Mar 21 18:10:05 2002
+++ cyrus-imapd-2.1.4/man/imapd.conf.5  Sun May 19 15:30:23 2002
@@ -318,8 +318,14 @@
 Unix domain socket that idled listens on.
 .IP "\fBnotifysocket:\fR /var/imap/socket/notify" 5
 Unix domain socket that the new mail notification daemon listens on.
+.IP "\fBdracinterval:\fR 0" 5
+If nonzero, enables the use of DRAC (Dynamic Relay Authorization Control)
+by the pop3d and imapd daemons.  Also sets the interval (in minutes) between 
+re-authorization requests made by imapd.
+.IP "\fBdrachost:\fR localhost" 5
+Hostname of the RPC dracd server.
 .SH SEE ALSO
 .PP
 \fBimapd(8)\fR, \fBpop3d(8)\fR, \fBlmtpd(8)\fR, \fBtimsieved(8)\fR,
 \fBidled(8)\fR, \fBnotifyd(8)\fR, \fBdeliver(8)\fR, \fBmaster(8)\fR, 
-\fBciphers(1)\fR
+\fBrpc.dracd(1m)\fR, \fBciphers(1)\fR

Reply via email to