Code

Updated handling of shared folder ACLs closes #1111
[gosa.git] / gosa-plugins / mail / admin / groups / mail / class_groupMail.inc
1 <?php
3 class mailgroup extends plugin
4 {
5   /* Multiple edit */
6   var $gosaMailForwardingAddress_Some  = array();  // Used in multiple edit 
8   /* Default values */
9   var $mail                       = "";           // Default mail address 
10   var $gosaMailAlternateAddress   = array();  // Set default Alternate Mail Adresses to empty array
11   var $gosaMailForwardingAddress  = array();  // Forwarding also empty
12   var $gosaMailServer             = "";       // Selected mailserver 
13   var $gosaMailQuota              = "";       // Defined Quota 
14   var $gosaVacationMessage        = "";       // Vocation message 
15   var $gosaSpamSortLevel          = "";     
16   var $gosaSpamMailbox            = "";
17   var $gosaSharedFolderTarget     ;
18   var $gosaMailDeliveryMode       = "[L        ]";   // 
19   var $gosaMailMaxSize            = "";       // 
20   var $FolderType                 = array("CAT" => '', "SUB_CAT" => '');
22   var $quotaUsage                 = -1;        // -1 Means undefined
24   /* Internal */
25   var $AclTypes                   = array();
26   var $members                    = array();  // Group members
27   var $mailusers                  = array();  // Group member with mail account
28   var $folder_acls                = array();
29   var $MailMethod = NULL; 
30   var $mailAddressSelect             = FALSE;    
31   var $remove_folder_from_imap    = true;
32   var $view_logged                = FALSE;
33   var $mailDomainPart             = "";
35   /* attribute list for save action */
36   var $attributes= array( "mail",   "gosaMailServer", "gosaMailQuota", "gosaMailMaxSize",
37       "gosaMailAlternateAddress", "gosaMailForwardingAddress",
38       "gosaMailDeliveryMode", "gosaSpamSortLevel", "gosaSpamMailbox",
39       "acl","gosaSharedFolderTarget", "gosaVacationMessage");
41   var $objectclasses= array("gosaMailAccount");
42   var $multiple_support = FALSE; // Not tested yet
44   var $uid = "";
45   var $cn ="";
46   var $orig_cn = "";
47   var $show_effective_memeber = FALSE;
49   function __construct (&$config, $dn= NULL, $base_object= NULL)
50   {
51     plugin::plugin($config, $dn);
53     /* Get attributes from parent object
54      */
55     foreach(array("uid","cn") as $attr){
56       if(isset($this->parent->by_object['group']) && isset($this->parent->by_object['group']->$attr)){
57         $this->$attr = $this->parent->by_object['group']->$attr;
58       }elseif(isset($this->attrs[$attr])){
59         $this->$attr = $this->attrs[$attr][0];
60       }
61     }
62     $this->orig_cn = $this->uid = $this->cn;
64     /* Intialize the used mailMethod
65      */
66     $tmp = new mailMethod($config,$this,"group");
67     $this->mailMethod           = $tmp->get_method();
68     $this->mailMethod->fixAttributesOnLoad();
69     $this->mailDomainParts      = $this->mailMethod->getMailDomains();
70     $this->AvailableFolderTypes = $this->mailMethod->getAvailableFolderTypes();
71     $this->MailBoxes = array();
73     /* Remember account status
74      */
75     $this->initially_was_account = $this->is_account;
77     /* While we are not not allowed to modify the mail address
78      *  and this is a new mail account, preset the user part of the 
79      *  mail address with the accounts cn.
80      */ 
81     if(!$this->mailMethod->isModifyableMail() && !$this->initially_was_account){
82       $this->mail = $base_object->cn;
83     }
85     /* Load folder_acls with defaults.
86       anyone -- The default acl, will be written to ldap.
87       member -- The ACL used for the members.
88      */ 
89     $this->folder_acls = $this->mailMethod->getDefaultACLs();
91     /* Load acls
92        The most used acl will be used as member acl, this
93         shortens the listed acls.        
94        This may be merged/overwritten by the mail methods.
95      */
96     $ldap = $this->config->get_ldap_link();
97     if(isset($this->attrs['acl'])){
98       for($i = 0; $i < $this->attrs['acl']['count'] ; $i++){
100         /* Be carefull here, since kolab22 uses spaces in the acls (herbert read anon/post)
101          */
102         $str = $this->attrs['acl'][$i];
103         list($name, $acl) = preg_split("/[ ]{1}/", $str, 2);
104         if($name == "anyone") $name = "__anyone__";
105         $this->folder_acls[$name] = $acl;
106       }
107     }
109     /* Initialize configured values
110      */
111     if($this->is_account){
112       if($this->mailMethod->connect() && $this->mailMethod->account_exists()){
114         /* Read quota */
115         $this->gosaMailQuota = $this->mailMethod->getQuota($this->gosaMailQuota);
116         $this->quotaUsage = $this->mailMethod->getQuotaUsage($this->quotaUsage);
117         if($this->mailMethod->is_error()){
118           msg_dialog::display(_("Mail error"), sprintf(_("Cannot read quota settings: %s"),
119                 $this->mailMethod->get_error()), ERROR_DIALOG);
120         }
122         /* Read mailboxes */
123         $this->MailBoxes = $this->mailMethod->getMailboxList($this->MailBoxes);
124         if($this->mailMethod->is_error()){
125           msg_dialog::display(_("Mail error"), sprintf(_("Cannot get list of mailboxes: %s"),
126                 $this->mailMethod->get_error()), ERROR_DIALOG);
127         }
129         /* Receive folder types */
130         $this->FolderType = $this->mailMethod->getFolderType($this->FolderType);
131         if($this->mailMethod->is_error()){
132           msg_dialog::display(_("Mail error"), sprintf(_("Cannot receive folder types: %s"),
133                 $this->mailMethod->get_error()), ERROR_DIALOG);
134         }
136         /* Receive permissions */  
137         $this->folder_acls = $this->mailMethod->getFolderACLs($this->folder_acls);
138         if($this->mailMethod->is_error()){
139           msg_dialog::display(_("Mail error"), sprintf(_("Cannot receive folder permissions: %s"),
140                 $this->mailMethod->get_error()), ERROR_DIALOG);
141         }
143       }elseif(!$this->mailMethod->is_connected()){
144         msg_dialog::display(_("Mail error"), sprintf(_("Mail method cannot connect: %s"),
145               $this->mailMethod->get_error()), ERROR_DIALOG);
146       }elseif(!$this->mailMethod->account_exists()){
147         msg_dialog::display(_("Mail error"), sprintf(_("Mailbox '%s' doesn't exists on mail server: %s"),
148               $this->mailMethod->get_account_id(),$this->gosaMailServer), ERROR_DIALOG);
149       }
151       /* If the doamin part is selectable, we have to split the mail address
152        */
153       if(!(!$this->mailMethod->isModifyableMail() && $this->is_account)){
154         if($this->mailMethod->domainSelectionEnabled() || $this->mailMethod->mailEqualsCN()){
155           $this->mailDomainPart = preg_replace("/^[^@]*+@/","",$this->mail);
156           $this->mail = preg_replace("/@.*$/","\\1",$this->mail);
157           if(!in_array($this->mailDomainPart,$this->mailDomainParts)){
158             $this->mailDomainParts[] = $this->mailDomainPart;
159           }
160         }
161       }
163       /* Load attributes containing arrays */
164       foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
165         $this->$val= array();
166         if (isset($this->attrs["$val"]["count"])){
167           for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
168             array_push($this->$val, $this->attrs["$val"][$i]);
169           }
170         }
171       }
172     }
174     /* Disconnect mailMethod. Connect on demand later.
175      */
176     $this->mailMethod->disconnect();
177     $this->AclTypes = $this->mailMethod->getAclTypes();
179     /* Summarize most used ACLs as member acl 
180      */
181     if(count($this->folder_acls) > 2){
182       $acl_usage = array();
183       $most_acl = $this->folder_acls['__member__'];
184       $most_cnt = 0;
185       $member = $this->get_member();
186       foreach($this->folder_acls as $user => $acl){
187         if(preg_match("/^__/",$user)) continue;
188         if(!in_array($user,$member['mail'])) continue; 
189         if(!isset($acl_usage[$acl])) $acl_usage[$acl]=0;
190         $acl_usage[$acl] ++;
191         if($acl_usage[$acl] > $most_cnt){
192           $most_cnt = $acl_usage[$acl];
193           $most_acl = $acl;
194         }
195       }
196       $this->folder_acls['__member__'] = $most_acl;  
197       foreach($this->folder_acls as $name => $acl){
198         if(preg_match("/^__/",$name)) continue;
199         if($acl == $most_acl && in_array($name,$member['mail'])){
200           unset($this->folder_acls[$name]);
201         }
202       }
203     }
205     /* Get global filter config */
206     if (!session::is_set("gmailfilter")){
207       $ui= get_userinfo();
208       $base= get_base_from_people($ui->dn);
209       $gmailfilter= array( "depselect"       => $base,
210           "muser"            => "",
211           "regex"           => "*");
212       session::set("gmailfilter", $gmailfilter);
213     }
214   }
216  
217   /*! \brief  Returns all group members once with 'dn' and once with 'mail'.
218               This function is used to summarize ACLs by member acls.
219       @return Array   Containing all members, with mail and dn
220    */ 
221   function get_member()
222   {
223     $member = array('all' => array(), 'mail' => array());
224     $ldap = $this->config->get_ldap_link();
225     $ldap->cd($this->config->current['BASE']);
226     if(isset($this->parent->by_object['group'])){
227       foreach($this->parent->by_object['group']->memberUid as $uid){
228         if(!isset($this->parent->by_object['group']->dnMapping[$uid])) continue;
229         $dn = $this->parent->by_object['group']->dnMapping[$uid];
230         $member['all'][$uid] = $uid;
231         if($ldap->object_match_filter($dn,"(&(objectClass=gosaMailAccount)(".$this->mailMethod->getUAttrib()."=*))")){
232           $ldap->cat($dn);
233           $attrs = $ldap->fetch();
234           $member['mail'][$uid] = $attrs[$this->mailMethod->getUAttrib()][0]; 
235         }
236       }
237     }else{
238       if(!isset($this->attrs['memberUid'])) return($member);
239       $uattrib = $this->mailMethod->getUAttrib();
240       $users = get_list("(&(objectClass=person)(objectClass=gosaAccount)(uid=*))",
241               "users",$this->config->current['BASE'],
242               array("uid","objectClass",$uattrib),GL_SUBSEARCH | GL_NO_ACL_CHECK);
243       foreach($users as $user){
244         $member['all'][$user['uid'][0]] = $user['dn'];
245         if(isset($user[$uattrib]) 
246             && in_array("gosaMailAccount",$user['objectClass']) 
247             && (in_array($user['uid'][0], $this->attrs['memberUid']))){
248           $member['mail'][$user['uid'][0]] = $user[$uattrib][0];
249         }
250       }
251     }
252     return($member);
253   }
256   function execute()
257   {
258     /* Call parent execute */
259     plugin::execute();
261     /* Log view */
262     if($this->is_account && !$this->view_logged){
263       $this->view_logged = TRUE;
264       new log("view","groups/".get_class($this),$this->dn);
265     }
266  
267     /****************
268       Account status
269      ****************/
271     if(!$this->multiple_support_active){
273       if(isset($_POST['modify_state'])){
274         if($this->is_account && $this->acl_is_removeable() && $this->mailMethod->accountRemoveAble()){
275           $this->is_account= FALSE;
276         }elseif(!$this->is_account && $this->acl_is_createable() && $this->mailMethod->accountCreateable()){
277           $this->is_account= TRUE;
278         }
279       }
281       if ($this->is_account){
282         $reason = "";
283         if(!$this->mailMethod->accountRemoveable($reason)){
284           $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),$reason ,TRUE,TRUE);
285         }else{
286           $display= $this->show_disable_header(msgPool::removeFeaturesButton(_("Mail")),msgPool::
287               featuresEnabled(_("Mail")));
288         }
289       } else {
290         $reason = "";
291         if(!$this->mailMethod->accountCreateable($reason)){
292           $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Mail")),$reason ,TRUE,TRUE);
293         }else{
294           $display= $this->show_disable_header(msgPool::addFeaturesButton(_("Mail")),msgPool::
295               featuresDisabled(_("Mail")));
297           /* Show checkbox that allows us to remove imap entry too*/
298           if($this->initially_was_account){
299             $c = "";
300             if($this->remove_folder_from_imap){
301               $c= " checked ";
302             }
303             $display .= "<h2>Shared folder delete options</h2>
304               <input class='center' type='checkbox' name='remove_folder_from_imap' value='1' ".$c."
305               title='"._("Remove shared folder from mail server database when entry gets removed in LDAP")."'>";
306             $display .= _("Remove the shared folder and all its contents after saving this account");
307           }
308         }
309         return ($display);
310       }
311     }
313     
314     /****************
315       Preset mail attribute
316      ****************/
317     if(empty($this->mail) && $this->mailMethod->mailEqualsCN() && !$this->initially_was_account){
318       if($this->mailMethod->domainSelectionEnabled()){
319         $this->mail = &$this->parent->by_object['group']->cn;
320       }
321     }
324     /****************
325       Forward addresses
326      ****************/
328     if (isset($_POST['add_local_forwarder'])){
329       $this->mailAddressSelect= new mailAddressSelect($this->config, get_userinfo());
330       $this->dialog= TRUE;
331     }
333     if (isset($_POST['mailAddressSelect_cancel'])){
334       $this->mailAddressSelect= FALSE;
335       $this->dialog= FALSE;
336     }
338     if (isset($_POST['mailAddressSelect_save'])){
339       if($this->acl_is_writeable("gosaMailForwardingAddress")){
340         $list = $this->mailAddressSelect->save();
341         foreach ($list as $entry){
342           $val = $entry['mail'][0];
343           if (!in_array ($val, $this->gosaMailAlternateAddress) && $val != $this->mail){
344             $this->addForwarder($val);
345             $this->is_modified= TRUE;
346           }
347         }
348         $this->mailAddressSelect= FALSE;
349         $this->dialog= FALSE;
350       } else {
351         msg_dialog::display(_("Error"), _("Please select an entry!"), ERROR_DIALOG);
352       }
353     }
355     if($this->mailAddressSelect instanceOf mailAddressSelect){
356       $used  = array();
357       $used['mail'] = array_values($this->gosaMailAlternateAddress);
358       $used['mail'] = array_merge($used['mail'], array_values($this->gosaMailForwardingAddress));
359       $used['mail'][] = $this->mail;
361       // Build up blocklist
362       session::set('filterBlacklist', $used);
363       return($this->mailAddressSelect->execute());
364     }
366     if (isset($_POST['add_forwarder'])){
367       if ($_POST['forward_address'] != ""){
368         $address= $_POST['forward_address'];
369         $valid= FALSE;
370         if (!tests::is_email($address)){
371           if (!tests::is_email($address, TRUE)){
372             if ($this->is_template){
373               $valid= TRUE;
374             } else {
375               msg_dialog::display(_("Error"), msgPool::invalid(_("Mail address"),
376                     "","","your-address@your-domain.com"),ERROR_DIALOG);
377             }
378           }
379         } elseif ($address == $this->mail
380             || in_array($address, $this->gosaMailAlternateAddress)) {
381           msg_dialog::display(_("Error"),_("Cannot add primary address to the list of forwarders!") , ERROR_DIALOG);
382         } else {
383           $valid= TRUE;
384         }
385         if ($valid){
386           if($this->acl_is_writeable("gosaMailForwardingAddress")){
387             $this->addForwarder ($address);
388             $this->is_modified= TRUE;
389           }
390         }
391       }
392     }
393     if (isset($_POST['delete_forwarder'])){
394       $this->delForwarder ($_POST['forwarder_list']);
395     }
397  
398     /****************
399       Alternate addresses
400      ****************/
402     if (isset($_POST['add_alternate'])){
403       $valid= FALSE;
404       if (!tests::is_email($_POST['alternate_address'])){
405         if ($this->is_template){
406           if (!(tests::is_email($_POST['alternate_address'], TRUE))){
407             msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),
408                   "","","your-domain@your-domain.com"),     ERROR_DIALOG);
409           } else {
410             $valid= TRUE;
411           }
412         } else {
413           msg_dialog::display(_("Error"),msgPool::invalid(_("Mail address"),
414                 "","","your-domain@your-domain.com"),       ERROR_DIALOG);
415         }
416       } else {
417         $valid= TRUE;
418       }
419       if ($valid && ($user= $this->addAlternate ($_POST['alternate_address'])) != ""){
420         $ui= get_userinfo();
421         $addon= "";
422         if ($user[0] == "!") {
423           $addon= sprintf(_("Address is already in use by group '%s'."), mb_substr($user, 1));
424         } else {
425           $addon= sprintf(_("Address is already in use by user '%s'."), $user);
426         }
427         msg_dialog::display(_("Error"), msgPool::duplicated(_("Mail address"))."<br><br><i>".
428             "$addon</i>", ERROR_DIALOG);
429       }
430     }
431     if (isset($_POST['delete_alternate']) && isset($_POST['alternates_list'])){
432       $this->delAlternate ($_POST['alternates_list']);
433     }
436     /****************
437       SMARTY- Assign smarty variables
438      ****************/
440     /* Load templating engine */
441     $smarty= get_smarty();
442     $smarty->assign("initially_was_account", $this->initially_was_account);
443     $smarty->assign("isModifyableMail", $this->mailMethod->isModifyableMail());
444     $smarty->assign("isModifyableServer", $this->mailMethod->isModifyableServer());
445     $smarty->assign("mailEqualsCN", $this->mailMethod->mailEqualsCN());
446     $smarty->assign("folder_acls" , $this->postable_acls());
447     $smarty->assign("AclTypes" ,    $this->AclTypes);
448     $smarty->assign("Effective",    $this->get_effective_member_acls());
449     $smarty->assign("show_effective_memeber",    $this->show_effective_memeber);
450   
451     $smarty->assign("quotaEnabled", $this->mailMethod->quotaEnabled());
452     if($this->mailMethod->quotaEnabled()){
453       $smarty->assign("gosaMailQuota",$this->gosaMailQuota);
454       $smarty->assign("quotaUsage",   mailMethod::quota_to_image($this->quotaUsage,$this->gosaMailQuota)); 
455     }
457     $smarty->assign("MailDomains", $this->mailDomainParts);
458     $smarty->assign("MailDomain" , $this->mailDomainPart);
459     $smarty->assign("MailServers", $this->mailMethod->getMailServers());
460     $smarty->assign("allowSieveManagement", $this->mailMethod->allowSieveManagement());
462     $smarty->assign("domainSelectionEnabled", $this->mailMethod->domainSelectionEnabled());
463     $smarty->assign("folderTypesEnabled",$this->mailMethod->folderTypesEnabled());
464     $smarty->assign("AvailableFolderTypes", $this->AvailableFolderTypes);
465     $smarty->assign("FolderType", $this->FolderType);
466  
467     if (is_numeric($this->gosaMailQuota) && $this->gosaMailQuota != 0){
468       if($this->acl_is_readable("gosaMailQuota")){
469         $smarty->assign("quotausage", progressbar(round(($this->quotaUsage * 100)/ $this->gosaMailQuota),100,15,true));
470         $smarty->assign("quotadefined", "true");
471       }else{
472         $smarty->assign("quotadefined", "true");
473         $smarty->assign("quotausage", "-");
474       }
475     } else {
476       $smarty->assign("quotadefined", "false");
477     }
479     /* Assign acls */
480     $tmp = $this->plInfo();
481     foreach($tmp['plProvidedAcls'] as $name => $translation) {
482       $smarty->assign($name."ACL",$this->getacl($name));
483     }
484     foreach($this->attributes as $name){
485       $smarty->assign($name,$this->$name);
486     }
490     $smarty->assign("mailServers", $this->mailMethod->getMailServers());
491     if (preg_match("/I/", $this->gosaMailDeliveryMode)) {
492       $smarty->assign("only_local", "checked");
493     }else{
494       $smarty->assign("only_local", "");
495     }
498     /******
499       Multi edit support 
500      ******/
501     foreach($this->attributes as $attr){
502       if(in_array($attr,$this->multi_boxes)){
503         $smarty->assign("use_".$attr,TRUE);
504       }else{
505         $smarty->assign("use_".$attr,FALSE);
506       }
507     }
509     /* Multiple support handling */
510     foreach(array("kolabFolderType") as $attr){
511       if(in_array($attr,$this->multi_boxes)){
512         $smarty->assign("use_".$attr,TRUE);
513       }else{
514         $smarty->assign("use_".$attr,FALSE);
515       }
516     }
518     $smarty->assign("Forward_all",$this->gosaMailForwardingAddress);
519     $smarty->assign("Forward_some",$this->gosaMailForwardingAddress_Some);
520     $smarty->assign("multiple_support",$this->multiple_support_active);
522     $display.= $smarty->fetch (get_template_path('mail.tpl', TRUE, dirname(__FILE__)));
523     return ($display);
524   }
527   /* remove object from parent */
528   function remove_from_parent()
529   {
530     if(!$this->initially_was_account){
531       return;
532     }
533  
534     /* If domain part was selectable, contruct mail address */
535     if($this->mailMethod->domainSelectionEnabled() || $this->mailMethod->mailEqualsCN()){
536       $this->mail = $this->mail."@".$this->mailDomainPart;
537     }
539     /* Remove GOsa attributes */
540     plugin::remove_from_parent();
542     /* Zero arrays */
543     $this->attrs['gosaMailAlternateAddress'] = array();
544     $this->attrs['gosaMailForwardingAddress']= array();
546     $this->mailMethod->fixAttributesOnRemove();
547     $this->cleanup();
548     $ldap = $this->config->get_ldap_link();
549     $ldap->cd($this->dn);
550     $ldap->modify ($this->attrs); 
551     if (!$ldap->success()){
552       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
553     }
555     new log("remove","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
558     /* Let the mailMethod remove this mailbox, e.g. from imap and
559        update shared folder membership, ACL may need to be updated.
560      */
561     if (!$this->is_template && $this->remove_folder_from_imap){
563       if(!$this->mailMethod->connect()){
564         msg_dialog::display(_("Mail error"), sprintf(_("Mail method cannot connect: %s"),
565               $this->mailMethod->get_error()), ERROR_DIALOG);
566       }else{
567         if(!$this->mailMethod->deleteMailbox()){
568           msg_dialog::display(_("Mail error"), sprintf(_("Cannot remove mailbox: %s"),
569                 $this->mailMethod->get_error()), ERROR_DIALOG);
570         }
571         if(!$this->mailMethod->updateSharedFolder()){
572           msg_dialog::display(_("Mail error"), sprintf(_("Cannot update shared folder permissions: %s"),
573                 $this->mailMethod->get_error()), ERROR_DIALOG);
574         }
575       }
576     }
577     $this->mailMethod->disconnect();
580     /* Optionally execute a command after we're done */
581     $this->handle_post_events("remove");
582   }
585   /* Save data to object */
586   function save_object()
587   {
588     /* Check if user wants to remove the shared folder from imap too 
589      */
590     if($this->initially_was_account && !$this->is_account){
591       if(isset($_POST['remove_folder_from_imap'])){
592         $this->remove_folder_from_imap = true;
593       }else{
594         $this->remove_folder_from_imap = false;
595       }
596     }
597     if (isset($_POST['mailedit'])){
599       if(isset($_POST['show_effective_memeber'])){
600         $this->show_effective_memeber = !$this->show_effective_memeber;
601       }
603       $mail = $this->mail;
604       $server = $this->gosaMailServer;
605       plugin::save_object();
607       if(!$this->mailMethod->isModifyableServer() && $this->initially_was_account){
608         $this->gosaMailServer = $server;
609       }
610       if(!$this->mailMethod->isModifyableMail() && $this->initially_was_account){
611         $this->mail = $mail;
612       }else{
614         if($this->mailMethod->mailEqualsCN()){
615           $this->mail = &$this->parent->by_object['group']->cn;
616           if(isset($_POST['MailDomain'])){
617             $this->mailDomainPart = get_post('MailDomain');
618           }
619         }
621       /* Get posted mail domain part, if necessary
622        */
623       if($this->mailMethod->domainSelectionEnabled() && isset($_POST['MailDomain'])){
624         if(in_array(get_post('MailDomain'), $this->mailDomainParts)){
625           $this->mailDomainPart = get_post('MailDomain');
626         }
627       }
628     }
630       /* Get folder type 
631        */
632       if($this->mailMethod->folderTypesEnabled()){
633         if(isset($_POST['FolderTypeCAT'])){
634         $this->FolderType['CAT']     = get_post('FolderTypeCAT');
635         }
636         if(isset($_POST['FolderTypeSUB_CAT'])){
637           $this->FolderType['SUB_CAT'] = get_post('FolderTypeSUB_CAT');
638         }
639       }
641       /* Handle posted ACL changes. 
642          Add/del member acls.
643        */
644       if(isset($_POST['mail_acls_posted'])){
645         $new_acls = array();
646         foreach(array("__anyone__","__member__") as $attr){
647           $pname = base64_encode($attr);
648           if(get_post('acl_value_'.$pname)){ 
649             $new_acls[$attr] = get_post('acl_value_'.$pname);
650           }else{
651             $new_acls[$attr] = $this->folder_acls[$attr];
652           }
653         }
655         foreach($this->folder_acls as $user => $acl){
656           $pname = base64_encode($user);
657           if($user == "__member__" || $user == "__anyone__") continue;
658           if(isset($_POST['remove_acl_user_'.$pname])){
659           }elseif(isset($_POST['acl_user_'.$pname])){
660             if($user != get_post('acl_user_'.$pname)){
661               $new_acls[get_post('acl_user_'.$pname)] = get_post('acl_value_'.$pname);
662             }else{
663               $new_acls[$user] = get_post('acl_value_'.$pname);
664             }
665           }else{
666             $new_acls[$user] = $acl;
667           }
668         }
669         if(isset($_POST['add_acl_user'])){
670           $new_acls[_('New')] = $this->folder_acls['__anyone__'];
671         }
672         $this->folder_acls = $new_acls;
673       }
675       /* Handle GOsa mail delivery flags.
676        */
678     /* Assemble mail delivery mode
679        The mode field in ldap consists of values between braces, this must
680        be called when 'mail' is set, because checkboxes may not be set when
681        we're in some other dialog.
683        Example for gosaMailDeliveryMode [LR        ]
684        L - Local delivery
685        R - Reject when exceeding mailsize limit
686        S - Use spam filter
687        V - Use vacation message
688        C - Use custom sieve script
689        I - Only insider delivery */
690       $tmp= preg_replace("/[^a-z]/i","",$this->gosaMailDeliveryMode);
691       if($this->acl_is_writeable("gosaMailDeliveryModeL")){
692         if(!preg_match("/L/",$tmp) && !isset($_POST['drop_own_mails'])){
693           $tmp.="L";
694         }elseif(preg_match("/L/",$tmp) && isset($_POST['drop_own_mails'])){
695           $tmp = preg_replace("/L/","",$tmp);
696         }
697       }
699       $opts = array(
700           "R"   => "use_mailsize_limit",
701           "S"   => "use_spam_filter",
702           "V"   => "use_vacation",
703           "C"   => "own_script",
704           "I"   => "only_local");
706       foreach($opts as $flag => $post){
707         if($this->acl_is_writeable("gosaMailDeliveryMode".$flag)){
708           if(!preg_match("/".$flag."/",$tmp) && isset($_POST[$post])){
709             $tmp.= $flag;
710           }elseif(preg_match("/".$flag."/",$tmp) && !isset($_POST[$post])){
711             $tmp = preg_replace("/".$flag."/","",$tmp);
712           }
713         }
714       }
716       $tmp= "[$tmp]";
717       if ($this->gosaMailDeliveryMode != $tmp){
718         $this->is_modified= TRUE;
719       }
720       $this->gosaMailDeliveryMode= $tmp;
721     }
722   }
725   /* Save data to LDAP, depending on is_account we save or delete */
726   function save()
727   {
728     $ldap= $this->config->get_ldap_link();
730     /* If domain part was selectable, contruct mail address */
731     if(!(!$this->mailMethod->isModifyableMail() && $this->initially_was_account)){
733       if($this->mailMethod->domainSelectionEnabled() || $this->mailMethod->mailEqualsCN()){
734         $this->mail = $this->mail."@".$this->mailDomainPart;
735       }
736     }
738     /* Enforce lowercase mail address and trim whitespaces
739      */
740     $this->mail = trim(strtolower($this->mail));
741     
743     /* Create acls 
744      */
745     $this->acl = array("anyone ".$this->folder_acls['__anyone__']);
746     $member = $this->get_member();
747     $new_folder_acls = array("anyone" => $this->folder_acls['__anyone__']);
748     foreach($member['mail'] as $uid => $mail){
750       /* Do not save overridden acls */
751       if(isset($this->folder_acls[$mail])){
752         continue;
753       }
755       $this->acl[] = $mail." ".$this->folder_acls['__member__'];
756       $new_folder_acls[$mail]=$this->folder_acls['__member__'];
757     }
758     foreach($this->folder_acls as $user => $acls){
759       if(preg_match("/^__/",$user)) continue;
760       $this->acl[] = $user." ".$acls;
761       $new_folder_acls[$user]=$acls;
762     }
763     $this->folder_acls = $new_folder_acls;
764     $this->acl = array_unique($this->acl);
765      
766     /* Call parents save to prepare $this->attrs */
767     plugin::save();
769     /* Save arrays */
770     $this->attrs['gosaMailAlternateAddress'] = $this->gosaMailAlternateAddress;
771     $this->attrs['gosaMailForwardingAddress']= $this->gosaMailForwardingAddress;
773     /* Map method attributes */
774     $this->mailMethod->fixAttributesOnStore();
776     /* Save data to LDAP */
777     $ldap->cd($this->dn);
778     $this->cleanup();
779     $ldap->modify ($this->attrs); 
780     if (!$ldap->success()){
781       msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_MOD, get_class()));
782     }
783     
784     if($this->initially_was_account){
785       new log("modify","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
786     }else{
787       new log("create","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());  
788     }
789     
790     /* Do imap/sieve actions,
791      */
792     $this->mailMethod->connect();
793     if(!$this->mailMethod->is_connected()){
794       msg_dialog::display(_("Mail error"), sprintf(_("Mail method cannot connect: %s"),
795             $this->mailMethod->get_error()), ERROR_DIALOG);
796     }else{
797       if(!$this->mailMethod->updateMailbox()){
798         msg_dialog::display(_("Mail error"), sprintf(_("Cannot update mailbox: %s"),
799               $this->mailMethod->get_error()), ERROR_DIALOG);
800       }
801       if(!$this->mailMethod->setQuota($this->gosaMailQuota)){
802         msg_dialog::display(_("Mail error"), sprintf(_("Cannot write quota settings: %s"),
803               $this->mailMethod->get_error()), ERROR_DIALOG);
804       }
805       /* Save Folder Types, if available 
806        */
807       if($this->mailMethod->folderTypesEnabled()){
808         $this->mailMethod->setFolderType($this->FolderType);
809       }
810       if(!$this->mailMethod->setFolderACLs($this->folder_acls)){
811         msg_dialog::display(_("Mail error"), sprintf(_("Cannot update shared folder permissions: %s"),
812               $this->mailMethod->get_error()), ERROR_DIALOG);
813       }
814     }
815     $this->mailMethod->disconnect();
817     /* Optionally execute a command after we're done */
818     if ($this->initially_was_account == $this->is_account){
819       if ($this->is_modified){
820         $this->handle_post_events("modify");
821       }
822     } else {
823       $this->handle_post_events("add");
824     }
825   }
829   /* Check formular input */
830   function check()
831   {
832     if(!$this->is_account) return array();
833     $ldap= $this->config->get_ldap_link();
836     /* Call common method to give check the hook */
837     $message= plugin::check();
839     /* Ensure that this group isn't renamed if the mailMethod enforces cn mailAttributes 
840      */
841     if($this->mailMethod->mailEqualsCN() && $this->initially_was_account){
842       if($this->cn != $this->orig_cn){
843         $message[] = sprintf(_("The group 'cn' has changed. It can't be changed due to the fact that mail method '%s' relies on it!")
844             ,get_class($this->mailMethod));
845       }
846     }
848     if(empty($this->gosaMailServer)){
849       $message[]= msgPool::noserver(_("Mail"));
850     }
852     /* Mail address checks */
853     $mail = $this->mail;
854     if(!(!$this->mailMethod->isModifyableMail() && $this->initially_was_account)){
855       if($this->mailMethod->domainSelectionEnabled() || $this->mailMethod->mailEqualsCN()){
856         $mail.= "@".$this->mailDomainPart;
857       }
858       if (empty($mail)){
859         $message[]= msgPool::required(_("Primary address"));
860       }elseif (!tests::is_email($mail)){
861         $message[]= msgPool::invalid(_("Mail address"),"","","your-address@your-domain.com");
862       }
863     }
864     
865     /* Check quota */
866     if ($this->gosaMailQuota != '' && $this->acl_is_writeable("gosaMailQuota")){
867       if (!is_numeric($this->gosaMailQuota)) {
868         $message[]= msgPool::invalid(_("Quota size"),$this->gosaMailQuota,"/[0-9]/");
869       } else {
870         $this->gosaMailQuota= (int) $this->gosaMailQuota;
871       }
872     }
874     /* Check if this mail address is already in use */
875     $ldap->cd($this->config->current['BASE']);
876     $filter = "(&(!(objectClass=gosaUserTemplate))(!(cn=".$this->cn."))".
877             "(objectClass=gosaMailAccount)".
878             "(|(mail=".$mail.")(alias=".$mail.")(gosaMailAlternateAddress=".$mail.")))";
879     $ldap->search($filter,array("cn"));
880     if ($ldap->count() != 0){
881             $message[]= msgPool::duplicated(_("Mail address"));
882     }
884     /* Check rejectsize for integer */
885     if ($this->gosaMailMaxSize != '' && $this->acl_is_writeable("gosaMailQuota")){
886       if (!is_numeric($this->gosaMailMaxSize)){
887         $message[]= msgPool::invalid(_("Mail max size"));
888       } else {
889         $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize;
890       }
891     }
893     /* Need gosaMailMaxSize if use_mailsize_limit is checked */
894     if (is_integer(strpos($this->gosaMailDeliveryMode, "reject")) && $this->gosaMailMaxSize == ""){
895       $message[]= _("You need to set the maximum mail size in order to reject anything.");
896     }
898     if(empty($this->gosaMailServer)){
899       $message[] = msgPool::required(_("Mail server"));
900     }
902     return ($message);
903   }
905   /* Adapt from template, using 'dn' */
906   function adapt_from_template($dn, $skip= array())
907   {
908     plugin::adapt_from_template($dn, $skip);
910     foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){
911  
912       if (in_array($val, $skip)){
913         continue;
914       }
916       $this->$val= array();
917       if (isset($this->attrs["$val"]["count"])){
918         for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){
919           $value= $this->attrs["$val"][$i];
920           foreach (array("sn", "givenName", "uid") as $repl){
921             if (preg_match("/%$repl/i", $value)){
922               $value= preg_replace ("/%$repl/i", $this->parent->$repl, $value);
923             }
924           }
925           array_push($this->$val, $value);
926         }
927       }
928     }
929   }
933   function make_name($attrs)
934   {
935     $name= "";
936     if (isset($attrs['sn'][0])){
937       $name= $attrs['sn'][0];
938     }
939     if (isset($attrs['givenName'][0])){
940       if ($name != ""){
941         $name.= ", ".$attrs['givenName'][0];
942       } else {
943         $name.= $attrs['givenName'][0];
944       }
945     }
946     if ($name != ""){
947       $name.= " ";
948     }
950     return ($name);
951   }
953   function getCopyDialog()
954   {
955     if(!$this->is_account) return("");
957     $smarty = get_smarty();
958     $smarty->assign("gosaMailAlternateAddress",$this->gosaMailAlternateAddress);
959     $smarty->assign("gosaMailForwardingAddress",$this->gosaMailForwardingAddress);
960     $smarty->assign("mail",$this->mail);
961     $display= $smarty->fetch (get_template_path('paste_mail.tpl', TRUE, dirname(__FILE__)));
962     $ret = array();
963     $ret['string'] = $display;
964     $ret['status'] = "";
965     return($ret);
966   }
968   function saveCopyDialog()
969   {
970     if(!$this->is_account) return;
972     /* Perform ADD / REMOVE ... for mail alternate / mail forwarding addresses 
973     */
974     $this->execute();
975     if(isset($_POST['mail'])){
976       $this->mail = $_POST['mail'];
977     }
978   }
981   function PrepareForCopyPaste($source)
982   {
983     plugin::PrepareForCopyPaste($source);
984  
985     /* Reset alternate mail addresses */
986     $this->gosaMailAlternateAddress = array();
987   }
990   /* Return plugin informations for acl handling  */
991   static function plInfo()
992   {
993     return (array(
994           "plShortName"   => _("Mail"),
995           "plDescription" => _("Group mail"),
996           "plSelfModify"  => FALSE,
997           "plDepends"     => array(),
998           "plPriority"    => 10,
999           "plSection"     => array("administration"),
1000           "plCategory"    => array("groups"), 
1001           "plProvidedAcls"=> array(
1002             "mail"                      => _("Mail address"),
1003             "gosaMailQuota"             => _("Quota size"),
1004             "gosaMailServer"            => _("Mail server"),
1005             "kolabFolderType"           => _("Folder type")." ("._("Kolab").")",
1006             "gosaMailAlternateAddress"  => _("Alternate addresses"),
1007             "gosaMailForwardingAddress" => _("Forwarding addresses"),
1008             "gosaMailDeliveryModeI"     => _("Only local"),
1009             "acl"                       => _("Permissions"))
1010           ));
1011   }
1013   
1014   /* Remove given ACL for given member (uid,mail) ..
1015    */
1016   function removeUserAcl($index )
1017   {
1018     if(isset($this->imapacl[$index])){
1019       unset($this->imapacl[$index]);
1020     }
1021   }
1023   function multiple_execute()
1024   {
1025     return($this->execute());
1026   }
1029   function init_multiple_support($attrs,$all)
1030   {
1031     plugin::init_multiple_support($attrs,$all);
1033     $this->gosaMailForwardingAddress = array();
1034     if(isset($attrs['gosaMailForwardingAddress'])){
1035       for($i = 0 ; $i < $attrs['gosaMailForwardingAddress']['count'] ; $i++){
1036         $this->gosaMailForwardingAddress[] = $attrs['gosaMailForwardingAddress'][$i];
1037       }
1038     }
1040     $this->gosaMailForwardingAddress_Some = array();
1041     if(isset($all['gosaMailForwardingAddress'])){
1042       for($i = 0 ; $i < $all['gosaMailForwardingAddress']['count'] ; $i++){
1043         if(!in_array($all['gosaMailForwardingAddress'][$i],$this->gosaMailForwardingAddress)){
1044           $this->gosaMailForwardingAddress_Some[] = $all['gosaMailForwardingAddress'][$i];
1045         }
1046       }
1047     }
1048   }
1050   function multiple_save_object()
1051   {
1052     if(isset($_POST['multiple_mail_group_posted'])){
1053       plugin::multiple_save_object();
1054       
1055       foreach(array("kolabFolderType") as $attr){
1056         if(isset($_POST['use_'.$attr])){
1057           $this->multi_boxes[] = $attr;
1058         }
1059       }
1061       /* Add special kolab attributes */
1062       if(preg_match("/olab/i",$this->config->get_cfg_value("mailmethod"))){
1063         if(isset($_POST['kolabFolderTypeType']) && $this->acl_is_writeable("kolabFolderType")){
1064           $this->kolabFolderTypeType = get_post("kolabFolderTypeType");
1065           $this->kolabFolderTypeSubType = get_post("kolabFolderTypeSubType");
1066         }
1067       }
1069       /* Collect data and re-assign it to the imapacl array */
1070       if ($this->acl_is_writeable("acl")){
1071         $this->imapacl= array();
1072         $this->imapacl['%members%']= $_POST['member_permissions'];
1073         $this->imapacl['anyone']= $_POST['default_permissions'];
1074         foreach ($this->indexed_user as $nr => $user){
1075           if (!isset($_POST["user_$nr"])){
1076             continue;
1077           }
1078           if ($_POST["user_$nr"] != $user ||
1079               $_POST["perm_$nr"] != $this->indexed_acl[$nr]){
1080             $this->is_modified= TRUE;
1081           }
1082           $this->imapacl[$_POST["user_$nr"]]= $_POST["perm_$nr"];
1083         }
1084       }
1085     }
1086   }
1087   
1088   
1089   /* Return selected values for multiple edit */
1090   function get_multi_edit_values()
1091   {
1092     $ret = plugin::get_multi_edit_values();
1093     $ret['Forward_some'] = $this->gosaMailForwardingAddress_Some;    
1094     $ret['Forward_all'] = $this->gosaMailForwardingAddress;    
1095     if(in_array('kolabFolderType',$this->multi_boxes)){
1096       $ret['kolabFolderTypeType'] = $this->kolabFolderTypeType;
1097       $ret['kolabFolderTypeSubType'] = $this->kolabFolderTypeSubType;
1098     }
1099     if(in_array("acl",$this->multi_boxes)){
1100       $ret['imapacl'] = $this->imapacl;
1101     }
1102     return($ret);
1103   }
1105   function set_multi_edit_values($attrs)
1106   {
1107     $forward = array();
1108     foreach($attrs['Forward_some'] as $addr){
1109       if(in_array($addr,$this->gosaMailForwardingAddress)){
1110         $forward[] = $addr;
1111       }
1112     }
1113     foreach($attrs['Forward_all'] as $addr){
1114       $forward[] = $addr;
1115     }
1116     plugin::set_multi_edit_values($attrs);
1117     $this->gosaMailForwardingAddress = $forward;
1118   }
1121   /*! \brief  Add given mail address to the list of forwarders.
1122    */
1123   function addForwarder($address)
1124   {
1125     if(empty($address)) return;
1126     $this->gosaMailForwardingAddress[]= $address;
1127     $this->gosaMailForwardingAddress= array_unique($this->gosaMailForwardingAddress);
1129     /* Update multiple edit values too */
1130     if($this->multiple_support_active){
1131       $this->gosaMailForwardingAddress_Some= 
1132         array_remove_entries (array($address),$this->gosaMailForwardingAddress_Some);
1133     }
1135     sort ($this->gosaMailForwardingAddress);
1136     reset ($this->gosaMailForwardingAddress);
1137     $this->is_modified= TRUE;
1138   }
1141   /*! \brief  Removes the given mail address from the forwarders 
1142    */
1143   function delForwarder($addresses)
1144   {
1145     if(empty($addresses)) return;
1146     $this->gosaMailForwardingAddress= array_remove_entries ($addresses,
1147         $this->gosaMailForwardingAddress);
1149     /* Update multiple edit values too */
1150     if($this->multiple_support_active){
1151       $this->gosaMailForwardingAddress_Some = array_remove_entries ($addresses,
1152           $this->gosaMailForwardingAddress_Some);
1153     }
1154     $this->is_modified= TRUE;
1155   }
1158   /*! \brief  Add given mail address to the list of alternate adresses ,
1159     .          check if this mal address is used, skip adding in this case
1160    */
1161   function addAlternate($address)
1162   {
1163     if(empty($address)) continue;
1164     $ldap= $this->config->get_ldap_link();
1166     $address= strtolower($address);
1168     /* Is this address already assigned in LDAP? */
1169     $ldap->cd ($this->config->current['BASE']);
1170     $ldap->search ("(&(objectClass=gosaMailAccount)(|(mail=$address)".
1171         "(gosaMailAlternateAddress=$address)))", array("cn", "uid"));
1173     if ($ldap->count() > 0){
1174       $attrs= $ldap->fetch ();
1175       if (!isset($attrs["uid"])) {
1176         return ("!".$attrs["cn"][0]);
1177       }
1178       return ($attrs["uid"][0]);
1179     }
1181     /* Add to list of alternates */
1182     if (!in_array($address, $this->gosaMailAlternateAddress)){
1183       $this->gosaMailAlternateAddress[]= $address;
1184     }
1186     sort ($this->gosaMailAlternateAddress);
1187     reset ($this->gosaMailAlternateAddress);
1188     $this->is_modified= TRUE;
1190     return ("");
1191   }
1194   /*! \brief  Removes the given mail address from the alternate addresses  
1195    */
1196   function delAlternate($addresses)
1197   {
1198     if(!count($addresses)) return;
1199     $this->gosaMailAlternateAddress= array_remove_entries ($addresses,
1200         $this->gosaMailAlternateAddress);
1201     $this->is_modified= TRUE;
1202   }
1205   function postable_acls()
1206   {
1207     $ret = array();
1208     foreach($this->folder_acls as $name => $acl){
1209       $ret[$name] = array("name" => $name,"acl" => $acl,"post_name" => base64_encode($name));
1210     }
1211     return($ret);
1212   }
1215   function get_effective_member_acls()
1216   {
1217     $tmp = array();
1218     $member = $this->get_member();
1219     foreach($member['mail'] as $uid => $mail){
1221       /* Do not save overridden acls */
1222       if(isset($this->folder_acls[$mail])){
1223         continue;
1224       }
1226       
1227       $tmp[$mail]  = $this->folder_acls['__member__'];
1228     }
1229     return($tmp);
1230   }
1233   function allow_remove()
1234   {
1235     $resason = "";
1236     if(!$this->mailMethod->allow_remove($reason)){
1237       return($reason);
1238     }
1239     return("");
1240   }
1243   // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1244 ?>