* More work on IMAP ACL...
if (strlen(temp.fullname) > 0) {
strcpy(rights, "");
- /* Known, zapped, etc. mailboxes can probably be LIST-ed */
- /* FIXME don't give away hidden rooms */
+ /* l - lookup (mailbox is visible to LIST/LSUB commands, SUBSCRIBE mailbox)
+ * FIXME don't give away hidden rooms
+ */
if (ra & UA_GOTOALLOWED) strcat(rights, "l");
- /* Known rooms can be LSUB-ed */
+ /* r - read (SELECT the mailbox, perform STATUS) */
if (ra & UA_KNOWN) strcat(rights, "r");
- /* FIXME do the rest */
+ /* s - keep seen/unseen information across sessions (set or clear \SEEN flag
+ * via STORE, also set \SEEN during APPEND/COPY/ FETCH BODY[...])
+ */
+ strcat(rights, "s"); /* Always granted */
+
+ /* w - write (set or clear flags other than \SEEN and \DELETED via
+ * STORE, also set them during APPEND/COPY)
+ */
+ /* Never granted in Citadel because our store doesn't support other flags */
+
+ /* i - insert (perform APPEND, COPY into mailbox) */
+ if (ra & UA_POSTALLOWED) strcat(rights, "i");
+
+ /* p - post (send mail to submission address for mailbox, not enforced by IMAP) */
+ if (ra & UA_POSTALLOWED) strcat(rights, "p");
+
+ /* k - create mailboxes (CREATE new sub-mailboxes in any
+ * implementation-defined hierarchy, parent mailbox for the new
+ * mailbox name in RENAME) */
+
+ /* x - delete mailbox (DELETE mailbox, old mailbox name in RENAME) */
+
+ /* t - delete messages (set or clear \DELETED flag via STORE, set
+ * \DELETED flag during APPEND/COPY) */
+
+ /* e - perform EXPUNGE and expunge as a part of CLOSE */
+
+ /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */
if (strlen(rights) > 0) {
cprintf(" ");
#define UA_GOTOALLOWED 4
#define UA_HASNEWMSGS 8
#define UA_ZAPPED 16
+#define UA_POSTALLOWED 32
#ifdef __cplusplus
}
* returns 0 on success.
*/
int CtdlDoIHavePermissionToPostInThisRoom(char *errmsgbuf, size_t n) {
+ int ra;
if (!(CC->logged_in)) {
snprintf(errmsgbuf, n, "Not logged in.");
return (ERROR + HIGHER_ACCESS_REQUIRED);
}
- if ((CC->user.axlevel < 4)
- && (CC->room.QRflags & QR_NETWORK)) {
- snprintf(errmsgbuf, n, "Need net privileges to enter here.");
- return (ERROR + HIGHER_ACCESS_REQUIRED);
- }
-
- if ((CC->user.axlevel < 6)
- && (CC->room.QRflags & QR_READONLY)) {
- snprintf(errmsgbuf, n, "Sorry, this is a read-only room.");
+ CtdlRoomAccess(&CC->room, &CC->user, &ra, NULL);
+ if (!(ra & UA_POSTALLOWED)) {
+ snprintf(errmsgbuf, n, "Higher access is required to post in this room.");
return (ERROR + HIGHER_ACCESS_REQUIRED);
}
/* for internal programs, always do everything */
if (((CC->internal_pgm)) && (roombuf->QRflags & QR_INUSE)) {
- retval = (UA_KNOWN | UA_GOTOALLOWED);
+ retval = (UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED);
vbuf.v_view = 0;
goto SKIP_EVERYTHING;
}
/* Force the properties of the Aide room */
if (!strcasecmp(roombuf->QRname, config.c_aideroom)) {
if (userbuf->axlevel >= 6) {
- retval = UA_KNOWN | UA_GOTOALLOWED;
+ retval = UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED;
} else {
retval = 0;
}
}
}
- /* For mailbox rooms, also check the generation number matchups */
+ /* For mailbox rooms, also check the namespace */
if (roombuf->QRflags & QR_MAILBOX) {
if (userbuf->usernum == atol(roombuf->QRname)) {
- retval = retval | UA_KNOWN | UA_GOTOALLOWED;
+ retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED;
}
/* An explicit match means the user belongs in this room */
if (vbuf.v_flags & V_ACCESS) {
- retval = retval | UA_KNOWN | UA_GOTOALLOWED;
+ retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED;
}
}
+ /* 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
+ */
+ int post_allowed = 1;
+ if (CC->user.axlevel < 2) post_allowed = 0;
+ if ((CC->user.axlevel < 4) && (CC->room.QRflags & QR_NETWORK)) post_allowed = 0;
+ if (roombuf->QRflags & QR_READONLY) post_allowed = 0;
+ if (post_allowed) {
+ retval = retval | UA_POSTALLOWED;
+ }
+
+ }
+
/* Check to see if the user has forgotten this room */
if (vbuf.v_flags & V_FORGET) {
retval = retval & ~UA_KNOWN;
}
/* If user is explicitly locked out of this room, deny everything */
if (vbuf.v_flags & V_LOCKOUT) {
- retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED;
+ retval = retval & ~UA_KNOWN & ~UA_GOTOALLOWED & ~UA_POSTALLOWED;
}
/* Aides get access to all private rooms */
if ( (userbuf->axlevel >= 6)
&& ((roombuf->QRflags & QR_MAILBOX) == 0) ) {
if (vbuf.v_flags & V_FORGET) {
- retval = retval | UA_GOTOALLOWED;
+ retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED;
}
else {
- retval = retval | UA_KNOWN | UA_GOTOALLOWED;
+ retval = retval | UA_KNOWN | UA_GOTOALLOWED | UA_POSTALLOWED;
}
}
*/
if ( (userbuf->axlevel >= 6)
&& (roombuf->QRflags & QR_MAILBOX) ) {
- retval = retval | UA_GOTOALLOWED;
+ retval = retval | UA_GOTOALLOWED | UA_POSTALLOWED;
}
NEWMSG: /* By the way, we also check for the presence of new messages */