CtdlRoomAccess() can now return a new value UA_REPLYALLOWED, which
authorArt Cancro <ajc@citadel.org>
Tue, 14 Sep 2010 13:50:32 +0000 (09:50 -0400)
committerArt Cancro <ajc@citadel.org>
Tue, 14 Sep 2010 13:50:32 +0000 (09:50 -0400)
indicates that the user may post a message to this room *if* it is
a reply to an existing message.

CtdlDoIHavePermissionToPostInThisRoom() now must be told whether
the user is replying to an existing message or posting a top-level
message.  If it is a reply, UA_REPLYALLOWED is checked.  If it is
a top-level message, UA_POSTALLOWED is checked.  If UA_POSTALLOWED
is not set, but UA_REPLYALLOWED is set, and the message is not a
reply, a new error message indicates that the user may only reply
to existing messages.  I may add a new error code for this later.

citadel/ipcdef.h
citadel/msgbase.c
citadel/msgbase.h
citadel/room_ops.c

index a350069bae801a60985f774e8b693586a0a550c7..f155a6e97fd01929c73ab36ca52c1b8ef172075d 100644 (file)
@@ -77,13 +77,14 @@ extern "C" {
                        US_NOPROMPT | US_DISAPPEAR | US_PAGINATOR | \
                        US_FLOORS | US_COLOR | US_PROMPTCTL | US_EXTEDIT)
 
-#define UA_KNOWN                2
-#define UA_GOTOALLOWED          4
-#define UA_HASNEWMSGS           8
-#define UA_ZAPPED               16
-#define UA_POSTALLOWED         32
-#define UA_ADMINALLOWED                64
-#define UA_DELETEALLOWED       128
+#define UA_KNOWN                2      /* Room appears in a 'known rooms' list */
+#define UA_GOTOALLOWED          4      /* User may goto this room if specified by exact name */
+#define UA_HASNEWMSGS           8      /* Unread messages exist in this room */
+#define UA_ZAPPED               16     /* User has forgotten (zapped) this room */
+#define UA_POSTALLOWED         32      /* User may post top-level messages here */
+#define UA_ADMINALLOWED                64      /* Aide or Room Aide rights exist here */
+#define UA_DELETEALLOWED       128     /* User is allowed to delete messages from this room */
+#define UA_REPLYALLOWED                256     /* User is allowed to reply to existing messages here */
 
 #ifdef __cplusplus
 }
