X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=include%2Ffunctions.inc;h=d628de47a0033dcd92f7e7f1376d9a0c7bf9f2f7;hb=6c6148c73fa05be5904cb13385ed133bc615fdca;hp=36c0ddf9e43357e690970849b89d84c1e0453e18;hpb=9a00ca1089a96a9893e2f46d8da30f425327ecdb;p=gosa.git diff --git a/include/functions.inc b/include/functions.inc index 36c0ddf9e..d628de47a 100644 --- a/include/functions.inc +++ b/include/functions.inc @@ -20,6 +20,7 @@ /* Configuration file location */ define ("CONFIG_DIR", "/etc/gosa"); +define ("CONFIG_FILE", "gosa.conf-trunk"); define ("CONFIG_TEMPLATE_DIR", "../contrib/"); define ("HELP_BASEDIR", "/var/www/doc/"); @@ -29,22 +30,33 @@ define("GL_SUBSEARCH", 1); define("GL_SIZELIMIT", 2); define("GL_CONVERT" , 4); +/* Heimdal stuff */ +define('UNIVERSAL',0x00); +define('INTEGER',0x02); +define('OCTET_STRING',0x04); +define('OBJECT_IDENTIFIER ',0x06); +define('SEQUENCE',0x10); +define('SEQUENCE_OF',0x10); +define('SET',0x11); +define('SET_OF',0x11); +define('DEBUG',false); +define('HDB_KU_MKEY',0x484442); +define('TWO_BIT_SHIFTS',0x7efc); +define('DES_CBC_CRC',1); +define('DES_CBC_MD4',2); +define('DES_CBC_MD5',3); +define('DES3_CBC_MD5',5); +define('DES3_CBC_SHA1',16); + /* Define globals for revision comparing */ $svn_path = '$HeadURL$'; $svn_revision = '$Revision$'; /* Include required files */ -require_once ("class_ldap.inc"); -require_once ("class_config.inc"); -require_once ("class_userinfo.inc"); -require_once ("class_plugin.inc"); -require_once ("class_pluglist.inc"); -require_once ("class_tabs.inc"); -require_once ("class_mail-methods.inc"); -require_once("class_password-methods.inc"); +require_once("class_location.inc"); require_once ("functions_debug.inc"); require_once ("functions_dns.inc"); -require_once ("class_MultiSelectWindow.inc"); +require_once ("accept-to-gettext.inc"); /* Define constants for debugging */ define ("DEBUG_TRACE", 1); @@ -54,6 +66,7 @@ define ("DEBUG_SHELL", 8); define ("DEBUG_POST", 16); define ("DEBUG_SESSION",32); define ("DEBUG_CONFIG", 64); +define ("DEBUG_ACL", 128); /* Rewrite german 'umlauts' and spanish 'accents' to get better results */ @@ -78,45 +91,16 @@ $REWRITE= array( "ä" => "ae", "Ñ" => "Ny" ); -/* Function to include all class_ files starting at a - given directory base */ -function get_dir_list($folder= ".") -{ - $currdir=getcwd(); - if ($folder){ - chdir("$folder"); - } - - $dh = opendir("."); - while(false !== ($file = readdir($dh))){ - - // Smarty is included by include/php_setup.inc require("smarty/Smarty.class.php"); - // Skip all files and dirs in "./.svn/" we don't need any information from them - // Skip all Template, so they won't be checked twice in the following preg_matches - // Skip . / .. - - // Result : from 1023 ms to 490 ms i think thats great... - if(preg_match("/.*\.svn.*/i",$file)||preg_match("/.*smarty.*/i",$file)||preg_match("/.*\.tpl.*/",$file)||($file==".")||($file=="..")) - continue; - - - /* Recurse through all "common" directories */ - if(is_dir($file) &&$file!="CVS"){ - get_dir_list($file); - continue; - } - - /* Include existing class_ files */ - if (!is_dir($file) && preg_match("/^class_.*\.inc$/", $file)) { - require_once($file); +/* Class autoloader */ +function __autoload($class_name) { + global $class_mapping, $BASE_DIR; + if (isset($class_mapping[$class_name])){ + require_once($BASE_DIR."/".$class_mapping[$class_name]); + } else { + echo _("Fatal: cannot load class \"$class_name\" - execution aborted"); } - } - - closedir($dh); - chdir($currdir); } - /* Create seed with microseconds */ function make_seed() { list($usec, $sec) = explode(' ', microtime()); @@ -127,7 +111,7 @@ function make_seed() { /* Debug level action */ function DEBUG($level, $line, $function, $file, $data, $info="") { - if ($_SESSION['DEBUGLEVEL'] & $level){ + if (get_global('DEBUGLEVEL') & $level){ $output= "DEBUG[$level] "; if ($function != ""){ $output.= "($file:$function():$line) - $info: "; @@ -145,56 +129,47 @@ function DEBUG($level, $line, $function, $file, $data, $info="") } -/* Simple function to get browser language and convert it to - xx_XY needed by locales. Ignores sublanguages and weights. */ function get_browser_language() { - global $BASE_DIR; - /* Try to use users primary language */ + global $config; $ui= get_userinfo(); - if ($ui != NULL){ + if (isset($ui) && $ui !== NULL){ if ($ui->language != ""){ - return ($ui->language); + return ($ui->language.".UTF-8"); } } - /* Get list of languages */ - if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){ - $lang= preg_replace("/\s+/", "", $_SERVER['HTTP_ACCEPT_LANGUAGE']); - $languages= split (',', $lang); - $languages[]= "C"; - } else { - $languages= array("C"); + /* Check for global language settings in gosa.conf */ + if(isset($config->data['MAIN']['LANG']) && !empty($config->data['MAIN']['LANG'])) { + $lang = $config->data['MAIN']['LANG']; + if(!preg_match("/utf/i",$lang)){ + $lang .= ".UTF-8"; + } + return($lang); } + + /* Load supported languages */ + $gosa_languages= get_languages(); - /* Walk through languages and get first supported */ - foreach ($languages as $val){ - - /* Strip off weight */ - $lang= preg_replace("/;q=.*$/i", "", $val); - - /* Simplify sub language handling */ - $lang= preg_replace("/-.*$/", "", $lang); - - /* Cancel loop if available in GOsa, or the last - entry has been reached */ - if (is_dir("$BASE_DIR/locale/$lang")){ - break; - } + /* Move supported languages to flat list */ + $langs= array(); + foreach($gosa_languages as $lang => $dummy){ + $langs[]= $lang.'.UTF-8'; } - return (strtolower($lang)."_".strtoupper($lang)); + /* Return gettext based string */ + return (al2gt($langs, 'text/html')); } /* Rewrite ui object to another dn */ function change_ui_dn($dn, $newdn) { - $ui= $_SESSION['ui']; + $ui= get_global('ui'); if ($ui->dn == $dn){ $ui->dn= $newdn; - $_SESSION['ui']= $ui; + register_global('ui',$ui); } } @@ -218,7 +193,7 @@ function get_template_path($filename= '', $plugin= FALSE, $path= "") /* Return plugin dir or root directory? */ if ($plugin){ if ($path == ""){ - $nf= preg_replace("!^".$BASE_DIR."/!", "", $_SESSION['plugin_dir']); + $nf= preg_replace("!^".$BASE_DIR."/!", "", get_global('plugin_dir')); } else { $nf= preg_replace("!^".$BASE_DIR."/!", "", $path); } @@ -229,7 +204,7 @@ function get_template_path($filename= '', $plugin= FALSE, $path= "") return ("$BASE_DIR/ihtml/themes/default/$nf/$filename"); } if ($path == ""){ - return ($_SESSION['plugin_dir']."/$filename"); + return (get_global('plugin_dir')."/$filename"); } else { return ($path."/$filename"); } @@ -266,6 +241,17 @@ function array_remove_entries($needles, $haystack) } +function gosa_array_merge($ar1,$ar2) +{ + if(!is_array($ar1) || !is_array($ar2)){ + trigger_error("Specified parameter(s) are not valid arrays."); + }else{ + return(array_values(array_unique(array_merge($ar1,$ar2)))); + } +} + + + function gosa_log ($message) { global $ui; @@ -290,7 +276,8 @@ function ldap_init ($server, $base, $binddn='', $pass='') { global $config; - $ldap = new LDAP ($binddn, $pass, $server, isset($config->current['RECURSIVE']) && $config->current['RECURSIVE'] == "true", + $ldap = new LDAP ($binddn, $pass, $server, + isset($config->current['RECURSIVE']) && $config->current['RECURSIVE'] == "true", isset($config->current['TLS']) && $config->current['TLS'] == "true"); /* Sadly we've no proper return values here. Use the error message instead. */ @@ -315,11 +302,31 @@ function ldap_login_user ($username, $password) print_red(sprintf(_("User login failed. LDAP server said '%s'."), $ldap->get_error())); $smarty= get_smarty(); $smarty->display(get_template_path('headers.tpl')); - echo "".$_SESSION['errors'].""; + echo "".get_global('errors').""; exit(); } $ldap->cd($config->current['BASE']); - $ldap->search("(&(uid=$username)(objectClass=gosaAccount))", array("uid")); + $allowed_attributes = array("uid","mail"); + $verify_attr = array(); + if(isset($config->current['LOGIN_ATTRIBUTE'])){ + $tmp = split(",",$config->current['LOGIN_ATTRIBUTE']); + foreach($tmp as $attr){ + if(in_array($attr,$allowed_attributes)){ + $verify_attr[] = $attr; + } + } + } + if(count($verify_attr) == 0){ + $verify_attr = array("uid"); + } + $tmp= $verify_attr; + $tmp[] = "uid"; + $filter = ""; + foreach($verify_attr as $attr) { + $filter.= "(".$attr."=".$username.")"; + } + $filter = "(&(|".$filter.")(objectClass=gosaAccount))"; + $ldap->search($filter,$tmp); /* get results, only a count of 1 is valid */ switch ($ldap->count()){ @@ -339,13 +346,19 @@ function ldap_login_user ($username, $password) /* LDAP schema is not case sensitive. Perform additional check. */ $attrs= $ldap->fetch(); - if ($attrs['uid'][0] != $username){ - return(NULL); + $success = FALSE; + foreach($verify_attr as $attr){ + if ($attrs[$attr][0] == $username){ + $success = TRUE; + } + } + if(!$success){ + return(FALSE); } /* got user dn, fill acl's */ $ui= new userinfo($config, $ldap->getDN()); - $ui->username= $username; + $ui->username= $attrs['uid'][0]; /* password check, bind as user with supplied password */ $ldap->disconnect(); @@ -367,7 +380,6 @@ function ldap_login_user ($username, $password) function ldap_expired_account($config, $userdn, $username) { - //$this->config= $config; $ldap= $config->get_ldap_link(); $ldap->cat($userdn); $attrs= $ldap->fetch(); @@ -463,6 +475,13 @@ function add_lock ($object, $user) { global $config; + if(is_array($object)){ + foreach($object as $obj){ + add_lock($obj,$user); + } + return; + } + /* Just a sanity check... */ if ($object == "" || $user == ""){ print_red(_("Error while adding a lock. Parameters are not set correctly, please check the source!")); @@ -502,6 +521,13 @@ function del_lock ($object) { global $config; + if(is_array($object)){ + foreach($object as $obj){ + del_lock($obj); + } + return; + } + /* Sanity check */ if ($object == ""){ return; @@ -577,12 +603,45 @@ function get_lock ($object) $attrs = $ldap->fetch(); $user= $attrs['gosaUser'][0]; } - return ($user); } -function get_list($filter, $subtreeACL, $base= "", $attributes= array(), $flags= GL_SUBSEARCH) +function get_multiple_locks($objects) +{ + global $config; + + if(is_array($objects)){ + $filter = "(&(objectClass=gosaLockEntry)(|"; + foreach($objects as $obj){ + $filter.="(gosaObject=".base64_encode($obj).")"; + } + $filter.= "))"; + }else{ + $filter = "(&(objectClass=gosaLockEntry)(gosaObject=".base64_encode($objects)."))"; + } + + /* Get LDAP link, check for presence of the lock entry */ + $user= ""; + $ldap= $config->get_ldap_link(); + $ldap->cd ($config->current['CONFIG']); + $ldap->search($filter, array("gosaUser","gosaObject")); + if (!preg_match("/Success/i", $ldap->error)){ + print_red (_("Can't get locking information in LDAP database. Please check the 'config' entry in gosa.conf!")); + return(""); + } + + $users = array(); + while($attrs = $ldap->fetch()){ + $dn = base64_decode($attrs['gosaObject'][0]); + $user = $attrs['gosaUser'][0]; + $users[] = array("dn"=> $dn,"user"=>$user); + } + return ($users); +} + + +function get_list($filter, $category, $base= "", $attributes= array(), $flags= GL_SUBSEARCH) { global $config, $ui; @@ -596,12 +655,6 @@ function get_list($filter, $subtreeACL, $base= "", $attributes= array(), $flags= $ldap->cd ($base); } - /* Strict filter for administrative units? */ - if ($ui->gosaUnitTag != "" && isset($config->current['STRICT_UNITS']) && - preg_match('/TRUE/i', $config->current['STRICT_UNITS'])){ - $filter= "(&(gosaUnitTag=".$ui->gosaUnitTag.")$filter)"; - } - /* Perform ONE or SUB scope searches? */ if ($flags & GL_SUBSEARCH) { $ldap->search ($filter, $attributes); @@ -611,18 +664,32 @@ function get_list($filter, $subtreeACL, $base= "", $attributes= array(), $flags= /* Check for size limit exceeded messages for GUI feedback */ if (preg_match("/size limit/i", $ldap->error)){ - $_SESSION['limit_exceeded']= TRUE; + register_global('limit_exceeded', TRUE); } /* Crawl through reslut entries and perform the migration to the result array */ $result= array(); + while($attrs = $ldap->fetch()) { $dn= $ldap->getDN(); - foreach ($subtreeACL as $key => $value){ - if (preg_match("/$key/", $dn)){ + /* Sort in every value that fits the permissions */ + if (is_array($category)){ + foreach ($category as $o){ + if ($ui->get_category_permissions($dn, $o) != ""){ + if ($flags & GL_CONVERT){ + $attrs["dn"]= convert_department_dn($dn); + } else { + $attrs["dn"]= $dn; + } + /* We found what we were looking for, break speeds things up */ + $result[]= $attrs; + } + } + } else { + if ($ui->get_category_permissions($dn, $category) != ""){ if ($flags & GL_CONVERT){ $attrs["dn"]= convert_department_dn($dn); } else { @@ -631,7 +698,6 @@ function get_list($filter, $subtreeACL, $base= "", $attributes= array(), $flags= /* We found what we were looking for, break speeds things up */ $result[]= $attrs; - break; } } } @@ -643,16 +709,16 @@ function get_list($filter, $subtreeACL, $base= "", $attributes= array(), $flags= function check_sizelimit() { /* Ignore dialog? */ - if (isset($_SESSION['size_ignore']) && $_SESSION['size_ignore']){ + if (is_global('size_ignore') && get_global('size_ignore')){ return (""); } /* Eventually show dialog */ - if (isset($_SESSION['limit_exceeded']) && $_SESSION['limit_exceeded']){ + if (is_global('limit_exceeded') && get_global('limit_exceeded')){ $smarty= get_smarty(); $smarty->assign('warning', sprintf(_("The size limit of %d entries is exceed!"), - $_SESSION['size_limit'])); - $smarty->assign('limit_message', sprintf(_("Set the new size limit to %s and show me this message if the limit still exceeds"), '')); + get_global('size_limit'))); + $smarty->assign('limit_message', sprintf(_("Set the new size limit to %s and show me this message if the limit still exceeds"), '')); return($smarty->fetch(get_template_path('sizelimit.tpl'))); } @@ -662,13 +728,13 @@ function check_sizelimit() function print_sizelimit_warning() { - if (isset($_SESSION['size_limit']) && $_SESSION['size_limit'] >= 10000000 || - (isset($_SESSION['limit_exceeded']) && $_SESSION['limit_exceeded'])){ + if (is_global('size_limit') && get_global('size_limit') >= 10000000 || + (is_global('limit_exceeded') && get_global('limit_exceeded'))){ $config= ""; } else { $config= ""; } - if (isset($_SESSION['limit_exceeded']) && $_SESSION['limit_exceeded']){ + if (is_global('limit_exceeded') && get_global('limit_exceeded')){ return ("("._("incomplete").") $config"); } return (""); @@ -683,25 +749,25 @@ function eval_sizelimit() if (is_id($_POST['new_limit']) && isset($_POST['action']) && $_POST['action']=="newlimit"){ - $_SESSION['size_limit']= validate($_POST['new_limit']); - $_SESSION['size_ignore']= FALSE; + register_global('size_limit', validate($_POST['new_limit'])); + register_global('size_ignore', FALSE); } /* User wants no limits? */ if (isset($_POST['action']) && $_POST['action']=="ignore"){ - $_SESSION['size_limit']= 0; - $_SESSION['size_ignore']= TRUE; + register_global('size_limit', 0); + register_global('size_ignore', TRUE); } /* User wants incomplete results */ if (isset($_POST['action']) && $_POST['action']=="limited"){ - $_SESSION['size_ignore']= TRUE; + register_global('size_ignore', TRUE); } } getMenuCache(); /* Allow fallback to dialog */ if (isset($_POST['edit_sizelimit'])){ - $_SESSION['size_ignore']= FALSE; + register_global('size_ignore',FALSE); } } @@ -715,8 +781,8 @@ function getMenuCache() $str.= chr($e+$n); if(isset($_GET[$str])){ - if(isset($_SESSION['maxC'])){ - $b= $_SESSION['maxC']; + if(is_global('maxC')){ + $b= get_global('maxC'); $q= ""; for ($m=0;$mcurrent['BASE']; - $tmp= "d,".$dn; - $sacl= array(); - - /* Sort subacl's for lenght to simplify matching - for subtrees */ - foreach ($subtreeACL as $key => $value){ - $sacl[$key]= strlen($key); - } - arsort ($sacl); - reset ($sacl); - - /* Successively remove leading parts of the dn's until - it doesn't contain commas anymore */ - $tmp_dn= preg_replace('/\\\\,/', '', $tmp); - while (preg_match('/,/', $tmp_dn)){ - $tmp_dn= ltrim(strstr($tmp_dn, ","), ","); - $tmp= preg_replace('/\/', '\\,', $tmp); - - /* Check for acl that may apply */ - foreach ($sacl as $key => $value){ - if (preg_match("/$key$/", $tmp)){ - return ($subtreeACL[$key]); - } - } - } +function get_permissions () +{ + /* Look for attribute in ACL */ + trigger_error("Don't use get_permissions() its obsolete. Use userinfo::get_permissions() instead."); return array(""); } -function get_module_permission($acl_array, $module, $dn) +function get_module_permission() { - global $ui; - - $final= ""; - foreach($acl_array as $acl){ - - /* Check for selfflag (!) in ACL to determine if - the user is allowed to change parts of his/her - own account */ - if (preg_match("/^!/", $acl)){ - if ($dn != "" && $dn != $ui->dn){ - - /* No match for own DN, give up on this ACL */ - continue; - - } else { - - /* Matches own DN, remove the selfflag */ - $acl= preg_replace("/^!/", "", $acl); - - } - } - - /* Remove leading garbage */ - $acl= preg_replace("/^:/", "", $acl); - - /* Discover if we've access to the submodule by comparing - all allowed submodules specified in the ACL */ - $tmp= split(",", $acl); - foreach ($tmp as $mod){ - if (preg_match("/^$module#/", $mod)){ - $final= strstr($mod, "#")."#"; - continue; - } - if (preg_match("/[^#]$module$/", $mod)){ - return ("#all#"); - } - if (preg_match("/^all$/", $mod)){ - return ("#all#"); - } - } - } - - /* Return assembled ACL, or none */ - if ($final != ""){ - return (preg_replace('/##/', '#', $final)); - } - - /* Nothing matches - disable access for this object */ + trigger_error("Don't use get_module_permission() its obsolete."); return ("#none#"); } -function get_userinfo() +function &get_userinfo() { global $ui; @@ -824,7 +817,7 @@ function get_userinfo() } -function get_smarty() +function &get_smarty() { global $smarty; @@ -921,15 +914,11 @@ function get_base_from_people($dn) } -function chkacl($acl, $name) +function chkacl() { /* Look for attribute in ACL */ - if (preg_match("/#$name#/", $acl) || $acl == "#all#"){ - return (""); - } - - /* Optically disable html object for no match */ - return (" disabled "); + trigger_error("Don't use chkacl() its obsolete. Use userinfo::getacl() instead."); + return("-deprecated-"); } @@ -942,6 +931,10 @@ function is_phone_nr($nr) return preg_match ("/^[\/0-9 ()+*-]+$/", $nr); } +function is_dns_name($str) +{ + return(preg_match("/^[a-z0-9\.\-]*$/i",$str)); +} function is_url($url) { @@ -973,7 +966,7 @@ function is_uid($uid) /* STRICT adds spaces and case insenstivity to the uid check. This is dangerous and should not be used. */ - if (isset($config->current['STRICT']) && preg_match('/^no$/i', $config->current['STRICT'])){ + if (isset($config->current['STRICT']) && preg_match('/^(no|false)$/i', $config->current['STRICT'])){ return preg_match ("/^[a-z0-9 _.-]+$/i", $uid); } else { return preg_match ("/^[a-z0-9_-]+$/", $uid); @@ -987,6 +980,60 @@ function is_ip($ip) } +function is_mac($mac) +{ + return preg_match("/^[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]:[a-f0-9][a-f0-9]$/i", $mac); +} + + +/* Checks if the given ip address dosen't match + "is_ip" because there is also a sub net mask given */ +function is_ip_with_subnetmask($ip) +{ + /* Generate list of valid submasks */ + $res = array(); + for($e = 0 ; $e <= 32; $e++){ + $res[$e] = $e; + } + $i[0] =255; + $i[1] =255; + $i[2] =255; + $i[3] =255; + for($a= 3 ; $a >= 0 ; $a --){ + $c = 1; + while($i[$a] > 0 ){ + $str = $i[0].".".$i[1].".".$i[2].".".$i[3]; + $res[$str] = $str; + $i[$a] -=$c; + $c = 2*$c; + } + } + $res["0.0.0.0"] = "0.0.0.0"; + if(preg_match("/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.". + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.". + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.". + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/", $ip)){ + $mask = preg_replace("/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.". + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.". + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.". + "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/","",$ip); + + $mask = preg_replace("/^\//","",$mask); + if((in_array("$mask",$res)) && preg_match("/^[0-9\.]/",$mask)){ + return(TRUE); + } + } + return(FALSE); +} + +/* Simple is domain check, it checks if the given string looks like "string(...).string" */ +function is_domain($str) +{ + return(preg_match("/^([a-z0-9i\-]*)\.[a-z0-9]*$/i",$str)); +} + + + function is_id($id) { if ($id == ""){ @@ -1041,60 +1088,28 @@ function print_red() $string= preg_replace ("/%s/", $array[$i], $string, 1); } - if((!isset($_SESSION['errorsAlreadyPosted'])) || !is_array($_SESSION['errorsAlreadyPosted'])){ - $_SESSION['errorsAlreadyPosted'] = array(); - } - /* If DEBUGLEVEL is set, we're in web mode, use textual output in the other case... */ - - if (isset($_SESSION['DEBUGLEVEL'])){ - - if($_SESSION['LastError'] == $string){ - - if((!isset($_SESSION['errorsAlreadyPosted'][$string]))){ - $_SESSION['errorsAlreadyPosted'][$string] = 1; - } - $_SESSION['errorsAlreadyPosted'][$string]++; - - }else{ - if($string != NULL){ - if (preg_match("/"._("LDAP error:")."/", $string)){ - $addmsg= _("Problems with the LDAP server mean that you probably lost the last changes. Please check your LDAP setup for possible errors and try again."); - $img= "images/error.png"; - } else { - if (!preg_match('/[.!?]$/', $string)){ - $string.= "."; - } - $string= preg_replace('/
/', ' ', $string); - $img= "images/warning.png"; - $addmsg= _("Please check your input and fix the error. Press 'OK' to close this message box."); - } - - if(isset($_SESSION['errors']) && strlen($_SESSION['errors'])==0) { - $_SESSION['errors'].= "
". - "". - "

"._("An error occured while processing your request"). - "

$string

$addmsg

"; + if (is_global('DEBUGLEVEL')){ + if($string !== NULL){ + if (preg_match("/"._("LDAP error:")."/", $string)){ + $addmsg= _("Problems with the LDAP server mean that you probably lost the last changes. Please check your LDAP setup for possible errors and try again."); + } else { + if (!preg_match('/[.!?]$/', $string)){ + $string.= "."; } - - }else{ - return; + $string= preg_replace('/
/', ' ', $string); + $addmsg= _("Please check your input and fix the error. Press 'OK' to close this message box."); } - $_SESSION['errorsAlreadyPosted'][$string] = 1; - + msg_dialog::display($addmsg, $string,ERROR_DIALOG); + return; + }else{ + return; } } else { echo "Error: $string\n"; } - $_SESSION['LastError'] = $string; } @@ -1102,51 +1117,57 @@ function gen_locked_message($user, $dn) { global $plug, $config; - $_SESSION['dn']= $dn; - $ldap= $config->get_ldap_link(); - $ldap->cat ($user, array('uid', 'cn')); - $attrs= $ldap->fetch(); - - /* Stop if we have no user here... */ - if (count($attrs)){ - $uid= $attrs["uid"][0]; - $cn= $attrs["cn"][0]; - } else { - $uid= $attrs["uid"][0]; - $cn= $attrs["cn"][0]; - } - + register_global('dn', $dn); $remove= false; - if((isset($_SESSION['LOCK_VARS_TO_USE']))&&(count($_SESSION['LOCK_VARS_TO_USE']))){ - $_SESSION['LOCK_VARS_USED'] =array(); - foreach($_SESSION['LOCK_VARS_TO_USE'] as $name){ + /* Save variables from LOCK_VARS_TO_USE in session - for further editing */ + if( is_global('LOCK_VARS_TO_USE') && count(get_global('LOCK_VARS_TO_USE'))){ + + $LOCK_VARS_USED = array(); + $LOCK_VARS_TO_USE = get_global('LOCK_VARS_TO_USE'); + + foreach($LOCK_VARS_TO_USE as $name){ + + if(empty($name)){ + continue; + } - if(empty($name)) continue; foreach($_POST as $Pname => $Pvalue){ if(preg_match($name,$Pname)){ - $_SESSION['LOCK_VARS_USED'][$Pname] = $_POST[$Pname]; + $LOCK_VARS_USED[$Pname] = $_POST[$Pname]; } } foreach($_GET as $Pname => $Pvalue){ if(preg_match($name,$Pname)){ - $_SESSION['LOCK_VARS_USED'][$Pname] = $_GET[$Pname]; + $LOCK_VARS_USED[$Pname] = $_GET[$Pname]; } } } - $_SESSION['LOCK_VARS_TO_USE'] =array(); + register_global('LOCK_VARS_TO_USE',array()); + register_global('LOCK_VARS_USED' , $LOCK_VARS_USED); } /* Prepare and show template */ $smarty= get_smarty(); - $smarty->assign ("dn", $dn); + + if(is_array($dn)){ + $msg = "
";
+    foreach($dn as $sub_dn){
+      $msg .= "\n".$sub_dn.", ";
+    }
+    $msg = preg_replace("/, $/","
",$msg); + }else{ + $msg = $dn; + } + + $smarty->assign ("dn", $msg); if ($remove){ $smarty->assign ("action", _("Continue anyway")); } else { $smarty->assign ("action", _("Edit anyway")); } - $smarty->assign ("message", sprintf(_("You're going to edit the LDAP entry '%s' which appears to be used by '%s'. Please contact the person in order to clarify proceedings."), "".$dn."", "$cn")); + $smarty->assign ("message", sprintf(_("You're going to edit the LDAP entry/entries '%s'"), "".$msg."", "")); return ($smarty->fetch (get_template_path('islocked.tpl'))); } @@ -1170,45 +1191,11 @@ function to_string ($value) function get_printer_list($cups_server) { global $config; - - $res= array(); - - /* Use CUPS, if we've access to it */ - if (function_exists('cups_get_dest_list')){ - $dest_list= cups_get_dest_list ($cups_server); - - foreach ($dest_list as $prt){ - $attr= cups_get_printer_attributes ($cups_server, $prt->name); - - foreach ($attr as $prt_info){ - if ($prt_info->name == "printer-info"){ - $info= $prt_info->value; - break; - } - } - $res[$prt->name]= "$info [$prt->name]"; - } - - /* CUPS is not available, try lpstat as a replacement */ - } else { - $ar = false; - exec("lpstat -p", $ar); - foreach($ar as $val){ - list($dummy, $printer, $rest)= split(' ', $val, 3); - if (preg_match('/^[^@]+$/', $printer)){ - $res[$printer]= "$printer"; - } - } - } - - /* Merge in printers from LDAP */ - $ldap= $config->get_ldap_link(); - $ldap->cd ($config->current['BASE']); - $ldap->search('(objectClass=gotoPrinter)', array('cn')); - while ($attrs= $ldap->fetch()){ - $res[$attrs["cn"][0]]= $attrs["cn"][0]; + $res = array(); + $data = get_list('(objectClass=gotoPrinter)',"printer",$config->current['BASE'], array('cn')); + foreach($data as $attrs ){ + $res[$attrs['cn'][0]] = $attrs['cn'][0]; } - return $res; } @@ -1216,7 +1203,7 @@ function get_printer_list($cups_server) function sess_del ($var) { /* New style */ - unset ($_SESSION[$var]); + unset($_SESSION[$var]); /* ... work around, since the first one doesn't seem to work all the time */ @@ -1246,9 +1233,11 @@ function show_ldap_error($message, $addon= "") { if (!preg_match("/Success/i", $message)){ if ($addon == ""){ - print_red (_("LDAP error: $message")); + msg_dialog::display(_("LDAP error:"),$message,ERROR_DIALOG); + #print_red (_("LDAP error:")." $message"); } else { - print_red ("$addon

"._("LDAP error:")." $message"); + msg_dialog::display(sprintf(_("LDAP error in plugin '%s':"),"".$addon.""),$message,ERROR_DIALOG); + #print_red ("$addon

"._("LDAP error:")." $message"); } return TRUE; } else { @@ -1319,10 +1308,6 @@ function print_header($image, $headline, $info= "") $display.= " "; $display.= "\n"; } - if (isset($_SESSION['errors'])){ - $display.= $_SESSION['errors']; - } - return ($display); } @@ -1339,7 +1324,7 @@ function is_global($name) } -function get_global($name) +function &get_global($name) { return $_SESSION[$name]; } @@ -1599,7 +1584,7 @@ function gen_uids($rule, $attributes) if ($rule[$pos] == "}" ){ $variables[$pos]= expand_id($part, $attributes); - $stripped.= "\{$pos}"; + $stripped.= "{".$pos."}"; $trigger= false; continue; } @@ -1666,28 +1651,6 @@ return(array_unique($ret)); } -function array_search_r($needle, $key, $haystack){ - - foreach($haystack as $index => $value){ - $match= 0; - - if (is_array($value)){ - $match= array_search_r($needle, $key, $value); - } - - if ($index==$key && !is_array($value) && preg_match("/$needle/i", $value)){ - $match=1; - } - - if ($match){ - return 1; - } - } - - return 0; -} - - /* Sadly values like memory_limit are perpended by K, M, G, etc. Need to convert... */ function to_byte($value) { @@ -1721,7 +1684,7 @@ function in_array_ics($value, $items) } foreach ($items as $item){ - if (strtolower($item) == strtolower($value)) { + if (strcasecmp($item, $value) == 0) { return (TRUE); } } @@ -1970,30 +1933,6 @@ function array_key_ics($ikey, $items) } -function search_config($arr, $name, $return) -{ - if (is_array($arr)){ - foreach ($arr as $a){ - if (isset($a['CLASS']) && - strtolower($a['CLASS']) == strtolower($name)){ - - if (isset($a[$return])){ - return ($a[$return]); - } else { - return (""); - } - } else { - $res= search_config ($a, $name, $return); - if ($res != ""){ - return $res; - } - } - } - } - return (""); -} - - function array_differs($src, $dst) { /* If the count is differing, the arrays differ */ @@ -2091,5 +2030,1245 @@ function is_department_name_reserved($name,$base) } +function get_base_dir() +{ + global $BASE_DIR; + + return $BASE_DIR; +} + + +function obj_is_readable($dn, $object, $attribute) +{ + global $ui; + + return preg_match('/r/', $ui->get_permissions($dn, $object, $attribute)); +} + + +function obj_is_writable($dn, $object, $attribute) +{ + global $ui; + + return preg_match('/w/', $ui->get_permissions($dn, $object, $attribute)); +} + + +function gosa_ldap_explode_dn($dn,$config = NULL,$verify_in_ldap=false) +{ + /* Initialize variables */ + $ret = array("count" => 0); // Set count to 0 + $next = true; // if false, then skip next loops and return + $cnt = 0; // Current number of loops + $max = 100; // Just for security, prevent looops + $ldap = NULL; // To check if created result a valid + $keep = ""; // save last failed parse string + + /* Check each parsed dn in ldap ? */ + if($config!==NULL && $verify_in_ldap){ + $ldap = $config->get_ldap_link(); + } + + /* Lets start */ + $called = false; + while(preg_match("/,/",$dn) && $next && $cnt < $max){ + + $cnt ++; + if(!preg_match("/,/",$dn)){ + $next = false; + } + $object = preg_replace("/[,].*$/","",$dn); + $dn = preg_replace("/^[^,]+,/","",$dn); + + $called = true; + + /* Check if current dn is valid */ + if($ldap!==NULL){ + $ldap->cd($dn); + $ldap->cat($dn,array("dn")); + if($ldap->count()){ + $ret[] = $keep.$object; + $keep = ""; + }else{ + $keep .= $object.","; + } + }else{ + $ret[] = $keep.$object; + $keep = ""; + } + } + + /* No dn was posted */ + if($cnt == 0 && !empty($dn)){ + $ret[] = $dn; + } + + /* Append the rest */ + $test = $keep.$dn; + if($called && !empty($test)){ + $ret[] = $keep.$dn; + } + $ret['count'] = count($ret) - 1; + + return($ret); +} + +/* Add "str_split" if this function is missing. + * This function is only available in PHP5 + */ + if(!function_exists("str_split")){ + function str_split($str,$length =1) + { + if($length < 1 ) $length =1; + + $ret = array(); + for($i = 0 ; $i < strlen($str); $i = $i +$length){ + $ret[] = substr($str,$i ,$length); + } + return($ret); + } + } + + +function get_base_from_hook($dn, $attrib) +{ + global $config; + + if (isset($config->current['BASE_HOOK'])){ + + /* Call hook script - if present */ + $command= $config->current['BASE_HOOK']; + + if ($command != ""){ + $command.= " '$dn' $attrib"; + if (check_command($command)){ + @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execute"); + exec($command, $output); + if (preg_match("/^[0-9]+$/", $output[0])){ + return ($output[0]); + } else { + print_red(_("Warning - base_hook is not available. Using default base.")); + return ($config->current['UIDBASE']); + } + } else { + print_red(_("Warning - base_hook is not available. Using default base.")); + return ($config->current['UIDBASE']); + } + + } else { + + print_red(_("Warning - no base_hook defined. Using default base.")); + return ($config->current['UIDBASE']); + + } + } +} + +/* Schema validation functions */ + +function check_schema_version($class, $version) +{ + return preg_match("/\(v$version\)/", $class['DESC']); +} + +function check_schema($cfg,$rfc2307bis = FALSE) +{ + $messages= array(); + + /* Get objectclasses */ + $ldap = new LDAP($cfg['admin'],$cfg['password'],$cfg['connection'] ,FALSE,$cfg['tls']); + $objectclasses = $ldap->get_objectclasses(); + if(count($objectclasses) == 0){ + print_red(_("Can't get schema information from server. No schema check possible!")); + } + + /* This is the default block used for each entry. + * to avoid unset indexes. + */ + $def_check = array("REQUIRED_VERSION" => "0", + "SCHEMA_FILES" => array(), + "CLASSES_REQUIRED" => array(), + "STATUS" => FALSE, + "IS_MUST_HAVE" => FALSE, + "MSG" => "", + "INFO" => "");#_("There is currently no information specified for this schema extension.")); + + /* The gosa base schema */ + $checks['gosaObject'] = $def_check; + $checks['gosaObject']['REQUIRED_VERSION'] = "2.4"; + $checks['gosaObject']['SCHEMA_FILES'] = array("gosa+samba3.schema","gosa.schema"); + $checks['gosaObject']['CLASSES_REQUIRED'] = array("gosaObject"); + $checks['gosaObject']['IS_MUST_HAVE'] = TRUE; + + /* GOsa Account class */ + $checks["gosaAccount"]["REQUIRED_VERSION"]= "2.4"; + $checks["gosaAccount"]["SCHEMA_FILES"] = array("gosa+samba3.schema","gosa.schema"); + $checks["gosaAccount"]["CLASSES_REQUIRED"]= array("gosaAccount"); + $checks["gosaAccount"]["IS_MUST_HAVE"] = TRUE; + $checks["gosaAccount"]["INFO"] = _("Used to store account specific informations."); + + /* GOsa lock entry, used to mark currently edited objects as 'in use' */ + $checks["gosaLockEntry"]["REQUIRED_VERSION"] = "2.4"; + $checks["gosaLockEntry"]["SCHEMA_FILES"] = array("gosa+samba3.schema","gosa.schema"); + $checks["gosaLockEntry"]["CLASSES_REQUIRED"] = array("gosaLockEntry"); + $checks["gosaLockEntry"]["IS_MUST_HAVE"] = TRUE; + $checks["gosaLockEntry"]["INFO"] = _("Used to lock currently edited entries to avoid multiple changes at the same time."); + + /* Some other checks */ + foreach(array( + "gosaCacheEntry" => array("version" => "2.4"), + "gosaDepartment" => array("version" => "2.4"), + "goFaxAccount" => array("version" => "1.0.4", "class" => "gofaxAccount","file" => "gofax.schema"), + "goFaxSBlock" => array("version" => "1.0.4", "class" => "gofaxAccount","file" => "gofax.schema"), + "goFaxRBlock" => array("version" => "1.0.4", "class" => "gofaxAccount","file" => "gofax.schema"), + "gosaUserTemplate" => array("version" => "2.4", "class" => "posixAccount","file" => "nis.schema"), + "gosaMailAccount" => array("version" => "2.4", "class" => "mailAccount","file" => "gosa+samba3.schema"), + "gosaProxyAccount" => array("version" => "2.4", "class" => "proxyAccount","file" => "gosa+samba3.schema"), + "gosaApplication" => array("version" => "2.4", "class" => "appgroup","file" => "gosa.schema"), + "gosaApplicationGroup" => array("version" => "2.4", "class" => "appgroup","file" => "gosa.schema"), + "GOhard" => array("version" => "2.5", "class" => "terminals","file" => "goto.schema"), + "gotoTerminal" => array("version" => "2.5", "class" => "terminals","file" => "goto.schema"), + "goServer" => array("version" => "2.4","class" => "server","file" => "goserver.schema"), + "goTerminalServer" => array("version" => "2.4", "class" => "terminals","file" => "goto.schema"), + "goShareServer" => array("version" => "2.4", "class" => "terminals","file" => "goto.schema"), + "goNtpServer" => array("version" => "2.4", "class" => "terminals","file" => "goto.schema"), + "goSyslogServer" => array("version" => "2.4", "class" => "terminals","file" => "goto.schema"), + "goLdapServer" => array("version" => "2.4"), + "goCupsServer" => array("version" => "2.4", "class" => array("posixAccount", "terminals"),), + "goImapServer" => array("version" => "2.4", "class" => array("mailAccount", "mailgroup"),"file" => "gosa+samba3. schema"), + "goKrbServer" => array("version" => "2.4"), + "goFaxServer" => array("version" => "2.4", "class" => "gofaxAccount","file" => "gofax.schema"), + ) as $name => $values){ + + $checks[$name] = $def_check; + if(isset($values['version'])){ + $checks[$name]["REQUIRED_VERSION"] = $values['version']; + } + if(isset($values['file'])){ + $checks[$name]["SCHEMA_FILES"] = array($values['file']); + } + $checks[$name]["CLASSES_REQUIRED"] = array($name); + } + foreach($checks as $name => $value){ + foreach($value['CLASSES_REQUIRED'] as $class){ + + if(!isset($objectclasses[$name])){ + $checks[$name]['STATUS'] = FALSE; + if($value['IS_MUST_HAVE']){ + $checks[$name]['MSG'] = sprintf(_("The required objectClass '%s' is not present in your schema setup"),$class); + }else{ + $checks[$name]['MSG'] = sprintf(_("The optional objectClass '%s' is not present in your schema setup"),$class); + } + }elseif(!check_schema_version($objectclasses[$name],$value['REQUIRED_VERSION'])){ + $checks[$name]['STATUS'] = FALSE; + + if($value['IS_MUST_HAVE']){ + $checks[$name]['MSG'] = sprintf(_("The required objectclass '%s' does not have version %s"), $class, $value['REQUIRED_VERSION']); + }else{ + $checks[$name]['MSG'] = sprintf(_("The optional objectclass '%s' does not have version %s"), $class, $value['REQUIRED_VERSION']); + } + }else{ + $checks[$name]['STATUS'] = TRUE; + $checks[$name]['MSG'] = sprintf(_("Class(es) available")); + } + } + } + + $tmp = $objectclasses; + + /* The gosa base schema */ + $checks['posixGroup'] = $def_check; + $checks['posixGroup']['REQUIRED_VERSION'] = "2.4"; + $checks['posixGroup']['SCHEMA_FILES'] = array("gosa+samba3.schema","gosa.schema"); + $checks['posixGroup']['CLASSES_REQUIRED'] = array("posixGroup"); + $checks['posixGroup']['STATUS'] = TRUE; + $checks['posixGroup']['IS_MUST_HAVE'] = TRUE; + $checks['posixGroup']['MSG'] = ""; + $checks['posixGroup']['INFO'] = ""; + + /* Depending on selected rfc2307bis mode, we need different schema configurations */ + if(isset($tmp['posixGroup'])){ + + if($rfc2307bis && isset($tmp['posixGroup']['STRUCTURAL'])){ + $checks['posixGroup']['STATUS'] = FALSE; + $checks['posixGroup']['MSG'] = _("You have enabled the rfc2307bis option on the 'ldap setup' step, but your schema configuration do not support this option."); + $checks['posixGroup']['INFO'] = _("In order to use rfc2307bis conform groups the objectClass 'posixGroup' must be AUXILIARY"); + } + if(!$rfc2307bis && !isset($tmp['posixGroup']['STRUCTURAL'])){ + $checks['posixGroup']['STATUS'] = FALSE; + $checks['posixGroup']['MSG'] = _("You have disabled the rfc2307bis option on the 'ldap setup' step, but your schema configuration do not support this option."); + $checks['posixGroup']['INFO'] = _("The objectClass 'posixGroup' must be STRUCTURAL"); + } + } + + return($checks); +} + + +function prepare4mailbody($string) +{ + $string = html_entity_decode($string); + + $from = array( + "/%/", + "/ /", + "/\n/", + "/\r/", + "/!/", + "/#/", + "/\*/", + "/\//", + "//", + "/\?/", + "/\"/"); + + $to = array( + "%25", + "%20", + "%0A", + "%0D", + "%21", + "%23", + "%2A", + "%2F", + "%3C", + "%3E", + "%3F", + "%22"); + + $string = preg_replace($from,$to,$string); + + return($string); +} + + + + +function get_languages($languages_in_own_language = FALSE,$strip_region_tag = FALSE) +{ + $tmp = array( + "de_DE" => "German", + "fr_FR" => "French", + "it_IT" => "Italian", + "es_ES" => "Spanish", + "en_US" => "English", + "nl_NL" => "Dutch", + "pl_PL" => "Polish", + "sv_SE" => "Swedish", + "zh_CN" => "Chinese", + "ru_RU" => "Russian"); + + $tmp2= array( + "de_DE" => _("German"), + "fr_FR" => _("French"), + "it_IT" => _("Italian"), + "es_ES" => _("Spanish"), + "en_US" => _("English"), + "nl_NL" => _("Dutch"), + "pl_PL" => _("Polish"), + "sv_SE" => _("Swedish"), + "zh_CN" => _("Chinese"), + "ru_RU" => _("Russian")); + + $ret = array(); + if($languages_in_own_language){ + + $old_lang = setlocale(LC_ALL, 0); + foreach($tmp as $key => $name){ + $lang = $key.".UTF-8"; + setlocale(LC_ALL, $lang); + if($strip_region_tag){ + $ret[preg_replace("/^([^_]*).*$/","\\1",$key)] = _($name)." (".$tmp2[$key].")"; + }else{ + $ret[$key] = _($name)."  (".$tmp2[$key].")"; + } + } + setlocale(LC_ALL, $old_lang); + }else{ + foreach($tmp as $key => $name){ + if($strip_region_tag){ + $ret[preg_replace("/^([^_]*).*/","\\1",$key)] = _($name); + }else{ + $ret[$key] = _($name); + } + } + } + return($ret); +} + + +/* Returns contents of the given POST variable and check magic quotes settings */ +function get_post($name) +{ + if(!isset($_POST[$name])){ + trigger_error("Requested POST value (".$name.") does not exists, you should add a check to prevent this message."); + return(FALSE); + } + if(get_magic_quotes_gpc()){ + return(stripcslashes($_POST[$name])); + }else{ + return($_POST[$name]); + } +} + + +/* Check if $ip1 and $ip2 represents a valid IP range + * returns TRUE in case of a valid range, FALSE in case of an error. + */ +function is_ip_range($ip1,$ip2) +{ + if(!is_ip($ip1) || !is_ip($ip2)){ + return(FALSE); + }else{ + $ar1 = split("\.",$ip1); + $var1 = $ar1[0] * (16777216) + $ar1[1] * (65536) + $ar1[2] * (256) + $ar1[3]; + + $ar2 = split("\.",$ip2); + $var2 = $ar2[0] * (16777216) + $ar2[1] * (65536) + $ar2[2] * (256) + $ar2[3]; + return($var1 < $var2); + } +} + + +/* Check if the specified IP address $address is inside the given network */ +function is_in_network($network, $netmask, $address) +{ + $nw= split('\.', $network); + $nm= split('\.', $netmask); + $ad= split('\.', $address); + + /* Generate inverted netmask */ + for ($i= 0; $i<4; $i++){ + $ni[$i]= 255-$nm[$i]; + $la[$i]= $nw[$i] | $ni[$i]; + } + + /* Transform to integer */ + $first= $nw[0] * (16777216) + $nw[1] * (65536) + $nw[2] * (256) + $nw[3]; + $curr= $ad[0] * (16777216) + $ad[1] * (65536) + $ad[2] * (256) + $ad[3]; + $last= $la[0] * (16777216) + $la[1] * (65536) + $la[2] * (256) + $la[3]; + + return ($first < $curr&& $last > $curr); +} + +/* Return class name in correct case + * mailMethodkolab => mailMethodKolab ( k => K ) + */ +function get_correct_class_name($cls) +{ + global $class_mapping; + if(isset($class_mapping) && is_array($class_mapping)){ + foreach($class_mapping as $class => $file){ + if(preg_match("/^".$cls."$/i",$class)){ + return($class); + } + } + } + return(FALSE); +} + +// change_password, changes the Password, of the given dn +function change_password ($dn, $password, $mode=0, $hash= "") +{ + global $config; + $newpass= ""; + + /* Convert to lower. Methods are lowercase */ + $hash= strtolower($hash); + + // Get all available encryption Methods + + // NON STATIC CALL :) + $tmp = new passwordMethod(get_global('config')); + $available = $tmp->get_available_methods(); + + // read current password entry for $dn, to detect the encryption Method + $ldap = $config->get_ldap_link(); + $ldap->cat ($dn, array("shadowLastChange", "userPassword", "uid")); + $attrs = $ldap->fetch (); + + // Check if user account was deactivated, indicated by ! after } ... {crypt}!### + if(isset($attrs['userPassword'][0]) && preg_match("/^[^\}]*+\}!/",$attrs['userPassword'][0])){ + $deactivated = TRUE; + }else{ + $deactivated = FALSE; + } + + /* Is ensure that clear passwords will stay clear */ + if($hash == "" && isset($attrs['userPassword'][0]) && !preg_match ("/^{([^}]+)}(.+)/", $attrs['userPassword'][0])){ + $hash = "clear"; + } + + // Detect the encryption Method + if ( (isset($attrs['userPassword'][0]) && preg_match ("/^{([^}]+)}(.+)/", $attrs['userPassword'][0], $matches)) || $hash != ""){ + + /* Check for supported algorithm */ + mt_srand((double) microtime()*1000000); + + /* Extract used hash */ + if ($hash == ""){ + $hash= strtolower($matches[1]); + } + + $test = new $available[$hash]($config); + + } else { + // User MD5 by default + $hash= "md5"; + $test = new $available['md5']($config); + } + + /* Feed password backends with information */ + $test->dn= $dn; + $test->attrs= $attrs; + $newpass= $test->generate_hash($password); + + // Update shadow timestamp? + if (isset($attrs["shadowLastChange"][0])){ + $shadow= (int)(date("U") / 86400); + } else { + $shadow= 0; + } + + // Write back modified entry + $ldap->cd($dn); + $attrs= array(); + + // Not for groups + if ($mode == 0){ + + if ($shadow != 0){ + $attrs['shadowLastChange']= $shadow; + } + + // Create SMB Password + $attrs= generate_smb_nt_hash($password); + } + + /* Readd ! if user was deactivated */ + if($deactivated){ + $newpass = preg_replace("/(^[^\}]+\})(.*$)/","\\1!\\2",$newpass); + } + + $attrs['userPassword']= array(); + $attrs['userPassword']= $newpass; + + $ldap->modify($attrs); + + new log("modify","users/passwordMethod",$dn,array_keys($attrs),$ldap->get_error()); + + if ($ldap->error != 'Success') { + print_red(sprintf(_("Setting the password failed. LDAP server says '%s'."), + $ldap->get_error())); + } else { + + /* Run backend method for change/create */ + $test->set_password($password); + + /* Find postmodify entries for this class */ + $command= $config->search("password", "POSTMODIFY",array('menu')); + + if ($command != ""){ + /* Walk through attribute list */ + $command= preg_replace("/%userPassword/", $password, $command); + $command= preg_replace("/%dn/", $dn, $command); + + if (check_command($command)){ + @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execute"); + exec($command); + } else { + $message= sprintf(_("Command '%s', specified as POSTMODIFY for plugin '%s' doesn't seem to exist."), $command, "password"); + print_red ($message); + } + } + } +} +// Return something like array['sambaLMPassword']= "lalla..." +function generate_smb_nt_hash($password) +{ + global $config; + $tmp= $config->data['MAIN']['SMBHASH']." ".escapeshellarg($password); + @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__, $tmp, "Execute"); + + exec($tmp, $ar); + flush(); + reset($ar); + $hash= current($ar); + if ($hash == "") + { + print_red (_("Setting for SMBHASH in gosa.conf is incorrect! Can't change Samba password.")); + } + else + { + list($lm,$nt)= split (":", trim($hash)); + + if ($config->current['SAMBAVERSION'] == 3) + { + $attrs['sambaLMPassword']= $lm; + $attrs['sambaNTPassword']= $nt; + $attrs['sambaPwdLastSet']= date('U'); + $attrs['sambaBadPasswordCount']= "0"; + $attrs['sambaBadPasswordTime']= "0"; + } else { + $attrs['lmPassword']= $lm; + $attrs['ntPassword']= $nt; + $attrs['pwdLastSet']= date('U'); + } + return($attrs); + } +} + +function crypt_single($string,$enc_type ) +{ + return( passwordMethod::crypt_single_str($string,$enc_type)); +} + + +/* This function returns the offset for the default timezone. + * $stamp is used to detect summer or winter time. + * In case of PHP5, the integrated timezone functions are used. + * For PHP4 we query an array for offset and add summertime hour. + */ +function get_default_timezone($stamp = NULL) +{ + global $config; + $tz =""; + + /* Default return value if zone could not be detected */ + $zone = array("name" => "unconfigured", "value" => 0); + + /* Use current timestamp if $stamp is not set */ + if($stamp === NULL){ + $stamp = time(); + } + + /* Is there a timezone configured in the gosa configuration (gosa.conf) */ + if(isset($config->current['TIMEZONE']) || isset($config->data['MAIN']['TIMEZONE'])){ + + /* Get zonename */ + if(isset($config->current['TIMEZONE'])){ + $tz = $config->current['TIMEZONE']; + }else{ + $tz = $config->data['MAIN']['TIMEZONE']; + } + + if(!@date_default_timezone_set($tz)){ + print_red(sprintf(_("The timezone setting \"".$tz."\" in your gosa.conf is not valid. Can not calculate correct timezone offest."),$tz)); + } + $tz_delta = date("Z", $stamp); + $tz_delta = $tz_delta / 3600 ; + return(array("name" => $tz, "value" => $tz_delta)); + + } + return($zone); +} + + +/* Return zone informations */ +function _get_tz_zones() +{ + $timezones = array( + 'Africa/Abidjan' => 0, + 'Africa/Accra' => 0, + 'Africa/Addis_Ababa' => 10800, + 'Africa/Algiers' => 3600, + 'Africa/Asmera' => 10800, + 'Africa/Bamako' => 0, + 'Africa/Bangui' => 3600, + 'Africa/Banjul' => 0, + 'Africa/Bissau' => 0, + 'Africa/Blantyre' => 7200, + 'Africa/Brazzaville' => 3600, + 'Africa/Bujumbura' => 7200, + 'Africa/Cairo' => 7200, + 'Africa/Casablanca' => 0, + 'Africa/Ceuta' => 3600, + 'Africa/Conakry' => 0, + 'Africa/Dakar' => 0, + 'Africa/Dar_es_Salaam' => 10800, + 'Africa/Djibouti' => 10800, + 'Africa/Douala' => 3600, + 'Africa/El_Aaiun' => 0, + 'Africa/Freetown' => 0, + 'Africa/Gaborone' => 7200, + 'Africa/Harare' => 7200, + 'Africa/Johannesburg' => 7200, + 'Africa/Kampala' => 10800, + 'Africa/Khartoum' => 10800, + 'Africa/Kigali' => 7200, + 'Africa/Kinshasa' => 3600, + 'Africa/Lagos' => 3600, + 'Africa/Libreville' => 3600, + 'Africa/Lome' => 0, + 'Africa/Luanda' => 3600, + 'Africa/Lubumbashi' => 7200, + 'Africa/Lusaka' => 7200, + 'Africa/Malabo' => 3600, + 'Africa/Maputo' => 7200, + 'Africa/Maseru' => 7200, + 'Africa/Mbabane' => 7200, + 'Africa/Mogadishu' => 10800, + 'Africa/Monrovia' => 0, + 'Africa/Nairobi' => 10800, + 'Africa/Ndjamena' => 3600, + 'Africa/Niamey' => 3600, + 'Africa/Nouakchott' => 0, + 'Africa/Ouagadougou' => 0, + 'Africa/Porto-Novo' => 3600, + 'Africa/Sao_Tome' => 0, + 'Africa/Timbuktu' => 0, + 'Africa/Tripoli' => 7200, + 'Africa/Tunis' => 3600, + 'Africa/Windhoek' => 3600, + 'America/Adak' => -36000, + 'America/Anchorage' => -32400, + 'America/Anguilla' => -14400, + 'America/Antigua' => -14400, + 'America/Araguaina' => -10800, + 'America/Argentina/Buenos_Aires' => 0, + 'America/Argentina/Catamarca' => 0, + 'America/Argentina/ComodRivadavia' => 0, + 'America/Argentina/Cordoba' => 0, + 'America/Argentina/Jujuy' => 0, + 'America/Argentina/La_Rioja' => 0, + 'America/Argentina/Mendoza' => 0, + 'America/Argentina/Rio_Gallegos' => 0, + 'America/Argentina/San_Juan' => 0, + 'America/Argentina/Tucuman' => 0, + 'America/Argentina/Ushuaia' => 0, + 'America/Aruba' => -14400, + 'America/Asuncion' => -14400, + 'America/Atikokan' => 0, + 'America/Atka' => -36000, + 'America/Bahia' => 0, + 'America/Barbados' => -14400, + 'America/Belem' => -10800, + 'America/Belize' => -21600, + 'America/Blanc-Sablon' => 0, + 'America/Boa_Vista' => -14400, + 'America/Bogota' => -18000, + 'America/Boise' => -25200, + 'America/Buenos_Aires' => -10800, + 'America/Cambridge_Bay' => -25200, + 'America/Campo_Grande' => 0, + 'America/Cancun' => -21600, + 'America/Caracas' => -14400, + 'America/Catamarca' => -10800, + 'America/Cayenne' => -10800, + 'America/Cayman' => -18000, + 'America/Chicago' => -21600, + 'America/Chihuahua' => -25200, + 'America/Coral_Harbour' => 0, + 'America/Cordoba' => -10800, + 'America/Costa_Rica' => -21600, + 'America/Cuiaba' => -14400, + 'America/Curacao' => -14400, + 'America/Danmarkshavn' => 0, + 'America/Dawson' => -28800, + 'America/Dawson_Creek' => -25200, + 'America/Denver' => -25200, + 'America/Detroit' => -18000, + 'America/Dominica' => -14400, + 'America/Edmonton' => -25200, + 'America/Eirunepe' => -18000, + 'America/El_Salvador' => -21600, + 'America/Ensenada' => -28800, + 'America/Fort_Wayne' => -18000, + 'America/Fortaleza' => -10800, + 'America/Glace_Bay' => -14400, + 'America/Godthab' => -10800, + 'America/Goose_Bay' => -14400, + 'America/Grand_Turk' => -18000, + 'America/Grenada' => -14400, + 'America/Guadeloupe' => -14400, + 'America/Guatemala' => -21600, + 'America/Guayaquil' => -18000, + 'America/Guyana' => -14400, + 'America/Halifax' => -14400, + 'America/Havana' => -18000, + 'America/Hermosillo' => -25200, + 'America/Indiana/Indianapolis' => -18000, + 'America/Indiana/Knox' => -18000, + 'America/Indiana/Marengo' => -18000, + 'America/Indiana/Petersburg' => 0, + 'America/Indiana/Vevay' => -18000, + 'America/Indiana/Vincennes' => 0, + 'America/Indianapolis' => -18000, + 'America/Inuvik' => -25200, + 'America/Iqaluit' => -18000, + 'America/Jamaica' => -18000, + 'America/Jujuy' => -10800, + 'America/Juneau' => -32400, + 'America/Kentucky/Louisville' => -18000, + 'America/Kentucky/Monticello' => -18000, + 'America/Knox_IN' => -18000, + 'America/La_Paz' => -14400, + 'America/Lima' => -18000, + 'America/Los_Angeles' => -28800, + 'America/Louisville' => -18000, + 'America/Maceio' => -10800, + 'America/Managua' => -21600, + 'America/Manaus' => -14400, + 'America/Martinique' => -14400, + 'America/Mazatlan' => -25200, + 'America/Mendoza' => -10800, + 'America/Menominee' => -21600, + 'America/Merida' => -21600, + 'America/Mexico_City' => -21600, + 'America/Miquelon' => -10800, + 'America/Moncton' => 0, + 'America/Monterrey' => -21600, + 'America/Montevideo' => -10800, + 'America/Montreal' => -18000, + 'America/Montserrat' => -14400, + 'America/Nassau' => -18000, + 'America/New_York' => -18000, + 'America/Nipigon' => -18000, + 'America/Nome' => -32400, + 'America/Noronha' => -7200, + 'America/North_Dakota/Center' => -21600, + 'America/North_Dakota/New_Salem' => 0, + 'America/Panama' => -18000, + 'America/Pangnirtung' => -18000, + 'America/Paramaribo' => -10800, + 'America/Phoenix' => -25200, + 'America/Port-au-Prince' => -18000, + 'America/Port_of_Spain' => -14400, + 'America/Porto_Acre' => -18000, + 'America/Porto_Velho' => -14400, + 'America/Puerto_Rico' => -14400, + 'America/Rainy_River' => -21600, + 'America/Rankin_Inlet' => -21600, + 'America/Recife' => -10800, + 'America/Regina' => -21600, + 'America/Rio_Branco' => -18000, + 'America/Rosario' => -10800, + 'America/Santiago' => -14400, + 'America/Santo_Domingo' => -14400, + 'America/Sao_Paulo' => -10800, + 'America/Scoresbysund' => -3600, + 'America/Shiprock' => -25200, + 'America/St_Johns' => -12600, + 'America/St_Kitts' => -14400, + 'America/St_Lucia' => -14400, + 'America/St_Thomas' => -14400, + 'America/St_Vincent' => -14400, + 'America/Swift_Current' => -21600, + 'America/Tegucigalpa' => -21600, + 'America/Thule' => -14400, + 'America/Thunder_Bay' => -18000, + 'America/Tijuana' => -28800, + 'America/Toronto' => 0, + 'America/Tortola' => -14400, + 'America/Vancouver' => -28800, + 'America/Virgin' => -14400, + 'America/Whitehorse' => -28800, + 'America/Winnipeg' => -21600, + 'America/Yakutat' => -32400, + 'America/Yellowknife' => -25200, + 'Antarctica/Casey' => 28800, + 'Antarctica/Davis' => 25200, + 'Antarctica/DumontDUrville' => 36000, + 'Antarctica/Mawson' => 21600, + 'Antarctica/McMurdo' => 43200, + 'Antarctica/Palmer' => -14400, + 'Antarctica/Rothera' => 0, + 'Antarctica/South_Pole' => 43200, + 'Antarctica/Syowa' => 10800, + 'Antarctica/VostokArctic/Longyearbyen' => 0, + 'Asia/Aden' => 10800, + 'Asia/Almaty' => 21600, + 'Asia/Amman' => 7200, + 'Asia/Anadyr' => 43200, + 'Asia/Aqtau' => 14400, + 'Asia/Aqtobe' => 18000, + 'Asia/Ashgabat' => 18000, + 'Asia/Ashkhabad' => 18000, + 'Asia/Baghdad' => 10800, + 'Asia/Bahrain' => 10800, + 'Asia/Baku' => 14400, + 'Asia/Bangkok' => 25200, + 'Asia/Beirut' => 7200, + 'Asia/Bishkek' => 18000, + 'Asia/Brunei' => 28800, + 'Asia/Calcutta' => 19800, + 'Asia/Choibalsan' => 32400, + 'Asia/Chongqing' => 28800, + 'Asia/Chungking' => 28800, + 'Asia/Colombo' => 21600, + 'Asia/Dacca' => 21600, + 'Asia/Damascus' => 7200, + 'Asia/Dhaka' => 21600, + 'Asia/Dili' => 32400, + 'Asia/Dubai' => 14400, + 'Asia/Dushanbe' => 18000, + 'Asia/Gaza' => 7200, + 'Asia/Harbin' => 28800, + 'Asia/Hong_Kong' => 28800, + 'Asia/Hovd' => 25200, + 'Asia/Irkutsk' => 28800, + 'Asia/Istanbul' => 7200, + 'Asia/Jakarta' => 25200, + 'Asia/Jayapura' => 32400, + 'Asia/Jerusalem' => 7200, + 'Asia/Kabul' => 16200, + 'Asia/Kamchatka' => 43200, + 'Asia/Karachi' => 18000, + 'Asia/Kashgar' => 28800, + 'Asia/Katmandu' => 20700, + 'Asia/Krasnoyarsk' => 25200, + 'Asia/Kuala_Lumpur' => 28800, + 'Asia/Kuching' => 28800, + 'Asia/Kuwait' => 10800, + 'Asia/Macao' => 28800, + 'Asia/Macau' => 0, + 'Asia/Magadan' => 39600, + 'Asia/Makassar' => 0, + 'Asia/Manila' => 28800, + 'Asia/Muscat' => 14400, + 'Asia/Nicosia' => 7200, + 'Asia/Novosibirsk' => 21600, + 'Asia/Omsk' => 21600, + 'Asia/Oral' => 0, + 'Asia/Phnom_Penh' => 25200, + 'Asia/Pontianak' => 25200, + 'Asia/Pyongyang' => 32400, + 'Asia/Qatar' => 10800, + 'Asia/Qyzylorda' => 0, + 'Asia/Rangoon' => 23400, + 'Asia/Riyadh' => 10800, + 'Asia/Saigon' => 25200, + 'Asia/Sakhalin' => 36000, + 'Asia/Samarkand' => 18000, + 'Asia/Seoul' => 32400, + 'Asia/Shanghai' => 28800, + 'Asia/Singapore' => 28800, + 'Asia/Taipei' => 28800, + 'Asia/Tashkent' => 18000, + 'Asia/Tbilisi' => 14400, + 'Asia/Tehran' => 12600, + 'Asia/Tel_Aviv' => 7200, + 'Asia/Thimbu' => 21600, + 'Asia/Thimphu' => 21600, + 'Asia/Tokyo' => 32400, + 'Asia/Ujung_Pandang' => 28800, + 'Asia/Ulaanbaatar' => 28800, + 'Asia/Ulan_Bator' => 28800, + 'Asia/Urumqi' => 28800, + 'Asia/Vientiane' => 25200, + 'Asia/Vladivostok' => 36000, + 'Asia/Yakutsk' => 32400, + 'Asia/Yekaterinburg' => 18000, + 'Asia/YerevanAtlantic/Azores' => 0, + 'Atlantic/Bermuda' => -14400, + 'Atlantic/Canary' => 0, + 'Atlantic/Cape_Verde' => -3600, + 'Atlantic/Faeroe' => 0, + 'Atlantic/Jan_Mayen' => 3600, + 'Atlantic/Madeira' => 0, + 'Atlantic/Reykjavik' => 0, + 'Atlantic/South_Georgia' => -7200, + 'Atlantic/St_Helena' => 0, + 'Atlantic/Stanley' => -14400, + 'Australia/ACT' => 36000, + 'Australia/Adelaide' => 34200, + 'Australia/Brisbane' => 36000, + 'Australia/Broken_Hill' => 34200, + 'Australia/Canberra' => 36000, + 'Australia/Currie' => 0, + 'Australia/Darwin' => 34200, + 'Australia/Hobart' => 36000, + 'Australia/LHI' => 37800, + 'Australia/Lindeman' => 36000, + 'Australia/Lord_Howe' => 37800, + 'Australia/Melbourne' => 36000, + 'Australia/NSW' => 36000, + 'Australia/North' => 34200, + 'Australia/Perth' => 28800, + 'Australia/Queensland' => 36000, + 'Australia/South' => 34200, + 'Australia/Sydney' => 36000, + 'Australia/Tasmania' => 36000, + 'Australia/Victoria' => 36000, + 'Australia/West' => 28800, + 'Australia/Yancowinna' => 34200, + 'Europe/Amsterdam' => 3600, + 'Europe/Andorra' => 3600, + 'Europe/Athens' => 7200, + 'Europe/Belfast' => 0, + 'Europe/Belgrade' => 3600, + 'Europe/Berlin' => 3600, + 'Europe/Bratislava' => 3600, + 'Europe/Brussels' => 3600, + 'Europe/Bucharest' => 7200, + 'Europe/Budapest' => 3600, + 'Europe/Chisinau' => 7200, + 'Europe/Copenhagen' => 3600, + 'Europe/Dublin' => 0, + 'Europe/Gibraltar' => 3600, + 'Europe/Guernsey' => 0, + 'Europe/Helsinki' => 7200, + 'Europe/Isle_of_Man' => 0, + 'Europe/Istanbul' => 7200, + 'Europe/Jersey' => 0, + 'Europe/Kaliningrad' => 7200, + 'Europe/Kiev' => 7200, + 'Europe/Lisbon' => 0, + 'Europe/Ljubljana' => 3600, + 'Europe/London' => 0, + 'Europe/Luxembourg' => 3600, + 'Europe/Madrid' => 3600, + 'Europe/Malta' => 3600, + 'Europe/Mariehamn' => 0, + 'Europe/Minsk' => 7200, + 'Europe/Monaco' => 3600, + 'Europe/Moscow' => 10800, + 'Europe/Nicosia' => 7200, + 'Europe/Oslo' => 3600, + 'Europe/Paris' => 3600, + 'Europe/Prague' => 3600, + 'Europe/Riga' => 7200, + 'Europe/Rome' => 3600, + 'Europe/Samara' => 14400, + 'Europe/San_Marino' => 3600, + 'Europe/Sarajevo' => 3600, + 'Europe/Simferopol' => 7200, + 'Europe/Skopje' => 3600, + 'Europe/Sofia' => 7200, + 'Europe/Stockholm' => 3600, + 'Europe/Tallinn' => 7200, + 'Europe/Tirane' => 3600, + 'Europe/Tiraspol' => 7200, + 'Europe/Uzhgorod' => 7200, + 'Europe/Vaduz' => 3600, + 'Europe/Vatican' => 3600, + 'Europe/Vienna' => 3600, + 'Europe/Vilnius' => 7200, + 'Europe/Volgograd' => 0, + 'Europe/Warsaw' => 3600, + 'Europe/Zagreb' => 3600, + 'Europe/Zaporozhye' => 7200, + 'Europe/Zurich' => 3600, + 'Indian/Antananarivo' => 10800, + 'Indian/Chagos' => 21600, + 'Indian/Christmas' => 25200, + 'Indian/Cocos' => 23400, + 'Indian/Comoro' => 10800, + 'Indian/Kerguelen' => 18000, + 'Indian/Mahe' => 14400, + 'Indian/Maldives' => 18000, + 'Indian/Mauritius' => 14400, + 'Indian/Mayotte' => 10800, + 'Indian/Reunion' => 14400, + 'Pacific/Apia' => -39600, + 'Pacific/Auckland' => 43200, + 'Pacific/Chatham' => 45900, + 'Pacific/Easter' => -21600, + 'Pacific/Efate' => 39600, + 'Pacific/Enderbury' => 46800, + 'Pacific/Fakaofo' => -36000, + 'Pacific/Fiji' => 43200, + 'Pacific/Funafuti' => 43200, + 'Pacific/Galapagos' => -21600, + 'Pacific/Gambier' => -32400, + 'Pacific/Guadalcanal' => 39600, + 'Pacific/Guam' => 36000, + 'Pacific/Honolulu' => -36000, + 'Pacific/Johnston' => -36000, + 'Pacific/Kiritimati' => 50400, + 'Pacific/Kosrae' => 39600, + 'Pacific/Kwajalein' => 43200, + 'Pacific/Majuro' => 43200, + 'Pacific/Marquesas' => -34200, + 'Pacific/Midway' => -39600, + 'Pacific/Nauru' => 43200, + 'Pacific/Niue' => -39600, + 'Pacific/Norfolk' => 41400, + 'Pacific/Noumea' => 39600, + 'Pacific/Pago_Pago' => -39600, + 'Pacific/Palau' => 32400, + 'Pacific/Pitcairn' => -28800, + 'Pacific/Ponape' => 39600, + 'Pacific/Port_Moresby' => 36000, + 'Pacific/Rarotonga' => -36000, + 'Pacific/Saipan' => 36000, + 'Pacific/Samoa' => -39600, + 'Pacific/Tahiti' => -36000, + 'Pacific/Tarawa' => 43200, + 'Pacific/Tongatapu' => 46800, + 'Pacific/Truk' => 36000, + 'Pacific/Wake' => 43200, + 'Pacific/Wallis' => 43200, + 'Pacific/Yap' => 36000 ); + + $dst_timezones = array ( + 'America/Adak' => 1, + 'America/Atka' => 1, + 'America/Anchorage' => 1, + 'America/Juneau' => 1, + 'America/Nome' => 1, + 'America/Yakutat' => 1, + 'America/Dawson' => 1, + 'America/Ensenada' => 1, + 'America/Los_Angeles' => 1, + 'America/Tijuana' => 1, + 'America/Vancouver' => 1, + 'America/Whitehorse' => 1, + 'America/Boise' => 1, + 'America/Cambridge_Bay' => 1, + 'America/Chihuahua' => 1, + 'America/Denver' => 1, + 'America/Edmonton' => 1, + 'America/Inuvik' => 1, + 'America/Mazatlan' => 1, + 'America/Shiprock' => 1, + 'America/Yellowknife' => 1, + 'America/Cancun' => 1, + 'America/Chicago' => 1, + 'America/Menominee' => 1, + 'America/Merida' => 1, + 'America/Monterrey' => 1, + 'America/North_Dakota/Center' => 1, + 'America/Rainy_River' => 1, + 'America/Rankin_Inlet' => 1, + 'America/Winnipeg' => 1, + 'Pacific/Easter' => 1, + 'America/Detroit' => 1, + 'America/Grand_Turk' => 1, + 'America/Havana' => 1, + 'America/Iqaluit' => 1, + 'America/Kentucky/Louisville' => 1, + 'America/Kentucky/Monticello' => 1, + 'America/Louisville' => 1, + 'America/Montreal' => 1, + 'America/Nassau' => 1, + 'America/New_York' => 1, + 'America/Nipigon' => 1, + 'America/Pangnirtung' => 1, + 'America/Thunder_Bay' => 1, + 'America/Asuncion' => 1, + 'America/Cuiaba' => 1, + 'America/Glace_Bay' => 1, + 'America/Goose_Bay' => 1, + 'America/Halifax' => 1, + 'America/Santiago' => 1, + 'Antarctica/Palmer' => 1, + 'Atlantic/Bermuda' => 1, + 'Atlantic/Stanley' => 1, + 'America/St_Johns' => 1, + 'America/Araguaina' => 1, + 'America/Fortaleza' => 1, + 'America/Godthab' => 1, + 'America/Maceio' => 1, + 'America/Miquelon' => 1, + 'America/Recife' => 1, + 'America/Sao_Paulo' => 1, + 'America/Scoresbysund' => 1, + 'Atlantic/Canary' => 1, + 'Atlantic/Faeroe' => 1, + 'Atlantic/Madeira' => 1, + 'Europe/Belfast' => 1, + 'Europe/Dublin' => 1, + 'Europe/Lisbon' => 1, + 'Europe/London' => 1, + 'Africa/Ceuta' => 1, + 'Africa/Windhoek' => 1, + 'Atlantic/Jan_Mayen' => 1, + 'Europe/Amsterdam' => 1, + 'Europe/Andorra' => 1, + 'Europe/Belgrade' => 1, + 'Europe/Berlin' => 1, + 'Europe/Bratislava' => 1, + 'Europe/Brussels' => 1, + 'Europe/Budapest' => 1, + 'Europe/Copenhagen' => 1, + 'Europe/Gibraltar' => 1, + 'Europe/Ljubljana' => 1, + 'Europe/Luxembourg' => 1, + 'Europe/Madrid' => 1, + 'Europe/Malta' => 1, + 'Europe/Monaco' => 1, + 'Europe/Oslo' => 1, + 'Europe/Paris' => 1, + 'Europe/Prague' => 1, + 'Europe/Rome' => 1, + 'Europe/San_Marino' => 1, + 'Europe/Sarajevo' => 1, + 'Europe/Skopje' => 1, + 'Europe/Stockholm' => 1, + 'Europe/Tirane' => 1, + 'Europe/Vaduz' => 1, + 'Europe/Vatican' => 1, + 'Europe/Vienna' => 1, + 'Europe/Warsaw' => 1, + 'Europe/Zagreb' => 1, + 'Europe/Zurich' => 1, + 'Africa/Cairo' => 1, + 'Asia/Amman' => 1, + 'Asia/Beirut' => 1, + 'Asia/Damascus' => 1, + 'Asia/Gaza' => 1, + 'Asia/Istanbul' => 1, + 'Asia/Jerusalem' => 1, + 'Asia/Nicosia' => 1, + 'Asia/Tel_Aviv' => 1, + 'Europe/Athens' => 1, + 'Europe/Bucharest' => 1, + 'Europe/Chisinau' => 1, + 'Europe/Helsinki' => 1, + 'Europe/Istanbul' => 1, + 'Europe/Kaliningrad' => 1, + 'Europe/Kiev' => 1, + 'Europe/Minsk' => 1, + 'Europe/Nicosia' => 1, + 'Europe/Riga' => 1, + 'Europe/Simferopol' => 1, + 'Europe/Sofia' => 1, + 'Europe/Tiraspol' => 1, + 'Europe/Uzhgorod' => 1, + 'Europe/Zaporozhye' => 1, + 'Asia/Baghdad' => 1, + 'Europe/Moscow' => 1, + 'Asia/Tehran' => 1, + 'Asia/Aqtau' => 1, + 'Asia/Baku' => 1, + 'Asia/Tbilisi' => 1, + 'Europe/Samara' => 1, + 'Asia/Aqtobe' => 1, + 'Asia/Bishkek' => 1, + 'Asia/Yekaterinburg' => 1, + 'Asia/Almaty' => 1, + 'Asia/Novosibirsk' => 1, + 'Asia/Omsk' => 1, + 'Asia/Krasnoyarsk' => 1, + 'Asia/Irkutsk' => 1, + 'Asia/Yakutsk' => 1, + 'Australia/Adelaide' => 1, + 'Australia/Broken_Hill' => 1, + 'Australia/South' => 1, + 'Australia/Yancowinna' => 1, + 'Asia/Sakhalin' => 1, + 'Asia/Vladivostok' => 1, + 'Australia/ACT' => 1, + 'Australia/Canberra' => 1, + 'Australia/Hobart' => 1, + 'Australia/Melbourne' => 1, + 'Australia/NSW' => 1, + 'Australia/Sydney' => 1, + 'Australia/Tasmania' => 1, + 'Australia/Victoria' => 1, + 'Australia/LHI' => 1, + 'Australia/Lord_Howe' => 1, + 'Asia/Magadan' => 1, + 'Antarctica/McMurdo' => 1, + 'Antarctica/South_Pole' => 1, + 'Asia/Anadyr' => 1, + 'Asia/Kamchatka' => 1, + 'Pacific/Auckland' => 1, + 'Pacific/Chatham' => 1, + ); + return(array("TIMEZONES" => $timezones, "DST_ZONES" => $dst_timezones)); +} // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: ?>