Merge branch 'develop' into feature/powerdns

This commit is contained in:
gruberroland 2021-12-08 20:26:30 +01:00 committed by GitHub
commit a32401ff6a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 57 additions and 55 deletions

View file

@ -5,6 +5,8 @@ December 2021 7.8
- LAM Pro:
-> PowerDNS support
-> Device: allow multiple cn values
- Fixed bugs:
-> PDF does not contain all group members (249)
30.09.2021 7.7

View file

@ -733,32 +733,6 @@ function get_preg($argument, $regexp) {
return false;
}
/**
* Escapes any special characters in an LDAP DN.
*
* @param String $dn DN
* @return String escaped DN
*/
function escapeDN($dn) {
return str_replace(
array(')', '(', ' ', '*'),
array('\\29', '\\28', '\\20', '\\2a'),
$dn
);
}
/**
* Escapes special characters in RDN part.
*
* @param string $rdn RDN
*/
function escapeRDN($rdn) {
return str_replace(
array(','),
array('\\2C'),
$rdn);
}
/**
* Converts the comma escaping from Windows to OpenLDAP style.
*
@ -837,7 +811,7 @@ function searchLDAPByAttribute($name, $value, $objectClass, $attributes, $scopes
continue; // skip non-active account types
}
// search LDAP
$entries = searchLDAPPaged($_SESSION['ldap']->server(), escapeDN($type->getSuffix()),
$entries = searchLDAPPaged($_SESSION['ldap']->server(), $type->getSuffix(),
$filter, $attributes, 0, $_SESSION['config']->get_searchLimit());
if (ldap_errno($_SESSION['ldap']->server()) == 4) {
logNewMessage(LOG_WARNING, 'LDAP size limit exceeded. Please increase the limit on your server.');
@ -876,7 +850,7 @@ function searchLDAPByFilter($filter, $attributes, $scopes, $attrsOnly = false) {
$filter = '(&' . $additionalFilter . $filter . ')';
}
// search LDAP
$entries = searchLDAPPaged($_SESSION['ldap']->server(), escapeDN($type->getSuffix()),
$entries = searchLDAPPaged($_SESSION['ldap']->server(), $type->getSuffix(),
$filter, $attributes, $readAttributesOnly, $_SESSION['config']->get_searchLimit());
if (ldap_errno($_SESSION['ldap']->server()) == 4) {
logNewMessage(LOG_WARNING, 'LDAP size limit exceeded. Please increase the limit on your server.');
@ -899,7 +873,7 @@ function searchLDAP($suffix, $filter, $attributes, $limit = -1) {
if ($limit === -1) {
$limit = !empty($_SESSION['config']) ? $_SESSION['config']->get_searchLimit() : 0;
}
$return = searchLDAPPaged(getLDAPServerHandle(), escapeDN($suffix), $filter, $attributes,
$return = searchLDAPPaged(getLDAPServerHandle(), $suffix, $filter, $attributes,
0, $limit);
if (ldap_errno(getLDAPServerHandle()) == 4) {
logNewMessage(LOG_WARNING, 'LDAP size limit exceeded. Please increase the limit on your server.');
@ -988,7 +962,7 @@ function ldapGetDN($dn, $attributes = array('dn'), $handle = null) {
$handle = getLDAPServerHandle();
}
$return = null;
$sr = @ldap_read($handle, escapeDN($dn), 'objectClass=*', $attributes, 0, 0, 0, LDAP_DEREF_NEVER);
$sr = @ldap_read($handle, $dn, 'objectClass=*', $attributes, 0, 0, 0, LDAP_DEREF_NEVER);
if ($sr) {
$entries = ldap_get_entries($handle, $sr);
if ($entries) {
@ -1018,7 +992,7 @@ function ldapListDN($dn, $filter = '(objectclass=*)', $attributes = array('dn'),
$handle = $_SESSION['ldap']->server();
}
$return = null;
$sr = @ldap_list($handle, escapeDN($dn), $filter, $attributes, 0, $limit, 0, LDAP_DEREF_NEVER);
$sr = @ldap_list($handle, $dn, $filter, $attributes, 0, $limit, 0, LDAP_DEREF_NEVER);
if ($sr) {
$entries = ldap_get_entries($handle, $sr);
if ($entries) {
@ -1354,11 +1328,14 @@ function extractRDN(?string $dn): ?string {
if (empty($dn)) {
return null;
}
$dn = convertCommaEscaping($dn);
$parts = ldap_explode_dn($dn, 0);
if (empty($parts[0])) {
return null;
}
return $parts[0];
$rdn = unescapeLdapSpecialCharacters($parts[0]);
$rdn = str_replace(',', '\\2C', $rdn);
return $rdn;
}
/**
@ -1374,8 +1351,15 @@ function extractDNSuffix($dn) {
}
$dn = convertCommaEscaping($dn);
$parts = ldap_explode_dn($dn, 0);
if ($parts === false) {
return null;
}
unset($parts['count']);
array_shift($parts);
for ($i = 0; $i < sizeof($parts); $i++) {
$parts[$i] = unescapeLdapSpecialCharacters($parts[$i]);
$parts[$i] = str_replace(',', '\\2C', $parts[$i]);
}
return implode(',', $parts);
}

View file

@ -1643,7 +1643,7 @@ class accountContainer {
$modTmp = new $module($this->type->getScope());
$searchAttrs = array_merge($searchAttrs, $modTmp->getManagedHiddenAttributes($this->type->getId()));
}
$result = @ldap_read($_SESSION['ldap']->server(), escapeDN($dn), $filter, $searchAttrs, 0, 0, 0, LDAP_DEREF_NEVER);
$result = @ldap_read($_SESSION['ldap']->server(), $dn, $filter, $searchAttrs, 0, 0, 0, LDAP_DEREF_NEVER);
if (!$result) {
return array(array("ERROR", _("Unable to load LDAP entry:") . " " . htmlspecialchars($dn), getDefaultLDAPErrorString($_SESSION['ldap']->server())));
}
@ -1879,28 +1879,28 @@ class accountContainer {
}
// build DN for new accounts and change it for existing ones if needed
if (isset($attributes[$this->dn_orig]['modify'][$this->rdn][0])) {
$this->finalDN = $this->rdn . '=' . escapeRDN($attributes[$this->dn_orig]['modify'][$this->rdn][0]) . ',' . $this->dnSuffix;
$this->finalDN = $this->rdn . '=' . ldap_escape($attributes[$this->dn_orig]['modify'][$this->rdn][0], '', LDAP_ESCAPE_DN) . ',' . $this->dnSuffix;
if ($this->dn_orig != $this->finalDN) {
$attributes[$this->finalDN] = $attributes[$this->dn_orig];
unset($attributes[$this->dn_orig]);
}
}
elseif (isset($attributes[$this->dn_orig]['add'][$this->rdn][0])) {
$this->finalDN = $this->rdn . '=' . escapeRDN($attributes[$this->dn_orig]['add'][$this->rdn][0]) . ',' . $this->dnSuffix;
$this->finalDN = $this->rdn . '=' . ldap_escape($attributes[$this->dn_orig]['add'][$this->rdn][0], '', LDAP_ESCAPE_DN) . ',' . $this->dnSuffix;
if ($this->dn_orig != $this->finalDN) {
$attributes[$this->finalDN] = $attributes[$this->dn_orig];
unset($attributes[$this->dn_orig]);
}
}
elseif (isset($attributes[$this->dn_orig]['remove'][$this->rdn][0]) && isset($attributes[$this->dn_orig]['notchanged'][$this->rdn][0])) {
$this->finalDN = $this->rdn . '=' . escapeRDN($attributes[$this->dn_orig]['notchanged'][$this->rdn][0]) . ',' . $this->dnSuffix;
$this->finalDN = $this->rdn . '=' . ldap_escape($attributes[$this->dn_orig]['notchanged'][$this->rdn][0], '', LDAP_ESCAPE_DN) . ',' . $this->dnSuffix;
if ($this->dn_orig != $this->finalDN) {
$attributes[$this->finalDN] = $attributes[$this->dn_orig];
unset($attributes[$this->dn_orig]);
}
}
elseif (!$this->isNewAccount && (($this->dnSuffix != extractDNSuffix($this->dn_orig)) || ($this->rdn != extractRDNAttribute($this->dn_orig)))) {
$this->finalDN = $this->rdn . '=' . escapeRDN($attributes[$this->dn_orig]['notchanged'][$this->rdn][0]) . ',' . $this->dnSuffix;
$this->finalDN = $this->rdn . '=' . ldap_escape($attributes[$this->dn_orig]['notchanged'][$this->rdn][0], '', LDAP_ESCAPE_DN) . ',' . $this->dnSuffix;
$attributes[$this->finalDN] = $attributes[$this->dn_orig];
unset($attributes[$this->dn_orig]);
}
@ -1974,7 +1974,9 @@ class accountContainer {
}
// Set to true if an real error has happened
$stopprocessing = false;
if (strtolower($this->finalDN) != convertCommaEscaping(strtolower($this->dn_orig))) {
$finalDnLower = strtolower($this->finalDN);
$dnOrigLower = strtolower($this->dn_orig);
if (($finalDnLower !== $dnOrigLower) && (unescapeLdapSpecialCharacters($finalDnLower) !== unescapeLdapSpecialCharacters($dnOrigLower))) {
// move existing DN
if ($this->dn_orig != '') {
$removeOldRDN = false;
@ -1984,7 +1986,8 @@ class accountContainer {
$rdnAttr = strtolower(extractRDNAttribute($this->finalDN));
if (isset($attributes[$this->finalDN]['modify'][$rdnAttr])
&& (sizeof($attributes[$this->finalDN]['modify'][$rdnAttr]) == 1)
&& ($attributes[$this->finalDN]['modify'][$rdnAttr][0] == extractRDNValue($this->finalDN))) {
&& (($attributes[$this->finalDN]['modify'][$rdnAttr][0] == extractRDNValue($this->finalDN))
|| (unescapeLdapSpecialCharacters($attributes[$this->finalDN]['modify'][$rdnAttr][0]) == unescapeLdapSpecialCharacters(extractRDNValue($this->finalDN))))) {
// remove old RDN if attribute is single valued
$removeOldRDN = true;
unset($attributes[$this->finalDN]['modify'][extractRDNAttribute($this->finalDN)]);

View file

@ -647,7 +647,7 @@ class kolabUser extends baseModule {
// delegates
if (in_array('kolabDelegate', $fields)) {
$delegates = array();
$sr = @ldap_search($_SESSION['ldapHandle'], escapeDN($this->selfServiceSettings->LDAPSuffix), '(&(objectClass=inetOrgPerson)(mail=*))', array('dn'), 0, 0, 0, LDAP_DEREF_NEVER);
$sr = @ldap_search($_SESSION['ldapHandle'], $this->selfServiceSettings->LDAPSuffix, '(&(objectClass=inetOrgPerson)(mail=*))', array('dn'), 0, 0, 0, LDAP_DEREF_NEVER);
if ($sr) {
$result = ldap_get_entries($_SESSION['ldapHandle'], $sr);
cleanLDAPResult($result);

View file

@ -601,7 +601,7 @@ class posixAccount extends baseModule implements passwordService {
$types = array('gon', 'group');
$gonList = array();
foreach ($types as $type) {
$gonFilter = '(|(&(objectClass=groupOfNames)(member=' . ldap_escape($dn) . '))(&(objectClass=groupOfMembers)(member=' . ldap_escape($dn) . '))(&(objectClass=groupOfUniqueNames)(uniqueMember=' . ldap_escape($dn) . ')))';
$gonFilter = '(|(&(objectClass=groupOfNames)(member=' . ldap_escape($dn, '', LDAP_ESCAPE_FILTER) . '))(&(objectClass=groupOfMembers)(member=' . ldap_escape($dn) . '))(&(objectClass=groupOfUniqueNames)(uniqueMember=' . ldap_escape($dn) . ')))';
if (!empty($typeSettings['filter_' . $type])) {
$typeFilter = $typeSettings['filter_' . $type];
if (strpos($typeFilter, '(') !== 0) {

View file

@ -839,7 +839,7 @@ class TreeView {
$pos = $oldPos;
}
$newRdnValue = $ldapChanges[$rdnAttribute][$pos];
$newRdn = $rdnAttribute . '=' . ldap_escape($newRdnValue);
$newRdn = $rdnAttribute . '=' . ldap_escape($newRdnValue, '', LDAP_ESCAPE_DN);
$parent = extractDNSuffix($dn);
$renameOk = ldap_rename($_SESSION['ldap']->server(), $dn, $newRdn, $parent, true);
$newDn = $newRdn . ',' . $parent;
@ -1166,7 +1166,7 @@ class TreeView {
if (!isset($attributes[$rdnAttribute][0])) {
return $this->createNewNodeCheckObjectClassesStep($dn, _('The RDN field is empty.'), $rdnAttribute, $attributes);
}
$rdn = $rdnAttribute . '=' . ldap_escape($attributes[$rdnAttribute][0]);
$rdn = $rdnAttribute . '=' . ldap_escape($attributes[$rdnAttribute][0], '', LDAP_ESCAPE_DN);
$newDn = $rdn . ',' . $dn;
$success = ldap_add($_SESSION['ldap']->server(), $newDn, $attributes);
if (!$success) {

View file

@ -255,7 +255,7 @@ class ConfiguredType {
$connection = $_SESSION["ldap"]->server();
$ret = array();
$filter = $this->getBaseType()->getSuffixFilter();
$sr = @ldap_search($connection, escapeDN($this->getSuffix()), $filter, array('dn', 'objectClass'), 0, 0, 0, LDAP_DEREF_NEVER);
$sr = @ldap_search($connection, $this->getSuffix(), $filter, array('dn', 'objectClass'), 0, 0, 0, LDAP_DEREF_NEVER);
if ($sr) {
$units = ldap_get_entries($connection, $sr);
cleanLDAPResult($units);

View file

@ -739,7 +739,7 @@ class lamUserList extends lamList {
elseif (($attribute == "jpegphoto") && (!empty($entry[$attribute][0]))) {
if (strlen($entry[$attribute][0]) < 100) {
// looks like we have read broken binary data, reread photo
$result = @ldap_read($_SESSION['ldap']->server(), escapeDN($entry['dn']), $attribute . "=*", array($attribute), 0, 0, 0, LDAP_DEREF_NEVER);
$result = @ldap_read($_SESSION['ldap']->server(), $entry['dn'], $attribute . "=*", array($attribute), 0, 0, 0, LDAP_DEREF_NEVER);
if ($result) {
$tempEntry = @ldap_first_entry($_SESSION['ldap']->server(), $result);
if ($tempEntry) {

View file

@ -353,7 +353,7 @@ if (isset($_POST['delete'])) {
* @return integer number of children
*/
function getChildCount($dn) {
$entries = searchLDAP(escapeDN($dn), 'objectClass=*', array('dn'));
$entries = searchLDAP($dn, 'objectClass=*', array('dn'));
return (sizeof($entries) - 1);
}

