[PATCH] Trafficaccounting in a mysql db
Christian Schulte
cs at schulte.it
Wed Apr 23 14:44:59 EDT 2003
Much more efficient in high-load situations and completely configurable
in imapd.conf now!
Do a cvs checkout of 2.2 of the date of the writing of this email. Copy
the attached patch into the toplevel-directory and do patch -p0 <
patchfile. After that do a cvs update to get the current versions and
check for conflicts with the patch which must be corrected afterwards. Than
LIBS="-lmysqlclient" ./configure --...;make;make install
After make install completes successfully read imapd.conf manpage.
--Christian--
-------------- next part --------------
Index: imap/backend.c
===================================================================
RCS file: /cvs/src/cyrus/imap/backend.c,v
retrieving revision 1.7.6.17
diff -u -r1.7.6.17 backend.c
--- imap/backend.c 24 Feb 2003 17:01:15 -0000 1.7.6.17
+++ imap/backend.c 23 Apr 2003 18:38:00 -0000
@@ -259,6 +259,10 @@
}
/* r == SASL_OK on success */
+
+ prot_setlogin(s->in, userid);
+ prot_setlogin(s->out, userid);
+
return r;
}
@@ -308,8 +312,24 @@
memcpy(&ret->addr, res->ai_addr, res->ai_addrlen);
freeaddrinfo(res0);
- ret->in = prot_new(sock, 0);
- ret->out = prot_new(sock, 1);
+ ret->in = prot_new(sock,
+ 0,
+ "BACKEND",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
+ ret->out = prot_new(sock,
+ 1,
+ "BACKEND",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
ret->sock = sock;
prot_setflushonread(ret->in, ret->out);
Index: imap/deliver.c
===================================================================
RCS file: /cvs/src/cyrus/imap/deliver.c,v
retrieving revision 1.164.4.7
diff -u -r1.164.4.7 deliver.c
--- imap/deliver.c 17 Apr 2003 17:00:55 -0000 1.164.4.7
+++ imap/deliver.c 23 Apr 2003 18:38:01 -0000
@@ -266,8 +266,24 @@
}
}
- deliver_in = prot_new(0, 0);
- deliver_out = prot_new(1, 1);
+ deliver_in = prot_new(0,
+ 0,
+ "DELIVER",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
+ deliver_out = prot_new(1,
+ 1,
+ "DELIVER",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
prot_setflushonread(deliver_in, deliver_out);
prot_settimeout(deliver_in, 300);
Index: imap/imapd.c
===================================================================
RCS file: /cvs/src/cyrus/imap/imapd.c,v
retrieving revision 1.398.2.72
diff -u -r1.398.2.72 imapd.c
--- imap/imapd.c 22 Apr 2003 15:55:13 -0000 1.398.2.72
+++ imap/imapd.c 23 Apr 2003 18:38:09 -0000
@@ -503,8 +503,24 @@
id_getcmdline(argc, argv);
#endif
- imapd_in = prot_new(0, 0);
- imapd_out = prot_new(1, 1);
+ imapd_in = prot_new(0,
+ 0,
+ "IMAP",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
+ imapd_out = prot_new(1,
+ 1,
+ "IMAP",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
/* Find out name of client host */
salen = sizeof(imapd_remoteaddr);
@@ -597,7 +613,15 @@
char buf[1024];
char *p;
- motd_in = prot_new(fd, 0);
+ motd_in = prot_new(fd,
+ 0,
+ "MOTD_FILE",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
prot_fgets(buf, sizeof(buf), motd_in);
if ((p = strchr(buf, '\r'))!=NULL) *p = 0;
@@ -1607,6 +1631,10 @@
imapd_clienthost, passwd);
reply = "Anonymous access granted";
imapd_userid = xstrdup("anonymous");
+
+ prot_setlogin(imapd_in, imapd_userid);
+ prot_setlogin(imapd_out, imapd_userid);
+
}
else {
syslog(LOG_NOTICE, "badlogin: %s anonymous login refused",
@@ -1642,6 +1670,10 @@
}
else {
imapd_userid = xstrdup(canon_user);
+
+ prot_setlogin(imapd_in, imapd_userid);
+ prot_setlogin(imapd_out, imapd_userid);
+
snmp_increment_args(AUTHENTICATION_YES, 1,
VARIABLE_AUTH, 0 /*hash_simple("LOGIN") */,
VARIABLE_LISTEND);
@@ -1756,6 +1788,9 @@
}
proc_register("imapd", imapd_clienthost, imapd_userid, (char *)0);
+
+ prot_setlogin(imapd_in, imapd_userid);
+ prot_setlogin(imapd_out, imapd_userid);
syslog(LOG_NOTICE, "login: %s %s %s%s %s", imapd_clienthost, imapd_userid,
authtype, imapd_starttls_done ? "+TLS" : "", "User logged in");
Index: imap/lmtpd.c
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtpd.c,v
retrieving revision 1.99.2.30
diff -u -r1.99.2.30 lmtpd.c
--- imap/lmtpd.c 21 Apr 2003 15:49:56 -0000 1.99.2.30
+++ imap/lmtpd.c 23 Apr 2003 18:38:11 -0000
@@ -250,8 +250,24 @@
{
int opt;
- deliver_in = prot_new(0, 0);
- deliver_out = prot_new(1, 1);
+ deliver_in = prot_new(0,
+ 0,
+ "LMTP",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
+ deliver_out = prot_new(1,
+ 1,
+ "LMTP",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
prot_setflushonread(deliver_in, deliver_out);
prot_settimeout(deliver_in, 360);
Index: imap/lmtpengine.c
===================================================================
RCS file: /cvs/src/cyrus/imap/lmtpengine.c,v
retrieving revision 1.75.4.20
diff -u -r1.75.4.20 lmtpengine.c
--- imap/lmtpengine.c 10 Apr 2003 17:55:17 -0000 1.75.4.20
+++ imap/lmtpengine.c 23 Apr 2003 18:38:13 -0000
@@ -726,7 +726,15 @@
}
m->size = sbuf.st_size;
m->f = f;
- m->data = prot_new(fileno(f), 0);
+ m->data = prot_new(fileno(f),
+ 0,
+ "LMTP_SPOOL",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
return 0;
}
@@ -955,6 +963,10 @@
the AUTH command */
ssf = 2;
auth_id = "postman";
+
+ prot_setlogin(pin, auth_id);
+ prot_setlogin(pout, auth_id);
+
sasl_setprop(cd.conn, SASL_SSF_EXTERNAL, &ssf);
sasl_setprop(cd.conn, SASL_AUTH_EXTERNAL, auth_id);
} else {
@@ -1097,6 +1109,9 @@
authenticated += 2;
prot_printf(pout, "235 Authenticated!\r\n");
+ prot_setlogin(pin, user);
+ prot_setlogin(pout, user);
+
/* set protection layers */
prot_setsasl(pin, cd.conn);
prot_setsasl(pout, cd.conn);
@@ -1892,8 +1907,24 @@
conn->mechs = NULL;
conn->saslconn = NULL;
/* setup prot layers */
- conn->pin = prot_new(sock, 0);
- conn->pout = prot_new(sock, 1);
+ conn->pin = prot_new(sock,
+ 0,
+ "LMTP",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
+ conn->pout = prot_new(sock,
+ 1,
+ "LMTP",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
prot_setflushonread(conn->pin, conn->pout);
/* read greeting */
Index: imap/mupdate-client.c
===================================================================
RCS file: /cvs/src/cyrus/imap/mupdate-client.c,v
retrieving revision 1.32.4.12
diff -u -r1.32.4.12 mupdate-client.c
--- imap/mupdate-client.c 27 Feb 2003 18:39:43 -0000 1.32.4.12
+++ imap/mupdate-client.c 23 Apr 2003 18:38:14 -0000
@@ -201,8 +201,24 @@
free(secprops);
/* create protstream */
- h->pin = prot_new(h->sock, 0);
- h->pout = prot_new(h->sock, 1);
+ h->pin = prot_new(h->sock,
+ 0,
+ "MUPDATE",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
+ h->pout = prot_new(h->sock,
+ 1,
+ "MUPDATE",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
prot_setflushonread(h->pin, h->pout);
prot_settimeout(h->pin, 30*60);
Index: imap/pop3d.c
===================================================================
RCS file: /cvs/src/cyrus/imap/pop3d.c,v
retrieving revision 1.122.4.30
diff -u -r1.122.4.30 pop3d.c
--- imap/pop3d.c 22 Apr 2003 15:55:15 -0000 1.122.4.30
+++ imap/pop3d.c 23 Apr 2003 18:38:16 -0000
@@ -341,8 +341,24 @@
signals_poll();
- popd_in = prot_new(0, 0);
- popd_out = prot_new(1, 1);
+ popd_in = prot_new(0,
+ 0,
+ "POP",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
+ popd_out = prot_new(1,
+ 1,
+ "POP",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
/* Find out name of client host */
salen = sizeof(popd_remoteaddr);
@@ -1042,6 +1058,8 @@
syslog(LOG_NOTICE, "login: %s %s APOP %s",
popd_clienthost, popd_userid, "User logged in");
+ prot_setlogin(popd_in, popd_userid);
+ prot_setlogin(popd_out, popd_userid);
popd_auth_done = 1;
openinbox();
}
@@ -1076,6 +1094,10 @@
}
else {
popd_userid = xstrdup(p);
+
+ prot_setlogin(popd_in, popd_userid);
+ prot_setlogin(popd_out, popd_userid);
+
prot_printf(popd_out, "+OK Name is a valid mailbox\r\n");
}
}
@@ -1304,6 +1326,9 @@
syslog(LOG_NOTICE, "login: %s %s %s %s", popd_clienthost, popd_userid,
authtype, "User logged in");
+
+ prot_setlogin(popd_in, popd_userid);
+ prot_setlogin(popd_out, popd_userid);
popd_auth_done = 1;
openinbox();
Index: imtest/imtest.c
===================================================================
RCS file: /cvs/src/cyrus/imtest/imtest.c,v
retrieving revision 1.82.2.16
diff -u -r1.82.2.16 imtest.c
--- imtest/imtest.c 19 Apr 2003 02:01:45 -0000 1.82.2.16
+++ imtest/imtest.c 23 Apr 2003 18:38:19 -0000
@@ -2443,8 +2443,24 @@
}
/* set up the prot layer */
- pin = prot_new(sock, 0);
- pout = prot_new(sock, 1);
+ pin = prot_new(sock,
+ 0,
+ "IMTEST",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0);
+ pout = prot_new(sock,
+ 1,
+ "IMTEST",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0);
#ifdef HAVE_SSL
if (dossl==1) {
Index: lib/imapoptions
===================================================================
RCS file: /cvs/src/cyrus/lib/Attic/imapoptions,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 imapoptions
--- lib/imapoptions 19 Mar 2003 19:00:39 -0000 1.1.2.5
+++ lib/imapoptions 23 Apr 2003 18:38:20 -0000
@@ -574,7 +574,102 @@
{ "virtdomains", 0, SWITCH }
/* Enable virtual domain support */
-/*
+{ "mysqllogging", 0, SWITCH }
+/* Enable accounting into a mysql db */
+
+{ "mysql_host", "localhost", STRING }
+/* The mysql host to connect to:
+.br
+ For every service-connection to cyrus at least 4 queries
+ to the db will be made each with theire own db connection.
+ If a user authenticates to a service two more queries are
+ done setting the provided login.
+.br
+ Example of db connection liftimes for a typical imap
+ session:
+.br
+ 1. Client establishes the IMAP connection to cyrus
+.br
+ imapd connects to mysql, issues an INSERT query for the
+ input stream and disconnects from mysql
+.br
+ imapd connects to mysql, issues an INSERT query for the
+ output stream and disconnects from mysql
+.br
+ imapd does not have any active mysql connections after that
+.br
+ 2. Client authenticates successfully
+.br
+ imapd connects to mysql, issues an UPDATE query setting the
+ successfully authenticated user for the input stream and
+ disconnects from mysql
+.br
+ imapd connects to mysql, issues an UPDATE query setting the
+ successfully authenticated user for the output stream and
+ disconnects from mysql
+.br
+ imapd does not have any active mysql connections after that
+.br
+ 3. Client disconnects
+.br
+ imapd connects to mysql, issues an UPDATE query setting the
+ disconnect_time and the amount of transferred bytes for the
+ input stream and disconnects from mysql
+.br
+ imapd connects to mysql, issues an UPDATE query setting the
+ disconnect_time and the amount of transferred bytes for the
+ output stream and disconnects from mysql
+.br
+ imapd terminates
+.br
+.br
+ So a typical IMAP session leads to 6 database connections.
+ Because an IMAP connection can be active for very long time,
+ the last update queries during disconnection could be done
+ hours after the first insert queries during connecting.
+ You should set a default value for the disconnect_time
+ field as an indicator for currently active connections!
+ The disconnect_time field will only be used in the last
+ query during disconnecting and so a row containing your
+ default value will indicate a currently active connection! */
+
+
+{ "mysql_user", NULL, STRING }
+/* The mysql user to connect with */
+
+{ "mysql_pass", NULL, STRING }
+/* The mysql password to use. Defaults to no password */
+
+{ "mysql_db", "cyrus", STRING }
+/* The database to use */
+
+{ "mysql_table", "cyrus_accounting", STRING }
+/* The table to use in mysql_db. Fieldnames are hardcoded:
+.br
+.br
+ id int(11) NOT NULL auto_increment
+.br
+ login varchar(128) NOT NULL default ''
+.br
+ service varchar(30) NOT NULL default ''
+.br
+ bytes double NOT NULL default '0'
+.br
+ type enum('IN','OUT','UNSPECIFIED') NOT NULL default 'UNSPECIFIED'
+.br
+ connect_time datetime default NULL
+.br
+ disconnect_time datetime NOT NULL default '0000-00-00 00:00:00'
+.br
+ PRIMARY KEY (id)
+.br
+ KEY connect_time (connect_time)
+.br
+ KEY login (login)
+.br
+ KEY disconnect_time (disconnect_time)
+.br */
+
.SH SEE ALSO
.PP
\fBimapd(8)\fR, \fBpop3d(8)\fR, \fBlmtpd(8)\fR, \fBtimsieved(8)\fR,
Index: lib/prot.c
===================================================================
RCS file: /cvs/src/cyrus/lib/prot.c,v
retrieving revision 1.72.4.17
diff -u -r1.72.4.17 prot.c
--- lib/prot.c 31 Mar 2003 21:48:25 -0000 1.72.4.17
+++ lib/prot.c 23 Apr 2003 18:38:22 -0000
@@ -73,6 +73,8 @@
#include "util.h"
#include "xmalloc.h"
+char buf[1024];
+
/* Transparant protgroup structure */
struct protgroup
{
@@ -81,19 +83,45 @@
struct protstream **group;
};
+/* Added by mysql-accounting.patch by <cs at schulte.it>
+ * perform a mysql query
+ *
+ * store = 1: set to update the protstream->primkey member
+ * store = 0: just execute the query and log all errors which occure
+ */
+void _query_mysql(struct protstream *s, const char *query, int store) {
+ if(! mysql_init(&s->mysql) ) {
+ sprintf(buf, "MYSQL: mysql_init() failed:%s", mysql_error(&s->mysql));
+ syslog(LOG_ERR, buf);
+ }
+ else
+ if(! mysql_connect(&s->mysql, s->mysql_host, s->mysql_user, s->mysql_pass) ) {
+ sprintf(buf, "MYSQL: mysql_connect() failed:%s", mysql_error(&s->mysql));
+ syslog(LOG_ERR, buf);
+ }
+ else
+ if( mysql_query(&s->mysql, query) ) {
+ syslog(LOG_ERR, buf);
+ sprintf(buf, "MYSQL: mysql_query() failed:%s", mysql_error(&s->mysql));
+ syslog(LOG_ERR, buf);
+ }
+ else
+ if(store)
+ s->primkey=(unsigned long)mysql_insert_id(&s->mysql);
+ mysql_close(&s->mysql);
+}
+
+
/*
* Create a new protection stream for file descriptor 'fd'. Stream
* will be used for writing iff 'write' is nonzero.
*/
-struct protstream *prot_new(fd, write)
-int fd;
-int write;
+struct protstream *prot_new(int fd,int write,const char *service,const char *mysql_host,const char *mysql_user,const char *mysql_pass,const char *mysql_db,const char *mysql_table,int mysqllogging)
{
struct protstream *newstream;
newstream = (struct protstream *) xzmalloc(sizeof(struct protstream));
- newstream->buf = (unsigned char *)
- xmalloc(sizeof(char) * (PROT_BUFSIZE));
+ newstream->buf = (unsigned char *) xmalloc(sizeof(char) * (PROT_BUFSIZE));
newstream->buf_size = PROT_BUFSIZE;
newstream->ptr = newstream->buf;
newstream->maxplain = PROT_BUFSIZE;
@@ -101,9 +129,25 @@
newstream->write = write;
newstream->logfd = PROT_NO_FD;
newstream->big_buffer = PROT_NO_FD;
+ newstream->bytes=0;
+ newstream->primkey=0;
+ newstream->mysql_host = mysql_host;
+ newstream->mysql_user = mysql_user;
+ newstream->mysql_pass = mysql_pass;
+ newstream->mysql_db = mysql_db;
+ newstream->mysql_table = mysql_table;
+ newstream->mysqllogging = mysqllogging;
if(write)
newstream->cnt = PROT_BUFSIZE;
-
+ if(mysqllogging) {
+ sprintf(buf, "INSERT INTO %s.%s (service, bytes, type, connect_time) VALUES ('%s',%d,'%s',SYSDATE())",
+ newstream->mysql_db,
+ newstream->mysql_table,
+ service,
+ 0,
+ write ? "OUT" : "IN");
+ _query_mysql(newstream, buf, 1);
+ }
return newstream;
}
@@ -112,6 +156,7 @@
*/
int prot_free(struct protstream *s)
{
+
if (s->error) free(s->error);
free(s->buf);
@@ -119,9 +164,19 @@
map_free(&(s->bigbuf_base), &(s->bigbuf_siz));
close(s->big_buffer);
}
-
+ if( s->mysqllogging ) {
+ if(s->primkey != 0) {
+ sprintf(buf,
+ "UPDATE %s.%s SET disconnect_time=SYSDATE(),bytes=%lu WHERE id=%lu",
+ s->mysql_db,
+ s->mysql_table,
+ s->bytes, s->primkey);
+ _query_mysql(s, buf, 0);
+ }
+ else
+ syslog(LOG_ERR, "prot_free did not have a primary db key to update the row");
+ }
free((char*)s);
-
return 0;
}
@@ -134,6 +189,28 @@
return 0;
}
+/*
+ * Set the the authenticated userid if it is known'.
+ */
+void prot_setlogin(struct protstream *s, const char *userid)
+{
+ if( s->mysqllogging ) {
+ if( s->primkey==0 ) {
+ syslog(LOG_ERR, "prot_setlogin did not have a primary db key to update the row");
+ }
+ else {
+ sprintf(buf,
+ "UPDATE %s.%s SET login='%s' WHERE id=%lu",
+ s->mysql_db,
+ s->mysql_table,
+ userid,
+ s->primkey);
+ _query_mysql(s, buf, 0);
+ }
+ }
+}
+
+
#ifdef HAVE_SSL
/*
@@ -499,8 +576,9 @@
s->ptr = s->buf+1;
s->cnt = n;
}
-
+
if (s->cnt > 0) {
+ s->bytes+=s->cnt;
if (s->logfd != -1) {
time_t newtime;
char timebuf[20];
@@ -534,6 +612,7 @@
*/
int prot_flush(struct protstream *s)
{
+ s->bytes+=strlen(s->buf);
return prot_flush_internal(s, 1);
}
@@ -832,7 +911,8 @@
assert(s->write);
if(s->error || s->eof) return EOF;
if(len == 0) return 0;
-
+
+ s->bytes+=len;
while (len >= s->cnt) {
/* XXX can we manage to write data from 'buf' without copying it
to s->ptr ? */
@@ -1246,6 +1326,7 @@
assert(s->write);
assert(s->cnt > 0);
+ s->bytes+=1;
*s->ptr++ = c;
if (--s->cnt == 0) {
return prot_flush_internal(s,0);
Index: lib/prot.h
===================================================================
RCS file: /cvs/src/cyrus/lib/prot.h,v
retrieving revision 1.35.4.7
diff -u -r1.35.4.7 prot.h
--- lib/prot.h 13 Feb 2003 20:33:14 -0000 1.35.4.7
+++ lib/prot.h 23 Apr 2003 18:38:23 -0000
@@ -51,6 +51,7 @@
#include <stdlib.h>
#include <sasl/sasl.h>
+#include <mysql/mysql.h>
#ifdef HAVE_SSL
#include <openssl/ssl.h>
@@ -111,6 +112,16 @@
/* For use by applications */
void *userdata;
+
+ unsigned long primkey;
+ unsigned long bytes;
+ MYSQL mysql;
+ const char *mysql_host;
+ const char *mysql_user;
+ const char *mysql_pass;
+ const char *mysql_db;
+ const char *mysql_table;
+ int mysqllogging;
};
typedef struct prot_waitevent *prot_waiteventcallback_t(struct protstream *s,
@@ -160,11 +171,15 @@
#define prot_IS_BLOCKING(s) ((s)->dontblock == 0)
/* Allocate/free the protstream structure */
-extern struct protstream *prot_new(int fd, int write);
+extern struct protstream *prot_new(int fd,int write,const char *service,const char *mysql_host,const char *mysql_user,const char *mysql_pass,const char *mysql_db,const char *mysql_table,int mysqllogging);
+
extern int prot_free(struct protstream *s);
/* Set the telemetry logfile for a given protstream */
extern int prot_setlog(struct protstream *s, int fd);
+
+/* Set the userid of this stream for storage in MySQL db */
+extern void prot_setlogin(struct protstream *s, const char *userid);
/* Set the SASL options for a protstream (requires authentication to
* be complete for the given sasl_conn_t */
Index: perl/sieve/lib/isieve.c
===================================================================
RCS file: /cvs/src/cyrus/perl/sieve/lib/isieve.c,v
retrieving revision 1.24.4.4
diff -u -r1.24.4.4 isieve.c
--- perl/sieve/lib/isieve.c 13 Feb 2003 20:33:28 -0000 1.24.4.4
+++ perl/sieve/lib/isieve.c 23 Apr 2003 18:38:24 -0000
@@ -151,8 +151,24 @@
(*obj)->port = port;
/* set up the prot layer */
- (*obj)->pin = prot_new(sock, 0);
- (*obj)->pout = prot_new(sock, 1);
+ (*obj)->pin = prot_new(sock,
+ 0,
+ "SIEVE",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0);
+ (*obj)->pout = prot_new(sock,
+ 1,
+ "SIEVE",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0);
return 0;
}
Index: timsieved/parser.c
===================================================================
RCS file: /cvs/src/cyrus/timsieved/parser.c,v
retrieving revision 1.20.4.10
diff -u -r1.20.4.10 parser.c
--- timsieved/parser.c 13 Feb 2003 20:33:36 -0000 1.20.4.10
+++ timsieved/parser.c 23 Apr 2003 18:38:25 -0000
@@ -636,6 +636,9 @@
}
username = xstrdup(canon_user);
+ prot_setlogin(sieved_in, username);
+ prot_setlogin(sieved_out, username);
+
verify_only = !strcmp(username, "anonymous");
if (!verify_only) {
Index: timsieved/timsieved.c
===================================================================
RCS file: /cvs/src/cyrus/timsieved/timsieved.c,v
retrieving revision 1.40.4.12
diff -u -r1.40.4.12 timsieved.c
--- timsieved/timsieved.c 13 Feb 2003 20:33:36 -0000 1.40.4.12
+++ timsieved/timsieved.c 23 Apr 2003 18:38:26 -0000
@@ -217,8 +217,24 @@
char hbuf[NI_MAXHOST];
/* set up the prot streams */
- sieved_in = prot_new(0, 0);
- sieved_out = prot_new(1, 1);
+ sieved_in = prot_new(0,
+ 0,
+ "SIEVE",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
+ sieved_out = prot_new(1,
+ 1,
+ "SIEVE",
+ config_getstring(IMAPOPT_MYSQL_HOST),
+ config_getstring(IMAPOPT_MYSQL_USER),
+ config_getstring(IMAPOPT_MYSQL_PASS),
+ config_getstring(IMAPOPT_MYSQL_DB),
+ config_getstring(IMAPOPT_MYSQL_TABLE),
+ config_getswitch(IMAPOPT_MYSQLLOGGING) );
timeout = config_getint(IMAPOPT_TIMEOUT);
if (timeout < 10) timeout = 10;
More information about the Info-cyrus
mailing list