]> code.citadel.org Git - citadel.git/blobdiff - citadel/room_ops.c
Move user privileges functions to user_ops.c, room access check functions to room_ops.c
[citadel.git] / citadel / room_ops.c
index 23e5c9e03b59674f189d4a1f9ac153aa656b1a87..29fa36971788043db962f3cb47ccec23928e701c 100644 (file)
 
 struct floor *floorcache[MAXFLOORS];
 
+/* 
+ * 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))
+               && (!config.c_guest_logins)
+       ) {
+               return(om_not_logged_in);
+       }
+       return(om_ok);
+}
+
+/*
+ * 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, 
+       const char* RemoteIdentifier,
+       PostType PostPublic,
+       int is_reply
+       ) {
+       int ra;
+
+       if (!(CC->logged_in) && 
+           (PostPublic == POST_LOGGED_IN)) {
+               snprintf(errmsgbuf, n, "Not logged in.");
+               return (ERROR + NOT_LOGGED_IN);
+       }
+       else if (PostPublic == CHECK_EXISTANCE) {
+               return (0); // We're Evaling whether a recipient exists
+       }
+       else if (!(CC->logged_in)) {
+               
+               if ((CC->room.QRflags & QR_READONLY)) {
+                       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);
+               }
+               if ((PostPublic!=POST_LMTP) &&(CC->room.QRflags2 & QR2_SMTP_PUBLIC) == 0) {
+
+                       return CtdlNetconfigCheckRoomaccess(errmsgbuf, n, RemoteIdentifier);
+               }
+               return (0);
+
+       }
+
+       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);
+               return (ERROR + HIGHER_ACCESS_REQUIRED);
+       }
+
+       CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
+
+       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.
+                */
+               strcpy(errmsgbuf, "OK to reply here");
+               return(0);
+       }
+
+       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);
+       }
+
+       snprintf(errmsgbuf, n, "Higher access is required to post in this room.");
+       return (ERROR + HIGHER_ACCESS_REQUIRED);
+
+}
+
+/*
+ * 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);
+       if (ra & UA_DELETEALLOWED) return(1);
+       return(0);
+}
+
 /*
  * Retrieve access control information for any user/room pair
  */
@@ -278,12 +377,13 @@ void room_sanity_check(struct ctdlroom *qrbuf)
 /*
  * CtdlGetRoom()  -  retrieve room data from disk
  */
-int CtdlGetRoom(struct ctdlroom *qrbuf, char *room_name)
+int CtdlGetRoom(struct ctdlroom *qrbuf, const char *room_name)
 {
        struct cdbdata *cdbqr;
        char lowercase_name[ROOMNAMELEN];
        char personal_lowercase_name[ROOMNAMELEN];
-       char *dptr, *sptr, *eptr;
+       const char *sptr;
+       char *dptr, *eptr;
 
        dptr = lowercase_name;
        sptr = room_name;
@@ -608,7 +708,7 @@ void CtdlForEachNetCfgRoom(ForEachRoomNetCfgCallBack CB,
                room_sanity_check(&qrbuf);
                if (qrbuf.QRflags & QR_INUSE)
                {
-                       const OneRoomNetCfg* RNCfg;
+                       OneRoomNetCfg* RNCfg;
                        RNCfg = CtdlGetNetCfgForRoom(qrbuf.QRnumber);
                        if ((RNCfg != NULL) &&
                            ((filter == maxRoomNetCfg) ||
@@ -658,6 +758,7 @@ int sort_msglist_cmp(const void *m1, const void *m2) {
 int sort_msglist(long listptrs[], int oldcount)
 {
        int numitems;
+       int i = 0;
 
        numitems = oldcount;
        if (numitems < 2) {
@@ -668,9 +769,12 @@ int sort_msglist(long listptrs[], int oldcount)
        qsort(listptrs, numitems, sizeof(long), sort_msglist_cmp);
 
        /* and yank any nulls */
-       while ((numitems > 0) && (listptrs[0] == 0L)) {
-               memmove(&listptrs[0], &listptrs[1], (sizeof(long) * (numitems - 1)));
-               --numitems;
+       while ((i < numitems) && (listptrs[i] == 0L)) i++;
+
+       if (i > 0)
+       {
+               memmove(&listptrs[0], &listptrs[i], (sizeof(long) * (numitems - i)));
+               numitems-=i;
        }
 
        return (numitems);
@@ -1703,7 +1807,7 @@ void cmd_seta(char *new_ra)
  */
 void cmd_rinf(char *gargs)
 {
-       char filename[128];
+       char filename[PATH_MAX];
        char buf[SIZ];
        FILE *info_fp;