\version 2.00 \date 24.07.2003 This class provides the functionality to read and write all attributes relevant for gosaMailAccounts from/to the LDAP. It does syntax checking and displays the formulars required. */ /* Load sieve support */ @require_once ("class_sieve.inc"); /* Load mail methods */ global $BASE_DIR; get_dir_list("$BASE_DIR/include"); class mailAccount extends plugin { /* Definitions */ var $plHeadline= "Mail"; var $plDescription= "This does something"; var $method= "mailMethod"; /* CLI vars */ var $cli_summary= "Manage users mail account"; var $cli_description= "Some longer text\nfor help"; var $cli_parameters= array("eins" => "Eins ist toll", "zwei" => "Zwei ist noch besser"); /* plugin specific values */ var $mail= ""; var $uid= ""; var $gosaMailAlternateAddress= array(); var $gosaMailForwardingAddress= array(); var $gosaMailDeliveryMode= "[L ]"; var $gosaMailServer= ""; var $gosaMailQuota= ""; var $gosaMailMaxSize= ""; var $gosaVacationMessage= ""; var $gosaSpamSortLevel= ""; var $gosaSpamMailbox= ""; var $quotaUsage= 0; var $forward_dialog= FALSE; var $folder_prefix= ""; var $mailboxList= array(); var $default_permissions= "none"; var $member_permissions= "post"; var $members= array(); var $admins= array(); var $vacations= array(); var $perms= array( "lrs" => "read", "lrsp" => "post", "lrsip" => "append", "lrswipcd" => "write", "lrswipcda" => "all" ); /* attribute list for save action */ var $attributes= array("mail", "gosaMailServer", "gosaMailQuota", "gosaMailMaxSize", "gosaMailDeliveryMode", "gosaSpamSortLevel", "gosaSpamMailbox", "gosaVacationMessage", "uid"); var $objectclasses= array("gosaMailAccount"); /* constructor, if 'dn' is set, the node loads the given 'dn' from LDAP */ function mailAccount ($config, $dn= NULL) { /* Configuration is fine, allways */ $this->config= $config; /* Load bases attributes */ plugin::plugin($config, $dn); /* Set mailMethod to the one defined in gosa.conf */ if (isset($this->config->current['MAILMETHOD'])){ $method= $this->config->current['MAILMETHOD']; if (class_exists("mailMethod$method")){ $this->method= "mailMethod$method"; } else { print_red(sprintf(_("There is no mail method '%s' specified in your gosa.conf available."), $method)); } } /* Preset folder prefix. Will change it later to respect altnamespace. */ if (isset($this->config->current['CYRUSUNIXSTYLE']) && $this->config->current['CYRUSUNIXSTYLE'] == "true"){ $this->folder_prefix= "user/"; } else { $this->folder_prefix= "user."; } if ($dn != NULL){ /* Load attributes containing arrays */ foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){ if (isset($this->attrs["$val"]["count"])){ for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){ array_push($this->$val, $this->attrs["$val"][$i]); } } } /* Only do IMAP actions if gosaMailServer attribute is set */ if (isset ($this->attrs["gosaMailServer"][0])){ $method= new $this->method($this->config); $id= $method->uattrib; if ($method->connect($this->attrs["gosaMailServer"][0])){ $quota= $method->getQuota($this->folder_prefix.$this->$id); $this->quotaUsage= $quota['quotaUsage']; $this->gosaMailQuota= $quota['gosaMailQuota']; $this->mailboxList= $method->getMailboxList( $this->folder_prefix.$this->$id, $this->$id); $method->disconnect(); } /* Adapt attributes if needed */ $method->fixAttributesOnLoad($this); } } /* Fill vacation array */ $this->vacation= array(); if (isset($this->config->current['VACATIONDIR'])){ $dir= $this->config->current['VACATIONDIR']; if (is_dir($dir) && is_readable($dir)){ /* Look for files and build the vacation array */ $dh= opendir($dir); while ($file = readdir($dh)){ $description= $this->parse_vacation("$dir/$file"); if ($description != ""){ $this->vacation["$dir/$file"]= $description; } } closedir($dh); } } /* Get global filter config */ if (!is_global("mailfilter")){ $ui= get_userinfo(); $base= get_base_from_people($ui->dn); $mailfilter= array( "depselect" => $base, "muser" => "", "regex" => "*"); register_global("mailfilter", $mailfilter); } /* Save initial account state */ $this->initially_was_account= $this->is_account; } function parse_vacation($file) { $desc= ""; if (is_file($file)){ $fh = fopen($file, "r"); $line= fgets($fh, 256); if (!preg_match('/^DESC:/', $line)){ print_red (_("No DESC tag in vacation file:")." $file"); return $desc; } fclose ($fh); $desc= trim(preg_replace('/^DESC:\s*/', '', $line)); } return $desc; } function execute() { /* Load templating engine */ $smarty= get_smarty(); $display= ""; /* Do we need to flip is_account state? */ if (isset($_POST['modify_state'])){ $this->is_account= !$this->is_account; } /* Do we represent a valid account? */ if (!$this->is_account && $this->parent == NULL){ $display= "\"\" ". _("This account has no mail extensions.").""; $display.= back_to_main(); return ($display); } /* Show tab dialog headers */ if ($this->parent != NULL){ if ($this->is_account){ $display= $this->show_header(_("Remove mail account"), _("This account has mail features enabled. You can disable them by clicking below.")); } else { $display= $this->show_header(_("Create mail account"), _("This account has mail features disabled. You can enable them by clicking below.")); return ($display); } } /* Trigger forward add dialog? */ if (isset($_POST['add_local_forwarder'])){ $this->forward_dialog= TRUE; $this->dialog= TRUE; } /* Cancel forward add dialog? */ if (isset($_POST['add_locals_cancel'])){ $this->forward_dialog= FALSE; $this->dialog= FALSE; } /* Finished adding of locals? */ if (isset($_POST['add_locals_finish'])){ if (count ($_POST['local_list']) && chkacl ($this->acl, "gosaMailForwardingAddress") == ""){ /* Walk through list of forwarders, ignore own addresses */ foreach ($_POST['local_list'] as $val){ if (!in_array ($val, $this->gosaMailAlternateAddress) && $val != $this->mail){ $this->addForwarder($val); $this->is_modified= TRUE; } } } $this->forward_dialog= FALSE; $this->dialog= FALSE; } /* Add forward email addresses */ if (isset($_POST['add_forwarder'])){ if ($_POST['forward_address'] != ""){ /* Valid email address specified? */ $address= $_POST['forward_address']; $valid= FALSE; if (!is_email($address)){ if (!is_email($address, TRUE)){ if ($this->is_template){ $valid= TRUE; } else { print_red (_("You're trying to add an invalid email address to the list of forwarders.")); } } } elseif ($address == $this->mail || in_array($address, $this->gosaMailAlternateAddress)) { print_red (_("Adding your one of your own addresses to the forwarders makes no sense.")); } else { $valid= TRUE; } if ($valid){ /* Add it */ if (chkacl ($this->acl, "gosaMailForwardingAddress") == ""){ $this->addForwarder ($address); $this->is_modified= TRUE; } } } } /* Delete forward email addresses */ if (isset($_POST['delete_forwarder'])){ if (count($_POST['forwarder_list']) && chkacl ($this->acl, "gosaMailForwardingAddress") == ""){ $this->delForwarder ($_POST['forwarder_list']); } } /* Add alternate email addresses */ if (isset($_POST['add_alternate'])){ if ($_POST['alternate_address'] != "" && chkacl ($this->acl, "gosaMailAlternateAddress") == ""){ $valid= FALSE; if (!is_email($_POST['alternate_address'])){ if ($this->is_template){ if (!(is_email($_POST['alternate_address'], TRUE))){ print_red (_("You're trying to add an invalid email address to the list of alternate addresses.")); } else { $valid= TRUE; } } else { print_red (_("You're trying to add an invalid email address to the list of alternate addresses.")); } } else { $valid= TRUE; } if ($valid && ($user= $this->addAlternate ($_POST['alternate_address'])) != ""){ $ui= get_userinfo(); if ($user != $ui->username){ print_red (_("The address you're trying to add is already used by user")." '$user'."); } } } } /* Delete alternate email addresses */ if (isset($_POST['delete_alternate']) && isset ($_POST['alternates_list'])){ if (count($_POST['alternates_list']) && chkacl ($this->acl, "gosaMailAlternateAddress") == ""){ $this->delAlternate ($_POST['alternates_list']); } } /* Import vacation message? */ if (isset($_POST["import_vacation"]) && isset($this->vacation[$_POST["vacation_template"]])){ $contents= ""; $lines= file($_POST["vacation_template"]); foreach ($lines as $line){ if (!preg_match('/^DESC:/', $line)){ $contents.= $line; } } /* Replace attributes */ $attrs= $this->parent->by_object['user']->attributes; foreach ($attrs as $val){ $contents= preg_replace("/%$val/", $this->parent->by_object['user']->$val, $contents); } /* Save message */ $this->gosaVacationMessage= htmlspecialchars($contents); } /* Show forward add dialog */ if ($this->forward_dialog){ $ldap= $this->config->get_ldap_link(); /* Save data */ $mailfilter= get_global("mailfilter"); foreach( array("depselect", "muser", "regex") as $type){ if (isset($_POST[$type])){ $mailfilter[$type]= $_POST[$type]; } } if (isset($_GET['search'])){ $s= mb_substr($_GET['search'], 0, 1, "UTF8")."*"; if ($s == "**"){ $s= "*"; } $mailfilter['regex']= $s; } register_global("mailfilter", $mailfilter); /* Get actual list */ $mailusers= array (); if ($mailfilter['regex'] != '*' && $mailfilter['regex'] != ""){ $regex= $mailfilter['regex']; $filter= "(|(mail=$regex)(gosaMailAlternateAddress=$regex))"; } else { $filter= ""; } if ($mailfilter['muser'] != ""){ $user= $mailfilter['muser']; $filter= "$filter(|(uid=$user)(cn=$user)(givenName=$user)(sn=$user))"; } /* Add already present people to the filter */ $exclude= ""; foreach ($this->gosaMailForwardingAddress as $mail){ $exclude.= "(mail=$mail)"; } if ($exclude != ""){ $filter.= "(!(|$exclude))"; } $acl= array($this->config->current['BASE'] => ":all"); $res= get_list($acl, "(&(objectClass=gosaMailAccount)$filter)", TRUE, $mailfilter['depselect'], array("sn", "mail", "givenName"), TRUE); $ldap->cd($mailfilter['depselect']); $ldap->search ("(&(objectClass=gosaMailAccount)$filter)", array("sn", "mail", "givenName")); error_reporting (0); while ($attrs= $ldap->fetch()){ if(preg_match('/%/', $attrs['mail'][0])){ continue; } $name= $this->make_name($attrs); $mailusers[$attrs['mail'][0]]= $name."<". $attrs['mail'][0].">"; } error_reporting (E_ALL); natcasesort ($mailusers); reset ($mailusers); /* Show dialog */ $smarty->assign("search_image", get_template_path('images/search.png')); $smarty->assign("tree_image", get_template_path('images/tree.png')); $smarty->assign("infoimage", get_template_path('images/info.png')); $smarty->assign("launchimage", get_template_path('images/small_filter.png')); $smarty->assign("mailusers", $mailusers); if (isset($_POST['depselect'])){ $smarty->assign("depselect", $_POST['depselect']); } $smarty->assign("deplist", $this->config->idepartments); $smarty->assign("apply", apply_filter()); $smarty->assign("alphabet", generate_alphabet()); $smarty->assign("hint", print_sizelimit_warning()); foreach( array("depselect", "muser", "regex") as $type){ $smarty->assign("$type", $mailfilter[$type]); } $smarty->assign("hint", print_sizelimit_warning()); $display.= $smarty->fetch (get_template_path('mail_locals.tpl', TRUE, dirname(__FILE__))); return ($display); } /* Show main page */ $mailserver= array(); foreach ($this->config->data['SERVERS']['IMAP'] as $key => $val){ $mailserver[]= $key; } $smarty->assign("mailServers", $mailserver); foreach(array("gosaMailServer", "gosaMailQuota", "perms", "mail", "gosaMailAlternateAddress", "gosaMailForwardingAddress", "gosaVacationMessage", "gosaMailDeliveryMode", "gosaMailMaxSize", "gosaSpamSortLevel", "gosaSpamMailbox") as $val){ $smarty->assign("$val", $this->$val); $smarty->assign("$val"."ACL", chkacl($this->acl, "$val")); } if (is_numeric($this->gosaMailQuota) && $this->gosaMailQuota != 0){ $smarty->assign("quotausage", progressbar(($this->quotaUsage * 100)/ $this->gosaMailQuota,100,15,true)); $smarty->assign("quotadefined", "true"); } else { $smarty->assign("quotadefined", "false"); } /* Disable mail field if needed */ $method= new $this->method($this->config); if ($method->uattrib == "mail" && $this->initially_was_account){ $smarty->assign("mailACL", "disabled"); } /* Fill checkboxes */ if (!preg_match("/L/", $this->gosaMailDeliveryMode)) { $smarty->assign("drop_own_mails", "checked"); } else { $smarty->assign("drop_own_mails", ""); } if (preg_match("/V/", $this->gosaMailDeliveryMode)) { $smarty->assign("use_vacation", "checked"); } else { $smarty->assign("use_vacation", ""); } if (preg_match("/S/", $this->gosaMailDeliveryMode)) { $smarty->assign("use_spam_filter", "checked"); } else { $smarty->assign("use_spam_filter", ""); } if (preg_match("/R/", $this->gosaMailDeliveryMode)) { $smarty->assign("use_mailsize_limit", "checked"); } else { $smarty->assign("use_mailsize_limit", ""); } if (preg_match("/I/", $this->gosaMailDeliveryMode)) { $smarty->assign("only_local", "checked"); } else { $smarty->assign("only_local", ""); } if (preg_match("/C/", $this->gosaMailDeliveryMode)) { $smarty->assign("own_script", "checked"); } else { $smarty->assign("own_script", ""); } /* Have vacation templates? */ $smarty->assign("template", ""); if (count($this->vacation)){ $smarty->assign("show_templates", "true"); $smarty->assign("vacationtemplates", $this->vacation); if (isset($_POST['vacation_template'])){ $smarty->assign("template", $_POST['vacation_template']); } } else { $smarty->assign("show_templates", "false"); } /* Fill spam selector */ $spamlevel= array(); for ($i= 0; $i<21; $i++){ $spamlevel[]= $i; } $smarty->assign("spamlevel", $spamlevel); $smarty->assign("spambox", $this->mailboxList); $smarty->assign("custom_sieveACL", chkacl($this->acl, "custom_sieve")); $smarty->assign("only_localACL", chkacl($this->acl, "only_local")); $display.= $smarty->fetch (get_template_path('generic.tpl', TRUE, dirname(__FILE__))); return ($display); } /* remove object from parent */ function remove_from_parent() { /* Cancel if there's nothing to do here */ if (!$this->initially_was_account){ return; } /* include global link_info */ $ldap= $this->config->get_ldap_link(); /* Remove and write to LDAP */ plugin::remove_from_parent(); /* Zero arrays */ $this->attrs['gosaMailAlternateAddress']= array(); $this->attrs['gosaMailForwardingAddress']= array(); /* Adapt attributes if needed */ $method= new $this->method($this->config); $method->fixAttributesOnRemove($this); /* Mailmethod wants us to remove the entry from LDAP. Keep uid! */ unset ($this->attrs['uid']); @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__, $this->attributes, "Save"); $ldap->cd($this->dn); $ldap->modify($this->attrs); show_ldap_error($ldap->get_error()); /* Connect to IMAP server for account deletion */ if ($this->gosaMailServer != ""){ $method= new $this->method($this->config); $id= $method->uattrib; if ($method->connect($this->gosaMailServer)){ /* Remove account from IMAP server */ $method->deleteMailbox($this->folder_prefix.$this->$id); $method->disconnect(); } } /* Optionally execute a command after we're done */ $this->handle_post_events("remove"); } /* Save data to object */ function save_object() { if (isset($_POST['mailTab'])){ /* Save ldap attributes */ plugin::save_object(); /* Assemble mail delivery mode The mode field in ldap consists of values between braces, this must be called when 'mail' is set, because checkboxes may not be set when we're in some other dialog. Example for gosaMailDeliveryMode [LR ] L: Local delivery R: Reject when exceeding mailsize limit S: Use spam filter V: Use vacation message C: Use custm sieve script I: Only insider delivery */ $tmp= ""; if (!isset($_POST["drop_own_mails"])){ $tmp.= "L"; } if (isset($_POST["use_mailsize_limit"])){ $tmp.= "R"; } if (isset($_POST["use_spam_filter"])){ $tmp.= "S"; } if (isset($_POST["use_vacation"])){ $tmp.= "V"; } if (isset($_POST["own_script"])){ $tmp.= "C"; } if (isset($_POST["only_local"])){ $tmp.= "I"; } $tmp= "[$tmp]"; if (chkacl ($this->acl, "gosaMailDeliveryMode") == ""){ if ($this->gosaMailDeliveryMode != $tmp){ $this->is_modified= TRUE; } $this->gosaMailDeliveryMode= $tmp; } } } /* Save data to LDAP, depending on is_account we save or delete */ function save() { $ldap= $this->config->get_ldap_link(); /* Call parents save to prepare $this->attrs */ plugin::save(); /* Save arrays */ $this->attrs['gosaMailAlternateAddress']= $this->gosaMailAlternateAddress; $this->attrs['gosaMailForwardingAddress']= $this->gosaMailForwardingAddress; /* Adapt attributes if needed */ $method= new $this->method($this->config); $id= $method->uattrib; $method->fixAttributesOnStore($this); /* Save data to LDAP */ $ldap->cd($this->dn); $ldap->modify($this->attrs); show_ldap_error($ldap->get_error()); /* Only do IMAP actions if we are not a template */ if (!$this->is_template){ if ($method->connect($this->gosaMailServer)){ $method->updateMailbox($this->folder_prefix.$this->$id); $method->setQuota($this->folder_prefix.$this->$id, $this->gosaMailQuota); $method->disconnect(); /* Write sieve information only if not in C mode */ if (!is_integer(strpos($this->gosaMailDeliveryMode, "C"))){ $method->configureFilter($this->$id, $this->gosaMailDeliveryMode, $this->mail, $this->gosaMailAlternateAddress, $this->gosaMailMaxSize, $this->gosaSpamMailbox, $this->gosaSpamSortLevel, $this->gosaVacationMessage); } } } /* Optionally execute a command after we're done */ if ($this->initially_was_account == $this->is_account){ if ($this->is_modified){ $this->handle_post_events("mofify"); } } else { $this->handle_post_events("add"); } } /* Check formular input */ function check() { $ldap= $this->config->get_ldap_link(); $message= array(); /* must: mail */ if ($this->mail == ""){ $message[]= _("The required field 'Primary address' is not set."); } if ($this->is_template){ if (!is_email($this->mail, TRUE)){ $message[]= _("Please enter a valid email address in 'Primary address' field."); } } else { if (!is_email($this->mail)){ $message[]= _("Please enter a valid email address in 'Primary address' field."); } } $ldap->cd($this->config->current['BASE']); $ldap->search ("(&(objectClass=gosaMailAccount)(!(objectClass=gosaUserTemplate))(|(mail=".$this->mail.")(gosaMailAlternateAddress=". $this->mail."))(!(uid=".$this->uid."))(!(cn=".$this->uid.")))", array("uid")); if ($ldap->count() != 0){ $message[]= _("The primary address you've entered is already in use."); } /* Check quota */ if ($this->gosaMailQuota != '' && chkacl ($this->acl, "gosaMailQuota") == ""){ if (!is_numeric($this->gosaMailQuota)) { $message[]= _("Value in 'Quota size' is not valid."); } else { $this->gosaMailQuota= (int) $this->gosaMailQuota; } } /* Check rejectsize for integer */ if ($this->gosaMailMaxSize != '' && chkacl ($this->acl, "gosaMailQuota") == ""){ if (!is_numeric($this->gosaMailMaxSize)){ $message[]= _("Please specify a vaild mail size for mails to be rejected."); } else { $this->gosaMailMaxSize= (int) $this->gosaMailMaxSize; } } /* Need gosaMailMaxSize if use_mailsize_limit is checked */ if (is_integer(strpos($this->gosaMailDeliveryMode, "R")) && $this->gosaMailMaxSize == ""){ $message[]= _("You need to set the maximum mail size in order to reject anything."); } return ($message); } /* Adapt from template, using 'dn' */ function adapt_from_template($dn) { plugin::adapt_from_template($dn); foreach (array("gosaMailAlternateAddress", "gosaMailForwardingAddress") as $val){ $this->$val= array(); if (isset($this->attrs["$val"]["count"])){ for ($i= 0; $i<$this->attrs["$val"]["count"]; $i++){ $value= $this->attrs["$val"][$i]; foreach (array("sn", "givenName", "uid") as $repl){ if (preg_match("/%$repl/i", $value)){ $value= preg_replace ("/%$repl/i", $this->parent->$repl, $value); } } array_push($this->$val, strtolower(rewrite($value))); } } } $this->mail= strtolower(rewrite($this->mail)); } /* Add entry to forwarder list */ function addForwarder($address) { $this->gosaMailForwardingAddress[]= $address; $this->gosaMailForwardingAddress= array_unique ($this->gosaMailForwardingAddress); sort ($this->gosaMailForwardingAddress); reset ($this->gosaMailForwardingAddress); $this->is_modified= TRUE; } /* Remove list of addresses from forwarder list */ function delForwarder($addresses) { $this->gosaMailForwardingAddress= array_remove_entries ($addresses, $this->gosaMailForwardingAddress); $this->is_modified= TRUE; } function addAlternate($address) { $ldap= $this->config->get_ldap_link(); $address= strtolower($address); /* Is this address already assigned in LDAP? */ $ldap->cd ($this->config->current['BASE']); $ldap->search ("(&(objectClass=gosaMailAccount)(|(mail=$address)". "(gosaMailAlternateAddress=$address)))", array("uid")); if ($ldap->count() > 0){ $attrs= $ldap->fetch (); return ($attrs["uid"][0]); } /* Add to list of alternates */ if (!in_array($address, $this->gosaMailAlternateAddress)){ $this->gosaMailAlternateAddress[]= $address; $this->is_modified= TRUE; } sort ($this->gosaMailAlternateAddress); reset ($this->gosaMailAlternateAddress); return (""); } function delAlternate($addresses) { $this->gosaMailAlternateAddress= array_remove_entries ($addresses, $this->gosaMailAlternateAddress); $this->is_modified= TRUE; } function make_name($attrs) { $name= ""; if (isset($attrs['sn'][0])){ $name= $attrs['sn'][0]; } if (isset($attrs['givenName'][0])){ if ($name != ""){ $name.= ", ".$attrs['givenName'][0]; } else { $name.= $attrs['givenName'][0]; } } if ($name != ""){ $name.= " "; } return ($name); } } // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: ?>