From 647f86562f1b84b4777e91d1cc31cf6aab237a0f Mon Sep 17 00:00:00 2001 From: Deon George Date: Tue, 30 Jun 2009 21:52:55 +1000 Subject: [PATCH] RELEASE 1.1.0.6 --- INSTALL | 4 +- VERSION | 2 +- config/config.php.example | 34 +- doc/uidpool.schema | 11 + htdocs/add_attr.php | 32 +- htdocs/add_attr_form.php | 6 +- htdocs/add_oclass.php | 14 +- htdocs/add_oclass_form.php | 12 +- htdocs/add_value.php | 18 +- htdocs/add_value_form.php | 23 +- htdocs/compare.php | 40 +- htdocs/compare_form.php | 4 +- htdocs/copy.php | 25 +- htdocs/copy_form.php | 7 +- htdocs/create.php | 30 +- htdocs/css/style.css | 27 +- htdocs/delete.php | 19 +- htdocs/delete_attr.php | 18 +- htdocs/delete_form.php | 5 +- htdocs/download_binary_attr.php | 23 +- htdocs/draw_tree_node.php | 65 +- htdocs/entry_chooser.php | 11 +- htdocs/export.php | 18 +- htdocs/export_form.php | 3 +- htdocs/images/compare.png | Bin 665 -> 662 bytes htdocs/images/debug-cache.png | Bin 648 -> 661 bytes htdocs/images/favicon.ico | Bin 902 -> 902 bytes htdocs/images/files.png | Bin 1113 -> 1165 bytes htdocs/images/light-big.png | Bin 1985 -> 1950 bytes htdocs/images/logo-small.png | Bin 0 -> 7053 bytes htdocs/images/logo.jpg | Bin 16958 -> 0 bytes htdocs/images/logo.png | Bin 0 -> 42594 bytes htdocs/images/logo_small.jpg | Bin 3611 -> 0 bytes htdocs/images/notice.png | Bin 2295 -> 2293 bytes htdocs/images/smile-big.png | Bin 1364 -> 1332 bytes htdocs/images/timeout.png | Bin 608 -> 661 bytes htdocs/index.php | 40 +- htdocs/ldif_import.php | 15 +- htdocs/ldif_import_form.php | 8 +- htdocs/login.php | 4 +- htdocs/login_form.php | 10 +- htdocs/logout.php | 8 +- htdocs/mass_delete.php | 18 +- htdocs/modify_member_form.php | 19 +- htdocs/password_checker.php | 5 +- htdocs/purge_cache.php | 4 +- htdocs/rdelete.php | 33 +- htdocs/refresh.php | 4 +- htdocs/rename.php | 18 +- htdocs/rename_form.php | 6 +- htdocs/schema.php | 29 +- htdocs/search.php | 22 +- htdocs/server_info.php | 8 +- htdocs/show_cache.php | 5 +- htdocs/template_engine.php | 7 +- htdocs/timeout.php | 41 - htdocs/update.php | 30 +- htdocs/update_confirm.php | 17 +- htdocs/view_jpeg_photo.php | 12 +- htdocs/welcome.php | 4 +- lib/AJAXTree.php | 22 +- lib/Attribute.php | 7 +- lib/DefaultCreatingEntry.php | 6 +- lib/DefaultEditingEntry.php | 12 +- lib/Entry.php | 15 +- lib/EntryReader.php | 12 +- lib/EntryWriter1.php | 423 +- lib/EntryWriter2.php | 8 +- lib/HTMLTree.php | 67 +- lib/PLMTree.php | 6 +- lib/TemplateCreatingEntry.php | 7 +- lib/TemplateEditingEntry.php | 21 +- lib/blowfish.php | 8 +- lib/common.php | 48 +- lib/config_default.php | 20 +- lib/emuhash_functions.php | 4 +- lib/export_functions.php | 8 +- lib/functions.php | 295 +- lib/hooks.php | 41 +- lib/page.php | 26 +- lib/schema_functions.php | 42 +- lib/search_results_list.php | 4 +- lib/search_results_table.php | 4 +- lib/server_functions.php | 257 +- lib/session_functions.php | 4 +- lib/template_functions.php | 17 +- lib/timeout_functions.php | 5 +- locale/ca_ES/LC_MESSAGES/messages.mo | Bin 22265 -> 12923 bytes locale/ca_ES/LC_MESSAGES/messages.po | 3643 ++++++++++++---- locale/cs_CZ/LC_MESSAGES/messages.mo | Bin 36410 -> 25630 bytes locale/cs_CZ/LC_MESSAGES/messages.po | 4387 ++++++++++++------- locale/de_DE/LC_MESSAGES/messages.mo | Bin 39181 -> 30513 bytes locale/de_DE/LC_MESSAGES/messages.po | 4487 ++++++++++++------- locale/es_ES/LC_MESSAGES/messages.mo | Bin 46157 -> 47968 bytes locale/es_ES/LC_MESSAGES/messages.po | 5249 ++++++++++++++--------- locale/fi_FI/LC_MESSAGES/messages.mo | Bin 46798 -> 36725 bytes locale/fi_FI/LC_MESSAGES/messages.po | 2369 ++++++---- locale/fr_FR/LC_MESSAGES/messages.mo | Bin 51716 -> 49414 bytes locale/fr_FR/LC_MESSAGES/messages.po | 4814 +++++++++++---------- locale/hu_HU/LC_MESSAGES/messages.mo | Bin 36853 -> 26215 bytes locale/hu_HU/LC_MESSAGES/messages.po | 4381 ++++++++++++------- locale/it_IT/LC_MESSAGES/messages.mo | Bin 47520 -> 47454 bytes locale/it_IT/LC_MESSAGES/messages.po | 852 ++-- locale/ja_JP/LC_MESSAGES/messages.mo | Bin 41228 -> 35933 bytes locale/ja_JP/LC_MESSAGES/messages.po | 4882 +++++++++++---------- locale/pl_PL/LC_MESSAGES/messages.mo | Bin 47545 -> 48423 bytes locale/pl_PL/LC_MESSAGES/messages.po | 950 ++-- locale/pt_BR/LC_MESSAGES/messages.mo | Bin 36811 -> 36915 bytes locale/pt_BR/LC_MESSAGES/messages.po | 4390 ++++++++++++------- locale/ru_RU/LC_MESSAGES/messages.mo | Bin 45388 -> 32707 bytes locale/ru_RU/LC_MESSAGES/messages.po | 4427 ++++++++++++------- locale/zh_CN/LC_MESSAGES/messages.mo | Bin 45880 -> 30895 bytes locale/zh_CN/LC_MESSAGES/messages.po | 5186 +++++++++++++--------- templates/creation/alias.xml | 9 +- templates/creation/mozillaOrgPerson.xml | 80 +- tools/po/make_mo_all | 4 +- tools/unit_test.php | 150 - tools/unserialize.php | 26 + 118 files changed, 32686 insertions(+), 19807 deletions(-) create mode 100755 doc/uidpool.schema create mode 100644 htdocs/images/logo-small.png delete mode 100644 htdocs/images/logo.jpg create mode 100644 htdocs/images/logo.png delete mode 100644 htdocs/images/logo_small.jpg delete mode 100644 htdocs/timeout.php delete mode 100644 tools/unit_test.php create mode 100644 tools/unserialize.php diff --git a/INSTALL b/INSTALL index 2f150fe..e079b12 100644 --- a/INSTALL +++ b/INSTALL @@ -1,5 +1,5 @@ For install instructions in non-English languages, see the wiki: - http://phpldapadmin.wiki.sourceforge.net + http://phpldapadmin.sourceforge.net * Requirements @@ -17,7 +17,7 @@ For install instructions in non-English languages, see the wiki: * For additional help See the wiki: - http://phpldapadmin.wiki.sourceforge.net + http://phpldapadmin.sourceforge.net Join our mailing list: https://lists.sourceforge.net/lists/listinfo/phpldapadmin-devel diff --git a/VERSION b/VERSION index ab8bba9..09636ab 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -$Name: RELEASE-1_1_0_5 $ +$Name: RELEASE-1_1_0_6 $ diff --git a/config/config.php.example b/config/config.php.example index faa0be0..f8d1d4e 100644 --- a/config/config.php.example +++ b/config/config.php.example @@ -134,11 +134,17 @@ $config->custom->commands['all'] = array( An AttributeFactory defines which class to use to represent a given attribute */ // $config->custom->appearance['attribute_factory'] = "AttributeFactory"; +/* Just show your custom templates. */ +// $config->custom->appearance['custom_templates_only'] = false; + +/* Disable the default template. */ +// $config->custom->appearance['disable_default_template'] = false; + /* Configure what objects are shown in left hand tree */ // $config->custom->appearance['tree_filter'] = '(objectclass=*)'; /* The height and width of the tree. If these values are not set, then - no tree scroll bars are provided. + no tree scroll bars are provided. */ // $config->custom->appearance['tree_height'] = null; # $config->custom->appearance['tree_height'] = 600; // $config->custom->appearance['tree_width'] = null; @@ -270,7 +276,8 @@ $ldapservers->SetValue($i,'server','name','My LDAP Server'); authentication with dn. This is useful, when users should be able to log in with their uid, but the ldap administrator wants to log in with his root-dn, that does not - necessarily have the uid attribute. */ + necessarily have the uid attribute. + When using this feature, login_class is ignored. */ // $ldapservers->SetValue($i,'login','fallback_dn',false); /* If you specified 'cookie' or 'session' as the auth_type above, and you @@ -314,7 +321,7 @@ $ldapservers->SetValue($i,'server','name','My LDAP Server'); // $ldapservers->SetValue($i,'auto_number','min','1000'); /* The DN of the uidPool entry when 'uidpool' mechanism is used above. */ -# $servers[$i]['auto_uid_number_uid_pool_dn'] = 'cn=uidPool,dc=example,dc=com'; +// $ldapservers->SetValue($i,'auto_number','uidpool_dn','cn=uidPool,dc=example,dc=com'); /* If you set this, then phpldapadmin will bind to LDAP with this user ID when searching for the uidnumber. The idea is, this user id would have full @@ -364,6 +371,25 @@ $ldapservers->SetValue($i,'server','name','My LDAP Server'); has children. Certain servers are known to allow it, certain are not */ // $ldapservers->SetValue($i,'server','branch_rename',false); +/* If you set this, then phpldapadmin will show these attributes as + internal attributes, even if they are not defined in your schema. */ +// $ldapservers->SetValue($i,'server','custom_sys_attrs',array('')); +# $ldapservers->SetValue($i,'server','custom_sys_attrs',array('passwordExpirationTime','passwordAllowChangeTime')); + +/* If you set this, then phpldapadmin will show these attributes on + objects, even if they are not defined in your schema. */ +// $ldapservers->SetValue($i,'server','custom_attrs',array('')); +# $ldapservers->SetValue($i,'server','custom_attrs',array('nsRoleDN','nsRole','nsAccountLock')); + +/* These attributes will be forced to MAY attributes and become option in the + templates. If they are not defined in the templates, then they wont appear + as per normal template processing. You may want to do this becuase your LDAP + server may automatically calculate a default value. + In Fedora Directory Server using the DNA Plugin one could ignore uidNumber, + gidNumber and sambaSID. */ +// $ldapservers->SetValue($i,'force_may','attrs',array('')); +# $ldapservers->SetValue($i,'force_may','attrs',array('uidNumber','gidNumber','sambaSID')); + /************************************************************************** * If you want to configure additional LDAP servers, do so below. * * Remove the commented lines and use this section as a template for all * @@ -494,7 +520,7 @@ $friendly_attrs['uid'] = 'User Name'; /*********************************************/ /* Add "modify group members" link to the attribute. */ -// $config->custom->modify_member['groupattr'] = array('member','uniqueMember','memberUid') +// $config->custom->modify_member['groupattr'] = array('member','uniqueMember','memberUid'); /* Configure filter for member search. This only applies to "modify group members" feature */ // $config->custom->modify_member['filter'] = '(objectclass=Person)'; diff --git a/doc/uidpool.schema b/doc/uidpool.schema new file mode 100755 index 0000000..7154740 --- /dev/null +++ b/doc/uidpool.schema @@ -0,0 +1,11 @@ +## +## Used for storing the next gid and next uid in the the directory +## +objectclass ( 1.3.6.1.4.1.7165.1.2.2.3 NAME 'uidPool' SUP top AUXILIARY + DESC 'Pool for allocating UNIX uids' + MUST ( uidNumber $ cn ) ) + + +objectclass ( 1.3.6.1.4.1.7165.1.2.2.4 NAME 'gidPool' SUP top AUXILIARY + DESC 'Pool for allocating UNIX gids' + MUST ( gidNumber $ cn ) ) diff --git a/htdocs/add_attr.php b/htdocs/add_attr.php index 6bb205f..574e4f1 100644 --- a/htdocs/add_attr.php +++ b/htdocs/add_attr.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if (! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_add')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('add attribute'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('add attribute')),'error','index.php'); +$entry = array(); $entry['val'] = get_request('val','POST'); $entry['binary'] = get_request('binary','POST'); @@ -34,7 +35,7 @@ $entry['attr']['string'] = get_request('attr','POST'); $entry['attr']['encode'] = rawurlencode($entry['attr']['string']); if ((strlen($entry['binary']) <= 0) && (strlen($entry['val']) <= 0)) - pla_error(_('You left the attribute value blank. Please go back and try again.')); + error(_('You left the attribute value blank. Please go back and try again.'),'error','index.php'); /* * Special case for binary attributes (like jpegPhoto and userCertificate): @@ -48,44 +49,44 @@ if ($badattr = $ldapserver->checkUniqueAttr($entry['dn']['string'],$entry['attr' $href = htmlspecialchars(sprintf('cmd.php?cmd=search&search=true&form=advanced&server_id=%s&filter=%s=%s', $ldapserver->server_id,$entry['attr']['string'],$badattr)); - pla_error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'),$entry['attr']['string'],$badattr,$entry['dn']['string'],$href)); + error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'),$entry['attr']['string'],$badattr,$entry['dn']['string'],$href),'error','index.php'); } if (strlen($entry['binary']) > 0) { if ($_FILES['val']['size'] == 0) - pla_error(_('The file you chose is either empty or does not exist. Please go back and try again.')); + error(_('The file you chose is either empty or does not exist. Please go back and try again.'),'error','index.php'); if (! is_uploaded_file($_FILES['val']['tmp_name'])) { if (isset($_FILES['val']['error'])) switch($_FILES['val']['error']) { case 0: # No error; possible file attack! - pla_error(_('Security error: The file being uploaded may be malicious.')); + error(_('Security error: The file being uploaded may be malicious.'),'error','index.php'); break; case 1: # Uploaded file exceeds the upload_max_filesize directive in php.ini - pla_error(_('The file you uploaded is too large. Please check php.ini, upload_max_size setting')); + error(_('The file you uploaded is too large. Please check php.ini, upload_max_size setting'),'error','index.php'); break; case 2: # Uploaded file exceeds the MAX_FILE_SIZE directive specified in the html form - pla_error(_('The file you uploaded is too large. Please check php.ini, upload_max_size setting')); + error(_('The file you uploaded is too large. Please check php.ini, upload_max_size setting'),'error','index.php'); break; case 3: # Uploaded file was only partially uploaded - pla_error(_('The file you selected was only partially uploaded, likley due to a network error.')); + error(_('The file you selected was only partially uploaded, likley due to a network error.'),'error','index.php'); break; case 4: # No file was uploaded - pla_error(_('You left the attribute value blank. Please go back and try again.')); + error(_('You left the attribute value blank. Please go back and try again.'),'error','index.php'); break; default: # A default error, just in case! :) - pla_error(_('Security error: The file being uploaded may be malicious.')); + error(_('Security error: The file being uploaded may be malicious.'),'error','index.php'); break; } else - pla_error(_('Security error: The file being uploaded may be malicious.')); + error(_('Security error: The file being uploaded may be malicious.'),'error','index.php'); } $binaryfile['name'] = $_FILES['val']['tmp_name']; @@ -125,7 +126,10 @@ if ($result) { die(); } else { - pla_error(_('Failed to add the attribute.'),$ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Failed to add the attribute.'), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); } /** diff --git a/htdocs/add_attr_form.php b/htdocs/add_attr_form.php index 76feae6..4455163 100644 --- a/htdocs/add_attr_form.php +++ b/htdocs/add_attr_form.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); +$entry = array(); $entry['dn']['string'] = get_request('dn','GET'); $entry['rdn'] = get_rdn($entry['dn']['string']); @@ -24,6 +25,7 @@ printf('

%s %s

',_('Add new attribute'),htmlspecialc printf('

%s: %s     %s: %s

