Code

Backport from trunk, allows to use " in vacation messages.
[gosa.git] / gosa-plugins / mail / personal / mail / class_mail-methods-cyrus.inc
index 3b7e8b08329014f3d22f7fdd1e827a089a76c994..db67e08c080ee699fb033d52dde28b2623216ebd 100644 (file)
@@ -1,52 +1,54 @@
 <?php
-/*
-   This code is part of GOsa (https://gosa.gonicus.de)
-   Copyright (C) 2004  Cajus Pollmeier
-
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
-   (at your option) any later version.
-
-   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.
-
-   You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-class mailMethodCyrus extends mailMethod
-{
-  var $mbox= "-";
-  var $config;
-  var $gosaMailServer= "";
-  var $uattrib= "uid";
-
-  function mailMethodCyrus(&$config)
+
+
+class mailMethodCyrus extends mailMethod{
+
+  protected $ServerList = array();
+  protected $imap_handle = NULL;
+  protected $quota_loaded = FALSE;
+   
+  /* Allow modification of account_ids for existing mail accounts */
+  protected $modifyableMail   = FALSE;
+
+  /* Allow modification of the mail server attribute existing mail accounts */
+  protected $modifyableServer = FALSE;
+
+  /* Enforces same value for 'mail' as used for 'cn' */
+  protected $mailEqualsCN   = FALSE; 
+
+  protected $enableDomainSelection= FALSE;
+  protected $enableQuota          = TRUE;
+  protected $enableSieveManager   = TRUE;
+  protected $enableVacationRange  = TRUE;
+  protected $enableFolderTypes    = FALSE;
+
+  protected function init()
   {
-    /* Check if the mail account identification attribute
-       is overridden in the configuration file
-     */
-    if(isset($config->current['MAIL_ATTRIB'])){
-      $this->uattrib = $config->current['MAIL_ATTRIB'];
+    mailMethod::init();
+    if(isset($this->config->data['SERVERS']['IMAP'])){
+      $this->ServerList = $this->config->data['SERVERS']['IMAP']; 
     }
-    $this->config= $config->data['SERVERS']['IMAP'];
   }
 
-  function connect($gosaMailServer)
+  
+  public function connect()
   {
-    $cfg=array();
-
-    /* Connect to IMAP server. I don't want to see these warning here... */
-    $this->gosaMailServer= $gosaMailServer;
-    if (!isset($this->config[$gosaMailServer])){
-      msg_dialog::display(_("Warning"), _("Mail server for this account is invalid!"), WARNING_DIALOG);
+    mailMethod::connect();
+
+    if(!count($this->ServerList)){
+      $this->error = _("There are no IMAP compatible mail servers defined!");
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,
+          "<b>IMAP: No mail servers configured, check systems->server->service->imap.</b>","");
+      return(FALSE);
+    }elseif (!isset($this->ServerList[$this->MailServer])){
+      $this->error = _("Mail server for this account is invalid!");
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,
+          "<b>IMAP: The selected mail server '".$this->MailServer."' is invalid.</b>",""); 
+      return(FALSE);
     } else {
-      $cfg= $this->config[$gosaMailServer];
+      $cfg= $this->ServerList[$this->MailServer];
     }
+
     /* For some reason, hiding errors with @ does not wor here... */
     if(!isset($cfg['connect']))   $cfg['connect']="";
     if(!isset($cfg['admin']))     $cfg['admin']="";
@@ -55,256 +57,498 @@ class mailMethodCyrus extends mailMethod
     /* Setting connect timeout to 10 seconds,
         else the GOsa UI may freeze for 60 seconds.
        (PHP default is 'default_socket_timeout = 60') */
-    imap_timeout(1, 10 );
+    $timeout = $this->config->get_cfg_value("core","imapTimeout");
+    @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,$timeout,
+          "<b>IMAP: Setting imap connect timeout to</b> (seconds)");
+    imap_timeout(1, $timeout);
 
