Compare commits

...

50 Commits

Author SHA1 Message Date
226a76d5fc Re-apply d15bd2dab 2023-04-02 10:42:25 +10:00
a0117e4ad8 Mandatory function arguments must be listed before optional ones. Alternate fix for 3a75a32 2023-04-02 10:42:25 +10:00
3bfd55de08 Revert "Mandatory function arguments must be listed before optional ones."
This reverts commit 3a75a32100.

Since calls to those functions had the arguements fully populated, just remove the default configured arg values.
2023-04-02 10:42:25 +10:00
d1dae60f05 get_magic_quotes_gpc() was deprecrated as of PHP 7.4 2023-04-02 10:42:25 +10:00
f29e200b96 Revert "Do not call get_magic_quote_gpc() when running in PHP version >= 5.4."
This reverts commit 3ec9c23d58.

The minimum requirement for PLA is 7.0
2023-04-02 10:42:25 +10:00
e5aa9eb1e7 each() deprecated in php 7.2 2023-04-02 10:42:25 +10:00
Deon George
30abeffc30 Fix for Implicit conversion from float 0.75 in createlm - fixes #193 2023-04-02 00:58:00 +11:00
d4b19d07db Updated version to 1.2.6.6 2023-04-02 00:46:16 +11:00
85f8c61e80 Fix for Setting of IV length for AEAD mode failed - closes #183 2023-04-02 00:36:15 +11:00
1650d6a921 Another fix for CVE-2020-35132 - closes #137, missed from #130 2023-04-02 00:25:47 +11:00
Deon George
c84b2d6d91 Updated version to 1.2.6.5 2023-02-15 17:36:15 +11:00
Deon George
ef8d0ce94c Fix mistake in patch #176 as identified in #170 2023-02-15 17:33:47 +11:00
Eric Lavault
15cc6f5382
Issue #165 Proper check for memory_limit config (#180)
* fix #165 : Handle shorthand notation for PHP memory_limit check

