X-Git-Url: https://code.citadel.org/?a=blobdiff_plain;f=citadel%2Fmsgbase.c;h=7eb321905315c9b2313e81cf0639729cb8891ebe;hb=e26a8dee20d1726b4995821f717f867f50fc5659;hp=c1387c2c093b1e8bf0241268a3e46e991baf3de3;hpb=f51cc3830485ab05801c37ddbf0c51a5e68100ef;p=citadel.git diff --git a/citadel/msgbase.c b/citadel/msgbase.c index c1387c2c0..7eb321905 100644 --- a/citadel/msgbase.c +++ b/citadel/msgbase.c @@ -593,56 +593,6 @@ void CtdlSetSeen(long *target_msgnums, int num_target_msgnums, } - -/* store a value in the binary tree */ -void seenit_store(struct seenit **si, long msgnum) { - struct seenit *this_si; - - if (*si == NULL) { /* store now */ - *si = malloc(sizeof(struct seenit)); - this_si = *si; - this_si->l = NULL; - this_si->r = NULL; - this_si->msgnum = msgnum; - return; - } - - this_si = *si; - if (msgnum < this_si->msgnum) { - seenit_store(&this_si->l, msgnum); - } - else if (msgnum > this_si->msgnum) { - seenit_store(&this_si->r, msgnum); - } - else { - return; - } -} - - -/* search for a value in the binary tree */ -int seenit_isthere(struct seenit *si, long msgnum) { - if (!si) return(0); /* not there */ - if (msgnum < si->msgnum) return(seenit_isthere(si->l, msgnum)); - if (msgnum > si->msgnum) return(seenit_isthere(si->r, msgnum)); - return(1); /* found it */ -} - - -/* free the binary tree */ -void seenit_free(struct seenit **si) { - struct seenit *this_si = *si; - if (!this_si) return; - seenit_free(&this_si->l); - seenit_free(&this_si->r); - free(this_si); - *si = NULL; -} - - - - - /* * API function to perform an operation for each qualifying message in the * current room. (Returns the number of messages processed.) @@ -695,33 +645,10 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, cdb_free(cdbfr); /* we own this memory now */ /* -<<<<<<< HEAD -======= - * 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; - CC->cached_num_msgs = num_msgs; - syslog(LOG_DEBUG, "\033[34m RELOAD \033[0m\n"); - } - - /* ->>>>>>> parent of 4ec6a9d... Updating cmd_euid() to use the CtdlForEachMessage() API fixes the security check in blog view and saves some code * Now begin the traversal. */ if (num_msgs > 0) for (a = 0; a < num_msgs; ++a) { - /* - * cache the msgnums we've seen in order to perform security checks later - */ - if (CC->client_socket > 0) { - seenit_store(&CC->cached_msglist, msglist[a]); - } - /* If the caller is looking for a specific MIME type, filter * out all messages which are not of the type requested. */ @@ -848,7 +775,21 @@ int CtdlForEachMessage(int mode, long ref, char *search_string, } } if (need_to_free_re) regfree(&re); - free(msglist); + + /* + * 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; + CC->cached_num_msgs = num_msgs; + } + else { + free(msglist); + } + return num_processed; } @@ -1165,6 +1106,10 @@ void mime_download(char *name, char *filename, char *partnum, char *disp, return; rv = fwrite(content, length, 1, CC->download_fp); + if (rv == -1) { + syslog(LOG_EMERG, "mime_download(): Couldn't write: %s\n", + strerror(errno)); + } fflush(CC->download_fp); rewind(CC->download_fp); @@ -1617,17 +1562,14 @@ int check_cached_msglist(long msgnum) { if (!CC) return om_ok; /* not a session */ if (CC->client_socket <= 0) return om_ok; /* not a client session */ if (CC->cached_msglist == NULL) return om_access_denied; /* no msglist fetched */ + if (CC->cached_num_msgs == 0) return om_access_denied; /* nothing to check */ + -<<<<<<< HEAD - if (seenit_isthere(CC->cached_msglist, msgnum)) { - return om_ok; -======= /* Do a binary search within the cached_msglist for the requested msgnum */ int min = 0; int max = (CC->cached_num_msgs - 1); while (max >= min) { - syslog(LOG_DEBUG, "\033[35m Checking from %d to %d \033[0m\n", min, max); int middle = min + (max-min) / 2 ; if (msgnum == CC->cached_msglist[middle]) { return om_ok; @@ -1638,7 +1580,6 @@ int check_cached_msglist(long msgnum) { else { max = middle - 1; } ->>>>>>> parent of 4ec6a9d... Updating cmd_euid() to use the CtdlForEachMessage() API fixes the security check in blog view and saves some code } return om_access_denied; @@ -1695,37 +1636,29 @@ int CtdlOutputMsg(long msg_num, /* message number (local) to fetch */ return(r); } + /* + * Check to make sure the message is actually IN this room + */ r = check_cached_msglist(msg_num); -<<<<<<< HEAD -<<<<<<< HEAD + if (r == om_access_denied) { + /* Not in the cache? We get ONE shot to check it again. */ + CtdlForEachMessage(MSGS_ALL, 0L, NULL, NULL, NULL, NULL, NULL); + r = check_cached_msglist(msg_num); + } if (r != om_ok) { - syslog(LOG_DEBUG, "Denying access to message %ld - not yet listed\n", msg_num); + syslog(LOG_DEBUG, "Security check fail: message %ld is not in %s\n", + msg_num, CC->room.QRname + ); if (do_proto) { if (r == om_access_denied) { - cprintf("%d Message %ld was not found in this room.\n", - ERROR + MESSAGE_NOT_FOUND, + cprintf("%d message %ld was not found in this room\n", + ERROR + HIGHER_ACCESS_REQUIRED, msg_num ); } - else { - cprintf("%d An unknown error has occurred.\n", ERROR); - } - return(r); } -======= -======= ->>>>>>> parent of 4ec6a9d... Updating cmd_euid() to use the CtdlForEachMessage() API fixes the security check in blog view and saves some code - if (r == om_ok) { - syslog(LOG_DEBUG, "\033[32m PASS \033[0m\n"); - } - else { - syslog(LOG_DEBUG, "\033[31m FAIL \033[0m\n"); -<<<<<<< HEAD ->>>>>>> parent of 4ec6a9d... Updating cmd_euid() to use the CtdlForEachMessage() API fixes the security check in blog view and saves some code -======= ->>>>>>> parent of 4ec6a9d... Updating cmd_euid() to use the CtdlForEachMessage() API fixes the security check in blog view and saves some code + return(r); } - /* FIXME after testing, this is where we deny access */ /* * Fetch the message from disk. If we're in HEADERS_FAST mode, @@ -2026,6 +1959,7 @@ void OutputRFC822MsgHeaders( int i, j, k; char *mptr = NULL; char *mpptr = NULL; + char *hptr; for (i = 0; i < 256; ++i) { if (TheMessage->cm_fields[i]) { @@ -2051,7 +1985,11 @@ void OutputRFC822MsgHeaders( else if (i == 'V') { if ((flags & QP_EADDR) != 0) mptr = qp_encode_email_addrs(mptr); - cprintf("Envelope-To: %s%s", mptr, nl); + hptr = mptr; + while ((*hptr != '\0') && isspace(*hptr)) + hptr ++; + if (!IsEmptyStr(hptr)) + cprintf("Envelope-To: %s%s", hptr, nl); } else if (i == 'U') { cprintf("Subject: %s%s", mptr, nl); @@ -2104,7 +2042,11 @@ void OutputRFC822MsgHeaders( } } else if (i == 'K') { - cprintf("Reply-To: <%s>%s", mptr, nl); + hptr = mptr; + while ((*hptr != '\0') && isspace(*hptr)) + hptr ++; + if (!IsEmptyStr(hptr)) + cprintf("Reply-To: %s%s", mptr, nl); } if (mptr != mpptr) free (mptr); @@ -2130,7 +2072,6 @@ void Dump_RFC822HeadersBody( int outlen = 0; int nllen = strlen(nl); char *mptr; - int rc; mptr = TheMessage->cm_fields['M']; @@ -2190,7 +2131,7 @@ void Dump_RFC822HeadersBody( } } if (outlen > 0) { - rc = client_write(outbuf, outlen); + client_write(outbuf, outlen); outlen = 0; } } @@ -2869,7 +2810,11 @@ long send_message(struct CtdlMessage *msg) { /* Get a new message number */ newmsgid = get_new_message_number(); - snprintf(msgidbuf, sizeof msgidbuf, "%010ld@%s", newmsgid, config.c_fqdn); + snprintf(msgidbuf, sizeof msgidbuf, "%08lX-%08lX@%s", + (long unsigned int) time(NULL), + (long unsigned int) newmsgid, + config.c_fqdn + ); /* Generate an ID if we don't have one already */ if (msg->cm_fields['I']==NULL) { @@ -2992,7 +2937,6 @@ void serialize_message(struct ser_ret *ret, /* return values */ void dump_message(struct CtdlMessage *msg, /* unserialized msg */ long Siz) /* how many chars ? */ { - size_t wlen; int i; static char *forder = FORDER; char *buf; @@ -3007,8 +2951,6 @@ void dump_message(struct CtdlMessage *msg, /* unserialized msg */ buf = (char*) malloc (Siz + 1); - wlen = 3; - for (i=0; i<26; ++i) if (msg->cm_fields[(int)forder[i]] != NULL) { snprintf (buf, Siz, " msg[%c] = %s ...\n", (char) forder[i], msg->cm_fields[(int)forder[i]]); @@ -3366,6 +3308,10 @@ long CtdlSubmitMsg(struct CtdlMessage *msg, /* message to save */ network_fp = fopen(submit_filename, "wb+"); if (network_fp != NULL) { rv = fwrite(smr.ser, smr.len, 1, network_fp); + if (rv == -1) { + syslog(LOG_EMERG, "CtdlSubmitMsg(): Couldn't write network spool file: %s\n", + strerror(errno)); + } fclose(network_fp); } free(smr.ser); @@ -4006,30 +3952,36 @@ int CtdlDoIHavePermissionToPostInThisRoom( if ((CC->user.axlevel < AxProbU) && ((CC->room.QRflags & QR_MAILBOX) == 0)) { - snprintf(errmsgbuf, n, "Need to be validated to enter " - "(except in %s> to sysop)", MAILROOM); + snprintf(errmsgbuf, n, "Need to be validated to enter (except in %s> to sysop)", MAILROOM); return (ERROR + HIGHER_ACCESS_REQUIRED); } CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL); - if ( (!(ra & UA_POSTALLOWED)) && (ra & UA_REPLYALLOWED) && (!is_reply) ) { + if (ra & UA_POSTALLOWED) { + strcpy(errmsgbuf, "OK to post or reply here"); + return(0); + } + + if ( (ra & UA_REPLYALLOWED) && (is_reply) ) { /* * To be thorough, we ought to check to see if the message they are * replying to is actually a valid one in this room, but unless this * actually becomes a problem we'll go with high performance instead. */ - snprintf(errmsgbuf, n, "You may only reply to existing messages here."); - return (ERROR + HIGHER_ACCESS_REQUIRED); + strcpy(errmsgbuf, "OK to reply here"); + return(0); } - else if (!(ra & UA_POSTALLOWED)) { - snprintf(errmsgbuf, n, "Higher access is required to post in this room."); + if ( (ra & UA_REPLYALLOWED) && (!is_reply) ) { + /* Clarify what happened with a better error message */ + snprintf(errmsgbuf, n, "You may only reply to existing messages here."); return (ERROR + HIGHER_ACCESS_REQUIRED); } - strcpy(errmsgbuf, "Ok"); - return(0); + snprintf(errmsgbuf, n, "Higher access is required to post in this room."); + return (ERROR + HIGHER_ACCESS_REQUIRED); + } @@ -5020,6 +4972,11 @@ void AdjRefCount(long msgnum, int incr) new_arcq.arcq_msgnum = msgnum; new_arcq.arcq_delta = incr; rv = fwrite(&new_arcq, sizeof(struct arcq), 1, arcfp); + if (rv == -1) { + syslog(LOG_EMERG, "Couldn't write Refcount Queue File %s: %s\n", + file_arcq, + strerror(errno)); + } fflush(arcfp); return;