-    $this->mbox = @imap_open($cfg['connect'], $cfg['admin'], $cfg['password'], OP_HALFOPEN);
+    $this->imap_handle = @imap_open($cfg['connect'], $cfg['admin'], $cfg['password'], OP_HALFOPEN);
 
     /* Mailbox reachable? */
-    if ($this->mbox === FALSE){
-      msg_dialog::display(_("IMAP error"), _("Cannot store mail settings on IMAP server!"), ERROR_DIALOG);
+    if ($this->imap_handle === FALSE){
+      $this->error = imap_last_error();
+
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>Failed</b> :".imap_last_error(),
+        "<b>IMAP:</b> ".$cfg['admin']."@".$cfg['connect']);
+
       return (FALSE);
+      $this->connected = FALSE;
     }
+    @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"<b>successful</b>",
+        "<b>IMAP:</b> ".$cfg['admin']."@".$cfg['connect']);
+    $this->connected = TRUE;
+
     return (TRUE);
   }
 
-  function disconnect()
+
+  public function account_exists()
+  {
+    if(!$this->is_connected() || !$this->imap_handle){
+      trigger_error("Method not connected, catch error.");
+      return(array());
+    }
+
+    /* Get server config */
+    $cfg= $this->ServerList[$this->MailServer];
+    $list = @imap_listmailbox($this->imap_handle, $cfg["connect"], $this->account_id);
+    $res = is_array($list) && count($list);
+    if($res){
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>IMAP: Account exists in imap server.</b>"); 
+    }else{
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"","<b>IMAP: Account seems NOT to exists in imap server.</b>"); 
+    }
+    return($res);
+  }
+
+  public function disconnect()
   {
-    imap_close ($this->mbox);
+    mailMethod::disconnect();
+    if($this->is_connected()){
+      @imap_close ($this->imap_handle);
+    }
   }
 
-  function getQuota($folder)
+
+  public function is_connected()
   {
-    $result= array('quotaUsage' => '', 'gosaMailQuota' => '');
+    $ret =    mailMethod::is_connected();
+    return($ret && $this->imap_handle);
+  }
+
+  protected function loadQuota()
+  {
+    if(!$this->quotaEnabled()) return(TRUE);
+    if(!$this->is_connected() || !$this->imap_handle){
+      trigger_error("Method not connected, catch error.");
+      return(FALSE);
+    }
+
+    $this->reset_error();
 
     /* Load quota settings */
-    error_reporting (0);
-    $quota_value = @imap_get_quota($this->mbox, $folder);
-    if(is_array($quota_value)) {
+    $result = array("quotaUsage"=>"","gosaMailQuota"=>"");
+    $quota_value = @imap_get_quota($this->imap_handle, $this->account_id);
+
+    /* Reset error queue, imap_qet_quota() will fail if the quota wasn't set yet.
+     */
+    imap_errors();
+
+    if(is_array($quota_value) && count($quota_value)) {
       if (isset($quota_value["STORAGE"]) && is_array($quota_value["STORAGE"])){
+
         /* use for PHP >= 4.3 */
         if($quota_value["STORAGE"]['limit'] == 2147483647){
           $result['quotaUsage']=    (int) ($quota_value["STORAGE"]['usage'] / 1024);
-          $result['gosaMailQuota']= (int) ($quota_value["STORAGE"]['limit'] );
+          $result['gosaMailQuota']=  "";
         }else{
           $result['quotaUsage']=    (int) ($quota_value["STORAGE"]['usage'] / 1024);
           $result['gosaMailQuota']= (int) ($quota_value["STORAGE"]['limit'] / 1024);
         }
       } else {
+
         /* backward icompatible */
         if($quota_value['usage'] == 2147483647){
           $result['quotaUsage']=    (int) ($quota_value['usage'] / 1024);
-          $result['gosaMailQuota']= (int) ($quota_value['limit'] );
+          $result['gosaMailQuota']= "";
         }else{
           $result['quotaUsage']=    (int) ($quota_value['usage'] / 1024);
           $result['gosaMailQuota']= (int) ($quota_value['limit'] / 1024);
         }
       }
-    }elseif(!$quota_value){
-      /* If there is no quota defined for this account, the function imap_get_quota returns false. */
-      return(array("quotaUsage"=>"","gosaMailQuota"=>""));
     }
-    error_reporting (E_ALL | E_STRICT);
-    return ($result);
+    $this->quotaValue = $result['gosaMailQuota'];
+    $this->quotaUsage = $result['quotaUsage'];
+
+    /* Write debug output */
+    if(is_array($quota_value)){
+      if($this->quotaValue == ""){
+        $quota = "(".$this->quotaUsage." / unlimited)";
+      }else{
+        $quota = "(".$this->quotaUsage." / ".$this->quotaValue.")";
+      }
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, $quota , 
+          "<b>IMAP: Successfully received account quota</b>");
+    }else{
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, imap_last_error() , 
+          "<b>IMAP: Failed to receive account quota</b>");
+    }
   }
 
