$Id: drac_auth.patch,v 1.5 2001/04/01 18:20:48 ken3 Exp $

Patch to add support for Dynamic Relay Authorization Control

For more information about DRAC, see:
	http://mail.cc.umanitoba.ca/drac/index.html


Installation
------------

1.  Apply this patch in the toplevel directory using the following command:

	# patch -b -p0 < contrib/drac_auth.patch

2.  Cleanup any previous builds:

	# make distclean

3a. If you DO NOT have 'smake' and 'autoconf' installed on your system, goto
    step 3b.

    Perform the following to reconfigure your build:

	# rm aclocal.m4 configure
	# sh SMakefile
	# ./configure ... --with-drac=<location of libdrac>

    NOTE: you can find your original configure command in config.status

    Proceed to step 4.

3b. Edit imap/Makefile and modify the following three variables:

	DEFS = ... -DDRAC_AUTH
	LIBS = ... -ldrac
	LDFLAGS = ... -L<location of libdrac>

4.  Build and install the software:

	# make
	# make install

5.  If dracd is not running on the same system as Cyrus (localhost),
    use the 'drachost' option in imapd.conf(5) to specify the hostname of
    the dracd server.

6.  Installation is complete!


Operation
---------

The behavior of DRAC is controlled by the value of the 'dracinterval' option
in imapd.conf(5).  If 'dracinterval' is 0 (zero), DRAC support is disabled.
Otherwise, DRAC support is enabled and has the following behavior:

pop3d: Whenever a client opens a user's INBOX, drac_auth() is called.

imapd: Once a client is logged in (via LOGIN or AUTHENTICATE),
       drac_send() will be once called every 'dracinterval' minutes.





*** acconfig.h.orig	Wed Mar 28 11:11:49 2001
--- acconfig.h	Sun Apr  1 14:05:59 2001
***************
*** 81,86 ****
--- 81,89 ----
  /* 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
  
*** configure.in.orig	Wed Mar 28 11:11:49 2001
--- configure.in	Sun Apr  1 14:05:59 2001
***************
*** 719,724 ****
--- 719,739 ----
  SNMP_SUBDIRS=""
  AC_SUBST(SNMP_SUBDIRS)
  
+ 
+ 
+ dnl
+ dnl Test for DRAC
+ dnl
+ 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)
+ 			LIBS="${LIBS} -ldrac")
+ 	fi)
+ 
+ 
+ 
  CMU_SOCKETS
  CMU_LIBWRAP
  CMU_UCDSNMP
*** imap/imapd.c.orig	Fri Mar 16 16:05:03 2001
--- imap/imapd.c	Sun Apr  1 14:08:49 2001
***************
*** 115,120 ****
--- 115,124 ----
  static SSL *tls_conn = NULL;
  #endif /* HAVE_SSL */
  
+ #ifdef DRAC_AUTH
+ static int drac_interval; /* dracd "ping" interval; 0 = disabled */
+ #endif /* DRAC_AUTH */
+ 
  /* current sub-user state */
  static struct mailbox mboxstruct;
  static struct mailbox *imapd_mailbox;
***************
*** 541,546 ****
--- 545,565 ----
         TLS negotiation immediately */
      if (imaps == 1) cmd_starttls(NULL, 1);
  
+ #ifdef DRAC_AUTH
+     drac_interval = config_getint("dracinterval", 5);
+     if (drac_interval < 0) drac_interval = 0;
+ 
+     if (drac_interval) {
+ 	char *err;
+ 
+ 	if (dracconn(config_getstring("drachost", "localhost"), &err) != 0) {
+ 	    /* disable DRAC */
+ 	    drac_interval = 0;
+ 	    syslog(LOG_NOTICE, "dracconn: %s (DISABLED)", err);
+ 	}
+     }
+ #endif /* DRAC_AUTH */
+ 
      snmp_increment(TOTAL_CONNECTIONS, 1);
      snmp_increment(ACTIVE_CONNECTIONS, 1);
  
***************
*** 622,627 ****
--- 641,651 ----
      prot_flush(imapd_out);
      /* one less active connection */
      snmp_increment(ACTIVE_CONNECTIONS, -1);
+ 
+ #ifdef DRAC_AUTH
+     if (drac_interval) (void) dracdisc((char **)NULL);
+ #endif /* DRAC_AUTH */
+ 
      exit(code);
  }
  
***************
*** 642,647 ****
--- 666,693 ----
  
  }
  