index a34530828c423528d04865b171f20919dfba587d..a2224a8b5edcdf552afc328b344ea5629173ac0e 100644 (file)
@@ -3599,10 +3599,13 @@ struct CtdlMessage *CtdlMakeMessage(
  * room.  Returns a *CITADEL ERROR CODE* and puts a message in errmsgbuf, or
  * returns 0 on success.
  */
-int CtdlDoIHavePermissionToPostInThisRoom(char *errmsgbuf, 
-                                         size_t n, 
-                                         const char* RemoteIdentifier,
-                                         int PostPublic) {
+int CtdlDoIHavePermissionToPostInThisRoom(
+       char *errmsgbuf, 
+       size_t n, 
+       const char* RemoteIdentifier,
+       int PostPublic,
+       int is_reply
+) {
        int ra;
 
        if (!(CC->logged_in) && 
@@ -3667,7 +3670,18 @@ int CtdlDoIHavePermissionToPostInThisRoom(char *errmsgbuf,
        }
 
        CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
-       if (!(ra & UA_POSTALLOWED)) {
+
+       if ( (!(ra & UA_POSTALLOWED)) && (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);
+       }
+
+       else if (!(ra & UA_POSTALLOWED)) {
                snprintf(errmsgbuf, n, "Higher access is required to post in this room.");
                return (ERROR + HIGHER_ACCESS_REQUIRED);
        }
@@ -3827,10 +3841,12 @@ struct recptypes *validate_recipients(const char *supplied_recipients,
                                        CC->room = tempQR;
                                        
                                        /* Check permissions to send mail to this room */
-                                       err = CtdlDoIHavePermissionToPostInThisRoom(errmsg, 
-                                                                                   sizeof errmsg, 
-                                                                                   RemoteIdentifier,
-                                                                                   Flags
+                                       err = CtdlDoIHavePermissionToPostInThisRoom(
+                                               errmsg, 
+                                               sizeof errmsg, 
+                                               RemoteIdentifier,
+                                               Flags,
+                                               0                       /* 0 = not a reply */
                                        );
                                        if (err)
                                        {
@@ -4033,7 +4049,13 @@ void cmd_ent0(char *entargs)
 
        /* first check to make sure the request is valid. */
 
-       err = CtdlDoIHavePermissionToPostInThisRoom(errmsg, sizeof errmsg, NULL, POST_LOGGED_IN);
+       err = CtdlDoIHavePermissionToPostInThisRoom(
+               errmsg,
+               sizeof errmsg,
+               NULL,
+               POST_LOGGED_IN,
+               (!IsEmptyStr(references))               /* is this a reply?  or a top-level post? */
+       );
        if (err)
        {
                cprintf("%d %s\n", err, errmsg);
index 5bbd7aef6a10e1f005f0e86844887c63eb3ed56a..039a8a1bbd5da01ccb49050889a81a03eaa1c4c8 100644 (file)
@@ -186,10 +186,13 @@ enum {
        CHECK_EXISTANCE,
        POST_LMTP
 };
+
 int CtdlDoIHavePermissionToPostInThisRoom(char *errmsgbuf, 
-                                         size_t n, 
-                                         const char* RemoteIdentifier,
-                                         int PostPublic);
+       size_t n, 
+       const char* RemoteIdentifier,
+       int PostPublic,
+       int is_reply
+);
 
 
 /* values for which_set */
index 68eeb36385971435d6f9e2accc12de4f29cd7d04..22e0cb2dd9e7c51d75a7d6341d0c3b81133d3b62 100644 (file)
@@ -65,7 +65,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
 
        /* for internal programs, always do everything */
        if (((CC->internal_pgm)) && (roombuf->QRflags & QR_INUSE)) {
-               retval = (UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED);
+               retval = (UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED);
                vbuf.v_view = 0;
                goto SKIP_EVERYTHING;
        }
@@ -88,7 +88,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
        /* Force the properties of the Aide room */
        if (!strcasecmp(roombuf->QRname, config.c_aideroom)) {
                if (userbuf->axlevel >= AxAideU) {
-                       retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED;
+                       retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
                } else {
                        retval = 0;
                }
@@ -130,11 +130,11 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
        /* Also, mailbox owners can delete their messages */
        if (roombuf->QRflags & QR_MAILBOX) {
                if (userbuf->usernum == atol(roombuf->QRname)) {
-                       retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED;
+                       retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
                }
                /* An explicit match means the user belongs in this room */
                if (vbuf.v_flags & V_ACCESS) {
-                       retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED;
+                       retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
                }
        }
 
@@ -151,7 +151,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
                if ((userbuf->axlevel < AxNetU) && (roombuf->QRflags & QR_NETWORK)) post_allowed = 0;
                if (roombuf->QRflags & QR_READONLY) post_allowed = 0;
                if (post_allowed) {
-                       retval = retval | UA_POSTALLOWED;
+                       retval = retval | UA_POSTALLOWED | UA_REPLYALLOWED;
                }
 
                /* If "collaborative deletion" is active for this room, any user who can post
@@ -177,17 +177,17 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
        }
        /* If user is explicitly locked out of this room, deny everything */
        if (vbuf.v_flags & V_LOCKOUT) {
-               retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED & ~UA_POSTALLOWED;
+               retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED & ~UA_POSTALLOWED & ~UA_REPLYALLOWED;
        }
 
        /* Aides get access to all private rooms */
        if ( (userbuf->axlevel >= AxAideU)
           && ((roombuf->QRflags & QR_MAILBOX) == 0) ) {
                if (vbuf.v_flags & V_FORGET) {
-                       retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED;
+                       retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
                }
                else {
-                       retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED;
+                       retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
                }
        }
 
@@ -196,14 +196,14 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf,
         */
        if ( (userbuf->axlevel >= AxAideU)
           && (roombuf->QRflags & QR_MAILBOX) ) {
-               retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED;
+               retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
        }
 
        /* Aides and Room Aides have admin privileges */
        if ( (userbuf->axlevel >= AxAideU)
           || (userbuf->usernum == roombuf->QRroomaide)
           ) {
-               retval = retval | UA_ADMINALLOWED | UA_DELETEALLOWED | UA_POSTALLOWED;
+               retval = retval | UA_ADMINALLOWED | UA_DELETEALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
        }
 
 NEWMSG:        /* By the way, we also check for the presence of new messages */