-
-  /* return all folders of the users mailbox*/
-  function getMailboxList($folder, $uid)
+  public function getQuota($quota)
   {
-    global $config;
-    $result = array();
+    mailMethod::getQuota($quota);
+    if(!$this->quota_loaded){
+      $this->quota_loaded = TRUE;
+      $this->loadQuota();
+    }
+    return($this->quotaValue);
+  }
 
-    /* Get domain an mail address if uid is an mail address */
-    $domain = "";
-    if(preg_match("/@/",$folder)){
-      $domain = "@".preg_replace("/^.*@/","",$folder);
-      $folder = preg_replace("/@.*$/","",$folder);
+  public function getQuotaUsage()
+  {
+    mailMethod::getQuotaUsage();
+    if(!$this->quota_loaded){
+      $this->quota_loaded = TRUE;
+      $this->loadQuota();
     }
+    return($this->quotaUsage);
+  }
 
-    /* Get list of mailboxes for combo box */
-    $cfg= $this->config[$this->gosaMailServer];
+  public function setQuota($number)
+  {
+    mailMethod::setQuota($number);    
 
-    /* Create search pattern
-         (user/kekse*@domain.de
-          user.kekse*@domain.de
-          user.kekse*  )
-       depending on given folder name) */
-    $q = $folder."*".$domain;
-    $list = imap_listmailbox($this->mbox, $cfg["connect"], $q);
+    if(!$this->quotaEnabled()) return(TRUE);
+    if(!$this->is_connected() || !$this->imap_handle){
+      trigger_error("Method not connected, catch error.");
+      return(FALSE);
+    }
 
-    /* Create list of returned folder names */
-    if (is_array($list)){
-      foreach ($list as $val){
+    $this->build_account_id();
 
-        /* Cut domain name */
-        $val = preg_replace("/@.*$/","",$val);
-        $result[]=preg_replace ("/^.*".normalizePreg($folder)."/","INBOX", mb_convert_encoding($val, "UTF-8", "UTF7-IMAP"));
-      }
+    /* Workaround for the php imap extension */
+    if (($this->quotaValue == "") || ($this->quotaValue== "2147483647")){
+      $this->quotaValue= "2147483647";
+    }elseif($this->quotaValue > 0){
+      $this->quotaValue = $this->quotaValue *1024;
     }
-
-    /* Append "INBOX" to the folder array if result is empty and request comes from user dialog */
-    if(empty($result) && !empty($uid)){
-      $result[] = "INBOX";
+    $debug_number = $this->quotaValue." KB";
+    if($this->quotaValue == "2147483647"){
+      $debug_number .= "<i>Unlimited</i>";
     }
 
-    return ($result);
+    if (!imap_set_quota($this->imap_handle, $this->account_id, $this->quotaValue)){
+      msg_dialog::display(_("IMAP error"), sprintf(_("Cannot modify IMAP mailbox quota: %s"),
+            '<br><br><i>'.imap_last_error().'</i>'), ERROR_DIALOG);
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id.": (".$debug_number.")</b>" , 
+          "<b>IMAP: Set account quota</b> on server '".$this->MailServer."' <b>".imap_last_error()."</b>");
+      return (FALSE);
+    }
+    @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id.": (".$debug_number.")</b>" , 
+        "<b>IMAP: Set account quota</b> on server :".$this->MailServer);
+    return (TRUE);
   }
 
 
-  function updateMailbox($folder)
+  public function updateMailbox()
   {
-    /* Check if mailbox exists */
-    $cfg= $this->config[$this->gosaMailServer];
-    $list = imap_listmailbox($this->mbox, $cfg["connect"], $folder);
-    if ($list === FALSE){
-      if (!imap_createmailbox($this->mbox, $cfg["connect"]. $folder)){
-        msg_dialog::display(_("IMAP error"), sprintf(_("Cannot create IMAP mailbox: %s"), '<br><br><i>'.imap_last_error().'</i>'), ERROR_DIALOG);
-        return;
+    mailMethod::updateMailbox();
+
+    if(!$this->is_connected() || !$this->imap_handle){
+      trigger_error("Method not connected, catch error.");
+      return(FALSE);
+    }
+  
+    $this->build_account_id ();
+    if($this->is_connected()){
+      $cfg= $this->ServerList[$this->MailServer];
+      $list = imap_listmailbox($this->imap_handle, $cfg["connect"], $this->account_id);
+      if ($list === FALSE){
+        @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id."</b>" , 
+          "<b>IMAP: Add/Update account</b> on server :".$this->MailServer);
+        if (!imap_createmailbox($this->imap_handle, $cfg["connect"].$this->account_id)){
+          $this->error = imap_last_error();
+          return(FALSE);
+        }
+
+        /* Autocreate configured default folders */ 
+        $folders= $this->config->get_cfg_value("mailAccount","cyrusAutocreateFolders");
+        if ($folders) {
+          $foldersToCreate= explode(",", $folders);
+          $cyrus_delim= $this->cyrusUseSlashes?"/":".";
+
+          // Walk thru list of specified folders
+          foreach ($foldersToCreate as $folder) {
+            @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "<b>".$this->account_id."</b>" , 
+              "<b>IMAP: Add/Update account folder ".$folder."</b> on server :".$this->MailServer);
+            if(!imap_createmailbox($this->imap_handle, $cfg["connect"].$this->account_id.$cyrus_delim.$folder)) {
+              $this->error= imap_last_error();
+              return(FALSE);
+            }
+          }
+
+        }
       }
     }
+    return(TRUE);
   }
 
 
-  function setQuota($folder, $gosaMailQuota)
+  public function deleteMailbox()
   {
-    /* Workaround for the php imap extension */
-    if (($gosaMailQuota == "") || ($gosaMailQuota== "2147483647")){
-      $gosaMailQuota= "2147483647";
-    }elseif($gosaMailQuota > 0){
-      $gosaMailQuota = $gosaMailQuota *1024;
-    }
-    
-    
-    /* Write mail quota */
-    if (!imap_set_quota($this->mbox, $folder, $gosaMailQuota)){
-      msg_dialog::display(_("IMAP error"), sprintf(_("Cannot modify IMAP mailbox quota: %s"), '<br><br><i>'.imap_last_error().'</i>'), ERROR_DIALOG);
-      return (FALSE);
+    mailMethod::deleteMailbox();
+
+    if(!$this->is_connected() || !$this->imap_handle){
+      trigger_error("Method not connected, catch error.");
+      return(FALSE);
+    }
+
+    $this->build_account_id ();
+
+    $cfg= $this->ServerList[$this->MailServer];
+    @imap_setacl ($this->imap_handle, $this->account_id, $cfg["admin"], "lrswipcda");
+
+    if ($this->config->boolValueIsTrue("mailAccount","cyrusDeleteMailbox")){
+      if (!imap_deletemailbox($this->imap_handle, $cfg["connect"].$this->account_id)){
+        $this->error = imap_last_error();
+        return (FALSE);
+      }
+    } else{ 
+      msg_dialog::display(_("Mail info"),
+        sprintf(_("LDAP entry has been removed but Cyrus mailbox (%s) is kept.\nPlease delete it manually!"),
+        $this->account_id), INFO_DIALOG);
     }
     return (TRUE);
   }
 
-
-  function setSharedFolderPermissions($folder, $permissions)
+  
+  public function getMailboxList()
   {
-    /* Get list of subfolders */
-    $folders= $this->getMailboxList($folder, "");
-    $folders[]= $folder;
-    
-    foreach ($folders as $subfolder){
+    mailMethod::getMailboxList();
 
-      /* Set shared folder acl's */
-      if (function_exists('imap_getacl')){
+    if(!$this->is_connected() || !$this->imap_handle){
+      trigger_error("Method not connected, catch error.");
+      return(array());
+    }
 
-        /* Remove all acl's for this folder */
-        $users= @imap_getacl ($this->mbox, $subfolder);
-        if(is_array($users)){
-          foreach ($users as $userid => $perms){
-            imap_setacl ($this->mbox, $subfolder, $userid, "");
-          }
-        }
-      } else {
-        msg_dialog::display(_("Internal error"), _("Cannot remove IMAP ACL: imap_getacl not implemented!"), ERROR_DIALOG);
+    $result = array();
+
+    /* Get server config */
+    $cfg= $this->ServerList[$this->MailServer];
+
+    /* Create search string
+       And prepare replacements 
+     */ 
+    if(preg_match("/\@/",$this->account_id)){
+      $search = preg_replace("/\@/","/*@",$this->account_id);
+      $with_domain = TRUE;
+    }else{
+      $search = $this->account_id."/*";
+      $with_domain = FALSE;
+    }
+    $folder = $this->account_id;
+    if(preg_match("/\@/",$folder)){
+      $folder = preg_replace("/\@.*$/","",$folder);
+    }
+
+    /* Contact imap server */
+    $list = @imap_listmailbox($this->imap_handle, $cfg["connect"], $this->account_id);
+    $list2 = @imap_listmailbox($this->imap_handle, $cfg["connect"], $search);
+
+    /* Create list of returned folder names */
+    if (is_array($list)){
+
+      /* Merge in subfolders */
+      if(is_array($list2)){
+        $list = array_merge($list,$list2);
       }
 
-      /* Set permissions for this folder */
-      foreach ($permissions as $user => $acl){
-        imap_setacl ($this->mbox, $subfolder, $user, $acl);
+      foreach ($list as $val){
+        $str = trim(preg_replace("/^\{[^\}]*+\}/","",$val));
+        if($with_domain){
+          $str = trim(preg_replace("/\@.*$/","",$str));
+        }
+        $str = preg_replace ("/^.*".preg_quote($folder, '/')."/","INBOX", 
+          mb_convert_encoding($str, "UTF-8", "UTF7-IMAP"));
+        $result[] = $str;      
       }
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,trim(implode($result,", "),", "),
+          "<b>IMAP: Received mailbox folders.</b>");
+      $this->error = imap_last_error();
+    }else{
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,imap_last_error(),
+          "<b>IMAP: Cannot receive mailbox folders.</b>");
+      $this->error = imap_last_error();
+      return(array());
     }
 
+    /* Append "INBOX" to the folder array if result is empty and request comes from user dialog */
+    if(!count($result)){
+      $result[] = "INBOX";
+    }
+
+    return($result);
   }
 
 
-  function getSharedFolderPermissions($folder)
+  /*! \brief  Returns configured acls
+   */
+  public function  getFolderACLs($folder_acls)
   {
-    $result= array();
+    $this->reset_error();
 
     /* imap_getacl available? */
     if (!function_exists('imap_getacl')){
-      msg_dialog::display(_("Internal error"), _("Cannot retrieve IMAP ACL: imap_getacl not implemented!"), ERROR_DIALOG);
+      $this->error = _("The module imap_getacl is not implemented!");
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"The imap_getacl module is missing!",
+          "<b>IMAP: Cannot set folder acls.</b>");
+      return($folder_acls);
     }
 
-    /* Get permissions in case of shared folders */
-    else {
-      $users= imap_getacl ($this->mbox, $folder);
+    /* Get ACLs and merge them with the already given acls (ldap)
+     */
+    $this->build_account_id();
+    $acls = imap_getacl ($this->imap_handle, $this->account_id);
+    foreach($acls as $user => $acl){
+      if($user == "anyone") $user = "__anyone__"; // Map to internal placeholder
+      $folder_acls[$user] = $acl;
+    }
 
-      foreach ($users as $userid => $perms){
-        $result[preg_replace('/^user\./', '', $userid)]= $perms;
+    /* Merge given ACL with acl mapping
+       This ensures that no ACL will accidentally overwritten by gosa.
+     */
+    foreach($folder_acls as $user => $acl){
+      if(!isset($this->acl_mapping[$acl])){
+        $this->acl_mapping[$acl] = $acl;
       }
-
     }
 
-    return ($result);
+    return($folder_acls);
   }
 
 
-  function deleteMailbox($folder)
+
+  /*! \brief  Write ACLs back to imap or what ever
+   */
+  public function  setFolderACLs($permissions)
   {
-    $cfg= $this->config[$this->gosaMailServer];
-    imap_setacl ($this->mbox, $folder, $cfg["admin"], "lrswipcda");
-    if (!imap_deletemailbox($this->mbox, $cfg["connect"].$folder)){
-      msg_dialog::display(_("IMAP error"), sprintf(_('Cannot remove IMAP mailbox: %s'), '<br><br><i>'.imap_last_error().'</i>'), ERROR_DIALOG);
-      return (FALSE);
+    $this->reset_error();
+
+    /* imap_getacl available? */
+    if (!function_exists('imap_getacl')){
+      $this->error = _("The module imap_getacl is not implemented!");
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"The imap_getacl module is missing!",
+          "<b>IMAP: Cannot set folder acls.</b>");
+      return(FALSE);
     }
-    return (TRUE);
-  }
 
+    /* Get list of subfolders */
+    $folders= $this->getMailboxList();
+    foreach ($folders as $subfolder){
+      $folder_id = $this->create_folder_id($subfolder);
+
+      /* Remove all acl's for this folder */
+      $users= @imap_getacl ($this->imap_handle, $folder_id);
+      
+      if(is_array($users)){
+        foreach ($users as $userid => $perms){
+          $userid = strtolower($userid);
+          imap_setacl ($this->imap_handle, $folder_id, $userid, "");
+          @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,$folder_id." -> ".$userid,
+              "<b>IMAP: Removing folder permissions.</b>");
+        }
+      }
+    }
 
-  function configureFilter($user, $gosaMailDeliveryMode,
-      $mail, $gosaMailAlternateAddress,
-      $gosaMailMaxSize,
-      $gosaSpamMailbox, $gosaSpamSortLevel,
-      $gosaVacationMessage)
-  {
-    $cfg= $this->config[$this->gosaMailServer];
+    /* Set permissions for this folder */
+    foreach($folders as $subfolder){
+      $folder_id = $this->create_folder_id($subfolder);
 
-    /* Build spamlevel. Spamassassin tags mails with "*" for each integer
-       point of spam. So a spam level of 5.3 gets "*****" which can be
-       checked easily by spam filters */
-    $spamlevel= "";
-    for ($i= 0; $i<$gosaSpamSortLevel; $i++){
-      $spamlevel .= "*";
+      foreach ($permissions as $user => $acl){
+        imap_setacl ($this->imap_handle, $folder_id, $user, $acl);
+        @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,$folder_id." -> ".$user.": ".$acl,
+            "<b>IMAP: Setting new folder permissions.</b>");
+      }
     }
+    return(TRUE);
+  }
+
 
-    /* Log into the mail server */
-    $sieve= new sieve($cfg["sieve_server"], $cfg["sieve_port"], $user,
-        $cfg["password"], $cfg["admin"]);
+  public function saveSieveSettings()
+  {
+    mailMethod::saveSieveSettings();
+
+    // Check file integrity 
+    $files = array();
+    foreach(array("sieve-header.txt","sieve-spam.txt","sieve-mailsize.txt","sieve-vacation.txt","sieve-discard.txt") as $file){
+      if(!file_exists(CONFIG_DIR."/".$file) || ! is_readable(CONFIG_DIR."/".$file)){
+        $files[] = CONFIG_DIR."/".$file;
+        @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__ , CONFIG_DIR."/".$file,
+            "<b>Sieve template missing, please locate and move the template file: </b>");
+      }
+    }
+    if(count($files)){
+      $msg = sprintf(_("File '%s' does not exist!"),implode($files,", "));
+      $msg .= "&nbsp;"._("The sieve script may not be written correctly.");
+      msg_dialog::display(_("Warning"),$msg,WARNING_DIALOG);
+    }
 
+    /* Map attribute from parent class 
+     */
+    $mail = $this->parent->mail;
+    $gosaMailDeliveryMode = $this->parent->gosaMailDeliveryMode;
+    $gosaMailAlternateAddress = $this->parent->gosaMailAlternateAddress;
+    $gosaMailMaxSize = $this->parent->gosaMailMaxSize;
+    $gosaSpamMailbox = $this->parent->gosaSpamMailbox;
+    $gosaSpamSortLevel = $this->parent->gosaSpamSortLevel;
+    $gosaVacationMessage = $this->parent->gosaVacationMessage;
+
+    /* Try to login into sieve
+     */ 
+    $cfg = $this->ServerList[$this->MailServer];
+    $sieve= new sieve($cfg["sieve_server"], $cfg["sieve_port"], $this->getUAttribValue(),
+        $cfg["password"], $cfg["admin"],$cfg["sieve_option"]);
     if (!$sieve->sieve_login()){
-      msg_dialog::display(_("SIEVE error"), sprintf(_("Cannot log into SIEVE server: %s"), '<br><br><i>'.to_string($sieve->error_raw).'</i>'), ERROR_DIALOG);
-      return;
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,$sieve->error_raw ,"<b>SIEVE: login failed.</b>");
+      $this->error = $sieve->error_raw;
+      return(FALSE);
     }
 
-    /* Load current script from server and remove everything between the comments
-       "###GOSA" */
+    /* Build spamlevel. Spamassassin tags mails with "*" for each integer
+       point of spam. So a spam level of 5.3 gets "*****" which can be
+       checked easily by spam filters */
+    $spamlevel= str_pad("",(int) $gosaSpamSortLevel,"*");
+
+    /* Get current sieve script named 'gosa'.
+        Check if it valid ("###GOSA" must be the first string).
+        If it is valid just replace it, if it is NOT valid
+         create a backup of the old 
+     */
     $script= "";
     if($sieve->sieve_listscripts()){
       if (in_array("gosa", $sieve->response)){
-
-        /* get old GOsa script */
         if(!$sieve->sieve_getscript("gosa")){
-          msg_dialog::display(_("SIEVE error"), sprintf(_("Cannot retrieve SIEVE script: %s"), '<br><br><i>'.to_string($sieve->error_raw).'</i>'), ERROR_DIALOG);
-          return;
+          $this->error = sprintf(_("Cannot retrieve SIEVE script: %s"),to_string($sieve->error_raw));
+          @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,$sieve->error_raw ,
+              "<b>SIEVE: Connot read 'gosa' sieve script.</b>");
+          $this->error = $sieve->error_raw;
+          return(FALSE);
         }
 
+        $is_valid_script = FALSE;
         foreach ($sieve->response as $line){
-          if (preg_match ("/^###GOSA/", $line)){
-            break;
+          if(empty($line)) continue;
+          if (preg_match ("/^###GOSA/", $line) && strlen($script) == 0){
+            $is_valid_script = TRUE;
           }
           $line= rtrim($line);
-          if (!preg_match ('/^\s*$/', $line)){
-            $script .= $line."\n";
-          }
+          $script .= $line;
         }
 
+        if($is_valid_script || strlen($script) == 0 || empty($script)){
+          @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,"" ,
+              "<b>SIEVE</b>: Sieve script 'gosa' was a valid GOsa script and will be replaced.");
+        }else{
+          $new_name = "non_gosa_".date("Ymd_H-i-s");
+          $sieve->sieve_sendscript($new_name, $script);
+          @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__,$this->sieve->error_raw ,
+              "<b>SIEVE</b>: Non GOsa sieve script. <b>Creating backup of the current sieve script '".$new_name."'.</b>");
+        }
       }
     }
 