+ #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;
+ 
+     if (dracsend(imapd_remoteaddr.sin_addr.s_addr, &err) != 0) {
+ 	/* disable DRAC */
+ 	prot_removewaitevent(s, ev);
+ 	syslog(LOG_NOTICE, "dracsend: %s (DISABLED)", err);
+ 	return NULL;
+     }
+ 
+     ev->mark = time(NULL) + (drac_interval * 60);
+     return ev;
+ }
+ #endif /* DRAC_AUTH */
+ 
  /*
   * Top-level command loop parsing
   */
***************
*** 1487,1492 ****
--- 1533,1543 ----
  
      if (!reply) reply = "User logged in";
  
+ #ifdef DRAC_AUTH
+     if (drac_interval)
+ 	prot_addwaitevent(imapd_in, 0 /* ping now */, drac_ping, NULL);
+ #endif /* DRAC_AUTH */
+ 
      /* Create telemetry log */
      imapd_logfd = telemetry_log(imapd_userid, imapd_in, imapd_out);
  
***************
*** 1630,1635 ****
--- 1681,1691 ----
  
      prot_setsasl(imapd_in,  imapd_saslconn);
      prot_setsasl(imapd_out, imapd_saslconn);
+ 
+ #ifdef DRAC_AUTH
+     if (drac_interval)
+ 	prot_addwaitevent(imapd_in, 0 /* ping now */, drac_ping, NULL);
+ #endif /* DRAC_AUTH */
  
      /* Create telemetry log */
      imapd_logfd = telemetry_log(imapd_userid, imapd_in, imapd_out);
*** imap/pop3d.c.orig	Wed Mar 28 20:20:29 2001
--- imap/pop3d.c	Sun Apr  1 14:05:59 2001
***************
*** 99,105 ****
  
  extern int errno;
  
! 
  
  #ifdef HAVE_SSL
  static SSL *tls_conn;
--- 99,107 ----
  
  extern int errno;
  
! #ifdef DRAC_AUTH
! static int drac_enabled;
! #endif /* DRAC_AUTH */
  
  #ifdef HAVE_SSL
  static SSL *tls_conn;
***************
*** 284,289 ****
--- 286,295 ----
         TLS negotiation immediatly */
      if (pop3s == 1) cmd_starttls(1);
  
+ #ifdef DRAC_AUTH
+     drac_enabled = (config_getint("dracinterval", 5) > 0);
+ #endif /* DRAC_AUTH */
+ 
      prot_printf(popd_out, "+OK %s Cyrus POP3 %s server ready\r\n",
  		apop_enabled() ? popd_apop_chal : config_servername,
  		CYRUS_VERSION);
***************
*** 1221,1226 ****
--- 1227,1245 ----
      }
      popd_mailbox = &mboxstruct;
      proc_register("pop3d", popd_clienthost, popd_userid, popd_mailbox->name);
+ 
+ #ifdef DRAC_AUTH
+     if (drac_enabled) {
+ 	char *err;
+ 
+ 	if (dracauth(config_getstring("drachost", "localhost"),
+ 		     popd_remoteaddr.sin_addr.s_addr, &err) != 0) {
+ 	    /* disable DRAC */
+ 	    drac_enabled = 0;
+ 	    syslog(LOG_NOTICE, "dracauth: %s (DISABLED)", err);
+ 	}
+     }
+ #endif /* DRAC_AUTH */
  
      /* Create telemetry log */
      telemetry_log(popd_userid, popd_in, popd_out);
*** man/imapd.conf.5.orig	Wed Mar  7 11:00:51 2001
--- man/imapd.conf.5	Sun Apr  1 14:05:59 2001
***************
*** 224,230 ****
  Unix domain socket that lmtpd listens on.
  .IP "\fBidlesocket:\fR /var/imap/socket/idle" 5
  Unix domain socket that idled listens on.
  .SH SEE ALSO
  .PP
  \fBimapd(8)\fR, \fBpop3d(8)\fR, \fBlmtpd(8)\fR, \fBtimsieved(8)\fR,
! \fBidled(8)\fR, \fBdeliver(8)\fR, \fBmaster(8)\fR
--- 224,236 ----
  Unix domain socket that lmtpd listens on.
  .IP "\fBidlesocket:\fR /var/imap/socket/idle" 5
  Unix domain socket that idled listens on.
+ .IP "\fBdracinterval:\fR 5" 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 dracd server.
  .SH SEE ALSO
  .PP
  \fBimapd(8)\fR, \fBpop3d(8)\fR, \fBlmtpd(8)\fR, \fBtimsieved(8)\fR,
! \fBidled(8)\fR, \fBdeliver(8)\fR, \fBmaster(8)\fR, \fBrpc.dracd(1m)\fR
