* added message subject to all those tiny messages
[citadel.git] / citadel / serv_managesieve.c
index 32b5f113efedcb208e2c276cc6906035e7cf18b8..608318fb6e8148231a043524951ea7faa3d30ca7 100644 (file)
@@ -1,7 +1,7 @@
 /**
- * $Id: serv_smtp.c 4570 2006-08-27 02:07:18Z ajc $
+ * $Id: $
  *
- * This module is an Manage Sieve implementation for the Citadel system.
+ * This module is an managesieve implementation for the Citadel system.
  * It is compliant with all of the following:
  *
  * http://tools.ietf.org/html/draft-martin-managesieve-06
 #include "serv_crypto.h"
 #endif
 
-
-
 #ifndef HAVE_SNPRINTF
 #include "snprintf.h"
 #endif
 
+#ifdef HAVE_LIBSIEVE
+
+#include "serv_sieve.h"
 
 
 /**
 
 struct citmgsve {              
        int command_state;             /**< Information about the current session */
-       char helo_node[SIZ];
-       struct ctdluser vrfy_buffer;
-       int vrfy_count;
-       char vrfy_match[SIZ];
-       char from[SIZ];
-       char recipients[SIZ];
-       int number_of_recipients;
-       int delivery_mode;
-       int message_originated_locally;
-       char *transmitted_message;      /* for APPEND command... */
+       char *transmitted_message;
        size_t transmitted_length;