+
+    /*****
+      Build up new sieve script here.
+     *****/
+
+
     /* Only create a new one, if it is not empty */
+    $script= "";
     if (is_integer(strpos($gosaMailDeliveryMode, "R")) ||
         is_integer(strpos($gosaMailDeliveryMode, "C")) ||
-        !is_integer(strpos($gosaMailDeliveryMode, "L")) ||
+        is_integer(strpos($gosaMailDeliveryMode, "I")) ||
         is_integer(strpos($gosaMailDeliveryMode, "V")) ||
         is_integer(strpos($gosaMailDeliveryMode, "S"))){
 
@@ -337,35 +581,36 @@ class mailMethodCyrus extends mailMethod
       foreach ($gosaMailAlternateAddress as $val){
         $addrlist .= ", \"$val\"";
       }
-      $vacmsg= $gosaVacationMessage;
+      $vacmsg= addslashes(addslashes($gosaVacationMessage));
       $text= preg_replace('/"/', '\\"', implode ("", file(CONFIG_DIR."/sieve-vacation.txt")));
       eval ("\$script.=\"$text\";");
     }
 
     /* If no local delivery is wanted, tell the script to discard the mail */
-    if (!is_integer(strpos($gosaMailDeliveryMode, "L"))){
+    if (is_integer(strpos($gosaMailDeliveryMode, "I"))){
       $text= preg_replace('/"/', '\\"', implode ("", file(CONFIG_DIR."/sieve-discard.txt")));
       eval ("\$script.=\"$text\";");
     }
 
-    /* Just be aware of null scripts... */
-    if (!isset ($script)){
-      $script= "";
-    }
+    /****
+      Sieve script build complete
+     ****/
 
     /* Upload script and make it the default one */
     if (!$sieve->sieve_sendscript("gosa", $script)){
-      msg_dialog::display(_("SIEVE error"), sprintf(_("Cannot store SIEVE script: %s"), '<br><br><i>'.to_string($sieve->error_raw).'</i>'), ERROR_DIALOG);
-      return;
+      $this->error = sprintf(_("Cannot store SIEVE script: %s"), to_string($sieve->error_raw));
+      @DEBUG (DEBUG_MAIL, __LINE__, __FUNCTION__, __FILE__, "Error was: ".to_string($sieve->error_raw) ,
+        "<b>SIEVE: Writing new Sieve script failed!</b>");
+      return(FALSE);
     }
+
     if(!$sieve->sieve_setactivescript("gosa")){
-      msg_dialog::display(_("SIEVE error"), sprintf(_("Cannot activate SIEVE script: %s"), '<br><br><i>'.to_string($sieve->error_raw).'</i>'), ERROR_DIALOG);
-      return;
+      $this->error = sprintf(_("Cannot activate SIEVE script: %s"), to_string($sieve->error_raw));
+      return(FALSE);
     }
 
     $sieve->sieve_logout();
   }
-
 }
 
 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: