$class ) $object_classes[$i] = strtolower( $class ); // get the prefix (ie: dc, ou, cn, uid) $exploded_dn = ldap_explode_dn( $dn, 0 ); $rdn = $dn[0]; $prefix = explode( '=', $rdn ); $prefix = $prefix[0]; // Is it a person or some type of account/user? if( in_array( 'person', $object_classes ) || in_array( 'organizationalperson', $object_classes ) || in_array( 'inetorgperson', $object_classes ) || in_array( 'account', $object_classes ) || in_array( 'posixaccount', $object_classes ) ) return 'user.png'; // Is it an organization? elseif ( in_array( 'organization', $object_classes ) ) return 'o.png'; // Is it an organizational Unit? elseif( in_array( 'organizationalunit', $object_classes ) ) return 'ou.png'; // Is it a domain controler (dc) elseif( in_array( 'dcobject', $object_classes ) || in_array( 'domainrelatedobject', $object_classes ) ) return 'dc.png'; elseif( in_array( 'country', $object_classes ) ) return 'country.png'; elseif( in_array( 'jammvirtualdomain', $object_classes ) ) return 'mail.png'; elseif( in_array( 'locality', $object_classes ) ) return 'locality.png'; // Oh well, I don't know what it is. Use a generic icon. else return 'object.png'; } /* * Given a server_id, returns whether or not we have enough information * to authenticate against the server. For example, if the user specifies * '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. */ function have_auth_info( $server_id ) { global $servers; if( ! is_numeric( $server_id ) || ! isset( $servers[$server_id] ) ) return false; $server = $servers[$server_id]; if( $server['auth_type'] == 'form' ) { global $_COOKIE; if( isset( $_COOKIE[ 'pla_login_dn_' . $server_id ] ) && isset( $_COOKIE[ 'pla_pass_' . $server_id ] ) ) return true; else return false; } // whether or not the login_dn or pass is specified, we return // true here. (if they are blank, we do an anonymous bind anyway) elseif( $server['auth_type'] == 'config' ) { return true; } else { pla_error( "Error: You have an error in your config file. The only two allowed values for 'auth_type' in the $servers section are 'config' and 'form'. You entered '" . htmlspecialchars($server['auth_type']) . "', which is not allowed. " ); } } function get_logged_in_pass( $server_id ) { global $_COOKIE; $pass = $_COOKIE[ 'pla_login_pass_' . $server_id ]; if( $pass == '0' ) return false; else return $pass; } function get_logged_in_dn( $server_id ) { global $_COOKIE; $dn = $_COOKIE[ 'pla_login_dn_' . $server_id ]; if( $dn == '0' ) return 'Anonymous'; else return $dn; } /* * Specify a $server_id (0,1,2...) based on the order it appears in config.php. * The first is 0, the second is 1, etc. You rarely will need to consult * config.php since those values are usually generated dynamically in hrefs. */ function pla_ldap_connect( $server_id ) { if( ! check_server_id( $server_id ) ) return false; if( ! have_auth_info( $server_id ) ) return false; global $servers; // cache the connection, so if we are called multiple // times, we don't have to reauthenticate with the LDAP server static $conns; if( $conns[$server_id] ) return $conns[$server_id]; $host = $servers[$server_id]['host']; $port = $servers[$server_id]['port']; if( ! $port ) $port = 389; $conn = @ldap_connect( $host, $port ); if( ! $conn ) return false; // go with LDAP version 3 if possible (needed for renaming and Novell schema fetching) @ldap_set_option( $conn, LDAP_OPT_PROTOCOL_VERSION, 3 ); // try to fire up TLS is specified in the config if( $servers[ $server_id ][ 'tls' ] == true ) { function_exists( 'ldap_start_tls' ) or pla_error( "Your PHP install does not support TLS" ); @ldap_start_tls( $conn ) or pla_error( "Could not start TLS.
Please check your ". "LDAP server configuration." ); } // grab the auth info based on the auth_type for this server if( $servers[ $server_id ][ 'auth_type' ] == 'config' ) { $login_dn = $servers[$server_id]['login_dn']; $login_pass = $servers[$server_id]['login_pass']; } elseif( $servers[ $server_id ][ 'auth_type' ] == 'form' ) { global $_COOKIE; $login_dn = $_COOKIE['pla_login_dn_' . $server_id ]; $login_pass = $_COOKIE['pla_pass_' . $server_id ]; // Was this an anonyous bind (the cookie stores 0 if so)? if( '0' == $login_dn ) { $login_dn = null; $login_pass = null; } } else { pla_error( "You have an error in your config file. auth_type of " . htmlspecialchars( $servers[ $server_id ][ 'auth_type' ] ) . " is not valid." ); } $res = @ldap_bind( $conn, $login_dn, $login_pass ); if( ! $res ) return false; // store the cached connection resource $conns[$server_id] = $conn; return $conn; } /* * Returns an array listing the DNs contained by the specified $dn */ function get_container_contents( $server_id, $dn, $size_limit=0 ) { $con = pla_ldap_connect( $server_id ); if( ! $con ) return false; $search = @ldap_list( $con, $dn, 'objectClass=*', array( 'dn' ), 1, $size_limit ); if( ! $search ) return array(); $search = ldap_get_entries( $con, $search ); $return = array(); for( $i=0; $i<$search['count']; $i++ ) { $entry = $search[$i]; $dn = $entry['dn']; $return[] = $dn; } return $return; } /* * Builds the initial tree that is stored in the session variable 'tree'. * Simply returns an array with an entry for each active server in * config.php */ function build_initial_tree() { global $servers; $tree = array(); foreach( $servers as $id => $server ) { if( $server['host'] == '' ) { continue; /* $root_dn = try_to_get_root_dn( $id ); echo "Root is $root_dn
"; if( $root_dn ) $tree[$id][$root_dn] = array(); */ } $dn = $server['base']; $tree[$id] = array(); } return $tree; } /* * Builds the initial array that stores the icon-lookup for each DN in the tree browser */ 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; } function get_entry_system_attrs( $server_id, $dn ) { $conn = pla_ldap_connect( $server_id ); if( ! $conn ) return false; $search = @ldap_read( $conn, $dn, '(objectClass=*)', array("+"), 0, 200, 0, LDAP_DEREF_ALWAYS ); if( ! $search ) return false; $entry = ldap_first_entry( $conn, $search ); $attrs = ldap_get_attributes( $conn, $entry ); foreach( $attrs as $name => $vals ) if( is_numeric( $name ) || $name == 'count' ) unset( $attrs[$name] ); else $attrs[$name] = $vals[0]; return $attrs; } /* * Returns the attribute/value pairs for the given $dn on the given * $server_id. If the attribute is single valued, it will return * a single value for that attribute. Otherwise, it will return an * array of values for that attribute. Here's a sample return value: * * Array * ( * [objectclass] => Array * ( * [0] => organizationalRole * [1] => krb5principal * [2] => kerberosSecurityObject * ) * [cn] => Manager * [krbname] => phpldap@EXAMPLE.COM * [dn] => cn=Manager,dc=example,dc=com * ) */ function get_object_attrs( $server_id, $dn, $lower_case_attr_names = false ) { $conn = pla_ldap_connect( $server_id ); if( ! $conn ) return false; $search = @ldap_read( $conn, $dn, '(objectClass=*)' ); if( ! $search ) return false; $entry = ldap_first_entry( $conn, $search ); $attrs = ldap_get_attributes( $conn, $entry ); //$attrs = ldap_get_entries( $conn, $search ); if( ! $attrs || $attrs['count'] == 0 ) return false; //$attrs = $attrs[0]; $num_attrs = $attrs['count']; unset( $attrs['count'] ); for( $i=0; $i<$num_attrs; $i++ ) unset( $attrs[$i] ); $return_array = array(); foreach( $attrs as $attr => $vals ) { if( $lower_case_attr_names ) $attr = strtolower( $attr ); $count = $vals['count']; unset( $vals['count'] ); if( $count == 1 ) $return_array[ $attr ] = $vals[0]; else $return_array[ $attr ] = $vals; } ksort( $return_array ); return $return_array; } /* * Returns true if the passed string $temp contains all printable * 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; } /* * Much like get_object_attrs(), but only returns the entry for * one attribute of an object. Again, if the attribute contains * multiple values, returns an array of values. Otherwise, it * returns the single attribute value. * TODO: Don't call get_object_attrs() and filter. Do the actual ldap_read() ourselves (for efficiencey) */ function get_object_attr( $server_id, $dn, $attr ) { $attr = strtolower( $attr ); $attrs = get_object_attrs( $server_id, $dn, true ); if( isset( $attrs[$attr] ) ) return $attrs[$attr]; else return false; } /* * Returns true if $var is not white space only, and false otherwise. */ function not_white( $var ) { return trim($var) != "" ? true : false; } /* * Returns an associative array of objectClasses for the specified * $server_id. Each array entry's key is the name of the objectClass * in lower-case. * The sub-entries consist of sub-arrays called 'must_attrs' and * 'may_attrs', and sub-entries called 'oid', 'name' and 'description'. * * The bulk of this function came from the good code in the * GPL'ed LDAP Explorer project. Thank you. */ function get_schema_objectclasses( $server_id ) { $ds = pla_ldap_connect( $server_id ); if( ! $ds ) return false; // get all the objectClasses $result = @ldap_read($ds, 'cn=subschema', '(objectClass=*)', array( 'objectclasses' ), 0, 200, 0, LDAP_DEREF_ALWAYS ); if( ! $result ) $result = @ldap_read($ds, 'cn=schema', '(objectClass=*)', array( 'objectclasses' ), 0, 200, 0, LDAP_DEREF_ALWAYS ); if( ! $result ) return false; if( $result ) $raw_oclasses = ldap_get_entries($ds,$result ); // build the array of objectClasses $oclasses = array(); for( $att=0; $att < count( $raw_oclasses[0]["objectclasses"] ); $att++ ) { $class = $raw_oclasses[0]["objectclasses"][$att]; preg_match( "/[\s]+NAME[\s'\(]+([a-zA-Z0-9\-_]+)[\s'\)]/" , $class, $name); preg_match( "/[\s]+([\d\.]+)[\s]+NAME/", $class, $oid ); preg_match( "/[\s]+DESC[\s]+'([a-zA-Z0-9\-_ ]+)'/", $class, $description ); preg_match( "/[\s]+SUP[\s]+([a-zA-Z0-9\-_]+)[\s]/", $class, $sup ); $key = strtolower( trim( $name[1] ) ); $oclass_name = trim( $name[1] ); if( ! $key ) continue; $oclasses[$key] = array(); $oclasses[$key]['oid'] = trim( $oid[1] ); $oclasses[$key]['description'] = trim( $description[1] ); $oclasses[$key]['sup'] = trim( $sup[1] ); unset( $name ); unset( $syntax ); unset( $desription ); // get all the required attributes preg_match( "/MUST[\s\(]+([a-zA-Z0-9\s$]+)(MAY|\))/" , $class, $must_attrs ); $must_attrs = str_replace( ' ', '', $must_attrs[1] ); $oclasses[$key]['must_attrs'] = array_filter( explode( '$', $must_attrs ), "not_white" ); // get all the optional attributes preg_match( "/MAY[\s\(]+([a-zA-Z0-9\s$]+)(MUST|\))/" , $class, $may_attrs ); $may_attrs = str_replace( ' ', '', $may_attrs[1] ); $oclasses[$key]['may_attrs'] = array_filter( array_merge( $oclasses[$key]['must_attrs'], explode( '$', $may_attrs) ), "not_white" ); unset( $must_attrs ); unset( $may_attrs ); $oclasses[$key]['name'] = $oclass_name; } // go back and add any inherited MUST/MAY attrs to each objectClass foreach( $oclasses as $oclass => $attrs ) { $new_must = $attrs['must_attrs']; $new_may = $attrs['may_attrs']; $sup_attr = $attrs['sup']; while( $sup_attr && $sup_attr != "top" ) { $new_must = array_merge( $new_must, $oclasses[strtolower($sup_attr)]['must_attrs'] ); $new_may = array_merge( $new_may, $oclasses[strtolower($sup_attr)]['may_attrs'] ); $sup_attr = $oclasses[strtolower($sup_attr)]['sup']; } $oclasses[$oclass]['must_attrs'] = array_unique( $new_must ); $oclasses[$oclass]['may_attrs'] = array_unique( $new_may ); } ksort( $oclasses ); return $oclasses; } /* * Returns an associate array of the server's schema matching rules */ function get_schema_matching_rules( $server_id ) { static $cache; if( isset( $cache[$server_id] ) ) return $cache[$server_id]; $ds = pla_ldap_connect( $server_id ); if( ! $ds ) return false; // get all the attributeTypes $result = @ldap_read($ds, 'cn=subschema', '(objectClass=*)', array( 'matchingRules', 'matchingRuleUse' ), 0, 200, 0, LDAP_DEREF_ALWAYS ); if( ! $result ) $result = @ldap_read($ds, 'cn=schema', '(objectClass=*)', array( 'matchingRules', 'matchingRuleUse' ), 0, 200, 0, LDAP_DEREF_ALWAYS ); if( $result ) $raw = ldap_get_entries( $ds, $result ); else return( array() ); // build the array of attributes $rules = array(); for( $i=0; $i < $raw[0]['matchingrules']['count']; $i++ ) { $rule = $raw[0]['matchingrules'][$i]; preg_match( "/[\s]+([\d\.]+)[\s]+/", $rule, $oid); preg_match( "/[\s]+NAME[\s]+'([\)\(:?\.a-zA-Z0-9\-_ ]+)'/", $rule, $name ); $key = strtolower( trim( $oid[1] ) ); if( ! $key ) continue; $rules[$key] = $name[1]; //$rules[$key]['name'] = $name[1]; } ksort( $rules ); $cache[$server_id] = $rules; return $rules; } /* * Returns an associate array of the syntax OIDs that this LDAP server uses mapped to * their descriptions. */ function get_schema_syntaxes( $server_id ) { static $cache; if( isset( $cache[$server_id] ) ) return $cache[$server_id]; $ds = pla_ldap_connect( $server_id ); if( ! $ds ) return false; // get all the attributeTypes $result = @ldap_read($ds, 'cn=subschema', '(objectClass=*)', array( 'ldapSyntaxes' ), 0, 200, 0, LDAP_DEREF_ALWAYS ); if( ! $result ) $result = @ldap_read($ds, 'cn=schema', '(objectClass=*)', array( 'ldapSyntaxes' ), 0, 200, 0, LDAP_DEREF_ALWAYS ); if( $result ) $raw = ldap_get_entries( $ds, $result ); else return( array() ); // build the array of attributes $syntaxes = array(); for( $i=0; $i < $raw[0]['ldapsyntaxes']['count']; $i++ ) { $syntax = $raw[0]['ldapsyntaxes'][$i]; preg_match( "/[\s]+([\d\.]+)[\s]+/", $syntax, $oid); preg_match( "/[\s]+DESC[\s]+'([\)\(:?\.a-zA-Z0-9\-_ ]+)'/", $syntax, $description ); $key = strtolower( trim( $oid[1] ) ); if( ! $key ) continue; $syntaxes[$key] = array(); $syntaxes[$key]['description'] = $description[1]; } ksort( $syntaxes ); $cache[$server_id] = $syntaxes; return $syntaxes; } /* * Returns an associative array of attributes for the specified * $server_id. Each array entry's key is the name of the attribute, * in lower-case. * The sub-entries are 'oid', 'syntax', 'equality', 'substr', 'name', * and 'single_value'. * * The bulk of this function came from the good code in the * GPL'ed LDAP Explorer project. Thank you. It was extended * considerably for application here. */ function get_schema_attributes( $server_id ) { $ds = pla_ldap_connect( $server_id ); if( ! $ds ) return false; // get all the attributeTypes $result = @ldap_read($ds, 'cn=subschema', '(objectClass=*)', array( 'attributeTypes' ), 0, 200, 0, LDAP_DEREF_ALWAYS ); if( ! $result ) $result = @ldap_read($ds, 'cn=schema', '(objectClass=*)', array( 'attributeTypes' ), 0, 200, 0, LDAP_DEREF_ALWAYS ); if( $result ) $raw_attrs = ldap_get_entries( $ds, $result ); else $raw_attrs = array(); $syntaxes = get_schema_syntaxes( $server_id ); // build the array of attributes $attrs = array(); for( $i=0; $i < $raw_attrs[0]['attributetypes']['count']; $i++ ) { $attr = $raw_attrs[0]['attributetypes'][$i]; preg_match( "/[\s]+NAME[\s'\(]+([a-zA-Z0-9\-_]+)[\s'\)]/" , $attr, $name); preg_match( "/\s+NAME\s+'([a-zA-Z0-9\-_]+)'\s/" , $attr, $name); preg_match( "/[\s]+([\d\.]+)[\s]+NAME/", $attr, $oid ); preg_match( "/[\s]+DESC[\s]+'([\)\(:?\.a-zA-Z0-9\-_ ]+)'/", $attr, $description ); preg_match( "/[\s]+SYNTAX[\s]+([\d\.]+)/", $attr, $syntax); preg_match( "/[\s]+EQUALITY[\s]+([a-zA-Z]+)/", $attr, $equality); preg_match( "/[\s]+SUBSTR[\s]+([a-zA-Z]+)/", $attr, $substr); preg_match( "/[\s]+SUP[\s]+([a-zA-Z0-9\-_]+)/", $attr, $sup ); if( preg_match( "/[\s]+SINGLE-VALUE[\s]+/", $attr, $single_value ) ) $single_value = 'Yes'; else $single_value = 'No'; // If this schema attribute has multiple names (like: "NAME ( 'uid' 'userid' )"), then we need // to create a matching attribute entry for each name it bares. if( preg_match( "/\s+NAME\s+\(\s*['\sa-zA-Z0-9\-_]+\s*\)/", $attr, $multi_name ) ) { $multi_name = $multi_name[0]; preg_match_all( "/'([a-zA-Z0-9\-_]+)'/", $multi_name, $multiple_names ); $multiple_names = $multiple_names[1]; //print_r( $multiple_names ); foreach( $multiple_names as $name ) { $key = strtolower( trim( $name ) ); $attr_name = trim( $name ); if( ! $key ) continue; $attrs[$key] = array(); $attrs[$key]['oid'] = trim( $oid[1] ); $attrs[$key]['description'] = trim( $description[1] ); $attrs[$key]['syntax'] = trim( $syntax[1] ); $attrs[$key]['type'] = $syntaxes[ trim($syntax[1]) ]['description']; $attrs[$key]['equality'] = trim( $equality[1] ); $attrs[$key]['substr'] = trim( $substr[1] ); $attrs[$key]['single_value'] = $single_value; $attrs[$key]['sup'] = trim( $sup[1] ); $attrs[$key]['name'] = $attr_name; $count = 1; for( $j=0; $j $desc ) { $sup_attr = $desc['sup']; while( $sup_attr ) { if( ! $attrs[ $sup_attr ]['sup'] ) { $attrs[ $attr ][ 'syntax' ] = $attrs[ $sup_attr ]['syntax']; $attrs[ $attr ][ 'equality' ] = $attrs[ $sup_attr ]['equality']; $attrs[ $attr ][ 'substr' ] = $attrs[ $sup_attr ]['substr']; $attrs[ $attr ][ 'single_value' ] = $attrs[ $sup_attr ]['single_value']; break; } else { $sup_attr = $attrs[ $sup_attr ]['sup']; } } } ksort( $attrs ); return $attrs; } /* * A wrapper function to save you from having to call get_schema_objectclasses() * and get_schema_attributes(). Returns an array with two indexes: 'oclasses' * and 'attributes', as defined by their respective functions above. */ function get_schema( $server_id ) { $ds = pla_ldap_connect( $server_id ); if( ! $ds ) return false; $attrs = get_schema_attributes($server_id, $lower_case_all ); $oclasses = get_schema_objectclasses($server_id, $lower_case_all ); if( ! $oclasses ) return false; $schema = array( 'attrs' => $attrs, 'oclasses' => $oclasses ); return $schema; } /* * A do-it-all ldap_search function. You can even specify the search scope. Other than * that, it's pretty much the same as the PHP ldap_search() call, except it returns * an array of results, rather than an LDAP result resource. */ function pla_ldap_search( $server_id, $filter, $base_dn=null, $attrs=array(), $scope='sub', $sort_results=true ) { global $servers; if( ! isset($servers[$server_id]) || $servers[$server_id]['host'] == '' ) return false; if( $base_dn == null ) $base_dn = $servers[$server_id]['base']; $ds = pla_ldap_connect( $server_id ); if( ! $ds ) return false; switch( $scope ) { case 'base': $search = @ldap_read( $ds, $base_dn, $filter, $attrs ); break; case 'one': $search = @ldap_list( $ds, $base_dn, $filter, $attrs ); break; case 'sub': default: $search = @ldap_search( $ds, $base_dn, $filter, $attrs ); break; } if( ! $search ) return array(); $search = ldap_get_entries( $ds, $search ); $return = array(); foreach( $search as $id => $attrs ) { if( ! is_array( $attrs ) ) continue; for( $i=0; $i<$attrs['count']; $i++ ) unset( $attrs[$i] ); $dn = $attrs['dn']; foreach( $attrs as $attr => $vals ) { $count = $vals['count']; unset( $vals['count'] ); if( $count == 1 ) $return[$dn][$attr] = $vals[0]; else $return[$dn][$attr] = $vals; } } if( $sort_results ) ksort( $return ); return $return; } /* * Transforms the user-configured lists into arrays and such. This is a little weird, but * it takes the comma-separated lists (like the search result attribute list) in config.php * and turns them into arrays. Only call this ONCE per script. Any subsequent call will * mess up the arrays. This function operates only on global variables defined in config.php. */ 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" ); global $search_criteria_options; $search_criteria_options= explode( ",", $search_criteria_options); array_walk( $search_criteria_options, "trim_it" ); } /* * Call-by-reference to trim a string. Used to filter empty entries out of the arrays * that we generate in process_config(). */ function trim_it( &$str ) { $str = trim($str); } /* * Checks the server id for sanity. Ensures that the server is indeed in the configured list and active */ function check_server_id( $server_id ) { global $servers; if( ! is_numeric( $server_id ) || ! isset( $servers[$server_id] ) || $servers[$server_id]['host'] == '' ) return false; else return true; } /* * Used to generate a random salt for crypt-style passwords * --- added 20021125 by bayu irawan --- * --- ammended 20030625 by S C Rigler --- */ 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 ); } /* * Commented out following line because of problem * with crypt function in update.php * --- 20030625 by S C Rigler --- */ //$str = "\$1\$".$str."\$"; return $str; } /* * Goes through the user-configured server list and looks for an available server_id, * ie one that has specified enough information to login. This is for choosing the * server to display in the drop-down box in search.php mostly. */ function get_avail_server_id() { global $servers; for( $i=0; $i 0 ) { return $err_codes[ $err_no ]; } else { } $err_codes_file = 'ldap_error_codes.txt'; if( ! file_exists( $err_codes_file ) ) return false; if( ! is_readable( $err_codes_file ) ) return false; if( ! ($f = fopen( $err_codes_file, 'r' )) ) return false; $contents = fread( $f, filesize( $err_codes_file ) ); preg_match_all( "/0x[A-Fa-f0-9][A-Za-z0-9]\s+[0-9A-Za-z_]+\s+\"[^\"]*\"\n/", $contents, $entries ); $err_codes = array(); foreach( $entries[0] as $e ) { preg_match( "/(0x[A-Za-z0-9][A-Za-z0-9])\s+([0-9A-Za-z_]+)\s+\"([^\"]*)\"/", $e, $entry ); $hex_code = $entry[1]; $title = $entry[2]; $desc = $entry[3]; $desc = preg_replace( "/\s+/", " ", $desc ); $err_codes[ $hex_code ] = array( 'title' => $title, 'desc' => $desc ); } return $err_codes[ $err_no ]; } /* * Spits out an HTML-formatted error string. If you specify the optional * parameters, pla_error will lookup the error number and display a * verbose message in addition to the message you pass it. */ function pla_error( $msg, $ldap_err_msg=null, $ldap_err_no=-1 ) { include_once 'header.php'; echo "
"; echo "
\n\n"; echo "

Error

\n\n"; echo "
$msg
"; echo "

\n"; if( $ldap_err_msg ) echo "LDAP Server Said: " . htmlspecialchars( $ldap_err_msg ) . "

\n"; 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 ) { echo "Error number: $ldap_err_no (" . $verbose_error['title'] . ")

\n"; echo "Description: " . $verbose_error['desc'] . "

\n\n"; } else { echo "Error number: $ldap_err_no

\n"; echo "Description: (no description available)
\n\n"; } } echo "
\n"; echo "
"; die(); } /* * 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 * in config.php. */ 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; } /* * Returns true if the specified DN exists on the specified server, or false otherwise */ function dn_exists( $server_id, $dn ) { if( ! check_server_id( $server_id ) ) return false; $ds = pla_ldap_connect( $server_id ); if( ! $ds ) return false; $search_result = @ldap_read( $ds, $dn, 'objectClass=*', array('dn') ); if( ! $search_result ) return false; $num_entries = ldap_count_entries( $ds, $search_result ); if( $num_entries > 0 ) return true; else return false; } /* * Given a DN and server_id, this draws fetches the jpegPhoto binary data and echo's the * HTML necesary to draw it. You can optionally have it draw the 'delete' button below * each image. This function supports multiple jpegPhotos. */ function draw_jpeg_photos( $server_id, $dn, $draw_delete_buttons=false ) { global $jpeg_temp_dir; global $jpeg_tmp_keep_time; $conn = pla_ldap_connect( $server_id ); $search_result = ldap_search( $conn, $dn, 'objectClass=*', array( 'jpegPhoto' ) ); $entry = ldap_first_entry( $conn, $search_result ); echo "
\n\n"; // for each jpegPhoto in the entry, draw it (there may be only one, and that's okay) $jpeg_data = ldap_get_values_len( $conn, $entry, "jpegphoto"); for( $i=0; $i<$jpeg_data['count']; $i++ ) { $jpeg_filename = $jpeg_temp_dir . '/' . basename( tempnam ('.', 'djp') ); $outjpeg = fopen($jpeg_filename, "wb"); fwrite($outjpeg, $jpeg_data[$i]); fclose ($outjpeg); $jpeg_data_size = filesize( $jpeg_filename ); if( $jpeg_data_size < 6 ) { echo "jpegPhoto contains errors
"; echo 'Delete Photo'; continue; } $jpeg_dimensions = getimagesize ($jpeg_filename); $width = $jpeg_dimensions[0]; $height = $jpeg_dimensions[1]; if( $width > 300 ) { $scale_factor = 300 / $width; $img_width = 300; $img_height = $height * $scale_factor; } else { $img_width = $width; $img_height = $height; } echo "
\n"; echo "" . number_format($jpeg_data_size) . " bytes. "; echo "$width x $height pixels.
\n\n"; if( $draw_delete_buttons ) { ?> Delete Photo
\n\n"; // If they have misconfigured their config.php, use default values if( ! isset( $jpeg_tmp_keep_time ) ) $jpeg_tmp_keep_time = 120; if( $jpeg_tmp_keep_time == 0 ) $jpeg_tmp_keep_time = 10; // delete old jpeg files. $jpegtmp_wildcard = "djp.*"; $handle = opendir($jpeg_temp_dir); while (($file = readdir($handle)) != false) if (eregi($jpegtmp_wildcard, $file)) { $file = "$jpeg_temp_dir/$file"; if ((time() - filemtime($file)) > $jpeg_tmp_keep_time) unlink ( $file ); } closedir($handle); } /* * Returns 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). * Tested with OpenLDAP 2.0, Netscape iPlanet, and Novell eDirectory 8.7 (nldap.com) * Please report any and all bugs!! */ function try_to_get_root_dn( $server_id ) { if( ! have_auth_info( $server_id ) ) return false; $ds = pla_ldap_connect( $server_id ); if( ! $ds ) return false; $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]; return $root_dn; } else { return false; } } /* * Hashes a password and returns the hash based on the enc_type, which can be one of * crypt, md5, sha, or clear. */ function password_hash( $password_clear, $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': $new_value = '{crypt}' . crypt( $password_clear , '$1$' . random_salt(9) ); break; case '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( "Your PHP install does not have the mhash() function." . " Cannot do SHA hashes." ); } break; case 'clear': default: $new_value = $password_clear; } return $new_value; } /* * Returns the version as a string as stored in the VERSION file. */ function pla_version() { if( ! file_exists( 'VERSION' ) ) return 'unknown version'; $f = fopen( 'VERSION', 'r' ); $version = fread( $f, filesize( 'VERSION' ) ); fclose( $f ); return $version; } function draw_chooser_link( $form_element ) { $href = "javascript:dnChooserPopup('$form_element');"; echo ""; echo "browse\n"; } ?>