From 379e2ba3144d057726f107333521689b862d9f9b Mon Sep 17 00:00:00 2001 From: Art Cancro Date: Wed, 26 Jan 2011 18:08:16 -0500 Subject: [PATCH] Cache the most recently fetched msglist in CtdlForEachMessage() (This will be used for a security check in an upcoming commit) --- citadel/citserver.c | 1 + citadel/context.c | 4 ++++ citadel/context.h | 5 +++-- citadel/msgbase.c | 29 +++++++++++++++++++++-------- 4 files changed, 29 insertions(+), 10 deletions(-) diff --git a/citadel/citserver.c b/citadel/citserver.c index 3bec05b1e..3f9ac42ab 100644 --- a/citadel/citserver.c +++ b/citadel/citserver.c @@ -906,6 +906,7 @@ void begin_session(CitContext *con) con->internal_pgm = 0; con->download_fp = NULL; con->upload_fp = NULL; + con->cached_msglist = NULL; con->FirstExpressMessage = NULL; time(&con->lastcmd); time(&con->lastidle); diff --git a/citadel/context.c b/citadel/context.c index bf34f255e..2b1cce1b0 100644 --- a/citadel/context.c +++ b/citadel/context.c @@ -368,6 +368,10 @@ void RemoveContext (CitContext *con) FreeStrBuf(&con->MigrateBuf); FreeStrBuf(&con->RecvBuf.Buf); + if (con->cached_msglist) { + free(con->cached_msglist); + } + syslog(LOG_DEBUG, "Done with RemoveContext()\n"); } diff --git a/citadel/context.h b/citadel/context.h index 205cf4f1e..4c7c117a5 100644 --- a/citadel/context.h +++ b/citadel/context.h @@ -41,7 +41,7 @@ struct CitContext { struct CitContext *next; /* Link to next session in the list */ int cs_pid; /* session ID */ - int dont_term; /* for special activities like artv so we don't get killed */ + int dont_term; /* for special activities like artv so we don't get killed */ time_t lastcmd; /* time of last command executed */ time_t lastidle; /* For computing idle time */ CCState state; /* thread state (see CON_ values below) */ @@ -131,10 +131,11 @@ struct CitContext { void *openid_data; /* Data stored by the OpenID module */ char *ldap_dn; /* DN of user when using AUTHMODE_LDAP */ - void (*h_command_function) (void) ; /* service command function */ void (*h_async_function) (void) ; /* do async msgs function */ void (*h_greeting_function) (void) ; /* greeting function for session startup */ + + long *cached_msglist; /* results of the previous CtdlForEachMessage() */ }; typedef struct CitContext CitContext; diff --git a/citadel/msgbase.c b/citadel/msgbase.c index ec76c0aed..be46195a4 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -1,9 +1,9 @@ /* * Implements the message store. * - * Copyright (c) 1987-2010 by the citadel.org team + * Copyright (c) 1987-2011 by the citadel.org team * - * This program is free software; you can redistribute it and/or modify + * This program is open source software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "sysdep.h" @@ -633,14 +633,27 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, /* Load the message list */ cdbfr = cdb_fetch(CDB_MSGLISTS, &CC->room.QRnumber, sizeof(long)); - if (cdbfr != NULL) { - msglist = (long *) cdbfr->ptr; - num_msgs = cdbfr->len / sizeof(long); - } else { + if (cdbfr == NULL) { if (need_to_free_re) regfree(&re); return 0; /* No messages at all? No further action. */ } + msglist = (long *) cdbfr->ptr; + num_msgs = cdbfr->len / sizeof(long); + + cdbfr->ptr = NULL; /* clear this so that cdb_free() doesn't free it */ + cdb_free(cdbfr); /* we own this memory now */ + + /* + * We cache the most recent msglist in order to do security checks later + */ + if (CC->client_socket > 0) { + if (CC->cached_msglist != NULL) { + free(CC->cached_msglist); + } + + CC->cached_msglist = msglist; + } /* * Now begin the traversal. @@ -772,8 +785,8 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, ++num_processed; } } - cdb_free(cdbfr); /* Clean up */ if (need_to_free_re) regfree(&re); + if (CC->client_socket <= 0) free(msglist); return num_processed; } -- 2.30.2