', _('Server'),$ldapserver->name,_('Distinguished Name'),htmlspecialchars($entry['dn']['string'])); +$dn = array(); $dn['attrs'] = $ldapserver->getDNAttrs($entry['dn']['string']); $dn['oclasses'] = $ldapserver->getDNAttr($entry['dn']['string'],'objectClass'); diff --git a/htdocs/add_oclass.php b/htdocs/add_oclass.php index 6064ea0..c270071 100644 --- a/htdocs/add_oclass.php +++ b/htdocs/add_oclass.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if ($ldapserver->isAttrReadOnly('objectClass')) - pla_error(_('ObjectClasses are flagged as read only in the phpLDAPadmin configuration.')); + error(_('ObjectClasses are flagged as read only in the phpLDAPadmin configuration.'),'error','index.php'); +$entry = array(); $entry['dn']['encode'] = get_request('dn'); $entry['dn']['string'] = urldecode($entry['dn']['encode']); @@ -42,7 +43,7 @@ if (is_array($entry['new']['attrs']) && count($entry['new']['attrs']) > 0) $href['search'] = htmlspecialchars(sprintf('cmd.php?cmd=search&search=true&form=advanced&server_id=%s&filter=%s=%s', $ldapserver->server_id,$attr,$badattr)); - pla_error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'),$attr,$badattr,$entry['dn']['string'],$href['search'])); + error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'),$attr,$badattr,$entry['dn']['string'],$href['search']),'error','index.php'); } $new_entry[$attr] = $val; @@ -51,7 +52,10 @@ if (is_array($entry['new']['attrs']) && count($entry['new']['attrs']) > 0) $result = $ldapserver->attrModify($entry['dn']['string'],$new_entry); if (! $result) - pla_error(_('Could not perform ldap_mod_add operation.'),$ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not perform ldap_mod_add operation.'), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); else { $modified_attrs = array_keys($entry['new']['attrs']); diff --git a/htdocs/add_oclass_form.php b/htdocs/add_oclass_form.php index eafd013..22490f4 100644 --- a/htdocs/add_oclass_form.php +++ b/htdocs/add_oclass_form.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if (! $entry['oclass']['new']) - pla_error(_('You did not select any ObjectClasses for this object. Please go back and do so.')); + error(_('You did not select any ObjectClasses for this object. Please go back and do so.'),'error','index.php'); /* Ensure that the object has defined all MUST attrs for this objectClass. * If it hasn't, present a form to have the user enter values for all the @@ -108,7 +109,10 @@ if (count($ldap['attrs']['need']) > 0) { $result = $ldapserver->attrModify($entry['dn']['string'],array('objectClass'=>$entry['oclass']['new'])); if (! $result) - pla_error('Could not perform ldap_mod_add operation.',$ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not perform ldap_mod_add operation.'), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); else { $href = sprintf('cmd.php?cmd=template_engine&server_id=%s&dn=%s&modified_attrs[]=objectClass', diff --git a/htdocs/add_value.php b/htdocs/add_value.php index de1fa4b..e75608f 100644 --- a/htdocs/add_value.php +++ b/htdocs/add_value.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if (! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_add_value')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('add attribute value'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('add attribute value')),'error','index.php'); # The DN and ATTR we are working with. +$entry = array(); $entry['dn']['encode'] = get_request('dn','POST',true); $entry['dn']['string'] = rawurldecode($entry['dn']['encode']); $entry['attr']['encode'] = get_request('attr','POST',true); @@ -34,7 +35,7 @@ $entry['value']['string'] = get_request('new_value','POST',true); $entry['value']['bin'] = get_request('binary','POST') ? true : false; if ($ldapserver->isAttrReadOnly($entry['attr']['string'])) - pla_error(sprintf(_('The attribute "%s" is flagged as read-only in the phpLDAPadmin configuration.'),$entry['attr']['html'])); + error(sprintf(_('The attribute "%s" is flagged as read-only in the phpLDAPadmin configuration.'),$entry['attr']['html']),'error','index.php'); /* * Special case for binary attributes: @@ -56,7 +57,7 @@ if ($badattr = $ldapserver->checkUniqueAttr($entry['dn']['string'],$entry['attr' $href = htmlspecialchars(sprintf('cmd.php?cmd=search&search=true&form=advanced&server_id=%s&filter=%s=%s', $ldapserver->server_id,$entry['attr']['string'],$badattr)); - pla_error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'),$entry['attr']['string'],$badattr,$entry['dn']['string'],$href)); + error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'),$entry['attr']['string'],$badattr,$entry['dn']['string'],$href),'error','index.php'); } # Call the custom callback for each attribute modification and verify that it should be modified. @@ -69,8 +70,11 @@ if (run_hook('pre_attr_add', $add_result = $ldapserver->attrModify($entry['dn']['string'],$new_entry); if (! $add_result) { - pla_error(_('Could not perform ldap_mod_add operation.'), - $ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not perform ldap_mod_add operation.'), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); + } else { run_hook('post_attr_modify', array('server_id'=>$ldapserver->server_id,'dn'=>$entry['dn']['string'],'attr_name'=>$entry['attr']['string'],'new_value'=>$new_entry)); diff --git a/htdocs/add_value_form.php b/htdocs/add_value_form.php index ec12e65..e77792e 100644 --- a/htdocs/add_value_form.php +++ b/htdocs/add_value_form.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); # The DN and ATTR we are working with. +$entry = array(); $entry['dn']['encode'] = get_request('dn','GET',true); $entry['dn']['string'] = urldecode($entry['dn']['encode']); $entry['dn']['html'] = htmlspecialchars($entry['dn']['string']); @@ -34,7 +35,7 @@ $entry['rdn']['html'] = htmlspecialchars($entry['rdn']['string']); /***************/ if (! $entry['dn']['string'] || ! $ldapserver->dnExists($entry['dn']['string'])) - pla_error(sprintf(_('The entry (%s) does not exist.'),$entry['dn']['html']),null,-1,true); + error(sprintf(_('The entry (%s) does not exist.'),$entry['dn']['html']),'error','index.php'); $tree = get_cached_item($ldapserver->server_id,'tree'); $entry['ldap'] = null; @@ -52,7 +53,7 @@ eval('$reader = new '.$_SESSION[APPCONFIG]->GetValue('appearance','entry_reader' $reader->visit('Start', $entry['ldap']); if (! $entry['ldap'] || $entry['ldap']->isReadOnly()) - pla_error(sprintf(_('The entry (%s) is in readonly mode.'),$entry['dn']['html']),null,-1,true); + error(sprintf(_('The entry (%s) is in readonly mode.'),$entry['dn']['html']),'error','index.php'); /*********************/ /* attribute values */ @@ -71,11 +72,13 @@ if (!$ldap['attr']) { $ldap['count'] = $ldap['attr']->getValueCount(); if ($ldap['attr']->isReadOnly()) - pla_error(sprintf(_('The attribute (%s) is in readonly mode.'),$entry['attr']['html']),null,-1,true); + error(sprintf(_('The attribute (%s) is in readonly mode.'),$entry['attr']['html']),'error','index.php'); + if (! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_add_value')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('add attribute value'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('add attribute value')),'error','index.php'); + if (($ldap['attr']->getValueCount() == 0) && ! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_add')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('add attribute'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('add attribute')),'error','index.php'); $entry['attr']['oclass'] = (strcasecmp($entry['attr']['string'],'objectClass') == 0) ? true : false; @@ -156,8 +159,8 @@ if ($entry['attr']['oclass']) { echo ''; if ($_SESSION[APPCONFIG]->GetValue('appearance','show_hints')) - printf('
Hint%s
', - _('Note: You may be required to enter new attributes that these objectClass(es) require')); + printf('
Hint%s
', + IMGDIR,_('Note: You may be required to enter new attributes that these objectClass(es) require')); echo ''; echo ''; echo ''; @@ -165,7 +168,7 @@ if ($entry['attr']['oclass']) { } else { # Draw a blank field echo ''; @@ -322,8 +323,7 @@ foreach ($attrs_all as $attr) { if ($side == 'dst') { printf('',htmlspecialchars($user_password)); - echo enc_type_select_list($enc_type); - + echo enc_type_select_list($enc_type,'enc','userpassword',0); } echo '
'; @@ -383,8 +383,8 @@ foreach ($attrs_all as $attr) { # Is this value is a structural objectClass, make it read-only if (0 == strcasecmp($attr,'objectClass')) { - printf('', - _('View the schema description for this objectClass'),$ldapserver->server_id,htmlspecialchars($val)); + printf('', + _('View the schema description for this objectClass'),$ldapserver->server_id,htmlspecialchars($val),IMGDIR); $schema_object = $ldapserver->getSchemaObjectClass($val); @@ -400,14 +400,14 @@ foreach ($attrs_all as $attr) { } if (is_dn_string($val) || $ldapserver->isDNAttr($attr)) - printf('', - sprintf(_('Go to %s'),htmlspecialchars($val)),$ldapserver->server_id,rawurlencode($val)); + printf('', + sprintf(_('Go to %s'),htmlspecialchars($val)),$ldapserver->server_id,rawurlencode($val),IMGDIR); elseif (is_mail_string($val)) - printf('',htmlspecialchars($val)); + printf('',htmlspecialchars($val),IMGDIR); elseif (is_url_string($val)) - printf('',htmlspecialchars($val)); + printf('',htmlspecialchars($val),IMGDIR); if ($ldapserver->isMultiLineAttr($attr,$val)) { if ($side == 'dst') diff --git a/htdocs/compare_form.php b/htdocs/compare_form.php index 7eaafb9..89bce98 100644 --- a/htdocs/compare_form.php +++ b/htdocs/compare_form.php @@ -1,5 +1,5 @@ server_id,true,'server_id_dst'); diff --git a/htdocs/copy.php b/htdocs/copy.php index c9d6333..3dab63b 100644 --- a/htdocs/copy.php +++ b/htdocs/copy.php @@ -1,5 +1,5 @@ isCommandAvailable('entry_move')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('copy entry'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('copy entry')),'error','index.php'); +$entry = array(); $entry['src']['id'] = get_request('server_id'); $entry['dst']['id'] = get_request('dest_server_id'); @@ -26,10 +27,10 @@ $entry['src']['ldapserver'] = $_SESSION[APPCONFIG]->ldapservers->Instance($entry $entry['dst']['ldapserver'] = $_SESSION[APPCONFIG]->ldapservers->Instance($entry['dst']['id']); if ($entry['dst']['ldapserver']->isReadOnly()) - pla_error(_('Destination server is currently READ-ONLY.')); + error(_('Destination server is currently READ-ONLY.'),'error','index.php'); if (! $entry['src']['ldapserver']->haveAuthInfo() || ! $entry['dst']['ldapserver']->haveAuthInfo()) - pla_error(_('Not enough information to login to server. Please check your configuration.')); + error(_('Not enough information to login to server. Please check your configuration.'),'error','index.php'); $entry['src']['dn'] = get_request('old_dn'); $entry['dst']['dn'] = get_request('new_dn'); @@ -38,19 +39,19 @@ $entry['src']['remove'] = (get_request('remove') == 'yes') ? true : false; # Error checking if (strlen(trim($entry['dst']['dn'])) == 0) - pla_error(_('You left the destination DN blank.')); + error(_('You left the destination DN blank.'),'error','index.php'); if (pla_compare_dns($entry['src']['dn'],$entry['dst']['dn']) == 0 && $entry['src']['id'] == $entry['dst']['id']) - pla_error(_('The source and destination DN are the same.')); + error(_('The source and destination DN are the same.'),'error','index.php'); if ($entry['dst']['ldapserver']->dnExists($entry['dst']['dn'])) - pla_error(sprintf(_('The destination entry (%s) already exists.'),pretty_print_dn($entry['dst']['dn']))); + error(sprintf(_('The destination entry (%s) already exists.'),pretty_print_dn($entry['dst']['dn'])),'error','index.php'); if (! $entry['dst']['ldapserver']->dnExists(get_container($entry['dst']['dn']))) - pla_error(sprintf(_('The destination container (%s) does not exist.'),pretty_print_dn(get_container($entry['dst']['dn'])))); + error(sprintf(_('The destination container (%s) does not exist.'),pretty_print_dn(get_container($entry['dst']['dn']))),'error','index.php'); if ($entry['src']['recursive']) { - $filter = isset($_POST['filter']) ? $_POST['filter'] : '(objectClass=*)'; + $filter = get_request('filter','POST',false,'(objectClass=*)'); # Build a tree similar to that of the tree browser to give to r_copy_dn $snapshot_tree = array(); @@ -141,7 +142,11 @@ function copy_dn($ldapserver_src,$ldapserver_dst,$dn_src,$dn_dst) { $add_result = $ldapserver_dst->add($dn_dst,$new_entry); if (! $add_result) { echo '

'; - pla_error(_('Failed to copy DN: ').$dn_dst,$ldapserver_dst->error(),$ldapserver_dst->errno()); + system_message(array( + 'title'=>_('Failed to copy DN.').sprintf(' (%s)',$dn_dst), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); + } else { run_hook('post_entry_create', array('server_id'=>$ldapserver_dst->server_id,'dn'=>$dn_dst,'attrs'=>$new_entry)); diff --git a/htdocs/copy_form.php b/htdocs/copy_form.php index 1c09fb1..b397e18 100644 --- a/htdocs/copy_form.php +++ b/htdocs/copy_form.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); +$entry = array(); $entry['dn'] = get_request('dn','GET'); $entry['rdn'] = get_rdn($entry['dn']); @@ -99,7 +100,7 @@ echo '
'; - $writer->draw('BlankValue', $ldap['attr'], $ldap['count']); + $writer->draw('BlankValue',$ldap['attr'],$ldap['count'],$reader); echo '
'; if ($ldap['schema']->getDescription()) diff --git a/htdocs/compare.php b/htdocs/compare.php index ede7d83..24a4e4a 100644 --- a/htdocs/compare.php +++ b/htdocs/compare.php @@ -1,5 +1,5 @@ ldapservers->Instance($server_id_src); if (! $ldapserver_src->haveAuthInfo()) - pla_error(_('Not enough information to login to server. Please check your configuration.')); + error(_('Not enough information to login to server. Please check your configuration.'),'error','index.php'); $ldapserver_dst = $_SESSION[APPCONFIG]->ldapservers->Instance($server_id_dst); if (! $ldapserver_src->haveAuthInfo()) - pla_error(_('Not enough information to login to server. Please check your configuration.')); + error(_('Not enough information to login to server. Please check your configuration.'),'error','index.php'); if (! $ldapserver_src->dnExists($dn_src)) - pla_error(sprintf(_('No such entry: %s'),pretty_print_dn($dn_src))); + error(sprintf('%s (%s)',_('No such entry.'),pretty_print_dn($dn_src)),'error','index.php'); + if (! $ldapserver_dst->dnExists($dn_dst)) - pla_error(sprintf(_('No such entry: %s'),pretty_print_dn($dn_dst))); + error(sprintf('%s (%s)',_('No such entry.'),pretty_print_dn($dn_dst)),'error','index.php'); $attrs_src = $ldapserver_src->getDNAttrs($dn_src,false,$_SESSION[APPCONFIG]->GetValue('deref','view')); $attrs_dst = $ldapserver_dst->getDNAttrs($dn_dst,false,$_SESSION[APPCONFIG]->GetValue('deref','view')); @@ -253,12 +254,12 @@ foreach ($attrs_all as $attr) { if (count($vals) > 1) for ($i=1; $i<=count($vals); $i++) - printf(' %s(%s)
',$href,$i,_('download value'),$i); + printf(' %s(%s)
',$href,$i,_('download value'),IMGDIR,$i); else - printf(' %s
',$href,_('download value')); + printf(' %s
',$href,IMGDIR,_('download value')); if ($side == 'dst' && ! $ldapserver_dst->isReadOnly() && ! $ldapserver->isAttrReadOnly($attr)) - printf(' %s',$attr,_('delete attribute')); + printf(' %s',$attr,IMGDIR,_('delete attribute')); echo ''; echo '
'; echo "\n"; if ($_SESSION[APPCONFIG]->GetValue('appearance','show_hints')) - printf('Light%s',_('Hint: Copying between different servers only works if there are no schema violations')); + printf('Light%s',IMGDIR,_('Hint: Copying between different servers only works if there are no schema violations')); echo ''; ?> diff --git a/htdocs/create.php b/htdocs/create.php index 15f0698..07ca5c2 100644 --- a/htdocs/create.php +++ b/htdocs/create.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode'), null, -1, true); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if (! $_SESSION[APPCONFIG]->isCommandAvailable('entry_create')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('create entry'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('create entry')),'error','index.php'); -$rdn_attr = isset($_POST['rdn_attribute']) ? $_POST['rdn_attribute'] : null; +$rdn_attr = get_request('rdn_attribute'); $entryfactoryclass = $_SESSION[APPCONFIG]->GetValue('appearance','entry_factory'); eval('$entry_factory = new '.$entryfactoryclass.'();'); @@ -36,7 +36,7 @@ $entry->accept($reader); $container = $entry->getContainer(); if (!$container || !$ldapserver->dnExists($container)) - pla_error(sprintf(_('The container you specified (%s) does not exist. Please try again.'),htmlspecialchars($container)),null,-1,true); + error(sprintf(_('The container you specified (%s) does not exist. Please try again.'),htmlspecialchars($container)),'error','index.php'); $tree = get_cached_item($ldapserver->server_id,'tree'); if ($tree) { @@ -46,18 +46,18 @@ if ($tree) { $container_entry = $tree->getEntry($container); if ($container_entry->isLeaf()) - pla_error(sprintf(_('The container (%s) is a leaf.'), htmlspecialchars($container)), null, -1, true); + error(sprintf(_('The container (%s) is a leaf.'), htmlspecialchars($container)),'error','index.php'); } $entry->setRdnAttributeName($rdn_attr); if (!$entry->getRdnAttribute()) - pla_error(sprintf(_('The Rdn attribute (%s) does not exist.'), htmlspecialchars($rdn_attr)), null, -1, true); + error(sprintf(_('The Rdn attribute (%s) does not exist.'), htmlspecialchars($rdn_attr)),'error','index.php'); $new_dn = $entry->getDn(); if (! $new_dn) - pla_error(_('You left the RDN field blank.')); + error(_('You left the RDN field blank.'),'error','index.php'); -$redirect = isset($_POST['redirect']) ? $_POST['redirect'] : false; +$redirect = get_request('redirect','POST',false,false); $new_entry = array(); $attrs = $entry->getAttributes(); @@ -69,8 +69,9 @@ foreach ($attrs as $attr) { $new_vals[] = $val; } - if ($attr->isRequired() && !$new_vals) - pla_error(sprintf(_('You left the value blank for required attribute (%s).'), htmlspecialchars($attr->getName()))); + if ($attr->isRequired() && !$new_vals && !$ldapserver->isIgnoredAttr($attr->getName())) + error(sprintf(_('You left the value blank for required attribute (%s).'),htmlspecialchars($attr->getName())),'error','index.php'); + if ($new_vals) $new_entry[$attr->getName()] = $new_vals; @@ -83,7 +84,7 @@ foreach ($new_entry as $attr => $vals) { # Check to see if this is a unique Attribute if ($badattr = $ldapserver->checkUniqueAttr($new_dn,$attr,$vals)) { $search_href = sprintf('?cmd=search&search=true&form=advanced&server_id=%s&filter=%s=%s', $ldapserver->server_id,$attr,$badattr); - pla_error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'),$attr,$badattr,$new_dn,$search_href)); + error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'),$attr,$badattr,$new_dn,$search_href),'error','index.php'); } } @@ -129,6 +130,9 @@ if ($add_result) { } } else { - pla_error(_('Could not add the object to the LDAP server.'),$ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not add the object to the LDAP server.'), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); } ?> diff --git a/htdocs/css/style.css b/htdocs/css/style.css index cd5751b..3ddc2ab 100644 --- a/htdocs/css/style.css +++ b/htdocs/css/style.css @@ -1,4 +1,4 @@ -/* $Header: /cvsroot/phpldapadmin/phpldapadmin/htdocs/css/style.css,v 1.48.2.4 2008/01/13 07:17:23 wurley Exp $ */ +/* $Header: /cvsroot/phpldapadmin/phpldapadmin/htdocs/css/style.css,v 1.48.2.8 2008/12/19 00:38:31 wurley Exp $ */ /* Global Page */ table.page { @@ -96,7 +96,7 @@ table.page table.control td.logo img.logo { text-align: right; width: 100px; - height: 60px; + height: 50px; } /* Global Page - LDAP Tree */ @@ -276,6 +276,7 @@ table.tree td.rdn a:hover { font-size: 13px; color: #841212; background-color: #FFF0C0; + text-decoration: none; } table.tree td.rdn span.count { @@ -300,13 +301,6 @@ table.tree td.link a:hover { text-decoration: none; } -table.tree td.rdn a:hover { - font-size: 13px; - color: #841212; - background-color: #FFF0C0; - text-decoration: none; -} - table.tree td.links a:hover { text-decoration: none; color: blue; @@ -438,6 +432,7 @@ table.entry input { } table.entry input.value { + color: #000000; font-size: 14px; width: 350px; background-color: #FFFFFF; @@ -447,15 +442,16 @@ table.entry div.helper { text-align: left; white-space: nowrap; background-color: #FFFFFF; + color: #888; font-size: 14px; font-weight: normal; - color: #888; } table.entry input.roval { font-size: 14px; width: 350px; background-color: #FFFFFF; + color: #000000; border: none; } @@ -463,12 +459,14 @@ table.entry textarea.value { font-size: 14px; width: 350px; background-color: #FFFFFF; + color: #000000; } table.entry textarea.roval { font-size: 14px; width: 350px; background-color: #FFFFFF; + color: #000000; border: none; } @@ -604,41 +602,50 @@ table.entry tr.updated td.ew2_val { #login { background: url('../images/uid.png') no-repeat 0 1px; background-color: #FAFAFF; + color: #000000; padding-left: 17px; } #login:focus { background-color: #F0F0FF; + color: #000000; } #login:disabled { background-color: #DDDDFF; + color: #000000; } #password { background: url('../images/key.png') no-repeat 0 1px; background-color: #FAFAFF; + color: #000000; padding-left: 17px; } #password:focus { background-color: #F0F0FF; + color: #000000; } #password:disabled { background-color: #DDDDFF; + color: #000000; } #generic { background-color: #FAFAFF; + color: #000000; padding-left: 17px; } #generic:focus { background-color: #F0F0FF; + color: #000000; } #generic:disabled { background-color: #DDDDFF; + color: #000000; } /* After input results */ diff --git a/htdocs/delete.php b/htdocs/delete.php index 37017ff..277e0a2 100644 --- a/htdocs/delete.php +++ b/htdocs/delete.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if (! $_SESSION[APPCONFIG]->isCommandAvailable('entry_delete', 'simple_delete')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete entry'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete entry')),'error','index.php'); +$entry = array(); $entry['dn'] = get_request('dn'); if (! $entry['dn']) - pla_error(_('You must specify a DN')); + error(_('You must specify a DN'),'error','index.php'); if (! $ldapserver->dnExists($entry['dn'])) - pla_error(sprintf(_('No such entry: %s'),''.pretty_print_dn($entry['dn']).'')); + error(sprintf('%s (%s)',_('No such entry.'),''.pretty_print_dn($entry['dn']).''),'error','index.php'); # Check the user-defined custom callback first. if (run_hook('pre_entry_delete',array('server_id'=>$ldapserver->server_id,'dn'=>$entry['dn']))) $result = $ldapserver->delete($entry['dn']); else - pla_error(sprintf(_('Could not delete the entry: %s'),''.pretty_print_dn($entry['dn']).'')); + error(sprintf(_('Could not delete the entry: %s'),''.pretty_print_dn($entry['dn']).''),'error','index.php'); if ($result) { # Custom callback @@ -46,7 +47,9 @@ if ($result) { sprintf('index.php?server_id=%s',$ldapserver->server_id)); } else { - pla_error(sprintf(_('Could not delete the entry: %s'),''.pretty_print_dn($entry['dn']).''), - $ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not delete the entry.').sprintf(' (%s)',pretty_print_dn($entry['dn'])), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); } ?> diff --git a/htdocs/delete_attr.php b/htdocs/delete_attr.php index cbce0d2..94f364f 100644 --- a/htdocs/delete_attr.php +++ b/htdocs/delete_attr.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if (! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_delete')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete attribute'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete attribute')),'error','index.php'); +$entry = array(); $entry['dn']['string'] = get_request('dn'); $entry['dn']['encode'] = rawurlencode($entry['dn']['string']); $entry['attr'] = get_request('attr'); if (! $entry['dn']['string']) - pla_error(_('No DN specified')); + error(_('No DN specified'),'error','index.php'); if (! $entry['attr']) - pla_error(_('No attribute name specified.')); + error(_('No attribute name specified.'),'error','index.php'); if ($ldapserver->isAttrReadOnly($entry['attr'])) - pla_error(sprintf(_('The attribute "%s" is flagged as read-only in the phpLDAPadmin configuration.'),htmlspecialchars($entry['attr']))); + error(sprintf(_('The attribute "%s" is flagged as read-only in the phpLDAPadmin configuration.'),htmlspecialchars($entry['attr'])),'error','index.php'); $update_array = array(); $update_array[$entry['attr']] = array(); @@ -47,6 +48,9 @@ if ($result) { die(); } else { - pla_error(_('Could not perform ldap_modify operation.'),$ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not perform ldap_modify operation.'), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); } ?> diff --git a/htdocs/delete_form.php b/htdocs/delete_form.php index bb73667..9e27481 100644 --- a/htdocs/delete_form.php +++ b/htdocs/delete_form.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); +$entry = array(); $entry['dn']['string'] = get_request('dn','GET'); $entry['dn']['html'] = htmlspecialchars($entry['dn']['string']); diff --git a/htdocs/download_binary_attr.php b/htdocs/download_binary_attr.php index 2acd2f3..bdbf7a2 100644 --- a/htdocs/download_binary_attr.php +++ b/htdocs/download_binary_attr.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); -if (! $ldapserver->haveAuthInfo()) - pla_error(_('Not enough information to login to server. Please check your configuration.')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); -$dn = rawurldecode($_GET['dn']); -$attr = $_GET['attr']; +if (! $ldapserver->haveAuthInfo()) + error(_('Not enough information to login to server. Please check your configuration.'),'error','index.php'); + +$dn = rawurldecode(get_request('dn','GET')); +$attr = get_request('attr','GET'); # if there are multiple values in this attribute, which one do you want to see? -$value_num = isset($_GET['value_num']) ? $_GET['value_num'] : null; +$value_num = get_request('value_num','GET'); if (! $ldapserver->dnExists($dn)) - pla_error(sprintf(_('No such entry: %s'),pretty_print_dn($dn))); + error(sprintf('%s (%s)',_('No such entry.'),pretty_print_dn($dn)),'error','index.php'); $search = $ldapserver->search(null,$dn,'(objectClass=*)',array($attr),'base',false,$_SESSION[APPCONFIG]->GetValue('deref','view')); # Dump the binary data to the browser -if (ob_get_level()) ob_end_clean(); +$obStatus = ob_get_status(); +if (isset($obStatus['type']) && $obStatus['type'] && $obStatus['status']) + ob_end_clean(); + header('Content-type: octet-stream'); header("Content-disposition: attachment; filename=$attr"); header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); + if ($value_num && is_array($search[$attr][$dn])) echo $search[$dn][$attr][$value_num]; else diff --git a/htdocs/draw_tree_node.php b/htdocs/draw_tree_node.php index 7839d0a..edbe477 100644 --- a/htdocs/draw_tree_node.php +++ b/htdocs/draw_tree_node.php @@ -1,41 +1,42 @@ getEntry($entry['dn']); - if (! $dnentry) { - $tree->addEntry($entry['dn']); - $dnentry = $this->getEntry($entry['dn']); - } - - if (! $dnentry) - die(); - - if ($entry['action'] == 0) { - $dnentry->close(); - - } elseif ($entry['action'] == 2) { - $dnentry->open(); - - } else { - $dnentry->open(); - if ($entry['dn']) { - echo $tree->draw_children($dnentry,$entry['code']); - } else { - $tree->draw(true); - } - } +$tree = Tree::getInstance($entry['server_id']); +if (! $tree) die(); + +$dnentry = $tree->getEntry($entry['dn']); +if (! $dnentry) { + $tree->addEntry($entry['dn']); + $dnentry = $this->getEntry($entry['dn']); +} + +if (! $dnentry) + die(); + +if ($entry['action'] == 0) { + $dnentry->close(); + +} elseif ($entry['action'] == 2) { + $dnentry->open(); + +} else { + $dnentry->open(); + if ($entry['dn']) { + echo $tree->draw_children($dnentry,$entry['code']); + } else { + $tree->draw(true); + } +} +die(); ?> diff --git a/htdocs/entry_chooser.php b/htdocs/entry_chooser.php index a788095..09dbf73 100644 --- a/htdocs/entry_chooser.php +++ b/htdocs/entry_chooser.php @@ -1,5 +1,5 @@ haveAuthInfo()) - pla_error(_('Not enough information to login to server. Please check your configuration.')); + error(_('Not enough information to login to server. Please check your configuration.'),'error','index.php'); $entry['children'] = $ldapserver->getContainerContents($entry['container'],0,'(objectClass=*)',$_SESSION[APPCONFIG]->GetValue('deref','tree')); sort($entry['children']); @@ -61,7 +62,7 @@ if (isset($ldapserver) && ! is_null($entry['container'])) { echo ''; echo ' '; - printf('Up',$href['up']); + printf('Up',$href['up'],IMGDIR); printf('%s',$href['up'],_('Back Up...')); echo ''; @@ -76,7 +77,7 @@ if (isset($ldapserver) && ! is_null($entry['container'])) { echo ''; echo ' '; - printf('Plus',$href['expand']); + printf('Plus',$href['expand'],IMGDIR); printf('%s',$href['return'],htmlspecialchars($dn)); echo ''; @@ -107,7 +108,7 @@ if (isset($ldapserver) && ! is_null($entry['container'])) { echo ''; echo ' '; - printf('Plus',$href['expand']); + printf('Plus',$href['expand'],IMGDIR); printf('%s',$href['return'],htmlspecialchars($dn)); } } diff --git a/htdocs/export.php b/htdocs/export.php index 6ecb620..4a2bc0a 100755 --- a/htdocs/export.php +++ b/htdocs/export.php @@ -1,5 +1,5 @@ isCommandAvailable('export')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('export'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('export')),'error','index.php'); +$entry = array(); $entry['base_dn'] = get_request('dn'); $entry['format'] = get_request('format','POST',false,'unix'); $entry['scope'] = get_request('scope','POST',false,'base'); @@ -40,8 +41,8 @@ if ($entry['sys_attr']) { array_push($attributes,'+'); } -(! is_null($entry['exporter_id'])) or pla_error(_('You must choose an export format.')); -isset($exporters[$entry['exporter_id']]) or pla_error(_('Invalid export format')); +(! is_null($entry['exporter_id'])) or error(_('You must choose an export format.'),'error','index.php'); +isset($exporters[$entry['exporter_id']]) or error(_('Invalid export format'),'error','index.php'); # Initialisation of other variables $friendly_rdn = get_rdn($entry['base_dn'],1); @@ -85,13 +86,13 @@ switch ($entry['exporter_id']) { default: # truly speaking,this default case will never be reached. See check at the bottom. - pla_error(_('No available exporter found.')); + error(_('No available exporter found.'),'error','index.php'); } # set the CLRN $exporter->setOutputFormat($br); -if (isset($_REQUEST['compress']) && $_REQUEST['compress'] = 'on') +if (get_request('compress','REQUEST') == 'on') $exporter->compress(true); # prevent script from bailing early for long search @@ -99,7 +100,10 @@ if (isset($_REQUEST['compress']) && $_REQUEST['compress'] = 'on') # send the header if ($entry['file']) { - if (ob_get_level()) ob_end_clean(); + $obStatus = ob_get_status(); + if (isset($obStatus['type']) && $obStatus['type'] && $obStatus['status']) + ob_end_clean(); + header('Content-type: application/download'); header(sprintf('Content-Disposition: filename="%s.%s"',$friendly_rdn,$exporters[$entry['exporter_id']]['extension'].($exporter->isCompressed()?'.gz':''))); $exporter->export(); diff --git a/htdocs/export_form.php b/htdocs/export_form.php index bb9fe25..c0a9d1e 100755 --- a/htdocs/export_form.php +++ b/htdocs/export_form.php @@ -1,5 +1,5 @@ GZx^prw85kJYlDyqr82*Fcg1yTp14TFsJR*x37`TN%nDNrx zx<5cc_7YEDSN0n`JRFAdKW^GCVPIeq^K@|xu{gc4RD?-@@3k^FP!)rxtDnm{r-UW| DtGOP? delta 83 zcmbQnI+JyRiablYqpu?a!^VE@KZ&di3=C{Z-tI0y8VG(m@2;QdASZH}k&}y^A?mbP0l+XkKiR%{7 diff --git a/htdocs/images/debug-cache.png b/htdocs/images/debug-cache.png index 87243bc6857bf3e08a516dbe8bb44b9ddd322fb0..61ae9ef87917302ff0e5787bfab2c18515f7f92f 100644 GIT binary patch delta 79 zcmeBRoys~v#f7mr$lZxy-8q?;3=9lxN#5=*4F5rJ!QSPQfg+p*9+AZi4E%{8%(%jS cc_vVhy~NYkmHh?}4~HQ`=|zLUjnTSH0JmrsuK)l5 delta 40 scmbQr+QB+Og`X|S+uel$41PNAuAk^2$90uOkVRMVhevSs#tdC10Mru;8UO$Q diff --git a/htdocs/images/favicon.ico b/htdocs/images/favicon.ico index 8a33cda176f6b2990d97c9ba45ed48c3284cd98e..7865d94ff1e82513e10c198eaf32fb85b57470c4 100644 GIT binary patch delta 321 zcmXZXyGufG6bJC{y%hch4MF4*G&BZjnt1hIqjZSqu?Y!DgAYm~Xy`@ZUFFoD(<2P05IaRMaA3x2Fwf=l7^rn*SDw8 zCna+LPN$D9)yMt4BPec_iq_AEr#pN-S8%w!!yl}_V>uLOU?j@L$T~k>iS+RWLg86@ zJU+TLjSkhyT;T>yqlCo#0ymdd*fgrpvr=~}STLZ=ah(0zUA!+b~k_Z|qA~+fvI$m09 zt8j?+!01D0h^Pj`A;c0nOwObs>dJp_L-fG!`TyZr9>Zn0wv#ktrbKF+`+Xfazj#2y zZhEY86~$r!j#KxT6?YeW$`mwh5)wpx7Uk>9mdj+3&2qU91 zZtl*&rl~s$S=JFybsQcXLkX%-v_U*R-{bqGwt2L>hhJ!Xkkz<>=vWHN$qjtIfn-lE z5l_q`6w(pYH275sh0-mW6$@L7OW0Xi!?(tsgrwL;$Sc?A;Yt3r^Zqxqg^aA zmpF}uf)SPzE+$s46Z&e@lc^c7|Mcn8N3LGI+FDy%^E6GRF|sjJL>L|(rrYh(>2&;m&Ye4Q{P-u~;>C+R ze?I@w!otGGBC_i41yG8J;O+w_PoA7RbLPy^s;ZJK%Yul!k)eoSW(*DvvTxr$Mn^|! zx7*yh^|c>6_MzXn@l`l??);1C>FF<%B>7QQ7lGGl4UmqHj~~8v?OLm&(pjL{XI6?wiH~X-ctKBm(aLNh9KvWyQ$IUM40c7#Z2aA~8nHBC3(~_16?dK?nhN$g-4L?v48!0L^5K6=sHNKcK3j+6N6G#Y|9D zz;TCOuZNjZ6vgHYwgNPhWmzB+P_2kjG4mP#vJA|W{!&4tVb1^c!0Gi0lBCZvMg{uv z^aJ$$Xx6EJsux8ms^+RuwmD2U14u1Pi7GXF-H%F2q}y?Z~j+wB}sGxKdS@VX2m zAy8M0Z!qpZ_cO|}Owu$Xguvdt?@6b#ymJ5kgGWh!k}LwN?p^`*27sA+Rh8uVYj^LP z-Vd&I$r|p0nUZBGAtbD>uG+nO_rlAU?Jh9m?k|8pfPa7r@XaR6(9kdk4<3?MYe3B6 zmLsDN>bRR{SxY*d<&}pIzj>4-$t&PbGwT4aYJdok*5#?Qv$KEQym@nAetupD2V2t5 zf+o{-`neAfLhv-rT8oP>H#6@5OLg#~X`RiM3&5wq7;p#}tl#a_v%UW2Z{Qc;H{kdB zce%mpt@A!flH`!Pzh5`}-TqQ|eF7K2GSIDq@7VOSI&iCQ+`{g|YBTftZf`I67o`)q U^d{aawg3PC07*qoM6N<$g0@8-!vFvP delta 1050 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 Eg3r~JtpET3 delta 1953 zcmV;S2VVG|55W(RB!32COGiWi9RL^r2@2YxAOHXdc1c7*RCwB@mu-w(RT;y)K{Lga; zYYQs3r@JgkUj^X~0(JuEZ2mUSjJJ*9m%UIQuDi(;fCzvFU{-zc8YUM#W#>^MdhiF2 zJT}~WU0;;Twbpujdkf5r(b3E9J0s_uk&!ox|9<1duJh;5Jvmj09tPkwK@0$17eIHH zvy%wFedMRVbbkj1c4yn$yF?UWj2RTiI#SBSNn)TiBb!Bea`N5m(Pszc;lU@{{6HV5 zHPkQwA3$<72)V-KH{G~n=gU9*@#B{U25wK4N}Y{#+IDQ)DhWZPwegvu0e~3@LgTfz zba4MIpR%sMek%>1JpOel=pSKhW&x+Y6fv6STV_KlV$ z+L*Z!$GW05hf5P^z=&cUDJARu{Wq63ZtC%eUwi3G4L>;wAZTiW*96d0c7FDaZ$6m0 z=ia^T*=(-rIH?{Xs6+&F@uHAd)kdMMMOTh-${L3qTW*1)%wm1&{Fd!afTUc7KN=ZE_5O+oUC831tSC;LBbDMgo>`{of*D5ZduloEo9Qc|mJi&oo~ zZH^<`vRSJ&ld+1neI^hC1VKbFh9CqRA}Gy9Y8EiiS{r6Bh!*RO*p-6r0FZ7jn3iVYBSb{h zRVb7QAl90Nl*TefWSF@qglHu~MhKB1Vk0Gp8LX6E6v9fhe_<$2v_cXaZ444{d1FsP zgaUxnavHFfs{&?*)(j#8t%-zSX<4*Q2yy_3rUnEvBb5?tjImYh2SipN1W8y-0HNs; zv?RN$12A(Xih=@=sWDps3=@&jDw-uSCELj=fO15X2LRts#C1mMuRXJO%fdk zej`c@PsE7|6eTfR+OPye0D)WGs11(+h?{%AVihoezyA09shqUThDb&1sYrWK95jMx zv{v^jUJ%a*p<3|6q!NUx62vN*uhueN6jptX>XB4|f3}PUh%I9Zt~=kGXg=9IoRU>D zz>LACfBnR5Z=XA(Y|Ac1Mj2m6%2#n%=;-ij^{KoYMT=e-)f!<`bA#BuJTWPK9W^4E zgh|RMCYZc%N(<9t8!wHV>vg^4NYew%sy;9=8_ogv#ew_3QmIrXZ5@C@t&GQ!irI*> zBO|S~f6(`8q36~E*LA%ayS*#@ZX}aX+eR_iz?0AoxAn;HpXxmJm*l!v(Xmdp*JG+61p@}7AyH1}`(AqC z&*h^-zq4i+;zt40muO&3ry&<|)~o+|`%+>o|#f*fUYGKkC1|LKn#9{>5lcGuVUMarCQ0_baPNN7{1vy%va5UKoo zhYtOwJDn1JvF1$55=f^7G7f==VGKjs8Moo-nZtvFsiQ-Kmh0;W8eZ}WfW_uX$m?mz ze+Yo+?s6Uzg1&R&Z%4?F9T?;gg+2sDutWfGjQ1{`!v1gl3Sp#=RjTpB0LB4SSL%kY zs(}xcrJ0xw4@xPLoD-mTgN1D$-+?XN3SET>WM~|TdjYf4qaY%#RO6=sG?tVduh?*| zp($kmyl2mz7qZ2V!Sf@GUwjR-Gn1H`f2(1k7C_4~%H?j9%kA~1(vz$0`Fa2VfQN>L zc6+rE~p)l`Xq9Nc68tHS+uveqowGewdjEKe;h84 zUPPr*EiC8vD}}Yzfw%9z>v@HiFV`D2_%p+3EL=q3)eryKnD3qI*+2UApuRcTT@G#-~r6Wo=kZ&W8H{yxs%|*K#+!R=pGfe7>uz zYxvNiL%eI(E_NJe8o-YL+y-ECbBwjt#nCz-WOJgg0q6j562LzJ%r`xM%^t8GfcO6+ n0oVYX=J&Yi_iBlGtttKo8B_yl5@HHb00000NkvXXu0mjfif*EW diff --git a/htdocs/images/logo-small.png b/htdocs/images/logo-small.png new file mode 100644 index 0000000000000000000000000000000000000000..6fcdbf9118efc3c68439dc60d168859b47631be1 GIT binary patch literal 7053 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ΜIY1%$PA_VnIQ{ zBYwZ1g%D&IhNDzdefyVSGY+q${L80U2jj9RCpX)5jPnKn)G4KoDBp^Px({Su35(A@`)m^cEX!)C!4MI?`s%BdnVFgH zs3o-q{PwsYgy3jt;Ak=6-)$i%E-L;`GdGZ+8M(PRi;luV{?5z=Y>){c?&tbH|NQf~ z`|i8VpX)bw?p!QbumCT={Bjco-)u2?d3m?=>eXx0k|j&pgtE<6)W+@A)YSAUDJj|e zpX%BUb(Hi6L1G6p*BzyWJV``XGxOlX>3{d#cOUlLLx&EU2thGDEHBCWMXdV0Ds zd-iPf@8AFWZr!@MTUq3u)YMdeU0vNk$8n-SYkvIk#|N)f6zwePD5Z;)R{p%a>?3|! rsc7e}R4JraDMfktxx4XOJM8wqo`@$A2&IMu00000NkvXXu0mjf-X(=D literal 0 HcmV?d00001 diff --git a/htdocs/images/logo.jpg b/htdocs/images/logo.jpg deleted file mode 100644 index 6eadc24a9317bb7c58705e73d61d33665e270d89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16958 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 literal 0 HcmV?d00001 diff --git a/htdocs/images/logo_small.jpg b/htdocs/images/logo_small.jpg deleted file mode 100644 index 583ec4e299f32505c698d8bd103221f0926df4a9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3611 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 DP$e8~ delta 53 zcmbQr`haDEiX>Z-x4R1i82ohJUC+S4BYour install of PHP appears to be missing PCRE support.

Please install PCRE support before using phpLDAPadmin.
(Dont forget to restart your web server afterwards)

'); + require LIBDIR.'functions.php'; # Define the path to our configuration file. @@ -48,9 +52,30 @@ if (defined('CONFDIR')) else $app['config_file'] = 'config.php'; +# Make sure this PHP install has session support +if (! extension_loaded('session')) + error('

Your install of PHP appears to be missing php-session support.

Please install php-session support before using phpLDAPadmin.
(Dont forget to restart your web server afterwards)

','error',null,true); + # Make sure this PHP install has gettext, we use it for language translation if (! extension_loaded('gettext')) - error('

Your install of PHP appears to be missing GETTEXT support.

GETTEXT is used for language translation.

Please install GETTEXT support before using phpLDAPadmin.
(Dont forget to restart your web server afterwards)

','error',true); + system_message(array( + 'title'=>_('Missing required extension'), + 'body'=>'Your install of PHP appears to be missing GETTEXT support.

GETTEXT is used for language translation.

Please install GETTEXT support before using phpLDAPadmin.
(Dont forget to restart your web server afterwards)', + 'type'=>'error')); + +# Make sure this PHP install has all our required extensions +if (! extension_loaded('ldap')) + system_message(array( + 'title'=>_('Missing required extension'), + 'body'=>'Your install of PHP appears to be missing LDAP support.

Please install LDAP support before using phpLDAPadmin.
(Dont forget to restart your web server afterwards)', + 'type'=>'error')); + +# Make sure that we have php-xml loaded. +if (! function_exists('xml_parser_create')) + system_message(array( + 'title'=>_('Missing required extension'), + 'body'=>'Your install of PHP appears to be missing XML support.

Please install XML support before using phpLDAPadmin.
(Dont forget to restart your web server afterwards)', + 'type'=>'error')); /** * Helper functions. @@ -59,10 +84,10 @@ if (! extension_loaded('gettext')) if (isset($app['function_files']) && is_array($app['function_files'])) foreach ($app['function_files'] as $file_name ) { if (! file_exists($file_name)) - error(sprintf('Fatal error: Required file "%s" does not exist.',$file_name),'error',true); + error(sprintf('Fatal error: Required file "%s" does not exist.',$file_name),'error',null,true); if (! is_readable($file_name)) - error(sprintf('Fatal error: Cannot read the file "%s", its permissions may be too strict.',$file_name),'error',true); + error(sprintf('Fatal error: Cannot read the file "%s", its permissions may be too strict.',$file_name),'error',null,true); ob_start(); require $file_name; @@ -71,10 +96,10 @@ if (isset($app['function_files']) && is_array($app['function_files'])) # Configuration File check if (! file_exists($app['config_file'])) { - error(sprintf(_('You need to configure %s. Edit the file "%s" to do so. An example config file is provided in "%s.example".'),'phpLDAPadmin',$app['config_file'],$app['config_file']),'error',true); + error(sprintf(_('You need to configure %s. Edit the file "%s" to do so. An example config file is provided in "%s.example".'),'phpLDAPadmin',$app['config_file'],$app['config_file']),'error',null,true); } elseif (! is_readable($app['config_file'])) { - error(sprintf('Fatal error: Cannot read your configuration file "%s", its permissions may be too strict.',$app['config_file']),'error',true); + error(sprintf('Fatal error: Cannot read your configuration file "%s", its permissions may be too strict.',$app['config_file']),'error',null,true); } # If our config file fails the sanity check, then stop now. @@ -87,5 +112,8 @@ if (! check_config($app['config_file'])) { exit; } +if ($uri = get_request('URI','GET')) + header(sprintf('Location: cmd.php?%s',base64_decode($uri))); + include './cmd.php'; ?> diff --git a/htdocs/ldif_import.php b/htdocs/ldif_import.php index 4d08d70..50d6b40 100644 --- a/htdocs/ldif_import.php +++ b/htdocs/ldif_import.php @@ -1,5 +1,5 @@ isCommandAvailable('import')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('import'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('import')),'error','index.php'); +$entry = array(); $entry['continuous_mode'] = get_request('continuous_mode') ? true : false; $entry['ldif'] = get_request('ldif'); @@ -31,20 +32,20 @@ if ($entry['ldif']) { $entry['size'] = $_FILES['ldif_file']['size']; if (! is_array($_FILES['ldif_file'])) { - pla_error(_('Missing uploaded file.'),null,-1,false); + error(_('Missing uploaded file.'),'error'); return; } if (! file_exists($file)) { - pla_error(_('No LDIF file specified. Please try again.'),null,-1,false); + error(_('No LDIF file specified. Please try again.'),'error'); return; } if ($entry['size'] <= 0) { - pla_error(_('Uploaded LDIF file is empty.'),null,-1,false); + error(_('Uploaded LDIF file is empty.'),'error'); return; } } else { - pla_error(_('You must either upload a file or provide an LDIF in the text box.'),null,-1,false); + error(_('You must either upload a file or provide an LDIF in the text box.'),'error'); return; } @@ -182,7 +183,7 @@ function display_pla_parse_error($exception,$faultyEntry) { $errorMessage = $actionErrorMsg[$faultyEntry->getChangeType()]; echo '

'; - echo ''; + printf('
',IMGDIR); echo '',_('Maximum echo ''; printf('',_('Or paste your LDIF here')); -echo ''; +echo ''; echo ''; printf('', _("Don't stop on errors")); diff --git a/htdocs/login.php b/htdocs/login.php index fda54b9..a1ea2ba 100644 --- a/htdocs/login.php +++ b/htdocs/login.php @@ -1,5 +1,5 @@ auth_type = $save_auth_type; -$ldapserver->setLoginDN($login['dn'],$login['pass'],$anon_bind) or pla_error(_('Could not set cookie.')); +$ldapserver->setLoginDN($login['dn'],$login['pass'],$anon_bind) or error(_('Could not set cookie.'),'error','index.php'); set_lastactivity($ldapserver); if (! $anon_bind) { diff --git a/htdocs/login_form.php b/htdocs/login_form.php index d82be02..fcb6f87 100644 --- a/htdocs/login_form.php +++ b/htdocs/login_form.php @@ -1,5 +1,5 @@ auth_type, array('cookie','session'))) - pla_error(sprintf(_('Unknown auth_type: %s'),htmlspecialchars($ldapserver->auth_type))); + error(sprintf(_('Unknown auth_type: %s'),htmlspecialchars($ldapserver->auth_type)),'error','index.php'); printf('

%s %s

',_('Authenticate to server'),$ldapserver->name); # Check for a secure connection -if (! isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] != 'on') { +if (! isset($_SERVER['HTTPS']) || strtolower($_SERVER['HTTPS']) != 'on') { echo '
'; echo '
'; echo ''; @@ -36,8 +36,8 @@ echo '
'; echo ''; printf('',$ldapserver->server_id); -if (isset($_GET['redirect'])) - printf('',rawurlencode($_GET['redirect'])); +if (get_request('redirect','GET',false,false)) + printf('',rawurlencode(get_request('redirect','GET'))); echo '
'; echo '
'; printf('

%s

',_('LDIF Parse Error')); echo '
'; diff --git a/htdocs/ldif_import_form.php b/htdocs/ldif_import_form.php index 006dd90..ab883c0 100644 --- a/htdocs/ldif_import_form.php +++ b/htdocs/ldif_import_form.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); printf('

%s

',_('Import LDIF File')); printf('

%s: %s

',_('Server'),htmlspecialchars($ldapserver->name)); @@ -38,7 +38,7 @@ printf('
 %s %s
 
%s
 
 %s
'; diff --git a/htdocs/logout.php b/htdocs/logout.php index 3bb771b..39e6101 100644 --- a/htdocs/logout.php +++ b/htdocs/logout.php @@ -1,5 +1,5 @@ haveAuthInfo()) - pla_error(_('No one is logged in to that server.')); + error(_('No one is logged in to that server.'),'error','index.php'); if (in_array($ldapserver->auth_type, array('cookie','session','http'))) { syslog_notice (sprintf('Logout for %s',$ldapserver->getLoggedInDN())); if($ldapserver->auth_type!='http') - $ldapserver->unsetLoginDN() or pla_error(_('Could not logout.')); + $ldapserver->unsetLoginDN() or error(_('Could not logout.'),'error','index.php'); unset_lastactivity($ldapserver); @session_destroy(); } else - pla_error(sprintf(_('Unknown auth_type: %s'), htmlspecialchars($ldapserver->auth_type))); + error(sprintf(_('Unknown auth_type: %s'),htmlspecialchars($ldapserver->auth_type)),'error','index.php'); system_message(array( 'title'=>_('Logout'), diff --git a/htdocs/mass_delete.php b/htdocs/mass_delete.php index 71a8adf..81dfa48 100644 --- a/htdocs/mass_delete.php +++ b/htdocs/mass_delete.php @@ -1,5 +1,5 @@ isReadOnly() ) - pla_error(_('Unable to delete, server is in READY-ONLY mode.')); +if ($ldapserver->isReadOnly()) + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); -if (! $_SESSION[APPCONFIG]->isCommandAvailable('entry_delete', 'mass_delete')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete mass entries'))); +if (! $_SESSION[APPCONFIG]->isCommandAvailable('entry_delete','mass_delete')) + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete mass entries')),'error','index.php'); $confirmed = isset($_POST['confirmed']) ? true : false; isset($_POST['mass_delete']) or - pla_error(_('Error calling mass_delete.php. Missing mass_delete in POST vars.')); + error(_('Error calling mass_delete.php. Missing mass_delete in POST vars.'),'error','index.php'); $mass_delete = $_POST['mass_delete']; is_array($mass_delete) or - pla_error(_('mass_delete POST var is not an array.')); + error(_('mass_delete POST var is not an array.'),'error','index.php'); $ldapserver->isMassDeleteEnabled() or - pla_error(_('Mass deletion is not enabled. Please enable it in config.php before proceeding.')); + error(_('Mass deletion is not enabled. Please enable it in config.php before proceeding.'),'error','index.php'); printf('

%s

',_('Mass Deleting')); @@ -48,7 +48,7 @@ if ($confirmed == true) { $failed_dns = array(); if (! is_array($mass_delete)) - pla_error(_('Malformed mass_delete array.')); + error(_('Malformed mass_delete array.'),'error','index.php'); if (count($mass_delete) == 0) { echo '
'; diff --git a/htdocs/modify_member_form.php b/htdocs/modify_member_form.php index 22dc66f..a90e777 100644 --- a/htdocs/modify_member_form.php +++ b/htdocs/modify_member_form.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if (! $ldapserver->haveAuthInfo()) - pla_error(_('Not enough information to login to server. Please check your configuration.')); + error(_('Not enough information to login to server. Please check your configuration.'),'error','index.php'); -$attr = $_GET['attr']; -$dn = isset($_GET['dn']) ? $_GET['dn'] : null; +$attr = get_request('attr','GET'); +$dn = get_request('dn','GET'); $encoded_dn = rawurlencode($dn); $encoded_attr = rawurlencode($attr); @@ -39,7 +39,7 @@ if ($current_members) else $num_current_members = 0; -sort($current_members); +usort($current_members,'pla_compare_dns'); # Loop through all base dn's and search possible member entries foreach ($ldapserver->getBaseDN() as $base_dn) { @@ -74,6 +74,7 @@ printf('

%s %s     %s: %s

' printf('%s %s %s %s:', _('There are'),$num_current_members,_('members in group'),htmlspecialchars($rdn)); +$possible_members = array(); for ($i=0; $iGetValue('modify_member','posixgroupattr'))) $possible_members[$i] = $possible_values[$i][$_SESSION[APPCONFIG]->GetValue('modify_member','posixattr')]; @@ -81,7 +82,7 @@ for ($i=0; $iGetValue('modify_member','attr')]; } -sort($possible_members); +usort($possible_members,'pla_compare_dns'); /* * Show only user that are not already in group. @@ -110,8 +111,8 @@ echo ''; echo '
'; echo ''; -printf('',_('Available members')); -printf('',_('Group members')); +printf('',IMGDIR,_('Available members')); +printf('',IMGDIR,_('Group members')); echo ''; # Generate select box from all possible members diff --git a/htdocs/password_checker.php b/htdocs/password_checker.php index e059155..4190c7f 100644 --- a/htdocs/password_checker.php +++ b/htdocs/password_checker.php @@ -1,5 +1,5 @@ '; +$entry = array(); $entry['hash'] = get_request('hash','REQUEST'); $entry['password'] = get_request('check_password','REQUEST'); $entry['action'] = get_request('action','REQUEST'); @@ -34,7 +35,7 @@ echo '
Users %sMembers %sUsers %sMembers %s
'; echo ''; printf('',_('Compare')); printf('', - $entry['enc_type'] ? 'text' : 'password',htmlspecialchars($entry['hash'])); + (obfuscate_password_display($entry['enc_type']) ? 'password' : 'text'),htmlspecialchars($entry['hash'])); echo ''; echo ''; diff --git a/htdocs/purge_cache.php b/htdocs/purge_cache.php index 15de8e4..911d88e 100644 --- a/htdocs/purge_cache.php +++ b/htdocs/purge_cache.php @@ -1,5 +1,5 @@ isCommandAvailable('purge')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('purge'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('purge')),'error','index.php'); $purge_session_keys = array('cache'); diff --git a/htdocs/rdelete.php b/htdocs/rdelete.php index 96595eb..fde4e9a 100644 --- a/htdocs/rdelete.php +++ b/htdocs/rdelete.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); -if (! $_SESSION[APPCONFIG]->isCommandAvailable('entry_delete', 'simple_delete')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete entry'))); +if (! $_SESSION[APPCONFIG]->isCommandAvailable('entry_delete','simple_delete')) + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete entry')),'error','index.php'); -$entry['dn'] = $_POST['dn']; +$entry = array(); +$entry['dn'] = get_request('dn'); if (! $entry['dn']) - pla_error(_('You must specify a DN')); + error(_('You must specify a DN'),'error','index.php'); if (! $ldapserver->dnExists($entry['dn'])) - pla_error(sprintf(_('No such entry: %s'),htmlspecialchars($entry['dn']))); + error(sprintf('%s (%s)',_('No such entry.'),htmlspecialchars($entry['dn'])),'error','index.php'); printf('

'._('Deleting %s').'

',htmlspecialchars(get_rdn($entry['dn']))); printf('

%s

',_('Recursive delete progress')); @@ -42,8 +43,10 @@ if ($result) { printf(_('Entry %s and sub-tree deleted successfully.'),''.htmlspecialchars($entry['dn']).''); } else { - pla_error(sprintf(_('Could not delete the entry: %s'),htmlspecialchars($entry['dn'])), - $ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not delete the entry.').sprintf(' (%s)',pretty_print_dn($entry['dn'])), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); } function pla_rdelete($ldapserver,$dn) { @@ -60,8 +63,10 @@ function pla_rdelete($ldapserver,$dn) { return true; } else { - pla_error(sprintf(_('Failed to delete entry %s'),htmlspecialchars($dn)), - $ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not delete the entry.').sprintf(' (%s)',pretty_print_dn($entry['dn'])), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); } } else { @@ -77,8 +82,10 @@ function pla_rdelete($ldapserver,$dn) { return true; } else { - pla_error(sprintf(_('Failed to delete entry %s'),htmlspecialchars($dn)), - $ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not delete the entry.').sprintf(' (%s)',pretty_print_dn($entry['dn'])), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); } } } diff --git a/htdocs/refresh.php b/htdocs/refresh.php index cab3f82..5658a83 100644 --- a/htdocs/refresh.php +++ b/htdocs/refresh.php @@ -1,5 +1,5 @@ isCommandAvailable('server_refresh')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('refresh server'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('refresh server')),'error','index.php'); unset($_SESSION['cache'][$ldapserver->server_id]['tree']); diff --git a/htdocs/rename.php b/htdocs/rename.php index 9670fb5..6459192 100644 --- a/htdocs/rename.php +++ b/htdocs/rename.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if (! $_SESSION[APPCONFIG]->isCommandAvailable('entry_rename')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('rename entry'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('rename entry')),'error','index.php'); -$dn = ($_POST['dn']); +$dn = get_request('dn'); if (! $ldapserver->isBranchRenameEnabled()) { # we search all children, not only the visible children in the tree $children = $ldapserver->getContainerContents($dn); if (count($children) > 0) - pla_error(_('You cannot rename an entry which has children entries (eg, the rename operation is not allowed on non-leaf entries)')); + error(_('You cannot rename an entry which has children entries (eg, the rename operation is not allowed on non-leaf entries)'),'error','index.php'); } -$new_rdn = ($_POST['new_rdn']); +$new_rdn = get_request('new_rdn'); $container = get_container($dn); $new_dn = sprintf('%s,%s',$new_rdn,$container); if ($new_dn == $dn) - pla_error(_('You did not change the RDN')); + error(_('You did not change the RDN'),'error','index.php'); $old_dn_attr = explode('=',$dn); $old_dn_attr = $old_dn_attr[0]; @@ -44,7 +44,7 @@ $old_dn_attr = $old_dn_attr[0]; $new_dn_value = explode('=',$new_rdn,2); if (count($new_dn_value) != 2 || ! isset($new_dn_value[1])) - pla_error(_('Invalid RDN value')); + error(_('Invalid RDN value'),'error','index.php'); $new_dn_attr = $new_dn_value[0]; $new_dn_value = $new_dn_value[1]; @@ -58,7 +58,7 @@ if ($success) { $success = $ldapserver->rename($dn,$new_rdn,$container,$deleteoldrdn); } else { - pla_error(_('Could not rename the entry') ); + error(_('Could not rename the entry'),'error','index.php'); } if ($success) { diff --git a/htdocs/rename_form.php b/htdocs/rename_form.php index cee7784..d251a48 100644 --- a/htdocs/rename_form.php +++ b/htdocs/rename_form.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); if (! $ldapserver->haveAuthInfo()) - pla_error(_('Not enough information to login to server. Please check your configuration.')); + error(_('Not enough information to login to server. Please check your configuration.'),'error','index.php'); $dn = $_GET['dn']; $rdn = get_rdn($dn); diff --git a/htdocs/schema.php b/htdocs/schema.php index a39fb34..7eece09 100644 --- a/htdocs/schema.php +++ b/htdocs/schema.php @@ -1,5 +1,5 @@ isCommandAvailable('schema')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('view schema'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('view schema')),'error','index.php'); +$entry = array(); $entry['view'] = get_request('view','GET','false','objectClasses'); $entry['value'] = get_request('viewvalue','GET'); @@ -63,7 +64,7 @@ echo '
'; switch($entry['view']) { case 'syntaxes': - $highlight_oid = isset($_GET['highlight_oid']) ? $_GET['highlight_oid'] : false; + $highlight_oid = get_request('highlight_oid','GET',false,false); echo '
'; print '
%s
'; @@ -73,7 +74,7 @@ switch($entry['view']) { $schema_syntaxes = $ldapserver->SchemaSyntaxes(null,true); if (! $schema_syntaxes) - pla_error($schema_error_str); + error($schema_error_str,'error','index.php'); foreach ($schema_syntaxes as $syntax) { $counter++; @@ -108,14 +109,15 @@ switch($entry['view']) { 'usage' => _('Usage'), 'maximum_length' => _('Maximum Length'), 'aliases' => _('Aliases'), - 'used_by_objectclasses' => _('Used by objectClasses') + 'used_by_objectclasses' => _('Used by objectClasses'), + 'force_as_may' => _('Force as MAY by config') ); $schema_attrs = $ldapserver->SchemaAttributes(); $schema_object_classes = $ldapserver->SchemaObjectClasses(); if (! $schema_attrs || ! $schema_object_classes) - pla_error($schema_error_str); + error($schema_error_str,'error','index.php'); printf('%s:',_('Jump to an attribute type')); echo ''; @@ -279,6 +281,10 @@ switch($entry['view']) { print ''; break; + case 'force_as_may': + printf('',$attr->forced_as_may ? _('Yes') : _('No')); + break; + } print ''; } @@ -292,7 +298,7 @@ switch($entry['view']) { case 'matching_rules': $schema_matching_rules = $ldapserver->MatchingRules(null,true); if (! $schema_matching_rules) - pla_error($schema_error_str); + error($schema_error_str,'error','index.php'); printf('%s
',_('Jump to a matching rule')); @@ -371,7 +377,7 @@ switch($entry['view']) { case 'objectClasses': $schema_oclasses = $ldapserver->SchemaObjectClasses(); if (! $schema_oclasses) - pla_error($schema_error_str); + error($schema_error_str,'error','index.php'); printf('%s:',_('Jump to an objectClass')); @@ -485,6 +491,11 @@ switch($entry['view']) { $href = htmlspecialchars(sprintf($entry['href']['objectClasses'],strtolower($attr->getSource()))); printf('(%s %s)',_('Inherited from'),$href,$attr->getSource()); } + + if ($oclass->isForceMay($attr->getName())) { + echo '
'; + printf('%s',_('This attribute has been forced as a MAY attribute by the configuration')); + } echo ''; } echo ''; @@ -502,5 +513,5 @@ switch($entry['view']) { } if (! is_null($entry['value']) && ! $entry['viewed']) - pla_error(sprintf(_('No such schema item: "%s"'),htmlspecialchars($entry['value']))); + error(sprintf(_('No such schema item: "%s"'),htmlspecialchars($entry['value'])),'error','index.php'); ?> diff --git a/htdocs/search.php b/htdocs/search.php index 05ec0f6..7f2764d 100644 --- a/htdocs/search.php +++ b/htdocs/search.php @@ -1,5 +1,5 @@ GetValue('search','display')); $entry['form'] = get_request('form','GET',false,get_request('form','SESSION')); @@ -117,15 +118,15 @@ echo '
'; if ($entry['search']) { if ($entry['form'] == 'advanced') { if (! $_SESSION[APPCONFIG]->isCommandAvailable('search','advanced_search')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('advanced search'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('advanced search')),'error','index.php'); } elseif ($entry['form'] == 'predefined') { if (! $_SESSION[APPCONFIG]->isCommandAvailable('search','predefined_search')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('predefined search'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('predefined search')),'error','index.php'); } elseif ($entry['form'] == 'simple') { if (! $_SESSION[APPCONFIG]->isCommandAvailable('search','simple_search')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('simple search'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('simple search')),'error','index.php'); } if ($entry['form'] == 'advanced') { @@ -247,7 +248,10 @@ if ($entry['search']) { $entry['scope'],$entry['orderby']['array'],$_SESSION[APPCONFIG]->GetValue('deref','search')); if ((! $results) && $ldapserver->errno()) - pla_error(_('Encountered an error while performing search.'),$ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Encountered an error while performing search.'), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); $errno = $ldapserver->errno(); @@ -269,11 +273,11 @@ if ($entry['search']) { $href = htmlspecialchars(sprintf('cmd.php?cmd=export_form&server_id=%s&scope=%s&dn=%s&filter=%s&attributes=%s', $ldapserver->server_id,$entry['scope'],$base_dn,rawurlencode($entry['filter']['clean']),rawurlencode(join(', ',$search_result_attributes)))); - printf(''; if (preg_match('/^[0-9]+\.[0-9]+/',$value)) { - printf('', - htmlspecialchars($value), htmlspecialchars($value)); + printf('', + IMGDIR,htmlspecialchars($value), htmlspecialchars($value)); if ($oidtext = support_oid_to_text($value)) if (isset($oidtext['ref'])) diff --git a/htdocs/show_cache.php b/htdocs/show_cache.php index 302efa9..0ea9e1d 100644 --- a/htdocs/show_cache.php +++ b/htdocs/show_cache.php @@ -1,5 +1,5 @@ GetValue('appearance','hide_debug_info')) { poststr += "&index=" + encodeURI(xx); } - obj.innerHTML = ' Loading...'; + obj.innerHTML = ' Loading...'; makePOSTRequest('cmd.php',poststr,'alertCacheContents','cancelCacheContents'); } diff --git a/htdocs/template_engine.php b/htdocs/template_engine.php index 1b8fb38..1502816 100644 --- a/htdocs/template_engine.php +++ b/htdocs/template_engine.php @@ -1,5 +1,5 @@ dnExists($entry['dn']['string']) - or pla_error(sprintf(_('No such entry: %s'),pretty_print_dn($entry['dn']['string']))); + or error(sprintf('%s (%s)',_('No such entry'),pretty_print_dn($entry['dn']['string'])),'error','index.php'); $tree = get_cached_item($ldapserver->server_id,'tree'); @@ -51,7 +52,7 @@ if ($entry['dn']['string']) { } else { if ($ldapserver->isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); # Create a new empty entry $entryfactoryclass = $_SESSION[APPCONFIG]->GetValue('appearance','entry_factory'); diff --git a/htdocs/timeout.php b/htdocs/timeout.php deleted file mode 100644 index dcc7b1b..0000000 --- a/htdocs/timeout.php +++ /dev/null @@ -1,41 +0,0 @@ -session_timeout ? $ldapserver->session_timeout : session_cache_expire()-1; -?> - -

name; ?>

-
-
-
- -
-
-
- -
- - - diff --git a/htdocs/update.php b/htdocs/update.php index fe31f55..6faf8ff 100644 --- a/htdocs/update.php +++ b/htdocs/update.php @@ -1,5 +1,5 @@ server_id,$entry['dn']['encode'])); die(); } if ($ldapserver->isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); $entry['update'] = get_request('update_array','POST',false,array()); $entry['skip'] = get_request('skip_array','POST',false,array()); $failed_attrs = array(); if (! is_array($entry['update'])) - pla_error(_('update_array is malformed. This might be a phpLDAPadmin bug. Please report it.')); + error(_('update_array is malformed. This might be a phpLDAPadmin bug. Please report it.'),'error','index.php'); run_hook ('pre_update', array('server_id'=>$ldapserver->server_id,'dn'=>$entry['dn']['string'],'update_array'=>$entry['update'])); @@ -58,13 +59,14 @@ foreach ($entry['update'] as $attr => $val) { $entry['update'][$attr] = array(); if (! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_delete')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete attribute'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('delete attribute')),'error','index.php'); + } else { # Skip change $entry['update'][$attr] = $val; if (! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_add_value') && ! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_delete_value')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('modify attribute values'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('modify attribute values')),'error','index.php'); } } else { @@ -77,7 +79,7 @@ foreach ($entry['update'] as $attr => $val) { if (! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_add_value') && ! $_SESSION[APPCONFIG]->isCommandAvailable('attribute_delete_value')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('modify attribute values'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('modify attribute values')),'error','index.php'); } } } @@ -89,8 +91,8 @@ foreach ($entry['update'] as $attr_name => $val) { $href['search'] = sprintf('cmd.php?cmd=search&search=true&form=advanced&server_id=%s&filter=%s=%s', $ldapserver->server_id,$attr_name,$badattr); - pla_error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'), - $attr_name,$badattr,$entry['dn']['string'],$href['search'])); + error(sprintf(_('Your attempt to add %s (%s) to
%s
is NOT allowed. That attribute/value belongs to another entry.

You might like to search for that entry.'), + $attr_name,$badattr,$entry['dn']['string'],$href['search']),'error','index.php'); } if (run_hook('pre_attr_modify', @@ -100,8 +102,9 @@ foreach ($entry['update'] as $attr_name => $val) { $failed_attrs[$attr_name] = $val; } elseif ($ldapserver->isAttrReadOnly($attr)) { - pla_error(sprintf(_('The attribute "%s" is flagged as read-only in the phpLDAPadmin configuration.'), - htmlspecialchars($attr_name))); + error(sprintf(_('The attribute "%s" is flagged as read-only in the phpLDAPadmin configuration.'), + htmlspecialchars($attr_name)),'error','index.php'); + } else { // binary values if (isset($_SESSION['submitform'][$attr_name])) { @@ -175,6 +178,9 @@ if ($result) { die(); } else { - pla_error(_('Could not perform ldap_modify operation.'),$ldapserver->error(),$ldapserver->errno()); + system_message(array( + 'title'=>_('Could not perform ldap_modify operation.'), + 'body'=>ldap_error_msg($ldapserver->error(),$ldapserver->errno()), + 'type'=>'error')); } ?> diff --git a/htdocs/update_confirm.php b/htdocs/update_confirm.php index 9909553..dcfc4d0 100644 --- a/htdocs/update_confirm.php +++ b/htdocs/update_confirm.php @@ -1,5 +1,5 @@ isReadOnly()) - pla_error(_('You cannot perform updates while server is in read-only mode')); + error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); /***************/ /* get entry */ /***************/ - + +$entry = array(); $entry['dn']['string'] = get_request('dn'); $entry['dn']['encode'] = rawurlencode($entry['dn']['string']); if (! $entry['dn']['string'] || ! $ldapserver->dnExists($entry['dn']['string'])) - pla_error(sprintf(_('The entry (%s) does not exist.'),htmlspecialchars($entry['dn']['string'])),null,-1,true); + error(sprintf(_('The entry (%s) does not exist.'),htmlspecialchars($entry['dn']['string'])),'error','index.php'); $tree = get_cached_item($ldapserver->server_id,'tree'); $entry['ldap'] = null; @@ -40,7 +41,7 @@ if ($tree) { } if (! $entry['ldap'] || $entry['ldap']->isReadOnly()) - pla_error(sprintf(_('The entry (%s) is in readonly mode.'),htmlspecialchars($entry['dn']['string'])),null,-1,true); + error(sprintf(_('The entry (%s) is in readonly mode.'),htmlspecialchars($entry['dn']['string'])),'error','index.php'); /***************/ /* old values */ @@ -96,9 +97,9 @@ $attr_to_delete = array(); // if objectClass attribute is modified if (isset($entry['values']['new']['objectClass'])) { - if (!isset($entry['values']['old']['objectClass'])) { - pla_error(_('An entry should have one structural objectClass.')); - } + if (!isset($entry['values']['old']['objectClass'])) + error(_('An entry should have one structural objectClass.'),'error','index.php'); + // deleted objectClasses foreach ($entry['values']['old']['objectClass'] as $oldOC) { if (!in_array($oldOC, $entry['values']['new']['objectClass'])) { diff --git a/htdocs/view_jpeg_photo.php b/htdocs/view_jpeg_photo.php index ed9313d..8dcdfd2 100644 --- a/htdocs/view_jpeg_photo.php +++ b/htdocs/view_jpeg_photo.php @@ -1,5 +1,5 @@ GetValue('jpeg','tmpdir'),$file['name']); if (! file_exists($file['name'])) - pla_error(sprintf('%s%s %s',_('No such file'),_(':'),htmlspecialchars($file['name']))); + error(sprintf('%s%s %s',_('No such file'),_(':'),htmlspecialchars($file['name'])),'error','index.php'); $file['handle'] = fopen($file['name'],'r'); $file['data'] = fread($file['handle'],filesize($file['name'])); fclose($file['handle']); -if (ob_get_level()) - ob_clean(); +$obStatus = ob_get_status(); +if (isset($obStatus['type']) && $obStatus['type'] && $obStatus['status']) + ob_end_clean(); Header('Content-type: image/jpeg'); Header('Content-disposition: inline; filename=jpeg_photo.jpg'); diff --git a/htdocs/welcome.php b/htdocs/welcome.php index fb7aca2..078a88c 100644 --- a/htdocs/welcome.php +++ b/htdocs/welcome.php @@ -1,5 +1,5 @@ '; echo '

'; -printf('%s',_('phpLDAPadmin logo'),_('phpLDAPadmin logo')); +printf('%s',IMGDIR,_('phpLDAPadmin logo'),_('phpLDAPadmin logo')); echo '

'; echo _('Use the menu to the left to navigate'); echo '

'; diff --git a/lib/AJAXTree.php b/lib/AJAXTree.php index b4a2e8c..9c902a6 100644 --- a/lib/AJAXTree.php +++ b/lib/AJAXTree.php @@ -1,5 +1,5 @@ '; - echo '->'; + printf('->',$node_id,IMGDIR,$entry->getIcon($ldapserver)); echo ''; echo ' '; echo ''; @@ -131,6 +131,10 @@ class AJAXTree extends PLMTree { $first_child = $this->get_plm_before_first_child($parent_entry,$code); $last_child = $this->get_plm_after_last_child($parent_entry,$code); + # If compression is on, we need to compress this output - but only if called by draw_tree_node + if (function_exists('isCompress') && isCompress() && get_request('cmd','REQUEST') == 'draw_tree_node') + ob_start(); + echo $first_child; for ($i=0; $i
'._('Retrieving DN').'...<\/small>\'); + if (mainPageDiv) includeHTML(mainPageDiv, \'
'._('Retrieving DN').'...<\/small>\'); makeGETRequest(\'cmd.php\', urlParameters+\'&meth=get_body\', \'alertMainPage\', \'cancelMainPage\'); return false; } @@ -337,7 +347,7 @@ class AJAXTree extends PLMTree { $output .= $this->get_indentation($level); $output .= '--'; $output .= '
'; - $output .= '->'; + $output .= sprintf('->',IMGDIR); $output .= ''; $output .= ' '; $output .= ''; @@ -361,7 +371,7 @@ class AJAXTree extends PLMTree { $output .= $this->get_indentation($level); $output .= '--'; $output .= ''; - $output .= '->'; + $output .= sprintf('->',IMGDIR); $output .= ''; $output .= ' '; $output .= ''; diff --git a/lib/Attribute.php b/lib/Attribute.php index 016c9fd..492203c 100644 --- a/lib/Attribute.php +++ b/lib/Attribute.php @@ -1,5 +1,5 @@ entry) { - //$rdn = get_rdn($this->entry->getDn()); - //$attr = $this->name; - //return preg_match("/^${attr}=/", $rdn); - return ($this->name == $this->entry->getRdnAttributeName()); + return (preg_grep('/'.$this->name.'/',$this->entry->getRdnAttributeName())); } else { return false; } diff --git a/lib/DefaultCreatingEntry.php b/lib/DefaultCreatingEntry.php index 7ea1b7d..85ad8b6 100644 --- a/lib/DefaultCreatingEntry.php +++ b/lib/DefaultCreatingEntry.php @@ -1,5 +1,5 @@ getRdnAttribute(); - if ($attr) return $attr->getName(); - else return ''; + if ($attr) return array($attr->getName()); + else return array(''); } public function getRdnAttribute() { diff --git a/lib/DefaultEditingEntry.php b/lib/DefaultEditingEntry.php index cfca77a..9efc40e 100644 --- a/lib/DefaultEditingEntry.php +++ b/lib/DefaultEditingEntry.php @@ -1,5 +1,5 @@ getCustomDNSysAttrs($this->getDn()); + if (! $custom_int_attrs_vals) $attrs_vals = array(); + elseif (! is_array($custom_int_attrs_vals)) $custom_int_attrs_vals = array($custom_int_attrs_vals); + $attrs_vals = $ldapserver->getDNAttrs($this->getDn(),false,$_SESSION[APPCONFIG]->GetValue('deref','view')); if (! $attrs_vals) $attrs_vals = array(); elseif (! is_array($attrs_vals)) $attrs_vals = array($attrs_vals); + $custom_attrs_vals = $ldapserver->getCustomDNAttrs($this->getDn(),false,$_SESSION[APPCONFIG]->GetValue('deref','view')); + if (! $custom_attrs_vals) $attrs_vals = array(); + elseif (! is_array($custom_attrs_vals)) $custom_attrs_vals = array($custom_attrs_vals); + + $int_attrs_vals = array_merge($int_attrs_vals,$custom_int_attrs_vals); + $attrs_vals = array_merge($attrs_vals,$custom_attrs_vals); $attrs_vals = array_merge($attrs_vals, $int_attrs_vals); uksort($attrs_vals,'sortAttrs'); # Sort these entries diff --git a/lib/Entry.php b/lib/Entry.php index 35b1d0d..c253875 100644 --- a/lib/Entry.php +++ b/lib/Entry.php @@ -1,5 +1,5 @@ dn) { - $i = strpos($this->dn, '='); - if ($i !== false) $attr = substr($this->dn, 0, $i); + $i = strpos($this->dn, ','); + if ($i !== false) { + $attrs = split('\+',substr($this->dn, 0, $i)); + foreach ($attrs as $id => $attr) { + list ($name,$value) = split('=',$attr); + $attrs[$id] = $name; + } + $attr = array_unique($attrs); + } } return $attr; } diff --git a/lib/EntryReader.php b/lib/EntryReader.php index 599042e..dc559c3 100644 --- a/lib/EntryReader.php +++ b/lib/EntryReader.php @@ -1,5 +1,5 @@ context == ENTRY_READER_CREATION_CONTEXT) && ($name == 'objectClass')) return; - $old_vals = $this->get('OldValues', $attribute); + if ($this->context == ENTRY_READER_EDITING_CONTEXT) + $old_vals = $this->get('OldValues', $attribute); + else + $old_vals = array(); + $new_vals = $this->get('NewValues', $attribute); if (isset($_POST['old_values'][$name])) { @@ -205,7 +209,7 @@ class EntryReader extends Visitor { } if (is_null($val)) { - pla_error(sprintf(_('Your template is missing variable (%s)'), $request)); + error(sprintf(_('Your template is missing variable (%s)'),$request),'error','index.php'); } return $val; @@ -255,7 +259,7 @@ class EntryReader extends Visitor { if (function_exists($matches[1])) { $val = call_user_func($matches[1], $matches[2], $attribute, $i, $val); } else { - pla_error(sprintf(_('Your template has an unknown post function (%s).'), $matches[1])); + error(sprintf(_('Your template has an unknown post function (%s).'),$matches[1]),'error','index.php'); } } } diff --git a/lib/EntryWriter1.php b/lib/EntryWriter1.php index 02a3d89..7f80981 100644 --- a/lib/EntryWriter1.php +++ b/lib/EntryWriter1.php @@ -1,5 +1,5 @@ draw('Title', $entry); $this->draw('Subtitle', $entry); echo "\n"; - // menu + # Menu $this->draw('Menu', $entry); } @@ -56,13 +56,20 @@ class EntryWriter1 extends EntryWriter { protected function drawEntryMenu($entry) {} protected function drawEntryJavascript($entry) { + printf("\n\n",__METHOD__); + if (isset($_SESSION[APPCONFIG])) { - echo ''; + echo "\n"; + echo ''."\n"; + echo ''."\n"; + echo "\n"; } + echo ''."\n"; echo ''; + } - echo ''; + return values; + } + '."\n"; + echo ''."\n"; + echo "\n"; echo ''; + '."\n"; echo ''; + '."\n"; for ($i = 0; $i < count($this->shown_attributes); $i++) { $this->draw('Javascript', $this->shown_attributes[$i]); @@ -175,7 +188,9 @@ class EntryWriter1 extends EntryWriter { echo ''; + '."\n"; + + printf("\n\n",__METHOD__); } /********************************/ @@ -186,10 +201,10 @@ class EntryWriter1 extends EntryWriter { if (DEBUG_ENABLED) debug_log('Entered with (%s)',1,__FILE__,__LINE__,__METHOD__,$entry->getDn()); - // init + # Init $this->visit('Entry::Start', $entry); - // check + # Check $container = $entry->getContainer(); $container_ok = true; $objectclasses_ok = true; @@ -205,17 +220,17 @@ class EntryWriter1 extends EntryWriter { } } - // header + # Header $this->draw('Header', $entry); - // errors + # Errors if (!$container_ok) { - pla_error(sprintf(_('The container you specified (%s) does not exist.'),htmlspecialchars($container)), null, -1, false); + error(sprintf(_('The container you specified (%s) does not exist.'),htmlspecialchars($container)),'error'); echo '
'; } if (!$objectclasses_ok) { - pla_error(_('You did not select any objectClasses for this object.'), null, -1, false); + error(_('You did not select any objectClasses for this object.'),'error'); echo '
'; } } @@ -318,7 +333,7 @@ class EntryWriter1 extends EntryWriter { public function drawDefaultCreatingEntryStepFormEnd($entry, $step) { echo ''; - // javascript + # Javascript $this->draw('Javascript', $entry); } @@ -381,13 +396,11 @@ class EntryWriter1 extends EntryWriter { protected function drawDefaultCreatingEntryShownAttributes($entry) { $attrs = array(); - // put required attributes first - foreach ($this->shown_attributes as $sa) { + # Put required attributes first + foreach ($this->shown_attributes as $sa) if ($sa->isRequired()) $attrs[] = $sa; - } - foreach ($this->shown_attributes as $sa) { + foreach ($this->shown_attributes as $sa) if (!$sa->isRequired()) $attrs[] = $sa; - } $has_required_attrs = false; $has_optional_attrs = false; @@ -409,7 +422,7 @@ class EntryWriter1 extends EntryWriter { } } - $this->draw('', $attr); + $this->draw('',$attr,$entry); echo "\n"; } @@ -421,7 +434,7 @@ class EntryWriter1 extends EntryWriter { protected function drawDefaultCreatingEntryHiddenAttributes($entry) { foreach ($this->hidden_attributes as $attr) { - $this->draw('', $attr); + $this->draw('',$attr,$entry); echo "\n"; } } @@ -438,13 +451,13 @@ class EntryWriter1 extends EntryWriter { if (DEBUG_ENABLED) debug_log('Entered with (%s)',1,__FILE__,__LINE__,__METHOD__,$entry->getDn()); - // init + # Init $this->visit('Entry::Start', $entry); - // header + # Header $this->draw('Header', $entry); - // form start + # Form start if (! $entry->isReadOnly()) { echo '
'; printf('',$this->index); @@ -459,21 +472,21 @@ class EntryWriter1 extends EntryWriter { if (DEBUG_ENABLED) debug_log('Entered with (%s)',1,__FILE__,__LINE__,__METHOD__,$entry->getDn()); - // draw internal attributes + # Draw internal attributes if (get_request('show_internal_attrs','REQUEST')) { $this->draw('InternalAttributes', $entry); echo "\n\n"; } - // draw visible attributes + # Draw visible attributes $this->draw('ShownAttributes', $entry); - // form end + # Form end if (! $entry->isReadOnly()) { $this->draw('FormSubmitButton', $entry); echo '

%s
[ Save %s ]', - $href,_('export results')); + printf('[ Save %s ]', + $href,IMGDIR,_('export results')); } - printf('[ rename %s%s',_('Format'),_(':')); + printf('[ rename %s%s',IMGDIR,_('Format'),_(':')); foreach ($result_formats as $f) { echo ' '; @@ -380,7 +384,7 @@ if ($entry['search']) { elseif ($entry['format'] == 'table') require LIBDIR.'search_results_table.php'; else - pla_error(sprintf(_('Unrecognized search result format: %s'),htmlspecialchars($entry['format']))); + error(sprintf(_('Unrecognized search result format: %s'),htmlspecialchars($entry['format'])),'error','index.php'); echo '
'; if (trim($pager_html)) diff --git a/htdocs/server_info.php b/htdocs/server_info.php index 5fef5cd..1d3d586 100644 --- a/htdocs/server_info.php +++ b/htdocs/server_info.php @@ -1,5 +1,5 @@ isCommandAvailable('server_info')) - pla_error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('view server informations'))); + error(sprintf('%s%s %s',_('This operation is not permitted by the configuration'),_(':'),_('view server information')),'error','index.php'); # The attributes we'll examine when searching the LDAP server's RootDSE $root_dse_attributes = array( @@ -94,8 +94,8 @@ foreach ($attrs as $attr => $values) { print '
%s%s
'; - // draw hidden attributes + # Draw hidden attributes $this->draw('HiddenAttributes', $entry); printf(''); @@ -482,7 +495,7 @@ class EntryWriter1 extends EntryWriter { printf(''); } - // javascript + # Javascript $this->draw('Javascript', $entry); } @@ -631,13 +644,13 @@ class EntryWriter1 extends EntryWriter { case IdEntryRenameMenuItem : if (!$entry->isReadOnly() && $config->isCommandAvailable('entry_rename')) { - $rdnAttr = $entry->getAttribute($entry->getRdnAttributeName()); - if ($rdnAttr && $rdnAttr->isVisible() && !$rdnAttr->isReadOnly()) { - return $this->get('RenameMenuItem', $entry); - } else { - return ''; + foreach ($entry->getRdnAttributeName() as $rdnAttr) { + $rdnAttr = $entry->getAttribute($rdnAttr); + if ($rdnAttr && $rdnAttr->isVisible() && !$rdnAttr->isReadOnly()) + return $this->get('RenameMenuItem', $entry); } - } else return ''; + } + return ''; case IdEntryDeleteAttributeMessage : if ($config->GetValue('appearance', 'show_hints') @@ -666,15 +679,15 @@ class EntryWriter1 extends EntryWriter { static $children_count = false; static $more_children = false; if ($children_count === false) { - // visible children in the tree + # Visible children in the tree $children_count = $entry->getChildrenNumber(); - // is there filtered children ? + # Is there filtered children ? $more_children = $entry->isSizeLimited(); if (!$more_children) { - // all children in ldap + # All children in ldap $all_children = $this->getLDAPServer()->getContainerContents( - $entry->getDn(), $children_count + 1, - '(objectClass=*)', $config->GetValue('deref','view')); + $entry->getDn(), $children_count + 1, + '(objectClass=*)', $config->GetValue('deref','view')); $more_children = (count($all_children) > $children_count); } } @@ -805,7 +818,7 @@ class EntryWriter1 extends EntryWriter { } protected function getDefaultEditingEntryDeleteAttributeMessage($entry) { - if ($_SESSION[APPCONFIG]->isCommandAvailable('attribute_delete_value')) + if ($_SESSION[APPCONFIG]->isCommandAvailable('attribute_delete_value') && ! $entry->isReadOnly()) return sprintf($this->hint_layout,_('Hint: To delete an attribute, empty the text field and click save.')); else return ''; @@ -830,7 +843,7 @@ class EntryWriter1 extends EntryWriter { $counter = 0; foreach ($this->internal_attributes as $attr) { - $this->draw('',$attr); + $this->draw('',$attr,$entry); $counter++; echo "\n"; } @@ -844,14 +857,14 @@ class EntryWriter1 extends EntryWriter { protected function drawDefaultEditingEntryShownAttributes($entry) { foreach ($this->shown_attributes as $attr) { - $this->draw('',$attr); + $this->draw('',$attr,$entry); echo "\n"; } } protected function drawDefaultEditingEntryHiddenAttributes($entry) { foreach ($this->hidden_attributes as $attr) { - $this->draw('',$attr); + $this->draw('',$attr,$entry); echo "\n"; } } @@ -970,13 +983,11 @@ class EntryWriter1 extends EntryWriter { echo '
'; } else { - // Patch 1539633 - // default action is create.php - // you can change this behavior by setting myscript.php in template header echo ''; printf('', $entry->hasProperty('action') ? rawurlencode($entry->getProperty('action')) : 'create'); } + } else { $this->draw('DefaultCreatingEntry::StepFormStart', $entry, $step); } @@ -998,7 +1009,7 @@ class EntryWriter1 extends EntryWriter { $this->draw('RdnChooser', $entry); - // draw attributes + # Draw attributes $this->draw('ShownAttributes', $entry); $this->draw('StepFormSubmitButton', $entry, $step); @@ -1040,6 +1051,7 @@ class EntryWriter1 extends EntryWriter { $i = -1; $templates = &$entry->getTemplates(); $nb_templates = count($templates); + if ($entry->hasDefaultTemplate()) $nb_templates++; foreach ($templates as $template_name => $template_attrs) { @@ -1109,12 +1121,13 @@ class EntryWriter1 extends EntryWriter { foreach ($this->shown_attributes as $attr) { $page = $attr->getProperty('page'); + if ($page == $this->step) { - $this->draw('', $attr); + $this->draw('',$attr,$entry); echo "\n"; - //} elseif ($page < $this->step) { + } else { - // the displayed attributes are the visible attributes in shown_attributes list + # The displayed attributes are the visible attributes in shown_attributes list $attr->hide(); $this->hidden_attributes[] = $attr; } @@ -1128,15 +1141,13 @@ class EntryWriter1 extends EntryWriter { } foreach ($this->hidden_attributes as $attr) { - //$page = $attr->hasProperty('page') ? $attr->getProperty('page') : -1; - //if ($page <= $this->step) { - $this->draw('', $attr); - echo "\n"; - //} + $this->draw('',$attr,$entry); + echo "\n"; } } protected function drawTemplateCreatingEntryJavascript($entry) { + printf("\n\n",__METHOD__); $this->draw('DefaultCreatingEntry::Javascript', $entry); $templates = new Templates($this->index); @@ -1173,17 +1184,21 @@ class EntryWriter1 extends EntryWriter { // here comes template-specific implementation, generated by php if (false) {}'; foreach ($entry->getAttributes() as $attribute) { - $attr = $attribute->getName(); - echo "\n\t\t\t\t\telse if ((i = id.indexOf('_".$attr."_')) >= 0) {\n"; - echo "\t\t\t\t\t\tpre = id.substring(0, i+1);\n"; - echo "\t\t\t\t\t\tsuf = id.substring(i + 1 + '$attr'.length, id.length);\n"; - $this->draw('FillJavascript', $attribute, 'id', 'value'); - if (isset($hash['autoFill'.$attr])) { - echo $hash['autoFill'.$attr]; + if ($attribute->isVisible() && ($attribute->hasProperty('onchange')) || $attribute->isRequired()) { + $attr = $attribute->getName(); + echo "\n\t\t\t\t\telse if ((i = id.indexOf('_".$attr."_')) >= 0) {\n"; + echo "\t\t\t\t\t\tpre = id.substring(0, i+1);\n"; + echo "\t\t\t\t\t\tsuf = id.substring(i + 1 + '$attr'.length, id.length);\n"; + $this->draw('FillJavascript', $attribute, 'id', 'value'); + if (isset($hash['autoFill'.$attr])) { + echo $hash['autoFill'.$attr]; + } + echo "\t\t\t}\n"; } - echo "\t\t\t}\n"; } echo '}}'; + + printf("\n\n",__METHOD__); } /********************************/ @@ -1258,6 +1273,7 @@ class EntryWriter1 extends EntryWriter { $i = -1; $templates = &$entry->getTemplates(); $nb_templates = count($templates); + if ($entry->hasDefaultTemplate()) $nb_templates++; foreach ($templates as $template_name => $template_attrs) { @@ -1309,7 +1325,7 @@ class EntryWriter1 extends EntryWriter { protected function drawTemplateEditingEntryShownAttributes($entry) { foreach ($this->shown_attributes as $attr) { // @todo if this->page == attr->page - $this->draw('', $attr); + $this->draw('',$attr,$entry); echo "\n"; } } @@ -1320,6 +1336,7 @@ class EntryWriter1 extends EntryWriter { } protected function drawTemplateEditingEntryJavascript($entry) { + printf("\n\n",__METHOD__); $this->draw('DefaultEditingEntry::Javascript', $entry); $templates = new Templates($this->index); @@ -1354,44 +1371,47 @@ class EntryWriter1 extends EntryWriter { // here comes template-specific implementation, generated by php if (false) {}'; foreach ($entry->getAttributes() as $attribute) { - $attr = $attribute->getName(); - echo "\n\t\t\telse if ((i = id.indexOf('_".$attr."_')) >= 0) {\n"; - echo "\t\t\t\tpre = id.substring(0, i+1);\n"; - echo "\t\t\t\tsuf = id.substring(i + 1 + '$attr'.length, id.length);\n"; - $this->draw('FillJavascript', $attribute, 'id', 'value'); - if (isset($hash['autoFill'.$attr])) { - echo $hash['autoFill'.$attr]; + if ($attribute->isVisible() && ($attribute->hasProperty('onchange')) || $attribute->isRequired()) { + $attr = $attribute->getName(); + echo "\n\t\t\telse if ((i = id.indexOf('_".$attr."_')) >= 0) {\n"; + echo "\t\t\t\tpre = id.substring(0, i+1);\n"; + echo "\t\t\t\tsuf = id.substring(i + 1 + '$attr'.length, id.length);\n"; + $this->draw('FillJavascript', $attribute, 'id', 'value'); + if (isset($hash['autoFill'.$attr])) { + echo $hash['autoFill'.$attr]; + } + echo "\t\t\t}\n"; } - echo "\t\t\t}\n"; } echo '}}'; + printf("\n\n",__METHOD__); } /**************************/ /* Paint an Attribute */ /**************************/ - protected function drawAttribute($attribute) { + protected function drawAttribute($attribute,$entry) { if ($attribute->isVisible()) $this->draw('Informations', $attribute); - $this->draw('Values', $attribute); + $this->draw('Values',$attribute,$entry); } protected function drawAttributeJavascript($attribute) { - echo ''; + echo '}'."\n"; + echo ''."\n"; } protected function drawAttributeFocusJavascript($attribute, $component) { @@ -1413,11 +1433,12 @@ class EntryWriter1 extends EntryWriter { echo 'var vals = getAttributeValues("new", "'.$attribute->getName().'"); if (vals.length <= 0) { '.$var_valid.' = false; - alertError("'._('This attribute is required')._(':').' '.$attribute->getFriendlyName().'", '.$silence.'); + alertError("'._('This attribute is required')._(':').' '.$attribute->getFriendlyName().'", '.$silence.'); }'; echo 'var comp = getAttributeComponents("new", "'.$attribute->getName().'"); for (var i = 0; i < comp.length; i++) { - comp[i].style.backgroundColor = '.$var_valid.' ? "white" : \'#F0F0FF\'; + comp[i].style.backgroundColor = '.$var_valid.' ? "white" : \'#FFFFA0\'; + comp[i].style.color = '.$var_valid.' ? "black" : \'#00005F\'; }'; } } @@ -1436,7 +1457,6 @@ class EntryWriter1 extends EntryWriter { protected function getTemplateCreatingEntryAttributeBlurJavascript($entry, $attribute, $component) { $j = 'fill('.$component.'.id, pla_getComponentValue('.$component.'));'; - //$j .= $this->get('DefaultCreatingEntry::AttributeBlurJavascript',$entry, $attribute, $component); return $j; } @@ -1446,7 +1466,6 @@ class EntryWriter1 extends EntryWriter { protected function getTemplateEditingEntryAttributeBlurJavascript($entry, $attribute, $component) { $j = 'fill('.$component.'.id, pla_getComponentValue('.$component.'));'; - //$j .= $this->get('DefaultEditingEntry::AttributeBlurJavascript',$entry, $attribute, $component); return $j; } @@ -1494,6 +1513,12 @@ class EntryWriter1 extends EntryWriter { $attr_note .= $rdn_note; } + $hint_note = $this->get('HintNote',$attribute); + if ($hint_note) { + if (trim($attr_note)) $attr_note .= ', '; + $attr_note .= $hint_note; + } + if ($attr_note) printf('%s', $attr_note); if ($attribute->isReadOnly() && $this->getLDAPServer()->isAttrReadOnly($attribute->getName())) { @@ -1503,14 +1528,14 @@ class EntryWriter1 extends EntryWriter { } } - protected function drawAttributeValues($attribute) { + protected function drawAttributeValues($attribute,$entry) { if ($attribute->isVisible()) $this->draw('StartValueLine', $attribute); # draws values $value_count = $attribute->getValueCount(); $i = 0; for (; $i < $value_count; $i++) { - $this->draw('Value', $attribute, $i); + $this->draw('Value',$attribute,$i,$entry); } if ($this->context == ENTRY_WRITER_CREATION_CONTEXT) { @@ -1519,7 +1544,7 @@ class EntryWriter1 extends EntryWriter { else $blankvalue_count -= $value_count; for ($j = 0; $j < $blankvalue_count; $j++) { - $this->draw('BlankValue', $attribute, $i + $j); + $this->draw('BlankValue',$attribute,$i+$j,$entry); } } @@ -1548,7 +1573,7 @@ class EntryWriter1 extends EntryWriter { switch ($i) { case IdAttributeAddValueMenuItem : if ($attribute->isVisible() && !$attribute->isReadOnly() - && !$attribute->isRdn() && $_SESSION[APPCONFIG]->isCommandAvailable('attribute_add_value')) { + && $_SESSION[APPCONFIG]->isCommandAvailable('attribute_add_value')) { if ($attribute->getMaxValueCount() < 0 || $attribute->getValueCount() < $attribute->getMaxValueCount()) { return $this->get('AddValueMenuItem', $attribute); } @@ -1595,7 +1620,7 @@ class EntryWriter1 extends EntryWriter { } } - protected function drawAttributeValue($attribute, $i) { + protected function drawAttributeValue($attribute,$i,$entry) { if (DEBUG_ENABLED) debug_log('Entered with (%s, %d)',1,__FILE__,__LINE__,__METHOD__,$attribute->getName(),$i); @@ -1610,7 +1635,7 @@ class EntryWriter1 extends EntryWriter { $this->draw('OldValue', $attribute, $i); - $this->draw('NewValue', $attribute, $i); + $this->draw('NewValue',$attribute,$i,$entry); if ($attribute->isVisible()) { echo ''; @@ -1626,7 +1651,10 @@ class EntryWriter1 extends EntryWriter { * Save the current value to detect changes */ protected function drawAttributeOldValue($attribute, $i) { - $val = $attribute->getValue($i); + if ($this->context == ENTRY_WRITER_EDITING_CONTEXT) + $val = $attribute->getValue($i); + else + $val = ''; if (!is_string($val)) $val = ''; if ($i < 0) $i = 0; @@ -1637,20 +1665,33 @@ class EntryWriter1 extends EntryWriter { /** * Display the current value */ - protected function drawAttributeNewValue($attribute, $i) { + protected function drawAttributeNewValue($attribute,$i,$entry) { if (!$attribute->isVisible()) { $this->draw('HiddenValue', $attribute, $i); + $this->draw('Javascript',$attribute); } elseif ($attribute->isReadOnly() || ($attribute->getEntry() && $attribute->getEntry()->getDn() && $attribute->isRdn())) { - $this->draw('ReadOnlyValue', $attribute, $i); + + /* If this is the RDN, we need to see if it has multiple values. If it does, and the multivalues are not + * not in the RDN, then we need to make them editable. */ + + if ($attribute->isRdn()) { + $rdn = split('\+',get_rdn($entry->getDN())); + if (in_array(sprintf('%s=%s',$attribute->getName(),$attribute->getValue($i)),$rdn)) + $this->draw('ReadOnlyValue', $attribute, $i); + else + $this->draw('ReadWriteValue', $attribute, $i); + + } else + $this->draw('ReadOnlyValue', $attribute, $i); } else { $this->draw('ReadWriteValue', $attribute, $i); - } + } } - protected function drawAttributeBlankValue($attribute, $i) { - $this->draw('Value', $attribute, $i); + protected function drawAttributeBlankValue($attribute,$i,$entry) { + $this->draw('Value',$attribute,$i,$entry); } protected function drawAttributeHiddenValue($attribute, $i) { @@ -1753,8 +1794,8 @@ class EntryWriter1 extends EntryWriter { $found = false; printf(''; } else { printf('', - $id, htmlspecialchars($attribute->getName()), $i, - $id, htmlspecialchars($attribute->getName()), $i, - htmlspecialchars($default)); + $id, htmlspecialchars($attribute->getName()), $i, + $id, htmlspecialchars($attribute->getName()), $i, + htmlspecialchars($default)); } if ($display) { @@ -1854,9 +1895,8 @@ class EntryWriter1 extends EntryWriter { printf('Go ',IMGDIR); } elseif ($this->getLDAPServer()->dnExists($val)) { - $href = sprintf('cmd.php?cmd=template_engine&server_id=%s&dn=%s',$this->index,$val); - printf('Go ',_('Go to'), - htmlspecialchars($val), htmlspecialchars($href),IMGDIR); + printf('Go ', + _('Go to'),htmlspecialchars($val),$this->index,rawurlencode($val),IMGDIR); } else { printf('Go ',_('DN not available'),htmlspecialchars($val),IMGDIR); @@ -1872,8 +1912,9 @@ class EntryWriter1 extends EntryWriter { protected function drawAttributeUrlValueIcon($attribute, $val) { $img = sprintf('%s',IMGDIR,_('URL')); + $url = split(' +',$val,2); if (strlen($val) <= 0) echo $img; - else printf(''.$img.'', htmlspecialchars($val)); + else printf('%s',htmlspecialchars($url[0]),$img); echo ' '; } @@ -1884,24 +1925,26 @@ class EntryWriter1 extends EntryWriter { if ($attribute->getEntry() && $attribute->getEntry()->getDn() // if not creating attribute && $config->isCommandAvailable('schema') ) { + $href = sprintf('cmd.php?cmd=schema&server_id=%s&view=attributes&viewvalue=%s', $this->index, real_attr_name($attribute->getName())); printf('%s', $attribute->getName(), htmlspecialchars($href), $attr_display); + } else { printf('%s', $attr_display); } } protected function getAttributeAliasNote($attribute) { - # is there a user-friendly translation available for this attribute? + # Is there a user-friendly translation available for this attribute? $friendly_name = $attribute->getFriendlyName(); - if ($friendly_name != $attribute->getName()) { - return sprintf('%s',_('Note'),$friendly_name,_('is an alias for'),$attribute->getName(),_('alias')); - } else { + if ($friendly_name != $attribute->getName()) + return sprintf('%s', + _('Note'),$friendly_name,_('is an alias for'),$attribute->getName(),_('alias')); + else return ''; - } } protected function getAttributeRequiredNote($attribute) { @@ -1949,6 +1992,15 @@ class EntryWriter1 extends EntryWriter { } } + protected function getAttributeHintNote($attribute) { + # Is there a hint for this attribute + if ($attribute->getHint()) { + return sprintf('%s ',htmlspecialchars($attribute->getHint()),_('hint')); + } else { + return ''; + } + } + protected function drawAttributeRequiredSymbol($attribute) { echo '*'; } @@ -2029,6 +2081,7 @@ class EntryWriter1 extends EntryWriter { } protected function drawBinaryAttributeJavascript($attribute) { + printf("\n\n",__METHOD__); $this->draw('Attribute::Javascript', $attribute); $dn = ''; @@ -2057,6 +2110,7 @@ class EntryWriter1 extends EntryWriter { } } '; + printf("\n\n",__METHOD__); } protected function drawBinaryAttributeBlurJavascript($attribute, $component) { @@ -2071,16 +2125,17 @@ class EntryWriter1 extends EntryWriter { if (!is_string($val)) $val = ''; printf(' ', + .' name="new_values[%s][%s]" value="%s" onFocus="focus_%s(this);" onBlur="blur_%s(this);" %s %s/> ', $attribute->getName(), $i, htmlspecialchars($attribute->getName()), $i, htmlspecialchars($val), $attribute->getName(), $attribute->getName(), ($attribute->getSize() > 0) ? 'size="'.$attribute->getSize().'"' : '', ($attribute->getMaxLength() > 0) ? 'maxlength="'.$attribute->getMaxLength().'"' : ''); draw_date_selector_link($attribute->getName().'_'.$i); - echo ''; + echo ''."\n"; } protected function drawDateAttributeJavascript($attribute) { + printf("\n\n",__METHOD__); $this->draw('Attribute::Javascript', $attribute); $entry['date'] = $_SESSION[APPCONFIG]->GetValue('appearance','date_attrs'); @@ -2100,6 +2155,7 @@ class EntryWriter1 extends EntryWriter { if (in_array_ignore_case($attribute->getName(),array_keys($entry['time'])) && ($entry['time'][$attribute->getName()])) printf('',$attribute->getName(),$i,'true'); } + printf("\n\n",__METHOD__); } /***************************/ @@ -2119,7 +2175,7 @@ class EntryWriter1 extends EntryWriter { $input_id = sprintf('new_values_%s_%s', htmlspecialchars($attribute->getName()), $i); printf(' ', + .' onFocus="focus_%s(this);" onBlur="blur_%s(this);" %s %s/> ', $input_name, $input_id, htmlspecialchars($val), $attribute->getName(), $attribute->getName(), ($attribute->getSize() > 0) ? 'size="'.$attribute->getSize().'"' : '', @@ -2135,6 +2191,7 @@ class EntryWriter1 extends EntryWriter { $this->draw('Helper', $attribute, $i); echo ''; } + echo "\n"; } protected function drawDnAttributeIcon($attribute, $val) { @@ -2261,7 +2318,7 @@ class EntryWriter1 extends EntryWriter { /* Paint a ObjectClassAttribute */ /********************************/ - protected function drawObjectClassAttributeNewValue($attribute, $i) { + protected function drawObjectClassAttributeNewValue($attribute,$i,$entry) { $val = $attribute->getValue($i); if (!is_string($val)) $val = ''; if ($i < 0) $i = 0; @@ -2282,7 +2339,7 @@ class EntryWriter1 extends EntryWriter { _('This is a structural ObjectClass and cannot be removed.'), _('structural')); } else { - $this->draw('Attribute::NewValue', $attribute, $i); + $this->draw('Attribute::NewValue',$attribute,$i,$entry); } } @@ -2300,15 +2357,12 @@ class EntryWriter1 extends EntryWriter { /*****************************/ protected function drawPasswordAttributeOldValue($attribute, $i) { - //if ($this->context == ENTRY_WRITER_CREATION_CONTEXT) { - $this->draw('Attribute::OldValue', $attribute, $i); - //} + $this->draw('Attribute::OldValue', $attribute, $i); } protected function drawPasswordAttributeHiddenValue($attribute, $i) { - if ($this->context == ENTRY_WRITER_CREATION_CONTEXT) { + if ($this->context == ENTRY_WRITER_CREATION_CONTEXT) $this->draw('Attribute::HiddenValue', $attribute, $i); - } } protected function drawPasswordAttributeReadOnlyValue($attribute, $i) { @@ -2321,9 +2375,10 @@ class EntryWriter1 extends EntryWriter { $obfuscate_password = obfuscate_password_display($enc_type); printf('
', - ($obfuscate_password ? 'password' : 'text'), + ($obfuscate_password ? 'password' : 'text'), htmlspecialchars($attribute->getName()), $i, htmlspecialchars($attribute->getName()), $i, htmlspecialchars($val), ($attribute->getSize() > 0) ? 'size="'.$attribute->getSize().'"' : ''); + if ($val != '') $this->draw('CheckLink', $attribute, 'new_values_'.htmlspecialchars($attribute->getName()).'_'.$i); } @@ -2335,16 +2390,15 @@ class EntryWriter1 extends EntryWriter { $enc_type = get_enc_type($val); # Set the default hashing type if the password is blank (must be newly created) - if ($val == '') { + if ($val == '') $enc_type = get_default_hash($this->index); - } echo '', - $id, htmlspecialchars($attribute->getName()), $value, - $attribute->getName(), $attribute->getName(), + .' onFocus="focus_%s(this);" onClick="blur_%s(this);" %s />', + $id, htmlspecialchars($attribute->getName()), $value, + $attribute->getName(), $attribute->getName(), isset($selected[$value]) ? 'checked' : '', " $description"); } + foreach ($vals as $val) { if (!isset($selected[$val])) { $id = 'new_values_'.htmlspecialchars($attribute->getName()).'_'.($j++); @@ -2516,35 +2583,49 @@ class EntryWriter1 extends EntryWriter { } echo '
'; $obfuscate_password = obfuscate_password_display($enc_type); $id = sprintf('new_values_%s_%s', htmlspecialchars($attribute->getName()), $i); printf('', + .' onFocus="focus_%s(this);" onBlur="blur_%s(this);" %s %s/>', ($obfuscate_password ? 'password' : 'text'), htmlspecialchars($attribute->getName()), $i, $id, htmlspecialchars($val), @@ -2353,19 +2407,20 @@ class EntryWriter1 extends EntryWriter { ($attribute->getMaxLength() > 0) ? 'maxlength="'.$attribute->getMaxLength().'"' : ''); echo ''; - if ($attribute->hasProperty('helper')) { + + if ($attribute->hasProperty('helper')) $this->draw('Helper', $attribute, $i); - } else { - echo enc_type_select_list($enc_type,'enc',$attribute,$i); - } + else + echo enc_type_select_list($enc_type,'enc',$attribute->getName(),$i); + echo '
'; if ($attribute->hasProperty('verify') && $attribute->getProperty('verify') && $obfuscate_password) { $id_v = sprintf('new_values_verify_%s_%s', htmlspecialchars($attribute->getName()), $i); printf('', - htmlspecialchars($attribute->getName()), $i, $id_v, - ($attribute->getSize() > 0) ? 'size="'.$attribute->getSize().'"' : '', - ($attribute->getMaxLength() > 0) ? 'maxlength="'.$attribute->getMaxLength().'"' : ''); + htmlspecialchars($attribute->getName()), $i, $id_v, + ($attribute->getSize() > 0) ? 'size="'.$attribute->getSize().'"' : '', + ($attribute->getMaxLength() > 0) ? 'maxlength="'.$attribute->getMaxLength().'"' : ''); echo ''; printf('(%s)', _('confirm')); echo '
'; @@ -2394,6 +2449,7 @@ class EntryWriter1 extends EntryWriter { } protected function drawPasswordAttributeJavascript($attribute) { + printf("\n\n",__METHOD__); $this->draw('Attribute::Javascript', $attribute); static $already_draw = false; @@ -2401,6 +2457,7 @@ class EntryWriter1 extends EntryWriter { else $already_draw = true; # add the javascript so we can call check password later. + printf("\n\n",__METHOD__); echo ' '; + printf("\n\n",__METHOD__); } /***********************************/ @@ -2416,12 +2474,14 @@ class EntryWriter1 extends EntryWriter { /***********************************/ protected function drawRandomPasswordAttributeJavascript($attribute) { + printf("\n\n",__METHOD__); $this->draw('PasswordAttribute::Javascript', $attribute); $pwd = password_generate(); $pwd = str_replace("\\", "\\\\", $pwd); $pwd = str_replace("'", "\\'", $pwd); + printf("\n\n",__METHOD__); echo ''; + printf("\n\n",__METHOD__); } /******************************/ /* Paint a SelectionAttribute */ /******************************/ - protected function drawSelectionAttributeValues($attribute) { + protected function drawSelectionAttributeValues($attribute,$entry) { if (!$attribute->isVisible() || !$attribute->isMultiple() || ($attribute->getValueCount() > 0)) { - $this->draw('Attribute::Values', $attribute); + $this->draw('Attribute::Values',$attribute,$entry); } else { $this->draw('StartValueLine', $attribute); $this->draw('Value', $attribute, 0); @@ -2463,7 +2524,7 @@ class EntryWriter1 extends EntryWriter { protected function drawSelectionAttributeReadWriteValue($attribute, $i) { if ($attribute->isMultiple()) { - // for multiple selection, we draw the component only one time + # For multiple selection, we draw the component only one time if ($i > 0) return; if (($attribute->getSize() > 0) && ($attribute->getSize() < $attribute->getOptionCount())) { @@ -2472,22 +2533,27 @@ class EntryWriter1 extends EntryWriter { htmlspecialchars($attribute->getName()), $attribute->getSize()); $vals = $attribute->getValues(); $j = 0; + foreach ($attribute->getSelection() as $value => $description) { if (in_array($value, $vals)) $selected[$value] = true; $id = 'new_values_'.htmlspecialchars($attribute->getName()).'_'.($j++); printf('', - $id, $value, htmlspecialchars($attribute->getName()), htmlspecialchars($attribute->getName()), - isset($selected[$value]) ? 'selected' : '', $description); + $id, $value, htmlspecialchars($attribute->getName()), htmlspecialchars($attribute->getName()), + isset($selected[$value]) ? 'selected' : '', $description); + echo "\n"; } + foreach ($vals as $val) { if (!isset($selected[$val])) { $id = 'new_values_'.htmlspecialchars($attribute->getName()).'_'.($j++); printf('', $id, $val, htmlspecialchars($attribute->getName()), - htmlspecialchars($attribute->getName()), $val); + .'%s', $id, $val, htmlspecialchars($attribute->getName()), + htmlspecialchars($attribute->getName()), $val); } + echo "\n"; } echo ''; + } else { $selected = array(); $vals = $attribute->getValues(); @@ -2498,12 +2564,13 @@ class EntryWriter1 extends EntryWriter { if (in_array($value, $vals)) $selected[$value] = true; $id = 'new_values_'.htmlspecialchars($attribute->getName()).'_'.($j++); printf('
%s
%s
'; } + } else { $val = $attribute->getValue($i); if (!is_string($val)) $val = ''; if ($i < 0) $i = 0; - if ($attribute->hasProperty('helper')) { + if ($attribute->hasProperty('helper')) echo '',$this->getDepth()+3); printf('',_('Error number'),$errnum,$verbose_error['title']); + $body .= sprintf('',_('Description'),$verbose_error['desc']); } else { - $body = $msg; + $body .= sprintf('',_('Error number'),$errnum); + $body .= sprintf('',_('Description'),_('no description available')); } - system_message(array('title'=>$title ? $title : 'Error','body'=>$body,'type'=>'error'),$fatal ? 'index.php' : null); + $body .= '
'; - } $found = false; $empty_value = false; $id = 'new_values_'.htmlspecialchars($attribute->getName()).'_'.$i; + + # If we are a required attribute, and the selection is blank, then the user cannot submit this form. + if ($attribute->isRequired() && ! count($attribute->getSelection())) + system_message(array( + 'title'=>_('Template Value Error'), + 'body'=>sprintf('This template uses a selection list for attribute [%s], however the selection list is empty.
You may need to create some dependancy entries in your LDAP server so that this attribute renders with values. Alternatively, you may be able to define the appropriate selection values in the template file.',$attribute->getName()), + 'type'=>'warn')); + + printf(''; @@ -2563,17 +2644,18 @@ class EntryWriter1 extends EntryWriter { return $this->get('Attribute::MenuItem', $attribute, $i); } return ''; + case IdAttributeModifyMemberMenuItem : return ''; + default : return $this->get('Attribute::MenuItem', $attribute, $i); } } protected function drawSelectionAttributeIcon($attribute, $val) { - if (!$attribute->isMultiple() || $attribute->isReadOnly()) { + if (!$attribute->isMultiple() || $attribute->isReadOnly()) $this->draw('Attribute::Icon', $attribute, $val); - } } /***************************/ @@ -2626,7 +2708,6 @@ class EntryWriter1 extends EntryWriter { protected function drawShadowAttributeShadowDate($attribute, $shadow_date) { $config = $_SESSION[APPCONFIG]; - //$shadow_format_attrs = array_merge($shadow_before_today_attrs,$shadow_after_today_attrs); $shadow_before_today_attrs = arrayLower($attribute->shadow_before_today_attrs); $shadow_after_today_attrs = arrayLower($attribute->shadow_after_today_attrs); $today = date('U'); diff --git a/lib/EntryWriter2.php b/lib/EntryWriter2.php index d647f3a..1185bd1 100644 --- a/lib/EntryWriter2.php +++ b/lib/EntryWriter2.php @@ -1,5 +1,5 @@ getHint() /*&& $_SESSION[APPCONFIG]->GetValue('appearance', 'show_hints')*/) { - echo 'Hint '.$attribute->getHint().''; - } + if ($attribute->getHint()) + printf('Hint %s',IMGDIR,$attribute->getHint()); + parent::drawAttributeMenu($attribute); } diff --git a/lib/HTMLTree.php b/lib/HTMLTree.php index a872cea..779225a 100644 --- a/lib/HTMLTree.php +++ b/lib/HTMLTree.php @@ -1,5 +1,5 @@
 
 
', - $_SESSION['plaConfig']->GetValue('appearance','tree_width') ? sprintf('width: %spx; ',$_SESSION['plaConfig']->GetValue('appearance','tree_width')) : '', - $_SESSION['plaConfig']->GetValue('appearance','tree_height') ? sprintf('height: %spx; ',$_SESSION['plaConfig']->GetValue('appearance','tree_height')) : ''); + $_SESSION[APPCONFIG]->GetValue('appearance','tree_width') ? sprintf('width: %spx; ',$_SESSION[APPCONFIG]->GetValue('appearance','tree_width')) : '', + $_SESSION[APPCONFIG]->GetValue('appearance','tree_height') ? sprintf('height: %spx; ',$_SESSION[APPCONFIG]->GetValue('appearance','tree_height')) : ''); foreach ($ldapserver->getBaseDN() as $base_dn) { # Did we get a base_dn for this server somehow? @@ -55,7 +55,7 @@ class HTMLTree extends Tree { if (! $ldapserver->dnExists($base_dn)) { $javascript_id++; - printf('',$this->getDepth()+3-3,pretty_print_dn($base_dn)); + printf('',IMGDIR,$this->getDepth()+3-3,pretty_print_dn($base_dn)); /* Move this form and add it to the end of the html - otherwise the javascript * doesnt work when isMassDeleteEnabled returning true. @@ -103,9 +103,10 @@ class HTMLTree extends Tree { } } else { // end if $ldapserver->haveAuthInfo() /* We don't have enough information to login to this server - * Draw the "login..." link - */ - $this->draw_login_link(); + * Draw the "login..." link */ + + if ($ldapserver->auth_type != 'http') + $this->draw_login_link(); } $this->draw_mass_deletion_submit_button(); @@ -153,14 +154,14 @@ class HTMLTree extends Tree { $ldapserver = $this->getLdapServer(); echo ''; - printf('',_('Server')); + printf('',IMGDIR,_('Server')); printf(''; } @@ -209,7 +210,7 @@ class HTMLTree extends Tree { if ($_SESSION[APPCONFIG]->isCommandAvailable('export')) return $this->get_export_menu_item(); else return ''; case 6 : - if ($ldapserver->auth_type != 'config') return $this->get_logout_menu_item(); + if (! in_array($ldapserver->auth_type,array('config','http'))) return $this->get_logout_menu_item(); else return ''; default : return false; @@ -220,56 +221,56 @@ class HTMLTree extends Tree { $ldapserver = $this->getLdapServer(); $href = sprintf('cmd.php?cmd=schema&server_id=%s',$ldapserver->server_id); - return sprintf('%s
%s
', - _('View schema for'),$ldapserver->name,htmlspecialchars($href),'images/schema.png',_('schema'),_('schema')); + return sprintf('%s
%s
', + _('View schema for'),$ldapserver->name,htmlspecialchars($href),IMGDIR,'schema.png',_('schema'),_('schema')); } protected function get_search_menu_item() { $ldapserver = $this->getLdapServer(); $href = sprintf('cmd.php?cmd=search&server_id=%s&form=undefined',$ldapserver->server_id); - return sprintf('%s
%s
', - _('search'),$ldapserver->name,htmlspecialchars($href),'images/search.png',_('search'),_('search')); + return sprintf('%s
%s
', + _('search'),$ldapserver->name,htmlspecialchars($href),IMGDIR,'search.png',_('search'),_('search')); } protected function get_refresh_menu_item() { $ldapserver = $this->getLdapServer(); $href = sprintf('cmd.php?cmd=refresh&server_id=%s',$ldapserver->server_id); - return sprintf('%s
%s
', - _('Refresh all expanded containers for'),$ldapserver->name,htmlspecialchars($href),'images/refresh-big.png',_('refresh'),_('refresh')); + return sprintf('%s
%s
', + _('Refresh all expanded containers for'),$ldapserver->name,htmlspecialchars($href),IMGDIR,'refresh-big.png',_('refresh'),_('refresh')); } protected function get_info_menu_item() { $ldapserver = $this->getLdapServer(); $href = sprintf('cmd.php?cmd=server_info&server_id=%s',$ldapserver->server_id); - return sprintf('%s
%s
', - _('View server-supplied information'),htmlspecialchars($href),'images/info.png',_('info'),_('info')); + return sprintf('%s
%s
', + _('View server-supplied information'),htmlspecialchars($href),IMGDIR,'info.png',_('info'),_('info')); } protected function get_import_menu_item() { $ldapserver = $this->getLdapServer(); $href = sprintf('cmd.php?cmd=ldif_import_form&server_id=%s',$ldapserver->server_id); - return sprintf('%s
%s
', - _('Import entries from an LDIF file'),htmlspecialchars($href),'images/import.png',_('import'),_('import')); + return sprintf('%s
%s
', + _('Import entries from an LDIF file'),htmlspecialchars($href),IMGDIR,'import.png',_('import'),_('import')); } protected function get_export_menu_item() { $ldapserver = $this->getLdapServer(); $href = sprintf('cmd.php?cmd=export_form&server_id=%s',$ldapserver->server_id); - return sprintf('%s
%s
', - _('Export entries'),htmlspecialchars($href),'images/export.png',_('export'),_('export')); + return sprintf('%s
%s
', + _('Export entries'),htmlspecialchars($href),IMGDIR,'export.png',_('export'),_('export')); } protected function get_logout_menu_item() { $ldapserver = $this->getLdapServer(); $href = sprintf('cmd.php?cmd=logout&server_id=%s',$ldapserver->server_id); - return sprintf('%s
%s
', - _('Logout of this server'),htmlspecialchars($href),'images/logout.png',_('logout'),_('logout')); + return sprintf('%s
%s
', + _('Logout of this server'),htmlspecialchars($href),IMGDIR,'logout.png',_('logout'),_('logout')); } protected function draw_logged_in_dn() { @@ -338,7 +339,7 @@ class HTMLTree extends Tree { $href['expand'] = sprintf('cmd.php?cmd=expand&server_id=%s&dn=%s',$ldapserver->server_id,$encoded_dn); $href['collapse'] = sprintf('cmd.php?cmd=collapse&server_id=%s&dn=%s',$ldapserver->server_id,$encoded_dn); $href['edit'] = sprintf('cmd.php?cmd=template_engine&server_id=%s&dn=%s',$ldapserver->server_id,$encoded_dn); - $img_src = sprintf('images/%s',$dnEntry->getIcon($ldapserver)); + $img_src = sprintf('%s/%s',IMGDIR,$dnEntry->getIcon($ldapserver)); $rdn = get_rdn($dn); echo ''; @@ -362,15 +363,15 @@ class HTMLTree extends Tree { # Is this node expanded? (deciding whether to draw "+" or "-") if ($dnEntry->isOpened()) { if (!$child_count && !$ldapserver->isShowCreateEnabled()) { - echo ''; + printf('',IMGDIR); } else { - printf('',$href['collapse']); + printf('',$href['collapse'],IMGDIR); } } else { if (($child_count !== false) && (!$child_count) && (!$ldapserver->isShowCreateEnabled())) { - echo ''; + printf('',IMGDIR); } else { - printf('',$href['expand']); + printf('',$href['expand'],IMGDIR); } } $colspan--; @@ -458,7 +459,7 @@ class HTMLTree extends Tree { echo ''; echo ''; - printf('',$href,_('new')); + printf('',$href,IMGDIR,_('new')); printf('', $this->getDepth()+3-$level-1-3,$href,_('Create a new entry in'),$rdn,_('Create new entry here')); echo ''; @@ -473,7 +474,7 @@ class HTMLTree extends Tree { sprintf('cmd.php?cmd=%s&server_id=%s',get_custom_file($ldapserver->server_id,'login_form',''),$ldapserver->server_id)); echo ''; - printf('',$href,_('login')); + printf('',$href,IMGDIR,_('login')); printf('',$this->getDepth()+3-2,$href,_('Login').'...'); echo ''; @@ -489,7 +490,7 @@ class HTMLTree extends Tree { protected function draw_logout_link() { $ldapserver = $this->getLdapServer(); - if ($ldapserver->auth_type != 'config') { + if (! in_array($ldapserver->auth_type,array('config','http'))) { printf('', $this->getDepth()+3-1,get_custom_file($ldapserver->server_id,'logout',''),$ldapserver->server_id,_('logout')); } diff --git a/lib/PLMTree.php b/lib/PLMTree.php index bdc253f..6261a43 100644 --- a/lib/PLMTree.php +++ b/lib/PLMTree.php @@ -1,5 +1,5 @@ setDirroot(JSDIR.'phplayersmenu/'); - $tm->setIcondir(HTDOCDIR.'/images/'); - $tm->setIconwww('images/'); + $tm->setIcondir(IMGDIR); + $tm->setIconwww(IMGDIR); $tm->setImgwww(JSDIR.'phplayersmenu/menuimages/'); } diff --git a/lib/TemplateCreatingEntry.php b/lib/TemplateCreatingEntry.php index 4d1ed75..bbe461f 100644 --- a/lib/TemplateCreatingEntry.php +++ b/lib/TemplateCreatingEntry.php @@ -1,5 +1,5 @@ default_template; + if ($_SESSION[APPCONFIG]->GetValue('appearance','disable_default_template')) + return false; + else + return $this->default_template; } public function getAttributes() { diff --git a/lib/TemplateEditingEntry.php b/lib/TemplateEditingEntry.php index da6ad0d..8fb8a9a 100644 --- a/lib/TemplateEditingEntry.php +++ b/lib/TemplateEditingEntry.php @@ -1,5 +1,5 @@ templates = array(); $this->valid = false; - $this->default_template = false; + $this->default_template = true; $this->selected_template = ''; } @@ -81,7 +81,10 @@ class TemplateEditingEntry extends DefaultEditingEntry { } public function hasDefaultTemplate() { - return $this->default_template; + if ($_SESSION[APPCONFIG]->GetValue('appearance','disable_default_template')) + return false; + else + return $this->default_template; } public function getAttributes() { @@ -105,12 +108,22 @@ class TemplateEditingEntry extends DefaultEditingEntry { $int_attrs_vals = $ldapserver->getDNSysAttrs($this->getDn()); if (! $int_attrs_vals) $attrs_vals = array(); - elseif (! is_array($int_attrs_vals)) $int_attrs_vals = array($attrs_vals); + elseif (! is_array($int_attrs_vals)) $int_attrs_vals = array($int_attrs_vals); + + $custom_int_attrs_vals = $ldapserver->getCustomDNSysAttrs($this->getDn()); + if (! $custom_int_attrs_vals) $attrs_vals = array(); + elseif (! is_array($custom_int_attrs_vals)) $custom_int_attrs_vals = array($custom_int_attrs_vals); $attrs_vals = $ldapserver->getDNAttrs($this->getDn(),false,$_SESSION[APPCONFIG]->GetValue('deref','view')); if (! $attrs_vals) $attrs_vals = array(); elseif (! is_array($attrs_vals)) $attrs_vals = array($attrs_vals); + $custom_attrs_vals = $ldapserver->getCustomDNAttrs($this->getDn(),false,$_SESSION[APPCONFIG]->GetValue('deref','view')); + if (! $custom_attrs_vals) $attrs_vals = array(); + elseif (! is_array($custom_attrs_vals)) $custom_attrs_vals = array($custom_attrs_vals); + + $int_attrs_vals = array_merge($int_attrs_vals,$custom_int_attrs_vals); + $attrs_vals = array_merge($attrs_vals,$custom_attrs_vals); $attrs_vals = array_merge($attrs_vals,$int_attrs_vals); $selected_tmpl = isset($this->templates[$this->selected_template]) diff --git a/lib/blowfish.php b/lib/blowfish.php index 90f423d..8c48aec 100644 --- a/lib/blowfish.php +++ b/lib/blowfish.php @@ -1,5 +1,5 @@ - * @version $Revision: 1.4 $ + * @version $Revision: 1.4.2.1 $ * @since Horde 2.2 * @package horde.cipher */ @@ -440,9 +440,9 @@ class Horde_Cipher_blowfish { $unpack = unpack('N*', $block); if (! is_array($unpack)) - pla_error( + error( sprintf('BLOWFISH: decryptBock()
We expected unpack to produce an array, but instead it produced [%s]. This function was entered with (%s,%s). If you think that this is a bug, then please tell the PLA developers how you got here. You are using PLA [%s,%s]', - serialize($unpack),rawurlencode($block),$key,pla_version(),phpversion())); + serialize($unpack),rawurlencode($block),$key,pla_version(),phpversion()),'error','index.php'); list($L, $R) = array_values($unpack); diff --git a/lib/common.php b/lib/common.php index 9eb21e5..6ad22a7 100644 --- a/lib/common.php +++ b/lib/common.php @@ -1,5 +1,5 @@ CheckCustom(); } +# Check for safe mode. +if (ini_get('safe_mode') && ! get_request('cmd','GET')) + system_message(array( + 'title'=>_('PHP Safe Mode'), + 'body'=>_('You have PHP Safe Mode enabled. PLA may work unexpectedly in Safe Mode.'), + 'type'=>'info')); + # Set our timezone, if it is specified in config.php if ($_SESSION[APPCONFIG]->GetValue('appearance','timezone')) date_default_timezone_set($_SESSION[APPCONFIG]->GetValue('appearance','timezone')); @@ -163,11 +176,11 @@ if (DEBUG_ENABLED) # Set our PHP timelimit. if ($_SESSION[APPCONFIG]->GetValue('session','timelimit')) - set_time_limit($_SESSION[APPCONFIG]->GetValue('session','timelimit')); + @set_time_limit($_SESSION[APPCONFIG]->GetValue('session','timelimit')); # If debug mode is set, increase the time_limit, since we probably need it. if (DEBUG_ENABLED && $_SESSION[APPCONFIG]->GetValue('session','timelimit')) - set_time_limit($_SESSION[APPCONFIG]->GetValue('session','timelimit') * 5); + @set_time_limit($_SESSION[APPCONFIG]->GetValue('session','timelimit') * 5); /** * Language configuration. Auto or specified? @@ -204,7 +217,7 @@ if ($language == 'auto') { (file_exists($language_dir) && is_readable($language_dir))) { # Set language - putenv('LANG='.$HTTP_LANG); # e.g. LANG=de_DE + @putenv('LANG='.$HTTP_LANG); # e.g. LANG=de_DE $HTTP_LANG .= '.UTF-8'; setlocale(LC_ALL,$HTTP_LANG); # set LC_ALL to de_DE bindtextdomain('messages',LANGDIR); @@ -225,7 +238,7 @@ if ($language == 'auto') { $language = 'en_GB'; # Set language - putenv('LANG='.$language); # e.g. LANG=de_DE + @putenv('LANG='.$language); # e.g. LANG=de_DE $language .= '.UTF-8'; setlocale(LC_ALL,$language); # set LC_ALL to de_DE bindtextdomain('messages',LANGDIR); @@ -261,16 +274,23 @@ if (isset($_REQUEST['server_id'])) { * Look/evaluate our timeout */ if (isset($ldapserver) && is_object($ldapserver) && method_exists($ldapserver,'haveAuthInfo')) { - if ($ldapserver->haveAuthInfo() && isset($ldapserver->auth_type) && $ldapserver->auth_type != 'config') { + if ($ldapserver->haveAuthInfo() && isset($ldapserver->auth_type) && ! in_array($ldapserver->auth_type,array('config','http'))) { /** * If time out value has been reached: * - log out user * - put $server_id in array of recently timed out servers */ if (function_exists('session_timed_out') && session_timed_out($ldapserver)) { - $app['url_timeout'] = sprintf('cmd.php?cmd=timeout&server_id=%s',$_REQUEST['server_id']); - printf('', - htmlspecialchars($app['url_timeout'])); + + # If $session_timeout not defined, use ( session_cache_expire() - 1 ) + $session_timeout = $ldapserver->session_timeout ? $ldapserver->session_timeout : session_cache_expire()-1; + + system_message(array( + 'title'=>_('Session Timed Out'), + 'body'=>sprintf('%s %s %s', + _('Your Session timed out after'),$session_timeout, + _('min. of inactivity. You have been automatically logged out.')), + 'type'=>'info'),'index.php'); die(); } } diff --git a/lib/config_default.php b/lib/config_default.php index 00bef1a..7030b88 100644 --- a/lib/config_default.php +++ b/lib/config_default.php @@ -1,5 +1,5 @@ 'Array of attributes that should show a the time when showing the jscalendar', 'default'=>array('')); + $this->default->appearance['disable_default_template'] = array( + 'desc'=>'Disabled the Default Template', + 'default'=>false); + $this->default->appearance['hide_debug_info'] = array( 'desc'=>'Hide the features that may provide sensitive debugging information to the browser', 'default'=>true); @@ -508,10 +512,10 @@ class Config { if (! isset($config[$key])) error(sprintf('A call was made in [%s] to GetValue requesting [%s] that isnt predefined.', - basename($_SERVER['PHP_SELF']),$key),'error',true); + basename($_SERVER['PHP_SELF']),$key),'error',null,true); if (! isset($config[$key][$index])) - error(sprintf('Requesting an index [%s] in key [%s] that isnt predefined.',$index,$key),'error',true); + error(sprintf('Requesting an index [%s] in key [%s] that isnt predefined.',$index,$key),'error',null,true); return isset($config[$key][$index]['value']) ? $config[$key][$index]['value'] : $config[$key][$index]['default']; } @@ -526,23 +530,23 @@ class Config { if (isset($this->default->$masterkey)) { if (! is_array($masterdetails)) - error(sprintf('Error in configuration file, [%s] should be an ARRAY.',$masterdetails),'error',true); + error(sprintf('Error in configuration file, [%s] should be an ARRAY.',$masterdetails),'error',null,true); foreach ($masterdetails as $key => $value) { # Test that the key is correct. if (! in_array($key,array_keys($this->default->$masterkey))) - error(sprintf('Error in configuration file, [%s] has not been defined as a configurable variable.',$key),'error',true); + error(sprintf('Error in configuration file, [%s] has not been defined as a configurable variable.',$key),'error',null,true); # Test if its should be an array or not. if (is_array($this->default->{$masterkey}[$key]['default']) && ! is_array($value)) - error(sprintf('Error in configuration file, %s[\'%s\'] SHOULD be an array of values.',$masterkey,$key),'error',true); + error(sprintf('Error in configuration file, %s[\'%s\'] SHOULD be an array of values.',$masterkey,$key),'error',null,true); if (! is_array($this->default->{$masterkey}[$key]['default']) && is_array($value)) - error(sprintf('Error in configuration file, %s[\'%s\'] should NOT be an array of values.',$masterkey,$key),'error',true); + error(sprintf('Error in configuration file, %s[\'%s\'] should NOT be an array of values.',$masterkey,$key),'error',null,true); } } else { - error(sprintf('Error in configuration file, [%s] has not been defined as a MASTER configurable variable.',$masterkey),'error',true); + error(sprintf('Error in configuration file, [%s] has not been defined as a MASTER configurable variable.',$masterkey),'error',null,true); } } } diff --git a/lib/emuhash_functions.php b/lib/emuhash_functions.php index b6727b2..335488a 100644 --- a/lib/emuhash_functions.php +++ b/lib/emuhash_functions.php @@ -1,5 +1,5 @@ results && $this->ldap_info->ldapserver->errno()) - pla_error(_('Encountered an error while performing search.'),$this->ldap_info->ldapserver->error(), - $this->ldap_info->ldapserver->errno()); + system_message(array( + 'title'=>_('Encountered an error while performing search.'), + 'body'=>ldap_error_msg($this->ldap_info->ldapserver->error(),$this->ldap_info->ldapserver->errno()), + 'type'=>'error')); usort($this->results,'pla_compare_dns'); $this->num_entries = count($this->results); diff --git a/lib/functions.php b/lib/functions.php index c14badd..b4b8443 100644 --- a/lib/functions.php +++ b/lib/functions.php @@ -1,5 +1,5 @@ 'error')); } +/** + * If gettext is not installed, we will emulate it here. + */ +if (! function_exists('_')) { + function _($msg) { + return $msg; + } +} + /** * Generic Utility Functions */ @@ -151,7 +158,7 @@ function pla_error_handler($errno,$errstr,$file,$lineno) { } # If this is a more serious error, call the error call. - error(sprintf('%s: %s',$errtype,$errstr),'error',true,true); + error(sprintf('%s: %s',$errtype,$errstr),'error',null,true,true); } /** @@ -161,6 +168,11 @@ function pla_error_handler($errno,$errstr,$file,$lineno) { * @return string The current version as read from the VERSION file. */ function pla_version() { + static $return = null; + + if ($return) + return $return; + $version_file = realpath(LIBDIR.'../VERSION'); if (! file_exists($version_file)) $return = 'UNKNOWN'; @@ -229,27 +241,6 @@ function check_config($config_file) { REQUIRED_PHP_VERSION,phpversion()), 'type'=>'error')); - # Make sure this PHP install has all our required extensions - if (! extension_loaded('ldap')) - system_message(array( - 'title'=>_('Missing required extension'), - 'body'=>'Your install of PHP appears to be missing LDAP support.

Please install LDAP support before using phpLDAPadmin.
(Dont forget to restart your web server afterwards)', - 'type'=>'error')); - - # Make sure that we have php-xml loaded. - if (! function_exists('xml_parser_create')) - system_message(array( - 'title'=>_('Missing required extension'), - 'body'=>'Your install of PHP appears to be missing XML support.

Please install XML support before using phpLDAPadmin.
(Dont forget to restart your web server afterwards)', - 'type'=>'error')); - - # Make sure their session save path is writable, if they are using a file system session module, that is. - if (! strcasecmp('Files',session_module_name() && ! is_writable(realpath(session_save_path())))) - system_message(array( - 'title'=>_('PHP session configuration incorrect'), - 'body'=>sprintf('Your PHP session configuration is incorrect. Please check the value of session.save_path in your php.ini to ensure that the directory specified there exists and is writable. The current setting of "%s" is un-writable by the web server.',session_save_path()), - 'type'=>'error')); - $config = new Config; ob_start(); @@ -353,19 +344,19 @@ function check_config($config_file) { */ function cmd_control_pane() { return array( - 'home'=>array('link'=>sprintf('%s
%s
',_('Home'),_('Home'),_('Home'))), - 'purge'=>array('link'=>sprintf('%s
%s
', - _('Purge caches'),_('Purge all cached data in phpLDAPadmin, including server schemas.'),_('Purge caches'))), - 'external_links:feature'=>array('link'=>sprintf('%s
%s
', - get_href('add_rfe'),_('Request feature'),_('light'),_('Request feature'))), - 'external_links:bug'=>array('link'=>sprintf('%s
%s
', - get_href('add_bug'),_('Report a bug'),_('bug'),_('Report a bug'))), - 'external_links:donation'=>array('link'=>sprintf('%s
%s
', - get_href('donate'),_('Donate'),_('Donate'),_('Donate'))), - 'appearance:hide_debug_info'=>array('link'=>sprintf('%s
%s
', - _('Show Cache'),_('Show Cache'),_('Show Cache'))), - 'external_links:help'=>array('link'=>sprintf('%s
%s
', - get_href('documentation'),_('Help'),_('Help'),_('Help'))) + 'home'=>array('link'=>sprintf('%s
%s
',_('Home'),IMGDIR,_('Home'),_('Home'))), + 'purge'=>array('link'=>sprintf('%s
%s
', + _('Purge caches'),IMGDIR,_('Purge all cached data in phpLDAPadmin, including server schemas.'),_('Purge caches'))), + 'external_links:feature'=>array('link'=>sprintf('%s
%s
', + get_href('add_rfe'),_('Request feature'),IMGDIR,_('light'),_('Request feature'))), + 'external_links:bug'=>array('link'=>sprintf('%s
%s
', + get_href('add_bug'),_('Report a bug'),IMGDIR,_('bug'),_('Report a bug'))), + 'external_links:donation'=>array('link'=>sprintf('%s
%s
', + get_href('donate'),_('Donate'),IMGDIR,_('Donate'),_('Donate'))), + 'appearance:hide_debug_info'=>array('link'=>sprintf('%s
%s
', + _('Show Cache'),IMGDIR,_('Show Cache'),_('Show Cache'))), + 'external_links:help'=>array('link'=>sprintf('%s
%s
', + get_href('documentation'),_('Help'),IMGDIR,_('Help'),_('Help'))) ); } @@ -389,6 +380,14 @@ function debug_dump($variable,$die=false,$onlydebugaddr=false) { die(); } +/** + * This function generates a backtrace + * @param boolean Whether to stop execution or not. + */ +function debug_dump_backtrace($msg='Calling BackTrace',$die=false) { + error($msg,'note',null,$die,true); +} + /** * Debug Logging to Syslog * @@ -498,7 +497,7 @@ function debug_log($msg,$level=0) { /** * Display an error message in the system message panel of the page. */ -function error($msg,$type='note',$fatal=false,$backtrace=false) { +function error($msg,$type='note',$redirect=null,$fatal=false,$backtrace=false) { global $www; global $counter; @@ -510,7 +509,10 @@ function error($msg,$type='note',$fatal=false,$backtrace=false) { if (! isset($www['page'])) $www['page'] = new page(); - $www['page']->setsysmsg(array('title'=>_('Error'),'body'=>$msg,'type'=>$type)); + if ($fatal) + $www['page']->setsysmsg(array('title'=>_('Error'),'body'=>$msg,'type'=>$type)); + else + system_message(array('title'=>_('Error'),'body'=>$msg,'type'=>$type),$redirect); # Spin loop detection if ($counter++ > 20) { @@ -525,24 +527,33 @@ function error($msg,$type='note',$fatal=false,$backtrace=false) { $body = '
%s
%s
%s%s',$this->getDepth()+3-1); printf('%s',htmlspecialchars($ldapserver->name)); - if ($ldapserver->haveAuthInfo() && $ldapserver->auth_type != 'config') { + if ($ldapserver->haveAuthInfo() && ! in_array($ldapserver->auth_type,array('config','http'))) { $m = sprintf(_('Inactivity will log you off at %s'), strftime('%H:%M',time() + ($ldapserver->session_timeout*60))); - printf(' %s',$m,$m); + printf(' %s',IMGDIR,$m,$m); } echo '
------++%s%s
%s%s%s
%s
'; $body .= "\n"; - foreach (debug_backtrace() as $error => $line) { - $body .= sprintf('', - _('File'),isset($line['file']) ? $line['file'] : '',isset($line['line']) ? $line['line'] : ''); + foreach (debug_backtrace() as $error => $line) { + $_SESSION['backtrace'][$error]['file'] = $line['file']; + $_SESSION['backtrace'][$error]['line'] = $line['line']; + $body .= sprintf('', + _('File'),isset($line['file']) ? $line['file'] : $last['file'],isset($line['line']) ? $line['line'] : ''); + + $_SESSION['backtrace'][$error]['function'] = $line['function']; $body .= sprintf(''; $body .= "\n"; + + if ($line['file']) + $last['file'] = $line['file']; } + $body .= '
%s%s (%s)
%s%s (%s)
 %s%s', _('Function'),$line['function']); - if (isset($line['args'])) + if (isset($line['args'])) { + $display = strlen(serialize($line['args'])) < 50 ? serialize($line['args']) : substr(serialize($line['args']),0,50).'...'; + $_SESSION['backtrace'][$error]['args'] = $line['args']; if (file_exists(LIBDIR.'../tools/unserialize.php')) - $body .= sprintf(' (%s)', - '/tools/unserialize.php', - htmlspecialchars(serialize($line['args'])), - htmlspecialchars(serialize($line['args']))); + $body .= sprintf(' (%s)', + '../tools/unserialize.php',$error,htmlspecialchars($display)); else - $body .= sprintf(' (%s)',htmlspecialchars(serialize($line['args']))); + $body .= sprintf(' (%s)',htmlspecialchars($display)); + } $body .= '
'; $body .= "\n"; $backtraceblock->SetBody($body); @@ -609,7 +620,16 @@ function system_message($msg,$redirect=null) { $_SESSION['sysmsg'][] = $msg; + if (get_request('redirect','GET')) + debug_dump_backtrace('Redirect Loop Detected',true); + if ($redirect) { + if (preg_match('/\?/',$redirect)) + $redirect .= '&'; + else + $redirect .= '?'; + $redirect .= 'redirect=true'; + header("Location: $redirect"); die(); } @@ -1149,17 +1169,17 @@ function get_next_number(&$ldapserver,$startbase='',$type='uid',$increment=false $base_dn = $_SESSION[APPCONFIG]->ldapservers->GetValue($ldapserver->server_id,'auto_number','search_base'); if (is_null($base_dn)) - pla_error(sprintf(_('You specified the "auto_uid_number_mechanism" as "search" in your + error(sprintf(_('You specified the "auto_uid_number_mechanism" as "search" in your configuration for server %s, but you did not specify the - "auto_uid_number_search_base". Please specify it before proceeding.'),$ldapserver->name)); + "auto_uid_number_search_base". Please specify it before proceeding.'),$ldapserver->name),'error','index.php'); } else { $base_dn = $startbase; } if (! $ldapserver->dnExists($base_dn)) - pla_error(sprintf(_('Your phpLDAPadmin configuration specifies an invalid auto_uid_search_base for server %s'), - $ldapserver->name)); + error(sprintf(_('Your phpLDAPadmin configuration specifies an invalid auto_uid_search_base for server %s'), + $ldapserver->name),'error','index.php'); $filter = '(|(uidNumber=*)(gidNumber=*))'; $results = array(); @@ -1170,12 +1190,13 @@ function get_next_number(&$ldapserver,$startbase='',$type='uid',$increment=false $_SESSION[APPCONFIG]->ldapservers->GetValue($ldapserver->server_id,'auto_number','pass')); if (! $con) - pla_error(sprintf(_('Unable to bind to %s with your with auto_uid credentials. Please check your configuration file.'),$ldapserver->name)); + error(sprintf(_('Unable to bind to %s with your with auto_uid credentials. Please check your configuration file.'),$ldapserver->name), + 'error','index.php'); $search = $ldapserver->search($con,$base_dn,$filter,array('uidNumber','gidNumber'),'sub',false,$_SESSION[APPCONFIG]->GetValue('deref','search')); if (! is_array($search)) - pla_error('Untrapped error.'); + error(_('Untrapped error.'),'error','index.php'); foreach ($search as $dn => $attrs) { $attrs = array_change_key_case($attrs); @@ -1198,7 +1219,7 @@ function get_next_number(&$ldapserver,$startbase='',$type='uid',$increment=false } break; default : - pla_error(sprintf('Unknown type [%s] in search',$type)); + error(sprintf('Unknown type [%s] in search',$type),'error','index.php'); } } @@ -1234,13 +1255,15 @@ function get_next_number(&$ldapserver,$startbase='',$type='uid',$increment=false $_SESSION[APPCONFIG]->ldapservers->GetValue($ldapserver->server_id,'auto_number','pass')); if (! $con) - pla_error(sprintf(_('Unable to bind to %s with your with auto_uid credentials. Please check your configuration file.'),$ldapserver->name)); + error(sprintf(_('Unable to bind to %s with your with auto_uid credentials. Please check your configuration file.'),$ldapserver->name), + 'error','index.php'); # assume that uidpool dn is set in config file if no filter given - if (empty($filter)) + if (empty($filter)) { $uidpool_dn = $_SESSION[APPCONFIG]->ldapservers->GetValue($ldapserver->server_id,'auto_number','uidpool_dn'); + $filter = '(objectclass=*)'; - else { + } else { $filter = str_replace(array('&',':::'),array('&',','),$filter); $dns = $ldapserver->search($con,$startbase,$filter,array('dn'),'sub'); @@ -1249,10 +1272,10 @@ function get_next_number(&$ldapserver,$startbase='',$type='uid',$increment=false break; case '0': - pla_error(_('Uidpool dn not found, please change filter parameter')); + error(_('Uidpool dn not found, please change filter parameter'),'error','index.php'); default: - pla_error(_('There is more than one dn for uidpool,please change filter parameter')); + error(_('There is more than one dn for uidpool,please change filter parameter'),'error','index.php'); } list ($key,$attrs) = each($dns); @@ -1260,31 +1283,38 @@ function get_next_number(&$ldapserver,$startbase='',$type='uid',$increment=false $uidpool_dn = $attrs['dn']; } - if (empty($uidpool_dn)) - pla_error(_('uidpool_dn not found. Please check filter (arg 3) or set up uidpool_dn in config file')); + # Check that the UIDPOOL DN exists. + if (empty($uidpool_dn) || (! $ldapserver->dnExists($uidpool_dn))) + error(_('uidpool_dn not found. Please check filter (arg 3) or set up uidpool_dn in config file'),'error','index.php'); - $attrs = array($type); - $key = strtolower($type); - $realkey = $type; + switch ($type) { + case 'uid' : $attr = 'uidnumber'; + break; + case 'gid' : $attr = 'gidnumber'; + break; + default : + error(_('Unknown uidpool type.'),'error','index.php'); + } - $number = $ldapserver->search($con,$uidpool_dn,$filter,$attrs,'base'); - list($rkey,$number) = each($number); - $number = array_change_key_case($number); - $number = $number[$key]; + $number = $ldapserver->search($con,$uidpool_dn,$filter,array($attr),'base'); + $numbers = array_change_key_case($number[$uidpool_dn]); - if (isset($increment) && ($increment == 'true')) { - $updatedattr = array ($key => $number + 1); + if (! isset($numbers[$attr])) + error(_('A query on the uidpool_dn did return a valid uidNumber.'),'error','index.php'); + else + + if ($increment) { + $updatedattr = array($attr => $numbers[$attr] + 1); $ldapserver->modify($uidpool_dn,$updatedattr); } - return $number; + return $numbers[$attr]; break; # No other cases allowed. The user has an error in the configuration default : - pla_error( sprintf( _('You specified an invalid value for auto_uid_number_mechanism ("%s") - in your configration. Only "uidpool" and "search" are valid. - Please correct this problem.') , $mechanism) ); + error(sprintf(_('You specified an invalid value for auto_uid_number_mechanism ("%s") in your configration. Only "uidpool" and "search" are valid. + Please correct this problem.'),$mechanism),'error','index.php'); } } @@ -1380,7 +1410,7 @@ function get_icon( $ldapserver, $dn ) { $cval = explode( '=', $tmp[0], 2 ); $cval = isset( $cval[1] ) ? $cval[1] : false; if( $cval && false === strpos( $cval, ".." ) && - file_exists( realpath( sprintf("./images/countries/%s.png",strtolower($cval)) ) ) ) + file_exists(realpath(sprintf('%s/countries/%s.png',IMGDIR,strtolower($cval))))) return sprintf("countries/%s.png",strtolower($cval)); @@ -1732,56 +1762,28 @@ function support_oid_to_text($oid_id) { } /** - * 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 + * Print an LDAP error message */ -function pla_error($msg,$ldap_err_msg=null,$ldap_err_no=-1,$fatal=true) { - if (defined('DEBUG_ENABLED') && (DEBUG_ENABLED)) - debug_log('Entered with (%s,%s,%s,%s)',1,__FILE__,__LINE__,__METHOD__, - $msg,$ldap_err_msg,$ldap_err_no,$fatal); +function ldap_error_msg($msg,$errnum) { + $body = ''; - $title = ''; + $errnum = ('0x'.str_pad(dechex($errnum),2,0,STR_PAD_LEFT)); + $verbose_error = pla_verbose_error($errnum); - if (function_exists('syslog_err')) - syslog_err($msg); + $body .= sprintf('',_('LDAP said'),htmlspecialchars($msg)); - if ($ldap_err_msg) - $title = sprintf('%s: %s',_('LDAP said'),htmlspecialchars($ldap_err_msg)); - - if ($ldap_err_no != -1) { - $body = '
%s:%s
'; - - $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) { - $body .= sprintf('',_('Error number'),$ldap_err_no,$verbose_error['title']); - $body .= sprintf('',_('Description'),$verbose_error['desc']); - } else { - $body .= sprintf('',_('Error number'),$ldap_err_no); - $body .= sprintf('',_('Description'),_('no description available')); - } - $body .= '
%s: %s (%s)
%s: %s
%s: %s
%s: (%s)
'; - - if (function_exists('syslog_err')) - syslog_err(sprintf('%s %s',_('Error number'),$ldap_err_no)); + if ($verbose_error) { + $body .= sprintf('
%s:%s (%s)
%s:%s
%s:%s
%s:(%s)
'; + + return $body; } /** @@ -1832,7 +1834,7 @@ function draw_jpeg_photos($ldapserver,$dn,$attr_name='jpegPhoto',$draw_delete_bu $jpeg_temp_dir = realpath($_SESSION[APPCONFIG]->GetValue('jpeg','tmpdir').'/'); if (! is_writable($jpeg_temp_dir)) - pla_error(_('Please set $jpeg_temp_dir to a writable directory in the phpLDAPadmin config.php') ); + error(_('Please set $jpeg_temp_dir to a writable directory in the phpLDAPadmin config.php'),'error','index.php'); if (! is_array($jpeg_data[$attr_name])) $jpeg_data[$attr_name] = array($jpeg_data[$attr_name]); @@ -1841,7 +1843,8 @@ function draw_jpeg_photos($ldapserver,$dn,$attr_name='jpegPhoto',$draw_delete_bu $jpeg_filename = tempnam($jpeg_temp_dir.'/','pla'); $outjpeg = @fopen($jpeg_filename,'wb'); if (! $outjpeg) - pla_error(sprintf(_('Could not write to the $jpeg_temp_dir directory %s. Please verify that your web server can write files there.'),$jpeg_temp_dir)); + error(sprintf(_('Could not write to the $jpeg_temp_dir directory %s. Please verify that your web server can write files there.'),$jpeg_temp_dir), + 'error','index.php'); fwrite($outjpeg,$jpeg); fclose ($outjpeg); @@ -1902,7 +1905,7 @@ function draw_jpeg_photos($ldapserver,$dn,$attr_name='jpegPhoto',$draw_delete_bu } closedir($handle); } else { - pla_error(sprintf('failed to open dir %s : permission denied', $jpeg_temp_dir), null, -1, false, false); + error(sprintf('failed to open dir %s : permission denied',$jpeg_temp_dir),'error'); } } @@ -1932,21 +1935,21 @@ function password_hash( $password_clear, $enc_type ) { case 'ext_des': // extended des crypt. see OpenBSD crypt man page. if ( ! defined( 'CRYPT_EXT_DES' ) || CRYPT_EXT_DES == 0 ) - pla_error( _('Your system crypt library does not support extended DES encryption.') ); + error(_('Your system crypt library does not support extended DES encryption.'),'error','index.php'); $new_value = '{CRYPT}' . crypt( $password_clear, '_' . random_salt(8) ); break; case 'md5crypt': if( ! defined( 'CRYPT_MD5' ) || CRYPT_MD5 == 0 ) - pla_error( _('Your system crypt library does not support md5crypt encryption.') ); + error(_('Your system crypt library does not support md5crypt encryption.'),'error','index.php'); $new_value = '{CRYPT}' . crypt( $password_clear , '$1$' . random_salt(9) ); break; case 'blowfish': if( ! defined( 'CRYPT_BLOWFISH' ) || CRYPT_BLOWFISH == 0 ) - pla_error( _('Your system crypt library does not support blowfish encryption.') ); + error(_('Your system crypt library does not support blowfish encryption.'),'error','index.php'); // hardcoded to second blowfish version and set number of rounds $new_value = '{CRYPT}' . crypt( $password_clear , '$2a$12$' . random_salt(13) ); @@ -1965,7 +1968,7 @@ function password_hash( $password_clear, $enc_type ) { $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.') ); + error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php'); } break; @@ -1976,7 +1979,7 @@ function password_hash( $password_clear, $enc_type ) { $new_value = "{SSHA}".base64_encode( mhash( MHASH_SHA1, $password_clear.$salt ).$salt ); } else { - pla_error( _('Your PHP install does not have the mhash() function. Cannot do SHA hashes.') ); + error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php'); } break; @@ -1987,7 +1990,7 @@ function password_hash( $password_clear, $enc_type ) { $new_value = "{SMD5}".base64_encode( mhash( MHASH_MD5, $password_clear.$salt ).$salt ); } else { - pla_error( _('Your PHP install does not have the mhash() function. Cannot do SHA hashes.') ); + error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php'); } break; @@ -2026,7 +2029,8 @@ function password_check( $cryptedpassword, $plainpassword ) { // check php mhash support before using it if( function_exists( 'mhash' ) ) { $hash = base64_decode($cryptedpassword); - $salt = substr($hash, -4); + # OpenLDAP uses a 4 byte salt, SunDS uses an 8 byte salt - both from char 20. + $salt = substr($hash,20); $new_hash = base64_encode( mhash( MHASH_SHA1, $plainpassword.$salt).$salt ); if( strcmp( $cryptedpassword, $new_hash ) == 0 ) @@ -2035,7 +2039,7 @@ function password_check( $cryptedpassword, $plainpassword ) { return false; } else { - pla_error( _('Your PHP install does not have the mhash() function. Cannot do SHA hashes.') ); + error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php'); } break; @@ -2053,7 +2057,7 @@ function password_check( $cryptedpassword, $plainpassword ) { return false; } else { - pla_error( _('Your PHP install does not have the mhash() function. Cannot do SHA hashes.') ); + error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php'); } break; @@ -2080,7 +2084,7 @@ function password_check( $cryptedpassword, $plainpassword ) { // make sure that web server supports blowfish crypt if( ! defined( 'CRYPT_BLOWFISH' ) || CRYPT_BLOWFISH == 0 ) - pla_error( _('Your system crypt library does not support blowfish encryption.') ); + error(_('Your system crypt library does not support blowfish encryption.'),'error','index.php'); list(,$version,$rounds,$salt_hash) = explode('$',$cryptedpassword); @@ -2095,7 +2099,7 @@ function password_check( $cryptedpassword, $plainpassword ) { // make sure that web server supports md5 crypt if( ! defined( 'CRYPT_MD5' ) || CRYPT_MD5 == 0 ) - pla_error( _('Your system crypt library does not support md5crypt encryption.') ); + error(_('Your system crypt library does not support md5crypt encryption.'),'error','index.php'); list(,$type,$salt,$hash) = explode('$',$cryptedpassword); @@ -2110,7 +2114,7 @@ function password_check( $cryptedpassword, $plainpassword ) { // make sure that web server supports ext_des if ( ! defined( 'CRYPT_EXT_DES' ) || CRYPT_EXT_DES == 0 ) - pla_error( _('Your system crypt library does not support extended DES encryption.') ); + error(_('Your system crypt library does not support extended DES encryption.'),'error','index.php'); if( crypt($plainpassword, $cryptedpassword ) == $cryptedpassword ) return true; @@ -2218,7 +2222,7 @@ function draw_chooser_link( $form_element, $include_choose_text=true, $rdn="none $title = _('Click to popup a dialog to select an entry (DN) graphically'); - printf('Find',$href,$title); + printf('Find',$href,$title,IMGDIR); if ($include_choose_text) printf('%s',$href,$title,_('browse')); } @@ -2330,7 +2334,7 @@ function dn_unescape($dn) { */ function get_href($type,$extra_info='') { $sf = 'https://sourceforge.net'; - $pla = 'http://phpldapadmin.wiki.sourceforge.net'; + $pla = 'http://phpldapadmin.sourceforge.net'; $group_id = '61828'; $bug_atid = '498546'; $rfe_atid = '498549'; @@ -2921,13 +2925,13 @@ function server_info_list($visible=false) { return $server_info_list; } -function enc_type_select_list($enc_type,$id,$attribute,$i) { +function enc_type_select_list($enc_type,$id,$attributename,$i) { if (DEBUG_ENABLED) - debug_log('Entered with (%s,%s,%s,%s)',1,__FILE__,__LINE__,__METHOD__,$enc_type,$id,$attribute,$i); + debug_log('Entered with (%s,%s,%s,%s)',1,__FILE__,__LINE__,__METHOD__,$enc_type,$id,$attributename,$i); $html = sprintf('