X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-core%2Finclude%2Ffunctions.inc;h=677ebb193c86fbe16d749bfa387c3804ab54980c;hb=d304d276784b0675372dcdb402a61bfdd3f8488d;hp=87c667de61bfaab2ec2819d0d3f53ff136f86111;hpb=fc368de5c5710c5f67ba1b5ea104232cf432c65a;p=gosa.git diff --git a/gosa-core/include/functions.inc b/gosa-core/include/functions.inc index 87c667de6..677ebb193 100644 --- a/gosa-core/include/functions.inc +++ b/gosa-core/include/functions.inc @@ -1,7 +1,9 @@ "ae", /* Class autoloader */ function __autoload($class_name) { global $class_mapping, $BASE_DIR; + + if ($class_mapping === NULL){ + echo sprintf(_("Fatal error: no class locations defined - please run '%s' to fix this"), "update-gosa"); + exit; + } + if (isset($class_mapping[$class_name])){ require_once($BASE_DIR."/".$class_mapping[$class_name]); } else { - echo _("Fatal: cannot load class \"$class_name\" - execution aborted"); + echo sprintf(_("Fatal error: cannot instantiate class '%s' - try running '%s' to fix this"), $class_name, "update-gosa"); + exit; } } +/*! \brief Checks if a class is available. + * @param name String The class name. + * @return boolean True if class is available, else false. + */ +function class_available($name) +{ + global $class_mapping; + return(isset($class_mapping[$name])); +} + + +/* Check if plugin is avaliable */ +function plugin_available($plugin) +{ + global $class_mapping, $BASE_DIR; + + if (!isset($class_mapping[$plugin])){ + return false; + } else { + return is_readable($BASE_DIR."/".$class_mapping[$plugin]); + } +} + + /* Create seed with microseconds */ function make_seed() { list($usec, $sec) = explode(' ', microtime()); @@ -335,7 +368,7 @@ function ldap_login_user_htaccess ($username) /* Look for entry or realm */ $ldap= $config->get_ldap_link(); if (!preg_match("/Success/i", $ldap->error)){ - msg_dialog::display(_("LDAP error"), sprintf(_('User login failed.').'

'._('LDAP server returned: %s'), "

".$ldap->get_error().""), ERROR_DIALOG); + msg_dialog::display(_("LDAP error"), sprintf(_('User login failed.').'

'._('LDAP server returned: %s'), "

".$ldap->get_error().""), FATAL_ERROR_DIALOG); $smarty= get_smarty(); $smarty->display(get_template_path('headers.tpl')); echo "".session::get('errors').""; @@ -344,7 +377,7 @@ function ldap_login_user_htaccess ($username) $ldap->search("(&(objectClass=gosaAccount)(uid=$username))", array("uid")); /* Found no uniq match? Strange, because we did above... */ if ($ldap->count() != 1) { - msg_dialog::display(_("LDAP error"), _("Username / UID is not unique inside the LDAP tree. Please contact your Administrator."), ERROR_DIALOG); + msg_dialog::display(_("LDAP error"), _("Username / UID is not unique inside the LDAP tree. Please contact your Administrator."), FATAL_ERROR_DIALOG); return (NULL); } $attrs= $ldap->fetch(); @@ -373,7 +406,7 @@ function ldap_login_user ($username, $password) /* look through the entire ldap */ $ldap = $config->get_ldap_link(); if (!preg_match("/Success/i", $ldap->error)){ - msg_dialog::display(_("LDAP error"), sprintf(_("User login failed.")."

"._('LDAP server returned: %s'), "

".$ldap->get_error().""), ERROR_DIALOG); + msg_dialog::display(_("LDAP error"), sprintf(_("User login failed.")."

"._('LDAP server returned: %s'), "

".$ldap->get_error().""), FATAL_ERROR_DIALOG); $smarty= get_smarty(); $smarty->display(get_template_path('headers.tpl')); echo "".session::get('errors').""; @@ -414,7 +447,7 @@ function ldap_login_user ($username, $password) /* found more than one matching id */ default: - msg_dialog::display(_("Internal error"), _("Username / UID is not unique inside the LDAP tree. Please contact your Administrator."), ERROR_DIALOG); + msg_dialog::display(_("Internal error"), _("Username / UID is not unique inside the LDAP tree. Please contact your Administrator."), FATAL_ERROR_DIALOG); return (NULL); } @@ -715,43 +748,100 @@ function get_multiple_locks($objects) /* \!brief This function searches the ldap database. - It search in $sub_base,*,$base for all objects matching the $filter. + It search in $sub_bases,*,$base for all objects matching the $filter. @param $filter String The ldap search filter @param $category String The ACL category the result objects belongs - @param $sub_base String The sub base we want to search for e.g. "ou=apps" + @param $sub_bases String The sub base we want to search for e.g. "ou=apps" @param $base String The ldap base from which we start the search @param $attributes Array The attributes we search for. @param $flags Long A set of Flags */ -function get_sub_list($filter, $category,$sub_base, $base= "", $attributes= array(), $flags= GL_SUBSEARCH) +function get_sub_list($filter, $category,$sub_deps, $base= "", $attributes= array(), $flags= GL_SUBSEARCH) { - global $config, $ui; + $departments = array(); + +# $start = microtime(TRUE); /* Get LDAP link */ $ldap= $config->get_ldap_link($flags & GL_SIZELIMIT); /* Set search base to configured base if $base is empty */ if ($base == ""){ - $ldap->cd ($config->current['BASE']); - } else { - $ldap->cd ($base); + $base = $config->current['BASE']; + } + $ldap->cd ($base); + + /* Ensure we have an array as department list */ + if(is_string($sub_deps)){ + $sub_deps = array($sub_deps); } - /* Remove , ("ou=1,ou=2.." => "ou=1") */ - $sub_base = preg_replace("/,.*$/","",$sub_base); + /* Remove ,.*$ ("ou=1,ou=2.." => "ou=1") */ + $sub_bases = array(); + foreach($sub_deps as $key => $sub_base){ + if(empty($sub_base)){ - /* Check if there is a sub department specified */ - if($sub_base == ""){ - return(get_list($filter, $category,$base,$attributes,$flags)); + /* Subsearch is activated and we got an empty sub_base. + * (This may be the case if you have empty people/group ous). + * Fall back to old get_list(). + * A log entry will be written. + */ + if($flags & GL_SUBSEARCH){ + $sub_bases = array(); + break; + }else{ + + /* Do NOT search within subtrees is requeste and the sub base is empty. + * Append all known departments that matches the base. + */ + $departments[$base] = $base; + } + }else{ + $sub_bases[$key] = preg_replace("/,.*$/","",$sub_base); + } + } + + /* If there is no sub_department specified, fall back to old method, get_list(). + */ + if(!count($sub_bases) && !count($departments)){ + + /* Log this fall back, it may be an unpredicted behaviour. + */ + if(!count($sub_bases) && !count($departments)){ + // log($action,$objecttype,$object,$changes_array = array(),$result = "") + new log("debug","all",__FILE__,$attributes, + sprintf("get_sub_list(): Falling back to get_list(), due to empty sub_bases parameter.". + " This may slow down GOsa. Search was: '%s'",$filter)); + } + $tmp = get_list($filter, $category,$base,$attributes,$flags); + return($tmp); } - /* Get all deparments matching the given sub_base */ - $departments = array(); - $ldap->search($sub_base,array("dn")); + /* Get all deparments matching the given sub_bases */ + $base_filter= ""; + foreach($sub_bases as $sub_base){ + $base_filter .= "(".$sub_base.")"; + } + $base_filter = "(&(objectClass=organizationalUnit)(|".$base_filter."))"; + $ldap->search($base_filter,array("dn")); while($attrs = $ldap->fetch()){ - $departments[$attrs['dn']] = $attrs['dn']; + foreach($sub_deps as $sub_dep){ + + /* Only add those departments that match the reuested list of departments. + * + * e.g. sub_deps = array("ou=servers,ou=systems,"); + * + * In this case we have search for "ou=servers" and we may have also fetched + * departments like this "ou=servers,ou=blafasel,..." + * Here we filter out those blafasel departments. + */ + if(preg_match("/".normalizePreg($sub_dep)."/",$attrs['dn'])){ + $departments[$attrs['dn']] = $attrs['dn']; + break; + } + } } $result= array(); @@ -771,7 +861,7 @@ function get_sub_list($filter, $category,$sub_base, $base= "", $attributes= arra if ($flags & GL_SUBSEARCH) { $ldap->search ($filter, $attributes); } else { - $ldap->ls ($filter,$base,$attributes); + $ldap->ls ($filter,$dep,$attributes); } /* Check for size limit exceeded messages for GUI feedback */ @@ -792,21 +882,30 @@ function get_sub_list($filter, $category,$sub_base, $base= "", $attributes= arra $attrs["dn"]= $dn; } - /* Sort in every value that fits the permissions */ - if (is_array($category)){ - foreach ($category as $o){ - if ($ui->get_category_permissions($dn, $o) != ""){ + /* Skip ACL checks if we are forced to skip those checks */ + if($flags & GL_NO_ACL_CHECK){ + $result[]= $attrs; + }else{ + + /* Sort in every value that fits the permissions */ + if (is_array($category)){ + foreach ($category as $o){ + if ($ui->get_category_permissions($dn, $o) != ""){ + $result[]= $attrs; + break; + } + } + } else { + if ( $ui->get_category_permissions($dn, $category) != ""){ $result[]= $attrs; - break; } } - } else { - if ($ui->get_category_permissions($dn, $category) != ""){ - $result[]= $attrs; - } } } } +# if(microtime(TRUE) - $start > 0.1){ +# echo sprintf("
GET_SUB_LIST  %s .| %f  --- $base -----$filter ---- $flags
",__LINE__,microtime(TRUE) - $start); +# } return($result); } @@ -815,6 +914,8 @@ function get_list($filter, $category, $base= "", $attributes= array(), $flags= G { global $config, $ui; +# $start = microtime(TRUE); + /* Get LDAP link */ $ldap= $config->get_ldap_link($flags & GL_SIZELIMIT); @@ -842,36 +943,42 @@ function get_list($filter, $category, $base= "", $attributes= array(), $flags= G $result= array(); while($attrs = $ldap->fetch()) { + $dn= $ldap->getDN(); - /* 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; + /* Convert dn into a printable format */ + if ($flags & GL_CONVERT){ + $attrs["dn"]= convert_department_dn($dn); + } else { + $attrs["dn"]= $dn; + } + + if($flags & GL_NO_ACL_CHECK){ + $result[]= $attrs; + }else{ + + /* Sort in every value that fits the permissions */ + if (is_array($category)){ + foreach ($category as $o){ + if ($ui->get_category_permissions($dn, $o) != ""){ + + /* We found what we were looking for, break speeds things up */ + $result[]= $attrs; } + } + } else { + if ($ui->get_category_permissions($dn, $category) != ""){ /* 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 { - $attrs["dn"]= $dn; - } - - /* We found what we were looking for, break speeds things up */ - $result[]= $attrs; - } } } - + +# if(microtime(TRUE) - $start > 0.1){ +# echo sprintf("
GET_LIST %s .| %f  --- $base -----$filter ---- $flags
",__LINE__,microtime(TRUE) - $start); +# } return ($result); } @@ -916,7 +1023,7 @@ function eval_sizelimit() if (isset($_POST['set_size_action'])){ /* User wants new size limit? */ - if (is_id($_POST['new_limit']) && + if (tests::is_id($_POST['new_limit']) && isset($_POST['action']) && $_POST['action']=="newlimit"){ session::set('size_limit', validate($_POST['new_limit'])); @@ -1017,7 +1124,9 @@ function get_ou($name) { global $config; - $map = array( "applicationou" => "ou=apps,", + $map = array( + "ogroupou" => "ou=groups,", + "applicationou" => "ou=apps,", "systemsou" => "ou=systems,", "serverou" => "ou=servers,ou=systems,", "terminalou" => "ou=terminals,ou=systems,", @@ -1101,42 +1210,6 @@ function get_base_from_people($dn) } -function is_phone_nr($nr) -{ - if ($nr == ""){ - return (TRUE); - } - - return preg_match ("/^[\/0-9 ()+*-]+$/", $nr); -} - - -function is_dns_name($str) -{ - return(preg_match("/^[a-z0-9\.\-]*$/i",$str)); -} - - -function is_url($url) -{ - if ($url == ""){ - return (TRUE); - } - - return preg_match ("/^(http|https):\/\/((?:[a-zA-Z0-9_-]+\.?)+):?(\d*)/", $url); -} - - -function is_dn($dn) -{ - if ($dn == ""){ - return (TRUE); - } - - return preg_match ("/^[a-z0-9 _-]+$/i", $dn); -} - - function strict_uid_mode() { return !(isset($config->current['STRICT']) && preg_match('/^(no|false)$/i', $config->current['STRICT'])); @@ -1155,122 +1228,6 @@ function get_uid_regexp() } -function is_uid($uid) -{ - global $config; - - if ($uid == ""){ - return (TRUE); - } - - /* STRICT adds spaces and case insenstivity to the uid check. - This is dangerous and should not be used. */ - if (strict_uid_mode()){ - return preg_match ("/^[a-z0-9_-]+$/", $uid); - } else { - return preg_match ("/^[a-z0-9 _.-]+$/i", $uid); - } -} - - -function is_ip($ip) -{ - return 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); -} - - -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 == ""){ - return (FALSE); - } - - return preg_match ("/^[0-9]+$/", $id); -} - - -function is_path($path) -{ - if ($path == ""){ - return (TRUE); - } - if (!preg_match('/^[a-z0-9%\/_.+-]+$/i', $path)){ - return (FALSE); - } - - return preg_match ("/\/.+$/", $path); -} - - -function is_email($address, $template= FALSE) -{ - if ($address == ""){ - return (TRUE); - } - if ($template){ - return preg_match ("/^[._a-z0-9%-]+@[_a-z0-9-]+(\.[a-z0-9-]+)(\.[a-z0-9-]+)*$/i", - $address); - } else { - return preg_match ("/^[._a-z0-9-]+@[_a-z0-9-]+(\.[a-z0-9i-]+)(\.[a-z0-9-]+)*$/i", - $address); - } -} - - function print_red() { trigger_error("Use of obsolete print_red"); @@ -1406,15 +1363,8 @@ function show_errors($message) /* Assemble the message array to a plain string */ foreach ($message as $error){ - if ($complete == ""){ - $complete= $error; - } else { - $complete= "$error
$complete"; - } + msg_dialog::display(_("Error"), $error, ERROR_DIALOG); } - - /* Fill ERROR variable with nice error dialog */ - msg_dialog::display(_("Error"), $complete, ERROR_DIALOG); } @@ -1425,7 +1375,7 @@ function show_ldap_error($message, $addon= "") msg_dialog::display(_("LDAP error:"), $message, ERROR_DIALOG); } else { if(!preg_match("/No such object/i",$message)){ - msg_dialog::display(sprintf(_("LDAP error in plugin '%s':"),"".$addon.""),$message,ERROR_DIALOG); + msg_dialog::display(_("LDAP error"), sprintf(_("Plugin '%s':%s"),"".$addon."", "

$message"),ERROR_DIALOG); } } return TRUE; @@ -2184,29 +2134,6 @@ function get_MicroTimeDiff($start , $stop) } -/* Check if the given department name is valid */ -function is_department_name_reserved($name,$base) -{ - $reservedName = array("systems","apps","incomming","internal","accounts","fax","addressbook", - preg_replace("/ou=(.*),/","\\1",get_people_ou()), - preg_replace("/ou=(.*),/","\\1",get_groups_ou())); - $follwedNames['/ou=fai,ou=configs,ou=systems,/'] = array("fai","hooks","templates","scripts","disk","packages","variables","profiles"); - - /* Check if name is one of the reserved names */ - if(in_array_ics($name,$reservedName)) { - return(true); - } - - /* Check all follow combinations if name is in array && parent base == array_key, return false*/ - foreach($follwedNames as $key => $names){ - if((in_array_ics($name,$names)) && (preg_match($key,$base))){ - return(true); - } - } - return(false); -} - - function get_base_dir() { global $BASE_DIR; @@ -2457,7 +2384,7 @@ function check_schema($cfg,$rfc2307bis = FALSE) } 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']['MSG'] = _("Your schema is configured to support the rfc2307bis group, but you have disabled this option on the 'ldap setup' step."); $checks['posixGroup']['INFO'] = _("The objectClass 'posixGroup' must be STRUCTURAL"); } } @@ -2534,46 +2461,6 @@ function get_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 */ function get_correct_class_name($cls) { @@ -2710,31 +2597,40 @@ function change_password ($dn, $password, $mode=0, $hash= "") 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); + # Try to use gosa-si? + if (isset($config->current['GOSA_SI'])){ + $res= gosaSupportDaemon::send("gosa_gen_smb_hash", "GOSA", array("password" => $password), TRUE); + $hash= $res['XML']['HASH']; + } else { + $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 == "") { - msg_dialog::display(_("Configuration error"), _("Setting for SMBHASH in gosa.conf is incorrect! Cannot change Samba password."), ERROR_DIALOG); + msg_dialog::display(_("Configuration error"), _("Cannot generate samba hash!"), ERROR_DIALOG); + return (""); + } + + 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 { - 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); + $attrs['lmPassword']= $lm; + $attrs['ntPassword']= $nt; + $attrs['pwdLastSet']= date('U'); } + return($attrs); } @@ -2769,11 +2665,66 @@ function getEntryCSN($dn) } -function display_error_page() +/* Add a given objectClass to an attrs entry */ +function add_objectClass($classes, &$attrs) { - $smarty= get_smarty(); - $smarty->display(get_template_path('headers.tpl')); - echo "".msg_dialog::get_dialogs().""; + if (is_array($classes)){ + $list= $classes; + } else { + $list= array($classes); + } + + foreach ($list as $class){ + $attrs['objectClass'][]= $class; + } +} + + +/* Removes a given objectClass from the attrs entry */ +function remove_objectClass($classes, &$attrs) +{ + if (isset($attrs['objectClass'])){ + /* Array? */ + if (is_array($classes)){ + $list= $classes; + } else { + $list= array($classes); + } + + $tmp= array(); + foreach ($attrs['objectClass'] as $oc) { + foreach ($list as $class){ + if ($oc != $class){ + $tmp[]= $oc; + } + } + } + $attrs['objectClass']= $tmp; + } +} + +/*! \brief Initialize a file download with given content, name and data type. + * @param data String The content to send. + * @param name String The name of the file. + * @param type String The content identifier, default value is "application/octet-stream"; + */ +function send_binary_content($data,$name,$type = "application/octet-stream") +{ + header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); + header("Last-Modified: ".gmdate("D, d M Y H:i:s")." GMT"); + header("Cache-Control: no-cache"); + header("Pragma: no-cache"); + header("Cache-Control: post-check=0, pre-check=0"); + header("Content-type: ".$type.""); + + /* force download dialog */ + if (preg_match('/MSIE 5.5/', $HTTP_USER_AGENT) || preg_match('/MSIE 6.0/', $HTTP_USER_AGENT)) { + header('Content-Disposition: filename="'.$name.'"'); + } else { + header('Content-Disposition: attachment; filename="'.$name.'"'); + } + + echo $data; exit(); }