When checking to see whether we have to rebind a new key and/or
[citadel.git] / citadel / room_ops.c
index 44573dae34d985470c823f491b9005dba760efb8..5b84fd36636c2c063e6065c1740abb03b24bffd8 100644 (file)
@@ -1,16 +1,14 @@
-/* 
- * Server functions which perform operations on room objects.
- *
- * Copyright (c) 1987-2021 by the citadel.org team
- *
- * This program is open source software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License, version 3.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- */
+// Server functions which perform operations on room objects.
+//
+// Copyright (c) 1987-2022 by the citadel.org team
+//
+// This program is open source software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License, version 3.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
 
 #include <stdio.h>
 #include <libcitadel.h>
 
 struct floor *floorcache[MAXFLOORS];
 
-/* 
- * Determine whether the currently logged in session has permission to read
- * messages in the current room.
- */
+// Determine whether the currently logged in session has permission to read
+// messages in the current room.
 int CtdlDoIHavePermissionToReadMessagesInThisRoom(void) {
        if (    (!(CC->logged_in))
                && (!(CC->internal_pgm))
@@ -39,11 +35,9 @@ int CtdlDoIHavePermissionToReadMessagesInThisRoom(void) {
 }
 
 
-/*
- * Check to see whether we have permission to post a message in the current
- * room.  Returns a *CITADEL ERROR CODE* and puts a message in errmsgbuf, or
- * returns 0 on success.
- */
+// Check to see whether we have permission to post a message in the current
+// room.  Returns a *CITADEL ERROR CODE* and puts a message in errmsgbuf, or
+// returns 0 on success.
 int CtdlDoIHavePermissionToPostInThisRoom(
        char *errmsgbuf, 
        size_t n, 
@@ -57,7 +51,7 @@ int CtdlDoIHavePermissionToPostInThisRoom(
                snprintf(errmsgbuf, n, "Not logged in.");
                return (ERROR + NOT_LOGGED_IN);
        }
-       else if (PostPublic == CHECK_EXISTANCE) {
+       else if (PostPublic == CHECK_EXIST) {
                return (0);                                     // evaluate whether a recipient exists
        }
        else if (!(CC->logged_in)) {
@@ -65,14 +59,6 @@ int CtdlDoIHavePermissionToPostInThisRoom(
                        snprintf(errmsgbuf, n, "Not logged in.");
                        return (ERROR + NOT_LOGGED_IN);
                }
-               if (CC->room.QRflags2 & QR2_MODERATED) {
-                       snprintf(errmsgbuf, n, "Not logged in Moderation feature not yet implemented!");
-                       return (ERROR + NOT_LOGGED_IN);
-               }
-               // FIXME what was this?  AJC 2021
-               //if ((PostPublic != POST_LMTP) && (CC->room.QRflags2 & QR2_SMTP_PUBLIC) == 0) {
-                       //return CtdlNetconfigCheckRoomaccess(errmsgbuf, n, RemoteIdentifier);
-               //}
                return (0);
        }
 
@@ -89,17 +75,15 @@ int CtdlDoIHavePermissionToPostInThisRoom(
        }
 
        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.
-                */
+               // 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.
                strcpy(errmsgbuf, "OK to reply here");
                return(0);
        }
 
        if ( (ra & UA_REPLYALLOWED) && (!is_reply) ) {
-               /* Clarify what happened with a better error message */
+               // Clarify what happened with a better error message
                snprintf(errmsgbuf, n, "You may only reply to existing messages here.");
                return (ERROR + HIGHER_ACCESS_REQUIRED);
        }
@@ -110,10 +94,8 @@ int CtdlDoIHavePermissionToPostInThisRoom(
 }
 
 
-/*
- * Check whether the current user has permission to delete messages from
- * the current room (returns 1 for yes, 0 for no)
- */
+// Check whether the current user has permission to delete messages from
+// the current room (returns 1 for yes, 0 for no)
 int CtdlDoIHavePermissionToDeleteMessagesFromThisRoom(void) {
        int ra;
        CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
@@ -122,10 +104,8 @@ int CtdlDoIHavePermissionToDeleteMessagesFromThisRoom(void) {
 }
 
 
-/*
- * Retrieve access control information for any user/room pair.
- * Yes, it has a couple of gotos.  If you don't like that, go die in a car fire.
- */
+// Retrieve access control information for any user/room pair.
+// Yes, it has a couple of gotos.  If you don't like that, go die in a car fire.
 void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *result, int *view) {
        int retval = 0;
        visit vbuf;
@@ -140,21 +120,21 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                is_guest = 1;
        }
 
-       /* for internal programs, always do everything */
+       // for internal programs, always do everything
        if (((CC->internal_pgm)) && (roombuf->QRflags & QR_INUSE)) {
                retval = (UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED);
                vbuf.v_view = 0;
                goto SKIP_EVERYTHING;
        }
 
-       /* If guest mode is enabled, always grant access to the Lobby */
+       // If guest mode is enabled, always grant access to the Lobby
        if ((is_guest) && (!strcasecmp(roombuf->QRname, BASEROOM))) {
                retval = (UA_KNOWN | UA_GOTOALLOWED);
                vbuf.v_view = 0;
                goto SKIP_EVERYTHING;
        }
 
-       /* Locate any applicable user/room relationships */
+       // Locate any applicable user/room relationships
        if (is_guest) {
                memset(&vbuf, 0, sizeof vbuf);
        }
@@ -162,7 +142,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                CtdlGetRelationship(&vbuf, userbuf, roombuf);
        }
 
-       /* Force the properties of the Aide room */
+       // Force the properties of the Aide room
        if (!strcasecmp(roombuf->QRname, CtdlGetConfigStr("c_aideroom"))) {
                if (userbuf->axlevel >= AxAideU) {
                        retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
@@ -172,32 +152,31 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                goto NEWMSG;
        }
 
-       /* If this is a public room, it's accessible... */
+       // If this is a public room, it's accessible...
        if (    ((roombuf->QRflags & QR_PRIVATE) == 0) 
                && ((roombuf->QRflags & QR_MAILBOX) == 0)
        ) {
                retval = retval | UA_KNOWN | UA_GOTOALLOWED;
        }
 
-       /* If this is a preferred users only room, check access level */
+       // If this is a preferred users only room, check access level
        if (roombuf->QRflags & QR_PREFONLY) {
                if (userbuf->axlevel < AxPrefU) {
                        retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED;
                }
        }
 
-       /* For private rooms, check the generation number matchups */
+       // For private rooms, check the generation number matchups
        if (    (roombuf->QRflags & QR_PRIVATE) 
                && ((roombuf->QRflags & QR_MAILBOX) == 0)
        ) {
 
-               /* An explicit match means the user belongs in this room */
+               // An explicit match means the user belongs in this room
                if (vbuf.v_flags & V_ACCESS) {
                        retval = retval | UA_KNOWN | UA_GOTOALLOWED;
                }
-               /* Otherwise, check if this is a guess-name or passworded
-                * room.  If it is, a goto may at least be attempted
-                */
+               // Otherwise, check if this is a guess-name or passworded
+               // room.  If it is, a goto may at least be attempted
                else if (       (roombuf->QRflags & QR_PRIVATE)
                                || (roombuf->QRflags & QR_PASSWORDED)
                ) {
@@ -206,27 +185,24 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                }
        }
 
-       /* For mailbox rooms, also check the namespace */
-       /* Also, mailbox owners can delete their messages */
+       // For mailbox rooms, also check the namespace.   Also, mailbox owners can delete their messages
        if ( (roombuf->QRflags & QR_MAILBOX) && (atol(roombuf->QRname) != 0)) {
                if (userbuf->usernum == atol(roombuf->QRname)) {
                        retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED | UA_DELETEALLOWED | UA_REPLYALLOWED;
                }
-               /* An explicit match means the user belongs in this room */
+               // 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 | UA_REPLYALLOWED;
                }
        }
 
-       /* For non-mailbox rooms... */
+       // For non-mailbox rooms...
        else {
-
-               /* User is allowed to post in the room unless:
-                * - User is not validated
-                * - User has no net privileges and it is a shared network room
-                * - It is a read-only room
-                * - It is a blog room (in which case we only allow replies to existing messages)
-                */
+               // User is allowed to post in the room unless:
+               // - User is not validated
+               // - User has no net privileges and it is a shared network room
+               // - It is a read-only room
+               // - It is a blog room (in which case we only allow replies to existing messages)
                int post_allowed = 1;
                int reply_allowed = 1;
                if (userbuf->axlevel < AxProbU) {
@@ -251,9 +227,8 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                        retval = retval | UA_REPLYALLOWED;
                }
 
-               /* If "collaborative deletion" is active for this room, any user who can post
-                * is also allowed to delete
-                */
+               // If "collaborative deletion" is active for this room, any user who can post
+               // is also allowed to delete
                if (roombuf->QRflags2 & QR2_COLLABDEL) {
                        if (retval & UA_POSTALLOWED) {
                                retval = retval | UA_DELETEALLOWED;
@@ -262,7 +237,7 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
 
        }
 
-       /* Check to see if the user has forgotten this room */
+       // Check to see if the user has forgotten this room
        if (vbuf.v_flags & V_FORGET) {
                retval = retval & ~UA_KNOWN;
                if (    ( ((roombuf->QRflags & QR_PRIVATE) == 0) 
@@ -274,12 +249,12 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                }
        }
 
-       /* If user is explicitly locked out of this room, deny everything */
+       // 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 & ~UA_REPLYALLOWED;
        }
 
-       /* Aides get access to all private rooms */
+       // Aides get access to all private rooms
        if (    (userbuf->axlevel >= AxAideU)
                && ((roombuf->QRflags & QR_MAILBOX) == 0)
        ) {
@@ -291,48 +266,44 @@ void CtdlRoomAccess(struct ctdlroom *roombuf, struct ctdluser *userbuf, int *res
                }
        }
 
-       /* Aides can gain access to mailboxes as well, but they don't show
-        * by default.
-        */
+       // Aides can gain access to mailboxes as well, but they don't show by default.
        if (    (userbuf->axlevel >= AxAideU)
                && (roombuf->QRflags & QR_MAILBOX)
        ) {
                retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
        }
 
-       /* Aides and Room Aides have admin privileges */
+       // Aides and Room Aides have admin privileges
        if (    (userbuf->axlevel >= AxAideU)
                || (userbuf->usernum == roombuf->QRroomaide)
        ) {
                retval = retval | UA_ADMINALLOWED | UA_DELETEALLOWED | UA_POSTALLOWED | UA_REPLYALLOWED;
        }
 
-NEWMSG:        /* By the way, we also check for the presence of new messages */
+NEWMSG:        // By the way, we also check for the presence of new messages
        if (is_msg_in_sequence_set(vbuf.v_seen, roombuf->QRhighest) == 0) {
                retval = retval | UA_HASNEWMSGS;
        }
 
-       /* System rooms never show up in the list. */
+       // System rooms never show up in the list.
        if (roombuf->QRflags2 & QR2_SYSTEM) {
                retval = retval & ~UA_KNOWN;
        }
 
 SKIP_EVERYTHING:
-       /* Now give the caller the information it wants. */
+       // Now give the caller the information it wants.
        if (result != NULL) *result = retval;
        if (view != NULL) *view = vbuf.v_view;
 }
 
 
-/*
- * Self-checking stuff for a room record read into memory
- */
+// Self-checking stuff for a room record read into memory
 void room_sanity_check(struct ctdlroom *qrbuf) {
-       /* Mailbox rooms are always on the lowest floor */
+       // Mailbox rooms are always on the lowest floor
        if (qrbuf->QRflags & QR_MAILBOX) {
                qrbuf->QRfloor = 0;
        }
-       /* Listing order of 0 is illegal except for base rooms */
+       // Listing order of 0 is illegal except for base rooms
        if (qrbuf->QRorder == 0) {
                if (    !(qrbuf->QRflags & QR_MAILBOX)
                        && strncasecmp(qrbuf->QRname, CtdlGetConfigStr("c_baseroom"), ROOMNAMELEN)
@@ -344,9 +315,7 @@ void room_sanity_check(struct ctdlroom *qrbuf) {
 }
 
 
-/*
- * CtdlGetRoom()  -  retrieve room data from disk
- */
+// CtdlGetRoom()  -  retrieve room data from disk
 int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name) {
        struct cdbdata *cdbqr;
        char lowercase_name[ROOMNAMELEN];
@@ -365,10 +334,14 @@ int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name) {
 
        memset(qrbuf, 0, sizeof(struct ctdlroom));
 
-       /* First, try the public namespace */
+       if (IsEmptyStr(lowercase_name)) {
+               return(1);                      // empty room name , not valid
+       }
+
+       // First, try the public namespace
        cdbqr = cdb_fetch(CDB_ROOMS, lowercase_name, strlen(lowercase_name));
 
-       /* If that didn't work, try the user's personal namespace */
+       // If that didn't work, try the user's personal namespace
        if (cdbqr == NULL) {
                snprintf(personal_lowercase_name, sizeof personal_lowercase_name, "%010ld.%s", CC->user.usernum, lowercase_name);
                cdbqr = cdb_fetch(CDB_ROOMS, personal_lowercase_name, strlen(personal_lowercase_name));
@@ -385,9 +358,7 @@ int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name) {
 }
 
 
-/*
- * CtdlGetRoomLock()  -  same as getroom() but locks the record (if supported)
- */
+// CtdlGetRoomLock()  -  same as getroom() but locks the record (if supported)
 int CtdlGetRoomLock(struct ctdlroom *qrbuf, const char *room_name) {
        register int retval;
        retval = CtdlGetRoom(qrbuf, room_name);
@@ -396,12 +367,9 @@ int CtdlGetRoomLock(struct ctdlroom *qrbuf, const char *room_name) {
 }
 
 
-/*
- * b_putroom()  -  back end to putroom() and b_deleteroom()
- *              (if the supplied buffer is NULL, delete the room record)
- */
-void b_putroom(struct ctdlroom *qrbuf, char *room_name)
-{
+// b_putroom()  -  back end to putroom() and b_deleteroom()
+// (if the supplied buffer is NULL, delete the room record)
+void b_putroom(struct ctdlroom *qrbuf, char *room_name) {
        char lowercase_name[ROOMNAMELEN];
        char *aptr, *bptr;
        long len;
@@ -426,35 +394,27 @@ void b_putroom(struct ctdlroom *qrbuf, char *room_name)
 }
 
 
-/* 
- * CtdlPutRoom()  -  store room data to disk
- */
+// CtdlPutRoom()  -  store room data to disk
 void CtdlPutRoom(struct ctdlroom *qrbuf) {
        b_putroom(qrbuf, qrbuf->QRname);
 }
 
 
-/*
- * b_deleteroom()  -  delete a room record from disk
- */
+// b_deleteroom()  -  delete a room record from disk
 void b_deleteroom(char *room_name) {
        b_putroom(NULL, room_name);
 }
 
 
-/*
- * CtdlPutRoomLock()  -  same as CtdlPutRoom() but unlocks the record (if supported)
- */
+// CtdlPutRoomLock()  -  same as CtdlPutRoom() but unlocks the record (if supported)
 void CtdlPutRoomLock(struct ctdlroom *qrbuf) {
        CtdlPutRoom(qrbuf);
        end_critical_section(S_ROOMS);
 }
 
 
-/*
- * CtdlGetFloorByName()  -  retrieve the number of the named floor
- * return < 0 if not found else return floor number
- */
+// CtdlGetFloorByName()  -  retrieve the number of the named floor
+// return < 0 if not found else return floor number
 int CtdlGetFloorByName(const char *floor_name) {
        int a;
        struct floor *flbuf = NULL;
@@ -462,7 +422,7 @@ int CtdlGetFloorByName(const char *floor_name) {
        for (a = 0; a < MAXFLOORS; ++a) {
                flbuf = CtdlGetCachedFloor(a);
 
-               /* check to see if it already exists */
+               // check to see if it already exists
                if ((!strcasecmp(flbuf->f_name, floor_name)) && (flbuf->f_flags & F_INUSE)) {
                        return a;
                }
@@ -471,11 +431,8 @@ int CtdlGetFloorByName(const char *floor_name) {
 }
 
 
-/*
- * CtdlGetFloorByNameLock()  -  retrieve floor number for given floor and lock the floor list.
- */
-int CtdlGetFloorByNameLock(const char *floor_name)
-{
+// CtdlGetFloorByNameLock()  -  retrieve floor number for given floor and lock the floor list.
+int CtdlGetFloorByNameLock(const char *floor_name) {
        begin_critical_section(S_FLOORTAB);
        return CtdlGetFloorByName(floor_name);
 }
@@ -604,6 +561,7 @@ void lputfloor(struct floor *flbuf, int floor_num) {
        CtdlPutFloorLock(flbuf, floor_num);
 }
 
+
 /* 
  * Iterate through the room table, performing a callback for each room.
  */
@@ -697,7 +655,6 @@ int CtdlIsNonEditable(struct ctdlroom *qrbuf) {
 }
 
 
-
 /*
  * Make the specified room the current room for this session.  No validation
  * or access control is done here -- the caller should make sure that the
@@ -1069,26 +1026,25 @@ void CtdlDeleteRoom(struct ctdlroom *qrbuf) {
 
        syslog(LOG_NOTICE, "room_ops: deleting room <%s>", qrbuf->QRname);
 
-       /* Delete the room's network configdb entry */
+       // Delete the room's network configdb entry
        netcfg_keyname(configdbkeyname, qrbuf->QRnumber);
        CtdlDelConfig(configdbkeyname);
 
-       /* Delete the messages in the room
-        * (Careful: this opens an S_ROOMS critical section!)
-        */
+       // Delete the messages in the room
+       // (Careful: this opens an S_ROOMS critical section!)
        CtdlDeleteMessages(qrbuf->QRname, NULL, 0, "");
 
-       /* Flag the room record as not in use */
+       // Flag the room record as not in use
        CtdlGetRoomLock(qrbuf, qrbuf->QRname);
        qrbuf->QRflags = 0;
        CtdlPutRoomLock(qrbuf);
 
-       /* then decrement the reference count for the floor */
+       // then decrement the reference count for the floor
        lgetfloor(&flbuf, (int) (qrbuf->QRfloor));
        flbuf.f_ref_count = flbuf.f_ref_count - 1;
        lputfloor(&flbuf, (int) (qrbuf->QRfloor));
 
-       /* Delete the room record from the database! */
+       // Delete the room record from the database!
        b_deleteroom(qrbuf->QRname);
 }