From 855c6d200320d36f1c8c316aebafd135cba34149 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=B4me=20Chilliet?= <come@opensides.be>
Date: Wed, 18 Apr 2018 11:43:45 +0200
Subject: [PATCH] Merge branch
 '5817-unique-dn-creation-way-fail-for-audit-plugin' into '1.3-dev'

Resolve "Unique DN creation may fail for audit plugin"

See merge request fusiondirectory/fd!237

(cherry picked from commit fbc8fa120b53ce9aee09707aa0e7b0fa1330dfac)

c9318823 :ambulance: fix(references) Avoid logging removal of references tab
bca8a84a :sparkles: feat(simpleplugin) Use as many attributes as needed to build a unique DN
7ee453c1 :ambulance: fix(simpleplugin) Limit Cognitive Complexity
d26a71a6 :ambulance: fix(simpleplugin) Fix starting point of loop
ce4896f6 :ambulance: fix(simpleplugin) Fix Cognitive Complexity for Sonar
---
 include/class_Combinations.inc                | 88 +++++++++++++++++++
 include/simpleplugin/class_simplePlugin.inc   | 32 +++----
 .../generic/references/class_reference.inc    |  6 ++
 3 files changed, 110 insertions(+), 16 deletions(-)
 create mode 100644 include/class_Combinations.inc

diff --git a/include/class_Combinations.inc b/include/class_Combinations.inc
new file mode 100644
index 000000000..d0ef2ac59
--- /dev/null
+++ b/include/class_Combinations.inc
@@ -0,0 +1,88 @@
+<?php
+/*
+  This code is part of FusionDirectory (http://www.fusiondirectory.org/)
+  Copyright (C) 2018  FusionDirectory
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
+
+/*!brief Iterator that returns all combinations of $size element from $input array
+ */
+class Combinations implements Iterator
+{
+  protected $current  = NULL;
+  protected $input    = NULL;
+  protected $n        = 0;
+  protected $size     = 0;
+  protected $pos      = 0;
+
+  function __construct($input, $size)
+  {
+    $this->input = array_values($input);
+    $this->n = count($this->input);
+    $this->size = $size;
+    $this->rewind();
+  }
+
+  function key()
+  {
+    return $this->pos;
+  }
+
+  function current()
+  {
+    $r = array();
+    for ($i = 0; $i < $this->size; $i++) {
+      $r[] = $this->input[$this->current[$i]];
+    }
+    return $r;
+  }
+
+  function next()
+  {
+    if ($this->_next()) {
+      $this->pos++;
+    } else {
+      $this->pos = -1;
+    }
+  }
+
+  function rewind()
+  {
+    $this->current  = range(0, $this->size);
+    $this->pos      = 0;
+  }
+
+  function valid()
+  {
+    return ($this->pos >= 0);
+  }
+
+  protected function _next()
+  {
+    $i = $this->size - 1;
+    while (($i >= 0) && ($this->current[$i] == $this->n - $this->size + $i)) {
+      $i--;
+    }
+    if ($i < 0) {
+      return FALSE;
+    }
+    $this->current[$i]++;
+    while ($i++ < $this->size - 1) {
+      $this->current[$i] = $this->current[$i - 1] + 1;
+    }
+    return TRUE;
+  }
+}
diff --git a/include/simpleplugin/class_simplePlugin.inc b/include/simpleplugin/class_simplePlugin.inc
index 38ac3ae2b..8fe11514e 100644
--- a/include/simpleplugin/class_simplePlugin.inc
+++ b/include/simpleplugin/class_simplePlugin.inc
@@ -1731,27 +1731,27 @@ class simplePlugin
 
     /* Try to use plain entry first */
     $dn = $attribute.'='.ldap_escape_dn($this->$attribute).','.$base;
-    if ($dn == $this->orig_dn) {
-      return $dn;
-    }
-    $ldap->cat($dn, array('dn'));
-    if (!$ldap->fetch()) {
+    if (($dn == $this->orig_dn) || !$ldap->dn_exists($dn)) {
       return $dn;
     }
 
-    /* Look for additional attributes */
+    /* Build DN with multiple attributes */
+    $usableAttributes = array();
     foreach ($this->attributes as $attr) {
-      if (($attr == $attribute) || ($this->$attr == '') || is_array($this->$attr)) {
-        continue;
-      }
-
-      $dn = $attribute.'='.ldap_escape_dn($this->$attribute).'+'.$attr.'='.ldap_escape_dn($this->$attr).','.$base;
-      if ($dn == $this->orig_dn) {
-        return $dn;
+      if (($attr != $attribute) && is_string($this->$attr) && ($this->$attr != '')) {
+        $usableAttributes[] = $attr;
       }
-      $ldap->cat($dn, array('dn'));
-      if (!$ldap->fetch()) {
-        return $dn;
+    }
+    for ($i = 1; $i < count($usableAttributes); $i++) {
+      foreach (new Combinations($usableAttributes, $i) as $attrs) {
+        $dn = $attribute.'='.ldap_escape_dn($this->$attribute);
+        foreach ($attrs as $attr) {
+          $dn .= '+'.$attr.'='.ldap_escape_dn($this->$attr);
+        }
+        $dn .= ','.$base;
+        if (($dn == $this->orig_dn) || !$ldap->dn_exists($dn)) {
+          return $dn;
+        }
       }
     }
 
diff --git a/plugins/generic/references/class_reference.inc b/plugins/generic/references/class_reference.inc
index a9ca0aa78..de8b2e5b0 100644
--- a/plugins/generic/references/class_reference.inc
+++ b/plugins/generic/references/class_reference.inc
@@ -83,6 +83,12 @@ class reference extends simplePlugin
 
   function save()
   {
+    return array();
+  }
+
+  function remove($fulldelete = FALSE)
+  {
+    return array();
   }
 }
 
-- 
GitLab