2009-06-30 08:07:14 +00:00
< ? php
2009-06-30 09:22:30 +00:00
// $Header: /cvsroot/phpldapadmin/phpldapadmin/functions.php,v 1.224 2005/01/25 17:19:58 uugdave Exp $
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:07:14 +00:00
* A collection of functions used throughout phpLDAPadmin .
2009-06-30 09:22:30 +00:00
* @ author The phpLDAPadmin development team
* @ package phpLDAPadmin
*
* @ todo move functions that are only used by one script into said script ( if any )
*/
/**
* Determines if an attribute ' s value can contain multiple lines . Attributes that fall
* in this multi - line category may be configured in config . php . Hence , this function
* accesses the global variable $multi_line_attributes ;
*
* Usage example :
* < code >
* if ( is_muli_line_attr ( " postalAddress " ) )
* echo " <textarea name= \" postalAddress \" ></textarea> " ;
* else
* echo " <input name= \" postalAddress \" type= \" text \" > " ;
* </ code >
*
* @ param string $attr_name The name of the attribute of interestd ( case insensivite )
* @ param string $val ( optional ) The current value of the attribute ( speeds up the
* process by searching for carriage returns already in the attribute value )
* @ param int $server_id ( optional ) The ID of the server of interest . If specified ,
* is_multi_line_attr () will read the schema from the server to determine if
* the attr is multi - line capable . ( note that schema reads can be expensive ,
* but that impact is lessened due to PLA ' s new caching mechanism )
* @ return bool
*/
function is_multi_line_attr ( $attr_name , $val = null , $server_id = null )
{
// First, check the optional val param for a \n or a \r
if ( null != $val &&
( false !== strpos ( $val , " \n " ) ||
false !== strpos ( $val , " \r " ) ) )
return true ;
// Next, compare strictly by name first
global $multi_line_attributes ;
if ( isset ( $multi_line_attributes ) && is_array ( $multi_line_attributes ) )
foreach ( $multi_line_attributes as $multi_line_attr_name )
if ( 0 == strcasecmp ( $multi_line_attr_name , $attr_name ) )
return true ;
// If unfound, compare by syntax OID
if ( null !== $server_id ) {
global $multi_line_syntax_oids ;
if ( isset ( $multi_line_syntax_oids ) && is_array ( $multi_line_syntax_oids ) ) {
$schema_attr = get_schema_attribute ( $server_id , $attr_name );
if ( ! $schema_attr )
return false ;
$syntax_oid = $schema_attr -> getSyntaxOID ();
if ( ! $syntax_oid )
return false ;
foreach ( $multi_line_syntax_oids as $multi_line_syntax_oid )
if ( $multi_line_syntax_oid == $syntax_oid )
return true ;
}
}
return false ;
}
/**
* Fetches the user setting for $search_deref from config . php . The returned value
* will be one of the four LDAP_DEREF_ * constancts defined by the PHP LDAP API . If
* the user has failed to configure this setting or configured an inappropriate
* value , the constant DEFAULT_SEARCH_DEREF_SETTING is returned .
*
* @ see DEFAULT_SEARCH_DEREF_SETTING
* @ see is_valid_deref_setting ()
* @ return int
*/
function get_search_deref_setting ()
{
global $search_deref ;
if ( ! isset ( $search_deref ) || ! is_valid_deref_setting ( $search_deref ) )
return DEFAULT_SEARCH_DEREF_SETTING ;
else
return $search_deref ;
}
/**
* Fetches the user setting for $tree_deref from config . php . The returned value
* will be one of the four LDAP_DEREF_ * constancts defined by the PHP LDAP API . If
* the user has failed to configure this setting or configured an inappropriate
* value , the constant DEFAULT_TREE_DEREF_SETTING is returned .
*
* @ see DEFAULT_TREE_DEREF_SETTING
* @ see is_valid_deref_setting ()
* @ return int
*/
function get_tree_deref_setting ()
{
global $tree_deref ;
if ( ! isset ( $tree_deref ) || ! is_valid_deref_setting ( $tree_deref ) )
return DEFAULT_TREE_DEREF_SETTING ;
else
return $tree_deref ;
}
/**
* Fetches the user setting for $export_deref from config . php . The returned value
* will be one of the four LDAP_DEREF_ * constancts defined by the PHP LDAP API . If
* the user has failed to configure this setting or configured an inappropriate
* value , the constant DEFAULT_EXPORT_DEREF_SETTING is returned .
*
* @ see DEFAULT_EXPORT_DEREF_SETTING
* @ see is_valid_deref_setting ()
* @ return int
*/
function get_export_deref_setting ()
{
global $export_deref ;
if ( ! isset ( $export_deref ) || ! is_valid_deref_setting ( $export_deref ) )
return DEFAULT_EXPORT_DEREF_SETTING ;
else
return $export_deref ;
}
/**
* Fetches the user setting for $view_deref from config . php . The returned value
* will be one of the four LDAP_DEREF_ * constancts defined by the PHP LDAP API . If
* the user has failed to configure this setting or configured an inappropriate
* value , the constant DEFAULT_VIEW_DEREF_SETTING is returned .
*
* @ see DEFAULT_VIEW_DEREF_SETTING
* @ see is_valid_deref_setting ()
* @ return int
*/
function get_view_deref_setting ()
{
global $view_deref ;
if ( ! isset ( $view_deref ) || ! is_valid_deref_setting ( $view_deref ) )
return DEFAULT_VIEW_DEREF_SETTING ;
else
return $view_deref ;
}
/**
* Checks the user - configured parameter for sanity . For the various * _deref settings , users
* may only use one of LDAP_DEREF_NEVER , LDAP_DEREF_SEARCHING , LDAP_DEREF_FINDING , or
* LDAP_DEREF_ALWAYS . This function can be used to conveniently enforce this .
*
* @ param int $deref_setting The deref setting to validate .
* @ return bool
*/
function is_valid_deref_setting ( $deref_setting )
{
if ( $deref_setting == LDAP_DEREF_NEVER ||
$deref_setting == LDAP_DEREF_SEARCHING ||
$deref_setting == LDAP_DEREF_FINDING ||
$deref_setting == LDAP_DEREF_ALWAYS )
return true ;
else
return false ;
}
/**
* Fetch whether the user has configured a certain server as " low bandwidth " . Users may
* choose to configure a server as " low bandwidth " in config . php thus :
* < code >
* $servers [ $i ][ 'low_bandwidth' ] = true ;
* </ code >
* @ param int $server_id The ID of the server of interest from config . php .
* @ return bool
*/
function is_server_low_bandwidth ( $server_id )
{
global $servers ;
if ( isset ( $servers [ $server_id ][ 'low_bandwidth' ] ) && true == $servers [ $server_id ][ 'low_bandwidth' ] )
return true ;
else
return false ;
}
/**
* Fetch whether the user has configured a certain server login to be non anonymous
*
* < code >
* $servers [ $i ][ 'disable_anon_bind' ] = true ;
* </ code >
* @ param int $server_id The ID of the server of interest from config . php .
* @ return bool
*/
function is_anonymous_bind_allowed ( $server_id )
{
global $servers ;
return ( ! isset ( $servers [ $server_id ][ 'disable_anon_bind' ] )
|| false == $servers [ $server_id ][ 'disable_anon_bind' ] )
? true
: false ;
}
/**
* Fetches whether TLS has been configured for use with a certain server .
* Users may configure phpLDAPadmin to use TLS in config , php thus :
* < code >
* $servers [ $i ][ 'tls' ] = true ;
* </ code >
* @ param int $server_id The ID of the server of interest from config . php .
* @ return bool
*/
function tls_enabled ( $server_id )
{
global $servers ;
if ( isset ( $servers [ $server_id ][ 'tls' ] ) && true == $servers [ $server_id ][ 'tls' ] )
return true ;
else
return false ;
}
/**
* Fetches whether phpLDAPadmin has been configured to redirect anonymously bound users
* to a search form with no tree displayed .
* This is configured in config . php thus :
* < code >
* $anonymous_bind_redirect_no_tree = true ;
* </ code >
* @ return bool
*/
function anon_bind_tree_disabled ()
{
global $anonymous_bind_redirect_no_tree ;
if ( isset ( $anonymous_bind_redirect_no_tree ) && true == $anonymous_bind_redirect_no_tree )
return true ;
else
return false ;
}
/**
* Fetches whether phpLDAPadmin has been configured to display configuration
* management links ( report bug , request feature , etc )
* @ return bool
2009-06-30 08:05:37 +00:00
*/
2009-06-30 09:22:30 +00:00
function hide_configuration_management ()
{
global $hide_configuration_management ;
if ( isset ( $hide_configuration_management ) &&
$hide_configuration_management == true )
return true ;
else
return false ;
}
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
/**
* Fetches whether the user has configured phpLDAPadmin to obfuscate passwords
* with " ********* " when displaying them . This is configured in config . php thus :
* < code >
* $obfuscate_password_display = true ;
* </ code >
* @ return bool
*/
function obfuscate_password_display ()
{
global $obfuscate_password_display ;
if ( isset ( $obfuscate_password_display ) && true == $obfuscate_password_display )
return true ;
else
return false ;
}
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
/**
* Fetches whether the login_attr feature is enabled for a specified server .
* This is configured in config . php thus :
* < code >
* $servers [ $server_id ][ 'login_attr' ] = 'uid' ;
* </ code >
* By virtue of the fact that the login_attr is not blank and not 'dn' , the
* feature is configured to be enabled .
*
* @ return bool
*/
2009-06-30 08:10:17 +00:00
function login_attr_enabled ( $server_id )
{
global $servers ;
2009-06-30 09:22:30 +00:00
if ( isset ( $servers [ $server_id ][ 'login_attr' ] ) &&
2009-06-30 08:10:17 +00:00
0 != strcasecmp ( $servers [ $server_id ][ 'login_attr' ], " dn " ) &&
2009-06-30 09:22:30 +00:00
trim ( $servers [ $server_id ][ 'login_attr' ] != " " ) )
return true ;
else
return false ;
}
function login_string_enabled ( $server_id )
{
global $servers ;
if ( isset ( $servers [ $server_id ][ 'login_attr' ] ) &&
0 == strcasecmp ( $servers [ $server_id ][ 'login_attr' ], " string " ) )
2009-06-30 08:10:17 +00:00
return true ;
else
return false ;
}
2009-06-30 09:22:30 +00:00
function get_login_string ( $server_id )
{
global $servers ;
if ( isset ( $servers [ $server_id ][ 'login_string' ] ) )
return $servers [ $server_id ][ 'login_string' ];
else
return false ;
}
/**
2009-06-30 08:10:17 +00:00
* Returns an HTML - beautified version of a DN .
2009-06-30 09:22:30 +00:00
* Internally , this function makes use of pla_explode_dn () to break the
* the DN into its components . It then glues them back together with
* " pretty " HTML . The returned HTML is NOT to be used as a real DN , but
* simply displayed .
*
* @ param string $dn The DN to pretty - print .
* @ return string
2009-06-30 08:10:17 +00:00
*/
function pretty_print_dn ( $dn )
{
$dn = pla_explode_dn ( $dn );
foreach ( $dn as $i => $element ) {
$element = htmlspecialchars ( $element );
$element = explode ( '=' , $element , 2 );
$element = implode ( '<span style="color: blue; font-family: courier; font-weight: bold">=</span>' , $element );
$dn [ $i ] = $element ;
}
$dn = implode ( '<span style="color:red; font-family:courier; font-weight: bold;">,</span>' , $dn );
return $dn ;
}
2009-06-30 09:22:30 +00:00
/**
* Returns true if the attribute specified is required to take as input a DN .
* Some examples include 'distinguishedName' , 'member' and 'uniqueMember' .
* @ param int $server_id The ID of the server of interest
* ( required since this operation demands a schema lookup )
* @ param string $attr_name The name of the attribute of interest ( case insensitive )
* @ return bool
*/
function is_dn_attr ( $server_id , $attr_name )
{
// Simple test first
$dn_attrs = array ( " aliasedObjectName " );
foreach ( $dn_attrs as $dn_attr )
if ( 0 == strcasecmp ( $attr_name , $dn_attr ) )
return true ;
// Now look at the schema OID
$attr_schema = get_schema_attribute ( $server_id , $attr_name );
if ( ! $attr_schema )
return false ;
$syntax_oid = $attr_schema -> getSyntaxOID ();
if ( '1.3.6.1.4.1.1466.115.121.1.12' == $syntax_oid )
return true ;
if ( '1.3.6.1.4.1.1466.115.121.1.34' == $syntax_oid )
return true ;
$syntaxes = get_schema_syntaxes ( $server_id );
if ( ! isset ( $syntaxes [ $syntax_oid ] ) )
return false ;
$syntax_desc = $syntaxes [ $syntax_oid ] -> getDescription ();
if ( false !== strpos ( strtolower ( $syntax_desc ), 'distinguished name' ) )
return true ;
return false ;
}
2009-06-30 08:10:17 +00:00
2009-06-30 09:22:30 +00:00
/**
* Given a string , this function returns true if the string has the format
* of a DN ( ie , looks like " cn=Foo,dc=example,dc=com " ) . Returns false otherwise .
* The purpose of this function is so that developers can examine a string and
* know if it looks like a DN , and draw a hyperlink as needed .
*
* ( See unit_test . php for test cases )
*
* @ param string $attr The attribute to examine for " DNness "
* @ see unit_test . php
* @ return bool
2009-06-30 08:10:17 +00:00
*/
2009-06-30 09:22:30 +00:00
function is_dn_string ( $str )
2009-06-30 08:09:20 +00:00
{
2009-06-30 09:22:30 +00:00
// Try to break the string into its component parts if it can be done
// ie, "uid=Manager" "dc=example" and "dc=com"
$parts = pla_explode_dn ( $str );
if ( ! is_array ( $parts ) )
return false ;
if ( 0 == count ( $parts ) )
return false ;
// Foreach of the "parts", look for an "=" character,
// and make sure neither the left nor the right is empty
foreach ( $parts as $part ) {
if ( false === strpos ( $part , " = " ) )
return false ;
$sub_parts = explode ( " = " , $part , 2 );
$left = $sub_parts [ 0 ];
$right = $sub_parts [ 1 ];
if ( 0 == strlen ( trim ( $left ) ) || 0 == strlen ( trim ( $right ) ) )
return false ;
if ( false !== strpos ( $left , '#' ) )
return false ;
}
// We survived the above rigor. This is a bonified DN string.
return true ;
2009-06-30 08:09:20 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Get whether a string looks like an email address ( user @ example . com ) .
*
* @ param string $str The string to analyze .
* @ return bool Returns true if the specified string looks like
* an email address or false otherwise .
*/
function is_mail_string ( $str )
{
$mail_regex = " /^[_A-Za-z0-9-]+( \\ .[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+( \\ .[A-Za-z0-9-]+)* $ / " ;
if ( preg_match ( $mail_regex , $str ) )
return true ;
else
return false ;
}
/**
* Get whether a string looks like a web URL ( http :// www . example . com / )
*
* @ param string $str The string to analyze .
* @ return bool Returns true if the specified string looks like
* a web URL or false otherwise .
*/
function is_url_string ( $str )
{
$url_regex = '/(ftp|https?):\/\/+[\w\.\-\/\?\=\&]*\w+/' ;
if ( preg_match ( $url_regex , $str ) )
return true ;
else
return false ;
}
/**
* Utility wrapper for setting cookies , which takes into consideration
* phpLDAPadmin configuration values . On success , true is returned . On
* failure , false is returned .
*
* @ param string $name The name of the cookie to set .
* @ param string $val The value of the cookie to set .
* @ param int $expire ( optional ) The duration in seconds of this cookie . If unspecified , $cookie_time
* is used from config . php
* @ param string $dir ( optional ) The directory value of this cookie ( see php . net / setcookie )
*
* @ see setcookie
* @ return bool
2009-06-30 08:10:17 +00:00
*/
2009-06-30 08:09:20 +00:00
function pla_set_cookie ( $name , $val , $expire = null , $dir = null )
{
if ( $expire == null ) {
global $cookie_time ;
if ( ! isset ( $cookie_time ) )
$cookie_time = 0 ;
$expire = $cookie_time == 0 ? null : time () + $cookie_time ;
}
if ( $dir == null ) {
$dir = dirname ( $_SERVER [ 'PHP_SELF' ] );
}
2009-06-30 09:22:30 +00:00
if ( @ setcookie ( $name , $val , $expire , $dir ) ) {
2009-06-30 08:09:20 +00:00
$_COOKIE [ $name ] = $val ;
return true ;
} else {
return false ;
}
}
2009-06-30 09:22:30 +00:00
/**
* Responsible for setting two cookies / session - vars to indicate that a user has logged in ,
* one for the logged in DN and one for the logged in password . Cookies
* are stored unencrypted in the client 's browser' s cookie cache . Use caution !
*
* This function is only used if 'auth_type' is set to 'cookie' or 'session' . The values
* written have the name " pla_login_dn_X " and " pla_login_pass_X " where X is the
* ID of the server to which the user is attempting login .
*
* Note that as with all cookie / session operations this function must be called BEFORE
* any output is sent to the browser .
*
* On success , true is returned . On failure , false is returned .
*
* @ param int $server_id The ID of the server to which the user is logged in .
* @ param string $dn The DN with which the user has logged in .
* @ param string $password The password of the user logged in .
* @ param bool $anon_bind Indicates that this is an anonymous bind such that
* a password of " 0 " is stored .
* @ return bool
* @ see unset_login_dn
2009-06-30 08:10:17 +00:00
*/
2009-06-30 09:22:30 +00:00
function set_login_dn ( $server_id , $dn , $password , $anon_bind )
2009-06-30 08:09:20 +00:00
{
2009-06-30 09:22:30 +00:00
global $servers ;
2009-06-30 08:09:20 +00:00
if ( ! check_server_id ( $server_id ) )
return false ;
2009-06-30 09:22:30 +00:00
if ( ! isset ( $servers [ $server_id ][ 'auth_type' ] ) )
return false ;
$auth_type = $servers [ $server_id ][ 'auth_type' ];
switch ( $auth_type )
{
case 'cookie' :
$cookie_dn_name = " pla_login_dn_ $server_id " ;
$cookie_pass_name = " pla_login_pass_ $server_id " ;
if ( $anon_bind ) {
// we set the cookie password to 0 for anonymous binds.
$dn = 'anonymous' ;
$password = '0' ;
}
$res1 = pla_set_cookie ( $cookie_dn_name , pla_blowfish_encrypt ( $dn ) );
$res2 = pla_set_cookie ( $cookie_pass_name , pla_blowfish_encrypt ( $password ) );
if ( $res1 && $res2 )
return true ;
else
return false ;
break ;
case 'session' :
$sess_var_dn_name = " pla_login_dn_ $server_id " ;
$sess_var_pass_name = " pla_login_pass_ $server_id " ;
if ( $anon_bind ) {
$dn = 'anonymous' ;
$password = '0' ;
}
$_SESSION [ $sess_var_dn_name ] = $dn ;
$_SESSION [ $sess_var_pass_name ] = $password ;
return true ;
break ;
default :
global $lang ;
pla_error ( sprintf ( $lang [ 'unknown_auth_type' ], htmlspecialchars ( $auth_type ) ) );
break ;
}
}
/**
* Effectively logs a user out from a server .
* Removes the cookies / session - vars set by set_login_dn ()
* after a user logs out using " auth_type " of " session " or " cookie " .
* Returns true on success , false on failure .
*
* @ param int $server_id The ID of the server from which the user is logging out .
* @ return bool True on success , false on failure .
* @ see set_login_dn
*/
function unset_login_dn ( $server_id )
{
global $servers ;
2009-06-30 08:09:20 +00:00
2009-06-30 09:22:30 +00:00
if ( ! check_server_id ( $server_id ) )
2009-06-30 08:09:20 +00:00
return false ;
2009-06-30 09:22:30 +00:00
if ( ! isset ( $servers [ $server_id ][ 'auth_type' ] ) )
return false ;
$auth_type = $servers [ $server_id ][ 'auth_type' ];
switch ( $auth_type )
{
case 'cookie' :
$logged_in_dn = get_logged_in_dn ( $server_id );
if ( ! $logged_in_dn )
return false ;
$logged_in_pass = get_logged_in_pass ( $server_id );
$anon_bind = $logged_in_dn == 'anonymous' ? true : false ;
// set cookie with expire time already passed to erase cookie from client
$expire = time () - 3600 ;
$cookie_dn_name = " pla_login_dn_ $server_id " ;
$cookie_pass_name = " pla_login_pass_ $server_id " ;
if ( $anon_bind ) {
$res1 = pla_set_cookie ( $cookie_dn_name , 'anonymous' , $expire );
$res2 = pla_set_cookie ( $cookie_pass_name , '0' , $expire );
} else {
$res1 = pla_set_cookie ( $cookie_dn_name , pla_blowfish_encrypt ( $logged_in_dn ), $expire );
$res2 = pla_set_cookie ( $cookie_pass_name , pla_blowfish_encrypt ( $logged_in_pass ), $expire );
}
if ( ! $res1 || ! $res2 )
return false ;
else
return true ;
break ;
case 'session' :
// unset session variables
$session_var_dn_name = " pla_login_dn_ $server_id " ;
$session_var_pass_name = " pla_login_pass_ $server_id " ;
if ( array_key_exists ( $session_var_dn_name , $_SESSION ) )
unset ( $_SESSION [ $session_var_dn_name ] );
if ( array_key_exists ( $session_var_pass_name , $_SESSION ) )
unset ( $_SESSION [ " $session_var_pass_name " ] );
session_write_close ();
return true ;
break ;
default :
global $lang ;
pla_error ( sprintf ( $lang [ 'unknown_auth_type' ], htmlspecialchars ( $auth_type ) ) );
break ;
}
2009-06-30 08:09:20 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Get a customized file for a server
* We don 't need any caching, because it' s done by PHP
*
* @ param int $server_id The ID of the server
* @ param string $filename The requested filename
*
* @ return string The customized filename , if exists , or the standard one
*/
function get_custom_file ( $server_id , $filename )
{
global $servers ;
if ( ! check_server_id ( $server_id ) )
return $filename ;
if ( isset ( $servers [ $server_id ][ 'custom_pages_prefix' ] ) ) {
$custom = $servers [ $server_id ][ 'custom_pages_prefix' ];
if ( is_file ( realpath ( $custom . $filename ) ) )
return ( $custom . $filename );
}
return $filename ;
}
/**
* Call a customized function
*
* @ param int $server_id The ID of the server
* @ param string $filename The requested function
*
* @ return any The result of the called function
*/
function call_custom_function ( $server_id , $function )
{
global $servers ;
if ( ! check_server_id ( $server_id ) )
return $function ;
if ( isset ( $servers [ $server_id ][ 'custom_pages_prefix' ] ) ) {
$custom = $servers [ $server_id ][ 'custom_pages_prefix' ];
if ( function_exists ( $custom . $function ) )
return call_user_func ( $custom . $function );
}
return call_user_func ( $function );
}
/**
2009-06-30 08:09:20 +00:00
* Compares 2 DNs . If they are equivelant , returns 0 , otherwise ,
2009-06-30 09:22:30 +00:00
* returns their sorting order ( similar to strcmp ()) :
* Returns < 0 if dn1 is less than dn2 .
* Returns > 0 if dn1 is greater than dn2 .
*
* The comparison is performed starting with the top - most element
* of the DN . Thus , the following list :
* < code >
* ou = people , dc = example , dc = com
* cn = Admin , ou = People , dc = example , dc = com
* cn = Joe , ou = people , dc = example , dc = com
* dc = example , dc = com
* cn = Fred , ou = people , dc = example , dc = org
* cn = Dave , ou = people , dc = example , dc = org
* </ code >
* Will be sorted thus using usort ( $list , " pla_compare_dns " ) :
* < code >
* dc = com
* dc = example , dc = com
* ou = people , dc = example , dc = com
* cn = Admin , ou = People , dc = example , dc = com
* cn = Joe , ou = people , dc = example , dc = com
* cn = Dave , ou = people , dc = example , dc = org
* cn = Fred , ou = people , dc = example , dc = org
* </ code >
*
* @ param string $dn1 The first of two DNs to compare
* @ param string $dn2 The second of two DNs to compare
* @ return int
2009-06-30 08:09:20 +00:00
*/
function pla_compare_dns ( $dn1 , $dn2 )
{
// If they are obviously the same, return immediately
if ( 0 === strcasecmp ( $dn1 , $dn2 ) )
return 0 ;
2009-06-30 09:22:30 +00:00
$dn1_parts = pla_explode_dn ( pla_reverse_dn ( $dn1 ) );
$dn2_parts = pla_explode_dn ( pla_reverse_dn ( $dn2 ) );
assert ( is_array ( $dn1_parts ) );
assert ( is_array ( $dn2_parts ) );
// Foreach of the "parts" of the smaller DN
for ( $i = 0 ; $i < count ( $dn1_parts ) && $i < count ( $dn2_parts ); $i ++ )
2009-06-30 08:09:20 +00:00
{
// dnX_part is of the form: "cn=joe" or "cn = joe" or "dc=example"
// ie, one part of a multi-part DN.
$dn1_part = $dn1_parts [ $i ];
$dn2_part = $dn2_parts [ $i ];
// Each "part" consists of two sub-parts:
// 1. the attribute (ie, "cn" or "o")
// 2. the value (ie, "joe" or "example")
$dn1_sub_parts = explode ( '=' , $dn1_part , 2 );
$dn2_sub_parts = explode ( '=' , $dn2_part , 2 );
$dn1_sub_part_attr = trim ( $dn1_sub_parts [ 0 ] );
$dn2_sub_part_attr = trim ( $dn2_sub_parts [ 0 ] );
if ( 0 != ( $cmp = strcasecmp ( $dn1_sub_part_attr , $dn2_sub_part_attr ) ) )
return $cmp ;
$dn1_sub_part_val = trim ( $dn1_sub_parts [ 1 ] );
$dn2_sub_part_val = trim ( $dn2_sub_parts [ 1 ] );
if ( 0 != ( $cmp = strcasecmp ( $dn1_sub_part_val , $dn2_sub_part_val ) ) )
return $cmp ;
}
2009-06-30 09:22:30 +00:00
// If we iterated through all entries in the smaller of the two DNs
// (ie, the one with fewer parts), and the entries are different sized,
// then, the smaller of the two must be "less than" than the larger.
if ( count ( $dn1_parts ) > count ( $dn2_parts ) ) {
return 1 ;
} elseif ( count ( $dn2_parts ) > count ( $dn1_parts ) ) {
return - 1 ;
} else {
return 0 ;
}
2009-06-30 08:09:20 +00:00
}
/**
2009-06-30 09:22:30 +00:00
* Prunes off anything after the " ; " in an attr name . This is useful for
* attributes that may have " ;binary " appended to their names . With
* real_attr_name (), you can more easily fetch these attributes ' schema
* with their " real " attribute name .
*
* @ param string $attr_name The name of the attribute to examine .
* @ return string
2009-06-30 08:09:20 +00:00
*/
function real_attr_name ( $attr_name )
{
$attr_name = preg_replace ( " /;.* $ /U " , " " , $attr_name );
return $attr_name ;
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:09:20 +00:00
* Returns true if the user has configured the specified
2009-06-30 09:22:30 +00:00
* server to enable mass deletion . Mass deletion is enabled in config . php this :
* < code >
* $enable_mass_delete = true ;
* </ code >
* Notice that mass deletes are not enabled on a per - server basis , but this
* function checks that the sever is not in a read - only state as well .
*
* @ param int $server_id The ID of the server of interest .
* @ return bool
2009-06-30 08:09:20 +00:00
*/
function mass_delete_enabled ( $server_id )
{
global $enable_mass_delete ;
2009-06-30 09:22:30 +00:00
2009-06-30 08:09:20 +00:00
if ( check_server_id ( $server_id ) &&
2009-06-30 09:22:30 +00:00
! pla_ldap_connection_is_error ( pla_ldap_connect ( $server_id ), false ) &&
2009-06-30 08:09:20 +00:00
have_auth_info ( $server_id ) &&
! is_server_read_only ( $server_id ) &&
isset ( $enable_mass_delete ) &&
true === $enable_mass_delete )
return true ;
else
return false ;
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:09:20 +00:00
* Returns true if the user has configured PLA to show
* helpful hints with the $show_hints setting .
2009-06-30 09:22:30 +00:00
* This is configured in config . php thus :
* < code >
* $show_hints = true ;
* </ code >
*
* @ return bool
2009-06-30 08:09:20 +00:00
*/
function show_hints ()
{
global $show_hints ;
if ( isset ( $show_hints ) && $show_hints === true )
return true ;
}
2009-06-30 09:22:30 +00:00
/**
* Determines if the user has enabled auto uidNumbers for the specified server ID .
*
* @ param int $server_id The id of the server of interest .
* @ return bool True if auto uidNumbers are enabled , false otherwise .
*/
function auto_uid_numbers_enabled ( $server_id )
{
global $servers ;
if ( isset ( $servers [ $server_id ][ 'enable_auto_uid_numbers' ] ) &&
true == $servers [ $server_id ][ 'enable_auto_uid_numbers' ] )
return true ;
else
return false ;
}
/**
2009-06-30 08:09:20 +00:00
* For hosts who have 'enable_auto_uid_numbers' set to true , this function will
2009-06-30 09:22:30 +00:00
* get the next available uidNumber using the host ' s preferred mechanism
2009-06-30 08:09:20 +00:00
* ( uidpool or search ) . The uidpool mechanism uses a user - configured entry in
* the LDAP server to store the last used uidNumber . This mechanism simply fetches
* and increments and returns that value . The search mechanism is more complicated
* and slow . It searches all entries that have uidNumber set , finds the smalles and
* " fills in the gaps " by incrementing the smallest uidNumber until an unused value
* is found . Both mechanisms do NOT prevent race conditions or toe - stomping , so
* care must be taken when actually creating the entry to check that the uidNumber
* returned here has not been used in the mean time . Note that the two different
* mechanisms may ( will ! ) return different values as they use different algorithms
* to arrive at their result . Do not be alarmed if ( when ! ) this is the case .
2009-06-30 09:22:30 +00:00
*
* Also note that both algorithms are susceptible to a race condition . If two admins
* are adding users simultaneously , the users may get identical uidNumbers with this
* function .
*
* See config . php . example for more notes on the two auto uidNumber mechanisms .
*
* @ param int $server_id The ID of the server of interest .
* @ return int
*
* @ todo eliminate race condition at create time by re - running this function .
2009-06-30 08:09:20 +00:00
*/
function get_next_uid_number ( $server_id )
{
global $servers , $lang ;
// Some error checking
if ( ! check_server_id ( $server_id ) )
return false ;
2009-06-30 09:22:30 +00:00
if ( ! auto_uid_numbers_enabled ( $server_id ) )
return false ;
2009-06-30 08:09:20 +00:00
$server_name = isset ( $servers [ $server_id ][ 'name' ] ) ?
$servers [ $server_id ][ 'name' ] :
" Server $server_id " ;
if ( ! isset ( $servers [ $server_id ][ 'enable_auto_uid_numbers' ] ) )
return false ;
if ( ! isset ( $servers [ $server_id ][ 'auto_uid_number_mechanism' ] ) )
pla_error ( sprintf ( $lang [ 'auto_update_not_setup' ], $server_name ));
// Based on the configured mechanism, go get the next available uidNumber!
$mechanism = $servers [ $server_id ][ 'auto_uid_number_mechanism' ];
//
// case 1: uidpool mechanism
//
if ( 0 == strcasecmp ( $mechanism , 'uidpool' ) ) {
if ( ! isset ( $servers [ $server_id ][ 'auto_uid_number_uid_pool_dn' ] ) )
pla_error ( sprintf ( $lang [ 'uidpool_not_set' ], $server_name ) );
$uid_pool_dn = $servers [ $server_id ][ 'auto_uid_number_uid_pool_dn' ];
if ( ! dn_exists ( $server_id , $uid_pool_dn ) )
pla_error ( sprintf ( $lang [ 'uidpool_not_exist' ] , $uid_pool_dn ) );
$next_uid_number = get_object_attr ( $server_id , $uid_pool_dn , 'uidNumber' );
$next_uid_number = intval ( $next_uid_number [ 0 ] );
$next_uid_number ++ ;
return $next_uid_number ;
//
// case 2: search mechanism
//
} elseif ( 0 == strcasecmp ( $mechanism , 'search' ) ) {
if ( ! isset ( $servers [ $server_id ][ 'auto_uid_number_search_base' ] ) )
pla_error ( sprintf ( $lang [ 'specified_uidpool' ] , $server_name ) );
2009-06-30 09:22:30 +00:00
2009-06-30 08:09:20 +00:00
$base_dn = $servers [ $server_id ][ 'auto_uid_number_search_base' ];
$filter = " (uidNumber=*) " ;
2009-06-30 09:22:30 +00:00
// Check see and use our alternate uid_dn and password if we have it.
if ( isset ( $servers [ $server_id ][ 'auto_uid_number_search_dn' ] ) &&
isset ( $servers [ $server_id ][ 'auto_uid_number_search_dn_pass' ] ) ) {
$con = @ ldap_connect ( $servers [ $server_id ][ 'host' ], $servers [ $server_id ][ 'port' ] );
@ ldap_set_option ( $con , LDAP_OPT_PROTOCOL_VERSION , 3 );
@ ldap_set_option ( $con , LDAP_OPT_REFERRALS , 0 );
// Bind with the alternate ID.
$res = @ ldap_bind ( $con ,
$servers [ $server_id ][ 'auto_uid_number_search_dn' ],
$servers [ $server_id ][ 'auto_uid_number_search_dn_pass' ] );
if ( ! $res ) pla_error ( sprintf ( $lang [ 'auto_uid_invalid_credential' ] , $server_name ) );
$search = @ ldap_search ( $con , $base_dn , $filter , array ( 'uidNumber' ), 0 , 0 , 0 , get_search_deref_setting () );
if ( ! $search ) pla_error ( sprintf ( $lang [ 'bad_auto_uid_search_base' ], $server_name ) );
$search = @ ldap_get_entries ( $con , $search );
$res = @ ldap_unbind ( $con );
$results = array ();
for ( $i = 0 ; $i < $search [ 'count' ]; $i ++ ) {
$entry = $search [ $i ];
$dn [ 'dn' ] = $entry [ 'dn' ];
$dn [ 'uidnumber' ] = $entry [ 'uidnumber' ][ 0 ];
$results [] = $dn ;
}
} else {
$results = pla_ldap_search ( $server_id , $filter , $base_dn , array ( 'uidNumber' ));
}
2009-06-30 08:09:20 +00:00
// lower-case all the inices so we can access them by name correctly
foreach ( $results as $dn => $attrs )
foreach ( $attrs as $attr => $vals ) {
unset ( $results [ $dn ][ $attr ] );
$results [ $dn ][ strtolower ( $attr )] = $vals ;
}
// construct a list of used uidNumbers
$uids = array ();
foreach ( $results as $result )
$uids [] = $result [ 'uidnumber' ];
$uids = array_unique ( $uids );
if ( count ( $uids ) == 0 )
return false ;
sort ( $uids );
foreach ( $uids as $uid )
$uid_hash [ $uid ] = 1 ;
// start with the least existing uidNumber and add 1
2009-06-30 08:10:17 +00:00
if ( isset ( $servers [ $server_id ][ 'auto_uid_number_min' ])) {
$uidNumber = $servers [ $server_id ][ 'auto_uid_number_min' ];
} else {
$uidNumber = intval ( $uids [ 0 ] ) + 1 ;
}
2009-06-30 08:09:20 +00:00
// this loop terminates as soon as we encounter the next available uidNumber
while ( isset ( $uid_hash [ $uidNumber ] ) )
$uidNumber ++ ;
return $uidNumber ;
//
// No other cases allowed. The user has an error in the configuration
//
} else {
pla_error ( sprintf ( $lang [ 'auto_uid_invalid_value' ] , $mechanism ) );
}
}
2009-06-30 09:22:30 +00:00
/**
* Used to determine if the specified attribute is indeed a jpegPhoto . If the
* specified attribute is one that houses jpeg data , true is returned . Otherwise
* this function returns false .
*
* @ param int $server_id The ID of the server hosuing the attribute of interest
* @ param string $attr_name The name of the attribute to test .
* @ return bool
* @ see draw_jpeg_photos
2009-06-30 08:07:14 +00:00
*/
function is_jpeg_photo ( $server_id , $attr_name )
{
// easy quick check
if ( 0 == strcasecmp ( $attr_name , 'jpegPhoto' ) ||
0 == strcasecmp ( $attr_name , 'photo' ) )
return true ;
// go to the schema and get the Syntax OID
require_once realpath ( 'schema_functions.php' );
$schema_attr = get_schema_attribute ( $server_id , $attr_name );
if ( ! $schema_attr )
return false ;
$oid = $schema_attr -> getSyntaxOID ();
$type = $schema_attr -> getType ();
if ( 0 == strcasecmp ( $type , 'JPEG' ) )
return true ;
if ( $oid == '1.3.6.1.4.1.1466.115.121.1.28' )
return true ;
return false ;
}
2009-06-30 09:22:30 +00:00
/**
* Given an attribute name and server ID number , this function returns
* whether the attrbiute contains boolean data . This is useful for
* developers who wish to display the contents of a boolean attribute
* with a drop - down .
*
* @ param int $server_id The ID of the server of interest ( required since
* this action requires a schema lookup on the server )
* @ param string $attr_name The name of the attribute to test .
* @ return bool
2009-06-30 08:07:14 +00:00
*/
2009-06-30 09:22:30 +00:00
function is_attr_boolean ( $server_id , $attr_name )
2009-06-30 08:07:14 +00:00
{
2009-06-30 09:22:30 +00:00
$type = ( $schema_attr = get_schema_attribute ( $server_id , $attr_name ) ) ?
$schema_attr -> getType () :
null ;
if ( 0 == strcasecmp ( 'boolean' , $type ) ||
0 == strcasecmp ( 'isCriticalSystemObject' , $attr_name ) ||
0 == strcasecmp ( 'showInAdvancedViewOnly' , $attr_name ) )
return true ;
else
return false ;
}
2009-06-30 08:07:14 +00:00
2009-06-30 09:22:30 +00:00
/**
* Given an attribute name and server ID number , this function returns
* whether the attrbiute may contain binary data . This is useful for
* developers who wish to display the contents of an arbitrary attribute
* but don ' t want to dump binary data on the page .
*
* @ param int $server_id The ID of the server of interest ( required since
* this action requires a schema lookup on the server )
* @ param string $attr_name The name of the attribute to test .
* @ return bool
*
* @ see is_jpeg_photo
*/
function is_attr_binary ( $server_id , $attr_name )
{
$attr_name = strtolower ( $attr_name );
/** Determining if an attribute is binary can be an expensive
operation . We cache the results for each attr name on each
server in the $attr_cache to speed up subsequent calls .
The $attr_cache looks like this :
Array
0 => Array
'objectclass' => false
'cn' => false
'usercertificate' => true
1 => Array
'jpegphoto' => true
'cn' => false
*/
static $attr_cache ;
if ( isset ( $attr_cache [ $server_id ][ $attr_name ] ) )
return $attr_cache [ $server_id ][ $attr_name ];
if ( $attr_name == 'userpassword' ) {
$attr_cache [ $server_id ][ $attr_name ] = false ;
return false ;
}
// Quick check: If the attr name ends in ";binary", then it's binary.
if ( 0 == strcasecmp ( substr ( $attr_name , strlen ( $attr_name ) - 7 ), " ;binary " ) ) {
$attr_cache [ $server_id ][ $attr_name ] = true ;
2009-06-30 08:07:14 +00:00
return true ;
2009-06-30 09:22:30 +00:00
}
2009-06-30 08:09:20 +00:00
2009-06-30 09:22:30 +00:00
// See what the server schema says about this attribute
2009-06-30 08:09:20 +00:00
$schema_attr = get_schema_attribute ( $server_id , $attr_name );
2009-06-30 09:22:30 +00:00
if ( ! $schema_attr ) {
// Strangely, some attributeTypes may not show up in the server
// schema. This behavior has been observed in MS Active Directory.
$type = null ;
$syntax = null ;
} else {
$type = $schema_attr -> getType ();
$syntax = $schema_attr -> getSyntaxOID ();
}
if ( 0 == strcasecmp ( $type , 'Certificate' ) ||
2009-06-30 08:09:20 +00:00
0 == strcasecmp ( $type , 'Binary' ) ||
2009-06-30 09:22:30 +00:00
0 == strcasecmp ( $attr_name , 'usercertificate' ) ||
0 == strcasecmp ( $attr_name , 'usersmimecertificate' ) ||
0 == strcasecmp ( $attr_name , 'networkaddress' ) ||
0 == strcasecmp ( $attr_name , 'objectGUID' ) ||
0 == strcasecmp ( $attr_name , 'objectSID' ) ||
2009-06-30 08:09:20 +00:00
$syntax == '1.3.6.1.4.1.1466.115.121.1.10' ||
$syntax == '1.3.6.1.4.1.1466.115.121.1.28' ||
$syntax == '1.3.6.1.4.1.1466.115.121.1.5' ||
$syntax == '1.3.6.1.4.1.1466.115.121.1.8' ||
2009-06-30 09:22:30 +00:00
$syntax == '1.3.6.1.4.1.1466.115.121.1.9' ) {
$attr_cache [ $server_id ][ $attr_name ] = true ;
2009-06-30 08:07:14 +00:00
return true ;
2009-06-30 09:22:30 +00:00
} else {
$attr_cache [ $server_id ][ $attr_name ] = false ;
2009-06-30 08:07:14 +00:00
return false ;
2009-06-30 09:22:30 +00:00
}
2009-06-30 08:07:14 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Returns true if the specified attribute is configured as read only
* in config . php with the $read_only_attrs array .
* Attributes are configured as read - only in config . php thus :
* < code >
* $read_only_attrs = array ( " objectClass " , " givenName " );
* </ code >
*
* @ param string $attr The name of the attribute to test .
* @ return bool
2009-06-30 08:07:14 +00:00
*/
2009-06-30 09:22:30 +00:00
function is_attr_read_only ( $server_id , $attr )
2009-06-30 08:07:14 +00:00
{
2009-06-30 09:22:30 +00:00
global $read_only_attrs , $read_only_except_dn ;
2009-06-30 08:09:20 +00:00
2009-06-30 09:22:30 +00:00
$attr = trim ( $attr );
if ( '' === $attr )
return false ;
if ( ! isset ( $read_only_attrs ) )
return false ;
if ( ! is_array ( $read_only_attrs ) )
return false ;
2009-06-30 08:09:20 +00:00
2009-06-30 09:22:30 +00:00
// Is the user excluded?
if ( isset ( $read_only_except_dn ) && userIsMember ( $server_id , get_logged_in_dn ( $server_id ), $read_only_except_dn ))
return false ;
foreach ( $read_only_attrs as $attr_name )
if ( 0 == strcasecmp ( $attr , trim ( $attr_name ) ) )
return true ;
return false ;
}
/**
* Returns true if the specified attribute is configured as hidden
* in config . php with the $hidden_attrs array or the $hidden_attrs_ro
* array .
* Attributes are configured as hidden in config . php thus :
* < code >
* $hidden_attrs = array ( " objectClass " , " givenName " );
* </ code >
* or
* < code >
* $hidden_attrs_ro = array ( " objectClass " , " givenName " , " shadowWarning " ,
* " shadowLastChange " , " shadowMax " , " shadowFlag " ,
* " shadowInactive " , " shadowMin " , " shadowExpire " );
* </ code >
*
* @ param string $attr The name of the attribute to test .
* @ return bool
*/
function is_attr_hidden ( $server_id , $attr )
{
global $hidden_attrs , $hidden_attrs_ro , $hidden_except_dn ;
$attr = trim ( $attr );
if ( '' === $attr )
return false ;
if ( ! isset ( $hidden_attrs ) )
return false ;
if ( ! is_array ( $hidden_attrs ) )
return false ;
if ( ! isset ( $hidden_attrs_ro ) )
$hidden_attrs_ro = $hidden_attrs ;
if ( ! is_array ( $hidden_attrs_ro ) )
$hidden_attrs_ro = $hidden_attrs ;
// Is the user excluded?
if ( isset ( $hidden_except_dn ) && userIsMember ( $server_id , get_logged_in_dn ( $server_id ), $hidden_except_dn ))
return false ;
if ( is_server_read_only ( $server_id ) ) {
foreach ( $hidden_attrs_ro as $attr_name )
if ( 0 == strcasecmp ( $attr , trim ( $attr_name ) ) )
return true ;
} else {
foreach ( $hidden_attrs as $attr_name )
if ( 0 == strcasecmp ( $attr , trim ( $attr_name ) ) )
return true ;
}
return false ;
}
/**
* Returns true if the specified server is configured to be displayed
* in read only mode . If a user has logged in via anonymous bind , and
* config . php specifies anonymous_bind_implies_read_only as true , then
* this also returns true . Servers can be configured read - only in
* config . php thus :
* < code >
* $server [ $i ][ 'read_only' ] = true ;
* </ code >
*
* @ param int $server_id The ID of the server of interest from the $servers array in config . php
* @ return bool
*/
function is_server_read_only ( $server_id )
{
global $servers ;
if ( isset ( $servers [ $server_id ][ 'read_only' ] ) &&
$servers [ $server_id ][ 'read_only' ] == true )
return true ;
global $anonymous_bind_implies_read_only ;
if ( " anonymous " == get_logged_in_dn ( $server_id ) &&
isset ( $anonymous_bind_implies_read_only ) &&
$anonymous_bind_implies_read_only == true )
2009-06-30 08:07:14 +00:00
return true ;
return false ;
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:09:20 +00:00
* Given a DN and server ID , this function reads the DN ' s objectClasses and
2009-06-30 08:07:14 +00:00
* determines which icon best represents the entry . The results of this query
2009-06-30 09:22:30 +00:00
* are cached in a session variable so it is not run every time the tree
2009-06-30 08:07:14 +00:00
* browser changes , just when exposing new DNs that were not displayed
* previously . That means we can afford a little bit of inefficiency here
* in favor of coolness . : )
2009-06-30 09:22:30 +00:00
*
* This function returns a string like " country.png " . All icon files are assumed
* to be contained in the / images / directory of phpLDAPadmin .
*
* Developers are encouraged to add new icons to the images directory and modify
* this function as needed to suit their types of LDAP entries . If the modifications
* are general to an LDAP audience , the phpLDAPadmin team will gladly accept them
* as a patch .
*
* @ param int $server_id The ID of the LDAP server housing the DN of interest .
* @ param string $dn The DN of the entry whose icon you wish to fetch .
*
* @ return string
2009-06-30 08:05:37 +00:00
*/
function get_icon ( $server_id , $dn )
{
// fetch and lowercase all the objectClasses in an array
2009-06-30 08:07:14 +00:00
$object_classes = get_object_attr ( $server_id , $dn , 'objectClass' , true );
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
if ( $object_classes === null || $object_classes === false || ! is_array ( $object_classes ) )
$object_classes = array ();
2009-06-30 08:05:37 +00:00
foreach ( $object_classes as $i => $class )
$object_classes [ $i ] = strtolower ( $class );
2009-06-30 08:07:14 +00:00
$rdn = get_rdn ( $dn );
2009-06-30 09:22:30 +00:00
$rdn_parts = explode ( '=' , $rdn , 2 );
$rdn_value = isset ( $rdn_parts [ 0 ] ) ? $rdn_parts [ 0 ] : null ;
$rdn_attr = isset ( $rdn_parts [ 1 ] ) ? $rdn_parts [ 1 ] : null ;
unset ( $rdn_parts );
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
// return icon filename based upon objectClass value
2009-06-30 08:07:14 +00:00
if ( in_array ( 'sambaaccount' , $object_classes ) &&
'$' == $rdn { strlen ( $rdn ) - 1 } )
2009-06-30 08:10:17 +00:00
return 'nt_machine.png' ;
if ( in_array ( 'sambaaccount' , $object_classes ) )
return 'nt_user.png' ;
2009-06-30 08:09:20 +00:00
elseif ( in_array ( 'person' , $object_classes ) ||
2009-06-30 08:05:37 +00:00
in_array ( 'organizationalperson' , $object_classes ) ||
2009-06-30 08:09:20 +00:00
in_array ( 'inetorgperson' , $object_classes ) ||
2009-06-30 08:05:37 +00:00
in_array ( 'account' , $object_classes ) ||
in_array ( 'posixaccount' , $object_classes ) )
return 'user.png' ;
2009-06-30 09:22:30 +00:00
elseif ( in_array ( 'organization' , $object_classes ) )
2009-06-30 08:05:37 +00:00
return 'o.png' ;
elseif ( in_array ( 'organizationalunit' , $object_classes ) )
return 'ou.png' ;
2009-06-30 09:22:30 +00:00
elseif ( in_array ( 'organizationalrole' , $object_classes ) )
return 'uid.png' ;
2009-06-30 08:09:20 +00:00
elseif ( in_array ( 'dcobject' , $object_classes ) ||
2009-06-30 09:22:30 +00:00
in_array ( 'domainrelatedobject' , $object_classes ) ||
in_array ( 'domain' , $object_classes ) ||
in_array ( 'builtindomain' , $object_classes ))
2009-06-30 08:05:37 +00:00
return 'dc.png' ;
2009-06-30 09:22:30 +00:00
elseif ( in_array ( 'alias' , $object_classes ) )
return 'go.png' ;
elseif ( in_array ( 'room' , $object_classes ) )
return 'door.png' ;
elseif ( in_array ( 'device' , $object_classes ) )
return 'device.png' ;
elseif ( in_array ( 'document' , $object_classes ) )
return 'document.png' ;
elseif ( in_array ( 'country' , $object_classes ) ) {
$tmp = pla_explode_dn ( $dn );
$cval = explode ( '=' , $tmp [ 0 ], 2 );
$cval = isset ( $cval [ 1 ] ) ? $cval [ 1 ] : false ;
if ( $cval && false === strpos ( $cval , " .. " ) &&
file_exists ( realpath ( " ./images/countries/ $cval .png " ) ) )
return " countries/ $cval .png " ;
else
return 'country.png' ;
}
2009-06-30 08:05:37 +00:00
elseif ( in_array ( 'jammvirtualdomain' , $object_classes ) )
return 'mail.png' ;
elseif ( in_array ( 'locality' , $object_classes ) )
return 'locality.png' ;
2009-06-30 08:09:20 +00:00
elseif ( in_array ( 'posixgroup' , $object_classes ) ||
2009-06-30 09:22:30 +00:00
in_array ( 'groupofnames' , $object_classes ) ||
in_array ( 'group' , $object_classes ) )
2009-06-30 08:07:14 +00:00
return 'ou.png' ;
2009-06-30 08:09:20 +00:00
elseif ( in_array ( 'applicationprocess' , $object_classes ) )
return 'process.png' ;
elseif ( in_array ( 'groupofuniquenames' , $object_classes ) )
return 'uniquegroup.png' ;
elseif ( in_array ( 'iphost' , $object_classes ) )
return 'host.png' ;
2009-06-30 09:22:30 +00:00
elseif ( in_array ( 'nlsproductcontainer' , $object_classes ) )
return 'n.png' ;
elseif ( in_array ( 'ndspkikeymaterial' , $object_classes ) )
return 'lock.png' ;
elseif ( in_array ( 'server' , $object_classes ) )
return 'server-small.png' ;
elseif ( in_array ( 'volume' , $object_classes ) )
return 'hard-drive.png' ;
elseif ( in_array ( 'ndscatcatalog' , $object_classes ) )
return 'catalog.png' ;
elseif ( in_array ( 'resource' , $object_classes ) )
return 'n.png' ;
elseif ( in_array ( 'ldapgroup' , $object_classes ) )
return 'ldap-server.png' ;
elseif ( in_array ( 'ldapserver' , $object_classes ) )
return 'ldap-server.png' ;
elseif ( in_array ( 'nisserver' , $object_classes ) )
return 'ldap-server.png' ;
elseif ( in_array ( 'rbscollection' , $object_classes ) )
return 'ou.png' ;
elseif ( in_array ( 'dfsconfiguration' , $object_classes ) )
return 'nt_machine.png' ;
elseif ( in_array ( 'applicationsettings' , $object_classes ) )
return 'server-settings.png' ;
elseif ( in_array ( 'aspenalias' , $object_classes ) )
return 'mail.png' ;
elseif ( in_array ( 'container' , $object_classes ) )
return 'folder.png' ;
elseif ( in_array ( 'ipnetwork' , $object_classes ) )
return 'network.png' ;
elseif ( in_array ( 'samserver' , $object_classes ) )
return 'server-small.png' ;
elseif ( in_array ( 'lostandfound' , $object_classes ) )
return 'find.png' ;
elseif ( in_array ( 'infrastructureupdate' , $object_classes ) )
return 'server-small.png' ;
elseif ( in_array ( 'filelinktracking' , $object_classes ) )
return 'files.png' ;
elseif ( in_array ( 'automountmap' , $object_classes ) ||
in_array ( 'automount' , $object_classes ) )
return 'hard-drive.png' ;
elseif ( 0 === strpos ( $rdn_value , " ipsec " ) ||
0 == strcasecmp ( $rdn_value , " IP Security " ) ||
0 == strcasecmp ( $rdn_value , " MSRADIUSPRIVKEY Secret " ) ||
0 === strpos ( $rdn_value , " BCKUPKEY_ " ) )
return 'lock.png' ;
elseif ( 0 == strcasecmp ( $rdn_value , " MicrosoftDNS " ) )
return 'dc.png' ;
2009-06-30 08:05:37 +00:00
// Oh well, I don't know what it is. Use a generic icon.
else
return 'object.png' ;
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:09:20 +00:00
* Does the same thing as get_icon (), but it tries to fetch the icon name from the
* tree_icons session variable first . If not found , resorts to get_icon () and stores
* the icon nmae in the tree_icons session before returing the icon .
2009-06-30 09:22:30 +00:00
*
* @ param int $server_id The ID of the server housing the DN of interest .
* @ param string $dn The DN of the entry of interest .
*
* @ return string
*
* @ see get_icon
2009-06-30 08:09:20 +00:00
*/
function get_icon_use_cache ( $server_id , $dn )
{
2009-06-30 09:22:30 +00:00
initialize_session_tree ();
if ( array_key_exists ( 'tree_icons' , $_SESSION ) ) {
if ( array_key_exists ( $server_id , $_SESSION [ 'tree_icons' ] ) &&
array_key_exists ( $dn , $_SESSION [ 'tree_icons' ][ $server_id ] ) )
{
2009-06-30 08:09:20 +00:00
return $_SESSION [ 'tree_icons' ][ $server_id ][ $dn ];
} else {
$icon = get_icon ( $server_id , $dn );
$_SESSION [ 'tree_icons' ][ $server_id ][ $dn ] = $icon ;
return $icon ;
}
}
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:05:37 +00:00
* Given a server_id , returns whether or not we have enough information
* to authenticate against the server . For example , if the user specifies
2009-06-30 09:22:30 +00:00
* auth_type of 'cookie' in the config for that server , it checks the $_COOKIE array to
* see if the cookie username and password is set for the server . If the auth_type
* is 'session' , the $_SESSION array is checked .
*
* There are three cases for this function depending on the auth_type configured for
* the specified server . If the auth_type is form or http , then get_logged_in_dn () is
* called to verify that the user has logged in . If the auth_type is config , then the
* $servers array in config . php is checked to ensure that the user has specified
* login information . In any case , if phpLDAPadmin has enough information to login
* to the server , true is returned . Otherwise false is returned .
*
* @ param int $server_id
* @ return bool
* @ see get_logged_in_dn
2009-06-30 08:05:37 +00:00
*/
function have_auth_info ( $server_id )
{
global $servers ;
2009-06-30 09:22:30 +00:00
if ( ! check_server_id ( $server_id ) )
2009-06-30 08:05:37 +00:00
return false ;
$server = $servers [ $server_id ];
2009-06-30 09:22:30 +00:00
// For session or cookie auth_types, we check the session or cookie to see if a user has logged in.
if ( isset ( $server [ 'auth_type' ] ) && ( in_array ( $server [ 'auth_type' ], array ( 'session' , 'cookie' ) ) ) ) {
2009-06-30 08:09:20 +00:00
// we don't look at get_logged_in_pass() cause it may be null for anonymous binds
// get_logged_in_dn() will never return null if someone is really logged in.
if ( get_logged_in_dn ( $server_id ) )
2009-06-30 08:05:37 +00:00
return true ;
else
return false ;
}
2009-06-30 08:09:20 +00:00
// whether or not the login_dn or pass is specified, we return
2009-06-30 08:05:37 +00:00
// true here. (if they are blank, we do an anonymous bind anyway)
2009-06-30 08:09:20 +00:00
elseif ( ! isset ( $server [ 'auth_type' ] ) || $server [ 'auth_type' ] == 'config' ) {
2009-06-30 08:05:37 +00:00
return true ;
}
2009-06-30 09:22:30 +00:00
else {
2009-06-30 08:09:20 +00:00
global $lang ;
2009-06-30 09:22:30 +00:00
pla_error ( sprintf ( $lang [ 'error_auth_type_config' ],
htmlspecialchars ( $server [ 'auth_type' ] ) ) );
2009-06-30 08:05:37 +00:00
}
}
2009-06-30 09:22:30 +00:00
/**
* Fetches the password of the currently logged in user ( for auth_types " form " and " http " only )
2009-06-30 08:09:20 +00:00
* or false if the current login is anonymous .
2009-06-30 09:22:30 +00:00
*
* @ param int $server_id The ID of the server of interest .
*
* @ return string
*
* @ see have_auth_info
* @ see get_logged_in_dn
2009-06-30 08:09:20 +00:00
*/
2009-06-30 08:05:37 +00:00
function get_logged_in_pass ( $server_id )
{
2009-06-30 09:22:30 +00:00
global $servers ;
2009-06-30 08:09:20 +00:00
if ( ! is_numeric ( $server_id ) )
return false ;
2009-06-30 09:22:30 +00:00
if ( ! isset ( $servers [ $server_id ][ 'auth_type' ] ) )
return false ;
$auth_type = $servers [ $server_id ][ 'auth_type' ];
switch ( $auth_type ) {
case 'cookie' :
$cookie_name = 'pla_login_pass_' . $server_id ;
$pass = isset ( $_COOKIE [ $cookie_name ] ) ? $_COOKIE [ $cookie_name ] : false ;
if ( $pass == '0' )
return null ;
else
return pla_blowfish_decrypt ( $pass );
break ;
case 'session' :
$session_var_name = 'pla_login_pass_' . $server_id ;
$pass = isset ( $_SESSION [ $session_var_name ] ) ? $_SESSION [ $session_var_name ] : false ;
if ( $pass == '0' )
return null ;
else
return $pass ;
break ;
case 'config' :
if ( isset ( $servers [ $server_id ][ 'login_pass' ] ) )
return ( $servers [ $server_id ][ 'login_pass' ] );
return false ;
break ;
default :
global $lang ;
pla_error ( sprintf ( $lang [ 'unknown_auth_type' ], htmlspecialchars ( $auth_type ) ) );
}
2009-06-30 08:05:37 +00:00
}
2009-06-30 08:09:20 +00:00
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:09:20 +00:00
* Returns the DN who is logged in currently to the given server , which may
2009-06-30 09:22:30 +00:00
* either be a DN or the string 'anonymous' . This applies only for auth_types
* " form " and " http " .
*
* One place where this function is used is the tree viewer :
* After a user logs in , the text " Logged in as: " is displayed under the server
* name . This information is retrieved from this function .
*
* @ param int $server_id The ID of the server of interest .
*
* @ return string
*
* @ see have_auth_info
* @ see get_logged_in_pass
2009-06-30 08:09:20 +00:00
*/
2009-06-30 08:05:37 +00:00
function get_logged_in_dn ( $server_id )
{
2009-06-30 09:22:30 +00:00
global $servers ;
2009-06-30 08:09:20 +00:00
if ( ! is_numeric ( $server_id ) )
return false ;
2009-06-30 09:22:30 +00:00
if ( ! isset ( $servers [ $server_id ][ 'auth_type' ] ) )
2009-06-30 08:07:14 +00:00
return false ;
2009-06-30 09:22:30 +00:00
$auth_type = $servers [ $server_id ][ 'auth_type' ];
switch ( $auth_type ) {
case 'cookie' :
$cookie_name = 'pla_login_dn_' . $server_id ;
if ( isset ( $_COOKIE [ $cookie_name ] ) ) {
$dn = $_COOKIE [ $cookie_name ];
} else {
return false ;
}
return pla_blowfish_decrypt ( $dn );
break ;
case 'session' :
$session_var_name = 'pla_login_dn_' . $server_id ;
if ( isset ( $_SESSION [ $session_var_name ] ) ) {
$dn = $_SESSION [ $session_var_name ];
return $dn ;
} else {
return false ;
}
break ;
case 'config' :
if ( isset ( $servers [ $server_id ][ 'login_dn' ] ) )
return ( $servers [ $server_id ][ 'login_dn' ] );
return false ;
break ;
default :
global $lang ;
pla_error ( sprintf ( $lang [ 'unknown_auth_type' ], htmlspecialchars ( $auth_type ) ) );
2009-06-30 08:09:20 +00:00
}
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Appends a servers base to a " sub " dn or returns the base .
* If $get_base is true , return at least the base , otherwise null .
2009-06-30 08:05:37 +00:00
*/
2009-06-30 09:22:30 +00:00
function expand_dn_with_base ( $server_id , $sub_dn , $conn = null , $get_base = true )
2009-06-30 08:05:37 +00:00
{
2009-06-30 09:22:30 +00:00
global $servers ;
2009-06-30 08:05:37 +00:00
if ( ! check_server_id ( $server_id ) )
return false ;
2009-06-30 09:22:30 +00:00
$empty_str = ( is_null ( $sub_dn ) || ( ( $len = strlen ( trim ( $sub_dn ) ) ) == 0 ) );
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
if ( $empty_str ) {
// If we have no string and want not base
if ( ! $get_base )
return null ;
} elseif ( $sub_dn [ $len - 1 ] != ',' )
// If we have a string which doesn't need a base
return $sub_dn ;
if ( ( $empty_str && $get_base ) || ! $empty_str )
{
if ( isset ( $servers [ $server_id ][ 'base' ]) ) {
$base = $servers [ $server_id ][ 'base' ];
if ( strlen ( trim ( $base ) ) == 0 )
$base = try_to_get_root_dn ( $server_id , $conn );
} else {
$base = try_to_get_root_dn ( $server_id , $conn );
}
if ( $base )
return ( ! $empty_str ) ? $sub_dn . $base : $base ;
}
return null ;
}
/**
* Logs into the specified server using the auth_type configured for that server using
* ldap_connect () and ldap_bind () from the PHP LDAP API .
* If anonymous is true bind information ( user / pass ) is ignored ( = anonymous ) .
* If anonymous is null a new bind is done ( i . e . user changed ) .
*
* @ param int $server_id The ID of the server of interest .
* @ param bool $anonymous Set to override server config
* @ return resource The LDAP connection resource or the LDAP errorcode
*
* @ see get_logged_in_dn
* @ see get_logged_in_pass
* @ see have_auth_info
* @ see check_server_id
*/
function pla_ldap_connect ( $server_id , $anonymous = false , $use_cache = true )
{
//echo "pla_ldap_connect( $server_id, $anonymous, $use_cache )<br />\n";
if ( ! check_server_id ( $server_id ) )
return - 1 ;
if ( ! $anonymous && ! have_auth_info ( $server_id ) )
return - 2 ;
global $servers , $lang ;
2009-06-30 08:05:37 +00:00
// cache the connection, so if we are called multiple
// times, we don't have to reauthenticate with the LDAP server
static $conns ;
2009-06-30 09:22:30 +00:00
// We can reuse connections for multiple binds if we don't ldap_unbind
if ( $use_cache && isset ( $conns [ $server_id ] ) ) {
$conn = $conns [ $server_id ][ 'conn' ];
$status = $conns [ $server_id ][ 'stat' ];
// Status tells us, if we can use the same bind
if ( ! is_null ( $status ) && $status == $anonymous )
return $conn ;
} else {
$host = $servers [ $server_id ][ 'host' ];
$port = isset ( $servers [ $server_id ][ 'port' ] ) ? $servers [ $server_id ][ 'port' ] : false ;
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
if ( $port )
$conn = @ ldap_connect ( $host , $port );
else
$conn = @ ldap_connect ( $host );
2009-06-30 08:09:20 +00:00
2009-06-30 09:22:30 +00:00
$conn or pla_error ( sprintf ( $lang [ 'could_not_connect_to_host_on_port' ], htmlspecialchars ( $host ), htmlspecialchars ( $port ) ) );
2009-06-30 08:09:20 +00:00
2009-06-30 09:22:30 +00:00
// go with LDAP version 3 if possible (needed for renaming and Novell schema fetching)
@ ldap_set_option ( $conn , LDAP_OPT_PROTOCOL_VERSION , 3 );
// Disabling this makes it possible to browse the tree for Active Directory, and seems
// to not affect other LDAP servers (tested with OpenLDAP) as phpLDAPadmin explicitly
// specifies deref behavior for each ldap_search operation.
@ ldap_set_option ( $conn , LDAP_OPT_REFERRALS , 0 );
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
// try to fire up TLS is specified in the config
if ( tls_enabled ( $server_id ) ) {
function_exists ( 'ldap_start_tls' ) or pla_error ( $lang [ 'php_install_not_supports_tls' ] );
@ ldap_start_tls ( $conn ) or pla_error ( $lang [ 'could_not_start_tls' ]);
}
// store the cached connection resource
$conns [ $server_id ][ 'conn' ] = $conn ;
$conns [ $server_id ][ 'stat' ] = null ;
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
if ( $anonymous == true ) {
$login_dn = null ;
$login_pass = null ;
} // grab the auth info based on the auth_type for this server
elseif ( $servers [ $server_id ][ 'auth_type' ] == 'config' ) {
2009-06-30 08:05:37 +00:00
$login_dn = $servers [ $server_id ][ 'login_dn' ];
$login_pass = $servers [ $server_id ][ 'login_pass' ];
2009-06-30 09:22:30 +00:00
$login_dn = expand_dn_with_base ( $server_id , $login_dn , $conn , false );
} else {
2009-06-30 08:09:20 +00:00
$login_dn = get_logged_in_dn ( $server_id );
$login_pass = get_logged_in_pass ( $server_id );
2009-06-30 08:05:37 +00:00
// Was this an anonyous bind (the cookie stores 0 if so)?
2009-06-30 08:09:20 +00:00
if ( 'anonymous' == $login_dn ) {
2009-06-30 08:05:37 +00:00
$login_dn = null ;
$login_pass = null ;
}
}
$res = @ ldap_bind ( $conn , $login_dn , $login_pass );
2009-06-30 09:22:30 +00:00
if ( ! $res )
return ldap_errno ( $conn );
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
// store the bind status
$conns [ $server_id ][ 'stat' ] = $anonymous ;
2009-06-30 08:05:37 +00:00
return $conn ;
}
2009-06-30 09:22:30 +00:00
/**
* Convenient function to handle pla_ldap_connect results
* @ see pla_ldap_connect
*
* @ param resource $ds The pla_ldap_connect result
* @ param bool $process_error Defines , if you want do run pla_error
* @ return Returns false if the connection ( $ds ) is ok , or true otherwise .
*/
function pla_ldap_connection_is_error ( $ds , $process_error = true )
{
if ( ! $process_error )
return ( ! is_resource ( $ds ) );
else {
if ( ! is_resource ( $ds ) ) {
global $lang ;
if ( is_numeric ( $ds ) ) {
switch ( $ds ) {
case - 1 : pla_error ( $lang [ 'bad_server_id' ] ); break ;
case - 2 : pla_error ( $lang [ 'not_enough_login_info' ] ); break ;
default : pla_error ( $lang [ 'ferror_error' ] ); break ;
}
return true ;
}
switch ( $ds ) {
case 0x31 :
pla_error ( $lang [ 'bad_user_name_or_password' ] );
break ;
case 0x32 :
pla_error ( $lang [ 'insufficient_access_rights' ] );
break ;
case 0x5b :
pla_error ( $lang [ 'could_not_connect' ] );
break ;
default :
pla_error ( $lang [ 'could_not_bind' ], ldap_err2str ( $ds ), $ds );
break ;
}
}
return false ;
}
}
/**
* Gets a list of child entries for an entry . Given a DN , this function fetches the list of DNs of
* child entries one level beneath the parent . For example , for the following tree :
*
* < code >
* dc = example , dc = com
* ou = People
* cn = Dave
* cn = Fred
* cn = Joe
* ou = More People
* cn = Mark
* cn = Bob
* </ code >
*
* Calling < code > get_container_contents ( $server_id , " ou=people,dc=example,dc=com " ) </ code >
* would return the following list :
*
* < code >
* cn = Dave
* cn = Fred
* cn = Joe
* ou = More People
* </ code >
*
* @ param int $server_id The ID of the server housing the entry of interest
* @ param string $dn The DN of the entry whose children to return .
* @ param int $size_limit ( optional ) The maximum number of entries to return .
* If unspecified , no limit is applied to the number of entries in the returned .
* @ param string $filter ( optional ) An LDAP filter to apply when fetching children , example : " (objectClass=inetOrgPerson) "
* @ return array An array of DN strings listing the immediate children of the specified entry .
2009-06-30 08:05:37 +00:00
*/
2009-06-30 09:22:30 +00:00
function get_container_contents ( $server_id , $dn , $size_limit = 0 , $filter = '(objectClass=*)' , $deref = LDAP_DEREF_ALWAYS )
2009-06-30 08:05:37 +00:00
{
2009-06-30 09:22:30 +00:00
$conn = pla_ldap_connect ( $server_id );
if ( pla_ldap_connection_is_error ( $conn , false ) )
return false ;
2009-06-30 08:09:20 +00:00
2009-06-30 09:22:30 +00:00
// echo "get_container_contents( $server_id, $dn, $size_limit, $filter, $deref )\n";
$search = @ ldap_list ( $conn , $dn , $filter , array ( 'dn' ), 1 , $size_limit , 0 , $deref );
2009-06-30 08:05:37 +00:00
if ( ! $search )
return array ();
2009-06-30 09:22:30 +00:00
$search = ldap_get_entries ( $conn , $search );
2009-06-30 08:05:37 +00:00
$return = array ();
2009-06-30 08:07:14 +00:00
for ( $i = 0 ; $i < $search [ 'count' ]; $i ++ ) {
2009-06-30 08:05:37 +00:00
$entry = $search [ $i ];
$dn = $entry [ 'dn' ];
$return [] = $dn ;
}
return $return ;
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:09:20 +00:00
* Builds the initial tree that is stored in the session variable 'tree' .
2009-06-30 08:05:37 +00:00
* Simply returns an array with an entry for each active server in
2009-06-30 09:22:30 +00:00
* config . php . The structure of the returned array is simple , and looks like
* this :
* < code >
* Array (
* 0 => Array ( )
* 1 => Array ( )
* )
* </ code >
* This function is not meant as a user callable function , but rather a convenient ,
* automated method for setting up the initial structure for the tree viewer .
2009-06-30 08:05:37 +00:00
*/
function build_initial_tree ()
{
global $servers ;
$tree = array ();
foreach ( $servers as $id => $server ) {
if ( $server [ 'host' ] == '' ) {
continue ;
}
$tree [ $id ] = array ();
}
return $tree ;
}
2009-06-30 09:22:30 +00:00
/**
* Builds the initial array that stores the icon - lookup for each server ' s DN in the tree browser . The returned
* array is then stored in the current session . The structure of the returned array is simple , and looks like
* this :
* < code >
* Array
* (
* [ 0 ] => Array
* (
* [ dc = example , dc = com ] => " dcobject.png "
* )
* [ 1 ] => Array
(
* [ o = Corporation ] => " o.png "
* )
* )
* </ code >
* This function is not meant as a user - callable function , but rather a convenient , automated method for
* setting up the initial data structure for the tree viewer ' s icon cache .
2009-06-30 08:05:37 +00:00
*/
function build_initial_tree_icons ()
{
global $servers ;
$tree_icons = array ();
// initialize an empty array for each server
foreach ( $servers as $id => $server ) {
if ( $server [ 'host' ] == '' )
continue ;
$tree_icons [ $id ] = array ();
$tree_icons [ $id ][ $server [ 'base' ] ] = get_icon ( $id , $server [ 'base' ] );
}
return $tree_icons ;
}
2009-06-30 09:22:30 +00:00
/*
* Checks and fixes an initial session ' s tree cache if needed .
*
* This function is not meant as a user - callable function , but rather a convenient ,
* automated method for checking the initial data structure of the session .
*/
function initialize_session_tree ()
{
// From the PHP manual: If you use $_SESSION don't use
// session_register(), session_is_registered() or session_unregister()!
if ( ! array_key_exists ( 'tree' , $_SESSION ) )
$_SESSION [ 'tree' ] = build_initial_tree ();
if ( ! array_key_exists ( 'tree_icons' , $_SESSION ) )
$_SESSION [ 'tree_icons' ] = build_initial_tree_icons ();
// Make sure that the tree index is indeed well formed.
if ( ! is_array ( $_SESSION [ 'tree' ] ) )
$_SESSION [ 'tree' ] = build_initial_tree ();
if ( ! is_array ( $_SESSION [ 'tree_icons' ] ) )
$_SESSION [ 'tree_icons' ] = build_initial_tree_icons ();
}
/**
* Gets the operational attributes for an entry . Given a DN , this function fetches that entry ' s
* operational ( ie , system or internal ) attributes . These attributes include " createTimeStamp " ,
* " creatorsName " , and any other attribute that the LDAP server sets automatically . The returned
* associative array is of this form :
* < code >
* Array
* (
* [ creatorsName ] => Array
* (
* [ 0 ] => " cn=Admin,dc=example,dc=com "
* )
* [ createTimeStamp ] => Array
* (
* [ 0 ] => " 10401040130 "
* )
* [ hasSubordinates ] => Array
* (
* [ 0 ] => " FALSE "
* )
* )
* </ code >
*
* @ param int $server_id the ID of the server of interest .
* @ param string $dn The DN of the entry whose interal attributes are desired .
* @ param int $deref For aliases and referrals , this parameter specifies whether to
* follow references to the referenced DN or to fetch the attributes for
* the referencing DN . See http :// php . net / ldap_search for the 4 valid
* options .
* @ return array An associative array whose keys are attribute names and whose values
* are arrays of values for the aforementioned attribute .
*/
function get_entry_system_attrs ( $server_id , $dn , $deref = LDAP_DEREF_NEVER )
2009-06-30 08:05:37 +00:00
{
$conn = pla_ldap_connect ( $server_id );
2009-06-30 09:22:30 +00:00
if ( pla_ldap_connection_is_error ( $conn , false ) )
return false ;
2009-06-30 08:05:37 +00:00
2009-06-30 08:09:20 +00:00
$attrs = array ( 'creatorsname' , 'createtimestamp' , 'modifiersname' ,
'structuralObjectClass' , 'entryUUID' , 'modifytimestamp' ,
'subschemaSubentry' , 'hasSubordinates' , '+' );
2009-06-30 09:22:30 +00:00
$search = @ ldap_read ( $conn , $dn , '(objectClass=*)' , $attrs , 0 , 0 , 0 , $deref );
2009-06-30 08:05:37 +00:00
if ( ! $search )
return false ;
$entry = ldap_first_entry ( $conn , $search );
2009-06-30 08:10:17 +00:00
if ( ! $entry )
return false ;
2009-06-30 08:05:37 +00:00
$attrs = ldap_get_attributes ( $conn , $entry );
2009-06-30 08:10:17 +00:00
if ( ! $attrs )
return false ;
if ( ! isset ( $attrs [ 'count' ] ) )
return false ;
2009-06-30 08:07:14 +00:00
$count = $attrs [ 'count' ];
unset ( $attrs [ 'count' ] );
2009-06-30 08:09:20 +00:00
$return_attrs = array ();
2009-06-30 08:07:14 +00:00
for ( $i = 0 ; $i < $count ; $i ++ ) {
$attr_name = $attrs [ $i ];
unset ( $attrs [ $attr_name ][ 'count' ] );
$return_attrs [ $attr_name ] = $attrs [ $attr_name ];
}
return $return_attrs ;
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Gets the attributes / values of an entry . Returns an associative array whose
* keys are attribute value names and whose values are arrays of values for
* said attribute . Optionally , callers may specify true for the parameter
* $lower_case_attr_names to force all keys in the associate array ( attribute
* names ) to be lower case .
*
* Sample return value of < code > get_object_attrs ( 0 , " cn=Bob,ou=pepole,dc=example,dc=com " ) </ code >
2009-06-30 08:05:37 +00:00
*
2009-06-30 09:22:30 +00:00
* < code >
2009-06-30 08:05:37 +00:00
* Array
2009-06-30 09:22:30 +00:00
* (
* [ objectClass ] => Array
2009-06-30 08:05:37 +00:00
* (
2009-06-30 09:22:30 +00:00
* [ 0 ] => person
* [ 1 ] => top
2009-06-30 08:05:37 +00:00
* )
2009-06-30 09:22:30 +00:00
* [ cn ] => Array
* (
* [ 0 ] => Bob
* )
* [ sn ] => Array
* (
* [ 0 ] => Jones
* )
* [ dn ] => Array
* (
* [ 0 ] => cn = Bob , ou = pepole , dc = example , dc = com
* )
* )
* </ code >
*
* @ param int $server_id The ID of the server of interest
* @ param string $dn The distinguished name ( DN ) of the entry whose attributes / values to fetch .
* @ param bool $lower_case_attr_names ( optional ) If true , all keys of the returned associative
* array will be lower case . Otherwise , they will be cased as the LDAP server returns
* them .
* @ param int $deref For aliases and referrals , this parameter specifies whether to
* follow references to the referenced DN or to fetch the attributes for
* the referencing DN . See http :// php . net / ldap_search for the 4 valid
* options .
* @ return array
* @ see get_entry_system_attrs
* @ see get_object_attr
2009-06-30 08:05:37 +00:00
*/
2009-06-30 09:22:30 +00:00
function get_object_attrs ( $server_id , $dn , $lower_case_attr_names = false , $deref = LDAP_DEREF_NEVER )
2009-06-30 08:05:37 +00:00
{
2009-06-30 09:22:30 +00:00
//echo "get_object_attrs( $server_id, $dn, $lower_case_attr_names )<br />";
2009-06-30 08:05:37 +00:00
$conn = pla_ldap_connect ( $server_id );
2009-06-30 09:22:30 +00:00
if ( pla_ldap_connection_is_error ( $conn , false ) )
return false ;
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
$search = @ ldap_read ( $conn , $dn , '(objectClass=*)' , array ( ), 0 , 0 , 0 , $deref );
2009-06-30 08:09:20 +00:00
2009-06-30 08:05:37 +00:00
if ( ! $search )
return false ;
$entry = ldap_first_entry ( $conn , $search );
2009-06-30 08:09:20 +00:00
if ( ! $entry )
return false ;
2009-06-30 08:05:37 +00:00
$attrs = ldap_get_attributes ( $conn , $entry );
2009-06-30 08:09:20 +00:00
if ( ! $attrs || $attrs [ 'count' ] == 0 )
2009-06-30 08:05:37 +00:00
return false ;
$num_attrs = $attrs [ 'count' ];
unset ( $attrs [ 'count' ] );
2009-06-30 08:07:14 +00:00
// strip numerical inices
2009-06-30 08:05:37 +00:00
for ( $i = 0 ; $i < $num_attrs ; $i ++ )
unset ( $attrs [ $i ] );
$return_array = array ();
2009-06-30 09:22:30 +00:00
foreach ( $attrs as $attr => $vals ) {
2009-06-30 08:05:37 +00:00
if ( $lower_case_attr_names )
$attr = strtolower ( $attr );
2009-06-30 09:22:30 +00:00
if ( is_attr_binary ( $server_id , $attr ) )
$vals = ldap_get_values_len ( $conn , $entry , $attr );
2009-06-30 08:05:37 +00:00
unset ( $vals [ 'count' ] );
2009-06-30 08:07:14 +00:00
$return_array [ $attr ] = $vals ;
2009-06-30 08:05:37 +00:00
}
ksort ( $return_array );
return $return_array ;
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:09:20 +00:00
* Returns true if the passed string $temp contains all printable
2009-06-30 08:05:37 +00:00
* ASCII characters . Otherwise ( like if it contains binary data ),
* returns false .
*/
function is_printable_str ( $temp ) {
$len = strlen ( $temp );
for ( $i = 0 ; $i < $len ; $i ++ ) {
$ascii_val = ord ( substr ( $temp , $i , 1 ) );
if ( $ascii_val < 32 || $ascii_val > 126 )
return false ;
}
return true ;
}
2009-06-30 09:22:30 +00:00
/**
* Much like get_object_attrs (), but only returns the values for
* one attribute of an object . Example calls :
*
* < code >
* print_r ( get_object_attr ( 0 , " cn=Bob,ou=people,dc=example,dc=com " , " sn " ) );
* // prints:
* // Array
* // (
* // [0] => "Smith"
* // )
*
* print_r ( get_object_attr ( 0 , " cn=Bob,ou=people,dc=example,dc=com " , " objectClass " ) );
* // prints:
* // Array
* // (
* // [0] => "top"
* // [1] => "person"
* // )
* </ code >
*
* @ param int $server_id The ID of the server of interest
* @ param string $dn The distinguished name ( DN ) of the entry whose attributes / values to fetch .
* @ param string $attr The attribute whose value ( s ) to return ( ie , " objectClass " , " cn " , " userPassword " )
* @ param bool $lower_case_attr_names ( optional ) If true , all keys of the returned associative
* array will be lower case . Otherwise , they will be cased as the LDAP server returns
* them .
* @ param int $deref For aliases and referrals , this parameter specifies whether to
* follow references to the referenced DN or to fetch the attributes for
* the referencing DN . See http :// php . net / ldap_search for the 4 valid
* options .
* @ see get_object_attrs
2009-06-30 08:05:37 +00:00
*/
2009-06-30 09:22:30 +00:00
function get_object_attr ( $server_id , $dn , $attr , $deref = LDAP_DEREF_NEVER )
2009-06-30 08:05:37 +00:00
{
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:05:37 +00:00
$attr = strtolower ( $attr );
$attrs = get_object_attrs ( $server_id , $dn , true );
if ( isset ( $attrs [ $attr ] ) )
return $attrs [ $attr ];
else
return false ;
2009-06-30 09:22:30 +00:00
*/
//echo "get_object_attr( $server_id, $dn, $attr )<br />";
$conn = pla_ldap_connect ( $server_id );
if ( pla_ldap_connection_is_error ( $conn , false ) )
return false ;
$search = @ ldap_read ( $conn , $dn , '(objectClass=*)' , array ( $attr ), 0 , 0 , 0 , $deref );
if ( ! $search )
return false ;
$entry = ldap_first_entry ( $conn , $search );
if ( ! $entry )
return false ;
$attrs = ldap_get_attributes ( $conn , $entry );
if ( ! $attrs || $attrs [ 'count' ] == 0 )
return false ;
if ( is_attr_binary ( $server_id , $attr ) )
$vals = ldap_get_values_len ( $conn , $entry , $attr );
else
$vals = ldap_get_values ( $conn , $entry , $attr );
unset ( $vals [ 'count' ] );
return $vals ;
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* A handy ldap searching function very similar to PHP ' s ldap_search () with the
* following exceptions : Callers may specify a search scope and the return value
* is an array containing the search results rather than an LDAP result resource .
2009-06-30 08:09:20 +00:00
*
2009-06-30 09:22:30 +00:00
* Example usage :
* < code >
* $samba_users = ldap_search ( 0 , " (&(objectClass=sambaAccount)(objectClass=posixAccount)) " ,
* " ou=People,dc=example,dc=com " , array ( " uid " , " homeDirectory " ) );
* print_r ( $samba_users );
* // prints (for example):
* // Array
* // (
* // [uid=jsmith,ou=People,dc=example,dc=com] => Array
* // (
* // [dn] => "uid=jsmith,ou=People,dc=example,dc=com"
* // [uid] => "jsmith"
* // [homeDirectory] => "\\server\jsmith"
* // )
* // [uid=byoung,ou=People,dc=example,dc=com] => Array
* // (
* // [dn] => "uid=byoung,ou=Samba,ou=People,dc=example,dc=com"
* // [uid] => "byoung"
* // [homeDirectory] => "\\server\byoung"
* // )
* // )
* </ code >
*
* WARNING : This function will use a lot of memory on large searches since the entire result set is
* stored in a single array . For large searches , you should consider sing the less memory intensive
* PHP LDAP API directly ( ldap_search (), ldap_next_entry (), ldap_next_attribute (), etc ) .
*
* @ param int $server_id The ID of the server to search on .
* @ param string $filter The LDAP filter to use when searching ( example : " (objectClass=*) " ) ( see RFC 2254 )
* @ param string $base_dn The DN of the base of search .
* @ param array $attrs An array of attributes to include in the search result ( example : array ( " objectClass " , " uid " , " sn " )) .
* @ param string $scope The LDAP search scope . Must be one of " base " , " one " , or " sub " . Standard LDAP search scope .
* @ param bool $sort_results Specify false to not sort results by DN or true to have the
* returned array sorted by DN ( uses ksort )
* @ param int $deref When handling aliases or referrals , this specifies whether to follow referrals . Must be one of
* LDAP_DEREF_ALWAYS , LDAP_DEREF_NEVER , LDAP_DEREF_SEARCHING , or LDAP_DEREF_FINDING . See the PHP LDAP API for details .
2009-06-30 08:05:37 +00:00
*/
2009-06-30 09:22:30 +00:00
function pla_ldap_search ( $server_id , $filter , $base_dn = null , $attrs = array (), $scope = 'sub' , $sort_results = true , $deref = LDAP_DEREF_ALWAYS )
2009-06-30 08:05:37 +00:00
{
global $servers ;
2009-06-30 08:07:14 +00:00
if ( ! check_server_id ( $server_id ) )
2009-06-30 08:05:37 +00:00
return false ;
if ( $base_dn == null )
$base_dn = $servers [ $server_id ][ 'base' ];
2009-06-30 08:07:14 +00:00
2009-06-30 08:05:37 +00:00
$ds = pla_ldap_connect ( $server_id );
2009-06-30 09:22:30 +00:00
if ( pla_ldap_connection_is_error ( $ds , false ) )
2009-06-30 08:05:37 +00:00
return false ;
2009-06-30 08:07:14 +00:00
2009-06-30 08:05:37 +00:00
switch ( $scope ) {
case 'base' :
2009-06-30 09:22:30 +00:00
$search = @ ldap_read ( $ds , $base_dn , $filter , $attrs , 0 , 0 , 0 , $deref );
2009-06-30 08:05:37 +00:00
break ;
case 'one' :
2009-06-30 09:22:30 +00:00
$search = @ ldap_list ( $ds , $base_dn , $filter , $attrs , 0 , 0 , 0 , $defef );
2009-06-30 08:05:37 +00:00
break ;
case 'sub' :
default :
2009-06-30 09:22:30 +00:00
$search = @ ldap_search ( $ds , $base_dn , $filter , $attrs , 0 , 0 , 0 , $deref );
2009-06-30 08:05:37 +00:00
break ;
}
if ( ! $search )
return array ();
2009-06-30 08:09:20 +00:00
$return = array ();
2009-06-30 08:07:14 +00:00
//get the first entry identifier
if ( $entry_id = ldap_first_entry ( $ds , $search ) )
2009-06-30 08:05:37 +00:00
2009-06-30 08:07:14 +00:00
//iterate over the entries
while ( $entry_id ) {
2009-06-30 08:05:37 +00:00
2009-06-30 08:07:14 +00:00
//get the distinguished name of the entry
$dn = ldap_get_dn ( $ds , $entry_id );
//get the attributes of the entry
$attrs = ldap_get_attributes ( $ds , $entry_id );
$return [ $dn ][ 'dn' ] = $dn ;
//get the first attribute of the entry
if ( $attr = ldap_first_attribute ( $ds , $entry_id , $attrs ))
2009-06-30 08:09:20 +00:00
//iterate over the attributes
2009-06-30 08:07:14 +00:00
while ( $attr ){
if ( is_attr_binary ( $server_id , $attr ))
$values = ldap_get_values_len ( $ds , $entry_id , $attr );
else
$values = ldap_get_values ( $ds , $entry_id , $attr );
//get the number of values for this attribute
$count = $values [ 'count' ];
unset ( $values [ 'count' ]);
if ( $count == 1 )
$return [ $dn ][ $attr ] = $values [ 0 ];
else
$return [ $dn ][ $attr ] = $values ;
$attr = ldap_next_attribute ( $ds , $entry_id , $attrs );
} // end while attr
$entry_id = ldap_next_entry ( $ds , $entry_id );
2009-06-30 08:05:37 +00:00
2009-06-30 08:07:14 +00:00
} // end while entry_id
if ( $sort_results && is_array ( $return ) )
ksort ( $return );
return $return ;
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Reads the query , checks all values and sets defaults .
*
* @ param int $query_id The ID of the predefined query .
*
* @ return array The fixed query or null on error
*/
function get_cleaned_up_predefined_search ( $query_id )
{
global $queries ;
if ( ! isset ( $queries [ $query_id ] ) )
return null ;
$query = $queries [ $query_id ];
if ( isset ( $query [ 'server' ] ) && ( is_numeric ( $query [ 'server' ] ) ) )
$server_id = $query [ 'server' ];
else $server_id = 0 ;
$base = ( isset ( $query [ 'base' ] ) ) ? $query [ 'base' ] : null ;
$base = expand_dn_with_base ( $server_id , $base );
if ( isset ( $query [ 'filter' ] ) && strlen ( trim ( $query [ 'filter' ] ) ) > 0 )
$filter = $query [ 'filter' ];
else
$filter = 'objectclass=*' ;
$scope = isset ( $query [ 'scope' ] )
&& ( in_array ( $query [ 'scope' ], array ( 'base' , 'sub' , 'one' ) ) )
? $query [ 'scope' ] : 'sub' ;
if ( isset ( $query [ 'attributes' ] ) && strlen ( trim ( $query [ 'filter' ] ) ) > 0 )
$attrib = $query [ 'attributes' ];
else
$attrib = " dn, cn, sn, objectClass " ;
return array ( 'server' => $server_id , 'base' => $base ,
'filter' => $filter , 'scope' => $scope , 'attributes' => $attrib );
}
/**
* Transforms the user - configured search lists into arrays for use by other components of phpLDAPadmin .
* This may seem a little strange , and that ' s because it is strange .
*
* The function takes the comma - separated lists ( like the search result attribute list ) in config . php
2009-06-30 08:05:37 +00:00
* and turns them into arrays . Only call this ONCE per script . Any subsequent call will
2009-06-30 09:22:30 +00:00
* mess up the arrays . This function operates on global variables defined in config . php and is currently
* only used by search_form_simple . php
*
* For more details , just read the function 's code. It' s short and pretty straightforward .
2009-06-30 08:05:37 +00:00
*/
function process_config ()
{
global $search_result_attributes ;
$search_result_attributes = explode ( " , " , $search_result_attributes );
array_walk ( $search_result_attributes , " trim_it " );
global $search_attributes_display ;
$search_attributes_display = explode ( " , " , $search_attributes_display );
array_walk ( $search_attributes_display , " trim_it " );
global $search_attributes ;
$search_attributes = explode ( " , " , $search_attributes );
array_walk ( $search_attributes , " trim_it " );
2009-06-30 09:22:30 +00:00
if ( count ( $search_attributes ) != count ( $search_attributes_display ) )
pla_error ( $lang [ 'search_Attrs_wrong_count' ] );
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Trim a string in place ( call by reference ) Used to filter empty entries out of the arrays
2009-06-30 08:05:37 +00:00
* that we generate in process_config () .
2009-06-30 09:22:30 +00:00
*
* @ see process_config
2009-06-30 08:05:37 +00:00
*/
function trim_it ( & $str )
{
$str = trim ( $str );
}
2009-06-30 09:22:30 +00:00
/**
* Checks the specified server id for sanity . Ensures that the server is indeed in the configured
* list and active . This is used by many many scripts to ensure that valid server ID values
* are passed in POST and GET .
2009-06-30 08:05:37 +00:00
*/
function check_server_id ( $server_id )
{
global $servers ;
2009-06-30 09:22:30 +00:00
if ( ! is_numeric ( $server_id ) || ! isset ( $servers [ $server_id ] ) || ! isset ( $servers [ $server_id ][ 'host' ] ) || $servers [ $server_id ][ 'host' ] == '' )
2009-06-30 08:05:37 +00:00
return false ;
else
return true ;
}
2009-06-30 09:22:30 +00:00
/**
* Used to generate a random salt for crypt - style passwords . Salt strings are used
* to make pre - built hash cracking dictionaries difficult to use as the hash algorithm uses
* not only the user ' s password but also a randomly generated string . The string is
* stored as the first N characters of the hash for reference of hashing algorithms later .
*
2009-06-30 08:09:20 +00:00
* --- added 20021125 by bayu irawan < bayuir @ divnet . telkom . co . id > ---
2009-06-30 08:05:37 +00:00
* --- ammended 20030625 by S C Rigler < srigler @ houston . rr . com > ---
2009-06-30 09:22:30 +00:00
*
* @ param int $length The length of the salt string to generate .
* @ return string The generated salt string .
2009-06-30 08:05:37 +00:00
*/
function random_salt ( $length )
{
$possible = '0123456789' .
'abcdefghijklmnopqrstuvwxyz' .
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' .
'./' ;
$str = " " ;
mt_srand (( double ) microtime () * 1000000 );
while ( strlen ( $str ) < $length )
{
$str .= substr ( $possible , ( rand () % strlen ( $possible ) ), 1 );
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:05:37 +00:00
* Commented out following line because of problem
* with crypt function in update . php
* --- 20030625 by S C Rigler < srigler @ houston . rr . com > ---
*/
//$str = "\$1\$".$str."\$";
return $str ;
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:05:37 +00:00
* Goes through the user - configured server list and looks for an available server_id ,
2009-06-30 09:22:30 +00:00
* one that has specified enough information to login . This is for choosing the
* server to display in the drop - down box in search . php .
*
* @ return int The first available server ID found .
2009-06-30 08:05:37 +00:00
*/
function get_avail_server_id ()
{
global $servers ;
for ( $i = 0 ; $i < count ( $servers ); $i ++ )
if ( check_server_id ( $i ) && have_auth_info ( $i ) )
return $i ;
return false ;
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:09:20 +00:00
* Given a DN string , this returns the 'RDN' portion of the string .
2009-06-30 08:05:37 +00:00
* For example . given 'cn=Manager,dc=example,dc=com' , this function returns
* 'cn=Manager' ( it is really the exact opposite of get_container ()) .
2009-06-30 09:22:30 +00:00
*
* @ param string $dn The DN whose RDN to return .
* @ param bool $include_attrs If true , include attributes in the RDN string .
* See http :// php . net / ldap_explode_dn for details
*
* @ return string The RDN
* @ see get_container
2009-06-30 08:05:37 +00:00
*/
2009-06-30 08:07:14 +00:00
function get_rdn ( $dn , $include_attrs = 0 )
2009-06-30 08:05:37 +00:00
{
2009-06-30 08:07:14 +00:00
if ( $dn == null )
return null ;
$rdn = pla_explode_dn ( $dn , $include_attrs );
2009-06-30 09:22:30 +00:00
if ( 0 == count ( $rdn ) )
return $dn ;
2009-06-30 08:07:14 +00:00
if ( ! isset ( $rdn [ 0 ] ) )
2009-06-30 09:22:30 +00:00
return $dn ;
2009-06-30 08:05:37 +00:00
$rdn = $rdn [ 0 ];
return $rdn ;
}
2009-06-30 09:22:30 +00:00
/**
* Given a DN string , this returns the parent container portion of the string .
2009-06-30 08:05:37 +00:00
* For example . given 'cn=Manager,dc=example,dc=com' , this function returns
* 'dc=example,dc=com' .
2009-06-30 09:22:30 +00:00
*
* @ param string $dn The DN whose container string to return .
*
* @ return string The container
* @ see get_rdn
2009-06-30 08:05:37 +00:00
*/
function get_container ( $dn )
{
2009-06-30 09:22:30 +00:00
$parts = pla_explode_dn ( $dn );
if ( count ( $parts ) <= 1 )
return null ;
$container = $parts [ 1 ];
for ( $i = 2 ; $i < count ( $parts ); $i ++ )
$container .= ',' . $parts [ $i ];
2009-06-30 08:05:37 +00:00
return $container ;
}
2009-06-30 09:22:30 +00:00
/**
* Given an LDAP error number , returns a verbose description of the error .
2009-06-30 08:05:37 +00:00
* This function parses ldap_error_codes . txt and looks up the specified
* ldap error number , and returns the verbose message defined in that file .
2009-06-30 09:22:30 +00:00
*
* @ param string $err_no The hex error number ( ie , " 0x42 " ) of the LDAP error of interest .
* @ return array An associative array contianing the error title and description like so :
* < code >
* Array
* (
* [ title ] => " Invalid Credentials "
* [ description ] => " An invalid username and/or password was supplied to the LDAP server. "
* )
* </ code >
2009-06-30 08:05:37 +00:00
*/
function pla_verbose_error ( $err_no )
{
static $err_codes ;
if ( count ( $err_codes ) > 0 ) {
2009-06-30 09:22:30 +00:00
if ( isset ( $err_codes [ $err_no ] ) )
return $err_codes [ $err_no ];
else
return array ( 'title' => null , 'desc' => null );
}
2009-06-30 08:05:37 +00:00
$err_codes_file = 'ldap_error_codes.txt' ;
2009-06-30 08:07:14 +00:00
if ( ! file_exists ( realpath ( $err_codes_file ) ) )
2009-06-30 08:05:37 +00:00
return false ;
2009-06-30 08:09:20 +00:00
if ( ! is_readable ( realpath ( $err_codes_file ) ) )
2009-06-30 08:05:37 +00:00
return false ;
2009-06-30 08:07:14 +00:00
if ( ! ( $f = fopen ( realpath ( $err_codes_file ), 'r' ) ) )
2009-06-30 08:05:37 +00:00
return false ;
$contents = fread ( $f , filesize ( $err_codes_file ) );
2009-06-30 09:22:30 +00:00
fclose ( $f );
2009-06-30 08:09:20 +00:00
$entries = array ();
2009-06-30 08:05:37 +00:00
preg_match_all ( " /0x[A-Fa-f0-9][A-Za-z0-9] \ s+[0-9A-Za-z_]+ \ s+ \" [^ \" ]* \" \n / " , $contents , $entries );
$err_codes = array ();
2009-06-30 09:22:30 +00:00
foreach ( $entries [ 0 ] as $e ) {
2009-06-30 08:09:20 +00:00
$entry = array ();
2009-06-30 08:05:37 +00:00
preg_match ( " /(0x[A-Za-z0-9][A-Za-z0-9]) \ s+([0-9A-Za-z_]+) \ s+ \" ([^ \" ]*) \" / " , $e , $entry );
2009-06-30 09:22:30 +00:00
$hex_code = isset ( $entry [ 1 ] ) ? $entry [ 1 ] : null ;
$title = isset ( $entry [ 2 ] ) ? $entry [ 2 ] : null ;
$desc = isset ( $entry [ 3 ] ) ? $entry [ 3 ] : null ;
2009-06-30 08:05:37 +00:00
$desc = preg_replace ( " / \ s+/ " , " " , $desc );
2009-06-30 09:22:30 +00:00
$err_codes [ " $hex_code " ] = array ( 'title' => $title , 'desc' => $desc );
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
// Sanity check
if ( isset ( $err_codes [ $err_no ] ) )
return $err_codes [ $err_no ];
else
return array ( 'title' => null , 'desc' => null );
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Prints an HTML - formatted error string . If you specify the optional
* parameters $ldap_err_msg and $ldap_err_no , this function will
* lookup the error number and display a verbose message in addition
* to the message you pass it .
*
* @ param string $msg The error message to display .
* @ param string $ldap_err_msg ( optional ) The error message supplied by the LDAP server
* @ param string $ldap_err_no ( optional ) The hexadecimal error number string supplied by the LDAP server
* @ param bool $fatal ( optional ) If true , phpLDAPadmin will terminate execution with the PHP die () function .
*
* @ see die
* @ see ldap_errno
* @ see pla_verbose_error
2009-06-30 08:05:37 +00:00
*/
2009-06-30 08:09:20 +00:00
function pla_error ( $msg , $ldap_err_msg = null , $ldap_err_no =- 1 , $fatal = true )
2009-06-30 08:05:37 +00:00
{
2009-06-30 09:22:30 +00:00
@ include_once 'header.php' ;
2009-06-30 08:09:20 +00:00
global $lang ;
2009-06-30 08:05:37 +00:00
2009-06-30 08:07:14 +00:00
?>
< center >
< table class = " error " >< tr >< td class = " img " >< img src = " images/warning.png " /></ td >
2009-06-30 08:09:20 +00:00
< td >< center >< h2 >< ? php echo $lang [ 'ferror_error' ]; ?> </h2></center>
2009-06-30 08:07:14 +00:00
< ? php echo $msg ; ?>
< br />
2009-06-30 08:09:20 +00:00
< br />
2009-06-30 08:07:14 +00:00
< ? php
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
if ( $ldap_err_msg ) {
2009-06-30 08:09:20 +00:00
echo sprintf ( $lang [ 'ldap_said' ], htmlspecialchars ( $ldap_err_msg ));
2009-06-30 09:22:30 +00:00
echo '<br />' ;
}
2009-06-30 08:05:37 +00:00
if ( $ldap_err_no != - 1 ) {
$ldap_err_no = ( '0x' . str_pad ( dechex ( $ldap_err_no ), 2 , 0 , STR_PAD_LEFT ) );
$verbose_error = pla_verbose_error ( $ldap_err_no );
if ( $verbose_error ) {
2009-06-30 08:09:20 +00:00
echo sprintf ( $lang [ 'ferror_number' ], $ldap_err_no , $verbose_error [ 'title' ]);
2009-06-30 09:22:30 +00:00
echo '<br />' ;
2009-06-30 08:09:20 +00:00
echo sprintf ( $lang [ 'ferror_discription' ], $verbose_error [ 'desc' ]);
2009-06-30 08:05:37 +00:00
} else {
2009-06-30 08:09:20 +00:00
echo sprintf ( $lang [ 'ferror_number_short' ], $ldap_err_no );
2009-06-30 09:22:30 +00:00
echo '<br />' ;
2009-06-30 08:09:20 +00:00
echo $lang [ 'ferror_discription_short' ];
2009-06-30 08:05:37 +00:00
}
}
2009-06-30 08:07:14 +00:00
?>
< br />
2009-06-30 09:22:30 +00:00
<!-- Commented out due to too many false bug reports . : )
2009-06-30 08:07:14 +00:00
< br />
< center >
< small >
2009-06-30 08:09:20 +00:00
< ? php echo sprintf ( $lang [ 'ferror_submit_bug' ] , get_href ( 'add_bug' )); ?>
2009-06-30 09:22:30 +00:00
< ? php
if ( function_exists ( " debug_print_backtrace " ) )
debug_print_backtrace ();
?>
2009-06-30 08:07:14 +00:00
</ small >
</ center >
2009-06-30 09:22:30 +00:00
-->
2009-06-30 08:07:14 +00:00
</ td ></ tr ></ table >
</ center >
< ? php
2009-06-30 08:09:20 +00:00
if ( $fatal )
2009-06-30 09:22:30 +00:00
echo " </body> \n </html> " ;
2009-06-30 08:09:20 +00:00
die ();
}
2009-06-30 09:22:30 +00:00
/**
* phpLDAPadmin ' s custom error handling function . When a PHP error occurs ,
* PHP will call this function rather than printing the typical PHP error string .
* This provides phpLDAPadmin the ability to format an error message more " pretty "
* and provide a link for users to submit a bug report . This function is not to
* be called by users . It is exclusively for the use of PHP internally . If this
* function is called by PHP from within a context where error handling has been
* disabled ( ie , from within a function called with " @ " prepended ), then this
* function does nothing .
*
* @ param int $errno The PHP error number that occurred ( ie , E_ERROR , E_WARNING , E_PARSE , etc ) .
* @ param string $errstr The PHP error string provided ( ie , " Warning index " foo " is undefined)
* @ param string $file The file in which the PHP error ocurred .
* @ param int $lineno The line number on which the PHP error ocurred
*
* @ see set_error_handler
2009-06-30 08:09:20 +00:00
*/
function pla_error_handler ( $errno , $errstr , $file , $lineno )
{
global $lang ;
// error_reporting will be 0 if the error context occurred
// within a function call with '@' preprended (ie, @ldap_bind() );
// So, don't report errors if the caller has specifically
// disabled them with '@'
if ( 0 == ini_get ( 'error_reporting' ) || 0 == error_reporting () )
return ;
$file = basename ( $file );
$caller = basename ( $_SERVER [ 'PHP_SELF' ] );
$errtype = " " ;
switch ( $errno ) {
2009-06-30 09:22:30 +00:00
case E_STRICT : $errtype = " E_STRICT " ; break ;
2009-06-30 08:09:20 +00:00
case E_ERROR : $errtype = " E_ERROR " ; break ;
case E_WARNING : $errtype = " E_WARNING " ; break ;
case E_PARSE : $errtype = " E_PARSE " ; break ;
case E_NOTICE : $errtype = " E_NOTICE " ; break ;
case E_CORE_ERROR : $errtype = " E_CORE_ERROR " ; break ;
case E_CORE_WARNING : $errtype = " E_CORE_WARNING " ; break ;
case E_COMPILE_ERROR : $errtype = " E_COMPILE_ERROR " ; break ;
case E_COMPILE_WARNING : $errtype = " E_COMPILE_WARNING " ; break ;
case E_USER_ERROR : $errtype = " E_USER_ERROR " ; break ;
case E_USER_WARNING : $errtype = " E_USER_WARNING " ; break ;
case E_USER_NOTICE : $errtype = " E_USER_NOTICE " ; break ;
case E_ALL : $errtype = " E_ALL " ; break ;
default : $errtype = $lang [ 'ferror_unrecognized_num' ] . $errno ;
}
if ( $errno == E_NOTICE ) {
echo sprintf ( $lang [ 'ferror_nonfatil_bug' ], $errstr , $errtype , $file ,
$lineno , $caller , pla_version (), phpversion (), php_sapi_name (),
$_SERVER [ 'SERVER_SOFTWARE' ], get_href ( 'add_bug' ));
return ;
}
2009-06-30 09:22:30 +00:00
$server = isset ( $_SERVER [ 'SERVER_SOFTWARE' ] ) ? $_SERVER [ 'SERVER_SOFTWARE' ] : 'undefined' ;
$phpself = isset ( $_SERVER [ 'PHP_SELF' ] ) ? basename ( $_SERVER [ 'PHP_SELF' ] ) : 'undefined' ;
2009-06-30 08:09:20 +00:00
pla_error ( sprintf ( $lang [ 'ferror_congrats_found_bug' ], $errstr , $errtype , $file ,
2009-06-30 09:22:30 +00:00
$lineno , $phpself , pla_version (),
phpversion (), php_sapi_name (), $server ));
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
/**
2009-06-30 08:05:37 +00:00
* Reads the friendly_attrs array as defined in config . php and lower - cases all
* the keys . Will return an empty array if the friendly_attrs array is not defined
2009-06-30 09:22:30 +00:00
* in config . php . This is simply used so we can more easily lookup user - friendly
* attributes configured by the admin .
2009-06-30 08:05:37 +00:00
*/
function process_friendly_attr_table ()
{
require 'config.php' ;
global $friendly_attrs ;
$attrs_table = array ();
if ( isset ( $friendly_attrs ) && is_array ( $friendly_attrs ) )
foreach ( $friendly_attrs as $old_name => $new_name )
$attrs_table [ strtolower ( $old_name ) ] = $new_name ;
else
return array ();
return $attrs_table ;
}
2009-06-30 09:22:30 +00:00
/**
* Gets whether an entry exists based on its DN . If the entry exists ,
* returns true . Otherwise returns false .
*
* @ param int $server_id The ID of the server of interest
* @ param string $dn The DN\of the entry of interest .
*
* @ return bool
2009-06-30 08:05:37 +00:00
*/
function dn_exists ( $server_id , $dn )
{
if ( ! check_server_id ( $server_id ) )
return false ;
$ds = pla_ldap_connect ( $server_id );
2009-06-30 09:22:30 +00:00
if ( pla_ldap_connection_is_error ( $ds , false ) )
2009-06-30 08:05:37 +00:00
return false ;
$search_result = @ ldap_read ( $ds , $dn , 'objectClass=*' , array ( 'dn' ) );
2009-06-30 08:09:20 +00:00
2009-06-30 08:05:37 +00:00
if ( ! $search_result )
return false ;
$num_entries = ldap_count_entries ( $ds , $search_result );
if ( $num_entries > 0 )
return true ;
else
return false ;
}
2009-06-30 09:22:30 +00:00
/**
* Draw the jpegPhoto image ( s ) for an entry wrapped in HTML . Many options are available to
* specify how the images are to be displayed .
*
* Usage Examples :
* < code >
* draw_jpeg_photos ( 0 , " cn=Bob,ou=People,dc=example,dc=com " , " jpegPhoto " true , false , " border: 1px; width: 150px " );
* draw_jpeg_photos ( 1 , " cn=Fred,ou=People,dc=example,dc=com " );
* </ code >
*
* @ param int $server_id The ID of the server of interest .
* @ param string $dn The DN of the entry that contains the jpeg attribute you want to draw .
* @ param string $attr_name The name of the attribute containing the jpeg data ( usually 'jpegPhoto' ) .
* @ param bool $draw_delete_buttons If true , draws a button beneath the image titled 'Delete' allowing the user
* to delete the jpeg attribute by calling JavaScript function deleteAttribute () provided
* in the default modification template .
* @ param bool $draw_bytes_and_size If true , draw text below the image indicating the byte size and dimensions .
* @ param string $table_html_attrs Specifies optional CSS style attributes for the table tag .
*
* @ return void
2009-06-30 08:05:37 +00:00
*/
2009-06-30 09:22:30 +00:00
function draw_jpeg_photos ( $server_id , $dn , $attr_name = 'jpegPhoto' , $draw_delete_buttons = false ,
$draw_bytes_and_size = true , $table_html_attrs = 'align="left"' , $img_html_attrs = '' )
2009-06-30 08:05:37 +00:00
{
global $jpeg_temp_dir ;
global $jpeg_tmp_keep_time ;
2009-06-30 08:09:20 +00:00
global $lang ;
2009-06-30 08:05:37 +00:00
$conn = pla_ldap_connect ( $server_id );
2009-06-30 09:22:30 +00:00
if ( pla_ldap_connection_is_error ( $conn , false ) )
return ;
$search_result = ldap_read ( $conn , $dn , 'objectClass=*' , array ( $attr_name ) );
2009-06-30 08:05:37 +00:00
$entry = ldap_first_entry ( $conn , $search_result );
2009-06-30 09:22:30 +00:00
echo " <table $table_html_attrs ><td><center> \n \n " ;
2009-06-30 08:05:37 +00:00
// for each jpegPhoto in the entry, draw it (there may be only one, and that's okay)
2009-06-30 09:22:30 +00:00
$jpeg_data = @ ldap_get_values_len ( $conn , $entry , $attr_name );
if ( ! is_array ( $jpeg_data ) ) {
echo " Could not fetch jpeg data from LDAP server for attribute " . htmlspecialchars ( $attr_name );
return ;
}
2009-06-30 08:09:20 +00:00
for ( $i = 0 ; $i < $jpeg_data [ 'count' ]; $i ++ )
2009-06-30 08:05:37 +00:00
{
2009-06-30 08:09:20 +00:00
// ensures that the photo is written to the specified jpeg_temp_dir
$jpeg_temp_dir = realpath ( $jpeg_temp_dir . '/' );
2009-06-30 09:22:30 +00:00
if ( ! is_writable ( $jpeg_temp_dir ) )
pla_error ( 'Please set $jpeg_temp_dir to a writable directory in the phpLDAPadmin config.php' );
2009-06-30 08:10:17 +00:00
$jpeg_filename = tempnam ( $jpeg_temp_dir . '/' , 'pla' );
2009-06-30 09:22:30 +00:00
$outjpeg = @ fopen ( $jpeg_filename , " wb " );
if ( ! $outjpeg )
pla_error ( 'Could not write to the $jpeg_temp_dir directory (' . $jpeg_temp_dir . '). Please verify that your web server can write files there.' );
2009-06-30 08:05:37 +00:00
fwrite ( $outjpeg , $jpeg_data [ $i ]);
fclose ( $outjpeg );
$jpeg_data_size = filesize ( $jpeg_filename );
2009-06-30 09:22:30 +00:00
if ( $jpeg_data_size < 6 && $draw_delete_buttons ) {
2009-06-30 08:09:20 +00:00
echo $lang [ 'jpeg_contains_errors' ];
2009-06-30 09:22:30 +00:00
echo '<a href="javascript:deleteAttribute( \'' . $attr_name . '\' );" style="color:red; font-size: 75%">' . $lang [ 'delete_photo' ] . '</a>' ;
2009-06-30 08:05:37 +00:00
continue ;
}
2009-06-30 09:22:30 +00:00
if ( function_exists ( 'getimagesize' ) ) {
$jpeg_dimensions = @ getimagesize ( $jpeg_filename );
$width = $jpeg_dimensions [ 0 ];
$height = $jpeg_dimensions [ 1 ];
} else {
$width = 0 ;
$height = 0 ;
}
2009-06-30 08:05:37 +00:00
if ( $width > 300 ) {
$scale_factor = 300 / $width ;
$img_width = 300 ;
2009-06-30 08:09:20 +00:00
$img_height = $height * $scale_factor ;
2009-06-30 08:05:37 +00:00
} else {
$img_width = $width ;
$img_height = $height ;
}
2009-06-30 09:22:30 +00:00
echo " <img width= \" $img_width\ " height = \ " $img_height\ " $img_html_attrs
2009-06-30 08:05:37 +00:00
src = \ " view_jpeg_photo.php?file= " . basename ( $jpeg_filename ) . " \" /><br /> \n " ;
2009-06-30 09:22:30 +00:00
if ( $draw_bytes_and_size ) {
echo " <small> " . number_format ( $jpeg_data_size ) . " bytes. " ;
echo " $width x $height pixels.<br /></small> \n \n " ;
}
2009-06-30 08:05:37 +00:00
if ( $draw_delete_buttons )
{ ?>
<!-- JavaScript function deleteJpegPhoto () to be defined later by calling script -->
2009-06-30 09:22:30 +00:00
< a href = " javascript:deleteAttribute( '<?php echo $attr_name ; ?>' ); " style = " color:red; font-size: 75% " > Delete Photo </ a >
2009-06-30 08:05:37 +00:00
< ? php }
}
echo " </center></td></table> \n \n " ;
// If they have misconfigured their config.php, use default values
if ( ! isset ( $jpeg_tmp_keep_time ) )
$jpeg_tmp_keep_time = 120 ;
2009-06-30 09:22:30 +00:00
// If they set keep time to 0, we up it to 10 to allow the browser to fetch it before it is deleted.
2009-06-30 08:09:20 +00:00
if ( $jpeg_tmp_keep_time == 0 )
2009-06-30 08:05:37 +00:00
$jpeg_tmp_keep_time = 10 ;
// delete old jpeg files.
2009-06-30 09:22:30 +00:00
$jpegtmp_wildcard = " /^pla/ " ;
2009-06-30 08:05:37 +00:00
$handle = opendir ( $jpeg_temp_dir );
2009-06-30 09:22:30 +00:00
while ( ( $file = readdir ( $handle ) ) != false ) {
if ( preg_match ( $jpegtmp_wildcard , $file ) ) {
2009-06-30 08:05:37 +00:00
$file = " $jpeg_temp_dir / $file " ;
2009-06-30 09:22:30 +00:00
if ( ( time () - filemtime ( $file ) ) > $jpeg_tmp_keep_time )
@ unlink ( $file );
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
}
2009-06-30 08:09:20 +00:00
closedir ( $handle );
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Gets the root DN of the specified server_id , or false if it
* can 't find it (ie, the server won' t give it to us ) . This is
* used when the user leaves the $servers [ $i ][ 'base' ] value empty
* to auto - determine the root DN .
*
2009-06-30 08:05:37 +00:00
* Tested with OpenLDAP 2.0 , Netscape iPlanet , and Novell eDirectory 8.7 ( nldap . com )
* Please report any and all bugs !!
2009-06-30 09:22:30 +00:00
*
* @ param int $server_id The ID of the server whose root DN to fetch .
* @ return mixed The root DN of the server on success ( string ) or false on error .
2009-06-30 08:05:37 +00:00
*/
2009-06-30 09:22:30 +00:00
function try_to_get_root_dn ( $server_id , $ds = null )
2009-06-30 08:05:37 +00:00
{
2009-06-30 09:22:30 +00:00
if ( is_null ( $ds ) ) {
if ( ! check_server_id ( $server_id ) )
return false ;
2009-06-30 08:05:37 +00:00
2009-06-30 09:22:30 +00:00
if ( isset ( $_SESSION [ " pla_root_dn_ $server_id " ] ) )
return $_SESSION [ " pla_root_dn_ $server_id " ];
if ( ! have_auth_info ( $server_id ) )
return false ;
$ds = pla_ldap_connect ( $server_id );
if ( pla_ldap_connection_is_error ( $ds , false ) )
return false ;
}
2009-06-30 08:09:20 +00:00
2009-06-30 08:05:37 +00:00
$r = @ ldap_read ( $ds , '' , 'objectClass=*' , array ( 'namingContexts' ) );
if ( ! $r )
return false ;
$r = @ ldap_get_entries ( $ds , $r );
if ( isset ( $r [ 0 ][ 'namingcontexts' ][ 0 ] ) ) {
$root_dn = $r [ 0 ][ 'namingcontexts' ][ 0 ];
2009-06-30 09:22:30 +00:00
$_SESSION [ " pla_root_dn_ $server_id " ] = $root_dn ;
2009-06-30 08:05:37 +00:00
return $root_dn ;
} else {
return false ;
}
}
2009-06-30 09:22:30 +00:00
/**
* Hashes a password and returns the hash based on the specified enc_type .
*
* @ param string $password_clear The password to hash in clear text .
* @ param string $enc_type Standard LDAP encryption type which must be one of
* crypt , md5 , md5crypt , sha , smd5 , ssha , or clear .
* @ return string The hashed password .
2009-06-30 08:05:37 +00:00
*/
function password_hash ( $password_clear , $enc_type )
{
2009-06-30 08:09:20 +00:00
global $lang ;
2009-06-30 09:22:30 +00:00
$enc_type = strtolower ( $enc_type );
switch ( $enc_type )
{
case 'crypt' :
$new_value = '{CRYPT}' . crypt ( $password_clear , random_salt ( 2 ) );
break ;
case 'md5' :
$new_value = '{MD5}' . base64_encode ( pack ( 'H*' , md5 ( $password_clear ) ) );
break ;
case 'md5crypt' :
if ( ! defined ( 'CRYPT_MD5' ) || 0 == CRYPT_MD5 )
pla_error ( $lang [ 'install_not_support_md5crypt' ] );
$new_value = '{CRYPT}' . crypt ( $password_clear , '$1$' . random_salt ( 9 ) );
break ;
case 'blowfish' :
if ( ! defined ( 'CRYPT_BLOWFISH' ) || 0 == CRYPT_BLOWFISH )
pla_error ( $lang [ 'install_not_support_blowfish' ] );
$new_value = '{CRYPT}' . crypt ( $password_clear , '$2$' . random_salt ( 13 ) );
break ;
case 'sha' :
if ( function_exists ( 'mhash' ) ) {
$new_value = '{SHA}' . base64_encode ( mhash ( MHASH_SHA1 , $password_clear ) );
} else {
pla_error ( $lang [ 'install_no_mash' ] );
}
break ;
case 'ssha' :
if ( function_exists ( 'mhash' ) && function_exists ( 'mhash_keygen_s2k' ) ) {
mt_srand ( ( double ) microtime () * 1000000 );
$salt = mhash_keygen_s2k ( MHASH_SHA1 , $password_clear , substr ( pack ( " h* " , md5 ( mt_rand () ) ), 0 , 8 ), 4 );
$new_value = " { SSHA} " . base64_encode ( mhash ( MHASH_SHA1 , $password_clear . $salt ) . $salt );
} else {
pla_error ( $lang [ 'install_no_mash' ] );
}
break ;
case 'smd5' :
if ( function_exists ( 'mhash' ) && function_exists ( 'mhash_keygen_s2k' ) ) {
mt_srand ( ( double ) microtime () * 1000000 );
$salt = mhash_keygen_s2k ( MHASH_MD5 , $password_clear , substr ( pack ( " h* " , md5 ( mt_rand () ) ), 0 , 8 ), 4 );
$new_value = " { SMD5} " . base64_encode ( mhash ( MHASH_MD5 , $password_clear . $salt ) . $salt );
} else {
pla_error ( $lang [ 'install_no_mash' ] );
}
break ;
case 'clear' :
default :
$new_value = $password_clear ;
2009-06-30 08:05:37 +00:00
}
return $new_value ;
}
2009-06-30 09:22:30 +00:00
/**
* Given a clear - text password and a hash , this function determines if the clear - text password
* is the password that was used to generate the hash . This is handy to verify a user ' s password
* when all that is given is the hash and a " guess " .
* @ param String $hash The hash .
* @ param String $clear The password in clear text to test .
* @ return Boolean True if the clear password matches the hash , and false otherwise .
*/
function password_check ( $cryptedpassword , $plainpassword )
{
//echo "password_check( $cryptedpassword, $plainpassword )\n";
if ( preg_match ( " / { ([^}]+)}(.*)/ " , $cryptedpassword , $cypher ) ) {
$cryptedpassword = $cypher [ 2 ];
$_cypher = strtolower ( $cypher [ 1 ]);
} else {
$_cypher = NULL ;
}
switch ( $_cypher )
{
// SSHA crypted passwords
case 'ssha' :
$hash = base64_decode ( $cryptedpassword );
$salt = substr ( $hash , - 4 );
$new_hash = base64_encode ( mhash ( MHASH_SHA1 , $plainpassword . $salt ) . $salt );
if ( strcmp ( $cryptedpassword , $new_hash ) == 0 )
return true ;
else
return false ;
break ;
// Salted MD5
case 'smd5' :
$hash = base64_decode ( $cryptedpassword );
$salt = substr ( $hash , - 4 );
$new_hash = base64_encode ( mhash ( MHASH_MD5 , $plainpassword . $salt ) . $salt );
if ( strcmp ( $cryptedpassword , $new_hash ) == 0 )
return true ;
else
return false ;
break ;
// SHA crypted passwords
case 'sha' :
if ( 0 == strcasecmp ( password_hash ( $plainpassword , 'sha' ), " { SHA} " . $cryptedpassword ) )
return true ;
else
return false ;
break ;
// MD5 cryped passwords
case 'md5' :
if ( 0 == strcasecmp ( password_hash ( $plainpassword , 'md5' ), " { MD5} " . $cryptedpassword ) )
return true ;
else
return false ;
break ;
// Crypt passwords
case 'crypt' :
// Check if it's an crypted md5
if ( strstr ( $cryptedpassword , '$1$' ) ) {
list (, $type , $salt , $hash ) = explode ( '$' , $cryptedpassword );
if ( crypt ( $plainpassword , '$1$' . $salt ) == $cryptedpassword )
return true ;
else
return false ;
}
// Password is plain crypt
else {
if ( crypt ( $plainpassword , $cryptedpassword ) == $cryptedpassword )
return true ;
else
return false ;
}
break ;
// No crypt is given assume plaintext passwords are used
default :
if ( $plainpassword == $cryptedpassword )
return true ;
else
return false ;
break ;
}
}
function get_enc_type ( $user_password )
{
/* Capture the stuff in the { } to determine if this is crypt, md5, etc. */
$enc_type = null ;
if ( preg_match ( " / { ([^}]+)}/ " , $user_password , $enc_type ) )
$enc_type = strtolower ( $enc_type [ 1 ] );
else
return null ;
/* handle crypt types */
if ( 0 == strcasecmp ( $enc_type , 'crypt' ) ) {
$salt = null ;
if ( preg_match ( " / { [^}]+} \\ $ (.) \\ $ / " , $user_password , $salt ) )
$salt = $salt [ 1 ];
else
$salt = null ;
switch ( $salt ) {
case '' : // CRYPT_STD_DES
$enc_type = " crypt " ;
break ;
case '1' : // CRYPT_MD5
$enc_type = " md5crypt " ;
break ;
case '2' : // CRYPT_BLOWFISH
$enc_type = " blowfish " ;
break ;
default :
$enc_type = " crypt " ;
}
}
return $enc_type ;
}
/**
* Gets the default enc_type configured in config . php for the server indicated by $server_id ;
* @ param int $server_id The ID of the server of interest .
* @ return String The enc_type , like 'sha' , 'md5' , 'ssha' , 'md5crypt' , for example .
*/
function get_default_hash ( $server_id )
{
global $servers ;
if ( isset ( $servers [ $server_id ][ 'default_hash' ] ) )
return $servers [ $server_id ][ 'default_hash' ];
else
return null ;
}
/**
* Returns the phpLDAPadmin version currently running . The version
* is read from the file named VERSION .
*
* @ return string The current version as read from the VERSION file .
2009-06-30 08:05:37 +00:00
*/
function pla_version ()
{
2009-06-30 08:07:14 +00:00
if ( ! file_exists ( realpath ( 'VERSION' ) ) )
2009-06-30 08:05:37 +00:00
return 'unknown version' ;
2009-06-30 08:07:14 +00:00
$f = fopen ( realpath ( 'VERSION' ), 'r' );
$version = fread ( $f , filesize ( realpath ( 'VERSION' ) ) );
2009-06-30 08:05:37 +00:00
fclose ( $f );
return $version ;
}
2009-06-30 09:22:30 +00:00
/**
* Draws an HTML browse button which , when clicked , pops up a DN chooser dialog .
* @ param string $form_element The name of the form element to which this chooser
* dialog will publish the user ' s choice . The form element must be a member
* of a form with the " name " or " id " attribute set in the form tag , and the element
* must also define " name " or " id " for JavaScript to uniquely identify it .
* Example $form_element values may include " creation_form.container " or
* " edit_form.member_uid " . See / templates / modification / default . php for example usage .
* @ param bool $include_choose_text ( optional ) If true , the function draws the localized text " choose " to the right of the button .
*/
function draw_chooser_link ( $form_element , $include_choose_text = true )
2009-06-30 08:05:37 +00:00
{
2009-06-30 08:07:14 +00:00
global $lang ;
2009-06-30 08:05:37 +00:00
$href = " javascript:dnChooserPopup(' $form_element '); " ;
2009-06-30 08:07:14 +00:00
$title = $lang [ 'chooser_link_tooltip' ];
2009-06-30 09:22:30 +00:00
echo " <nobr><a href= \" $href\ " title = \ " $title\ " >< img class = \ " chooser \" src= \" images/find.png \" /></a> " ;
if ( $include_choose_text )
echo " <span class= \" x-small \" ><a href= \" $href\ " title = \ " $title\ " > " . $lang['fbrowse'] . " </ a ></ span > " ;
echo " </nobr> " ;
2009-06-30 08:07:14 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Explode a DN into an array of its RDN parts . This function is UTF - 8 safe
* and replaces the buggy PHP ldap_explode_dn () which does not properly
* handle UTF - 8 DNs and also causes segmentation faults with some inputs .
*
* @ param string $dn The DN to explode .
* @ param int $with_attriutes ( optional ) Whether to include attribute names ( see http :// php . net / ldap_explode_dn for details )
*
* @ return array An array of RDN parts of this format :
* < code >
* Array
* (
* [ 0 ] => uid = ppratt
* [ 1 ] => ou = People
* [ 2 ] => dc = example
* [ 3 ] => dc = com
* )
* </ code >
*/
function pla_explode_dn ( $dn , $with_attributes = 0 )
{
// replace "\," with the hexadecimal value for safe split
$var = preg_replace ( " / \\ \ ,/ " , " \\ \\ \\ \\ 2C " , $dn );
// split the dn
$result = explode ( " , " , $var );
//translate hex code into ascii for display
foreach ( $result as $key => $value )
$result [ $key ] = preg_replace ( " / \\ \ ([0-9A-Fa-f] { 2})/e " , " ''.chr(hexdec(' \\ 1')).'' " , $value );
return $result ;
}
/**
* Fetches the URL for the specified item . This is a convenience function for
* fetching project HREFs ( like bugs )
*
* @ param string $type One of " open_bugs " , " add_bug " , " donate " , or " add_rfe "
* ( rfe = request for enhancement )
* @ return string The URL to the requested item .
*/
function get_href ( $type )
{
/* We don ' t use SourceForge IDs any more
$group_id = " 61828 " ;
$bug_atid = " 498546 " ;
$rfe_atid = " 498549 " ;
*/
switch ( $type ) {
case 'open_bugs' : return " http://www.phpldapadmin.com/bugs/ " ;
case 'add_bug' : return " http://www.phpldapadmin.com/bugs/bug_report_page.php " ;
case 'add_rfe' : return get_href ( 'add_bug' );
case 'donate' : return " donate.php " ;
case 'help' : return " help.php " ;
default : return null ;
2009-06-30 08:07:14 +00:00
}
}
2009-06-30 08:09:20 +00:00
2009-06-30 09:22:30 +00:00
/**
* Returns the current time as a double ( including micro - seconds ) .
*
* @ return double The current time in seconds since the beginning of the UNIX epoch ( Midnight Jan . 1 , 1970 )
*/
function utime ()
2009-06-30 08:07:14 +00:00
{
2009-06-30 09:22:30 +00:00
$time = explode ( " " , microtime ());
$usec = ( double ) $time [ 0 ];
$sec = ( double ) $time [ 1 ];
return $sec + $usec ;
2009-06-30 08:07:14 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Converts an array to a query - string with the option to exclude certain variables
* from the returned query string . This is convenient if callers want to convert the
* current GET query string or POST array into a string and replace certain
* variables with their own .
*
* @ param array $array The associate array to convert whose form is such that the keys are the
* names of the variables and the values are said variables ' values like this :
* < code >
* Array
* (
* [ server_id ] = 0 ,
* [ dn ] = " dc=example,dc=com " ,
* [ attr ] = " sn "
* )
* </ code >
* This will produce a string like this : " server_id=0&dn=dc=example,dc=com&attr=sn "
* @ param array $exclude_vars ( optional ) An array of variables to exclude in the resulting string
* @ param bool $url_encode_ampersands ( optional ) By default , this function encodes all ampersand - separators
* as & amp ; but callers may dislabe this by specifying false here . For example , URLs on HTML
* pages should encode the ampersands but URLs in header ( " Location: http://example.com " ) should
* not be encoded .
* @ return string The string created from the array .
*/
function array_to_query_string ( $array , $exclude_vars = array (), $url_encode_ampersands = true )
2009-06-30 08:07:14 +00:00
{
2009-06-30 09:22:30 +00:00
if ( ! is_array ( $array ) )
return '' ;
if ( ! $array )
return '' ;
$str = '' ;
$i = 0 ;
foreach ( $array as $name => $val ) {
if ( ! in_array ( $name , $exclude_vars ) ) {
if ( $i > 0 )
if ( $url_encode_ampersands )
$str .= '&' ;
else
$str .= '&' ;
$str .= urlencode ( $name ) . '=' . urlencode ( $val );
$i ++ ;
}
}
return $str ;
2009-06-30 08:07:14 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Gets whether the admin has configured phpLDAPadmin to show the " Create New " link in the tree viewer .
* If $servers [ $server_id ][ 'show_create' ] is NOT set , then default to show the Create New item .
* If $servers [ $server_id ][ 'show_create' ] IS set , then return the value ( it should be true or false ) .
*
* @ param int $server_id The ID of the server of interest
* @ return bool True if the feature is enabled and false otherwise .
*/
function show_create_enabled ( $server_id )
2009-06-30 08:07:14 +00:00
{
2009-06-30 09:22:30 +00:00
global $servers ;
if ( isset ( $servers [ $server_id ][ 'show_create' ] ))
return $servers [ $server_id ][ 'show_create' ];
else
return true ;
2009-06-30 08:07:14 +00:00
}
/**
2009-06-30 09:22:30 +00:00
* Reverses a DN such that the top - level RDN is first and the bottom - level RDN is last
* For example :
* < code >
* cn = Brigham , ou = People , dc = example , dc = com
* </ code >
* Becomes :
* < code >
* dc = com , dc = example , ou = People , cn = Brigham
* </ code >
* This makes it possible to sort lists of DNs such that they are grouped by container .
*
* @ param string $dn The DN to reverse
*
* @ return string The reversed DN
*
* @ see pla_compare_dns
2009-06-30 08:07:14 +00:00
*/
2009-06-30 09:22:30 +00:00
function pla_reverse_dn ( $dn )
2009-06-30 08:07:14 +00:00
{
2009-06-30 09:22:30 +00:00
foreach ( pla_explode_dn ( $dn ) as $key => $branch ) {
// pla_expode_dn returns the array with an extra count attribute, we can ignore that.
if ( $key === " count " ) continue ;
if ( isset ( $rev )) {
$rev = $branch . " , " . $rev ;
} else {
$rev = $branch ;
}
}
return $rev ;
}
/**
* Determins if the specified attribute is contained in the $unique_attrs list
* configured in config . php .
* @ return Bool True if the specified attribute is in the $unique_attrs list and false
* otherwise .
*/
function is_unique_attr ( $attr_name )
{
global $unique_attrs ;
if ( isset ( $unique_attrs ) && is_array ( $unique_attrs ) ) {
foreach ( $unique_attrs as $attr )
if ( 0 === strcasecmp ( $attr_name , $attr ) )
return true ;
}
return false ;
2009-06-30 08:07:14 +00:00
}
/*
2009-06-30 09:22:30 +00:00
* This function will check whether the value for an attribute being changed
* is already assigned to another DN .
*
* Inputs :
* - server_id
* - dn that is being changed
* - attribute being changed
* - new values for the attribute
*
* Returns the bad value , or null if all values are OK
2009-06-30 08:07:14 +00:00
*/
2009-06-30 09:22:30 +00:00
function checkUniqueAttr ( $server_id , $dn , $attr_name , $new_value )
2009-06-30 08:07:14 +00:00
{
2009-06-30 09:22:30 +00:00
global $servers , $lang ;
$server_name = $servers [ $server_id ][ 'name' ];
// Is this attribute in the unique_attrs list?
if ( is_unique_attr ( $attr_name ) ) {
// Search the tree and make sure that attribute doesnt already exist to somebody else.
// Check see and use our alternate uid_dn and password if we have it.
$unique_attrs_dn = $servers [ $server_id ][ 'unique_attrs_dn' ];
$unique_attrs_pass = $servers [ $server_id ][ 'unique_attrs_dn_pass' ];
$need_to_unbind = false ;
if ( isset ( $unique_attrs_dn ) && $unique_attrs_dn != '' && isset ( $uniqe_attrs_pass ) )
{
$con = @ ldap_connect ( $servers [ $server_id ][ 'host' ], $servers [ $server_id ][ 'port' ] );
@ ldap_set_option ( $con , LDAP_OPT_PROTOCOL_VERSION , 3 );
// Bind with the alternate ID.
$res = @ ldap_bind ( $con , $unuque_attrs_dn , $unique_attrs_pass );
if ( ! $res ) pla_error ( sprintf ( $lang [ 'unique_attrs_invalid_credential' ] , $server_name ) );
$need_to_unbind = true ;
} else {
$con = pla_ldap_connect ( $server_id );
}
// Should this be in a function?
$base_dn = $servers [ $server_id ][ 'base' ];
if ( ! $base_dn )
$base_dn = try_to_get_root_dn ( $server_id );
// Build our search filter to double check each attribute.
$searchfilter = " (| " ;
foreach ( $new_value as $val ) {
$searchfilter .= " ( $attr_name = $val ) " ;
}
$searchfilter .= " ) " ;
// Do we need a sanity check to just in case $new_value was null and hence the search string is bad?
// Do the search
$search = @ ldap_search ( $con , $base_dn , $searchfilter , array ( 'dn' ), 0 , 0 , 0 , LDAP_DEREF_ALWAYS );
$search = ldap_get_entries ( $con , $search );
foreach ( $search as $result ) {
// Skip the count result and go to the array.
if ( ! is_array ( $result )) continue ;
// If one of the attributes is owned to somebody else, then we may as well die here.
if ( $result [ 'dn' ] != $dn ) {
return $val ;
}
}
if ( $need_to_unbind ) {
$res = @ ldap_unbind ( $con );
}
// If we get here, then it must be OK?
return ;
} else {
return ;
}
}
function sortAttrs ( $a , $b ) {
global $friendly_attrs ;
2009-06-30 08:10:17 +00:00
2009-06-30 09:22:30 +00:00
$a = strtolower ( ( isset ( $friendly_attrs [ strtolower ( $a ) ]) ? $friendly_attrs [ strtolower ( $a ) ] : $a ));
$b = strtolower ( ( isset ( $friendly_attrs [ strtolower ( $b ) ]) ? $friendly_attrs [ strtolower ( $b ) ] : $b ));
return strcmp ( $a , $b );
}
function userIsMember ( $server_id , $user , $group ) {
$group = get_object_attrs ( $server_id , $group , $deref = LDAP_DEREF_NEVER );
return ( is_array ( $group ) ? ( in_array ( $user , $group [ 'uniqueMember' ])) : false );
}
2009-06-30 08:10:17 +00:00
2009-06-30 09:22:30 +00:00
function arrayLower ( $array ) {
foreach ( $array as $key => $value ) {
$newarray [ $key ] = strtolower ( $value );
}
return $newarray ;
}
/**
* Strips all slashes from the specified array in place ( pass by ref ) .
* @ param Array $array The array to strip slashes from , typically one of
* $_GET , $_POST , or $_COOKIE .
*/
function array_stripslashes ( & $array )
{
if ( is_array ( $array ) )
while ( list ( $key ) = each ( $array ) )
if ( is_array ( $array [ $key ] ) && $key != $array )
array_stripslashes ( $array [ $key ] );
else
$array [ $key ] = stripslashes ( $array [ $key ] );
}
/**
* Gets a HTTP value via $_GET or $_POST
*
* @ param string $val The HTTP value too look for
* @ param any $default The default return value , if failed to get ( default = false )
* @ param bool $trim Trim a string value ( default = true )
* @ return string The HTTP value or the $default
*/
function http_get_value ( $val , $default = false , $trim = true )
{
$result = $default ;
if ( array_key_exists ( $val , $_GET ) )
$result = $_GET [ $val ];
elseif ( array_key_exists ( $val , $_POST ) )
$result = $_POST [ $val ];
if ( ( $result !== $default ) && ( $trim === true ) && is_string ( $result ) )
$result = trim ( $result );
2009-06-30 08:07:14 +00:00
return $result ;
}
2009-06-30 09:22:30 +00:00
/**
* Gets the USER_AGENT string from the $_SERVER array , all in lower case in
* an E_NOTICE safe manner .
* @ return String The user agent string as reported by the browser .
2009-06-30 08:07:14 +00:00
*/
2009-06-30 09:22:30 +00:00
function get_user_agent_string ()
{
if ( isset ( $_SERVER [ 'HTTP_USER_AGENT' ] ) )
return strtolower ( $_SERVER [ 'HTTP_USER_AGENT' ] );
else
return false ;
2009-06-30 08:05:37 +00:00
}
2009-06-30 09:22:30 +00:00
/**
* Determines whether the browser ' s operating system is UNIX ( or something like UNIX ) .
* @ return boolean True if the brower ' s OS is UNIX , false otherwise .
2009-06-30 08:09:20 +00:00
*/
2009-06-30 09:22:30 +00:00
function is_browser_os_unix ()
2009-06-30 08:09:20 +00:00
{
2009-06-30 09:22:30 +00:00
$agent = get_user_agent_string ();
if ( ! $agent )
return false ;
$unix_agent_strs = array (
'sunos' ,
'sunos 4' ,
'sunos 5' ,
'i86' ,
'irix' ,
'irix 5' ,
'irix 6' ,
'irix6' ,
'hp-ux' ,
'09.' ,
'10.' ,
'aix' ,
'aix 1' ,
'aix 2' ,
'aix 3' ,
'aix 4' ,
'inux' ,
'sco' ,
'unix_sv' ,
'unix_system_v' ,
'ncr' ,
'reliant' ,
'dec' ,
'osf1' ,
'dec_alpha' ,
'alphaserver' ,
'ultrix' ,
'alphastation' ,
'sinix' ,
'freebsd' ,
'bsd' ,
'x11' ,
'vax' ,
'openvms'
);
foreach ( $unix_agent_strs as $agent_str )
if ( strpos ( $agent , $agent_str ) !== false )
return true ;
return false ;
}
/**
* Determines whether the browser ' s operating system is Windows .
* @ return boolean True if the brower ' s OS is Windows , false otherwise .
*/
function is_browser_os_windows ()
{
$agent = get_user_agent_string ();
if ( ! $agent )
return false ;
$win_agent_strs = array (
'win' ,
'win95' ,
'windows 95' ,
'win16' ,
'windows 3.1' ,
'windows 16-bit' ,
'windows' ,
'win31' ,
'win16' ,
'winme' ,
'win2k' ,
'winxp' ,
'win98' ,
'windows 98' ,
'win9x' ,
'winnt' ,
'windows nt' ,
'win32' ,
'win32' ,
'32bit'
);
foreach ( $win_agent_strs as $agent_str )
if ( strpos ( $agent , $agent_str ) !== false )
return true ;
return false ;
}
/**
* Determines whether the browser ' s operating system is Macintosh .
* @ return boolean True if the brower ' s OS is mac , false otherwise .
*/
function is_browser_os_mac ()
{
$agent = get_user_agent_string ();
if ( ! $agent )
return false ;
$mac_agent_strs = array (
'mac' ,
'68000' ,
'ppc' ,
'powerpc'
);
foreach ( $mac_agent_strs as $agent_str )
if ( strpos ( $agent , $agent_str ) !== false )
return true ;
return false ;
}
/**
* Return posix group entries .
* @ return Array An associative array of posix group entries with attributes as keys , and values as values .
* @ param int $server_id The ID of the server to search .
* @ param string $base_dn The base of the search .
*/
function get_posix_groups ( $server_id , $base_dn = NULL ){
global $servers ;
if ( is_null ( $base_dn ) )
$base_dn = isset ( $servers [ $server_id ][ 'base' ] ) ? $servers [ $server_id ][ 'base' ] : try_to_get_root_dn ( $server_id );
$results = pla_ldap_search ( $server_id , " objectclass=posixGroup " , $base_dn , array () );
if ( ! $results )
return array ();
else
return $results ;
}
function get_default_search_display ()
{
global $default_search_display ;
if ( ! isset ( $default_search_display ) || is_null ( $default_search_display ) )
return 'list' ;
elseif ( 0 == strcasecmp ( $default_search_display , 'list' ) )
return 'list' ;
elseif ( 0 == strcasecmp ( $default_search_display , 'table' ) )
return 'table' ;
else
pla_error ( sprintf ( $lang [ 'bad_search_display' ], htmlspecialchars ( $default_search_display ) ) );
}
/**
* Checks if a string exists in an array , ignoring case .
*/
function in_array_ignore_case ( $needle , $haystack )
{
if ( ! is_array ( $haystack ) )
return false ;
if ( ! is_string ( $needle ) )
return false ;
foreach ( $haystack as $element )
if ( is_string ( $element ) && 0 == strcasecmp ( $needle , $element ) )
return true ;
return false ;
}
/**
* String padding
*
* @ param string input string
* @ param integer length of the result
* @ param string the filling string
* @ param integer padding mode
*
* @ return string the padded string
*
* @ access public ( taken from the phpMyAdmin source )
*/
function full_str_pad ( $input , $pad_length , $pad_string = '' , $pad_type = 0 ) {
$str = '' ;
$length = $pad_length - strlen ( $input );
if ( $length > 0 ) { // str_repeat doesn't like negatives
if ( $pad_type == STR_PAD_RIGHT ) { // STR_PAD_RIGHT == 1
$str = $input . str_repeat ( $pad_string , $length );
} elseif ( $pad_type == STR_PAD_BOTH ) { // STR_PAD_BOTH == 2
$str = str_repeat ( $pad_string , floor ( $length / 2 ));
$str .= $input ;
$str .= str_repeat ( $pad_string , ceil ( $length / 2 ));
} else { // defaults to STR_PAD_LEFT == 0
$str = str_repeat ( $pad_string , $length ) . $input ;
}
} else { // if $length is negative or zero we don't need to do anything
$str = $input ;
}
return $str ;
}
/**
* Gets the user configured $blowfish_secret from config . php .
*/
function get_blowfish_secret ()
{
global $blowfish_secret ;
if ( isset ( $blowfish_secret ) ) {
if ( trim ( $blowfish_secret ) == '' )
return null ;
else
return $blowfish_secret ;
} else
return null ;
}
/**
* Encryption using blowfish algorithm
*
* @ param string original data
* @ param string the secret
*
* @ return string the encrypted result
*
* @ access public
*
* @ author lem9 ( taken from the phpMyAdmin source )
*/
function pla_blowfish_encrypt ( $data , $secret = null )
{
include_once './blowfish.php' ;
if ( null === $secret ) {
$secret = get_blowfish_secret ();
if ( null === $secret )
pla_error ( 'phpLDAPadmin cannot safely encrypt your sensitive information, because $blowfish_secret is not set in config.php. You need to edit config.php and set $blowfish_secret to some secret string now.' );
}
$pma_cipher = new Horde_Cipher_blowfish ;
$encrypt = '' ;
for ( $i = 0 ; $i < strlen ( $data ); $i += 8 ) {
$block = substr ( $data , $i , 8 );
if ( strlen ( $block ) < 8 ) {
$block = full_str_pad ( $block , 8 , " \0 " , 1 );
}
$encrypt .= $pma_cipher -> encryptBlock ( $block , $secret );
}
return base64_encode ( $encrypt );
}
/**
* Decryption using blowfish algorithm
*
* @ param string encrypted data
* @ param string the secret
*
* @ return string original data
*
* @ access public
*
* @ author lem9 ( taken from the phpMyAdmin source )
*/
function pla_blowfish_decrypt ( $encdata , $secret = null )
{
// This cache gives major speed up for stupid callers :)
static $cache = array ();
if ( isset ( $cache [ $encdata ] ) )
return $cache [ $encdata ];
include_once './blowfish.php' ;
if ( null === $secret ) {
$secret = get_blowfish_secret ();
if ( null === $secret )
pla_error ( 'phpLDAPadmin cannot safely decrypt your sensitive information, because $blowfish_secret is not set in config.php. You need to edit config.php and set $blowfish_secret to some secret string now.' );
}
$pma_cipher = new Horde_Cipher_blowfish ;
$decrypt = '' ;
$data = base64_decode ( $encdata );
for ( $i = 0 ; $i < strlen ( $data ); $i += 8 ) {
$decrypt .= $pma_cipher -> decryptBlock ( substr ( $data , $i , 8 ), $secret );
}
$return = trim ( $decrypt );
$cache [ $encdata ] = $return ;
return $return ;
}
/**
* Gets the user configured $tree_display_format from config . php
*/
function get_tree_display_format ()
{
global $tree_display_format ;
if ( ! isset ( $tree_display_format ) || '' == trim ( $tree_display_format ) )
$tree_display_format = " %rdn " ;
return $tree_display_format ;
}
/**
* Gets a DN string using the user - configured tree_display_format string to format it .
*/
function draw_formatted_dn ( $server_id , $dn )
{
$format = get_tree_display_format ();
preg_match_all ( " /%[a-zA-Z_0-9]+/ " , $format , $tokens );
$tokens = $tokens [ 0 ];
foreach ( $tokens as $token ) {
if ( 0 == strcasecmp ( $token , '%dn' ) )
$format = str_replace ( $token , pretty_print_dn ( $dn ), $format );
elseif ( 0 == strcasecmp ( $token , '%rdn' ) )
$format = str_replace ( $token , pretty_print_dn ( get_rdn ( $dn ) ), $format );
elseif ( 0 == strcasecmp ( $token , '%rdnvalue' ) ) {
$rdn = get_rdn ( $dn );
$rdn_value = explode ( '=' , $rdn , 2 );
$rdn_value = $rdn_value [ 1 ];
$format = str_replace ( $token , $rdn_value , $format );
} else {
$attr_name = str_replace ( '%' , '' , $token );
$attr_values = get_object_attr ( $server_id , $dn , $attr_name );
if ( null == $attr_values )
$display = 'none' ;
elseif ( is_array ( $attr_values ) )
$display = htmlspecialchars ( implode ( ', ' , $attr_values ) );
else
$display = htmlspecialchars ( $attr_values );
$format = str_replace ( $token , $display , $format );
}
}
echo $format ;
2009-06-30 08:09:20 +00:00
}
2009-06-30 08:05:37 +00:00
?>