View file

@ -61,7 +61,7 @@ if (isset($_POST['add_suff']) || isset($_POST['cancel'])) {
// add entries
foreach ($newSuffixes as $newSuffix) {
// check if entry is already present
$info = @ldap_read($_SESSION['ldap']->server(), escapeDN($newSuffix), "objectclass=*", array('dn'), 0, 0, 0, LDAP_DEREF_NEVER);
$info = @ldap_read($_SESSION['ldap']->server(), $newSuffix, "objectclass=*", array('dn'), 0, 0, 0, LDAP_DEREF_NEVER);
$res = false;
if ($info !== false) {
$res = ldap_get_entries($_SESSION['ldap']->server(), $info);
@ -112,7 +112,7 @@ if (isset($_POST['add_suff']) || isset($_POST['cancel'])) {
$subsuffCount = sizeof($subsuffs);
for ($k = $subsuffCount - 1; $k >= 0; $k--) {
// check if subsuffix is present
$info = @ldap_read($_SESSION['ldap']->server(), escapeDN($subsuffs[$k]), "objectclass=*", array('dn'), 0, 0, 0, LDAP_DEREF_NEVER);
$info = @ldap_read($_SESSION['ldap']->server(), $subsuffs[$k], "objectclass=*", array('dn'), 0, 0, 0, LDAP_DEREF_NEVER);
$res = false;
if ($info !== false) {
$res = ldap_get_entries($_SESSION['ldap']->server(), $info);

View file

@ -77,7 +77,7 @@ $new_suffs = array();
$typeManager = new \LAM\TYPES\TypeManager();
$types = $typeManager->getConfiguredTypes();
foreach ($types as $type) {
$info = @ldap_read($_SESSION['ldap']->server(), escapeDN($type->getSuffix()), "(objectClass=*)", array('objectClass'), 0, 0, 0, LDAP_DEREF_NEVER);
$info = @ldap_read($_SESSION['ldap']->server(), $type->getSuffix(), "(objectClass=*)", array('objectClass'), 0, 0, 0, LDAP_DEREF_NEVER);
if (($info === false) && !in_array($type->getSuffix(), $new_suffs)) {
$new_suffs[] = $type->getSuffix();
continue;

View file

@ -213,9 +213,13 @@ if ($_FILES['inputfile'] && ($_FILES['inputfile']['size'] > 0)) {
if (is_array($rdnValue)) {
$rdnValue = $rdnValue[0];
}
$account_dn = $data[$i][$ids['dn_rdn']] . "=" . escapeRDN($rdnValue) . ",";
if ($data[$i][$ids['dn_suffix']] == "") $account_dn = $account_dn . $suffix;
else $account_dn = $account_dn . $data[$i][$ids['dn_suffix']];
$account_dn = $data[$i][$ids['dn_rdn']] . "=" . ldap_escape($rdnValue, '', LDAP_ESCAPE_DN) . ",";
if ($data[$i][$ids['dn_suffix']] == "") {
$account_dn = $account_dn . $suffix;
}
else {
$account_dn = $account_dn . $data[$i][$ids['dn_suffix']];
}
$accounts[$i]['dn'] = $account_dn;
}
// set overwrite

View file

@ -160,10 +160,19 @@ class AccountTest extends TestCase {
$this->assertEquals('ou=test', extractRDN($dn));
$this->assertEquals('ou', extractRDNAttribute($dn));
$this->assertEquals('test', extractRDNValue($dn));
$dn = 'ou=test,dc=company,dc=com';
$this->assertEquals('ou=test', extractRDN($dn));
$dn = 'ou=tes\\, tä,dc=com\\, pany,dc=com';
$this->assertEquals('ou=tes\\2C tä', extractRDN($dn));
$this->assertEquals('ou', extractRDNAttribute($dn));
$this->assertEquals('test', extractRDNValue($dn));
$this->assertEquals('tes\\2C tä', extractRDNValue($dn));
}
function testExtractDNSuffix() {
$dn = 'test';
$this->assertEquals(null, extractDNSuffix($dn));
$dn = 'ou=test';
$this->assertEquals('', extractDNSuffix($dn));
$dn = 'ou=tes\\, t,dc=com\\, panyä,dc=com';
$this->assertEquals('dc=com\\2C panyä,dc=com', extractDNSuffix($dn));
}
/**