Compare commits
50 Commits
master
...
BRANCH-1.2
Author | SHA1 | Date | |
---|---|---|---|
226a76d5fc | |||
a0117e4ad8 | |||
3bfd55de08 | |||
d1dae60f05 | |||
f29e200b96 | |||
e5aa9eb1e7 | |||
|
30abeffc30 | ||
d4b19d07db | |||
85f8c61e80 | |||
1650d6a921 | |||
|
c84b2d6d91 | ||
|
ef8d0ce94c | ||
|
15cc6f5382 | ||
|
364c0565a2 | ||
|
d09aa72a42 | ||
|
7226cea874 | ||
|
d15bd2dab3 | ||
|
43bac58990 | ||
|
9488fe2ed7 | ||
|
5e9b95f9a8 | ||
|
aeebf3faa6 | ||
|
b035e8a0f4 | ||
|
f129579f45 | ||
|
c90dc06af2 | ||
|
3a75a32100 | ||
|
3ec9c23d58 | ||
|
857f0c539c | ||
|
97eed9d9cd | ||
|
d4cae5065b | ||
|
386d6ab83b | ||
|
1d26d435c2 | ||
|
a0de69bd58 | ||
|
a8c9abe22b | ||
|
1c7340ce48 | ||
|
24ce5d5833 | ||
|
fe3798f8ec | ||
|
1a09e4ff3c | ||
|
bc1691f5d2 | ||
|
54bb4743aa | ||
|
46cc4a1b13 | ||
|
45aa1e5208 | ||
|
02b047c1f5 | ||
|
6d4aff8733 | ||
|
00683b3ea7 | ||
|
da69ebf06a | ||
|
a8fe6f3274 | ||
|
0c334f0385 | ||
|
9fac4b415a | ||
|
f4c8c3d31e | ||
|
e45e71fd08 |
@ -5,7 +5,7 @@ For install instructions in non-English languages, see the wiki:
|
||||
|
||||
phpLDAPadmin requires the following:
|
||||
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
|
||||
|
||||
|
87
README.md
87
README.md
@ -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
|
||||
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)
|
||||
|
@ -71,6 +71,33 @@
|
||||
environments. */
|
||||
# $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 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
|
||||
@ -173,6 +200,10 @@ $config->custom->commands['script'] = array(
|
||||
// $config->custom->appearance['tree_width'] = null;
|
||||
# $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
|
||||
and optionally skip attributes during the create/update operation. */
|
||||
// $config->custom->confirm['create'] = true;
|
||||
@ -243,7 +274,6 @@ $config->custom->appearance['friendly_attrs'] = array(
|
||||
/* Attribute that is added to the group member attribute. */
|
||||
// $config->custom->modify_member['attr'] = 'dn';
|
||||
|
||||
|
||||
/* For Posix attributes */
|
||||
// $config->custom->modify_member['posixattr'] = '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.
|
||||
5. 'sasl': login will be taken from the webserver's kerberos authentication.
|
||||
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
|
||||
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. */
|
||||
// $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 *
|
||||
************************************/
|
||||
@ -352,6 +399,9 @@ $servers->setValue('server','name','My LDAP Server');
|
||||
NOTE: auth_type must be simple auth compatible (ie not sasl) */
|
||||
# $servers->setValue('sasl','mech','PLAIN');
|
||||
|
||||
/* SASL EXTERNAL support... really a different auth_type */
|
||||
# $servers->setValue('login','auth_type','sasl_external');
|
||||
|
||||
/* SASL authentication realm name */
|
||||
// $servers->setValue('sasl','realm','');
|
||||
# $servers->setValue('sasl','realm','EXAMPLE.COM');
|
||||
|
@ -41,7 +41,7 @@ if (DEBUG_ENABLED)
|
||||
$www['page'] = new page($app['server']->getIndex());
|
||||
|
||||
# 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 ($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');
|
||||
|
@ -41,7 +41,7 @@ $request['recursive'] = (get_request('recursive') == 'on') ? true : false;
|
||||
$request['remove'] = (get_request('remove') == 'yes') ? true : false;
|
||||
|
||||
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
|
||||
$ldap['tree'] = array();
|
||||
|
@ -13,11 +13,11 @@ require './common.php';
|
||||
require LIBDIR.'export_functions.php';
|
||||
|
||||
$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['scope'] = get_request('scope','GET',false,'base');
|
||||
$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['sys_attr'] = get_request('sys_attr','GET') ? true: false;
|
||||
|
||||
|
@ -19,7 +19,8 @@ if ($_SESSION[APPCONFIG]->getValue('session', 'reCAPTCHA-enable')) {
|
||||
if ($pass) {
|
||||
$user = array();
|
||||
$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'])) {
|
||||
system_message(array(
|
||||
|
@ -65,7 +65,7 @@ for ($i=0;$i<count($possible_values);$i++) {
|
||||
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];
|
||||
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.
|
||||
|
@ -15,8 +15,8 @@ $www['page'] = new page();
|
||||
|
||||
$request = array();
|
||||
$request['componentid'] = get_request('componentid','REQUEST');
|
||||
$request['hash'] = get_request('hash','REQUEST');
|
||||
$request['password'] = get_request('check_password','REQUEST');
|
||||
$request['hash'] = get_request('hash','REQUEST',false,'');
|
||||
$request['password'] = get_request('check_password','REQUEST',false,'');
|
||||
$request['action'] = get_request('action','REQUEST');
|
||||
$request['attribute'] = get_request('attr','REQUEST');
|
||||
|
||||
|
@ -150,7 +150,7 @@ switch($entry['view']) {
|
||||
|
||||
foreach ($sattrs as $attr) {
|
||||
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;
|
||||
|
||||
if (isAjaxEnabled() && $entry['value'])
|
||||
@ -380,7 +380,7 @@ switch($entry['view']) {
|
||||
$desc = $rule->getName(false);
|
||||
|
||||
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;
|
||||
|
||||
if (null != $rule->getDescription())
|
||||
@ -468,7 +468,7 @@ switch($entry['view']) {
|
||||
|
||||
foreach ($socs as $name => $oclass) {
|
||||
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;
|
||||
|
||||
if (isAjaxEnabled() && $entry['value'])
|
||||
|
@ -40,7 +40,7 @@ switch ($request['location']) {
|
||||
if (! isset($jpeg_data[$request['attr']][$request['index']])) {
|
||||
if (function_exists('imagecreate')) {
|
||||
$im = imagecreate(160,30);
|
||||
if (is_resource($im)) {
|
||||
if ($im) {
|
||||
header('Content-type: image/png');
|
||||
|
||||
# Set the background
|
||||
|
@ -133,7 +133,7 @@ class AttributeFactory {
|
||||
return $this->newGidAttribute($name,$values,$server_id,$source);
|
||||
|
||||
} else {
|
||||
return new Attribute($name,$values,$server_id,$source);
|
||||
return new PLAAttribute($name,$values,$server_id,$source);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class BinaryAttribute extends Attribute {
|
||||
class BinaryAttribute extends PLAAttribute {
|
||||
protected $filepaths;
|
||||
protected $filenames;
|
||||
|
||||
|
@ -12,6 +12,6 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class DateAttribute extends Attribute {
|
||||
class DateAttribute extends PLAAttribute {
|
||||
}
|
||||
?>
|
||||
|
@ -12,6 +12,6 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class DnAttribute extends Attribute {
|
||||
class DnAttribute extends PLAAttribute {
|
||||
}
|
||||
?>
|
||||
|
@ -12,6 +12,6 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class GidAttribute extends Attribute {
|
||||
class GidAttribute extends PLAAttribute {
|
||||
}
|
||||
?>
|
||||
|
@ -136,6 +136,7 @@ class HTMLTree extends Tree {
|
||||
case 'config':
|
||||
case 'proxy':
|
||||
case 'sasl':
|
||||
case 'sasl_external':
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -169,7 +170,7 @@ class HTMLTree extends Tree {
|
||||
|
||||
if (! is_null($server->inactivityTime())) {
|
||||
$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');
|
||||
}
|
||||
echo '</td></tr>';
|
||||
@ -184,10 +185,15 @@ class HTMLTree extends Tree {
|
||||
|
||||
$links = '';
|
||||
|
||||
$i = 0;
|
||||
$icons = $_SESSION[APPCONFIG]->getValue('appearance','tree_icons');
|
||||
if (is_array($_SESSION[APPCONFIG]->getValue('menu','session')))
|
||||
foreach ($_SESSION[APPCONFIG]->getValue('menu','session') as $link => $title) {
|
||||
if ($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.
|
||||
@ -329,7 +335,7 @@ class HTMLTree extends Tree {
|
||||
$server = $this->getServer();
|
||||
$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 '';
|
||||
else
|
||||
return sprintf('<a href="%s" title="%s"><img src="%s/%s" alt="%s" /><br />%s</a>',
|
||||
|
@ -12,7 +12,7 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class MultiLineAttribute extends Attribute {
|
||||
class MultiLineAttribute extends PLAAttribute {
|
||||
protected $rows = 0;
|
||||
protected $cols = 0;
|
||||
|
||||
|
@ -12,6 +12,6 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class ObjectClassAttribute extends Attribute {
|
||||
class ObjectClassAttribute extends PLAAttribute {
|
||||
}
|
||||
?>
|
||||
|
@ -12,7 +12,7 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class Attribute {
|
||||
class PLAAttribute {
|
||||
# Attribute Name
|
||||
public $name;
|
||||
# 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'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if (isset($this->values[$i]))
|
||||
return $this->values[$i];
|
||||
else
|
||||
return null;
|
||||
return $default;
|
||||
}
|
||||
|
||||
public function getOldValue($i) {
|
@ -538,7 +538,7 @@ class PageRender extends Visitor {
|
||||
final protected function drawHiddenValueAttribute($attribute,$i) {
|
||||
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" />',
|
||||
htmlspecialchars($attribute->getName()),$i,htmlspecialchars($attribute->getName()),$i,
|
||||
@ -556,7 +556,7 @@ class PageRender extends Visitor {
|
||||
final protected function drawOldValueAttribute($attribute,$i) {
|
||||
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
|
||||
|
||||
echo $attribute->getOldValue($i);
|
||||
echo htmlspecialchars($attribute->getOldValue($i));
|
||||
}
|
||||
|
||||
/** DRAW DISPLAYED CURRENT VALUES **/
|
||||
@ -607,7 +607,7 @@ class PageRender extends Visitor {
|
||||
protected function drawFormReadOnlyValueAttribute($attribute,$i) {
|
||||
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" />',
|
||||
htmlspecialchars($attribute->getName()),$i,htmlspecialchars($attribute->getName()),$i,htmlspecialchars($val));
|
||||
@ -616,7 +616,7 @@ class PageRender extends Visitor {
|
||||
protected function drawFormReadWriteValueAttribute($attribute,$i) {
|
||||
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
|
||||
|
||||
$val = $attribute->getValue($i);
|
||||
$val = $attribute->getValue($i, '');
|
||||
|
||||
if ($attribute->getHelper() || $attribute->getVerify())
|
||||
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) {
|
||||
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
|
||||
|
||||
$val = $attribute->getValue($i);
|
||||
$val = $attribute->getValue($i, '');
|
||||
|
||||
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/> ',
|
||||
@ -738,7 +738,7 @@ class PageRender extends Visitor {
|
||||
protected function drawFormReadWriteValueDnAttribute($attribute,$i) {
|
||||
if (DEBUGTMP) printf('<font size=-2>%s</font><br />',__METHOD__);
|
||||
|
||||
$val = $attribute->getValue($i);
|
||||
$val = $attribute->getValue($i, '');
|
||||
|
||||
if ($attribute->getHelper())
|
||||
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__);
|
||||
|
||||
$server = $this->getServer();
|
||||
$val = $attribute->getValue($i);
|
||||
$val = $attribute->getValue($i, '');
|
||||
|
||||
if (trim($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__);
|
||||
|
||||
$server = $this->getServer();
|
||||
$val = $attribute->getValue($i);
|
||||
$val = $attribute->getValue($i, '');
|
||||
|
||||
$enc_type = get_enc_type($val);
|
||||
|
||||
@ -1102,7 +1102,7 @@ class PageRender extends Visitor {
|
||||
|
||||
# This is a single value attribute
|
||||
} 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())
|
||||
echo '<table cellspacing="0" cellpadding="0"><tr><td valign="top">';
|
||||
@ -1196,7 +1196,8 @@ class PageRender extends Visitor {
|
||||
else
|
||||
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) {
|
||||
@ -1214,15 +1215,15 @@ class PageRender extends Visitor {
|
||||
echo '<br/><small>';
|
||||
if (($today < $shadow_date) && in_array(strtolower($attribute->getName()),$shadow_before_today_attrs))
|
||||
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))
|
||||
printf('<span style="color:red">(%s)</span>',
|
||||
strftime($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date));
|
||||
date($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date));
|
||||
|
||||
else
|
||||
printf('(%s)',
|
||||
strftime($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date));
|
||||
date($_SESSION[APPCONFIG]->getValue('appearance','date'),$shadow_date));
|
||||
|
||||
echo '</small><br />';
|
||||
}
|
||||
|
@ -12,6 +12,6 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class PasswordAttribute extends Attribute {
|
||||
class PasswordAttribute extends PLAAttribute {
|
||||
}
|
||||
?>
|
||||
|
@ -134,9 +134,9 @@ class Query extends xmlTemplate {
|
||||
# If this is a custom search, we need to populate are paramters
|
||||
if ($this->getID() == 'none') {
|
||||
$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');
|
||||
$attrs = get_request('display_attrs','REQUEST');
|
||||
$attrs = get_request('display_attrs','REQUEST',false,'');
|
||||
|
||||
$attrs = preg_replace('/\s+/','',$attrs);
|
||||
if ($attrs)
|
||||
|
@ -12,7 +12,7 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class SelectionAttribute extends Attribute {
|
||||
class SelectionAttribute extends PLAAttribute {
|
||||
protected $selection = array();
|
||||
protected $multiple;
|
||||
protected $default;
|
||||
|
@ -12,7 +12,7 @@
|
||||
* @package phpLDAPadmin
|
||||
* @subpackage Templates
|
||||
*/
|
||||
class ShadowAttribute extends Attribute {
|
||||
class ShadowAttribute extends PLAAttribute {
|
||||
public $shadow_before_today_attrs = array('shadowLastChange','shadowMin');
|
||||
public $shadow_after_today_attrs = array('shadowMax','shadowExpire','shadowWarning','shadowInactive');
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ class Template extends xmlTemplate {
|
||||
# Template RDN attributes
|
||||
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);
|
||||
|
||||
# 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) {
|
||||
// @todo Be nice to do all this in 1 location
|
||||
$dn = $this->getDN();
|
||||
if (is_null($dn))
|
||||
$dn = '';
|
||||
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
|
||||
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) {
|
||||
/*
|
||||
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.
|
||||
|start-end is optional, but must be present if the k flag is used.
|
||||
/flags is optional.
|
||||
|additionalcontrolchar is optional.
|
||||
|
||||
flags may be:
|
||||
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
|
||||
"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.
|
||||
U: Make the result upper case.
|
||||
A: Remap special characters to their corresponding ASCII value
|
||||
*/
|
||||
case 'autoFill':
|
||||
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);
|
||||
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
|
||||
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, 4 = delimiter
|
||||
|
||||
if (! isset($attribute->js['autoFill']))
|
||||
$attribute->js['autoFill'] = '';
|
||||
@ -1183,6 +1190,7 @@ class Template extends xmlTemplate {
|
||||
$match_attr = strtolower($matchall[1][$index]);
|
||||
$match_subst = $matchall[2][$index];
|
||||
$match_mod = $matchall[3][$index];
|
||||
$match_delim = $matchall[4][$index];
|
||||
|
||||
$substrarray = array();
|
||||
|
||||
@ -1220,13 +1228,19 @@ class Template extends xmlTemplate {
|
||||
$attribute->js['autoFill'] .= sprintf(" %s = %s.split(':')[%s];\n",$match_attr,$match_attr,$tok_idx);
|
||||
|
||||
} elseif (strstr($match_mod,'K')) {
|
||||
preg_match_all('/([0-9]+)/',trim($match_subst),$substrarray);
|
||||
if (isset($substrarray[1][0])) {
|
||||
$tok_idx = $substrarray[1][0];
|
||||
} else {
|
||||
$tok_idx = '0';
|
||||
}
|
||||
$attribute->js['autoFill'] .= sprintf(" %s = %s.split(' ')[%s];\n",$match_attr,$match_attr,$tok_idx);
|
||||
preg_match_all('/([0-9]+)/',trim($match_subst),$substrarray);
|
||||
if (isset($substrarray[1][0])) {
|
||||
$tok_idx = $substrarray[1][0];
|
||||
} else {
|
||||
$tok_idx = '0';
|
||||
}
|
||||
|
||||
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 {
|
||||
preg_match_all('/([0-9]*)-([0-9]*)/',trim($match_subst),$substrarray);
|
||||
@ -1251,13 +1265,13 @@ class Template extends xmlTemplate {
|
||||
# Matchfor only entry without modifiers.
|
||||
$formula = preg_replace('/^%('.$match_attr.')%$/U','$1 + \'\'',$formula);
|
||||
# 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.
|
||||
$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.
|
||||
$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.
|
||||
$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";
|
||||
}
|
||||
|
||||
|
@ -139,16 +139,23 @@ class TemplateRender extends PageRender {
|
||||
return;
|
||||
}
|
||||
|
||||
$function_args = explode(',',$args[0]);
|
||||
|
||||
if (function_exists($function))
|
||||
$vals = call_user_func_array($function,$function_args);
|
||||
|
||||
if (!empty($args[0]))
|
||||
$function_args = explode(',',$args[0]);
|
||||
else
|
||||
$function_args = '';
|
||||
|
||||
if (function_exists($function)) {
|
||||
if (empty($function_args))
|
||||
$vals = call_user_func($function);
|
||||
else
|
||||
$vals = call_user_func_array($function,$function_args);
|
||||
|
||||
} else {
|
||||
system_message(array(
|
||||
'title'=>_('Function doesnt exist'),
|
||||
'body'=>sprintf('%s (<b>%s</b>)',_('An attempt was made to call a function that doesnt exist'),$function),
|
||||
'type'=>'warn'));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@ -264,6 +271,9 @@ class TemplateRender extends PageRender {
|
||||
*
|
||||
* * arg 8 (for MultiList)
|
||||
* - size of displayed list (default: 10 lines)
|
||||
*
|
||||
* * arg 9
|
||||
* - if whether to include parent in sub query TRUE|FALSE
|
||||
*/
|
||||
case 'MultiList':
|
||||
case 'PickList':
|
||||
@ -322,6 +332,9 @@ class TemplateRender extends PageRender {
|
||||
$vals = array();
|
||||
|
||||
foreach ($picklistvalues as $key => $values) {
|
||||
if (! empty($args[9]) && $container == $key)
|
||||
continue;
|
||||
|
||||
$display = $args[3];
|
||||
|
||||
foreach ($matchall[1] as $key => $arg) {
|
||||
@ -2143,7 +2156,7 @@ function fillRec(id,value) {
|
||||
if ($attribute->isMultiple() && $i > 0)
|
||||
return;
|
||||
|
||||
$val = $attribute->getValue($i);
|
||||
$val = $attribute->getValue($i, '');
|
||||
|
||||
if ($attribute->isVisible()) {
|
||||
echo '<table cellspacing="0" cellpadding="0" width="100%" border="0"><tr><td class="icon" style="width: 25px;">';
|
||||
|
@ -22,6 +22,15 @@ abstract class Visitor {
|
||||
protected $server_id;
|
||||
|
||||
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'))
|
||||
debug_log('Entered (%%)',129,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
@ -33,19 +42,14 @@ abstract class Visitor {
|
||||
$fnct = array_shift($args);
|
||||
|
||||
$object = $args[0];
|
||||
$class = get_class($object);
|
||||
|
||||
$call = "$method$fnct$class";
|
||||
|
||||
array_push($methods,$call);
|
||||
|
||||
while ($class && ! method_exists($this,$call)) {
|
||||
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);
|
||||
if (method_exists($this,$call))
|
||||
break;
|
||||
if (defined('DEBUGTMP') && DEBUGTMP)
|
||||
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)
|
||||
|
@ -315,7 +315,7 @@ class Horde_Cipher_blowfish {
|
||||
$keyLen = count($key);
|
||||
for ($i = 0; $i < $iMax; $i++) {
|
||||
for ($t = 0; $t < 4; $t++) {
|
||||
$keyXor = ($keyXor << 8) | (($key[$keyPos]) & 0x0ff);
|
||||
$keyXor = (($keyXor << 8) | (($key[$keyPos]) & 0x0ff)) & 0xFFFFFFFF;
|
||||
if (++$keyPos == $keyLen) {
|
||||
$keyPos = 0;
|
||||
}
|
||||
@ -389,6 +389,37 @@ class Horde_Cipher_blowfish {
|
||||
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.
|
||||
*
|
||||
@ -400,22 +431,22 @@ class Horde_Cipher_blowfish {
|
||||
function _encryptBlock($L, $R)
|
||||
{
|
||||
$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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[16];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[1];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[2];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[3];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[4];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[5];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[6];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[7];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[8];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[9];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[10];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[11];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[12];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[13];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[14];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[15];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[16];
|
||||
$R ^= $this->p[17];
|
||||
|
||||
return array('L' => $R, 'R' => $L);
|
||||
@ -445,23 +476,22 @@ class Horde_Cipher_blowfish {
|
||||
list($L, $R) = array_values($unpack);
|
||||
|
||||
$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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $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];
|
||||
$L ^= ((($this->s1[($R >> 24) & 0xFF] + $this->s2[($R >> 16) & 0x0ff]) ^ $this->s3[($R >> 8) & 0x0ff]) + $this->s4[$R & 0x0ff]) ^ $this->p[1];
|
||||
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[16];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[15];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[14];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[13];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[12];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[11];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[10];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[9];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[8];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[7];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[6];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[5];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[4];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[3];
|
||||
$R ^= $this->_cryptStep($L) ^ $this->p[2];
|
||||
$L ^= $this->_cryptStep($R) ^ $this->p[1];
|
||||
$decrypted = pack("NN", $R ^ $this->p[0], $L);
|
||||
return $decrypted;
|
||||
}
|
||||
|
@ -259,15 +259,16 @@ if ($app['language'] == 'auto') {
|
||||
|
||||
if ((substr($lang,0,2) == 'en') ||
|
||||
(file_exists($app['language_dir']) && is_readable($app['language_dir']))) {
|
||||
|
||||
# Set language
|
||||
putenv('LANG='.$lang); # e.g. LANG=de_DE
|
||||
$lang .= '.UTF-8';
|
||||
setlocale(LC_ALL,$lang); # set LC_ALL to de_DE
|
||||
bindtextdomain('messages',LANGDIR);
|
||||
bind_textdomain_codeset('messages','UTF-8');
|
||||
textdomain('messages');
|
||||
header('Content-type: text/html; charset=UTF-8',true);
|
||||
if (extension_loaded('gettext')) {
|
||||
# Set language
|
||||
putenv('LANG='.$lang); # e.g. LANG=de_DE
|
||||
$lang .= '.UTF-8';
|
||||
setlocale(LC_ALL,$lang); # set LC_ALL to de_DE
|
||||
bindtextdomain('messages',LANGDIR);
|
||||
bind_textdomain_codeset('messages','UTF-8');
|
||||
textdomain('messages');
|
||||
header('Content-type: text/html; charset=UTF-8',true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -296,7 +297,7 @@ if ($app['language'] == 'auto') {
|
||||
* Strip slashes from GET, POST, and COOKIE variables if this
|
||||
* 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($_GET);
|
||||
array_stripslashes($_POST);
|
||||
|
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
/** 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.
|
||||
@ -261,6 +261,10 @@ class Config {
|
||||
'desc'=>'LDAP search filter for the tree entries',
|
||||
'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.
|
||||
$this->default->appearance['minimalMode'] = array(
|
||||
'desc'=>'Minimal mode hides header and footer parts',
|
||||
@ -500,7 +504,7 @@ class Config {
|
||||
|
||||
$this->default->session['memorylimit'] = array(
|
||||
'desc'=>'Set the PHP memorylimit warning threshold.',
|
||||
'default'=>24);
|
||||
'default'=>'24M');
|
||||
|
||||
$this->default->session['timelimit'] = array(
|
||||
'desc'=>'Set the PHP timelimit.',
|
||||
@ -550,6 +554,32 @@ class Config {
|
||||
'desc'=>'Disable random salt for crypt()',
|
||||
'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
|
||||
* By default, when searching you may display a list or a table of results.
|
||||
* Set this to 'table' to see table formatted results.
|
||||
|
@ -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);
|
||||
|
||||
for ($i = 0; $i < 64; $i++) {
|
||||
$inb[$i] = ($in[$i/8] & (1<<(7-($i%8)))) ? 1:0;
|
||||
$keyb[$i] = ($key2[$i/8] & (1<<(7-($i%8)))) ? 1:0;
|
||||
$inb[$i] = ($in[intdiv($i, 8)] & (1<<(7-($i%8)))) ? 1:0;
|
||||
$keyb[$i] = ($key2[intdiv($i, 8)] & (1<<(7-($i%8)))) ? 1:0;
|
||||
$outb[$i] = 0;
|
||||
}
|
||||
$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++) {
|
||||
if ( $outb[$i] ) {
|
||||
$out[$i/8] |= (1<<(7-($i%8)));
|
||||
$out[intdiv($i, 8)] |= (1<<(7-($i%8)));
|
||||
}
|
||||
}
|
||||
return $out;
|
||||
|
10
lib/ds.php
10
lib/ds.php
@ -139,6 +139,7 @@ abstract class DS {
|
||||
case 'proxy':
|
||||
case 'session':
|
||||
case 'sasl':
|
||||
case 'sasl_external':
|
||||
return $this->getValue('login','auth_type');
|
||||
|
||||
default:
|
||||
@ -194,6 +195,8 @@ abstract class DS {
|
||||
else
|
||||
return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['name']);
|
||||
|
||||
case 'sasl_external':
|
||||
return 'external';
|
||||
default:
|
||||
die(sprintf('Error: %s hasnt been configured for auth_type %s',__METHOD__,$this->getAuthType()));
|
||||
}
|
||||
@ -215,6 +218,7 @@ abstract class DS {
|
||||
return true;
|
||||
|
||||
case 'config':
|
||||
case 'sasl_external':
|
||||
return true;
|
||||
|
||||
case 'proxy':
|
||||
@ -274,6 +278,8 @@ abstract class DS {
|
||||
else
|
||||
return blowfish_decrypt($_SESSION['USER'][$this->index][$method]['pass']);
|
||||
|
||||
case 'sasl_external':
|
||||
return '';
|
||||
default:
|
||||
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,'/');
|
||||
|
||||
case 'config':
|
||||
case 'sasl_external':
|
||||
return true;
|
||||
|
||||
case 'http':
|
||||
@ -430,7 +437,8 @@ abstract class DS {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
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;
|
||||
else
|
||||
return $this->getValue('server','read_only');
|
||||
|
173
lib/ds_ldap.php
173
lib/ds_ldap.php
@ -54,6 +54,22 @@ class ldap extends DS {
|
||||
'desc'=>'Connect using TLS',
|
||||
'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
|
||||
$this->default->login['attr'] = array(
|
||||
'desc'=>'Attribute to use to find the users DN',
|
||||
@ -110,6 +126,35 @@ class ldap extends DS {
|
||||
'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
|
||||
*/
|
||||
@ -164,22 +209,25 @@ class ldap extends DS {
|
||||
else
|
||||
$resource = ldap_connect($this->getValue('server','host'));
|
||||
|
||||
$this->noconnect = false;
|
||||
$CACHE[$this->index][$method] = $resource;
|
||||
|
||||
if (DEBUG_ENABLED)
|
||||
debug_log('LDAP Resource [%s], Host [%s], Port [%s]',16,0,__FILE__,__LINE__,__METHOD__,
|
||||
$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);
|
||||
|
||||
# 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
|
||||
* to not affect other LDAP servers (tested with OpenLDAP) as phpLDAPadmin explicitly
|
||||
* 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
|
||||
* 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
|
||||
* Directory-specific entries (DSEs), regardless of type, to be treated as normal entries
|
||||
* 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
|
||||
if ($this->isTLSEnabled())
|
||||
$this->startTLS($resource);
|
||||
if ($this->isTLSEnabled() && !$this->noconnect)
|
||||
if(! $this->startTLS($resource))
|
||||
$this->noconnect = true;
|
||||
|
||||
# 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']);
|
||||
|
||||
# Normal bind...
|
||||
@ -211,17 +263,16 @@ class ldap extends DS {
|
||||
if (DEBUG_ENABLED)
|
||||
debug_log('Leaving with FALSE, bind FAILed',16,0,__FILE__,__LINE__,__METHOD__);
|
||||
|
||||
$this->noconnect = true;
|
||||
|
||||
system_message(array(
|
||||
'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),
|
||||
'type'=>'error'));
|
||||
|
||||
if (! $this->noconnect) {
|
||||
$this->noconnect = true;
|
||||
system_message(array(
|
||||
'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),
|
||||
'type'=>'error'));
|
||||
}
|
||||
$CACHE[$this->index][$method] = null;
|
||||
|
||||
} else {
|
||||
$this->noconnect = false;
|
||||
|
||||
# If this is a proxy session, we need to switch to the proxy user
|
||||
if ($this->isProxyEnabled() && $bind['id'] && $method != 'anon')
|
||||
@ -286,7 +337,7 @@ class ldap extends DS {
|
||||
$connect = $this->connect($method,false,$new);
|
||||
|
||||
# If we didnt log in...
|
||||
if (! is_resource($connect) || $this->noconnect || ! $this->userIsAllowedLogin($userDN)) {
|
||||
if (!$connect || $this->noconnect || ! $this->userIsAllowedLogin($userDN)) {
|
||||
$this->logout($method);
|
||||
|
||||
return false;
|
||||
@ -359,22 +410,24 @@ class ldap extends DS {
|
||||
if ($debug)
|
||||
debug_dump(array('query'=>$query,'server'=>$this->getIndex(),'con'=>$this->connect($method)));
|
||||
|
||||
$search = null;
|
||||
$resource = $this->connect($method,$debug);
|
||||
|
||||
switch ($query['scope']) {
|
||||
case 'base':
|
||||
$search = @ldap_read($resource,$query['base'],$query['filter'],$query['attrs'],$attrs_only,$query['size_limit'],$query['time_limit'],$query['deref']);
|
||||
break;
|
||||
if ($resource)
|
||||
switch ($query['scope']) {
|
||||
case 'base':
|
||||
$search = @ldap_read($resource,$query['base'],$query['filter'],$query['attrs'],$attrs_only,$query['size_limit'],$query['time_limit'],$query['deref']);
|
||||
break;
|
||||
|
||||
case 'one':
|
||||
$search = @ldap_list($resource,$query['base'],$query['filter'],$query['attrs'],$attrs_only,$query['size_limit'],$query['time_limit'],$query['deref']);
|
||||
break;
|
||||
case 'one':
|
||||
$search = @ldap_list($resource,$query['base'],$query['filter'],$query['attrs'],$attrs_only,$query['size_limit'],$query['time_limit'],$query['deref']);
|
||||
break;
|
||||
|
||||
case 'sub':
|
||||
default:
|
||||
$search = @ldap_search($resource,$query['base'],$query['filter'],$query['attrs'],$attrs_only,$query['size_limit'],$query['time_limit'],$query['deref']);
|
||||
break;
|
||||
}
|
||||
case 'sub':
|
||||
default:
|
||||
$search = @ldap_search($resource,$query['base'],$query['filter'],$query['attrs'],$attrs_only,$query['size_limit'],$query['time_limit'],$query['deref']);
|
||||
break;
|
||||
}
|
||||
|
||||
if ($debug)
|
||||
debug_dump(array('method'=>$method,'search'=>$search,'error'=>$this->getErrorMessage()));
|
||||
@ -570,10 +623,41 @@ class ldap extends DS {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
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(
|
||||
'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'));
|
||||
|
||||
return false;
|
||||
@ -590,6 +674,8 @@ class ldap extends DS {
|
||||
* $servers->setValue('login','auth_type','sasl');
|
||||
* OR
|
||||
* $servers->setValue('sasl','mech','PLAIN');
|
||||
* OR
|
||||
* $servers->setValue('login','auth_type','sasl_external');
|
||||
* </code>
|
||||
*
|
||||
* @return boolean
|
||||
@ -598,7 +684,7 @@ class ldap extends DS {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
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
|
||||
if (! in_array(strtolower($this->getValue('sasl', 'mech')), array('plain')))
|
||||
return false;
|
||||
@ -630,6 +716,13 @@ class ldap extends DS {
|
||||
if ($method == 'anon')
|
||||
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
|
||||
if (! in_array(strtolower($this->getValue('sasl','mech')),array('gssapi','plain'))) {
|
||||
system_message(array(
|
||||
@ -783,7 +876,7 @@ class ldap extends DS {
|
||||
'value'=>sprintf('dn:%s',$dn),
|
||||
'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(
|
||||
'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),
|
||||
@ -939,7 +1032,7 @@ class ldap extends DS {
|
||||
$dn = $this->getContainer($dn);
|
||||
|
||||
if ($dn == $top)
|
||||
break;
|
||||
continue;
|
||||
|
||||
} elseif($value)
|
||||
$dn = sprintf('%s,%s',$value,$dn);
|
||||
@ -1146,12 +1239,12 @@ class ldap extends DS {
|
||||
if (is_array($dn)) {
|
||||
$a = array();
|
||||
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;
|
||||
|
||||
} 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);
|
||||
|
||||
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.
|
||||
if (! $search && ! $dn) {
|
||||
@ -1210,7 +1303,7 @@ class ldap extends DS {
|
||||
|
||||
if (DEBUG_ENABLED)
|
||||
debug_log('Search returned (%s) for base (%s)',24,0,__FILE__,__LINE__,__METHOD__,
|
||||
is_resource($search),$base);
|
||||
!!$search,$base);
|
||||
|
||||
if ($search)
|
||||
break;
|
||||
@ -2225,7 +2318,7 @@ class ldap extends DS {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
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) ||
|
||||
! strcasecmp('isCriticalSystemObject',$attr_name) ||
|
||||
@ -2290,8 +2383,8 @@ class ldap extends DS {
|
||||
|
||||
/* Strangely, some attributeTypes may not show up in the server
|
||||
* schema. This behavior has been observed in MS Active Directory.*/
|
||||
$type = null;
|
||||
$syntax = null;
|
||||
$type = '';
|
||||
$syntax = '';
|
||||
|
||||
} else {
|
||||
$type = $sattr->getType();
|
||||
|
@ -599,10 +599,16 @@ class ldap_pla extends ldap {
|
||||
|
||||
# Build our search filter to double check each attribute.
|
||||
$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)
|
||||
if ($val)
|
||||
$query['filter'] .= sprintf('(%s=%s)',$attr,$val);
|
||||
}
|
||||
$query['filter'] .= ')';
|
||||
|
||||
$query['attrs'] = $checkattrs;
|
||||
|
@ -125,7 +125,7 @@ abstract class Export {
|
||||
$query = array();
|
||||
$base = get_request('dn','REQUEST');
|
||||
$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['deref'] = $_SESSION[APPCONFIG]->getValue('deref','export');
|
||||
$query['size_limit'] = 0;
|
||||
|
@ -21,6 +21,7 @@ define('TMPLDIR',sprintf('%s/',realpath(LIBDIR.'../templates/')));
|
||||
define('DOCDIR',sprintf('%s/',realpath(LIBDIR.'../doc/')));
|
||||
define('HOOKSDIR',sprintf('%s/',realpath(LIBDIR.'../hooks/')));
|
||||
define('JSDIR','js/');
|
||||
define('SESSION_CIPHER','aes-256-gcm');
|
||||
|
||||
/**
|
||||
* Supplimental functions
|
||||
@ -82,7 +83,7 @@ function array_stripslashes(&$array) {
|
||||
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if (is_array($array))
|
||||
while (list($key) = each($array))
|
||||
foreach ($array as $key => $values)
|
||||
if (is_array($array[$key]) && $key != $array)
|
||||
array_stripslashes($array[$key]);
|
||||
else
|
||||
@ -130,12 +131,13 @@ function app_error_handler($errno,$errstr,$file,$lineno) {
|
||||
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
/**
|
||||
* error_reporting will be 0 if the error context occurred
|
||||
* within a function call with '@' preprended (ie, @ldap_bind() );
|
||||
* error_reporting will be only the non-ignorable error number bits
|
||||
* if the error context occurred within a function call with '@'
|
||||
* preprended (ie, @ldap_bind() );
|
||||
* So, don't report errors if the caller has specifically
|
||||
* disabled them with '@'
|
||||
*/
|
||||
if (ini_get('error_reporting') == 0 || error_reporting() == 0)
|
||||
if (!(ini_get('error_reporting') & error_reporting() & $errno))
|
||||
return;
|
||||
|
||||
$file = basename($file);
|
||||
@ -331,16 +333,38 @@ function check_config($config_file) {
|
||||
$config->setServers($servers);
|
||||
|
||||
# Check the memory limit parameter.
|
||||
if ((ini_get('memory_limit') > -1) && ini_get('memory_limit') < $config->getValue('session','memorylimit'))
|
||||
system_message(array(
|
||||
'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.',
|
||||
ini_get('memory_limit'),$config->getValue('session','memorylimit')),
|
||||
'type'=>'error'));
|
||||
|
||||
$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(
|
||||
'title' => _('Memory Limit low.'),
|
||||
'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'), $limit, $config->getValue('session','memorylimit'), $threshold),
|
||||
'type'=>'error'
|
||||
));
|
||||
}
|
||||
}
|
||||
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
|
||||
*
|
||||
@ -687,16 +711,16 @@ function get_request($attr,$type='POST',$die=false,$default=null,$preventXSS=tru
|
||||
* Return valor escape XSS.
|
||||
*/
|
||||
function preventXSS($data){
|
||||
if (gettype($data) == 'array') {
|
||||
foreach ($data as $key => $value) {
|
||||
if (gettype($value) == 'array')
|
||||
$data[$key] = preventXSS($value);
|
||||
else
|
||||
$data[$key] = htmlspecialchars($value);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
|
||||
if (gettype($data) == 'array') {
|
||||
foreach ($data as $key => $value) {
|
||||
if (gettype($value) == 'array')
|
||||
$data[$key] = preventXSS($value);
|
||||
else
|
||||
$data[$key] = htmlspecialchars($value);
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
|
||||
}
|
||||
|
||||
/*
|
||||
@ -768,9 +792,11 @@ function blowfish_encrypt($data,$secret=null) {
|
||||
if (! trim($secret))
|
||||
return $data;
|
||||
|
||||
if (! empty($data) && function_exists('openssl_encrypt') && in_array('bf-ecb', openssl_get_cipher_methods())) {
|
||||
$keylen = openssl_cipher_iv_length('bf-ecb') * 2;
|
||||
return openssl_encrypt($data, 'bf-ecb', substr($secret,0,$keylen));
|
||||
if (! empty($data) && function_exists('openssl_encrypt') && in_array(SESSION_CIPHER, openssl_get_cipher_methods())) {
|
||||
$iv = openssl_random_pseudo_bytes(openssl_cipher_iv_length(SESSION_CIPHER));
|
||||
$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)) {
|
||||
@ -829,9 +855,10 @@ function blowfish_decrypt($encdata,$secret=null) {
|
||||
if (! trim($secret))
|
||||
return $encdata;
|
||||
|
||||
if (! empty($encdata) && function_exists('openssl_encrypt') && in_array('bf-ecb', openssl_get_cipher_methods())) {
|
||||
$keylen = openssl_cipher_iv_length('bf-ecb') * 2;
|
||||
return trim(openssl_decrypt($encdata, 'bf-ecb', substr($secret,0,$keylen)));
|
||||
if (! empty($encdata) && function_exists('openssl_encrypt') && in_array(SESSION_CIPHER, openssl_get_cipher_methods())) {
|
||||
$keylen = openssl_cipher_iv_length(SESSION_CIPHER) * 2;
|
||||
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)) {
|
||||
@ -928,7 +955,7 @@ function get_cached_item($index,$item,$subitem='null') {
|
||||
*
|
||||
* 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'))
|
||||
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'))
|
||||
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-]+)*$/";
|
||||
|
||||
if (preg_match($mail_regex,$str))
|
||||
@ -1287,6 +1317,9 @@ function is_url_string($str) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
if (is_null($str))
|
||||
return false;
|
||||
|
||||
$url_regex = '/^(ftp|https?):\/\/+[\w\.\-\/\?\=\&]*\w+/';
|
||||
|
||||
if (preg_match($url_regex,$str))
|
||||
@ -1298,29 +1331,29 @@ function is_url_string($str) {
|
||||
/**
|
||||
* Compares 2 DNs. If they are equivelant, returns 0, otherwise,
|
||||
* returns their sorting order (similar to strcmp()):
|
||||
* Returns < 0 if dn1 is less than dn2.
|
||||
* Returns > 0 if dn1 is greater than dn2.
|
||||
* Returns < 0 if dn1 is less than dn2.
|
||||
* Returns > 0 if dn1 is greater than dn2.
|
||||
*
|
||||
* The comparison is performed starting with the top-most element
|
||||
* of the DN. Thus, the following list:
|
||||
* <code>
|
||||
* ou=people,dc=example,dc=com
|
||||
* cn=Admin,ou=People,dc=example,dc=com
|
||||
* cn=Joe,ou=people,dc=example,dc=com
|
||||
* dc=example,dc=com
|
||||
* cn=Fred,ou=people,dc=example,dc=org
|
||||
* cn=Dave,ou=people,dc=example,dc=org
|
||||
* </code>
|
||||
* <code>
|
||||
* ou=people,dc=example,dc=com
|
||||
* cn=Admin,ou=People,dc=example,dc=com
|
||||
* cn=Joe,ou=people,dc=example,dc=com
|
||||
* dc=example,dc=com
|
||||
* cn=Fred,ou=people,dc=example,dc=org
|
||||
* cn=Dave,ou=people,dc=example,dc=org
|
||||
* </code>
|
||||
* Will be sorted thus using usort( $list, "pla_compare_dns" ):
|
||||
* <code>
|
||||
* dc=com
|
||||
* dc=example,dc=com
|
||||
* ou=people,dc=example,dc=com
|
||||
* cn=Admin,ou=People,dc=example,dc=com
|
||||
* cn=Joe,ou=people,dc=example,dc=com
|
||||
* cn=Dave,ou=people,dc=example,dc=org
|
||||
* cn=Fred,ou=people,dc=example,dc=org
|
||||
* </code>
|
||||
* <code>
|
||||
* dc=com
|
||||
* dc=example,dc=com
|
||||
* ou=people,dc=example,dc=com
|
||||
* cn=Admin,ou=People,dc=example,dc=com
|
||||
* cn=Joe,ou=people,dc=example,dc=com
|
||||
* cn=Dave,ou=people,dc=example,dc=org
|
||||
* cn=Fred,ou=people,dc=example,dc=org
|
||||
* </code>
|
||||
*
|
||||
* @param string The first of two DNs to compare
|
||||
* @param string The second of two DNs to compare
|
||||
@ -1828,15 +1861,9 @@ function random_salt($length) {
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
$possible = '0123456789'.
|
||||
'abcdefghijklmnopqrstuvwxyz'.
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
|
||||
'./';
|
||||
$str = '';
|
||||
mt_srand((double)microtime() * 1000000);
|
||||
|
||||
while (strlen($str) < $length)
|
||||
$str .= substr($possible,(rand()%strlen($possible)),1);
|
||||
$str = bin2hex(random_bytes(ceil($length/2)));
|
||||
if ($length % 2 == 1)
|
||||
return substr($str, 0, -1);
|
||||
|
||||
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
|
||||
* 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'))
|
||||
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'))
|
||||
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
return array(
|
||||
''=>'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',
|
||||
);
|
||||
return $_SESSION[APPCONFIG]->getValue('password', 'available_types');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2225,7 +2237,7 @@ function pla_password_hash($password_clear,$enc_type) {
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case 'md5crypt':
|
||||
@ -2237,60 +2249,65 @@ function pla_password_hash($password_clear,$enc_type) {
|
||||
break;
|
||||
|
||||
case 'sha':
|
||||
# Use php 4.3.0+ sha1 function, if it is available.
|
||||
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');
|
||||
$new_value = sprintf('{SHA}%s',base64_encode(sha1($password_clear, true)));
|
||||
|
||||
break;
|
||||
|
||||
case 'ssha':
|
||||
if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) {
|
||||
mt_srand((double)microtime()*1000000);
|
||||
$salt = mhash_keygen_s2k(MHASH_SHA1,$password_clear,substr(pack('h*',md5(mt_rand())),0,8),4);
|
||||
$new_value = 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');
|
||||
}
|
||||
$salt = hex2bin(random_salt(8));
|
||||
$new_value = sprintf('{SSHA}%s',base64_encode(sha1($password_clear.$salt, true).$salt));
|
||||
|
||||
break;
|
||||
|
||||
case 'bcrypt':
|
||||
$options = [
|
||||
'cost' => 8,
|
||||
];
|
||||
#Checking if password_hash() function is available.
|
||||
if (function_exists('password_hash'))
|
||||
$new_value = sprintf('{BCRYPT}%s',base64_encode(password_hash($password_clear, PASSWORD_BCRYPT, $options)));
|
||||
else
|
||||
error(_('Your PHP install does not have the password_hash() function. Cannot do BCRYPT hashes.'),'error','index.php');
|
||||
case 'bcrypt':
|
||||
$options = [
|
||||
'cost' => 8,
|
||||
];
|
||||
#Checking if password_hash() function is available.
|
||||
if (function_exists('password_hash'))
|
||||
$new_value = sprintf('{BCRYPT}%s',base64_encode(password_hash($password_clear, PASSWORD_BCRYPT, $options)));
|
||||
else
|
||||
error(_('Your PHP install does not have the password_hash() function. Cannot do BCRYPT hashes.'),'error','index.php');
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
|
||||
case 'smd5':
|
||||
if (function_exists('mhash') && function_exists('mhash_keygen_s2k')) {
|
||||
mt_srand((double)microtime()*1000000);
|
||||
$salt = mhash_keygen_s2k(MHASH_MD5,$password_clear,substr(pack('h*',md5(mt_rand())),0,8),4);
|
||||
$new_value = sprintf('{SMD5}%s',base64_encode(mhash(MHASH_MD5,$password_clear.$salt).$salt));
|
||||
$salt = hex2bin(random_salt(8));
|
||||
$new_value = sprintf('{SMD5}%s',base64_encode(md5($password_clear.$salt, true).$salt));
|
||||
|
||||
} else {
|
||||
error(_('Your PHP install does not have the mhash() or mhash_keygen_s2k() function. Cannot do S2K hashes.'),'error','index.php');
|
||||
}
|
||||
break;
|
||||
|
||||
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;
|
||||
|
||||
case 'sha512':
|
||||
if (function_exists('openssl_digest') && function_exists('base64_encode')) {
|
||||
$new_value = sprintf('{SHA512}%s', base64_encode(openssl_digest($password_clear, 'sha512', true)));
|
||||
$new_value = sprintf('{SHA512}%s', base64_encode(hash('sha512', $password_clear, true)));
|
||||
|
||||
} else {
|
||||
error(_('Your PHP install doest not have the openssl_digest() or base64_encode() function. Cannot do SHA512 hashes. '),'error','index.php');
|
||||
}
|
||||
break;
|
||||
|
||||
case 'ssha512':
|
||||
$salt = hex2bin(random_salt(8));
|
||||
$new_value = sprintf('{SSHA512}%s', base64_encode(hash('sha512', $password_clear.$salt, true).$salt));
|
||||
|
||||
break;
|
||||
|
||||
@ -2308,6 +2325,20 @@ function pla_password_hash($password_clear,$enc_type) {
|
||||
|
||||
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':
|
||||
default:
|
||||
$new_value = $password_clear;
|
||||
@ -2325,7 +2356,7 @@ function pla_password_hash($password_clear,$enc_type) {
|
||||
* @return Boolean True if the clear password matches the hash, and false otherwise.
|
||||
*/
|
||||
function password_check($cryptedpassword,$plainpassword,$attribute='userpassword') {
|
||||
$plainpassword = htmlspecialchars_decode($plainpassword);
|
||||
$plainpassword = htmlspecialchars_decode($plainpassword);
|
||||
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
|
||||
debug_log('Entered (%%)',1,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
@ -2360,58 +2391,46 @@ function password_check($cryptedpassword,$plainpassword,$attribute='userpassword
|
||||
switch($cypher) {
|
||||
# SSHA crypted passwords
|
||||
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.
|
||||
$salt = substr($hash,20);
|
||||
$new_hash = base64_encode(mhash(MHASH_SHA1,$plainpassword.$salt).$salt);
|
||||
# OpenLDAP uses a 4 byte salt, SunDS uses an 8 byte salt - both from char 20.
|
||||
$salt = substr($hash,20);
|
||||
$new_hash = base64_encode(sha1($plainpassword.$salt, true).$salt);
|
||||
|
||||
if (strcmp($cryptedpassword,$new_hash) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
} else {
|
||||
error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php');
|
||||
}
|
||||
if (strcmp($cryptedpassword,$new_hash) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
#BCRYPT hashed passwords
|
||||
case 'bcrypt':
|
||||
# Check php password_verify support before using it
|
||||
if (function_exists('password_verify')) {
|
||||
$hash = base64_decode($cryptedpassword);
|
||||
if (password_verify($plainpassword, $hash)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
} else {
|
||||
error(_('Your PHP install does not have the password_verify() function. Cannot do Bcrypt hashes.'),'error','index.php');
|
||||
}
|
||||
#BCRYPT hashed passwords
|
||||
case 'bcrypt':
|
||||
# Check php password_verify support before using it
|
||||
if (function_exists('password_verify')) {
|
||||
$hash = base64_decode($cryptedpassword);
|
||||
if (password_verify($plainpassword, $hash)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
break;
|
||||
} else {
|
||||
error(_('Your PHP install does not have the password_verify() function. Cannot do Bcrypt hashes.'),'error','index.php');
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
# Salted MD5
|
||||
case 'smd5':
|
||||
# Check php mhash support before using it
|
||||
if (function_exists('mhash')) {
|
||||
$hash = base64_decode($cryptedpassword);
|
||||
$salt = substr($hash,16);
|
||||
$new_hash = base64_encode(mhash(MHASH_MD5,$plainpassword.$salt).$salt);
|
||||
$hash = base64_decode($cryptedpassword);
|
||||
$salt = substr($hash,16);
|
||||
$new_hash = base64_encode(md5($plainpassword.$salt).$salt, true);
|
||||
|
||||
if (strcmp($cryptedpassword,$new_hash) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
} else {
|
||||
error(_('Your PHP install does not have the mhash() function. Cannot do SHA hashes.'),'error','index.php');
|
||||
}
|
||||
if (strcmp($cryptedpassword,$new_hash) == 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
|
||||
break;
|
||||
|
||||
@ -2489,6 +2508,50 @@ function password_check($cryptedpassword,$plainpassword,$attribute='userpassword
|
||||
|
||||
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
|
||||
case 'sha512':
|
||||
if (strcasecmp(pla_password_hash($plainpassword,'sha512'),'{SHA512}'.$cryptedpassword) == 0)
|
||||
@ -2498,6 +2561,27 @@ function password_check($cryptedpassword,$plainpassword,$attribute='userpassword
|
||||
|
||||
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
|
||||
default:
|
||||
if ($plainpassword == $cryptedpassword)
|
||||
@ -2541,6 +2625,16 @@ function get_enc_type($user_password) {
|
||||
|
||||
elseif (preg_match('/{[^}]+}_+/',$user_password))
|
||||
$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;
|
||||
@ -2619,6 +2713,9 @@ function pla_explode_dn($dn,$with_attributes=0) {
|
||||
|
||||
global $CACHE;
|
||||
|
||||
if (is_null($dn))
|
||||
$dn = '';
|
||||
|
||||
if (isset($CACHE['explode'][$dn][$with_attributes])) {
|
||||
if (DEBUG_ENABLED)
|
||||
debug_log('Return CACHED result (%s) for (%s)',1,0,__FILE__,__LINE__,__METHOD__,
|
||||
@ -3262,7 +3359,7 @@ function IsRobot($gResponse){
|
||||
$options = array(
|
||||
'http' => array (
|
||||
'method' => 'POST','header' =>
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
'Content-Type: application/x-www-form-urlencoded',
|
||||
'content' => http_build_query($data)
|
||||
)
|
||||
);
|
||||
|
@ -376,7 +376,7 @@ class page {
|
||||
'FOOT'=>true
|
||||
);
|
||||
|
||||
if ($_SESSION[APPCONFIG]->getValue('appearance','minimalMode')) {
|
||||
if (isset($_SESSION) && $_SESSION[APPCONFIG]->getValue('appearance','minimalMode')) {
|
||||
$display = array(
|
||||
'HEAD'=>false,
|
||||
'CONTROL'=>false,
|
||||
|
@ -18,11 +18,11 @@
|
||||
*/
|
||||
abstract class SchemaItem {
|
||||
# The schema item's name.
|
||||
protected $name = null;
|
||||
protected $name = '';
|
||||
# The OID of this schema item.
|
||||
private $oid = null;
|
||||
# The description of this schema item.
|
||||
protected $description = null;
|
||||
protected $description = '';
|
||||
# Boolean value indicating whether this objectClass is obsolete
|
||||
private $is_obsolete = false;
|
||||
|
||||
@ -703,7 +703,7 @@ class ObjectClass_ObjectClassAttribute {
|
||||
*/
|
||||
class AttributeType extends SchemaItem {
|
||||
# The attribute from which this attribute inherits (if any)
|
||||
private $sup_attribute = null;
|
||||
private $sup_attribute = '';
|
||||
# The equality rule used
|
||||
private $equality = null;
|
||||
# The ordering of the attributeType
|
||||
@ -711,8 +711,8 @@ class AttributeType extends SchemaItem {
|
||||
# Boolean: supports substring matching?
|
||||
private $sub_str = null;
|
||||
# The full syntax string, ie 1.2.3.4{16}
|
||||
private $syntax = null;
|
||||
private $syntax_oid = null;
|
||||
private $syntax = '';
|
||||
private $syntax_oid = '';
|
||||
# boolean: is single valued only?
|
||||
private $is_single_value = false;
|
||||
# boolean: is collective?
|
||||
@ -726,7 +726,7 @@ class AttributeType extends SchemaItem {
|
||||
# The max number of characters this attribute can be
|
||||
private $max_length = null;
|
||||
# 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)
|
||||
private $used_in_object_classes = array();
|
||||
# A list of object class names that require this attribute type.
|
||||
@ -1327,7 +1327,7 @@ class Syntax extends SchemaItem {
|
||||
*/
|
||||
class MatchingRule extends SchemaItem {
|
||||
# This rule's syntax OID
|
||||
private $syntax = null;
|
||||
private $syntax = '';
|
||||
# An array of attribute names who use this MatchingRule
|
||||
private $used_by_attrs = array();
|
||||
|
||||
|
@ -230,7 +230,7 @@ abstract class xmlTemplates {
|
||||
return clone $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;
|
||||
}
|
||||
|
||||
@ -272,7 +272,7 @@ abstract class xmlTemplate {
|
||||
# The TEMPLATE attributes as per the template definition, or the DN entry
|
||||
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'))
|
||||
debug_log('Entered (%%)',5,0,__FILE__,__LINE__,__METHOD__,$fargs);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user