Index: acconfig.h diff -u acconfig.h.orig acconfig.h --- acconfig.h.orig Fri Feb 14 05:32:50 2003 +++ acconfig.h Fri Mar 21 20:13:20 2003 @@ -98,6 +98,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 Index: configure.in diff -u configure.in.orig configure.in --- configure.in.orig Wed Mar 19 04:15:14 2003 +++ configure.in Fri Mar 21 20:20:54 2003 @@ -981,6 +981,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 [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_LIBWRAP CMU_UCDSNMP Index: imap/Makefile.in diff -u imap/Makefile.in.orig imap/Makefile.in --- imap/Makefile.in.orig Fri Feb 28 03:10:28 2003 +++ imap/Makefile.in Fri Mar 21 20:23:02 2003 @@ -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 = ../lib/libcyrus.a ../lib/libcyrus_min.a @DEPLIBS@ @@ -206,17 +207,17 @@ imapd: xversion $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) $(CC) $(LDFLAGS) -o imapd \ $(SERVICE) $(IMAPDOBJS) mutex_fake.o \ - libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) + libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) $(DRAC_LIBS) imapd.pure: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) $(PURIFY) $(PUREOPT) $(CC) $(LDFLAGS) -o imapd.pure \ $(SERVICE) $(IMAPDOBJS) mutex_fake.o libimap.a \ - $(DEPLIBS) $(LIBS) $(LIB_WRAP) + $(DEPLIBS) $(LIBS) $(LIB_WRAP) $(DRAC_LIBS) imapd.quant: $(IMAPDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) $(QUANTIFY) $(QUANTOPT) $(CC) $(LDFLAGS) -o imapd.quant \ $(SERVICE) $(IMAPDOBJS) mutex_fake.o libimap.a \ - $(DEPLIBS) $(LIBS) $(LIB_WRAP) + $(DEPLIBS) $(LIBS) $(LIB_WRAP) $(DRAC_LIBS) $(DRAC_LIBS) proxyd: $(PROXYDOBJS) mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) $(CC) $(LDFLAGS) -o proxyd \ @@ -242,7 +243,7 @@ pop3d: pop3d.o backend.o tls.o mutex_fake.o libimap.a $(DEPLIBS) $(SERVICE) $(CC) $(LDFLAGS) -o pop3d pop3d.o backend.o tls.o $(SERVICE) \ - mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) + mutex_fake.o libimap.a $(DEPLIBS) $(LIBS) $(LIB_WRAP) $(DRAC_LIBS) nntpd: nntpd.o backend.o index.o spool.o netnews.o wildmat.o tls.o \ mutex_fake.o nntp_err.o libimap.a $(DEPLIBS) $(SERVICE) Index: imap/imapd.c diff -u imap/imapd.c.orig imap/imapd.c --- imap/imapd.c.orig Thu Mar 6 03:32:05 2003 +++ imap/imapd.c Fri Mar 21 23:25:27 2003 @@ -126,6 +126,18 @@ 1, 1, &imapd_authstate, &imapd_userisadmin, &imapd_userisproxyadmin }; +#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; @@ -447,6 +459,23 @@ /* setup for sending IMAP IDLE notifications */ idle_enabled(); +#ifdef DRAC_AUTH + /* setup for sending DRAC "pings" */ + drac.event = NULL; + drac.interval = config_getint(IMAPOPT_DRACINTERVAL); + if (drac.interval < 0) drac.interval = 0; + if (drac.interval) { + char *err; + + if (dracconn((char*) config_getstring(IMAPOPT_DRACHOST), &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); @@ -533,6 +562,15 @@ imapd_haveaddr = 1; } } + +#ifdef DRAC_AUTH + if (((struct sockaddr *)&imapd_remoteaddr)->sa_family == AF_INET) + drac.clientaddr = ((struct sockaddr_in *)&imapd_remoteaddr)->sin_addr.s_addr; + else + drac.clientaddr = 0; + } else { + drac.clientaddr = 0; +#endif /* DRAC_AUTH */ } /* create the SASL connection */ @@ -575,6 +613,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(); @@ -645,6 +688,10 @@ cyrus_done(); +#ifdef DRAC_AUTH + if (drac.interval) (void) dracdisc((char **)NULL); +#endif /* DRAC_AUTH */ + exit(code); } @@ -667,6 +714,35 @@ shut_down(code); } +#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 */ @@ -1664,6 +1740,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); @@ -1786,6 +1867,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); Index: imap/pop3d.c diff -u imap/pop3d.c.orig imap/pop3d.c --- imap/pop3d.c.orig Thu Mar 13 01:38:16 2003 +++ imap/pop3d.c Fri Mar 21 23:37:11 2003 @@ -101,6 +101,10 @@ extern int opterr; +#ifdef DRAC_AUTH +static int drac_enabled; +extern int dracauth(char *server, unsigned long userip, char **errmsg); +#endif /* DRAC_AUTH */ #ifdef HAVE_SSL static SSL *tls_conn; @@ -395,6 +399,10 @@ prot_settimeout(popd_in, timeout*60); prot_setflushonread(popd_in, popd_out); +#ifdef DRAC_AUTH + drac_enabled = (config_getint(IMAPOPT_DRACINTERVAL) > 0); +#endif /* DRAC_AUTH */ + if (kflag) kpop(); /* we were connected on pop3s port so we should do @@ -1422,6 +1430,21 @@ popd_mailbox = &mboxstruct; proc_register("pop3d", popd_clienthost, popd_userid, popd_mailbox->name); + +#ifdef DRAC_AUTH + if (drac_enabled && + ((struct sockaddr *)&popd_remoteaddr)->sa_family == AF_INET) { + char *err; + + if (dracauth((char*) config_getstring(IMAPOPT_DRACHOST), + ((struct sockaddr_in *)&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 */ } else { /* remote mailbox */ Index: imap/version.c diff -u imap/version.c.orig imap/version.c --- imap/version.c.orig Fri Feb 14 05:33:02 2003 +++ imap/version.c Fri Mar 21 20:13:21 2003 @@ -143,6 +143,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"); Index: lib/imapoptions diff -u lib/imapoptions.orig lib/imapoptions --- lib/imapoptions.orig Thu Mar 20 04:00:39 2003 +++ lib/imapoptions Fri Mar 21 20:32:15 2003 @@ -154,6 +154,14 @@ { "deleteright", "c", STRING } /* The right that a user needs to delete a mailbox. */ +{ "dracinterval", 5, INT } +/* 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. */ + +{ "drachost", "localhost", STRING } +/* Hostname of the RPC dracd server. */ + { "duplicatesuppression", 1, SWITCH } /* If enabled, lmtpd will suppress delivery of a message to a mailbox if a message with the same message-id (or resent-message-id) is recorded