+       char *imap_format_outstring;
+       int imap_outstring_length;
 };
 
 enum {         /** Command states for login authentication */
@@ -102,41 +96,29 @@ enum {     /** Command states for login authentication */
        mgsve_plain
 };
 
-
-////int run_queue_now = 0;     /* Set to 1 to ignore SMTP send retry times */
-
 #define MGSVE          CC->MGSVE
 
 /*****************************************************************************/
 /*                      MANAGESIEVE Server                                   */
 /*****************************************************************************/
 
-
-void goto_sieverules_room(void);
-{// TODO: check if we're authenticated.
-       struct ctdlroom QRscratch;
-       char buf[SIZ];
-       int ra;
-       int c;
-       char *pattern;
-       char augmented_roomname[ROOMNAMELEN];
-
-       MailboxName(augmented_roomname, sizeof augmented_roomname,
-                   &CC->user, SIEVERULES);
-       c = getroom(&QRscratch, augmented_roomname);
-       if (c != 0)/* something went wrong. hit it! */
-       {
-               cprintf("BYE\r\n");
-               CC->kill_me = 1;
-               free(QRscratch);
-               return;
-       }
-       /* move to the sieve room. */
-       memcpy(&CC->room, &QRscratch,
-              sizeof(struct ctdlroom));
-       usergoto(NULL, 1, transiently, NULL, NULL);
+void sieve_outbuf_append(char *str)
+{
+        size_t newlen = strlen(str)+1;
+        size_t oldlen = (MGSVE->imap_format_outstring==NULL)? 0 : strlen(MGSVE->imap_format_outstring)+2;
+        char *buf = malloc ( newlen + oldlen + 10 );
+        buf[0]='\0';
+
+        if (oldlen!=0)
+                sprintf(buf,"%s%s",MGSVE->imap_format_outstring, str);
+        else
+                memcpy(buf, str, newlen);
+        
+        if (oldlen != 0) free (MGSVE->imap_format_outstring);
+        MGSVE->imap_format_outstring = buf;
 }
 
+
 /**
  * Capability listing. Printed as greeting or on "CAPABILITIES" 
  * see Section 1.8 ; 2.4
@@ -149,13 +131,13 @@ void cmd_mgsve_caps(void)
 /* if TLS is already there, should we say that again? */
                "\"STARTTLS\"\r\n"
 #endif
-               "\"SIEVE\" \"FILEINTO VACATION\"\r\n" /* TODO: print sieve extensions here. */
-               "OK\r\n");
+               "\"SIEVE\" \"%s\"\r\n"
+               "OK\r\n", msiv_extensions);
 }
 
 
 /*
- * Here's where our SMTP session begins its happy day.
+ * Here's where our managesieve session begins its happy day.
  */
 void managesieve_greeting(void) {
 
@@ -168,91 +150,106 @@ void managesieve_greeting(void) {
        cmd_mgsve_caps();
 }
 
-/* AUTHENTICATE command; 2.1 */
-void cmd_mgsve_auth(int num_parms, char **parms)
+
+long GetSizeToken(char * token)
 {
-/* TODO: compare "digest-md5" or "gssapi" and answer with "NO" */
-       if ((num_parms == 3) && !strncasecmp(parms[1], "PLAIN", 5))
-       /* todo, check length*/
-       {
-               char auth[SIZ];
-               int retval;
+       char *cursor = token;
+       char *number;
 
-               /* todo: how to do plain auth? */
+       while ((*cursor != '\0') && 
+              (*cursor != '{'))
+       {
+               cursor++;
+       }
+       if (*cursor == '\0') 
+               return -1;
+       number = cursor + 1;
+       while ((*cursor != '\0') && 
+              (*cursor != '}'))
+       {
+               cursor++;
+       }
 
-               if (parms[2][0] == '{') 
-               {
-                       long literal_length;
-                       long ret;
-
-                       literal_length = atol(&parms[2][1]);
-                       if (literal_length < 1) {
-                               cprintf("NO %s BAD Message length must be at least 1.\n",
-                                       parms[0]);
-                               CC->kill_me = 1;
-                               return;
-                       }
-                       MGSVE->transmitted_message = malloc(literal_length + 1);
-                       if (MGSVE->transmitted_message == NULL) {
-                               cprintf("NO %s Cannot allocate memory.\r\n", parms[0]);
-                               CC->kill_me = 1;
-                               return;
-                       }
-                       MGSVE->transmitted_length = literal_length;
+       if (cursor[-1] == '+')
+               cursor--;
 
-                       ret = client_read(MGSVE->transmitted_message, literal_length);
-                       MGSVE->transmitted_message[literal_length] = 0;
+       if (*cursor == '\0') 
+               return -1;
+       
+       return atol(number);
+}
 
-                       if (ret != 1) {
-                               cprintf("%s NO Read failed.\r\n", parms[0]);
-                               return;
-                       } 
+char *ReadString(long size, char *command)
+{
+       long ret;
+       if (size < 1) {
+               cprintf("NO %s: %ld BAD Message length must be at least 1.\r\n",
+                       command, size);
+               CC->kill_me = 1;
+               return NULL;
+       }
+       MGSVE->transmitted_message = malloc(size + 2);
+       if (MGSVE->transmitted_message == NULL) {
+               cprintf("NO %s Cannot allocate memory.\r\n", command);
+               CC->kill_me = 1;
+               return NULL;
+       }
+       MGSVE->transmitted_length = size;
+       
+       ret = client_read(MGSVE->transmitted_message, size);
+       MGSVE->transmitted_message[size] = '\0';
+       
+       if (ret != 1) {
+               cprintf("%s NO Read failed.\r\n", command);
+               return NULL;
+       } 
+       return MGSVE->transmitted_message;
 
+}
+/* AUTHENTICATE command; 2.1 */
+void cmd_mgsve_auth(int num_parms, char **parms, struct sdm_userdata *u)
+{
+       if ((num_parms == 3) && !strncasecmp(parms[1], "PLAIN", 5))
+               /* todo, check length*/
+       {
+               char auth[SIZ];
+               int retval;
+               char *message = ReadString(GetSizeToken(parms[2]), parms[0]);
+               
+               if (message != NULL) {/**< do we have tokenized login? */
                        retval = CtdlDecodeBase64(auth, MGSVE->transmitted_message, SIZ);
-
                }
                else 
                        retval = CtdlDecodeBase64(auth, parms[2], SIZ);
+
                if (login_ok == CtdlLoginExistingUser(auth))
+               {
+                       char *pass;
+                       pass = &(auth[strlen(auth)+1]);
+                       /* for some reason the php script sends us the username twice. y? */
+                       pass = &(pass[strlen(pass)+1]);
+                       
+                       if (pass_ok == CtdlTryPassword(pass))
                        {
-                               char *pass;
-                               pass = &(auth[strlen(auth)+1]);
-                               /* for some reason the php script sends us the username twice. y? */
-                               pass = &(pass[strlen(pass)+1]);
-
-                               CtdlTryPassword(pass);
-
                                MGSVE->command_state = mgsve_password;
-                               cprintf("OK\n");
-                       }
-               else 
-                       {
-                               cprintf("NO\n");
+                               cprintf("OK\r\n");
+                               return;
                        }
-       }
-       else
-       {
-               cprintf("NO\n");/* we just support auth plain. */
-               CC->kill_me = 1;
+               }
        }
        
-/*
-
-       switch (MGSVE->command_state)
-       {
-
-
-       MGSVE->command_state = plain;
-       }
-*/
+       cprintf("NO \"Authentication Failure.\"\r\n");/* we just support auth plain. */
+       CC->kill_me = 1;
 }
 
 
 #ifdef HAVE_OPENSSL
-/* STARTTLS command chapter 2.2 */
+/**
+ * STARTTLS command chapter 2.2 
+ */
 void cmd_mgsve_starttls(void)
-{ /* answer with OK, and fire off tls session. */
-       cprintf("OK\n");
+{ /** answer with OK, and fire off tls session. */
+       cprintf("OK\r\n");
        CtdlStartTLS(NULL, NULL, NULL);
        cmd_mgsve_caps();
 }
@@ -260,25 +257,28 @@ void cmd_mgsve_starttls(void)
 
 
 
-/* LOGOUT command, see chapter 2.3 */
-void cmd_mgsve_logout(void)
-{/* send "OK" and terminate the connection. */
+/**
+ *LOGOUT command, see chapter 2.3 
+ */
+void cmd_mgsve_logout(struct sdm_userdata *u)
+{
        cprintf("OK\r\n");
        lprintf(CTDL_NOTICE, "MgSve bye.");
        CC->kill_me = 1;
 }
 
 
-/* HAVESPACE command. see chapter 2.5 */
+/**
+ * HAVESPACE command. see chapter 2.5 
+ */
 void cmd_mgsve_havespace(void)
 {
-/* TODO answer NO in any case if auth is missing. */
 /* as we don't have quotas in citadel we should always answer with OK; 
  * pherhaps we should have a max-scriptsize. 
  */
        if (MGSVE->command_state != mgsve_password)
        {
-               cprintf("NO\n");
+               cprintf("NO\r\n");
                CC->kill_me = 1;
        }
        else
@@ -289,152 +289,147 @@ void cmd_mgsve_havespace(void)
        }
 }
 
-/* PUTSCRIPT command, see chapter 2.6 */
-void cmd_mgsve_putscript(void)
+/**
+ * PUTSCRIPT command, see chapter 2.6 
+ */
+void cmd_mgsve_putscript(int num_parms, char **parms, struct sdm_userdata *u)
 {
 /* "scriptname" {nnn+} */
-/* TODO: answer with "NO" instant, if we're unauthorized. */
 /* AFTER we have the whole script overwrite existing scripts */
 /* spellcheck the script before overwrite old ones, and reply with "no" */
-
-}
-
-
-/* LISTSCRIPT command. see chapter 2.7 */
-void cmd_mgsve_listscript(void)
-{
-       ctdlroom QRsieve;
-       QRsieve = goto_sieverules_room();
-       if (QRsieve == NULL)
+       if (num_parms == 3)
        {
-               cprintf("NO\r\n");
-               return;
+               char *ScriptName;
+               char *Script;
+               long slength;
+
+               if (parms[1][0]=='"')
+                       ScriptName = &parms[1][1];
+               else
+                       ScriptName = parms[1];
+               
+               slength = strlen (ScriptName);
+               
+               if (ScriptName[slength] == '"')
+                       ScriptName[slength] = '\0';
+
+               Script = ReadString(GetSizeToken(parms[2]),parms[0]);
+
+               if (Script == NULL) return;
+               
+               // TODO: do we spellcheck?
+               msiv_putscript(u, ScriptName, Script);
+               cprintf("OK\r\n");
        }
-/* TODO: check auth, if not, answer with "no" */
-/* do something like the sieve room indexlisting, one per row, in quotes. ACTIVE behind the active one.*/ 
-
-///    ra = getroom(sieveroom, SIEVERULES);
-///    /* Only list rooms to which the user has access!! */
-///    CtdlRoomAccess(SIEVERULES, &CC->user, &ra, NULL);
-///    if ((ra & UA_KNOWN)
-///        || ((ra & UA_GOTOALLOWED) && (ra & UA_ZAPPED))) {
-///            imap_mailboxname(buf, sizeof buf, qrbuf);
-///            if (imap_mailbox_matches_pattern(pattern, buf)) {
-///                    cprintf("* LIST () \"/\" ");
-///                    imap_strout(buf);
-///                    cprintf("\r\n");
-///            }
-///    }
-///
-       cprintf("OK\r\n");
-}
-
-
-/* SETACTIVE command. see chapter 2.8 */
-void cmd_mgsve_setactive(void)
-{
-/* TODO: check auth, if not, answer with "no" */
-/* search our room for subjects with that scriptname, 
- * if the scriptname is empty, use the default flag.
- * if the script is not there answer "No "there is no script by that name "
- */
+       else {
+               cprintf("%s NO Read failed.\r\n", parms[0]);
+               CC->kill_me = 1;
+               return;
+       } 
 
 
 
 }
 
 
-/* GETSCRIPT command. see chapter 2.9 */
-void cmd_mgsve_getscript(void)
-{
-/* TODO: check auth, if not, answer with "no" */
-/* check first param, this is the name. look up that in the folder.
- * answer with the size {nnn+}and spill it out, one blank line and OK
- */
-
-}
 
 
-/* DELETESCRIPT command. see chapter 2.10 */
-void cmd_mgsve_deletescript(void)
+/**
+ * LISTSCRIPT command. see chapter 2.7 
+ */
+void cmd_mgsve_listscript(int num_parms, char **parms, struct sdm_userdata *u)
 {
-/* TODO: check auth, if not, answer with "no" */
 
+       struct sdm_script *s;
+       long nScripts = 0;
 
+       MGSVE->imap_format_outstring = NULL;
+       for (s=u->first_script; s!=NULL; s=s->next) {
+               if (s->script_content != NULL) {
+                       cprintf("\"%s\"%s\r\n", 
+                               s->script_name, 
+                               (s->script_active)?" ACTIVE":"");
+                       nScripts++;
+               }
+       }
+       cprintf("OK\r\n");
 }
 
 
-
-/*
- *
-void smtp_get_user(char *argbuf) {
-       char buf[SIZ];
-       char username[SIZ];
-
-       CtdlDecodeBase64(username, argbuf, SIZ);
-       / * lprintf(CTDL_DEBUG, "Trying <%s>\n", username); * /
-       if (CtdlLoginExistingUser(username) == login_ok) {
-               CtdlEncodeBase64(buf, "Password:", 9);
-               cprintf("334 %s\r\n", buf);
-               SMTP->command_state = smtp_password;
-       }
-       else {
-               cprintf("500 5.7.0 No such user.\r\n");
-               SMTP->command_state = smtp_command;
-       }
-}
+/**
+ * \brief SETACTIVE command. see chapter 2.8 
  */
+void cmd_mgsve_setactive(int num_parms, char **parms, struct sdm_userdata *u)
+{
+       if (num_parms == 2)
+       {
+               if (msiv_setactive(u, parms[1]) == 0) {
+                       cprintf("OK\r\n");
+               }
+               else
+                       cprintf("No \"there is no script by that name %s \"\r\n", parms[1]);
+       }
+       else 
+               cprintf("NO \"unexpected parameters.\"\r\n");
 
+}
 
-/*
- *
-void smtp_get_pass(char *argbuf) {
-       char password[SIZ];
 
-       CtdlDecodeBase64(password, argbuf, SIZ);
-       / * lprintf(CTDL_DEBUG, "Trying <%s>\n", password); * /
-       if (CtdlTryPassword(password) == pass_ok) {
-               smtp_auth_greeting();
-       }
-       else {
-               cprintf("535 5.7.0 Authentication failed.\r\n");
+/**
+ * \brief GETSCRIPT command. see chapter 2.9 
+ */
+void cmd_mgsve_getscript(int num_parms, char **parms, struct sdm_userdata *u)
+{
+       if (num_parms == 2){
+               char *script_content;
+               long  slen;
+
+               script_content = msiv_getscript(u, parms[1]);
+               if (script_content != NULL){
+                       char *outbuf;
+
+                       slen = strlen(script_content);
+                       outbuf = malloc (slen + 64);
+                       snprintf(outbuf, slen + 64, "{%ld+}\r\n%s\r\nOK\r\n",slen, script_content);
+                       cprintf(outbuf);
+               }
+               else
+                       cprintf("No \"there is no script by that name %s \"\r\n", parms[1]);
        }
-       SMTP->command_state = smtp_command;
+       else 
+               cprintf("NO \"unexpected parameters.\"\r\n");
 }
- */
 
 
-/*
- * Back end for PLAIN auth method (either inline or multistate)
+/**
+ * \brief DELETESCRIPT command. see chapter 2.10 
  */
-void mgsve_try_plain(char *encoded_authstring) {
-       char decoded_authstring[1024];
-       char ident[256];
-       char user[256];
-       char pass[256];
-
-       CtdlDecodeBase64(decoded_authstring,
-                       encoded_authstring,
-                       strlen(encoded_authstring) );
-       safestrncpy(ident, decoded_authstring, sizeof ident);
-       safestrncpy(user, &decoded_authstring[strlen(ident) + 1], sizeof user);
-       safestrncpy(pass, &decoded_authstring[strlen(ident) + strlen(user) + 2], sizeof pass);
-
-//     SMTP->command_state = smtp_command;
-/*
-       if (CtdlLoginExistingUser(user) == login_ok) {
-               if (CtdlTryPassword(pass) == pass_ok) {
-                       smtp_auth_greeting();
-                       return;
-               }
+void cmd_mgsve_deletescript(int num_parms, char **parms, struct sdm_userdata *u)
+{
+       int i=-1;
+
+       if (num_parms == 2)
+               i = msiv_deletescript(u, parms[1]);
+       switch (i){             
+       case 0:
+               cprintf("OK\r\n");
+               break;
+       case 1:
+               cprintf("NO \"no script by that name: %s\"\r\n", parms[1]);
+               break;
+       case 2:
+               cprintf("NO \"can't delete active Script: %s\"\r\n", parms[1]);
+               break;
+       default:
+       case -1:
+               cprintf("NO \"unexpected parameters.\"\r\n");
+               break;
        }
-*/
-       cprintf("504 5.7.4 Authentication failed.\r\n");
 }
 
 
-/*
- * Attempt to perform authenticated SMTP
+/**
+ * \brief Attempt to perform authenticated managesieve
  */
 void mgsve_auth(char *argbuf) {
        char username_prompt[64];
@@ -442,7 +437,7 @@ void mgsve_auth(char *argbuf) {
        char encoded_authstring[1024];
 
        if (CC->logged_in) {
-               cprintf("504 5.7.4 Already logged in.\r\n");
+               cprintf("NO \"Already logged in.\"\r\n");
                return;
        }
 
@@ -450,12 +445,10 @@ void mgsve_auth(char *argbuf) {
 
        if (!strncasecmp(method, "login", 5) ) {
                if (strlen(argbuf) >= 7) {
-//                     smtp_get_user(&argbuf[6]);
                }
                else {
                        CtdlEncodeBase64(username_prompt, "Username:", 9);
                        cprintf("334 %s\r\n", username_prompt);
-//                     SMTP->command_state = smtp_user;
                }
                return;
        }
@@ -463,18 +456,14 @@ void mgsve_auth(char *argbuf) {
        if (!strncasecmp(method, "plain", 5) ) {
                if (num_tokens(argbuf, ' ') < 2) {
                        cprintf("334 \r\n");
-//                     SMTP->command_state = smtp_plain;
                        return;
                }
-
                extract_token(encoded_authstring, argbuf, 1, ' ', sizeof encoded_authstring);
-
-///            smtp_try_plain(encoded_authstring);
                return;
        }
 
        if (strncasecmp(method, "login", 5) ) {
-               cprintf("504 5.7.4 Unknown authentication method.\r\n");
+               cprintf("NO \"Unknown authentication method.\"\r\n");
                return;
        }
 
@@ -486,7 +475,7 @@ void mgsve_auth(char *argbuf) {
  * implements the STARTTLS command (Citadel API version)
  */
 #ifdef HAVE_OPENSSL
-void _smtp_starttls(void)
+void _mgsve_starttls(void)
 {
        char ok_response[SIZ];
        char nosup_response[SIZ];
@@ -499,33 +488,29 @@ void _smtp_starttls(void)
        sprintf(error_response,
                "554 5.7.3 Internal error\r\n");
        CtdlStartTLS(ok_response, nosup_response, error_response);
-///    smtp_rset(0);
 }
 #endif
 
 
-void mgsve_create_room(void)
-{
-
-       /* Create the tasks list room if it doesn't already exist */
-       create_room(SIEVERULES, 4, "", 0, 1, 0, VIEW_SIEVE);
-}
-
 /* 
- * Main command loop for manage Sieve sessions.
+ * Main command loop for managesieve sessions.
  */
 void managesieve_command_loop(void) {
        char cmdbuf[SIZ];
        char *parms[SIZ];
        int length;
        int num_parms;
+       struct sdm_userdata u;
+       int changes_made = 0;
+
+       memset(&u, 0, sizeof(struct sdm_userdata));
 
        time(&CC->lastcmd);
        memset(cmdbuf, 0, sizeof cmdbuf); /* Clear it, just in case */
        length = client_getln(cmdbuf, sizeof cmdbuf);
        if (length >= 1) {
                num_parms = imap_parameterize(parms, cmdbuf);
-               ///             length = client_getln(parms[0], sizeof parms[0]);
+               if (num_parms == 0) return;
                length = strlen(parms[0]);
        }
        if (length < 1) {
@@ -534,9 +519,8 @@ void managesieve_command_loop(void) {
                return;
        }
        lprintf(CTDL_INFO, "MANAGESIEVE: %s\n", cmdbuf);
-//// we have different lengths while (strlen(cmdbuf) < 5) strcat(cmdbuf, " ");
        if ((length>= 12) && (!strncasecmp(parms[0], "AUTHENTICATE", 12))){
-               cmd_mgsve_auth(num_parms, parms);
+               cmd_mgsve_auth(num_parms, parms, &u);
        }
 
 #ifdef HAVE_OPENSSL
@@ -545,34 +529,41 @@ void managesieve_command_loop(void) {
        }
 #endif
        else if ((length>= 6) && (!strncasecmp(parms[0], "LOGOUT", 6))){
-               cmd_mgsve_logout();
+               cmd_mgsve_logout(&u);
        }
        else if ((length>= 6) && (!strncasecmp(parms[0], "CAPABILITY", 10))){
                cmd_mgsve_caps();
-       } /* these commands need to be authenticated. throw it out if it tries. */
-       else if (MGSVE->command_state == mgsve_password)
+       } 
+       /** these commands need to be authenticated. throw it out if it tries. */
+       else if (!CtdlAccessCheck(ac_logged_in))
        {
+               msiv_load(&u);
                if ((length>= 9) && (!strncasecmp(parms[0], "HAVESPACE", 9))){
                        cmd_mgsve_havespace();
                }
                else if ((length>= 6) && (!strncasecmp(parms[0], "PUTSCRIPT", 9))){
-                       cmd_mgsve_putscript();
+                       cmd_mgsve_putscript(num_parms, parms, &u);
+                       changes_made = 1;
                }
                else if ((length>= 6) && (!strncasecmp(parms[0], "LISTSCRIPT", 10))){
-                       cmd_mgsve_listscript();
+                       cmd_mgsve_listscript(num_parms, parms,&u);
                }
                else if ((length>= 6) && (!strncasecmp(parms[0], "SETACTIVE", 9))){
-                       cmd_mgsve_setactive();
+                       cmd_mgsve_setactive(num_parms, parms,&u);
+                       changes_made = 1;
                }
                else if ((length>= 6) && (!strncasecmp(parms[0], "GETSCRIPT", 9))){
-                       cmd_mgsve_getscript();
+                       cmd_mgsve_getscript(num_parms, parms, &u);
                }
                else if ((length>= 6) && (!strncasecmp(parms[0], "DELETESCRIPT", 11))){
-                       cmd_mgsve_deletescript();
+                       cmd_mgsve_deletescript(num_parms, parms, &u);
+                       changes_made = 1;
                }
+               msiv_store(&u, changes_made);
        }
        else {
                cprintf("No\r\n");
+               lprintf(CTDL_INFO, "illegal Managesieve command: %s", parms[0]);
                CC->kill_me = 1;
        }
 
@@ -581,11 +572,6 @@ void managesieve_command_loop(void) {
 
 
 
-
-
-
-
-
 char *serv_managesieve_init(void)
 {
 
@@ -595,6 +581,15 @@ char *serv_managesieve_init(void)
                                managesieve_command_loop,
                                NULL);
 
-       CtdlRegisterSessionHook(mgsve_create_room, EVT_LOGIN);
        return "$Id: serv_managesieve.c 4570 2006-08-27 02:07:18Z dothebart $";
 }
+
+#else  /* HAVE_LIBSIEVE */
+
+char *serv_managesieve_init(void)
+{
+       lprintf(CTDL_INFO, "This server is missing libsieve.  Managesieve protocol is disabled..\n");
+       return "$Id:  $";
+}
+
+#endif /* HAVE_LIBSIEVE */