* fix config default memory threshold.
2023-02-15 17:24:19 +11:00
bendem
364c0565a2
don't apply preventXSS on 'filter' parameters in export and search (#168)
fixes #98
2023-01-20 20:08:49 +11:00
jmptbl
d09aa72a42
Inactivity message format fix (#171) 2023-01-20 20:08:07 +11:00
Klaus Tachtler
7226cea874
#170 - issue - openssl 3.0 patch (#176)
* Updated README with info on PLA v2

* Fix broken git command in readme - closes #124

* #170 - issue - openssl 3.0 patch

Co-authored-by: Deon George <deon@leenooks.net>
2023-01-20 20:06:44 +11:00
bendem
d15bd2dab3
Don't do any decoding on the password field (#163)
Fixes #162
2022-08-18 10:44:43 +10:00
Benjamin Renard
43bac58990 Add support of argon2i & argon2id password hash types
Closes pull-request #158
2022-08-05 10:49:10 +10:00
Patrick Monnerat
9488fe2ed7 Avoid passing a null value to PHP functions where another type is expected.
PHP 8.1 deprecates this feature.

Closes pull-request #149 and closes #150
2022-08-05 10:48:56 +10:00
Patrick Monnerat
5e9b95f9a8 Avoid 32-bit signed integer overflow in Blowfish computations.
PHP 8.1 deprecates float to int truncation.
2022-08-05 10:48:56 +10:00
Patrick Monnerat
aeebf3faa6 Replace calls to strftime() by calls to date().
PHP 8.1 deprecates strftime().
2022-08-05 10:48:56 +10:00
Patrick Monnerat
b035e8a0f4 Do not use function is_resource().
PHP 8.1 replaces some kind of resources by built-in class instances.
As is_resource() is always used to test for failures, replace calls by
simple Boolean checks.
2022-08-05 10:48:56 +10:00
Patrick Monnerat
f129579f45 Adapt app_error_handler() to PHP 8.
In an '@ error suppression context, PHP 8 error_reporting() no longer
returns 0 but an error mask of errors that cannot be supressed and
passes the effective error number to the error handler (instead of 0).

Adapt the test in a compatible way.
2022-08-05 10:48:56 +10:00
Patrick Monnerat
c90dc06af2 Rename class Attribute to PLAAttribute.
As PHP 8 introduces a built-in Attribute class, a name clash occurs
without this commit.

Class names are used by the Visitor class to dynamically build method
names. To avoid having to also rename the target methods, a class name
mapping is introduced for this purpose. This map may be augmented
whenever another similar case occurs.
2022-08-05 10:48:56 +10:00
Patrick Monnerat
3a75a32100 Mandatory function arguments must be listed before optional ones.
PHP 8 deprecates the ability to have
	function whatever($arg1, $arg2='something', $arg3)

This commit reorders arguments of functions set_cached_item() and
draw_jpeg_photo() to meet this new requirement.
2022-08-05 10:48:56 +10:00
Patrick Monnerat
3ec9c23d58 Do not call get_magic_quote_gpc() when running in PHP version >= 5.4.
This deprecated function has been removed in PHP 8.
2022-08-05 10:48:56 +10:00
KuhnChris
857f0c539c sanity-fix: gettext and session mod check
Closes pull-request #152
2022-08-05 10:48:56 +10:00
Andrés Maldonado
97eed9d9cd Prevent strftime overflow on 32 bit systems
Fixes "strftime() expects parameter 2 to be integer, float given"

Closes pull request #156 and closes #155
2022-08-05 10:48:31 +10:00
Deon George
d4cae5065b Updated version to 1.2.6.3 2021-12-12 13:35:51 +11:00
Deon George
386d6ab83b Fix syntax error created by a0de69b - thanks to Bert Van de Poel for testing this and identifying the error 2021-12-12 13:25:28 +11:00
Deon George
1d26d435c2 Special character issue in password - closes #104 2021-12-10 16:14:04 +11:00
Deon George
a0de69bd58 foreach error in lib_ldap_pla.php:checkUniqueAttrs when uidpool is turned on - closes #20 2021-12-10 16:05:01 +11:00
EtienneBarbier
a8c9abe22b Add option to list available password types - closes #143 2021-12-10 15:56:58 +11:00
Bert Van de Poel
1c7340ce48 Correct incorrent mixing of tabs and spaces.
All code (including code originating from the blowfish PR) now correctly use tabs. Spaces are only used for alignment in comments where necessary.
2021-12-10 15:18:26 +11:00
Bert Van de Poel
24ce5d5833 Replace salt function with a more modern, cryptographically secure pseudo-random method
Set minimum PHP version to 7.0.0 for random_bytes
2021-12-10 15:18:18 +11:00
Bert Van de Poel
fe3798f8ec Modernize sha1 and md5 password hash and check functions: remove unnecessary pack, no longer use very old fallbacks, and use random_salt 2021-12-10 15:18:09 +11:00
Bert Van de Poel
1a09e4ff3c Modernize sha512 hash code: replace openssl_digest with the generic hash function, remove check no longer necessary in minimum version 2021-12-10 15:18:01 +11:00
Bert Van de Poel
bc1691f5d2 Add hash support for ssha512 2021-12-10 15:17:54 +11:00
Bert Van de Poel
54bb4743aa Add hash support for salted and non-salted sha256 and sha384 (therefore adding full support for all hashes in the sha2 openLDAP module) 2021-12-10 15:17:43 +11:00
Franky Van Liedekerke
46cc4a1b13 Take into account empty arguments
If no argument is given to the function call, don't try to pass an empty array as some php functions don't allow arguments (like the time function)
2021-12-10 15:09:18 +11:00
Maarten
45aa1e5208 Added script comment for the Autofill A flag 2021-12-10 15:06:36 +11:00
Maarten
02b047c1f5 Bug fix: typo in regex 2021-12-10 15:06:36 +11:00
Maarten
6d4aff8733 Added optional delimiter to /K autofill function 2021-12-10 15:06:36 +11:00
Scott Shambarger
00683b3ea7 Added TLS client certificate support
Adds configuration for TLS client certificates to secure TLS connection
(requires PHP 7.1+ to use).
Updates use of ldap_set_option to report errors if settings fail.
Modifies connection logic to fail if connection preparation fails
(eg. to avoid connections over insecure links if requested TLS fails).
2021-12-10 15:02:31 +11:00
Scott Shambarger
da69ebf06a Added SASL EXTERNAL authentication support
New auth_type 'sasl_external'.  Login is hard coded as 'external'
2021-12-10 14:59:02 +11:00
Deon George
a8fe6f3274 Revert part of 0b657471 to fix #105 - Problem with member select list to goun 2020-09-23 10:13:11 +10:00
Deon George
0c334f0385 Fix for issue #103 - hexdec() causes an deprecation notice when invalid chars are used 2020-09-19 17:09:29 +10:00
Deon George
9fac4b415a Release 1.2.6 2020-09-19 13:45:09 +10:00
Nic Bernstein
f4c8c3d31e SF Bug #1008 getContainerPath doesn't properly traverse to baseDN and back & #1009 - return_ldap_hash should not return container object in result set 2020-08-31 08:49:02 +10:00
Andy Beefeater
e45e71fd08 SF Feature #356 - HTMLTree icons formatting 2020-08-31 08:48:49 +10:00
41 changed files with 771 additions and 340 deletions

View File

@ -5,7 +5,7 @@ For install instructions in non-English languages, see the wiki:
phpLDAPadmin requires the following: phpLDAPadmin requires the following:
a. A web server (Apache, IIS, etc). a. A web server (Apache, IIS, etc).
b. PHP 5.5.0 or newer (with LDAP support) b. PHP 7.0.0 or newer (with LDAP support)
* To install * To install

View File

@ -1,13 +1,90 @@
phpLDAPadmin # phpLDAPadmin
============ phpLDAPadmin is a web based LDAP data management tool for system administrators. It is commonly known and referred by many as "PLA".
phpLDAPadmin - Web based LDAP administration tool A primary goal of PLA is to be as intuitive as possible - so it is certainly possible for end users to use it as well, for example, to manage their data in an LDAP server.
PLA is designed to be compliant with LDAP RFCs, enabling it to be used with any LDAP server.
If you come across an LDAP server, where PLA exhibits problems, please open an issue with full details of the problem so that we can have it fixed.
## History
Initially created in 2002 by David Smith, it was taken over by Deon George (aka leenooks) in 2005.
Since 2003 many things have changed - initial development was done in CVS and the project was hosted on Sourceforge.
In 2009, CVS was swapped out for GIT, and in around 2011 the project was moved to Github.
The PLA v1.2.x stream was created in July 2009.
Work on PLA v2 has started and some information on that is below. Soon `master` will be updated and `BRANCH-2.0` will be visible in git. Until then, a sneak peak of v2 is available [here](https://phpldapadmin.servio.leenooks.net)
## THANK YOU
Over the years, many, many, many people have supported PLA with either their time, their coding or with financial donations.
I have tried to send an email to acknowledge each contribution, and if you havent seen anything personally from me, I am sorry, but please know that I do appreciate all the help I get, in whatever form it is provided.
Again, Thank You.
## Future
Web development, tools, approaches and technology has come along way since 2009 and some talented folks have created some fantastic tools.
With that PLA is going under a major revamp in preparation for v2 and will aim to use those existing creations to help speed up the revamp effort.
Some of the creations planned to be used in v2 include:
* Laravel (https://laravel.com)
* adldap2/adldap2 (https://github.com/Adldap2/Adldap2)
* JQuery (https://jquery.com)
* FancyTree (https://github.com/mar10/fancytree)
* ArchitectUI (https://architectui.com)
PLA v1.2.x will be archived into [BRANCH-1.2](https://github.com/leenooks/phpLDAPadmin/tree/BRANCH-1.2), and `master` will be changed to reflect the new v2 work and effort.
If you plan to use PLA, and cannot use an installation from your OS package, please use [BRANCH-1.2](https://github.com/leenooks/phpLDAPadmin/tree/BRANCH-1.2) while progress is made in master for v2.
If you like the cutting edge, feel free to try out `master`, but expect problems, bugs and missing functionality.
If you have extended v2 and would like to contribute your extension, or if you find a way to fix something that is broken or missing please submit a pull request.
Alternatively, you can get take a peek at the work so far by using our docker container, which is built automatically after testing passes.
The [demo](http://demo.phpldapadmin.org) site, will also be running the same docker container. (See below for details.)
In summary, for the time being, expect `master` to be buggy and broken, and I'll update this readme as enhancements progress.
## Installation ## Installation
The following instructions will be for PLA v2 when its commited to GIT. Checkback regularly, as it will be pushed when its is semi functional.
[INSTALL](INSTALL.md) ### Installation on your server
#### Prerequisites
* A HTTP server (eg: Apache, Nginx)
* PHP (minimum version 7.2) https://www.php.net
* Composer https://getcomposer.org
* GIT
#### Installation
1. Checkout the code from github
```bash
git clone https://github.com/leenooks/phpLDAPadmin.git
```
1. Install composer dependencies.
```bash
composer install
```
1. Edit your `.env` file as appropriate
copy `.env.example` to `.env` as a start.
1. Configure your webserver to have PLA's root in the `public` directory
### Using Docker
Instructions to come.
## Getting Help
The best place to get help with PLA (new and old) is on Stack Overflow (https://stackoverflow.com/tags/phpldapadmin/info)
## Found a bug?
If you have found a bug, and can provide detailed instructions so that it can be reproduced, please open an [issue](https://github.com/leenooks/phpLDAPadmin/issues) and provide those details.
Before opening a ticket, please check to see if it hasnt already been reported, and if it has, please provide any additional information that will help it be fixed.
*TIP*: Issues opened with reproducible details accompanied with a patch (or a pull request) to fix the problem will be looked at first.
## License ## License
[LICENSE](LICENSE) [LICENSE](LICENSE)

View File

@ -1 +1 @@
RELEASE-1.2.5 RELEASE-1.2.6.6

View File

@ -71,6 +71,33 @@
environments. */ environments. */
# $config->custom->password['no_random_crypt_salt'] = true; # $config->custom->password['no_random_crypt_salt'] = true;
/* If you want to restrict password available types (encryption algorithms)
Should be subset of:
array(
''=>'clear',
'bcrypt'=>'bcrypt',
'blowfish'=>'blowfish',
'crypt'=>'crypt',
'ext_des'=>'ext_des',
'md5'=>'md5',
'k5key'=>'k5key',
'md5crypt'=>'md5crypt',
'sha'=>'sha',
'smd5'=>'smd5',
'ssha'=>'ssha',
'sha256'=>'sha256',
'ssha256'=>'ssha256',
'sha384'=>'sha384',
'ssha384'=>'ssha384',
'sha512'=>'sha512',
'ssha512'=>'ssha512',
'sha256crypt'=>'sha256crypt',
'sha512crypt'=>'sha512crypt',
'argon2i'=>'argon2i',
'argon2id'=>'argon2id',
)*/
# $config->custom->password['available_types'] = array(''=>'clear','md5'=>'md5');
/* PHP script timeout control. If php runs longer than this many seconds then /* PHP script timeout control. If php runs longer than this many seconds then
PHP will stop with an Maximum Execution time error. Increase this value from PHP will stop with an Maximum Execution time error. Increase this value from
the default if queries to your LDAP server are slow. The default is either the default if queries to your LDAP server are slow. The default is either
@ -173,6 +200,10 @@ $config->custom->commands['script'] = array(
// $config->custom->appearance['tree_width'] = null; // $config->custom->appearance['tree_width'] = null;
# $config->custom->appearance['tree_width'] = 250; # $config->custom->appearance['tree_width'] = 250;
/* Number of tree command icons to show, 0 = show all icons on 1 row. */
// $config->custom->appearance['tree_icons'] = 0;
# $config->custom->appearance['tree_icons'] = 4;
/* Confirm create and update operations, allowing you to review the changes /* Confirm create and update operations, allowing you to review the changes
and optionally skip attributes during the create/update operation. */ and optionally skip attributes during the create/update operation. */
// $config->custom->confirm['create'] = true; // $config->custom->confirm['create'] = true;
@ -243,7 +274,6 @@ $config->custom->appearance['friendly_attrs'] = array(
/* Attribute that is added to the group member attribute. */ /* Attribute that is added to the group member attribute. */
// $config->custom->modify_member['attr'] = 'dn'; // $config->custom->modify_member['attr'] = 'dn';
/* For Posix attributes */ /* For Posix attributes */
// $config->custom->modify_member['posixattr'] = 'uid'; // $config->custom->modify_member['posixattr'] = 'uid';
// $config->custom->modify_member['posixfilter'] = '(uid=*)'; // $config->custom->modify_member['posixfilter'] = '(uid=*)';
@ -311,6 +341,7 @@ $servers->setValue('server','name','My LDAP Server');
login will be required to use phpLDAPadmin for this server. login will be required to use phpLDAPadmin for this server.
5. 'sasl': login will be taken from the webserver's kerberos authentication. 5. 'sasl': login will be taken from the webserver's kerberos authentication.
Currently only GSSAPI has been tested (using mod_auth_kerb). Currently only GSSAPI has been tested (using mod_auth_kerb).
6. 'sasl_external': login will be taken from SASL external mechanism.
Choose wisely to protect your authentication information appropriately for Choose wisely to protect your authentication information appropriately for
your situation. If you choose 'cookie', your cookie contents will be your situation. If you choose 'cookie', your cookie contents will be
@ -335,6 +366,22 @@ $servers->setValue('server','name','My LDAP Server');
/* Use TLS (Transport Layer Security) to connect to the LDAP server. */ /* Use TLS (Transport Layer Security) to connect to the LDAP server. */
// $servers->setValue('server','tls',false); // $servers->setValue('server','tls',false);
/* TLS Certificate Authority file (overrides ldap.conf, PHP 7.1+) */
// $servers->setValue('server','tls_cacert',null);
# $servers->setValue('server','tls_cacert','/etc/openldap/certs/ca.crt');
/* TLS Certificate Authority hashed directory (overrides ldap.conf, PHP 7.1+) */
// $servers->setValue('server','tls_cacertdir',null);
# $servers->setValue('server','tls_cacertdir','/etc/openldap/certs');
/* TLS Client Certificate file (PHP 7.1+) */
// $servers->setValue('server','tls_cert',null);
# $servers->setValue('server','tls_cert','/etc/pki/tls/certs/ldap_user.crt');
/* TLS Client Certificate Key file (PHP 7.1+) */
// $servers->setValue('server','tls_key',null);
# $servers->setValue('server','tls_key','/etc/pki/tls/private/ldap_user.key');
/************************************ /************************************
* SASL Authentication * * SASL Authentication *
************************************/ ************************************/
@ -352,6 +399,9 @@ $servers->setValue('server','name','My LDAP Server');
NOTE: auth_type must be simple auth compatible (ie not sasl) */ NOTE: auth_type must be simple auth compatible (ie not sasl) */
# $servers->setValue('sasl','mech','PLAIN'); # $servers->setValue('sasl','mech','PLAIN');
/* SASL EXTERNAL support... really a different auth_type */
# $servers->setValue('login','auth_type','sasl_external');
/* SASL authentication realm name */ /* SASL authentication realm name */
// $servers->setValue('sasl','realm',''); // $servers->setValue('sasl','realm','');
# $servers->setValue('sasl','realm','EXAMPLE.COM'); # $servers->setValue('sasl','realm','EXAMPLE.COM');

View File

@ -41,7 +41,7 @@ if (DEBUG_ENABLED)
$www['page'] = new page($app['server']->getIndex()); $www['page'] = new page($app['server']->getIndex());
# See if we can render the command # See if we can render the command
if (trim($www['cmd'])) { if ($www['cmd'] && trim($www['cmd'])) {
# If this is a READ-WRITE operation, the LDAP server must not be in READ-ONLY mode. # If this is a READ-WRITE operation, the LDAP server must not be in READ-ONLY mode.
if ($app['server']->isReadOnly() && ! in_array(get_request('cmd','REQUEST'),$app['readwrite_cmds'])) if ($app['server']->isReadOnly() && ! in_array(get_request('cmd','REQUEST'),$app['readwrite_cmds']))
error(_('You cannot perform updates while server is in read-only mode'),'error','index.php'); error(_('You cannot perform updates while server is in read-only mode'),'error','index.php');

View File

@ -41,7 +41,7 @@ $request['recursive'] = (get_request('recursive') == 'on') ? true : false;
$request['remove'] = (get_request('remove') == 'yes') ? true : false; $request['remove'] = (get_request('remove') == 'yes') ? true : false;
if ($request['recursive']) { if ($request['recursive']) {
$filter = get_request('filter','POST',false,'(objectClass=*)'); $filter = get_request('filter','POST',false,'(objectClass=*)',false);
# Build a tree similar to that of the tree browser to give to r_copy_dn # Build a tree similar to that of the tree browser to give to r_copy_dn
$ldap['tree'] = array(); $ldap['tree'] = array();

View File

@ -13,11 +13,11 @@ require './common.php';
require LIBDIR.'export_functions.php'; require LIBDIR.'export_functions.php';
$request = array(); $request = array();
$request['dn'] = get_request('dn','GET'); $request['dn'] = get_request('dn','GET',false,'');
$request['format'] = get_request('format','GET',false,get_line_end_format()); $request['format'] = get_request('format','GET',false,get_line_end_format());
$request['scope'] = get_request('scope','GET',false,'base'); $request['scope'] = get_request('scope','GET',false,'base');
$request['exporter_id'] = get_request('exporter_id','GET',false,'LDIF'); $request['exporter_id'] = get_request('exporter_id','GET',false,'LDIF');
$request['filter'] = get_request('filter','GET',false,'(objectClass=*)'); $request['filter'] = get_request('filter','GET',false,'(objectClass=*)',false);
$request['attr'] = get_request('attributes','GET',false,'*'); $request['attr'] = get_request('attributes','GET',false,'*');
$request['sys_attr'] = get_request('sys_attr','GET') ? true: false; $request['sys_attr'] = get_request('sys_attr','GET') ? true: false;

View File

@ -19,7 +19,8 @@ if ($_SESSION[APPCONFIG]->getValue('session', 'reCAPTCHA-enable')) {
if ($pass) { if ($pass) {
$user = array(); $user = array();
$user['login'] = get_request('login'); $user['login'] = get_request('login');
$user['password'] = get_request('login_pass'); $user['password'] = get_request('login_pass', 'POST', false, '', false);
$user['password'] = html_entity_decode($user['password'], ENT_QUOTES);
if ($user['login'] && !strlen($user['password'])) { if ($user['login'] && !strlen($user['password'])) {
system_message(array( system_message(array(

View File

@ -65,7 +65,7 @@ for ($i=0;$i<count($possible_values);$i++) {
if (preg_match("/^".$request['attr']."$/i",$_SESSION[APPCONFIG]->getValue('modify_member','posixgroupattr'))) if (preg_match("/^".$request['attr']."$/i",$_SESSION[APPCONFIG]->getValue('modify_member','posixgroupattr')))
$possible_members[$i] = $possible_values[$i][$_SESSION[APPCONFIG]->getValue('modify_member','posixattr')][0]; $possible_members[$i] = $possible_values[$i][$_SESSION[APPCONFIG]->getValue('modify_member','posixattr')][0];
else else
$possible_members[$i] = $possible_values[$i][$_SESSION[APPCONFIG]->getValue('modify_member','attr')][0]; $possible_members[$i] = $possible_values[$i][$_SESSION[APPCONFIG]->getValue('modify_member','attr')];
} }
# Show only user that are not already in group. # Show only user that are not already in group.

View File

@ -15,8 +15,8 @@ $www['page'] = new page();
$request = array(); $request = array();
$request['componentid'] = get_request('componentid','REQUEST'); $request['componentid'] = get_request('componentid','REQUEST');
$request['hash'] = get_request('hash','REQUEST'); $request['hash'] = get_request('hash','REQUEST',false,'');
$request['password'] = get_request('check_password','REQUEST'); $request['password'] = get_request('check_password','REQUEST',false,'');
$request['action'] = get_request('action','REQUEST'); $request['action'] = get_request('action','REQUEST');
$request['attribute'] = get_request('attr','REQUEST'); $request['attribute'] = get_request('attr','REQUEST');

View File

@ -150,7 +150,7 @@ switch($entry['view']) {
foreach ($sattrs as $attr) { foreach ($sattrs as $attr) {
if (isAjaxEnabled() || (is_null($entry['value']) || ! trim($entry['value']) || $entry['value']==$attr->getName())) { if (isAjaxEnabled() || (is_null($entry['value']) || ! trim($entry['value']) || $entry['value']==$attr->getName())) {
if ((! is_null($entry['value']) && $entry['value']==$attr->getName()) || ! trim($entry['value'])) if (!is_string($entry['value']) || $entry['value']==$attr->getName() || !trim($entry['value']))
$entry['viewed'] = true; $entry['viewed'] = true;
if (isAjaxEnabled() && $entry['value']) if (isAjaxEnabled() && $entry['value'])
@ -380,7 +380,7 @@ switch($entry['view']) {
$desc = $rule->getName(false); $desc = $rule->getName(false);
if (isAjaxEnabled() || (is_null($entry['value']) || ! trim($entry['value']) || $entry['value']==$rule->getName())) { if (isAjaxEnabled() || (is_null($entry['value']) || ! trim($entry['value']) || $entry['value']==$rule->getName())) {
if ((! is_null($entry['value']) && $entry['value']==$rule->getName()) || ! trim($entry['value'])) if (!is_string($entry['value']) || $entry['value']==$rule->getName() || !trim($entry['value']))
$entry['viewed'] = true; $entry['viewed'] = true;
if (null != $rule->getDescription()) if (null != $rule->getDescription())
@ -468,7 +468,7 @@ switch($entry['view']) {
foreach ($socs as $name => $oclass) { foreach ($socs as $name => $oclass) {
if (isAjaxEnabled() || (is_null($entry['value']) || ! trim($entry['value']) || $entry['value']==$oclass->getName())) { if (isAjaxEnabled() || (is_null($entry['value']) || ! trim($entry['value']) || $entry['value']==$oclass->getName())) {
if ((! is_null($entry['value']) && $entry['value']==$oclass->getName()) || ! trim($entry['value'])) if (!is_string($entry['value']) || $entry['value']==$oclass->getName() || !trim($entry['value']))
$entry['viewed'] = true; $entry['viewed'] = true;
if (isAjaxEnabled() && $entry['value']) if (isAjaxEnabled() && $entry['value'])

View File

@ -40,7 +40,7 @@ switch ($request['location']) {
if (! isset($jpeg_data[$request['attr']][$request['index']])) { if (! isset($jpeg_data[$request['attr']][$request['index']])) {
if (function_exists('imagecreate')) { if (function_exists('imagecreate')) {
$im = imagecreate(160,30); $im = imagecreate(160,30);
if (is_resource($im)) { if ($im) {
header('Content-type: image/png'); header('Content-type: image/png');
# Set the background # Set the background

View File

@ -133,7 +133,7 @@ class AttributeFactory {
return $this->newGidAttribute($name,$values,$server_id,$source); return $this->newGidAttribute($name,$values,$server_id,$source);
} else { } else {
return new Attribute($name,$values,$server_id,$source); return new PLAAttribute($name,$values,$server_id,$source);
} }
} }

View File

@ -12,7 +12,7 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class BinaryAttribute extends Attribute { class BinaryAttribute extends PLAAttribute {
protected $filepaths; protected $filepaths;
protected $filenames; protected $filenames;

View File

@ -12,6 +12,6 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class DateAttribute extends Attribute { class DateAttribute extends PLAAttribute {
} }
?> ?>

View File

@ -12,6 +12,6 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class DnAttribute extends Attribute { class DnAttribute extends PLAAttribute {
} }
?> ?>

View File

@ -12,6 +12,6 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class GidAttribute extends Attribute { class GidAttribute extends PLAAttribute {
} }
?> ?>

View File

@ -136,6 +136,7 @@ class HTMLTree extends Tree {
case 'config': case 'config':
case 'proxy': case 'proxy':
case 'sasl': case 'sasl':
case 'sasl_external':
break; break;
default: default:
@ -169,7 +170,7 @@ class HTMLTree extends Tree {
if (! is_null($server->inactivityTime())) { if (! is_null($server->inactivityTime())) {
$m = sprintf(_('Inactivity will log you off at %s'), $m = sprintf(_('Inactivity will log you off at %s'),
strftime('%H:%M',$server->inactivityTime())); date('H:i',$server->inactivityTime()));
printf(' <img width="14" height="14" src="%s/timeout.png" title="%s" alt="%s"/>',IMGDIR,$m,'Timeout'); printf(' <img width="14" height="14" src="%s/timeout.png" title="%s" alt="%s"/>',IMGDIR,$m,'Timeout');
} }
echo '</td></tr>'; echo '</td></tr>';
@ -184,10 +185,15 @@ class HTMLTree extends Tree {
$links = ''; $links = '';
$i = 0;
$icons = $_SESSION[APPCONFIG]->getValue('appearance','tree_icons');
if (is_array($_SESSION[APPCONFIG]->getValue('menu','session'))) if (is_array($_SESSION[APPCONFIG]->getValue('menu','session')))
foreach ($_SESSION[APPCONFIG]->getValue('menu','session') as $link => $title) { foreach ($_SESSION[APPCONFIG]->getValue('menu','session') as $link => $title) {
if ($this->get_menu_item($link)) if ($this->get_menu_item($link))
$links .= sprintf('<td class="server_links">%s</td>',$this->get_menu_item($link)); $links .= sprintf('<td class="server_links">%s</td>',$this->get_menu_item($link));
if ($icons && ++$i%$icons == 0)
$links .= '</tr><tr>';
} }
# Finally add our logout link. # Finally add our logout link.
@ -329,7 +335,7 @@ class HTMLTree extends Tree {
$server = $this->getServer(); $server = $this->getServer();
$href = sprintf('cmd.php?cmd=logout&server_id=%s',$server->getIndex()); $href = sprintf('cmd.php?cmd=logout&server_id=%s',$server->getIndex());
if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','logout') || in_array($server->getAuthType(),array('config','http','proxy','sasl'))) if (! $_SESSION[APPCONFIG]->isCommandAvailable('script','logout') || in_array($server->getAuthType(),array('config','http','proxy','sasl','sasl_external')))
return ''; return '';
else else
return sprintf('<a href="%s" title="%s"><img src="%s/%s" alt="%s" /><br />%s</a>', return sprintf('<a href="%s" title="%s"><img src="%s/%s" alt="%s" /><br />%s</a>',

View File

@ -12,7 +12,7 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class MultiLineAttribute extends Attribute { class MultiLineAttribute extends PLAAttribute {
protected $rows = 0; protected $rows = 0;
protected $cols = 0; protected $cols = 0;

View File

@ -12,6 +12,6 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class ObjectClassAttribute extends Attribute { class ObjectClassAttribute extends PLAAttribute {
} }
?> ?>

View File

@ -12,7 +12,7 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class Attribute { class PLAAttribute {
# Attribute Name # Attribute Name
public $name; public $name;
# Source of this attribute definition # Source of this attribute definition
@ -258,14 +258,14 @@ class Attribute {
} }
} }
public function getValue($i) { public function getValue($i, $default=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (isset($this->values[$i])) if (isset($this->values[$i]))
return $this->values[$i]; return $this->values[$i];
else else
return null; return $default;
} }
public function getOldValue($i) { public function getOldValue($i) {

View File

@ -538,7 +538,7 @@ class PageRender extends Visitor {
final protected function drawHiddenValueAttribute($attribute,$i) { final protected function drawHiddenValueAttribute($attribute,$i) {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__); if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
$val = $attribute->getValue($i); $val = $attribute->getValue($i, '');
printf('<input type="hidden" name="new_values[%s][%s]" id="new_values_%s_%s" value="%s" />', printf('<input type="hidden" name="new_values[%s][%s]" id="new_values_%s_%s" value="%s" />',
htmlspecialchars($attribute->getName()),$i,htmlspecialchars($attribute->getName()),$i, htmlspecialchars($attribute->getName()),$i,htmlspecialchars($attribute->getName()),$i,
@ -556,7 +556,7 @@ class PageRender extends Visitor {
final protected function drawOldValueAttribute($attribute,$i) { final protected function drawOldValueAttribute($attribute,$i) {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__); if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
echo $attribute->getOldValue($i); echo htmlspecialchars($attribute->getOldValue($i));
} }
/** DRAW DISPLAYED CURRENT VALUES **/ /** DRAW DISPLAYED CURRENT VALUES **/
@ -607,7 +607,7 @@ class PageRender extends Visitor {
protected function drawFormReadOnlyValueAttribute($attribute,$i) { protected function drawFormReadOnlyValueAttribute($attribute,$i) {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__); if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
$val = $attribute->getValue($i); $val = $attribute->getValue($i, '');
printf('<input type="text" class="roval" name="new_values[%s][%s]" id="new_values_%s_%s" value="%s" readonly="readonly" />', printf('<input type="text" class="roval" name="new_values[%s][%s]" id="new_values_%s_%s" value="%s" readonly="readonly" />',
htmlspecialchars($attribute->getName()),$i,htmlspecialchars($attribute->getName()),$i,htmlspecialchars($val)); htmlspecialchars($attribute->getName()),$i,htmlspecialchars($attribute->getName()),$i,htmlspecialchars($val));
@ -616,7 +616,7 @@ class PageRender extends Visitor {
protected function drawFormReadWriteValueAttribute($attribute,$i) { protected function drawFormReadWriteValueAttribute($attribute,$i) {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__); if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
$val = $attribute->getValue($i); $val = $attribute->getValue($i, '');
if ($attribute->getHelper() || $attribute->getVerify()) if ($attribute->getHelper() || $attribute->getVerify())
echo '<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="top">'; echo '<table cellspacing="0" cellpadding="0" border="0"><tr><td valign="top">';
@ -720,7 +720,7 @@ class PageRender extends Visitor {
protected function drawFormReadWriteValueDateAttribute($attribute,$i) { protected function drawFormReadWriteValueDateAttribute($attribute,$i) {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__); if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
$val = $attribute->getValue($i); $val = $attribute->getValue($i, '');
echo '<span style="white-space: nowrap;">'; echo '<span style="white-space: nowrap;">';
printf('<input type="text" class="value" id="new_values_%s_%s" name="new_values[%s][%s]" value="%s" %s%s %s %s/>&nbsp;', printf('<input type="text" class="value" id="new_values_%s_%s" name="new_values[%s][%s]" value="%s" %s%s %s %s/>&nbsp;',
@ -738,7 +738,7 @@ class PageRender extends Visitor {
protected function drawFormReadWriteValueDnAttribute($attribute,$i) { protected function drawFormReadWriteValueDnAttribute($attribute,$i) {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__); if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
$val = $attribute->getValue($i); $val = $attribute->getValue($i, '');
if ($attribute->getHelper()) if ($attribute->getHelper())
echo '<table cellspacing="0" cellpadding="0"><tr><td valign="top">'; echo '<table cellspacing="0" cellpadding="0"><tr><td valign="top">';
@ -952,7 +952,7 @@ class PageRender extends Visitor {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__); if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
$server = $this->getServer(); $server = $this->getServer();
$val = $attribute->getValue($i); $val = $attribute->getValue($i, '');
if (trim($val)) if (trim($val))
$enc_type = get_enc_type($val); $enc_type = get_enc_type($val);
@ -974,7 +974,7 @@ class PageRender extends Visitor {
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__); if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
$server = $this->getServer(); $server = $this->getServer();
$val = $attribute->getValue($i); $val = $attribute->getValue($i, '');
$enc_type = get_enc_type($val); $enc_type = get_enc_type($val);
@ -1102,7 +1102,7 @@ class PageRender extends Visitor {
# This is a single value attribute # This is a single value attribute
} else { } else {
$val = $attribute->getValue($i) ? $attribute->getValue($i) : $attribute->getDefault(); $val = $attribute->getValue($i) ? $attribute->getValue($i) : (is_null($attribute->getDefault())? '': $attribute->getDefault());
if ($attribute->getHelper()) if ($attribute->getHelper())
echo '<table cellspacing="0" cellpadding="0"><tr><td valign="top">'; echo '<table cellspacing="0" cellpadding="0"><tr><td valign="top">';
@ -1196,7 +1196,8 @@ class PageRender extends Visitor {
else else
return false; return false;
return $shadow_date*24*3600; $shadow_date_seconds = $shadow_date*24*3600;
return ($shadow_date_seconds > PHP_INT_MAX) ? PHP_INT_MAX: $shadow_date_seconds;
} }
protected function drawShadowDateShadowAttribute($attribute) { protected function drawShadowDateShadowAttribute($attribute) {
@ -1214,15 +1215,15 @@ class PageRender extends Visitor {
echo '<br/><small>'; echo '<br/><small>';
if (($today < $shadow_date) && in_array(strtolower($attribute->getName()),$shadow_before_today_attrs)) if (($today < $shadow_date) && in_array(strtolower($attribute->getName()),$shadow_before_today_attrs))
printf('<span style="color:red">(%s)</span>', printf('<span style="color:red">(%s)</span>',
strftime($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date)); date($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date));
elseif (($today > $shadow_date) && in_array(strtolower($attribute->getName()),$shadow_after_today_attrs)) elseif (($today > $shadow_date) && in_array(strtolower($attribute->getName()),$shadow_after_today_attrs))
printf('<span style="color:red">(%s)</span>', printf('<span style="color:red">(%s)</span>',
strftime($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date)); date($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date));
else else
printf('(%s)', printf('(%s)',
strftime($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date)); date($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date));
echo '</small><br />'; echo '</small><br />';
} }

View File

@ -12,6 +12,6 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class PasswordAttribute extends Attribute { class PasswordAttribute extends PLAAttribute {
} }
?> ?>

View File

@ -134,9 +134,9 @@ class Query extends xmlTemplate {
# If this is a custom search, we need to populate are paramters # If this is a custom search, we need to populate are paramters
if ($this->getID() == 'none') { if ($this->getID() == 'none') {
$bases = get_request('base','REQUEST',false,null); $bases = get_request('base','REQUEST',false,null);
$query['filter'] = get_request('filter','REQUEST',false,'objectClass=*'); $query['filter'] = get_request('filter','REQUEST',false,'objectClass=*',false);
$query['scope'] = get_request('scope','REQUEST',false,'sub'); $query['scope'] = get_request('scope','REQUEST',false,'sub');
$attrs = get_request('display_attrs','REQUEST'); $attrs = get_request('display_attrs','REQUEST',false,'');
$attrs = preg_replace('/\s+/','',$attrs); $attrs = preg_replace('/\s+/','',$attrs);
if ($attrs) if ($attrs)

View File

@ -12,7 +12,7 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class SelectionAttribute extends Attribute { class SelectionAttribute extends PLAAttribute {
protected $selection = array(); protected $selection = array();
protected $multiple; protected $multiple;
protected $default; protected $default;

View File

@ -12,7 +12,7 @@
* @package phpLDAPadmin * @package phpLDAPadmin
* @subpackage Templates * @subpackage Templates
*/ */
class ShadowAttribute extends Attribute { class ShadowAttribute extends PLAAttribute {
public $shadow_before_today_attrs = array('shadowLastChange','shadowMin'); public $shadow_before_today_attrs = array('shadowLastChange','shadowMin');
public $shadow_after_today_attrs = array('shadowMax','shadowExpire','shadowWarning','shadowInactive'); public $shadow_after_today_attrs = array('shadowMax','shadowExpire','shadowWarning','shadowInactive');
} }

View File

@ -56,7 +56,7 @@ class Template extends xmlTemplate {
# Template RDN attributes # Template RDN attributes
private $rdn; private $rdn;
public function __construct($server_id,$name=null,$filename=null,$type=null,$id=null) { public function __construct($server_id,$name='',$filename=null,$type=null,$id=null) {
parent::__construct($server_id,$name,$filename,$type,$id); parent::__construct($server_id,$name,$filename,$type,$id);
# If this is the default template, we might disable leafs by default. # If this is the default template, we might disable leafs by default.
@ -636,10 +636,13 @@ class Template extends xmlTemplate {
public function getDNEncode($url=true) { public function getDNEncode($url=true) {
// @todo Be nice to do all this in 1 location // @todo Be nice to do all this in 1 location
$dn = $this->getDN();
if (is_null($dn))
$dn = '';
if ($url) if ($url)
return urlencode(preg_replace('/%([0-9a-fA-F]+)/',"%25\\1",$this->getDN())); return urlencode(preg_replace('/%([0-9a-fA-F]+)/',"%25\\1",$dn));
else else
return preg_replace('/%([0-9a-fA-F]+)/',"%25\\1",$this->getDN()); return preg_replace('/%([0-9a-fA-F]+)/',"%25\\1",$dn);
} }
/** /**
@ -1123,10 +1126,11 @@ class Template extends xmlTemplate {
switch ($command) { switch ($command) {
/* /*
autoFill:string autoFill:string
string is a literal string, and may contain many fields like %attr|start-end/flags% string is a literal string, and may contain many fields like %attr|start-end/flags|additionalcontrolchar%
to substitute values read from other fields. to substitute values read from other fields.
|start-end is optional, but must be present if the k flag is used. |start-end is optional, but must be present if the k flag is used.
/flags is optional. /flags is optional.
|additionalcontrolchar is optional.
flags may be: flags may be:
T: Read display text from selection item (drop-down list), otherwise, read the value of the field T: Read display text from selection item (drop-down list), otherwise, read the value of the field
@ -1141,8 +1145,11 @@ class Template extends xmlTemplate {
The string read will be split into fields, using : as a delimiter The string read will be split into fields, using : as a delimiter
"start" indicates which field number to pass through. "start" indicates which field number to pass through.
K: The string read will be split into fields, using ' ' as a delimiter "start" indicates which field number to pass through. K: The string read will be split into fields, using ' ' as a delimiter "start" indicates which field number to pass through.
If additionalcontrolchar is given, it will be used as delimiter (e.g. this allows for splitting e-mail addresses
into domain and domain-local part).
l: Make the result lower case. l: Make the result lower case.
U: Make the result upper case. U: Make the result upper case.
A: Remap special characters to their corresponding ASCII value
*/ */
case 'autoFill': case 'autoFill':
if (! preg_match('/;/',$arg)) { if (! preg_match('/;/',$arg)) {
@ -1155,8 +1162,8 @@ class Template extends xmlTemplate {
} }
list($attr,$string) = preg_split('(([^,]+);(.*))',$arg,-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); list($attr,$string) = preg_split('(([^,]+);(.*))',$arg,-1,PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
preg_match_all('/%(\w+)(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?%/U',$string,$matchall); preg_match_all('/%(\w+)(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%/U',$string,$matchall);
//print"<PRE>";print_r($matchall); //0 = highlevel match, 1 = attr, 2 = subst, 3 = mod //print"<PRE>";print_r($matchall); //0 = highlevel match, 1 = attr, 2 = subst, 3 = mod, 4 = delimiter
if (! isset($attribute->js['autoFill'])) if (! isset($attribute->js['autoFill']))
$attribute->js['autoFill'] = ''; $attribute->js['autoFill'] = '';
@ -1183,6 +1190,7 @@ class Template extends xmlTemplate {
$match_attr = strtolower($matchall[1][$index]); $match_attr = strtolower($matchall[1][$index]);
$match_subst = $matchall[2][$index]; $match_subst = $matchall[2][$index];
$match_mod = $matchall[3][$index]; $match_mod = $matchall[3][$index];
$match_delim = $matchall[4][$index];
$substrarray = array(); $substrarray = array();
@ -1226,7 +1234,13 @@ class Template extends xmlTemplate {
} else { } else {
$tok_idx = '0'; $tok_idx = '0';
} }
$attribute->js['autoFill'] .= sprintf(" %s = %s.split(' ')[%s];\n",$match_attr,$match_attr,$tok_idx);
if ($match_delim == '') {
$delimiter = ' ';
} else {
$delimiter = preg_quote($match_delim);
}
$attribute->js['autoFill'] .= sprintf(" %s = %s.split('%s')[%s];\n",$match_attr,$match_attr,$delimiter,$tok_idx);
} else { } else {
preg_match_all('/([0-9]*)-([0-9]*)/',trim($match_subst),$substrarray); preg_match_all('/([0-9]*)-([0-9]*)/',trim($match_subst),$substrarray);
@ -1251,13 +1265,13 @@ class Template extends xmlTemplate {
# Matchfor only entry without modifiers. # Matchfor only entry without modifiers.
$formula = preg_replace('/^%('.$match_attr.')%$/U','$1 + \'\'',$formula); $formula = preg_replace('/^%('.$match_attr.')%$/U','$1 + \'\'',$formula);
# Matchfor only entry with modifiers. # Matchfor only entry with modifiers.
$formula = preg_replace('/^%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?%$/U','$1 + \'\'',$formula); $formula = preg_replace('/^%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%$/U','$1 + \'\'',$formula);
# Matchfor begining entry. # Matchfor begining entry.
$formula = preg_replace('/^%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?%/U','$1 + \'',$formula); $formula = preg_replace('/^%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%/U','$1 + \'',$formula);
# Matchfor ending entry. # Matchfor ending entry.
$formula = preg_replace('/%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?%$/U','\' + $1 ',$formula); $formula = preg_replace('/%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%$/U','\' + $1 ',$formula);
# Match for entries not at begin/end. # Match for entries not at begin/end.
$formula = preg_replace('/%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[:lTUA]+)?%/U','\' + $1 + \'',$formula); $formula = preg_replace('/%('.$match_attr.')(\|[0-9]*-[0-9]*)?(\/[KklTUA]+)?(?:\|(.))?%/U','\' + $1 + \'',$formula);
$attribute->js['autoFill'] .= "\n"; $attribute->js['autoFill'] .= "\n";
} }

View File

@ -139,16 +139,23 @@ class TemplateRender extends PageRender {
return; return;
} }
if (!empty($args[0]))
$function_args = explode(',',$args[0]); $function_args = explode(',',$args[0]);
else
$function_args = '';
if (function_exists($function)) if (function_exists($function)) {
if (empty($function_args))
$vals = call_user_func($function);
else
$vals = call_user_func_array($function,$function_args); $vals = call_user_func_array($function,$function_args);
else } else {
system_message(array( system_message(array(
'title'=>_('Function doesnt exist'), 'title'=>_('Function doesnt exist'),
'body'=>sprintf('%s (<b>%s</b>)',_('An attempt was made to call a function that doesnt exist'),$function), 'body'=>sprintf('%s (<b>%s</b>)',_('An attempt was made to call a function that doesnt exist'),$function),
'type'=>'warn')); 'type'=>'warn'));
}
break; break;
@ -264,6 +271,9 @@ class TemplateRender extends PageRender {
* *
* * arg 8 (for MultiList) * * arg 8 (for MultiList)
* - size of displayed list (default: 10 lines) * - size of displayed list (default: 10 lines)
*
* * arg 9
* - if whether to include parent in sub query TRUE|FALSE
*/ */
case 'MultiList': case 'MultiList':
case 'PickList': case 'PickList':
@ -322,6 +332,9 @@ class TemplateRender extends PageRender {
$vals = array(); $vals = array();
foreach ($picklistvalues as $key => $values) { foreach ($picklistvalues as $key => $values) {
if (! empty($args[9]) && $container == $key)
continue;
$display = $args[3]; $display = $args[3];
foreach ($matchall[1] as $key => $arg) { foreach ($matchall[1] as $key => $arg) {
@ -2143,7 +2156,7 @@ function fillRec(id,value) {
if ($attribute->isMultiple() && $i > 0) if ($attribute->isMultiple() && $i > 0)
return; return;
$val = $attribute->getValue($i); $val = $attribute->getValue($i, '');
if ($attribute->isVisible()) { if ($attribute->isVisible()) {
echo '<table cellspacing="0" cellpadding="0" width="100%" border="0"><tr><td class="icon" style="width: 25px;">'; echo '<table cellspacing="0" cellpadding="0" width="100%" border="0"><tr><td class="icon" style="width: 25px;">';

View File

@ -22,6 +22,15 @@ abstract class Visitor {
protected $server_id; protected $server_id;
public function __call($method,$args) { public function __call($method,$args) {
# This mapping array allows to map effective class names to
# function name suffixes.
# It has been introduced when class Attribute has been renamed
# to PLAAttribute to avoid a name clash with the built-in
# class of PHP 8.
# Entering a class name mapping here allows to rename the
# class without having to rename the methods too.
static $classmap = array('PLAAttribute' => 'Attribute');
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
@ -33,19 +42,14 @@ abstract class Visitor {
$fnct = array_shift($args); $fnct = array_shift($args);
$object = $args[0]; $object = $args[0];
$class = get_class($object);
$call = "$method$fnct$class";
for ($class = get_class($object); $class; $class = get_parent_class($class)) {
$call = isset($classmap[$class])? "$method$fnct$classmap[$class]": "$method$fnct$class";
array_push($methods,$call); array_push($methods,$call);
if (method_exists($this,$call))
while ($class && ! method_exists($this,$call)) { break;
if (defined('DEBUGTMP') && DEBUGTMP) if (defined('DEBUGTMP') && DEBUGTMP)
printf('<font size=-2><i>Class (%s): Method doesnt exist (%s,%s)</i></font><br />',$class,get_class($this),$call); printf('<font size=-2><i>Class (%s): Method doesnt exist (%s,%s)</i></font><br />',$class,get_class($this),$call);
$class = get_parent_class($class);
$call = "$method$fnct$class";
array_push($methods,$call);
} }
if (defined('DEBUGTMP') && DEBUGTMP) if (defined('DEBUGTMP') && DEBUGTMP)

View File

@ -315,7 +315,7 @@ class Horde_Cipher_blowfish {
$keyLen = count($key); $keyLen = count($key);
for ($i = 0; $i < $iMax; $i++) { for ($i = 0; $i < $iMax; $i++) {
for ($t = 0; $t < 4; $t++) { for ($t = 0; $t < 4; $t++) {
$keyXor = ($keyXor << 8) | (($key[$keyPos]) & 0x0ff); $keyXor = (($keyXor << 8) | (($key[$keyPos]) & 0x0ff)) & 0xFFFFFFFF;
if (++$keyPos == $keyLen) { if (++$keyPos == $keyLen) {
$keyPos = 0; $keyPos = 0;
} }
@ -389,6 +389,37 @@ class Horde_Cipher_blowfish {
return pack("NN", $parts['L'], $parts['R']); return pack("NN", $parts['L'], $parts['R']);
} }
/**
* Perform an encryption/decryption step.
*
* @param Int $x The bits source for the S tables indexing.
*
* @return Int The 32-bit step result.
*/
function _cryptStep($x)
{
if (PHP_INT_SIZE > 4)
return ((($this->s1[($x >> 24) & 0xFF] + $this->s2[($x >> 16) & 0xFF]) ^ $this->s3[($x >> 8) & 0xFF]) + $this->s4[$x & 0xFF]) & 0xFFFF;
/* For 32-bit machines, split values into 16-bit high and low parts
to avoid negative values and 32-bit overflows. */
$a = $this->s1[($x >> 24) & 0xFF];
$b = $this->s2[($x >> 16) & 0xFF];
$h = (($a >> 16) & 0xFFFF) + (($b >> 16) & 0xFFFF);
$l = ($a & 0xFFFF) + ($b & 0xFFFF);
if ($l & ~0xFFFF)
$h++;
$a = $this->s3[($x >> 8) & 0xFF];
$h ^= $a >> 16;
$l ^= $a;
$a = $this->s4[$x & 0xFF];
$h = ($h & 0xFFFF) + (($a >> 16) & 0xFFFF);
$l = ($l & 0xFFFF) + ($a & 0xFFFF);
if ($l & ~0xFFFF)
$h++;
return (($h & 0xFFFF) << 16) | ($l & 0xFFFF);
}
/** /**
* Encrypt a block on data. * Encrypt a block on data.
* *
@ -400,22 +431,22 @@ class Horde_Cipher_blowfish {
function _encryptBlock($L, $R) function _encryptBlock($L, $R)
{ {
$L ^= $this->p[0]; $L ^= $this->p[0];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[1]; $R ^= $this->_cryptStep($L) ^ $this->p[1];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[2]; $L ^= $this->_cryptStep($R) ^ $this->p[2];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[3]; $R ^= $this->_cryptStep($L) ^ $this->p[3];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[4]; $L ^= $this->_cryptStep($R) ^ $this->p[4];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[5]; $R ^= $this->_cryptStep($L) ^ $this->p[5];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[6]; $L ^= $this->_cryptStep($R) ^ $this->p[6];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[7]; $R ^= $this->_cryptStep($L) ^ $this->p[7];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[8]; $L ^= $this->_cryptStep($R) ^ $this->p[8];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[9]; $R ^= $this->_cryptStep($L) ^ $this->p[9];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[10]; $L ^= $this->_cryptStep($R) ^ $this->p[10];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[11]; $R ^= $this->_cryptStep($L) ^ $this->p[11];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[12]; $L ^= $this->_cryptStep($R) ^ $this->p[12];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[13]; $R ^= $this->_cryptStep($L) ^ $this->p[13];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[14]; $L ^= $this->_cryptStep($R) ^ $this->p[14];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[15]; $R ^= $this->_cryptStep($L) ^ $this->p[15];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[16]; $L ^= $this->_cryptStep($R) ^ $this->p[16];
$R ^= $this->p[17]; $R ^= $this->p[17];
return array('L' => $R, 'R' => $L); return array('L' => $R, 'R' => $L);
@ -445,23 +476,22 @@ class Horde_Cipher_blowfish {
list($L, $R) = array_values($unpack); list($L, $R) = array_values($unpack);
$L ^= $this->p[17]; $L ^= $this->p[17];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[16]; $R ^= $this->_cryptStep($L) ^ $this->p[16];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[15]; $L ^= $this->_cryptStep($R) ^ $this->p[15];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[14]; $R ^= $this->_cryptStep($L) ^ $this->p[14];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[13]; $L ^= $this->_cryptStep($R) ^ $this->p[13];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[12]; $R ^= $this->_cryptStep($L) ^ $this->p[12];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[11]; $L ^= $this->_cryptStep($R) ^ $this->p[11];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[10]; $R ^= $this->_cryptStep($L) ^ $this->p[10];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[9]; $L ^= $this->_cryptStep($R) ^ $this->p[9];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[8]; $R ^= $this->_cryptStep($L) ^ $this->p[8];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[7]; $L ^= $this->_cryptStep($R) ^ $this->p[7];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[6]; $R ^= $this->_cryptStep($L) ^ $this->p[6];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[5]; $L ^= $this->_cryptStep($R) ^ $this->p[5];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[4]; $R ^= $this->_cryptStep($L) ^ $this->p[4];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[3]; $L ^= $this->_cryptStep($R) ^ $this->p[3];
$R ^= ((($this->s1[($L >> 24) & 0xFF] + $this->s2[($L >> 16) & 0x0ff]) ^ $this->s3[($L >> 8) & 0x0ff]) + $this->s4[$L & 0x0ff]) ^ $this->p[2]; $R ^= $this->_cryptStep($L) ^ $this->p[2];
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[1]; $L ^= $this->_cryptStep($R) ^ $this->p[1];
$decrypted = pack("NN", $R ^ $this->p[0], $L); $decrypted = pack("NN", $R ^ $this->p[0], $L);
return $decrypted; return $decrypted;
} }

View File

@ -259,7 +259,7 @@ if ($app['language'] == 'auto') {
if ((substr($lang,0,2) == 'en') || if ((substr($lang,0,2) == 'en') ||
(file_exists($app['language_dir']) && is_readable($app['language_dir']))) { (file_exists($app['language_dir']) && is_readable($app['language_dir']))) {
if (extension_loaded('gettext')) {
# Set language # Set language
putenv('LANG='.$lang); # e.g. LANG=de_DE putenv('LANG='.$lang); # e.g. LANG=de_DE
$lang .= '.UTF-8'; $lang .= '.UTF-8';
@ -268,6 +268,7 @@ if ($app['language'] == 'auto') {
bind_textdomain_codeset('messages','UTF-8'); bind_textdomain_codeset('messages','UTF-8');
textdomain('messages'); textdomain('messages');
header('Content-type: text/html; charset=UTF-8',true); header('Content-type: text/html; charset=UTF-8',true);
}
break; break;
} }
} }
@ -296,7 +297,7 @@ if ($app['language'] == 'auto') {
* Strip slashes from GET, POST, and COOKIE variables if this * Strip slashes from GET, POST, and COOKIE variables if this
* PHP install is configured to automatically addslashes() * PHP install is configured to automatically addslashes()
*/ */
if (@get_magic_quotes_gpc() && (! isset($slashes_stripped) || ! $slashes_stripped)) { if ((! isset($slashes_stripped) || ! $slashes_stripped)) {
array_stripslashes($_REQUEST); array_stripslashes($_REQUEST);
array_stripslashes($_GET); array_stripslashes($_GET);
array_stripslashes($_POST); array_stripslashes($_POST);

View File

@ -8,7 +8,7 @@
*/ */
/** The minimum version of PHP required to run phpLDAPadmin. */ /** The minimum version of PHP required to run phpLDAPadmin. */
define('REQUIRED_PHP_VERSION','5.5.0'); define('REQUIRED_PHP_VERSION','7.0.0');
/** /**
* The config class contains all our configuration settings for a session. * The config class contains all our configuration settings for a session.
@ -261,6 +261,10 @@ class Config {
'desc'=>'LDAP search filter for the tree entries', 'desc'=>'LDAP search filter for the tree entries',
'default'=>'(objectClass=*)'); 'default'=>'(objectClass=*)');
$this->default->appearance['tree_icons'] = array(
'desc'=>'Number of Tree Icons to display on a row',
'default'=>0);
# PLA will not display the header and footer parts in minimal mode. # PLA will not display the header and footer parts in minimal mode.
$this->default->appearance['minimalMode'] = array( $this->default->appearance['minimalMode'] = array(
'desc'=>'Minimal mode hides header and footer parts', 'desc'=>'Minimal mode hides header and footer parts',
@ -500,7 +504,7 @@ class Config {
$this->default->session['memorylimit'] = array( $this->default->session['memorylimit'] = array(
'desc'=>'Set the PHP memorylimit warning threshold.', 'desc'=>'Set the PHP memorylimit warning threshold.',
'default'=>24); 'default'=>'24M');
$this->default->session['timelimit'] = array( $this->default->session['timelimit'] = array(
'desc'=>'Set the PHP timelimit.', 'desc'=>'Set the PHP timelimit.',
@ -550,6 +554,32 @@ class Config {
'desc'=>'Disable random salt for crypt()', 'desc'=>'Disable random salt for crypt()',
'default'=>false); 'default'=>false);
$this->default->password['available_types'] = array(
'desc'=>'List of available password types used for encryption',
'default'=>array(
''=>'clear',
'bcrypt'=>'bcrypt',
'blowfish'=>'blowfish',
'crypt'=>'crypt',
'ext_des'=>'ext_des',
'md5'=>'md5',
'k5key'=>'k5key',
'md5crypt'=>'md5crypt',
'sha'=>'sha',
'smd5'=>'smd5',
'ssha'=>'ssha',
'sha256'=>'sha256',
'ssha256'=>'ssha256',
'sha384'=>'sha384',
'ssha384'=>'ssha384',
'sha512'=>'sha512',
'ssha512'=>'ssha512',
'sha256crypt'=>'sha256crypt',
'sha512crypt'=>'sha512crypt',
'argon2i'=>'argon2i',
'argon2id'=>'argon2id',
));
/** Search display /** Search display
* By default, when searching you may display a list or a table of results. * By default, when searching you may display a list or a table of results.
* Set this to 'table' to see table formatted results. * Set this to 'table' to see table formatted results.

View File

@ -284,8 +284,8 @@ private $sbox = array(array(array(14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12
$key2 = $this->str_to_key($key); $key2 = $this->str_to_key($key);
for ($i = 0; $i < 64; $i++) { for ($i = 0; $i < 64; $i++) {
$inb[$i] = ($in[$i/8] & (1<<(7-($i%8)))) ? 1:0; $inb[$i] = ($in[intdiv($i, 8)] & (1<<(7-($i%8)))) ? 1:0;
$keyb[$i] = ($key2[$i/8] & (1<<(7-($i%8)))) ? 1:0; $keyb[$i] = ($key2[intdiv($i, 8)] & (1<<(7-($i%8)))) ? 1:0;
$outb[$i] = 0; $outb[$i] = 0;
} }
$outb = $this->doHash($inb, $keyb, $forw); $outb = $this->doHash($inb, $keyb, $forw);
@ -294,7 +294,7 @@ private $sbox = array(array(array(14, 4, 13, 1, 2, 15, 11, 8, 3, 10, 6, 12
} }
for ($i = 0; $i < 64; $i++) { for ($i = 0; $i < 64; $i++) {
if ( $outb[$i] ) { if ( $outb[$i] ) {
$out[$i/8] |= (1<<(7-($i%8))); $out[intdiv($i, 8)] |= (1<<(7-($i%8)));
} }
} }
return $out; return $out;

View File

@ -139,6 +139,7 @@ abstract class DS {
case 'proxy': case 'proxy':
case 'session': case 'session':
case 'sasl': case 'sasl':
case 'sasl_external':
return $this->getValue('login','auth_type'); return $this->getValue('login','auth_type');
default: default:
@ -194,6 +195,8 @@ abstract class DS {
else else
return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['name']); return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['name']);
case 'sasl_external':
return 'external';
default: default:
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType())); die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
} }
@ -215,6 +218,7 @@ abstract class DS {
return true; return true;
case 'config': case 'config':
case 'sasl_external':
return true; return true;
case 'proxy': case 'proxy':
@ -274,6 +278,8 @@ abstract class DS {
else else
return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['pass']); return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['pass']);
case 'sasl_external':
return '';
default: default:
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType())); die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
} }
@ -400,6 +406,7 @@ abstract class DS {
set_cookie($method.'-PASS','',time()-3600,'/'); set_cookie($method.'-PASS','',time()-3600,'/');
case 'config': case 'config':
case 'sasl_external':
return true; return true;
case 'http': case 'http':
@ -430,7 +437,8 @@ abstract class DS {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! trim($this->getLogin(null)) && $_SESSION[APPCONFIG]->getValue('appearance','anonymous_bind_implies_read_only')) $login = $this->getLogin(null);
if (!($login && trim($login)) && $_SESSION[APPCONFIG]->getValue('appearance','anonymous_bind_implies_read_only'))
return true; return true;
else else
return $this->getValue('server','read_only'); return $this->getValue('server','read_only');

View File

@ -54,6 +54,22 @@ class ldap extends DS {
'desc'=>'Connect using TLS', 'desc'=>'Connect using TLS',
'default'=>false); 'default'=>false);
$this->default->server['tls_cacert'] = array(
'desc'=>'TLS Certificate Authority',
'default'=>null);
$this->default->server['tls_cacertdir'] = array(
'desc'=>'TLS Certificate Authority Directory',
'default'=>null);
$this->default->server['tls_cert'] = array(
'desc'=>'TLS Client Certificate',
'default'=>null);
$this->default->server['tls_key'] = array(
'desc'=>'TLS Client Certificate Key',
'default'=>null);
# Login Details # Login Details
$this->default->login['attr'] = array( $this->default->login['attr'] = array(
'desc'=>'Attribute to use to find the users DN', 'desc'=>'Attribute to use to find the users DN',
@ -110,6 +126,35 @@ class ldap extends DS {
'default'=>null); 'default'=>null);
} }
/**
* Set LDAP option with error checking...
*
* @param resource Connection resource
* @param string Name of option to set
* @param mixed Option value
* @return boolean false if error
*/
private function setLdapOption($resource, $option, $value) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',16,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! defined($option)) {
system_message(array(
'title'=>sprintf('%s',_('Undefined LDAP option')),
'body'=>sprintf('<b>%s</b>: %s <b>%s</b>',_('Error'),_('Required LDAP option not defined'),$option),
'type'=>'error'));
return false;
}
if (! @ldap_set_option($resource,constant($option),$value)) {
system_message(array(
'title'=>sprintf('%s',_('Failed to set LDAP option')),
'body'=>sprintf('<b>%s</b>: %s <b>%s</b>',_('Error'),_('Failed to set LDAP option'),$option),
'type'=>'error'));
return false;
}
return true;
}
/** /**
* Required ABSTRACT functions * Required ABSTRACT functions
*/ */
@ -164,22 +209,25 @@ class ldap extends DS {
else else
$resource = ldap_connect($this->getValue('server','host')); $resource = ldap_connect($this->getValue('server','host'));
$this->noconnect = false;
$CACHE[$this->index][$method] = $resource; $CACHE[$this->index][$method] = $resource;
if (DEBUG_ENABLED) if (DEBUG_ENABLED)
debug_log('LDAP Resource [%s], Host [%s], Port [%s]',16,0,__FILE__,__LINE__,__METHOD__, debug_log('LDAP Resource [%s], Host [%s], Port [%s]',16,0,__FILE__,__LINE__,__METHOD__,
$resource,$this->getValue('server','host'),$this->getValue('server','port')); $resource,$this->getValue('server','host'),$this->getValue('server','port'));
if (! is_resource($resource)) if (!$resource)
debug_dump_backtrace('UNHANDLED, $resource is not a resource',1); debug_dump_backtrace('UNHANDLED, $resource is not a resource',1);
# Go with LDAP version 3 if possible (needed for renaming and Novell schema fetching) # Go with LDAP version 3 if possible (needed for renaming and Novell schema fetching)
ldap_set_option($resource,LDAP_OPT_PROTOCOL_VERSION,3); if (! $this->setLdapOption($resource,'LDAP_OPT_PROTOCOL_VERSION',3))
$this->noconnect = true;
/* Disabling this makes it possible to browse the tree for Active Directory, and seems /* Disabling this makes it possible to browse the tree for Active Directory, and seems
* to not affect other LDAP servers (tested with OpenLDAP) as phpLDAPadmin explicitly * to not affect other LDAP servers (tested with OpenLDAP) as phpLDAPadmin explicitly
* specifies deref behavior for each ldap_search operation. */ * specifies deref behavior for each ldap_search operation. */
ldap_set_option($resource,LDAP_OPT_REFERRALS,0); elseif (! $this->setLdapOption($resource,'LDAP_OPT_REFERRALS',0))
$this->noconnect = true;
/* Enabling manageDsaIt to be able to browse through glued entries /* Enabling manageDsaIt to be able to browse through glued entries
* 2.16.840.1.113730.3.4.2 : "ManageDsaIT Control" "RFC 3296" "The client may provide * 2.16.840.1.113730.3.4.2 : "ManageDsaIT Control" "RFC 3296" "The client may provide
@ -187,14 +235,18 @@ class ldap extends DS {
* to manage objects within the DSA (server) Information Tree. The control causes * to manage objects within the DSA (server) Information Tree. The control causes
* Directory-specific entries (DSEs), regardless of type, to be treated as normal entries * Directory-specific entries (DSEs), regardless of type, to be treated as normal entries
* allowing clients to interrogate and update these entries using LDAP operations." */ * allowing clients to interrogate and update these entries using LDAP operations." */
ldap_set_option($resource,LDAP_OPT_SERVER_CONTROLS,array(array('oid'=>'2.16.840.1.113730.3.4.2'))); elseif (! $this->setLdapOption($resource,'LDAP_OPT_SERVER_CONTROLS',array(array('oid'=>'2.16.840.1.113730.3.4.2'))))
$this->noconnect = true;
# Try to fire up TLS is specified in the config # Try to fire up TLS is specified in the config
if ($this->isTLSEnabled()) if ($this->isTLSEnabled() && !$this->noconnect)
$this->startTLS($resource); if(! $this->startTLS($resource))
$this->noconnect = true;
# If SASL has been configured for binding, then start it now. # If SASL has been configured for binding, then start it now.
if ($this->isSASLEnabled()) if ($this->noconnect)
$bind['result'] = false;
elseif ($this->isSASLEnabled())
$bind['result'] = $this->startSASL($resource,$method,$bind['id'],$bind['pass']); $bind['result'] = $this->startSASL($resource,$method,$bind['id'],$bind['pass']);
# Normal bind... # Normal bind...
@ -211,17 +263,16 @@ class ldap extends DS {
if (DEBUG_ENABLED) if (DEBUG_ENABLED)
debug_log('Leaving with FALSE, bind FAILed',16,0,__FILE__,__LINE__,__METHOD__); debug_log('Leaving with FALSE, bind FAILed',16,0,__FILE__,__LINE__,__METHOD__);
if (! $this->noconnect) {
$this->noconnect = true; $this->noconnect = true;
system_message(array( system_message(array(
'title'=>sprintf('%s %s',_('Unable to connect to LDAP server'),$this->getName()), 'title'=>sprintf('%s %s',_('Unable to connect to LDAP server'),$this->getName()),
'body'=>sprintf('<b>%s</b>: %s (%s) for <b>%s</b>',_('Error'),$this->getErrorMessage($method),$this->getErrorNum($method),$method), 'body'=>sprintf('<b>%s</b>: %s (%s) for <b>%s</b>',_('Error'),$this->getErrorMessage($method),$this->getErrorNum($method),$method),
'type'=>'error')); 'type'=>'error'));
}
$CACHE[$this->index][$method] = null; $CACHE[$this->index][$method] = null;
} else { } else {
$this->noconnect = false;
# If this is a proxy session, we need to switch to the proxy user # If this is a proxy session, we need to switch to the proxy user
if ($this->isProxyEnabled() && $bind['id'] && $method != 'anon') if ($this->isProxyEnabled() && $bind['id'] && $method != 'anon')
@ -286,7 +337,7 @@ class ldap extends DS {
$connect = $this->connect($method,false,$new); $connect = $this->connect($method,false,$new);
# If we didnt log in... # If we didnt log in...
if (! is_resource($connect) || $this->noconnect || ! $this->userIsAllowedLogin($userDN)) { if (!$connect || $this->noconnect || ! $this->userIsAllowedLogin($userDN)) {
$this->logout($method); $this->logout($method);
return false; return false;
@ -359,8 +410,10 @@ class ldap extends DS {
if ($debug) if ($debug)
debug_dump(array('query'=>$query,'server'=>$this->getIndex(),'con'=>$this->connect($method))); debug_dump(array('query'=>$query,'server'=>$this->getIndex(),'con'=>$this->connect($method)));
$search = null;
$resource = $this->connect($method,$debug); $resource = $this->connect($method,$debug);
if ($resource)
switch ($query['scope']) { switch ($query['scope']) {
case 'base': case 'base':
$search = @ldap_read($resource,$query['base'],$query['filter'],$query['attrs'],$attrs_only,$query['size_limit'],$query['time_limit'],$query['deref']); $search = @ldap_read($resource,$query['base'],$query['filter'],$query['attrs'],$attrs_only,$query['size_limit'],$query['time_limit'],$query['deref']);
@ -570,10 +623,41 @@ class ldap extends DS {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! $this->getValue('server','tls') || (function_exists('ldap_start_tls') && ! @ldap_start_tls($resource))) { // LDAP_OPT_X_TLS_ options must be set globally ($res = null)
// until LDAP_OPT_X_TLS_NEWCTX is exported,
// NOTE: new values will require php-fpm or other stateful
// php servers to be restarted, and are global for all php
// users in the process pool!
$val = $this->getValue('server','tls_cacert');
if (! empty($val))
if (! $this->setLdapOption(null, 'LDAP_OPT_X_TLS_CACERTFILE', $val))
return false;
$val = $this->getValue('server','tls_cacertdir');
if (! empty($val))
if (! $this->setLdapOption(null, 'LDAP_OPT_X_TLS_CACERTDIR', $val))
return false;
$val = $this->getValue('server','tls_cert');
if (! empty($val))
if (! $this->setLdapOption(null, 'LDAP_OPT_X_TLS_CERTFILE', $val))
return false;
$val = $this->getValue('server','tls_key');
if (! empty($val))
if (! $this->setLdapOption(null, 'LDAP_OPT_X_TLS_KEYFILE', $val))
return false;
if (! @ldap_start_tls($resource)) {
$diag_error='';
ldap_get_option($resource, LDAP_OPT_DIAGNOSTIC_MESSAGE, $diag_error);
if (! empty($diag_error)) {
$diag_error = '<br>'.$diag_error;
}
$error = ldap_error($resource);
system_message(array( system_message(array(
'title'=>sprintf('%s (%s)',_('Could not start TLS.'),$this->getName()), 'title'=>sprintf('%s (%s)',_('Could not start TLS.'),$this->getName()),
'body'=>sprintf('<b>%s</b>: %s',_('Error'),_('Could not start TLS. Please check your LDAP server configuration.')), 'body'=>sprintf('<b>%s</b>: %s %s%s',_('Error'),_('Could not start TLS.'),$error,$diag_error),
'type'=>'error')); 'type'=>'error'));
return false; return false;
@ -590,6 +674,8 @@ class ldap extends DS {
* $servers->setValue('login','auth_type','sasl'); * $servers->setValue('login','auth_type','sasl');
* OR * OR
* $servers->setValue('sasl','mech','PLAIN'); * $servers->setValue('sasl','mech','PLAIN');
* OR
* $servers->setValue('login','auth_type','sasl_external');
* </code> * </code>
* *
* @return boolean * @return boolean
@ -598,7 +684,7 @@ class ldap extends DS {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (! in_array($this->getValue('login','auth_type'), array('sasl'))) { if (! in_array($this->getValue('login','auth_type'), array('sasl','sasl_external'))) {
// check if SASL mech uses login from other auth_types // check if SASL mech uses login from other auth_types
if (! in_array(strtolower($this->getValue('sasl', 'mech')), array('plain'))) if (! in_array(strtolower($this->getValue('sasl', 'mech')), array('plain')))
return false; return false;
@ -630,6 +716,13 @@ class ldap extends DS {
if ($method == 'anon') if ($method == 'anon')
return false; return false;
# EXTERNAL mech is really a different authType
if ($this->getAuthType() == 'sasl_external') {
return @ldap_sasl_bind($resource,NULL,NULL,
'EXTERNAL',NULL,NULL,
$this->getValue('sasl','props'));
}
# At the moment, we have only implemented GSSAPI and PLAIN # At the moment, we have only implemented GSSAPI and PLAIN
if (! in_array(strtolower($this->getValue('sasl','mech')),array('gssapi','plain'))) { if (! in_array(strtolower($this->getValue('sasl','mech')),array('gssapi','plain'))) {
system_message(array( system_message(array(
@ -783,7 +876,7 @@ class ldap extends DS {
'value'=>sprintf('dn:%s',$dn), 'value'=>sprintf('dn:%s',$dn),
'iscritical' => true); 'iscritical' => true);
if (! ldap_set_option($resource,LDAP_OPT_SERVER_CONTROLS,array($ctrl))) { if (! @ldap_set_option($resource,LDAP_OPT_SERVER_CONTROLS,array($ctrl))) {
system_message(array( system_message(array(
'title'=>sprintf('%s %s',_('Unable to start proxy connection'),$this->getName()), 'title'=>sprintf('%s %s',_('Unable to start proxy connection'),$this->getName()),
'body'=>sprintf('<b>%s</b>: %s (%s) for <b>%s</b>',_('Error'),$this->getErrorMessage($method),$this->getErrorNum($method),$method), 'body'=>sprintf('<b>%s</b>: %s (%s) for <b>%s</b>',_('Error'),$this->getErrorMessage($method),$this->getErrorNum($method),$method),
@ -939,7 +1032,7 @@ class ldap extends DS {
$dn = $this->getContainer($dn); $dn = $this->getContainer($dn);
if ($dn == $top) if ($dn == $top)
break; continue;
} elseif($value) } elseif($value)
$dn = sprintf('%s,%s',$value,$dn); $dn = sprintf('%s,%s',$value,$dn);
@ -1146,12 +1239,12 @@ class ldap extends DS {
if (is_array($dn)) { if (is_array($dn)) {
$a = array(); $a = array();
foreach ($dn as $key => $rdn) { foreach ($dn as $key => $rdn) {
$a[$key] = preg_replace_callback('/\\\([0-9A-Fa-f]{2})/', function($m) { return chr(hexdec('${m[1]}')); }, $rdn); $a[$key] = preg_replace_callback('/\\\([0-9A-Fa-f]{2})/', function($m) { return chr(hexdec($m[1])); }, $rdn);
} }
return $a; return $a;
} else { } else {
return preg_replace_callback('/\\\([0-9A-Fa-f]{2})/', function($m) { return chr(hexdec('${m[1]}')); }, $dn); return preg_replace_callback('/\\\([0-9A-Fa-f]{2})/', function($m) { return chr(hexdec($m[1])); }, $dn);
} }
} }
@ -1197,7 +1290,7 @@ class ldap extends DS {
$search = @ldap_read($this->connect($method),$dn,'objectclass=*',array('subschemaSubentry'),false,0,10,LDAP_DEREF_NEVER); $search = @ldap_read($this->connect($method),$dn,'objectclass=*',array('subschemaSubentry'),false,0,10,LDAP_DEREF_NEVER);
if (DEBUG_ENABLED) if (DEBUG_ENABLED)
debug_log('Search returned (%s)',24,0,__FILE__,__LINE__,__METHOD__,is_resource($search)); debug_log('Search returned (%s)',24,0,__FILE__,__LINE__,__METHOD__,!!$search);
# Fix for broken ldap.conf configuration. # Fix for broken ldap.conf configuration.
if (! $search && ! $dn) { if (! $search && ! $dn) {
@ -1210,7 +1303,7 @@ class ldap extends DS {
if (DEBUG_ENABLED) if (DEBUG_ENABLED)
debug_log('Search returned (%s) for base (%s)',24,0,__FILE__,__LINE__,__METHOD__, debug_log('Search returned (%s) for base (%s)',24,0,__FILE__,__LINE__,__METHOD__,
is_resource($search),$base); !!$search,$base);
if ($search) if ($search)
break; break;
@ -2225,7 +2318,7 @@ class ldap extends DS {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',17,0,__FILE__,__LINE__,__METHOD__,$fargs);
$type = ($sattr = $this->getSchemaAttribute($attr_name)) ? $sattr->getType() : null; $type = ($sattr = $this->getSchemaAttribute($attr_name)) ? $sattr->getType() : '';
if (! strcasecmp('boolean',$type) || if (! strcasecmp('boolean',$type) ||
! strcasecmp('isCriticalSystemObject',$attr_name) || ! strcasecmp('isCriticalSystemObject',$attr_name) ||
@ -2290,8 +2383,8 @@ class ldap extends DS {
/* Strangely, some attributeTypes may not show up in the server /* Strangely, some attributeTypes may not show up in the server
* schema. This behavior has been observed in MS Active Directory.*/ * schema. This behavior has been observed in MS Active Directory.*/
$type = null; $type = '';
$syntax = null; $syntax = '';
} else { } else {
$type = $sattr->getType(); $type = $sattr->getType();

View File

@ -599,10 +599,16 @@ class ldap_pla extends ldap {
# Build our search filter to double check each attribute. # Build our search filter to double check each attribute.
$query['filter'] = '(|'; $query['filter'] = '(|';
foreach ($checkattrs as $attr) foreach ($checkattrs as $attr) {
if (!is_array($attrs[$attr])) {
$val = $attrs[$attr];
$query['filter'] .= sprintf('(%s=%s)',$attr,$val);
continue;
}
foreach ($attrs[$attr] as $val) foreach ($attrs[$attr] as $val)
if ($val) if ($val)
$query['filter'] .= sprintf('(%s=%s)',$attr,$val); $query['filter'] .= sprintf('(%s=%s)',$attr,$val);
}
$query['filter'] .= ')'; $query['filter'] .= ')';
$query['attrs'] = $checkattrs; $query['attrs'] = $checkattrs;

View File

@ -125,7 +125,7 @@ abstract class Export {
$query = array(); $query = array();
$base = get_request('dn','REQUEST'); $base = get_request('dn','REQUEST');
$query['baseok'] = true; $query['baseok'] = true;
$query['filter'] = get_request('filter','REQUEST',false,'objectclass=*'); $query['filter'] = get_request('filter','REQUEST',false,'objectclass=*',false);
$query['scope'] = get_request('scope','REQUEST',false,'base'); $query['scope'] = get_request('scope','REQUEST',false,'base');
$query['deref'] = $_SESSION[APPCONFIG]->getValue('deref','export'); $query['deref'] = $_SESSION[APPCONFIG]->getValue('deref','export');
$query['size_limit'] = 0; $query['size_limit'] = 0;

View File

@ -21,6 +21,7 @@ define('TMPLDIR',sprintf('%s/',realpath(LIBDIR.'../templates/')));
define('DOCDIR',sprintf('%s/',realpath(LIBDIR.'../doc/'))); define('DOCDIR',sprintf('%s/',realpath(LIBDIR.'../doc/')));
define('HOOKSDIR',sprintf('%s/',realpath(LIBDIR.'../hooks/'))); define('HOOKSDIR',sprintf('%s/',realpath(LIBDIR.'../hooks/')));
define('JSDIR','js/'); define('JSDIR','js/');
define('SESSION_CIPHER','aes-256-gcm');
/** /**
* Supplimental functions * Supplimental functions
@ -82,7 +83,7 @@ function array_stripslashes(&$array) {
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (is_array($array)) if (is_array($array))
while (list($key) = each($array)) foreach ($array as $key => $values)
if (is_array($array[$key]) && $key != $array) if (is_array($array[$key]) && $key != $array)
array_stripslashes($array[$key]); array_stripslashes($array[$key]);
else else
@ -130,12 +131,13 @@ function app_error_handler($errno,$errstr,$file,$lineno) {
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
/** /**
* error_reporting will be 0 if the error context occurred * error_reporting will be only the non-ignorable error number bits
* within a function call with '@' preprended (ie, @ldap_bind() ); * if the error context occurred within a function call with '@'
* preprended (ie, @ldap_bind() );
* So, don't report errors if the caller has specifically * So, don't report errors if the caller has specifically
* disabled them with '@' * disabled them with '@'
*/ */
if (ini_get('error_reporting') == 0 || error_reporting() == 0) if (!(ini_get('error_reporting') & error_reporting() & $errno))
return; return;
$file = basename($file); $file = basename($file);
@ -331,16 +333,38 @@ function check_config($config_file) {
$config->setServers($servers); $config->setServers($servers);
# Check the memory limit parameter. # Check the memory limit parameter.
if ((ini_get('memory_limit') > -1) && ini_get('memory_limit') < $config->getValue('session','memorylimit')) $limit = memory_str_to_int(ini_get('memory_limit'));
if ($limit != -1) {
$threshold = memory_str_to_int($config->getValue('session','memorylimit'));
if ($limit < $threshold) {
system_message(array( system_message(array(
'title'=>_('Memory Limit low.'), 'title' => _('Memory Limit low.'),
'body'=>sprintf('Your php memory limit is low - currently %s, you should increase it to atleast %s. This is normally controlled in /etc/php.ini.', 'body' => sprintf('Your php memory limit is low - currently %s (%s), you should increase it to atleast %s (%s). This is normally controlled in /etc/php.ini.',
ini_get('memory_limit'),$config->getValue('session','memorylimit')), ini_get('memory_limit'), $limit, $config->getValue('session','memorylimit'), $threshold),
'type'=>'error')); 'type'=>'error'
));
}
}
return $config; return $config;
} }
/**
* Converts shorthand memory notation string to an integer that represents the
* given amount in bytes (ie. "128M" -> 134217728).
*
* @param string|int $value
* @return int
*/
function memory_str_to_int($value) {
$value = trim(strtolower($value));
if (intval($value) > 0 && preg_match('/^(\d+)([kmg])?$/', $value, $match, PREG_UNMATCHED_AS_NULL)) {
[$int, $mod] = [intval($match[1]), $match[2]];
$pow = [NULL => 0, 'k' => 1, 'm' => 2, 'g' => 3][$mod];
return $int * 1024 ** $pow;
}
return intval($value);
}
/** /**
* Commands available in the control_panel of the page * Commands available in the control_panel of the page
* *
@ -768,9 +792,11 @@ function blowfish_encrypt($data,$secret=null) {
if (! trim($secret)) if (! trim($secret))
return $data; return $data;
if (! empty($data) && function_exists('openssl_encrypt') && in_array('bf-ecb', openssl_get_cipher_methods())) { if (! empty($data) && function_exists('openssl_encrypt') && in_array(SESSION_CIPHER, openssl_get_cipher_methods())) {
$keylen = openssl_cipher_iv_length('bf-ecb') * 2; $iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(SESSION_CIPHER));
return openssl_encrypt($data, 'bf-ecb', substr($secret,0,$keylen)); $keylen = openssl_cipher_iv_length(SESSION_CIPHER) * 2;
$encrypted = openssl_encrypt($data, SESSION_CIPHER, substr($secret,0,$keylen), $options=0, $iv, $tag);
return base64_encode($encrypted . '::' . $iv . '::' . $tag);
} }
if (function_exists('mcrypt_module_open') && ! empty($data)) { if (function_exists('mcrypt_module_open') && ! empty($data)) {
@ -829,9 +855,10 @@ function blowfish_decrypt($encdata,$secret=null) {
if (! trim($secret)) if (! trim($secret))
return $encdata; return $encdata;
if (! empty($encdata) && function_exists('openssl_encrypt') && in_array('bf-ecb', openssl_get_cipher_methods())) { if (! empty($encdata) && function_exists('openssl_encrypt') && in_array(SESSION_CIPHER, openssl_get_cipher_methods())) {
$keylen = openssl_cipher_iv_length('bf-ecb') * 2; $keylen = openssl_cipher_iv_length(SESSION_CIPHER) * 2;
return trim(openssl_decrypt($encdata, 'bf-ecb', substr($secret,0,$keylen))); list($encryptedData, $iv, $tag) = explode('::', base64_decode($encdata), 3);
return trim(openssl_decrypt($encryptedData, SESSION_CIPHER, substr($secret,0,$keylen), $options=0, $iv, $tag));
} }
if (function_exists('mcrypt_module_open') && ! empty($encdata)) { if (function_exists('mcrypt_module_open') && ! empty($encdata)) {
@ -928,7 +955,7 @@ function get_cached_item($index,$item,$subitem='null') {
* *
* Returns true on success of false on failure. * Returns true on success of false on failure.
*/ */
function set_cached_item($index,$item,$subitem='null',$data) { function set_cached_item($index,$item,$subitem,$data) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
@ -1269,6 +1296,9 @@ function is_mail_string($str) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (is_null($str))
return false;
$mail_regex = "/^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*$/"; $mail_regex = "/^[_A-Za-z0-9-]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9-]+)*$/";
if (preg_match($mail_regex,$str)) if (preg_match($mail_regex,$str))
@ -1287,6 +1317,9 @@ function is_url_string($str) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
if (is_null($str))
return false;
$url_regex = '/^(ftp|https?):\/\/+[\w\.\-\/\?\=\&]*\w+/'; $url_regex = '/^(ftp|https?):\/\/+[\w\.\-\/\?\=\&]*\w+/';
if (preg_match($url_regex,$str)) if (preg_match($url_regex,$str))
@ -1828,15 +1861,9 @@ function random_salt($length) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
$possible = '0123456789'. $str = bin2hex(random_bytes(ceil($length/2)));
'abcdefghijklmnopqrstuvwxyz'. if ($length % 2 == 1)
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'. return substr($str, 0, -1);
'./';
$str = '';
mt_srand((double)microtime() * 1000000);
while (strlen($str) < $length)
$str .= substr($possible,(rand()%strlen($possible)),1);
return $str; return $str;
} }
@ -2052,7 +2079,7 @@ function ldap_error_msg($msg,$errnum) {
* @param array Specifies optional image and CSS style attributes for the table tag. Supported keys are * @param array Specifies optional image and CSS style attributes for the table tag. Supported keys are
* fixed_width, fixed_height, img_opts. * fixed_width, fixed_height, img_opts.
*/ */
function draw_jpeg_photo($server,$dn,$attr_name='jpegphoto',$index,$draw_delete_buttons=false,$options=array()) { function draw_jpeg_photo($server,$dn,$attr_name,$index,$draw_delete_buttons=false,$options=array()) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
@ -2154,22 +2181,7 @@ function password_types() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
return array( return $_SESSION[APPCONFIG]->getValue('password', 'available_types');
''=>'clear',
'bcrypt'=>'bcrypt',
'blowfish'=>'blowfish',
'crypt'=>'crypt',
'ext_des'=>'ext_des',
'md5'=>'md5',
'k5key'=>'k5key',
'md5crypt'=>'md5crypt',
'sha'=>'sha',
'smd5'=>'smd5',
'ssha'=>'ssha',
'sha512'=>'sha512',
'sha256crypt'=>'sha256crypt',
'sha512crypt'=>'sha512crypt',
);
} }
/** /**
@ -2225,7 +2237,7 @@ function pla_password_hash($password_clear,$enc_type) {
break; break;
case 'md5': case 'md5':
$new_value = sprintf('{MD5}%s',base64_encode(pack('H*',md5($password_clear)))); $new_value = sprintf('{MD5}%s',base64_encode(md5($password_clear, true)));
break; break;
case 'md5crypt': case 'md5crypt':
@ -2237,25 +2249,13 @@ function pla_password_hash($password_clear,$enc_type) {
break; break;
case 'sha': case 'sha':
# Use php 4.3.0+ sha1 function, if it is available. $new_value = sprintf('{SHA}%s',base64_encode(sha1($password_clear, true)));
if (function_exists('sha1'))
$new_value = sprintf('{SHA}%s',base64_encode(pack('H*',sha1($password_clear))));
elseif (function_exists('mhash'))
$new_value = sprintf('{SHA}%s',base64_encode(mhash(MHASH_SHA1,$password_clear)));
else
error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php');
break; break;
case 'ssha': case 'ssha':
if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) { $salt = hex2bin(random_salt(8));
mt_srand((double)microtime()*1000000); $new_value = sprintf('{SSHA}%s',base64_encode(sha1($password_clear.$salt, true).$salt));
$salt = mhash_keygen_s2k(MHASH_SHA1,$password_clear,substr(pack('h*',md5(mt_rand())),0,8),4);
$new_value = sprintf('{SSHA}%s',base64_encode(mhash(MHASH_SHA1,$password_clear.$salt).$salt));
} else {
error(_('Your PHP install does not have the mhash() or mhash_keygen_s2k() function. Cannot do S2K hashes.'),'error','index.php');
}
break; break;
@ -2273,24 +2273,41 @@ function pla_password_hash($password_clear,$enc_type) {
case 'smd5': case 'smd5':
if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) { $salt = hex2bin(random_salt(8));
mt_srand((double)microtime()*1000000); $new_value = sprintf('{SMD5}%s',base64_encode(md5($password_clear.$salt, true).$salt));
$salt = mhash_keygen_s2k(MHASH_MD5,$password_clear,substr(pack('h*',md5(mt_rand())),0,8),4);
$new_value = sprintf('{SMD5}%s',base64_encode(mhash(MHASH_MD5,$password_clear.$salt).$salt));
} else { break;
error(_('Your PHP install does not have the mhash() or mhash_keygen_s2k() function. Cannot do S2K hashes.'),'error','index.php');
} case 'sha256':
$new_value = sprintf('{SHA256}%s', base64_encode(hash('sha256', $password_clear, true)));
break;
case 'ssha256':
$salt = hex2bin(random_salt(8));
$new_value = sprintf('{SSHA256}%s', base64_encode(hash('sha256', $password_clear.$salt, true).$salt));
break;
case 'sha384':
$new_value = sprintf('{SHA384}%s', base64_encode(hash('sha384', $password_clear, true)));
break;
case 'ssha384':
$salt = hex2bin(random_salt(8));
$new_value = sprintf('{SSHA384}%s', base64_encode(hash('sha384', $password_clear.$salt, true).$salt));
break; break;
case 'sha512': case 'sha512':
if (function_exists('openssl_digest') && function_exists('base64_encode')) { $new_value = sprintf('{SHA512}%s', base64_encode(hash('sha512', $password_clear, true)));
$new_value = sprintf('{SHA512}%s', base64_encode(openssl_digest($password_clear, 'sha512', true)));
} else { break;
error(_('Your PHP install doest not have the openssl_digest() or base64_encode() function. Cannot do SHA512 hashes. '),'error','index.php');
} case 'ssha512':
$salt = hex2bin(random_salt(8));
$new_value = sprintf('{SSHA512}%s', base64_encode(hash('sha512', $password_clear.$salt, true).$salt));
break; break;
@ -2308,6 +2325,20 @@ function pla_password_hash($password_clear,$enc_type) {
break; break;
case 'argon2i':
if (! defined('PASSWORD_ARGON2I'))
error(_('Your system does not support argon2i encryption (PHP 7.2 or upper is required).'),'error','index.php');
$new_value = sprintf('{ARGON2}%s',password_hash($password_clear,PASSWORD_ARGON2I));
break;
case 'argon2id':
if (! defined('PASSWORD_ARGON2ID'))
error(_('Your system does not support argon2id encryption (PHP 7.3 or upper is required).'),'error','index.php');
$new_value = sprintf('{ARGON2}%s',password_hash($password_clear,PASSWORD_ARGON2ID));
break;
case 'clear': case 'clear':
default: default:
$new_value = $password_clear; $new_value = $password_clear;
@ -2360,23 +2391,17 @@ function password_check($cryptedpassword,$plainpassword,$attribute='userpassword
switch($cypher) { switch($cypher) {
# SSHA crypted passwords # SSHA crypted passwords
case 'ssha': case 'ssha':
# Check php mhash support before using it
if (function_exists('mhash')) {
$hash = base64_decode($cryptedpassword); $hash = base64_decode($cryptedpassword);
# OpenLDAP uses a 4 byte salt, SunDS uses an 8 byte salt - both from char 20. # OpenLDAP uses a 4 byte salt, SunDS uses an 8 byte salt - both from char 20.
$salt = substr($hash,20); $salt = substr($hash,20);
$new_hash = base64_encode(mhash(MHASH_SHA1,$plainpassword.$salt).$salt); $new_hash = base64_encode(sha1($plainpassword.$salt, true).$salt);
if (strcmp($cryptedpassword,$new_hash) == 0) if (strcmp($cryptedpassword,$new_hash) == 0)
return true; return true;
else else
return false; return false;
} else {
error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php');
}
break; break;
#BCRYPT hashed passwords #BCRYPT hashed passwords
@ -2398,21 +2423,15 @@ function password_check($cryptedpassword,$plainpassword,$attribute='userpassword
# Salted MD5 # Salted MD5
case 'smd5': case 'smd5':
# Check php mhash support before using it
if (function_exists('mhash')) {
$hash = base64_decode($cryptedpassword); $hash = base64_decode($cryptedpassword);
$salt = substr($hash,16); $salt = substr($hash,16);
$new_hash = base64_encode(mhash(MHASH_MD5,$plainpassword.$salt).$salt); $new_hash = base64_encode(md5($plainpassword.$salt).$salt, true);
if (strcmp($cryptedpassword,$new_hash) == 0) if (strcmp($cryptedpassword,$new_hash) == 0)
return true; return true;
else else
return false; return false;
} else {
error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php');
}
break; break;
# SHA crypted passwords # SHA crypted passwords
@ -2489,6 +2508,50 @@ function password_check($cryptedpassword,$plainpassword,$attribute='userpassword
break; break;
# SHA256 crypted passwords
case 'sha256':
if (strcasecmp(pla_password_hash($plainpassword,'sha256'),'{SHA256}'.$cryptedpassword) == 0)
return true;
else
return false;
break;
# Salted SHA256 crypted passwords
case 'ssha256':
$hash = base64_decode($cryptedpassword);
$salt = substr($hash,64);
$new_hash = base64_encode(hash('sha256', $plainpassword.$salt, true).$salt);
if (strcmp($cryptedpassword,$new_hash) == 0)
return true;
else
return false;
break;
# SHA384 crypted passwords
case 'sha384':
if (strcasecmp(pla_password_hash($plainpassword,'sha384'),'{SHA384}'.$cryptedpassword) == 0)
return true;
else
return false;
break;
# Salted SHA384 crypted passwords
case 'ssha384':
$hash = base64_decode($cryptedpassword);
$salt = substr($hash,64);
$new_hash = base64_encode(hash('sha384', $plainpassword.$salt, true).$salt);
if (strcmp($cryptedpassword,$new_hash) == 0)
return true;
else
return false;
break;
# SHA512 crypted passwords # SHA512 crypted passwords
case 'sha512': case 'sha512':
if (strcasecmp(pla_password_hash($plainpassword,'sha512'),'{SHA512}'.$cryptedpassword) == 0) if (strcasecmp(pla_password_hash($plainpassword,'sha512'),'{SHA512}'.$cryptedpassword) == 0)
@ -2498,6 +2561,27 @@ function password_check($cryptedpassword,$plainpassword,$attribute='userpassword
break; break;
# Salted SHA512 crypted passwords
case 'ssha512':
$hash = base64_decode($cryptedpassword);
$salt = substr($hash,64);
$new_hash = base64_encode(hash('sha512', $plainpassword.$salt, true).$salt);
if (strcmp($cryptedpassword,$new_hash) == 0)
return true;
else
return false;
break;
# Argon2 crypted passwords
case 'argon2':
if (password_verify($plainpassword, $cryptedpassword))
return true;
else
return false;
break;
# No crypt is given assume plaintext passwords are used # No crypt is given assume plaintext passwords are used
default: default:
if ($plainpassword == $cryptedpassword) if ($plainpassword == $cryptedpassword)
@ -2541,6 +2625,16 @@ function get_enc_type($user_password) {
elseif (preg_match('/{[^}]+}_+/',$user_password)) elseif (preg_match('/{[^}]+}_+/',$user_password))
$enc_type = 'ext_des'; $enc_type = 'ext_des';
}
elseif (strcasecmp($enc_type,'argon2') == 0) {
if (preg_match('/{ARGON2}\$argon2i\$/',$user_password))
$enc_type = 'argon2i';
elseif (preg_match('/{ARGON2}\$argon2id\$/',$user_password))
$enc_type = 'argon2id';
} }
return $enc_type; return $enc_type;
@ -2619,6 +2713,9 @@ function pla_explode_dn($dn,$with_attributes=0) {
global $CACHE; global $CACHE;
if (is_null($dn))
$dn = '';
if (isset($CACHE['explode'][$dn][$with_attributes])) { if (isset($CACHE['explode'][$dn][$with_attributes])) {
if (DEBUG_ENABLED) if (DEBUG_ENABLED)
debug_log('Return CACHED result (%s) for (%s)',1,0,__FILE__,__LINE__,__METHOD__, debug_log('Return CACHED result (%s) for (%s)',1,0,__FILE__,__LINE__,__METHOD__,

View File

@ -376,7 +376,7 @@ class page {
'FOOT'=>true 'FOOT'=>true
); );
if ($_SESSION[APPCONFIG]->getValue('appearance','minimalMode')) { if (isset($_SESSION) && $_SESSION[APPCONFIG]->getValue('appearance','minimalMode')) {
$display = array( $display = array(
'HEAD'=>false, 'HEAD'=>false,
'CONTROL'=>false, 'CONTROL'=>false,

View File

@ -18,11 +18,11 @@
*/ */
abstract class SchemaItem { abstract class SchemaItem {
# The schema item's name. # The schema item's name.
protected $name = null; protected $name = '';
# The OID of this schema item. # The OID of this schema item.
private $oid = null; private $oid = null;
# The description of this schema item. # The description of this schema item.
protected $description = null; protected $description = '';
# Boolean value indicating whether this objectClass is obsolete # Boolean value indicating whether this objectClass is obsolete
private $is_obsolete = false; private $is_obsolete = false;
@ -703,7 +703,7 @@ class ObjectClass_ObjectClassAttribute {
*/ */
class AttributeType extends SchemaItem { class AttributeType extends SchemaItem {
# The attribute from which this attribute inherits (if any) # The attribute from which this attribute inherits (if any)
private $sup_attribute = null; private $sup_attribute = '';
# The equality rule used # The equality rule used
private $equality = null; private $equality = null;
# The ordering of the attributeType # The ordering of the attributeType
@ -711,8 +711,8 @@ class AttributeType extends SchemaItem {
# Boolean: supports substring matching? # Boolean: supports substring matching?
private $sub_str = null; private $sub_str = null;
# The full syntax string, ie 1.2.3.4{16} # The full syntax string, ie 1.2.3.4{16}
private $syntax = null; private $syntax = '';
private $syntax_oid = null; private $syntax_oid = '';
# boolean: is single valued only? # boolean: is single valued only?
private $is_single_value = false; private $is_single_value = false;
# boolean: is collective? # boolean: is collective?
@ -726,7 +726,7 @@ class AttributeType extends SchemaItem {
# The max number of characters this attribute can be # The max number of characters this attribute can be
private $max_length = null; private $max_length = null;
# A string description of the syntax type (taken from the LDAPSyntaxes) # A string description of the syntax type (taken from the LDAPSyntaxes)
private $type = null; private $type = '';
# An array of objectClasses which use this attributeType (must be set by caller) # An array of objectClasses which use this attributeType (must be set by caller)
private $used_in_object_classes = array(); private $used_in_object_classes = array();
# A list of object class names that require this attribute type. # A list of object class names that require this attribute type.
@ -1327,7 +1327,7 @@ class Syntax extends SchemaItem {
*/ */
class MatchingRule extends SchemaItem { class MatchingRule extends SchemaItem {
# This rule's syntax OID # This rule's syntax OID
private $syntax = null; private $syntax = '';
# An array of attribute names who use this MatchingRule # An array of attribute names who use this MatchingRule
private $used_by_attrs = array(); private $used_by_attrs = array();

View File

@ -230,7 +230,7 @@ abstract class xmlTemplates {
return clone $template; return clone $template;
# If we get here, the template ID didnt exist, so return a blank template, which be interpreted as the default template # If we get here, the template ID didnt exist, so return a blank template, which be interpreted as the default template
$object = new $class['name']($this->server_id,null,null,'default'); $object = new $class['name']($this->server_id,'',null,'default');
return $object; return $object;
} }
@ -272,7 +272,7 @@ abstract class xmlTemplate {
# The TEMPLATE attributes as per the template definition, or the DN entry # The TEMPLATE attributes as per the template definition, or the DN entry
protected $attributes = array(); protected $attributes = array();
public function __construct($server_id,$name=null,$filename=null,$type=null,$id=null) { public function __construct($server_id,$name='',$filename=null,$type=null,$id=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS')) if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs); debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);