Bug#1057310: bookworm-pu: package gosa/2.8~git20230203.10ab345+dfsg1+deb12u2

Mike Gabriel sunweaver at debian.org
Sun Dec 3 07:44:05 GMT 2023


Package: release.debian.org
Severity: normal
Tags: bookworm
User: release.debian.org at packages.debian.org
Usertags: pu
X-Debbugs-Cc: gosa at packages.debian.org, debian-edu-pkg-team at lists.alioth.debian.org
Control: affects -1 + src:gosa

This upload provides a last-minute fix-up collection of GOsa² for Debian
bookworm.

[ Reason ]
GOsa² is the core user and system management frontend part of Debian Edu.

Over the past months, Daniel Teichmann, Guido Berhörster and myself have
run tons of tests and dived deeply into the badly maintained GOsa²
upstream code. At this point it was no option to replace GOsa² by
something else, so we went down the road of fixing it for Debian Edu.

Unfortunately, at the time of the bookworm freeze, GOsa² was in very bad
shape upstream and not ready for PHP 8.2 (as it is shipped in Debian 12).

Most of those PHP 8.2 issues should be resolved now (for Debian Edu usage
code paths, at least). Please accept this change into the upcoming 12.3
point release. Thanks.

Also, we went over all the patches we shipped with Debian 11's gosa 2.7.x
version and forward ported various of the changes to not run into the
same bug reports again over time.

[ Impact ]
Debian Edu 12 release cannot happen without this bookworm-pu upload for gosa.

[ Tests ]
Many many Manual tests.

[ Risks ]
GOsa² users might be affected, Debian Edu Users might be affected.

We are not saying we have fixed very bug, but GOsa² is back in a state so that people can use it. In Debian Edu or standalone.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]

I won't highlight all of these changes, but a few are important:

+  [ Daniel Teichmann ]
+  * debian/patches:
+    + Add 1007_fix_debugLevel_bitwise_and.patch. Use single ampersand
+      operator for logical and operation (not double ampersand).
+    + Add 1008_main-dont-die-on-empty-config-object.patch. Gracefully exit
+      if config object is unavailable (and report to syslog). (Closes:
+      #1039964).
+    + Add 1009_plugin-callHook-always_output_shell_debugging_msgs.patch.
+      Fix output of shell debugging messages via WebUI.
+    + Add 1044_fix-class-ldap-serialization.patch which fixes a few bugs
+      regarding serialization. This especially fixes setting LDAP userPassword
+      attribute types via GOsa². (Closes: #1052159).

-> this one is important to password changing in Debian Edu and could
only be resolved a few days ago. This has been the last blocker for
uploading this pkg and cause of the delay and the last-minute nature of
this bookworm-pu acceptance request.

+    + Add 1045_fix-posixaccount-shadowExpire.patch which fixes shadowExpire
+      always being set to 0. (User can't login then). (Closes: #1053806).
+
+  [ Guido Berhoerster ]
+  * debian/patches:
+    + Add 1010_fix-fix-accept-to-gettext.patch. Fix PHP errors in accept-to-
+      gettext.inc. This fixes numerous errors due to accessing undefined
+      associative array elements. (Closes: #1043019).
+    + Add 2009-Revert-Enable-env-to-work.patch. Work around broken handling of
+      plugin hook commands in gosa > 2.7.4. (Closes: #1039698, #1039699).
+    + Add 1041_fix-role-selector.patch in order to fix role selection
+    + Add 1042_fix-user-info-default-theme.patch
+
+  [ Mike Gabriel ]
+  * debian/patches:
+    + Add patches 1011 to 1020. Revert nested group feature for GOsa² groups.
+      This feature is completely broken in GOsa² upstream when posixGroups
+      are in use. (Closes: #1049328). Also trivially rebase patches 1009 and
+      2009.

-> This patch series is huge and probably nearly unreviewable. Upstream
development took place over the past 1.5 yrs, unfortunately into a
technically not-working direction. The problem (wrong personel) has been
identified upstream and GOsa² won't continue into that direction.

However, the reverts have not been applied to upstream GOsa² yet, this is
still a process to come.

I have been in close contact with GOsa² upstream recently and we will
need to discuss soon about the future development of GOsa² on the
upstream side.

Until then, as you can guess from this changelog, GOsa² is being
maintained in Debian rather than in the upstream Git. Unfortunately.
Mostly because of Debian Edu depending so heavily on it.

+    + Add 1021_fix-config-parser-being-null.patch. Since PHP 8.x an XML parser
+      must not be null when accessed. It needs to be an instance of XMLParser().
+      (Closes: #1049338).
+    + Re-add 1035_acl_override_to_allow_delete_of_group_members.patch. Allow
+      users with memberUid write access to remove users from posixGroup objects.
+      Related to closing #1049328.
+    + Add 1099_remove-debug-code.patch. Drop unwanted var_dump() call and
+      other print statements.
+    + Add 1022_fix-implicit-conversions-of-float-to-int.patch. Avoid PHP
+      deprecation warning "Deprecated: Implicit conversion from float <floatval>
+      to int loses precision in <php-file>". (Closes: #1043575).
+    + Add 11?? patches. Derived from Debian's gosa 2.7.5 patchset (and ignored
+      first when bringing in gosa 2.8.x, but now re-reviewed and re-applied).
+    + Add 1023_fix-icon-labelling-with-default-theme.patch. Properly render
+      labelled icons if default materialize CSS theme is used. (Closes:
+      #1049400).
+    + Improve 1003_php-deprecations.patch. Silence another 'Deprecated:
+      preg_match(): Passing null to parameter #2 () of type string is
+      deprecated' warning. (Closes: #1049394).
+    + Add 1024_fix-mess-of-using-and-comparing-int-and-string-values.patch.
+      This resolves a dirty class property design for the posixAccount class.
+      This patch attempts at avoiding int-with-string value comparisons for
+      the properties gidNumber (string) and primaryGroup (int). (Closes:
+      #1049344).
+    + Add 1155_fix-uid-generation-when-many-uids-have-been-already-taken.patch
+      from Debian's GOsa² 2.7.5 (never uploaded to Debian, but valid for GOsa²
+      2.8). (Closes: #991545).
+    + Improve 1007_fix_debugLevel_bitwise_and.patch. Default value for
+      debugLevel is an empty string. Assure this gets interpreted as 0
+      debugLevel. (Closes: #1049937).
+    + Add 2010_vacation-templates-writeable-path.patch. Use a folder in
+      /var/lib/ for providing a GOsa²-writeable path for vacation templates.
+      (Closes: #1049938).
+    + Add 1025_fix-icons-in-debugBar.patch. Don't use image() method from
+      GOsa²'s function.inc. The debug toolbar is not themed, so hard-code
+      icon img tags. (Closes: #1049939). This resolves the problem of non-shown
+      icons if the default (Materialize CSS) theme is used.
+    + Add 1026_dont-access-static-property-non-static.patch. Resolves 'Accessing
+      static property LDAP:: as non static'. (Closes: #1049956).
+    + Add patches 1027 - 1033. Fix various PHP errors/warnings reported to
+      syslog. (Closes: #1049942).
+    + Add patches 106?_*.patch. Resolve various issues in GOsa²'s acl class.
+      (Closes: #1049940).
+    + Add 1034_include-class_listing.inc-Fix-processElementFilter-n.patch.
+      include/class_listing.inc: Fix processElementFilter() not considering
+      default values for method parameters. (Closes: #1050489).
+    + Add 1063_include-class_-listing-acl-.inc-plugins-admin-acl-cl.patch.
+      plugins/admin/acl/class_aclRole.inc: Fix accessing variables if they
+      are NULL or keys of arrays which aren't even set. (Closes: #1049940)
+    + Add 1036_include-class_filter.inc-Define-gridClass-for-defaul.patch.
+      include/class_filter.inc: Define gridClass for default and classic theme.
+    + Add 1037_include-php_setup.inc-Hide-ldap_-search-read-Search-.patch.
+      Silence 'Search: No such object.' PHP error messages for ldap_search()
+      and ldap_read(). Those errors are mostly not errors but simply search /
+      query results.
+    + Add 1038_include-class_pathNavigator.inc-Don-t-send-object-DN.patch.
+      Silence 'invalid DN syntax' errors from LDAP server when creating new
+      user objects. (Closes: #1051995).
+    + Add 1040_fix-instance-property-typo-in-class_acl-inc.patch. Fix 'Array
+      to string conversion (/usr/share/gosa/include/class_acl.inc, line 180)'.
+      (Closes: #1051997).
+    + Add 1043a_Add-setter-for-skipFooter-property-needed-for-mfa-ex.patch.
+      Add modifier for skipFooter protected class property. Required for
+      gosa-plugins-privacyidea.
+    + Add 1043b_honour-plugin-property-skipFooter-used-by-mfa-account.patch.
+      Honour plugin property 'skipFooter'.
+  * debian/gosa.{dirs,links,postinst}:
+    + Provide /var/lib/gosa/vacation and symlink to it from /etc/gosa.
+  * debian/rules:
+    + Symlink the smarty4 version of the smarty-gettext plugin to DATADIR/
+      gosa/include/smartyAddons/.

-> This last change is also important: In our tests we used GOsa with
smarty4 all the time. Also in d/control, smarty4 got referenced. Only
last minute we discovered that in the gosa bin:pkg we would still symlink
to the smarty3 code. This change might seem disruptive to existing GOsa
installation, but it is not, because smarty4 is much more PHP 8.2
compliant than smarty3.

[ Other info ]
Unfortunately, acceptance this bookworm-pu is vital for being able to release Debian Edu 12.
-------------- next part --------------
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/changelog gosa-2.8~git20230203.10abe45+dfsg/debian/changelog
--- gosa-2.8~git20230203.10abe45+dfsg/debian/changelog	2023-07-12 23:12:05.000000000 +0200
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/changelog	2023-12-03 08:16:31.000000000 +0100
@@ -1,3 +1,110 @@
+gosa (2.8~git20230203.10abe45+dfsg-1+deb12u2) bookworm; urgency=medium
+
+  [ Daniel Teichmann ]
+  * debian/patches:
+    + Add 1007_fix_debugLevel_bitwise_and.patch. Use single ampersand
+      operator for logical and operation (not double ampersand).
+    + Add 1008_main-dont-die-on-empty-config-object.patch. Gracefully exit
+      if config object is unavailable (and report to syslog). (Closes:
+      #1039964).
+    + Add 1009_plugin-callHook-always_output_shell_debugging_msgs.patch.
+      Fix output of shell debugging messages via WebUI.
+    + Add 1044_fix-class-ldap-serialization.patch which fixes a few bugs
+      regarding serialization. This especially fixes setting LDAP userPassword
+      attribute types via GOsa². (Closes: #1052159).
+    + Add 1045_fix-posixaccount-shadowExpire.patch which fixes shadowExpire
+      always being set to 0. (User can't login then). (Closes: #1053806).
+
+  [ Guido Berhoerster ]
+  * debian/patches:
+    + Add 1010_fix-fix-accept-to-gettext.patch. Fix PHP errors in accept-to-
+      gettext.inc. This fixes numerous errors due to accessing undefined
+      associative array elements. (Closes: #1043019).
+    + Add 2009-Revert-Enable-env-to-work.patch. Work around broken handling of
+      plugin hook commands in gosa > 2.7.4. (Closes: #1039698, #1039699).
+    + Add 1041_fix-role-selector.patch in order to fix role selection
+    + Add 1042_fix-user-info-default-theme.patch
+
+  [ Mike Gabriel ]
+  * debian/patches:
+    + Add patches 1011 to 1020. Revert nested group feature for GOsa² groups.
+      This feature is completely broken in GOsa² upstream when posixGroups
+      are in use. (Closes: #1049328). Also trivially rebase patches 1009 and
+      2009.
+    + Add 1021_fix-config-parser-being-null.patch. Since PHP 8.x an XML parser
+      must not be null when accessed. It needs to be an instance of XMLParser().
+      (Closes: #1049338).
+    + Re-add 1035_acl_override_to_allow_delete_of_group_members.patch. Allow
+      users with memberUid write access to remove users from posixGroup objects.
+      Related to closing #1049328.
+    + Add 1099_remove-debug-code.patch. Drop unwanted var_dump() call and
+      other print statements.
+    + Add 1022_fix-implicit-conversions-of-float-to-int.patch. Avoid PHP
+      deprecation warning "Deprecated: Implicit conversion from float <floatval>
+      to int loses precision in <php-file>". (Closes: #1043575).
+    + Add 11?? patches. Derived from Debian's gosa 2.7.5 patchset (and ignored
+      first when bringing in gosa 2.8.x, but now re-reviewed and re-applied).
+    + Add 1023_fix-icon-labelling-with-default-theme.patch. Properly render
+      labelled icons if default materialize CSS theme is used. (Closes:
+      #1049400).
+    + Improve 1003_php-deprecations.patch. Silence another 'Deprecated:
+      preg_match(): Passing null to parameter #2 () of type string is
+      deprecated' warning. (Closes: #1049394).
+    + Add 1024_fix-mess-of-using-and-comparing-int-and-string-values.patch.
+      This resolves a dirty class property design for the posixAccount class.
+      This patch attempts at avoiding int-with-string value comparisons for
+      the properties gidNumber (string) and primaryGroup (int). (Closes:
+      #1049344).
+    + Add 1155_fix-uid-generation-when-many-uids-have-been-already-taken.patch
+      from Debian's GOsa² 2.7.5 (never uploaded to Debian, but valid for GOsa²
+      2.8). (Closes: #991545).
+    + Improve 1007_fix_debugLevel_bitwise_and.patch. Default value for
+      debugLevel is an empty string. Assure this gets interpreted as 0
+      debugLevel. (Closes: #1049937).
+    + Add 2010_vacation-templates-writeable-path.patch. Use a folder in
+      /var/lib/ for providing a GOsa²-writeable path for vacation templates.
+      (Closes: #1049938).
+    + Add 1025_fix-icons-in-debugBar.patch. Don't use image() method from
+      GOsa²'s function.inc. The debug toolbar is not themed, so hard-code
+      icon img tags. (Closes: #1049939). This resolves the problem of non-shown
+      icons if the default (Materialize CSS) theme is used.
+    + Add 1026_dont-access-static-property-non-static.patch. Resolves 'Accessing
+      static property LDAP:: as non static'. (Closes: #1049956).
+    + Add patches 1027 - 1033. Fix various PHP errors/warnings reported to
+      syslog. (Closes: #1049942).
+    + Add patches 106?_*.patch. Resolve various issues in GOsa²'s acl class.
+      (Closes: #1049940).
+    + Add 1034_include-class_listing.inc-Fix-processElementFilter-n.patch.
+      include/class_listing.inc: Fix processElementFilter() not considering
+      default values for method parameters. (Closes: #1050489).
+    + Add 1063_include-class_-listing-acl-.inc-plugins-admin-acl-cl.patch.
+      plugins/admin/acl/class_aclRole.inc: Fix accessing variables if they
+      are NULL or keys of arrays which aren't even set. (Closes: #1049940)
+    + Add 1036_include-class_filter.inc-Define-gridClass-for-defaul.patch.
+      include/class_filter.inc: Define gridClass for default and classic theme.
+    + Add 1037_include-php_setup.inc-Hide-ldap_-search-read-Search-.patch.
+      Silence 'Search: No such object.' PHP error messages for ldap_search()
+      and ldap_read(). Those errors are mostly not errors but simply search /
+      query results.
+    + Add 1038_include-class_pathNavigator.inc-Don-t-send-object-DN.patch.
+      Silence 'invalid DN syntax' errors from LDAP server when creating new
+      user objects. (Closes: #1051995).
+    + Add 1040_fix-instance-property-typo-in-class_acl-inc.patch. Fix 'Array
+      to string conversion (/usr/share/gosa/include/class_acl.inc, line 180)'.
+      (Closes: #1051997).
+    + Add 1043a_Add-setter-for-skipFooter-property-needed-for-mfa-ex.patch.
+      Add modifier for skipFooter protected class property. Required for
+      gosa-plugins-privacyidea.
+    + Add 1043b_honour-plugin-property-skipFooter-used-by-mfa-account.patch.
+      Honour plugin property 'skipFooter'.
+  * debian/gosa.{dirs,links,postinst}:
+    + Provide /var/lib/gosa/vacation and symlink to it from /etc/gosa.
+  * debian/rules:
+    + Symlink the smarty4 version of the smarty-gettext plugin to DATADIR/
+      gosa/include/smartyAddons/.
+
+ -- Mike Gabriel <sunweaver at debian.org>  Sun, 03 Dec 2023 08:16:31 +0100
+
 gosa (2.8~git20230203.10abe45+dfsg-1+deb12u1) bookworm; urgency=medium
 
   [ Mike Gabriel ]
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.dirs gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.dirs
--- gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.dirs	2019-12-16 11:43:58.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.dirs	2023-08-17 07:32:24.000000000 +0200
@@ -2,3 +2,4 @@
 usr/share/gosa
 var/spool/gosa
 var/cache/gosa
+var/lib/gosa/vacation
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.links gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.links
--- gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.links	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.links	2023-08-17 07:32:24.000000000 +0200
@@ -0,0 +1 @@
+var/lib/gosa/vacation etc/gosa/vacation
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.postinst gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.postinst
--- gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.postinst	2023-01-21 20:42:25.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/gosa.postinst	2023-08-17 07:32:24.000000000 +0200
@@ -131,7 +131,10 @@
 chmod 770 -R /var/spool/gosa
 chown root:$WEBGROUP -R /var/cache/gosa
 chmod 770 -R /var/cache/gosa
-
 update-gosa
 
+# provide a writeable path for vacation messages
+chown root:$WEBGROUP -R /var/lib/gosa/vacation
+chmod 770 -R /var/lib/gosa/vacation
+
 exit 0
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1003_php-deprecations.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1003_php-deprecations.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1003_php-deprecations.patch	2023-07-12 23:10:08.000000000 +0200
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1003_php-deprecations.patch	2023-08-17 07:43:38.000000000 +0200
@@ -58,3 +58,11 @@
                              if (preg_match("<.*type=.submit..*>", $column) || preg_match("<a.*href=.*>", $column)) {
                                  $result.= "   <td$first>".$column."</td>\n";
                              } else {
+@@ -454,6 +455,7 @@
+ 
+                         foreach ($this->displayData[$row] as $column) {
+                             // Do NOT use the onClick statement for columns that contain links or buttons.
++                            $column = is_null($column) ? "" : $column;
+                             if (preg_match("<.*type=.submit..*>", $column) || preg_match("<a.*href=.*>", $column)) {
+                                 $result.= "   <td class='last-column'>".$column."</td>";
+                             } else {
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1007_fix_debugLevel_bitwise_and.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1007_fix_debugLevel_bitwise_and.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1007_fix_debugLevel_bitwise_and.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1007_fix_debugLevel_bitwise_and.patch	2023-08-17 07:32:24.000000000 +0200
@@ -0,0 +1,11 @@
+--- a/include/functions.inc
++++ b/include/functions.inc
+@@ -246,7 +246,7 @@
+     if($config instanceOf config){
+         $debugLevel = $config->get_cfg_value('core', 'debugLevel');
+     }
+-    if ($debugLevel && $level){
++    if (intval($debugLevel) & $level){ // Make bitwise AND operation.
+         $output= "DEBUG[$level] ";
+         if ($function != ""){
+             $output.= "($file:$function():$line) - $info: ";
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1008_main-dont-die-on-empty-config-object.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1008_main-dont-die-on-empty-config-object.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1008_main-dont-die-on-empty-config-object.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1008_main-dont-die-on-empty-config-object.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,14 @@
+--- a/html/main.php
++++ b/html/main.php
+@@ -77,7 +77,10 @@
+ 
+ $config = session::global_get('config');
+ if (!isset($config)) {
+-  die("Could not get config object. Please contact your system administrator or try again later.\n");
++  #die("Could not get config object. Please contact your system administrator or try again later.\n");
++  new log("security","login","",array(),"main.php called with empty config object. Logging user out.") ;
++  header ("Location: logout.php");
++  exit;
+ }
+ 
+ $config->check_and_reload();
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1009_plugin-callHook-always_output_shell_debugging_msgs.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1009_plugin-callHook-always_output_shell_debugging_msgs.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1009_plugin-callHook-always_output_shell_debugging_msgs.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1009_plugin-callHook-always_output_shell_debugging_msgs.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,36 @@
+--- a/include/class_plugin.inc
++++ b/include/class_plugin.inc
+@@ -1725,12 +1725,19 @@
+                   // Close the process and check its return value
+                   $returnCode = proc_close($process);
+                   $returnOutput = preg_split("/\n/", $arr,0,PREG_SPLIT_NO_EMPTY);
++                  if (!is_array($returnOutput)) {
++                    $returnOutput = array(); // Make sure returnOutput is always an array.
++                  }
++
+                   $errorOutput = preg_split("/\n/",$err,0,PREG_SPLIT_NO_EMPTY);
++                  if (!is_array($errorOutput)) {
++                    $errorOutput = array(); // Make sure returnOutput is always an array.
++                  }
+               }
+ 
+               if($returnCode != 0){
+-                  @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execution failed code: ".$returnCode);
+-                  @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Result: ".$err);
++                  @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execution failed code: " . $returnCode);
++                  @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Failure result: " . $err);
+                   if($displayErrors){
+                       $message= msgPool::cmdexecfailed($cmd,$command, get_class($plugin));
+                       msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
+@@ -1738,8 +1745,9 @@
+                       $message= msgPool::cmdexecfailed($cmd,"...", get_class($plugin));
+                       msg_dialog::display(_("Error"), $message, ERROR_DIALOG);
+                   }
+-              }elseif(is_array($arr)){
+-                  @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Result: ".$arr);
++              } else {
++                @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Success result (stdout):<br>" . implode("<br>", $returnOutput));
++                @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Success result (stderr):<br>" . implode("<br>", $errorOutput));
+               }
+           } elseif($displayErrors) {
+               $message= msgPool::cmdinvalid($cmd,$command, get_class($plugin));
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1010_fix-fix-accept-to-gettext.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1010_fix-fix-accept-to-gettext.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1010_fix-fix-accept-to-gettext.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1010_fix-fix-accept-to-gettext.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,40 @@
+--- gosa.orig/include/accept-to-gettext.inc
++++ gosa/include/accept-to-gettext.inc
+@@ -85,9 +85,9 @@ function find_match($curlscore,$curcscor
+ 
+ function al2gt($gettextlangs, $mime) {
+   /* default to "everything is acceptable", as RFC2616 specifies */
+-  $acceptLang=(($_SERVER["HTTP_ACCEPT_LANGUAGE"] == '') ? '*' :
++  $acceptLang=(($_SERVER["HTTP_ACCEPT_LANGUAGE"] ?? '' == '') ? '*' :
+   	$_SERVER["HTTP_ACCEPT_LANGUAGE"]);
+-  $acceptChar=(($_SERVER["HTTP_ACCEPT_CHARSET"] == '') ? '*' :
++  $acceptChar=(($_SERVER["HTTP_ACCEPT_CHARSET"] ?? '' == '') ? '*' :
+   	$_SERVER["HTTP_ACCEPT_CHARSET"]);
+   $alparts=@preg_split("/,/",$acceptLang);
+   $acparts=@preg_split("/,/",$acceptChar);
+@@ -147,12 +147,12 @@ function al2gt($gettextlangs, $mime) {
+     $noct=@preg_split("/-/",$allang);
+ 
+     $testvals=array(
+-         array($alscores[$allang], $acscores[$gtcs]),
+-	 array($alscores[$noct[0]], $acscores[$gtcs]),
+-	 array($alscores[$allang], $acscores["*"]),
+-	 array($alscores[$noct[0]], $acscores["*"]),
+-	 array($alscores["*"], $acscores[$gtcs]),
+-	 array($alscores["*"], $acscores["*"]));
++         array($alscores[$allang] ?? null, $acscores[$gtcs] ?? null),
++	 array($alscores[$noct[0]] ?? null, $acscores[$gtcs] ?? null),
++	 array($alscores[$allang] ?? null, $acscores["*"] ?? null),
++	 array($alscores[$noct[0]] ?? null, $acscores["*"] ?? null),
++	 array($alscores["*"] ?? null, $acscores[$gtcs] ?? null),
++	 array($alscores["*"] ?? null, $acscores["*"] ?? null));
+ 
+     $found=FALSE;
+     foreach($testvals as $tval) {
+@@ -182,4 +182,4 @@ function al2gt($gettextlangs, $mime) {
+ }
+ 
+ // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
+-?>
+\ No newline at end of file
++?>
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1011_Revert-bugfix-for-users-group-membership-after-group.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1011_Revert-bugfix-for-users-group-membership-after-group.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1011_Revert-bugfix-for-users-group-membership-after-group.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1011_Revert-bugfix-for-users-group-membership-after-group.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,135 @@
+From 74bd0bb635138c0f3269dd773734060f2eef8694 Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Sun, 13 Aug 2023 17:54:18 +0200
+Subject: [PATCH 1/9] Revert "bugfix for users group membership after groups
+ extensions."
+
+This reverts commit e2f756f23cc9477c2d91820c1f083347e8fa4b60.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ plugins/admin/groups/class_group.inc          | 22 ++++++++-----------
+ plugins/personal/posix/class_posixAccount.inc | 17 +++++---------
+ 2 files changed, 15 insertions(+), 24 deletions(-)
+
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -244,8 +244,8 @@
+                 $action = $this->$list->getAction();
+                 if($action['action'] == 'delete' && preg_match("/w/",$this->getacl("member"))){
+                     foreach ($action['targets'] as $id){
+-                        $value = $this->$list->getData($id);
+-                        $this->removeMember($value['dn']);
++                        $value = $this->$list->getKey($id);
++                        $this->removeMember($value);
+                     }
+                 }
+             }
+@@ -547,12 +547,10 @@
+     }
+ 
+     // remove the member using the array id
+-    function removeMember($dn)
++    function removeMember($id)
+     {
+-        foreach ($this->members as $key => $member) {
+-            if ($dn == $member['dn']) {
+-                unset($this->members[$key]);
+-            }
++        if(isset($this->members[$id])){
++            unset($this->members[$id]);
+         }
+ 
+         /** 
+@@ -562,10 +560,8 @@
+          * So we have to remove the specified member from both arrays.
+         */ 
+         if($this->multiple_support_active){
+-            foreach ($this->members_used_by_some as $key => $member) {
+-                if ($dn == $member) {
+-                    unset($this->members_used_by_some[$key]);
+-                }
++            if(isset($this->members_used_by_some[$id])){
++                unset($this->members_used_by_some[$id]);
+             }
+         }
+     }
+@@ -822,7 +818,7 @@
+             }
+             $this->attrs['member']= $temp;
+         }else {
+-            $this->attrs['member'] = [$this->dn];
++            $this->attrs['member'][]= $this->dn;
+         }
+ 
+         // Save data. Using 'modify' implies that the entry is already present, 
+@@ -831,7 +827,7 @@
+         if ($ldap->fetch()){
+             // Modify needs array() to remove values :-( 
+             if (!count($this->members)){
+-                $this->attrs['member']= [$this->dn];
++                $this->attrs['member'][]= $this->dn;;
+             }
+             if (!$this->smbgroup){
+                 $this->attrs['sambaGroupType']= array();
+--- a/plugins/personal/posix/class_posixAccount.inc
++++ b/plugins/personal/posix/class_posixAccount.inc
+@@ -3,7 +3,7 @@
+  * This code is part of GOsa (http://www.gosa-project.org)
+  * Copyright (C) 2003-2008 GONICUS GmbH
+  *
+- * ID: $$Id: class_posixAccount.inc 21142 2012-05-02 12:24:10Z hickert $$
++ * ID: $$Id$$
+  *
+  * 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
+@@ -178,7 +178,7 @@
+       /* Get group membership */
+       $this->groupListData = array();
+       $ldap->cd($this->config->current['BASE']);
+-      $ldap->search("(&(objectClass=posixGroup)(member=".$dn."))", array("cn", "description"));
++      $ldap->search("(&(objectClass=posixGroup)(memberUid=".$this->uid."))", array("cn", "description"));
+ 
+       while ($attrs= $ldap->fetch()){
+         if (!isset($attrs["description"][0])){
+@@ -485,11 +485,7 @@
+       $smarty->assign("groupMembership_some", set_post($this->groupMembership_some));
+     }
+ 
+-    if (count($this->groupMembership) > 16){
+-      $smarty->assign("groups", "too_many_for_nfs");
+-    } else {
+-      $smarty->assign("groups", "");
+-    }
++    $smarty->assign("groups", "");
+ 
+     /* Avoid "Undefined index: forceMode" */
+     $smarty->assign("forceMode", "");
+@@ -884,7 +880,7 @@
+       if (!isset($this->savedGroupMembership[$key])){
+         $g= new grouptabs($this->config,$this->config->data['TABS']['GROUPTABS'], $key,"groups");
+         $g->set_acl_base($key);
+-        $g->by_object['group']->addMember($this->dn);
++        $g->by_object['group']->addUser($this->uid);
+         $g->save();
+       }
+     }
+@@ -894,7 +890,7 @@
+       if (!isset($this->groupMembership[$key])){
+         $g= new grouptabs($this->config,$this->config->data['TABS']['GROUPTABS'], $key,"groups");
+         $g->set_acl_base($key);
+-        $g->by_object['group']->removeMember($this->dn);
++        $g->by_object['group']->removeUser ($this->uid);
+         $g->save();
+       }
+     }
+@@ -1178,8 +1174,7 @@
+     }
+ 
+     /* Adjust shadow checkboxes */
+-    foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
+-          "shadowExpire") as $val){
++    foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive") as $val){
+       if ($this->$val != 0){
+         $oval= "activate_".$val;
+         $this->$oval= "1";
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1012_Revert-fix-member-array-if-no-member-is-present.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1012_Revert-fix-member-array-if-no-member-is-present.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1012_Revert-fix-member-array-if-no-member-is-present.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1012_Revert-fix-member-array-if-no-member-is-present.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,46 @@
+From 4502d2867808ccaef37fd98dfc7a7b9b7c6a8a9c Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Sun, 13 Aug 2023 17:54:20 +0200
+Subject: [PATCH 2/9] Revert "fix member array if no member is present"
+
+This reverts commit 8e5da7d93fc7a5864a5378d2f2466c6f3d03bd47.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ plugins/admin/groups/class_group.inc | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -818,7 +818,7 @@
+             }
+             $this->attrs['member']= $temp;
+         }else {
+-            $this->attrs['member'][]= $this->dn;
++            $this->attrs['member']= $this->dn;
+         }
+ 
+         // Save data. Using 'modify' implies that the entry is already present, 
+@@ -827,7 +827,7 @@
+         if ($ldap->fetch()){
+             // Modify needs array() to remove values :-( 
+             if (!count($this->members)){
+-                $this->attrs['member'][]= $this->dn;;
++                $this->attrs['member']= $this->dn;;
+             }
+             if (!$this->smbgroup){
+                 $this->attrs['sambaGroupType']= array();
+@@ -853,9 +853,11 @@
+                 msg_dialog::display(_("Warning"),sprintf(_("The gidNumber '%s' is already in use by %s!"),$this->gidNumber,$cns) , WARNING_DIALOG );
+             }
+         }
+-
++        
+         // check if members are added to the group and delete redundancies
+-        $this->attrs['member'] = array_unique($this->attrs['member']);
++        if ($this->dn !== $this->attrs['member'] && !in_array($this->dn, $this->attrs['member'])) {
++            $this->attrs['member'] = array_unique($this->attrs['member']);
++        }
+ 
+         // if the member array is empty nothing is saved or updated
+         if (count($this->attrs['member'])) {
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1013_Revert-update-for-generic.tpl-to-use-memberACL-inste.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1013_Revert-update-for-generic.tpl-to-use-memberACL-inste.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1013_Revert-update-for-generic.tpl-to-use-memberACL-inste.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1013_Revert-update-for-generic.tpl-to-use-memberACL-inste.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,116 @@
+From 1aa8fa3ae0a8e458b63b1ce5bf61b3818e76b5f3 Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Sun, 13 Aug 2023 18:13:14 +0200
+Subject: [PATCH 3/9] Revert "update for generic.tpl to use memberACL instead
+ of memberUidACL"
+
+This reverts a variant of commit 0717777a19790e490fe436367069f9341d6577bc.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ plugins/admin/groups/classic/generic.tpl | 16 ++++++++--------
+ plugins/admin/groups/default/generic.tpl | 10 +++++-----
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/plugins/admin/groups/classic/generic.tpl b/plugins/admin/groups/classic/generic.tpl
+index 0f8f3e171..664ee15a9 100644
+--- a/plugins/admin/groups/classic/generic.tpl
++++ b/plugins/admin/groups/classic/generic.tpl
+@@ -1,4 +1,4 @@
+-{if $multiple_support}
++[6~{if $multiple_support}
+ <input type="hidden" value="1" name="group_mulitple_edit">
+ {/if}
+ 
+@@ -198,11 +198,11 @@
+             {if $restrictedByDynGroup}
+             <b>{t}The group members are part of a dyn-group and cannot be managed!{/t}</b>
+             {if $multiple_support}
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$commonList}
+             {/render}
+             {else}
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$memberList}
+             {/render}
+             {/if}
+@@ -210,24 +210,24 @@
+ 
+             {if $multiple_support}
+             <h3>{t}Common group members{/t}</h3>
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$commonList}
+             {/render}
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             <button type='submit' name='edit_membership'>{msgPool type=addButton}</button>
+             {/render}
+ 
+             <br>
+             <h3>{t}Partial group members{/t}</h3>
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$partialList}
+             {/render}
+             {else}
+             <h3>{t}Group members{/t}</h3>
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$memberList}
+             {/render}
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             <button type='submit' name='edit_membership'>{msgPool type=addButton}</button>
+             {/render}
+             {/if}
+diff --git a/plugins/admin/groups/default/generic.tpl b/plugins/admin/groups/default/generic.tpl
+index 40caa0712..cc7bae63b 100644
+--- a/plugins/admin/groups/default/generic.tpl
++++ b/plugins/admin/groups/default/generic.tpl
+@@ -133,13 +133,13 @@
+ 
+             {if $multiple_support}
+ 
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$commonList}
+             {/render}
+ 
+             {else}
+ 
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$memberList}
+             {/render}
+ 
+@@ -148,21 +148,21 @@
+             {if $multiple_support}
+             <h3 class="card-title">{t}Common group members{/t}</h3>
+ 
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$commonList}
+             <button class="btn-small" type='submit' name='edit_membership'>{msgPool type=addButton}</button>
+             {/render}
+ 
+             <h3 class="card-title">{t}Partial group members{/t}</h3>
+ 
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$partialList}
+             {/render}
+ 
+             {else}
+             <h3 class="card-title">{t}Group members{/t}</h3>
+ 
+-            {render acl=$memberACL}
++            {render acl=$memberUidACL}
+             {$memberList}
+             <button class="btn-small" type='submit' name='edit_membership'>{msgPool type=addButton}</button>
+             {/render}
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1014_Revert-source-code-and-definition-adjustments-for-th.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1014_Revert-source-code-and-definition-adjustments-for-th.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1014_Revert-source-code-and-definition-adjustments-for-th.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1014_Revert-source-code-and-definition-adjustments-for-th.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,55 @@
+From eade627d86e6a8178ff9e95a7e16444b776a01e0 Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Sun, 13 Aug 2023 18:20:41 +0200
+Subject: [PATCH 4/9] Revert "source code and definition adjustments for the
+ group extension. v0.2"
+
+This reverts a clean-up variant of commit 7e825c162dd8841b338fcb0e052f4f04d5a0073f.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ plugins/admin/groups/class_group.inc | 16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -546,7 +546,7 @@
+         }
+     }
+ 
+-    // remove the member using the array id
++
+     function removeMember($id)
+     {
+         if(isset($this->members[$id])){
+@@ -569,12 +569,17 @@
+     // reload and receive data from the LDAP
+     function reload(array $attrs)
+     {
+-        unset($attrs['member']['count']);
+-        $arr= array();
+         if (isset($attrs['member'][0])){
++            $tmp= array();
++            $arr= array();
++            foreach ($attrs['member'] as $member => $dn) {
++                if ($member !== 'count') {
++                    $tmp[$member]= $dn;
++                }
++            }
+             $ldap= $this->config->get_ldap_link();
+             $ldap->cd($this->config->current['BASE']);
+-            foreach ($attrs['member'] as $member => $dn) {
++            foreach ($tmp as $member => $dn) {
+                 $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
+                 while ($attr = $ldap->fetch()) {
+                     $arr[$attr['cn'][0]]= $attr;
+@@ -1153,6 +1158,9 @@
+     // Initialize plugin with given atribute arrays 
+     function init_multiple_support($attrs,$all)
+     {
++        $ldap = $this->config->get_ldap_link();
++        $ldap->cd($this->config->current['BASE']);
++
+         plugin::init_multiple_support($attrs,$all);
+         $this->trustModeDialog->init_multiple_support($attrs,$all);
+ 
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1015_Revert-source-code-and-definition-adjustments-for-th.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1015_Revert-source-code-and-definition-adjustments-for-th.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1015_Revert-source-code-and-definition-adjustments-for-th.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1015_Revert-source-code-and-definition-adjustments-for-th.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,24 @@
+From 6ead18a30ed79263d81ae3b4cda0cc87c86cfa32 Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Mon, 14 Aug 2023 07:51:01 +0200
+Subject: [PATCH 5/9] Revert "source code and definition adjustments for the
+ group extension. v0.1"
+
+This reverts a variant of commit 51905d512cfa404945223f8c786bbfff227e0df9.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ include/class_filter.inc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/include/class_filter.inc
++++ b/include/class_filter.inc
+@@ -305,7 +305,7 @@
+     public function constraintFilter(array $constraints, array $res)
+     {
+         $tmp = [];
+-        /* Check for every occurenc of the contraints and sort them out */
++	/* Check for every occurence of the contraints and sort them <output></output> */
+         for ($i = 0; $i < count($res); ++$i) {
+             foreach ($constraints as $filter => $value) {
+                 if (!in_array($res[$i][$filter], $value)) {
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1016_Revert-source-code-and-definition-adjustments-for-th.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1016_Revert-source-code-and-definition-adjustments-for-th.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1016_Revert-source-code-and-definition-adjustments-for-th.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1016_Revert-source-code-and-definition-adjustments-for-th.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,790 @@
+From feea4012aab7f593e2b251bc5be0c66b4542f227 Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Mon, 14 Aug 2023 07:51:48 +0200
+Subject: [PATCH 6/9] Revert "source code and definition adjustments for the
+ group extension. v0.3"
+
+This reverts a variant of commit 084b4ede95e74b76343e6f3f4c73e31c8dda7aa0.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ plugins/admin/groups/class_group.inc | 250 ++++++++++++++-------------
+ 1 file changed, 126 insertions(+), 124 deletions(-)
+
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -1,5 +1,5 @@
+ <?php
+-/**
++/*
+  * This code is part of GOsa (http://www.gosa-project.org)
+  * Copyright (C) 2003-2008 GONICUS GmbH
+  *
+@@ -18,17 +18,17 @@
+  * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+-*/ 
++ */
+ 
+ #[\AllowDynamicProperties]
+ class group extends plugin
+ {
+-    // Group attributes
++    /* Group attributes */
+     var $cn= "";
+     var $gidNumber= "";
+     var $members_used_by_some= array();
+ 
+-    // Helpers
++    /* Helpers */
+     var $base= "";
+     var $force_gid= FALSE;
+     var $fon_group= FALSE;
+@@ -57,7 +57,7 @@
+     var $baseSelector;
+     var $dns= array();
+ 
+-    // attribute list for save action
++    /* attribute list for save action */
+     var $attributes= array("cn", "description", "gidNumber","sambaGroupType","sambaSID","member");
+     var $objectclasses= array("top");
+     var $CopyPasteVars  = array("force_gid","fon_group","smbgroup","groupType","sambaSID","sambaDomainName","SID","nagios_group","sambaGroupType");
+@@ -70,7 +70,7 @@
+ 
+     function __construct(&$config, $dn= NULL)
+     {
+-        // Set rfc2307bis flag
++        /* Set rfc2307bis flag */
+         if ($config->get_cfg_value("core","rfc2307bis") == "true"){
+             $this->rfc2307bis= TRUE;
+             $this->attributes[]= "member";
+@@ -82,19 +82,19 @@
+         $this->trustModeDialog = new trustModeDialog($this->config, $this->dn,NULL);
+         $this->trustModeDialog->setAcl('groups/group');
+ 
+-        // Load attributes depending on the samba version
++        /* Load attributes depending on the samba version */
+         $this->orig_dn= $dn;
+         $this->orig_cn= $this->cn;
+ 
+-        // get Member list
++        /* Get member list */
+         $this->members =$this->reload($this->attrs);
+ 
+-        // Save gidNumber for later use
++        /* Save gidNumber for later use */
+         if (isset($this->attrs['gidNumber'])){
+             $this->saved_gidNumber= $this->attrs['gidNumber'][0];
+         }
+ 
+-        // Is a samba group?
++        /* Is a samba group? */
+         if (isset($this->attrs['objectClass'])){
+             if (array_search ('sambaGroupMapping', $this->attrs['objectClass']) == FALSE ){
+                 $this->smbgroup= FALSE;
+@@ -116,12 +116,12 @@
+             }
+         }
+ 
+-        // Set mail flag
++        /* Set mail flag */
+         if (isset($this->attrs['objectClass']) && in_array_strict('gosaMailAccount', $this->attrs['objectClass'])){
+             $this->has_mailAccount= TRUE;
+         }
+ 
+-        // Get samba Domain in case of samba 3
++        /* Get samba Domain in case of samba 3 */
+         if ($this->sambaSID != ""){
+             $this->SID= preg_replace ("/-[^-]+$/", "", $this->sambaSID);
+             $ldap= $this->config->get_ldap_link();
+@@ -135,7 +135,7 @@
+                     $this->ridBase= $this->config->get_cfg_value("core","sambaRidBase");
+                 } 
+ 
+-                // Get domain name for SID
++                /* Get domain name for SID */
+                 $this->sambaDomainName= "DEFAULT";
+                 foreach ($this->config->data['SERVERS']['SAMBA'] as $key => $val){
+                     if ($val['SID'] == $this->SID){
+@@ -153,7 +153,7 @@
+                 }
+             }
+ 
+-            // Get group type
++            /* Get group type */
+             $this->groupType= (int)substr(strrchr($this->sambaSID, "-"), 1);
+             if ($this->groupType < 500 || $this->groupType > 553){
+                 $this->groupType= 0;
+@@ -170,15 +170,15 @@
+             }
+         } else {
+ 
+-            // Get object base 
++            /* Get object base */
+             $this->base =preg_replace ("/^[^,]+,".preg_quote(get_groups_ou(), '/')."/i","",$this->dn);
+         }
+         $this->orig_base = $this->base;
+ 
+-        // This is always an account 
++        /* This is always an account */
+         $this->is_account= TRUE;
+ 
+-        // Instanciate base selector 
++        /* Instanciate base selector */
+         $this->baseSelector= new baseSelector($this->get_allowed_bases(), $this->base);
+         $this->baseSelector->setSubmitButton(false);
+         $this->baseSelector->setHeight(300);
+@@ -203,18 +203,18 @@
+ 
+     function execute()
+     {
+-        // Call parent execute 
++        /* Call parent execute */
+         plugin::execute();
+ 
+         $theme = getThemeName();
+ 
+-        // Log view 
++        // Log view */
+         if($this->is_account && !$this->view_logged){
+             $this->view_logged = TRUE;
+             new log("view","groups/".get_class($this),$this->dn);
+         }
+ 
+-        // Do we represent a valid group? 
++        // Do we represent a valid group? */
+         if (!$this->is_account && $this->parent === NULL){
+             switch ($theme) {
+                 case 'classic':
+@@ -251,17 +251,17 @@
+             }
+         }
+ 
+-        // Add objects? 
++        /* Add objects? */
+         if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("member"))){
+             $this->userSelect= new userSelect($this->config, get_userinfo(), $this->dns);
+         }
+ 
+-        // Add objects finished? 
++        /* Add objects finished? */
+         if (isset($_POST["add_users_cancel"]) || isset($_POST['cancel-abort'])){
+             $this->userSelect= NULL;
+         }
+ 
+-        // Add user to group 
++        /* Add user to group */
+         if (isset($_POST['add_users_finish']) || isset($_POST['ok-save']) && $this->userSelect){
+ 
+             $users = $this->userSelect->detectPostActions();
+@@ -288,13 +288,13 @@
+         $smarty->assign("nagios", $this->config->pluginEnabled("nagiosAccount") && class_available("nagiosAccount"));
+         $smarty->assign("pickupGroup", $this->config->pluginEnabled("phoneAccount") && class_available("phoneAccount"));
+ 
+-        // Manage object add dialog 
++        /* Manage object add dialog */
+         if ($this->userSelect){
+             $this->dialog = TRUE;
+             return($this->userSelect->execute());
+         }
+ 
+-        // Create base acls 
++        /* Create base acls */
+         $smarty->assign("base", $this->baseSelector->render());
+ 
+         $domains= array();
+@@ -306,7 +306,8 @@
+         $groupTypes= array(0 => _("Samba group"), 512 => _("Domain administrators"), 513 => _("Domain users"),
+                 514 => _("Domain guests"));
+ 
+-        // Don't loose special groups! If not key'ed above, add it to the combo box... 	
++        /* Don't loose special groups! If not key'ed above, add it to
++           the combo box... */	
+         if ($this->groupType >= 500 && $this->groupType <= 553 && !isset($groupTypes[$this->groupType])){
+             $groupTypes[$this->groupType]= sprintf(_("Special group (%d)"), $this->groupType);
+         }
+@@ -314,7 +315,7 @@
+         $smarty->assign("groupTypes", set_post($groupTypes));
+         $smarty->assign("groupType",  set_post($this->groupType));
+ 
+-        // Members and users 
++        /* Members and users */
+         if(!$this->multiple_support_active){
+             $this->memberList->setAcl($this->getacl("member"));
+             $data = $lData = array();
+@@ -430,7 +431,7 @@
+             $smarty->assign("partialList", $this->partialList->render());
+         }
+ 
+-        // Checkboxes 
++        /* Checkboxes */
+         foreach (array("force_gid", "smbgroup") as $val){
+             if ($this->$val == "1"){
+                 $smarty->assign("$val", "checked");
+@@ -455,7 +456,7 @@
+             $smarty->assign("nagios_group", "");
+         }
+ 
+-        // Fields 
++        /* Fields */
+         foreach (array("cn", "description", "gidNumber") as $val){
+             $smarty->assign("$val", set_post($this->$val));
+         }
+@@ -471,7 +472,7 @@
+             $smarty->assign("baseSelect",false);
+         }
+ 
+-        // Multiple edit handling 
++        /* Multiple edit handling */
+         $smarty->assign("multiple_support",$this->multiple_support_active);
+ 
+         foreach($this->attributes as $val){
+@@ -508,22 +509,20 @@
+         return($bool);
+     }
+ 
+-    // add new Member to a Group(s)
+     function addMember($dn)
+     {
+-        /** 
+-         * In mutliple edit we have to handle two arrays.
+-         * members               : Containing users used in all groups
+-         * members_used_by_some  : Those which are not used in all groups
++        /* In mutliple edit we have to handle two arrays.
++         *  members               : Containing users used in all groups
++         *  members_used_by_some  : Those which are not used in all groups
+          * So we have to remove the given $dn from the ..used_by_some array first.
+-        */
++         */
+         if($this->multiple_support_active){
+             if(isset($this->members_used_by_some[$dn])){
+                 unset($this->members_used_by_some[$dn]);
+             }
+         }  
+ 
+-        // Ensure that the requested object is known to the group class 
++        /* Ensure that the requested object is known to the group class */
+         $ldap = $this->config->get_ldap_link();
+         $ldap->cd($this->config->current['BASE']);
+         $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
+@@ -553,12 +552,11 @@
+             unset($this->members[$id]);
+         }
+ 
+-        /** 
+-         * We have two array contianing group members in multiple edit.
+-         * members             : Groups used by all currently edited groups 
+-         * members_used_by_some: Used by some 
++        /* We have two array contianing group members in multiple edit.
++         *  this->members             : Groups used by all currently edited groups 
++         *  this->members_used_by_some: Used by some 
+          * So we have to remove the specified member from both arrays.
+-        */ 
++         */
+         if($this->multiple_support_active){
+             if(isset($this->members_used_by_some[$id])){
+                 unset($this->members_used_by_some[$id]);
+@@ -566,7 +564,7 @@
+         }
+     }
+ 
+-    // reload and receive data from the LDAP
++    /* Reload data */
+     function reload(array $attrs)
+     {
+         if (isset($attrs['member'][0])){
+@@ -588,7 +586,7 @@
+             ksort ($arr);
+         }
+ 
+-        // check if all members are resolved 
++        /* check if all members are resolved */
+         foreach ($arr as $value){
+             if(!isset($arr[$value])){
+                 $arr[$value] = "";
+@@ -598,7 +596,7 @@
+     }
+ 
+ 
+-    // Create display name, this was used so often that it is excluded into a seperate function 
++    /* Create display name, this was used so often that it is excluded into a seperate function */
+     function createResultName($attrs)
+     {
+         if (isset($attrs["givenName"][0]) && isset($attrs["sn"][0])){
+@@ -621,7 +619,7 @@
+ 
+         new log("remove","groups/".get_class($this),$this->dn,array_keys($this->attrs),$ldap->get_error());
+ 
+-        // Delete references to object groups 
++        /* Delete references to object groups */
+         $ldap->cd ($this->config->current['BASE']);
+         $ldap->search ("(&(objectClass=gosaGroupOfNames)(member=".LDAP::prepare4filter($this->dn)."))", array("cn"));
+         while ($ldap->fetch()){
+@@ -630,8 +628,8 @@
+             $og->save ();
+         }
+ 
+-        // Remove ACL dependencies too,
+-         
++        /* Remove ACL dependencies too,
++         */
+         $ldap = $this->config->get_ldap_link();
+         $ldap->cd($this->config->current['BASE']);
+         $ldap->search("(&(objectClass=gosaAcl)(gosaAclEntry=*".base64_encode($this->dn)."*))",array("gosaAclEntry","dn"));
+@@ -648,28 +646,29 @@
+             $acl->save();
+         }
+ 
+-        // Remove ACL dependencies, too 
++        /* Remove ACL dependencies, too */
+         acl::remove_acl_for($this->dn);
+ 
+-        // Send signal to the world that we've done 
++        /* Send signal to the world that we've done */
+         $this->handle_post_events("remove");
+     }
+ 
+ 
+-    // Save data to object 
++    /* Save data to object */
+     function save_object()
+     {
+-        // Save additional values for possible next step 
++        /* Save additional values for possible next step */
+         if (isset($_POST['groupedit'])){
+ 
+-            // Create a base backup and reset the base directly after calling plugin::save_object();  
+-            // Base will be set seperatly a few lines below 
++            /* Create a base backup and reset the 
++               base directly after calling plugin::save_object();  
++               Base will be set seperatly a few lines below */
+             $base_tmp = $this->base;
+             plugin::save_object();
+             $this->trustModeDialog->save_object();
+             $this->base = $base_tmp;
+ 
+-            // Refresh base 
++            /* Refresh base */
+             if ($this->acl_is_moveable($this->base)){
+                 if (!$this->baseSelector->update()) {
+                     msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
+@@ -682,7 +681,7 @@
+ 
+             $this->force_gid= 0;
+ 
+-            // Only reset sambagroup flag if we are able to write this flag 
++            /* Only reset sambagroup flag if we are able to write this flag */
+             if($this->acl_is_writeable("sambaGroupType")){
+                 $this->smbgroup = 0;
+             }
+@@ -695,13 +694,13 @@
+                 }
+             }
+ 
+-            // Save sambaDomain attribute 
++            /* Save sambaDomain attribute */
+             if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
+                 $this->sambaDomainName= get_post('sambaDomainName');
+                 $this->groupType= get_post('groupType');
+             }
+ 
+-            // Save fon attribute 
++            /* Save fon attribute */
+             if ($this->acl_is_writeable("fonGroup")){
+                 if (isset ($_POST['fon_group'])){
+                     $this->fon_group= TRUE;
+@@ -720,20 +719,20 @@
+     }
+ 
+ 
+-    // Save to LDAP 
++    /* Save to LDAP */
+     function save()
+     {
+-        // ID handling 
++        /* ID handling */
+         if ($this->force_gid == 0){
+             if ($this->saved_gidNumber != ""){
+                 $this->gidNumber= $this->saved_gidNumber;
+             } else {
+-                // Calculate new, lock gids 
++                /* Calculate new, lock gids */
+                 $wait= 10;
+                 while (get_lock("gidnumber") != ""){
+                     sleep (1);
+ 
+-                    // timed out? 
++                    /* timed out? */
+                     if ($wait-- == 0){
+                         break;
+                     }
+@@ -745,7 +744,7 @@
+ 
+         plugin::save(); 
+ 
+-        // Remove objectClass for samba/phone support 
++        /* Remove objectClass for samba/phone support */
+         $tmp= array();
+         for ($i= 0; $i<count($this->attrs["objectClass"]); $i++){
+             if ($this->attrs['objectClass'][$i] != 'sambaGroupMapping' &&
+@@ -758,9 +757,11 @@
+         $this->attrs['objectClass']= $tmp;
+         $ldap= $this->config->get_ldap_link();
+ 
+-        // Add samba group functionality 
++        /* Add samba group functionality */
+         if ($this->smbgroup){
+-            // Fixed undefined index ...    
++
++            /* Fixed undefined index ... 
++             */ 
+             $this->SID = $this->ridBase = "";
+             if(isset($this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'])){
+                 $this->SID    = $this->config->data['SERVERS']['SAMBA'][$this->sambaDomainName]['SID'];
+@@ -776,44 +777,44 @@
+             $this->attrs['objectClass'][]= 'sambaGroupMapping';
+             $this->attrs['sambaGroupType']= "2";
+ 
+-            // Check if we need to create a special entry 
++            /* Check if we need to create a special entry */
+             if ($this->groupType == 0){
++
+                 if ($this->sambaSID == "" || $this->oldgroupType != $this->groupType){
+                     $sid = $this->getSambaSID();
+                     $this->attrs['sambaSID']= $sid;
+                     $this->sambaSID= $sid;
+                 }
++
+             } else {
+                 $this->attrs['sambaSID']=$this->SID."-".$this->groupType;
+             }
+ 
+-            /** 
+-             * User wants me to fake the idMappings? This is useful for
+-             * making winbind resolve the group names in a reasonable amount
+-             * of time in combination with larger databases. 
+-            */
++            /* User wants me to fake the idMappings? This is useful for
++               making winbind resolve the group names in a reasonable amount
++               of time in combination with larger databases. */
+             if ($this->config->boolValueIsTrue("core","sambaIdMapping")){
+                 $this->attrs['objectClass'][]= "sambaIdmapEntry";
+             }
+ 
+         }
+ 
+-        // Add phone functionality 
++        /* Add phone functionality */
+         if ($this->fon_group){
+             $this->attrs['objectClass'][]= "goFonPickupGroup";
+         }
+ 
+-        // Add nagios functionality 
++        /* Add nagios functionality */
+         if ($this->nagios_group){
+             $this->attrs['objectClass'][]= "nagiosContactGroup";
+         }
+ 
+-        // New accounts need proper 'dn', propagate it to remaining objects 
++        /* New accounts need proper 'dn', propagate it to remaining objects */
+         if ($this->dn == 'new'){
+             $this->dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
+         }
+ 
+-        // Add member dn's for RFC2307bis Support 
++        /* Add member dn's for RFC2307bis Support */
+         $temp = array();
+         if (count($this->members)) {
+             foreach($this->members as $member) {
+@@ -826,12 +827,12 @@
+             $this->attrs['member']= $this->dn;
+         }
+ 
+-        // Save data. Using 'modify' implies that the entry is already present, 
+-        // use 'add' for new entries. So do a check first... 
++        /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
++           new entries. So do a check first... */
+         $ldap->cat ($this->dn, array('dn'));
+         if ($ldap->fetch()){
+-            // Modify needs array() to remove values :-( 
+-            if (!count($this->members)){
++            /* Modify needs array() to remove values :-( */
++            if (!count ($this->members)){
+                 $this->attrs['member']= $this->dn;;
+             }
+             if (!$this->smbgroup){
+@@ -845,7 +846,8 @@
+             $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $this->dn));
+         }
+ 
+-        // check generated gidNumber, it may be used by another group. 
++        /* Check generated gidNumber, it may be used by another group. 
++         */
+         if($this->gidNumber != ""){
+             $ldap->cd($this->config->current['BASE']);
+             $ldap->search("(&(!(cn=".$this->orig_cn."))(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))",array("cn"));
+@@ -858,21 +860,14 @@
+                 msg_dialog::display(_("Warning"),sprintf(_("The gidNumber '%s' is already in use by %s!"),$this->gidNumber,$cns) , WARNING_DIALOG );
+             }
+         }
+-        
+-        // check if members are added to the group and delete redundancies
+-        if ($this->dn !== $this->attrs['member'] && !in_array($this->dn, $this->attrs['member'])) {
+-            $this->attrs['member'] = array_unique($this->attrs['member']);
+-        }
+ 
+-        // if the member array is empty nothing is saved or updated
+-        if (count($this->attrs['member'])) {
+-            // Write back to ldap 
+-            $ldap->cd($this->dn);
+-            $this->cleanup();
+-            $ldap->$mode($this->attrs);
+-        }
++        /* Write back to ldap */
++        $ldap->cd($this->dn);
++        $this->cleanup();
++        $ldap->$mode($this->attrs);
+ 
+-        // Remove ACL dependencies too,
++        /* Remove ACL dependencies too,
++         */
+         if($this->dn != $this->orig_dn && $this->orig_dn != "new"){
+             $tmp = new acl($this->config,$this->parent,$this->dn);
+             $tmp->update_acl_membership($this->orig_dn,$this->dn);
+@@ -893,10 +888,10 @@
+         $this->trustModeDialog->dn = $this->dn;
+         $this->trustModeDialog->save();
+ 
+-        // Remove gid lock 
++        /* Remove uid lock */
+         del_lock ("gidnumber");
+ 
+-        // Post that we've done
++        /* Post that we've done*/
+         $this->handle_post_events($mode);
+ 
+         return ($ret);
+@@ -904,17 +899,17 @@
+ 
+     function check()
+     {
+-        // Call common method to give check the hook 
++        /* Call common method to give check the hook */
+         $message= plugin::check();
+ 
+-        // Permissions for that base? 
++        /* Permissions for that base? */
+         if ($this->base != ""){
+             $new_dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
+         } else {
+             $new_dn= $this->dn;
+         }
+ 
+-        // must: cn 
++        /* must: cn */
+         if ($this->cn == "" && $this->acl_is_writeable("cn")){
+             $message[]= msgPool::required(_("Name"));
+         }
+@@ -924,7 +919,7 @@
+             $message[]= msgPool::check_base();;
+         }
+ 
+-        // Check for valid input 
++        /* Check for valid input */
+         if (!tests::is_uid($this->cn)){
+             if (strict_uid_mode()){
+                 $message[]= msgPool::invalid(_("Name"), $this->cn, "/[a-z0-9_-]/");
+@@ -939,7 +934,8 @@
+         }
+ 
+         if($this->allowGroupsWithSameNameInOtherSubtrees == true){
+-            // Check for used 'cn' 
++
++            /* Check for used 'cn' */
+             $ldap= $this->config->get_ldap_link();
+             if(($this->cn  != $this->orig_cn) || ($this->orig_dn == "new")){
+                 $ldap->cd(get_groups_ou().$this->base);
+@@ -949,16 +945,19 @@
+                 }
+             }
+         }else{
+-            // Check for used 'cn' 
++
++            /* Check for used 'cn' */
+             $ldap= $this->config->get_ldap_link();
+             $ldap->cd($this->config->current['BASE']);
+             $ldap->search("(&(|(objectClass=gosaGroupOfNames)(objectClass=posixGroup))(cn=$this->cn))",array("cn"));
+             if ($ldap->count() != 0){
+-                // New entry? 
++
++                /* New entry? */
+                 if ($this->dn == 'new'){
+                     $message[]= msgPool::duplicated(_("Name"));
+                 }
+-                // Moved? 
++
++                /* Moved? */
+                 elseif ($new_dn != $this->orig_dn){
+                     $ldap->fetch();
+                     if ($ldap->getDN() != $this->orig_dn){
+@@ -968,7 +967,7 @@
+             }
+         }
+ 
+-        // Check ID 
++        /* Check ID */
+         if ($this->force_gid == "1"){
+             if (!tests::is_id($this->gidNumber)){
+                 $message[]= msgPool::invalid(_("GID"), $this->gidNumber, "/[0-9]/");
+@@ -980,10 +979,11 @@
+             }
+         }
+ 
+-        // Check if we are allowed to create or move this object 
++        /* Check if we are allowed to create or move this object */
+         if(!$this->orig_dn == "new" || 
+                 $this->orig_base != $this->base || 
+                 $this->cn != $this->orig_cn){
++
+             if($this->orig_dn == "new" && !$this->acl_is_createable($this->base)){
+                 $message[] = msgPool::permCreate();
+             }elseif($this->orig_dn != "new" && !$this->acl_is_moveable($this->base)){
+@@ -1033,7 +1033,7 @@
+     }
+ 
+ 
+-    // Return plugin informations for acl handling   
++    /* Return plugin informations for acl handling  */ 
+     static function plInfo()
+     {
+         return (array(  
+@@ -1078,11 +1078,10 @@
+     function multiple_save_object()
+     {
+         if(isset($_POST['group_mulitple_edit'])){
+-            /** 
+-             * Create a base backup and reset the base directly
+-             * after calling plugin::save_object(); 
+-             * Base will be set seperatly a few lines below 
+-            */
++
++            /* Create a base backup and reset the
++               base directly after calling plugin::save_object();
++               Base will be set seperatly a few lines below */
+             $base_tmp = $this->base;
+             plugin::multiple_save_object();
+             plugin::save_object();
+@@ -1095,7 +1094,7 @@
+                 }
+             }
+ 
+-            // Refresh base 
++            /* Refresh base */
+             if ($this->acl_is_moveable($this->base)){
+                 if (!$this->baseSelector->update()) {
+                     msg_dialog::display(_("Error"), msgPool::permMove(), ERROR_DIALOG);
+@@ -1116,13 +1115,13 @@
+                 }
+             }
+ 
+-            // Save sambaDomain attribute 
++            /* Save sambaDomain attribute */
+             if ($this->acl_is_writeable("sambaDomainName") && isset ($_POST['sambaDomainName'])){
+                 $this->sambaDomainName= get_post('sambaDomainName');
+                 $this->groupType= get_post('groupType');
+             }
+ 
+-            // Save fon attribute 
++            /* Save fon attribute */
+             if ($this->acl_is_writeable("fonGroup")){
+                 if (isset ($_POST['fon_group'])){
+                     $this->fon_group= TRUE;
+@@ -1155,7 +1154,7 @@
+     }
+ 
+ 
+-    // Initialize plugin with given atribute arrays 
++    /* Initialize plugin with given atribute arrays */
+     function init_multiple_support($attrs,$all)
+     {
+         $ldap = $this->config->get_ldap_link();
+@@ -1219,7 +1218,7 @@
+ 
+         $this->trustModeDialog->PrepareForCopyPaste($source);
+ 
+-        // Get samba Domain in case of samba 3 
++        /* Get samba Domain in case of samba 3 */
+         if ($this->sambaSID != ""){
+             $this->SID= preg_replace ("/-[^-]+$/", "", $this->sambaSID);
+             $ldap= $this->config->get_ldap_link();
+@@ -1233,7 +1232,7 @@
+                     $this->ridBase= $this->config->get_cfg_value("core","sambaRidBase");
+                 }
+ 
+-                // Get domain name for SID 
++                /* Get domain name for SID */
+                 $this->sambaDomainName= "DEFAULT";
+                 foreach ($this->config->data['SERVERS']['SAMBA'] as $key => $val){
+                     if ($val['SID'] == $this->SID){
+@@ -1251,7 +1250,7 @@
+                 }
+             }
+ 
+-            // Get group type 
++            /* Get group type */
+             $this->groupType= (int)substr(strrchr($this->sambaSID, "-"), 1);
+             if ($this->groupType < 500 || $this->groupType > 553){
+                 $this->groupType= 0;
+@@ -1273,34 +1272,37 @@
+         }
+     }
+ 
++
+     function set_acl_base($base)
+     {
+         plugin::set_acl_base($base);
+         $this->trustModeDialog->set_acl_base($base);
+     }
+ 
+-    //! \brief  Enables multiple support for this plugin
++
++    /*! \brief  Enables multiple support for this plugin
++     */
+     function enable_multiple_support()
+     {
+         plugin::enable_multiple_support();
+         $this->trustModeDialog->enable_multiple_support();
+     }
+ 
+-    // Set all members of edited groups in $members 
++    /* Set all members of edited groups in $members */
+     function set_multi_edit_values($attrs)
+     {
+         $users = array();
+ 
+-        // Update groupMembership, keep optional group 
++        /* Update groupMembership, keep optinal group */
+         foreach($attrs['members_used_by_some'] as $member){
+             if(in_array_strict($member,$this->members)){
+                 $users[] = $member;
+             }
+         }
+ 
+-        // Update groupMembership, add forced groups 
++        /* Update groupMembership, add forced groups */
+         foreach($attrs['member'] as $member){
+-                $users[] = $member;
++            $users[] = $member;
+         }
+         
+         plugin::set_multi_edit_values($attrs);
+@@ -1309,7 +1311,7 @@
+     }
+ 
+ 
+-    //! \brief Get a new SambaSID for a group  
++    /*! \brief Get a new SambaSID for a group */ 
+     function getSambaSID() 
+     { 
+         $ldap = $this->config->get_ldap_link(); 
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1017_Revert-source-code-and-definition-adjustments-for-th.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1017_Revert-source-code-and-definition-adjustments-for-th.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1017_Revert-source-code-and-definition-adjustments-for-th.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1017_Revert-source-code-and-definition-adjustments-for-th.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,593 @@
+From 2990356aa8c84ad592cda18b7437e0caf12a3ade Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Mon, 14 Aug 2023 07:26:09 +0200
+Subject: [PATCH 7/9] Revert "source code and definition adjustments for the
+ group extension."
+
+This reverts a variant of commit 6537afc7daed7506ab4fe35030311f7d44994b39.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ plugins/admin/groups/class_group.inc          | 247 ++++++++++++------
+ .../groups/userSelect/class_userSelect.inc    |  12 +-
+ 2 files changed, 178 insertions(+), 81 deletions(-)
+
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -60,14 +60,18 @@
+     /* attribute list for save action */
+     var $attributes= array("cn", "description", "gidNumber","sambaGroupType","sambaSID","member");
+     var $objectclasses= array("top");
++
+     var $CopyPasteVars  = array("force_gid","fon_group","smbgroup","groupType","sambaSID","sambaDomainName","SID","nagios_group","sambaGroupType");
++
+     var $multiple_support = TRUE;
+ 
++
+     // Lists 
+     private $memberList;    // Single group editing
+     private $commonList;    // (Multiple support active)
+     private $partialList;   // (Multiple support active)
+ 
++
+     function __construct(&$config, $dn= NULL)
+     {
+         /* Set rfc2307bis flag */
+@@ -87,7 +91,21 @@
+         $this->orig_cn= $this->cn;
+ 
+         /* Get member list */
+-        $this->members =$this->reload($this->attrs);
++        if (isset($this->attrs['member'][0])){
++            $tmp= array();
++            for ($i= 0; $i<$this->attrs['member']['count']; $i++){
++                $tmp[]= $this->attrs['member'][$i];
++            }
++            $ldap= $this->config->get_ldap_link();
++            $ldap->cd($this->config->current['BASE']);
++            foreach ($tmp as $member => $dn) {
++                $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
++                while ($attrs = $ldap->fetch()) {
++                    $this->members[$attrs['cn'][0]]= $attrs;
++                }
++            }
++            ksort ($this->members);
++        }
+ 
+         /* Save gidNumber for later use */
+         if (isset($this->attrs['gidNumber'])){
+@@ -184,6 +202,8 @@
+         $this->baseSelector->setHeight(300);
+         $this->baseSelector->update(true);
+ 
++
++
+         // Prepare lists
+         $this->memberList = new sortableListing();
+         $this->memberList->setDeleteable(true);
+@@ -195,10 +215,7 @@
+         $this->memberList->setColspecs(array('20px','*','*','20px'));
+         $this->memberList->setDefaultSortColumn(1);
+ 
+-        // Set the dns of selected Group(s)
+-        if (!$this->dns[0]) {
+-            $this->dns[] = $this->dn;
+-        }
++        $this->reload(TRUE);
+     }
+ 
+     function execute()
+@@ -245,13 +262,17 @@
+                 if($action['action'] == 'delete' && preg_match("/w/",$this->getacl("member"))){
+                     foreach ($action['targets'] as $id){
+                         $value = $this->$list->getKey($id);
+-                        $this->removeMember($value);
++                        $this->removeUser($value);
+                     }
++                    $this->reload();
+                 }
+             }
+         }
+ 
+         /* Add objects? */
++        if (!$this->dns[0]) {
++            $this->dns[] = $this->dn;
++        }
+         if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("member"))){
+             $this->userSelect= new userSelect($this->config, get_userinfo(), $this->dns);
+         }
+@@ -269,7 +290,9 @@
+                 $headpage = $this->userSelect->getHeadpage();
+                 foreach($users['targets'] as $dn){
+                     $attrs = $headpage->getEntry($dn);
+-                    $this->addMember($attrs['dn']);                        
++                    $this->addUser($attrs['dn']);                        
++
++                    $this->reload();
+                 }
+             }
+             $this->userSelect= NULL;
+@@ -315,17 +338,20 @@
+         $smarty->assign("groupTypes", set_post($groupTypes));
+         $smarty->assign("groupType",  set_post($this->groupType));
+ 
++
+         /* Members and users */
+         if(!$this->multiple_support_active){
+             $this->memberList->setAcl($this->getacl("member"));
+             $data = $lData = array();
+-            foreach($this->members as $member => $values){
+-                if (!in_array($values['dn'], $this->dns)) {                
+-                    $data[$member] = $values;
+-                    $cn = _("Unknown");
+-                    if (isset($values['cn']) && isset($values['cn'][0])) $cn = $values['cn'][0];
++            foreach($this->members as $cn => $member){
++                if ($cn !== $this->cn) {                
++                    $data[$cn] = $member;
++                    $givenName = $sn = $cn = _("Unknown");
++                    // if(isset($member['sn']) && isset($member['sn'][0])) $sn = $member['sn'][0];
++                    if (isset($member['cn']) && isset($member['cn'][0])) $cn = $member['cn'][0];
++                    //if(isset($member['givenName']) && isset($member['givenName'][0])) $givenName = $member['givenName'][0];
+                     $image = image('images/false.png');
+-                    if(isset($values['sn'])){
++                    if(isset($member['sn'])){
+                         switch ($theme) {
+                             case 'classic':
+                                 $image = image("plugins/users/images/select_user.png");
+@@ -335,7 +361,7 @@
+                                 $image = image("<i class='material-icons'>person</i>");
+                                 break;
+                         }
+-                    }elseif(isset($values['gidNumber'])){
++                    }elseif(isset($member['gidNumber'])){
+                         switch ($variable) {
+                             case 'classic':
+                                 $image = image("plugins/groups/images/select_group.png");
+@@ -346,7 +372,7 @@
+                                 break;
+                         }
+                     }
+-                    $lData[$member] = array('data' => array($image,$cn, $data[$member]['uid'][0] ?? ""));
++                    $lData[$cn] = array('data' => array($image,$cn/*,$sn,$givenName*/, $data[$cn]['uid'][0] ?? ""));
+                 }
+             }
+             $this->memberList->setListData($data,$lData);
+@@ -360,13 +386,15 @@
+             $this->partialList->setAcl($this->getacl("member"));
+ 
+             $data = $lData = array();
+-            foreach($this->members as $member => $values){
+-                if (!in_array($values['dn'], $this->dns)) {
+-                    $data[$member] = $values;
+-                    $sn = _("Unknown");
+-                    if(isset($values['cn'][0])) $cn = $values['cn'][0];
++            foreach($this->members as $cn => $member){
++                if (!in_array($member['dn'], $this->dns)) {
++                    $data[$cn] = $member;
++                    $givenName = $sn = $cn = _("Unknown");
++                    //if(isset($member['sn'][0])) $sn = $member['sn'][0];
++                    if(isset($member['cn'][0])) $cn = $member['cn'][0];
++                    //if(isset($member['givenName'][0])) $givenName = $member['givenName'][0];
+                     $image = image('images/false.png');
+-                    if(isset($values['sn'])){
++                    if(isset($member['sn'])){
+                         switch ($theme) {
+                             case 'classic':
+                                 $image = image("plugins/users/images/select_user.png");
+@@ -376,7 +404,7 @@
+                                 $image = image("<i class='material-icons'>person</i>");
+                                 break;
+                         }
+-                    }elseif(isset($values['gidNumber'])){
++                    }elseif(isset($member['gidNumber'])){
+                         switch ($theme) {
+                             case 'classic':
+                                 $image = image("plugins/groups/images/select_group.png");
+@@ -387,7 +415,7 @@
+                                 break;
+                         }
+                     }
+-                    $lData[$member] = array('data' => array($image,$cn,$data[$member]['uid'][0] ?? ""));
++                    $lData[$cn] = array('data' => array($image,$cn/*,$sn,$givenName,*/,$data[$cn]['uid'][0] ?? ""));
+                 }
+             }
+             $this->commonList->setListData($data,$lData);
+@@ -395,13 +423,16 @@
+             $smarty->assign("commonList", $this->commonList->render());
+ 
+             $data = $lData = array();
+-            foreach($this->members_used_by_some as $member => $values){
+-                if (!in_array($values['dn'], $this->dns) && $member !== 'count') {
+-                    $data[$member] = $values;
+-                    $sn = _("Unknown");
+-                    if(isset($values['cn']) && isset($values['cn'][0])) $cn = $values['cn'][0];
++
++            foreach($this->members_used_by_some as $cn => $member){
++                if (!in_array($member['dn'], $this->dns)) {
++                    $data[$cn] = $member;
++                    $givenName = $sn = $cn = _("Unknown");
++                    //if(isset($member['sn']) && isset($member['sn'][0])) $sn = $member['sn'][0];
++                    if(isset($member['cn']) && isset($member['cn'][0])) $cn = $member['cn'][0];
++                    //if(isset($member['givenName'][0]) && isset($member['givenName'][0])) $givenName = $member['givenName'][0];
+                     $image = image('images/false.png');
+-                    if(isset($values['sn'])){
++                    if(isset($member['sn'])){
+                         switch ($theme) {
+                             case 'classic':
+                                 $image = image("plugins/users/images/select_user.png");
+@@ -412,7 +443,7 @@
+                                 break;
+                         }
+                         
+-                    }elseif(isset($values['gidNumber'])){
++                    }elseif(isset($member['gidNumber'])){
+                         switch ($theme) {
+                             case 'classic':
+                                 $image = image("plugins/groups/images/select_group.png");
+@@ -423,7 +454,7 @@
+                                 break;
+                         }
+                     }
+-                    $lData[$member] = array('data' => array($image,$cn,$data[$member]['uid'][0] ?? ""));
++                    $lData[$cn] = array('data' => array($image,$cn/*,$sn, $givenName*/, $data[$cn]['uid'][0] ?? ""));
+                 }
+             }
+             $this->partialList->setListData($data,$lData);
+@@ -499,6 +530,7 @@
+         return($smarty->fetch (get_template_path('generic.tpl', TRUE)));
+     }
+ 
++
+     function isRestrictedByDynGroup()
+     {
+         $bool = FALSE;
+@@ -509,12 +541,12 @@
+         return($bool);
+     }
+ 
+-    function addMember($dn)
++    function addUser($dn)
+     {
+         /* In mutliple edit we have to handle two arrays.
+          *  members               : Containing users used in all groups
+          *  members_used_by_some  : Those which are not used in all groups
+-         * So we have to remove the given $dn from the ..used_by_some array first.
++         * So we have to remove the given $uid from the ..used_by_some array first.
+          */
+         if($this->multiple_support_active){
+             if(isset($this->members_used_by_some[$dn])){
+@@ -528,14 +560,14 @@
+         $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
+         if($ldap->count() == 0 ){
+             msg_dialog::display(_("Error"), 
+-                sprintf(_("Adding DN '%s' to group '%s' failed: cannot find user object!"), 
+-                    $dn,$this->cn), 
++                sprintf(_("Adding UID '%s' to group '%s' failed: cannot find user object!"), 
++                    $uid,$this->cn), 
+                 ERROR_DIALOG);
+             return;
+         }elseif($ldap->count() >= 2){
+             msg_dialog::display(_("Error"), 
+-                sprintf(_("Add DN '%s' to group '%s' failed: DN is used more than once!"),
+-                    $dn,$this->cn), 
++                sprintf(_("Add UID '%s' to group '%s' failed: UID is used more than once!"),
++                    $uid,$this->cn), 
+                 ERROR_DIALOG);
+             return;
+         }else{
+@@ -546,7 +578,7 @@
+     }
+ 
+ 
+-    function removeMember($id)
++    function removeUser($id)
+     {
+         if(isset($this->members[$id])){
+             unset($this->members[$id]);
+@@ -555,7 +587,7 @@
+         /* We have two array contianing group members in multiple edit.
+          *  this->members             : Groups used by all currently edited groups 
+          *  this->members_used_by_some: Used by some 
+-         * So we have to remove the specified member from both arrays.
++         * So we have to remove the specified uid from both arrays.
+          */
+         if($this->multiple_support_active){
+             if(isset($this->members_used_by_some[$id])){
+@@ -565,34 +597,69 @@
+     }
+ 
+     /* Reload data */
+-    function reload(array $attrs)
++    function reload($silent = FALSE)
+     {
+-        if (isset($attrs['member'][0])){
+-            $tmp= array();
+-            $arr= array();
+-            foreach ($attrs['member'] as $member => $dn) {
+-                if ($member !== 'count') {
+-                    $tmp[$member]= $dn;
+-                }
++        /* Prepare ldap link */
++        $ldap= $this->config->get_ldap_link();
++        $ldap->cd($this->config->current['BASE']);
++
++
++        /* Resolve still unresolved members to fill the list with sn/giveName attributes 
++           (Store gathered sn/givenName informations in $this->allusers too, 
++           to be prepared when adding/deleting users)
++         */    
++        $filter = "";
++
++    
++
++        // Merge in partial uids in multiple edit
++        $allMember = array_keys($this->members);
++        if($this->multiple_support_active) {
++            $allMember = array_merge($allMember,  array_keys($this->members_used_by_some));
++        }
++        $allMember = array_values($allMember);
++
++        // To resolve the usernames out of the 'uid' we've to perform ldap queries. 
++        // To keep the amount of queries as short as possible, we combine the query 
++        //  for 'sn','givenName','..' for serveral users in one single query:
++        //      (|(uid=hans)(uid=peter)(uid=hubert)(..))
++        // 
++        // Unfortunately there is a filter length limit which causes the query to be invalid,
++        //  we've to split these huge query again into shorter query strings. 
++        // 
++        // maxPerRound specifies the amount of queries we can combine into a 
++        //  single query.
++        $maxPerRound = $this->config->get_cfg_value("core","ldapFilterNestingLimit");
++        if( $maxPerRound == "" ) {
++            $maxPerRound = count($allUids);
++        }
++
++        for ( $added = 0; $added < count($allMember); $added += $maxPerRound ) {
++
++            // First build the query....
++            $start = $added;
++            $end = $added + $maxPerRound;
++            $filter = "";
++            for ( $done = $start; $done < $end; $done++ ) {
++                if(!isset($allMember[$done])) break;
++                $value = $allMember[$done];
++                $filter .= "(cn=".normalizeLdap($value).")";
+             }
+-            $ldap= $this->config->get_ldap_link();
++
++            // Retrieve the data to LDAP
+             $ldap->cd($this->config->current['BASE']);
+-            foreach ($tmp as $member => $dn) {
+-                $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
+-                while ($attr = $ldap->fetch()) {
+-                    $arr[$attr['cn'][0]]= $attr;
+-                }
++            $ldap->search("(|".$filter."))",array("dn","cn","uid","sn","givenName","gidNumber"));
++            while( $attrs = $ldap->fetch() ) {
++                $this->members[$attrs['cn'][0]] = $attrs;
+             }
+-            ksort ($arr);
+         }
+ 
+-        /* check if all members are resolved */
+-        foreach ($arr as $value){
+-            if(!isset($arr[$value])){
+-                $arr[$value] = "";
++        /* check if all uids are resolved */
++        foreach ($this->members as $value){
++            if(!isset($this->members[$value])){
++                $this->members[$value] = "";
+             }
+         }
+-        return $arr;
+     }
+ 
+ 
+@@ -607,6 +674,7 @@
+         return($ret);
+     }
+ 
++
+     function remove_from_parent()
+     {
+         plugin::remove_from_parent();
+@@ -722,12 +790,13 @@
+     /* Save to LDAP */
+     function save()
+     {
++
+         /* ID handling */
+         if ($this->force_gid == 0){
+             if ($this->saved_gidNumber != ""){
+                 $this->gidNumber= $this->saved_gidNumber;
+             } else {
+-                /* Calculate new, lock gids */
++                /* Calculate new, lock uids */
+                 $wait= 10;
+                 while (get_lock("gidnumber") != ""){
+                     sleep (1);
+@@ -809,6 +878,12 @@
+             $this->attrs['objectClass'][]= "nagiosContactGroup";
+         }
+ 
++        /* Take members array */
++        
++        /*if (!$this->isRestrictedByDynGroup() && count ($this->memberUid)){
++            $this->attrs['member']= array_values(array_unique($this->member));
++        }*/
++
+         /* New accounts need proper 'dn', propagate it to remaining objects */
+         if ($this->dn == 'new'){
+             $this->dn= 'cn='.$this->cn.','.get_groups_ou().$this->base;
+@@ -839,6 +914,7 @@
+                 $this->attrs['sambaGroupType']= array();
+                 $this->attrs['sambaSID']= array();
+             }
++
+             $mode= "modify";
+         } else {
+             $mode= "add";
+@@ -944,6 +1020,7 @@
+                     $message[]= msgPool::duplicated(_("Name"));
+                 }
+             }
++
+         }else{
+ 
+             /* Check for used 'cn' */
+@@ -979,7 +1056,8 @@
+             }
+         }
+ 
+-        /* Check if we are allowed to create or move this object */
++        /* Check if we are allowed to create or move this object 
++         */
+         if(!$this->orig_dn == "new" || 
+                 $this->orig_base != $this->base || 
+                 $this->cn != $this->orig_cn){
+@@ -990,6 +1068,7 @@
+                 $message[] = msgPool::permMove();
+             }
+         }
++
+         return ($message);
+     }
+ 
+@@ -1057,6 +1136,7 @@
+                             "group"         => "plugin",
+                             "mandatory"     => FALSE)),
+ 
++
+             "plProvidedAcls"    => array(
+                     "cn"                => _("Name"),
+                     "description"       => _("Description"),
+@@ -1132,6 +1212,7 @@
+         }
+     }
+ 
++
+     function get_multi_edit_values()
+     {
+         $ret = plugin::get_multi_edit_values();
+@@ -1154,39 +1235,46 @@
+     }
+ 
+ 
+-    /* Initialize plugin with given atribute arrays */
++    /* Initialize plugin with given atribute arrays
++     */
+     function init_multiple_support($attrs,$all)
+     {
+-        $ldap = $this->config->get_ldap_link();
+-        $ldap->cd($this->config->current['BASE']);
+-
+         plugin::init_multiple_support($attrs,$all);
+         $this->trustModeDialog->init_multiple_support($attrs,$all);
+ 
++        // sort out members_used_by_some in $diff array
++        $diff= array_diff($all['member'],$attrs['member'] ?? [""]);
++
+         $this->dns = $all['dn'];
+-        $diff = array();
+         $this->members = array();
+         $this->members_used_by_some = array();
+ 
+-        // get all members who are in all groups for multiple edit
++        // fetch Members in all Groups to $members for multiple edit
++        $ldap = $this->config->get_ldap_link();
++        $ldap->cd($this->config->current['BASE']);
+         if (isset($attrs['member'])){
+-            $this->members = $this->reload($attrs);
++            foreach ($attrs['member'] as $member => $dn) {
++                $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
++                while ($attr = $ldap->fetch()) {
++                    $this->members[$attr['cn'][0]]= $attr;
++                }
++            }
+             ksort($this->members);
+         }
+ 
+-        // sort out all members that are not in all groups
+-        foreach ($all['member'] as $member => $value) {
+-            if (!in_array($value, $attrs['member'])) {
+-                $diff['member'][] = $value;
++        // fetch all Member in $diff to $members_used_by_some for multiple edit
++        if (isset($diff)){
++            foreach ($diff as $member => $dn) {
++                $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
++                while ($allAttr = $ldap->fetch()) {
++                    $this->members_used_by_some[$allAttr['cn'][0]]= $allAttr;
++                }
+             }
+-        }
+-
+-        // get all members who are not in all groups for multiple edit
+-        if (isset($diff['member'])){
+-            $this->members_used_by_some = $this->reload($diff);
+             ksort($this->members_used_by_some);
+         }
+ 
++        $this->reload(TRUE);
++
+         // We've two lists in mutliple support  
+         //  - one which represents those users which are part of ALL groups.
+         //  - ond one which represents those users which are only part of SOME groups.
+@@ -1302,6 +1390,7 @@
+ 
+         /* Update groupMembership, add forced groups */
+         foreach($attrs['member'] as $member){
++
+             $users[] = $member;
+         }
+         
+@@ -1324,9 +1413,11 @@
+                 break; 
+             } 
+             $gidNumber++; 
+-        }
++        } 
++
+         return $sid; 
+     } 
++
+ }
+ // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
+ ?>
+--- a/plugins/admin/groups/userSelect/class_userSelect.inc
++++ b/plugins/admin/groups/userSelect/class_userSelect.inc
+@@ -23,6 +23,7 @@
+ #[\AllowDynamicProperties]
+ class userSelect extends management
+ {
++    
+     public $plHeadline = "User selection";
+     protected $skipFooter = TRUE;
+     protected $skipHeader = TRUE;
+@@ -31,19 +32,24 @@
+     {
+         $this->config = $config;
+         $this->ui = $ui;
+-        $this->storagePoints = array(get_ou("core", "userRDN"),get_ou("core", "groupRDN"));
+ 
++        $this->storagePoints = array(get_ou("core", "userRDN"),get_ou("core", "groupRDN"));
++        # $this->storagePoints = array( get_ou("core", "groupRDN"));
+         // Build filter
+         if (session::global_is_set(get_class($this)."_filter")){
+             $filter= session::global_get(get_class($this)."_filter");
+-            $filter->setConstraint(['dn' => $dns]);
++            $filter->customConstraints['dn'] = $dns;
+         } else {
+             $filter = new filter(get_template_path("user-filter.xml", true, dirname(__FILE__)));
+             $filter->setObjectStorage($this->storagePoints);
+-            $filter->setConstraint(['dn' => $dns]);
++            $filter->addConstraint(['dn' => $dns]);
+         }
++        
++
+         $this->setFilter($filter);
+ 
++        
++
+         // Build headpage
+         $headpage = new listing(get_template_path("user-list.xml", true, dirname(__FILE__)));
+         $headpage->setFilter($filter);
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1018_Revert-fix-multiple_edit-and-add-custom-Constraint-t.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1018_Revert-fix-multiple_edit-and-add-custom-Constraint-t.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1018_Revert-fix-multiple_edit-and-add-custom-Constraint-t.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1018_Revert-fix-multiple_edit-and-add-custom-Constraint-t.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,529 @@
+From 496b5c60ab18bd5e60d7b238938eaff091418f15 Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Mon, 14 Aug 2023 07:38:03 +0200
+Subject: [PATCH 8/9] Revert "fix multiple_edit and add custom Constraint to
+ filters"
+
+This reverts a variant of commit 7f6cdfae3b1468e2db77c555cc41800bbae4a409.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ include/class_filter.inc                      |   2 +-
+ plugins/admin/groups/class_group.inc          | 247 +++++++++---------
+ .../groups/userSelect/class_userSelect.inc    |  13 +-
+ 3 files changed, 121 insertions(+), 141 deletions(-)
+
+--- a/include/class_filter.inc
++++ b/include/class_filter.inc
+@@ -3,7 +3,7 @@
+  * This code is part of GOsa (http://www.gosa-project.org)
+  * Copyright (C) 2003-2008 GONICUS GmbH
+  *
+- * ID: $$Id: class_filter.inc 19251 2010-07-29 13:21:27Z hickert $$
++ * ID: $$Id$$
+  *
+  * 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
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -26,7 +26,7 @@
+     /* Group attributes */
+     var $cn= "";
+     var $gidNumber= "";
+-    var $members_used_by_some= array();
++    var $memberUid_used_by_some= array();
+ 
+     /* Helpers */
+     var $base= "";
+@@ -55,7 +55,6 @@
+     var $view_logged = FALSE;
+     var $allowGroupsWithSameNameInOtherSubtrees = true;
+     var $baseSelector;
+-    var $dns= array();
+ 
+     /* attribute list for save action */
+     var $attributes= array("cn", "description", "gidNumber","sambaGroupType","sambaSID","member");
+@@ -107,6 +106,9 @@
+             ksort ($this->members);
+         }
+ 
++        /* Get group list */
++
++
+         /* Save gidNumber for later use */
+         if (isset($this->attrs['gidNumber'])){
+             $this->saved_gidNumber= $this->attrs['gidNumber'][0];
+@@ -252,7 +254,7 @@
+             // Check if list is available, depends on multi- or sinlge- group editing. 
+             if($this->$list){
+                 // ensure we can delete group members if we have
+-                // write permission to the member attribute
++                // write permission to the memberUid attribute
+                 $mu_acl = $this->getacl("member");
+                 if (preg_match("/w/",$mu_acl) && !preg_match("/d/",$mu_acl)) {
+                     $this->$list->setAcl($mu_acl.'d');
+@@ -270,11 +272,8 @@
+         }
+ 
+         /* Add objects? */
+-        if (!$this->dns[0]) {
+-            $this->dns[] = $this->dn;
+-        }
+         if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("member"))){
+-            $this->userSelect= new userSelect($this->config, get_userinfo(), $this->dns);
++            $this->userSelect= new userSelect($this->config, get_userinfo());
+         }
+ 
+         /* Add objects finished? */
+@@ -343,9 +342,9 @@
+         if(!$this->multiple_support_active){
+             $this->memberList->setAcl($this->getacl("member"));
+             $data = $lData = array();
+-            foreach($this->members as $cn => $member){
+-                if ($cn !== $this->cn) {                
+-                    $data[$cn] = $member;
++            foreach($this->members as $uid => $member){
++                if ($uid !== $this->cn) {                
++                    $data[$uid] = $member;
+                     $givenName = $sn = $cn = _("Unknown");
+                     // if(isset($member['sn']) && isset($member['sn'][0])) $sn = $member['sn'][0];
+                     if (isset($member['cn']) && isset($member['cn'][0])) $cn = $member['cn'][0];
+@@ -372,7 +371,7 @@
+                                 break;
+                         }
+                     }
+-                    $lData[$cn] = array('data' => array($image,$cn/*,$sn,$givenName*/, $data[$cn]['uid'][0] ?? ""));
++                    $lData[$uid] = array('data' => array($image,$cn/*,$sn,$givenName*/, $data[$uid]['uid'][0] ?? ""));
+                 }
+             }
+             $this->memberList->setListData($data,$lData);
+@@ -386,37 +385,36 @@
+             $this->partialList->setAcl($this->getacl("member"));
+ 
+             $data = $lData = array();
+-            foreach($this->members as $cn => $member){
+-                if (!in_array($member['dn'], $this->dns)) {
+-                    $data[$cn] = $member;
+-                    $givenName = $sn = $cn = _("Unknown");
+-                    //if(isset($member['sn'][0])) $sn = $member['sn'][0];
+-                    if(isset($member['cn'][0])) $cn = $member['cn'][0];
+-                    //if(isset($member['givenName'][0])) $givenName = $member['givenName'][0];
+-                    $image = image('images/false.png');
+-                    if(isset($member['sn'])){
+-                        switch ($theme) {
+-                            case 'classic':
+-                                $image = image("plugins/users/images/select_user.png");
+-                                break;
+-                            
+-                            default:
+-                                $image = image("<i class='material-icons'>person</i>");
+-                                break;
+-                        }
+-                    }elseif(isset($member['gidNumber'])){
+-                        switch ($theme) {
+-                            case 'classic':
+-                                $image = image("plugins/groups/images/select_group.png");
+-                                break;
+-                            
+-                            default:
+-                                $image = image("<i class='material-icons'>groups</i>");
+-                                break;
+-                        }
++            foreach($this->members as $uid => $member){
++                $member = $this->members[$member];
++                $data[$uid] = $member;
++                $givenName = $sn = $cn = _("Unknown");
++                //if(isset($member['sn'][0])) $sn = $member['sn'][0];
++                if(isset($member['cn'][0])) $cn = $member['cn'][0];
++                //if(isset($member['givenName'][0])) $givenName = $member['givenName'][0];
++                $image = image('images/false.png');
++                if(isset($member['sn'])){
++                    switch ($theme) {
++                        case 'classic':
++                            $image = image("plugins/users/images/select_user.png");
++                            break;
++                        
++                        default:
++                            $image = image("<i class='material-icons'>person</i>");
++                            break;
++                    }
++                }elseif(isset($member['gidNumber'])){
++                    switch ($theme) {
++                        case 'classic':
++                            $image = image("plugins/groups/images/select_group.png");
++                            break;
++                        
++                        default:
++                            $image = image("<i class='material-icons'>groups</i>");
++                            break;
+                     }
+-                    $lData[$cn] = array('data' => array($image,$cn/*,$sn,$givenName,*/,$data[$cn]['uid'][0] ?? ""));
+                 }
++                $lData[$uid] = array('data' => array($image,$cn/*,$sn,$givenName,*/,$uid));
+             }
+             $this->commonList->setListData($data,$lData);
+             $this->commonList->update();
+@@ -424,38 +422,37 @@
+ 
+             $data = $lData = array();
+ 
+-            foreach($this->members_used_by_some as $cn => $member){
+-                if (!in_array($member['dn'], $this->dns)) {
+-                    $data[$cn] = $member;
+-                    $givenName = $sn = $cn = _("Unknown");
+-                    //if(isset($member['sn']) && isset($member['sn'][0])) $sn = $member['sn'][0];
+-                    if(isset($member['cn']) && isset($member['cn'][0])) $cn = $member['cn'][0];
+-                    //if(isset($member['givenName'][0]) && isset($member['givenName'][0])) $givenName = $member['givenName'][0];
+-                    $image = image('images/false.png');
+-                    if(isset($member['sn'])){
+-                        switch ($theme) {
+-                            case 'classic':
+-                                $image = image("plugins/users/images/select_user.png");
+-                                break;
+-                            
+-                            default:
+-                                $image = image("<i class='material-icons'>person</i>");
+-                                break;
+-                        }
++            foreach($this->members_used_by_some as $uid => $member){
++                $member = (isset($this->members[$member])) ?? NULL;
++                $data[$uid] = $member;
++                $givenName = $sn = $cn = _("Unknown");
++                //if(isset($member['sn']) && isset($member['sn'][0])) $sn = $member['sn'][0];
++                if(isset($member['cn']) && isset($member['cn'][0])) $cn = $member['cn'][0];
++                //if(isset($member['givenName'][0]) && isset($member['givenName'][0])) $givenName = $member['givenName'][0];
++                $image = image('images/false.png');
++                if(isset($member['sn'])){
++                    switch ($theme) {
++                        case 'classic':
++                            $image = image("plugins/users/images/select_user.png");
++                            break;
+                         
+-                    }elseif(isset($member['gidNumber'])){
+-                        switch ($theme) {
+-                            case 'classic':
+-                                $image = image("plugins/groups/images/select_group.png");
+-                                break;
+-                            
+-                            default:
+-                                $image = image("<i class='material-icons'>groups</i>");
+-                                break;
+-                        }
++                        default:
++                            $image = image("<i class='material-icons'>person</i>");
++                            break;
++                    }
++                    
++                }elseif(isset($member['gidNumber'])){
++                    switch ($theme) {
++                        case 'classic':
++                            $image = image("plugins/groups/images/select_group.png");
++                            break;
++                        
++                        default:
++                            $image = image("<i class='material-icons'>groups</i>");
++                            break;
+                     }
+-                    $lData[$cn] = array('data' => array($image,$cn/*,$sn, $givenName*/, $data[$cn]['uid'][0] ?? ""));
+                 }
++                $lData[$uid] = array('data' => array($image,$cn/*,$sn, $givenName*/, $uid));
+             }
+             $this->partialList->setListData($data,$lData);
+             $this->partialList->update();
+@@ -524,7 +521,7 @@
+         $bool = $this->isRestrictedByDynGroup();
+         $smarty->assign("restrictedByDynGroup", $bool);
+         if($bool){
+-            $smarty->assign("memberACL", preg_replace("/[^r]/","",$this->getacl('member')));
++            $smarty->assign("memberUidACL", preg_replace("/[^r]/","",$this->getacl('member')));
+              
+         }
+         return($smarty->fetch (get_template_path('generic.tpl', TRUE)));
+@@ -544,17 +541,18 @@
+     function addUser($dn)
+     {
+         /* In mutliple edit we have to handle two arrays.
+-         *  members               : Containing users used in all groups
+-         *  members_used_by_some  : Those which are not used in all groups
++         *  memberUid               : Containing users used in all groups
++         *  memberUid_used_by_some  : Those which are not used in all groups
+          * So we have to remove the given $uid from the ..used_by_some array first.
+          */
+         if($this->multiple_support_active){
+-            if(isset($this->members_used_by_some[$dn])){
+-                unset($this->members_used_by_some[$dn]);
++            if(isset($this->memberUid_used_by_some[$dn])){
++                unset($this->memberUid_used_by_some[$dn]);
+             }
+         }  
+ 
+-        /* Ensure that the requested object is known to the group class */
++        /* Ensure that the requested object is known to the group class 
++         */
+         $ldap = $this->config->get_ldap_link();
+         $ldap->cd($this->config->current['BASE']);
+         $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
+@@ -575,6 +573,7 @@
+                 $this->members[$attrs['cn'][0]] = $attrs;
+             }
+         }
++        
+     }
+ 
+ 
+@@ -585,13 +584,13 @@
+         }
+ 
+         /* We have two array contianing group members in multiple edit.
+-         *  this->members             : Groups used by all currently edited groups 
+-         *  this->members_used_by_some: Used by some 
++         *  this->memberUid             : Groups used by all currently edited groups 
++         *  this->memberUid_used_by_some: Used by some 
+          * So we have to remove the specified uid from both arrays.
+          */
+         if($this->multiple_support_active){
+-            if(isset($this->members_used_by_some[$id])){
+-                unset($this->members_used_by_some[$id]);
++            if(isset($this->memberUid_used_by_some[$id])){
++                unset($this->memberUid_used_by_some[$id]);
+             }
+         }
+     }
+@@ -604,7 +603,7 @@
+         $ldap->cd($this->config->current['BASE']);
+ 
+ 
+-        /* Resolve still unresolved members to fill the list with sn/giveName attributes 
++        /* Resolve still unresolved memberuids to fill the list with sn/giveName attributes 
+            (Store gathered sn/givenName informations in $this->allusers too, 
+            to be prepared when adding/deleting users)
+          */    
+@@ -613,11 +612,11 @@
+     
+ 
+         // Merge in partial uids in multiple edit
+-        $allMember = array_keys($this->members);
++        $allUids = array_keys($this->members);
+         if($this->multiple_support_active) {
+-            $allMember = array_merge($allMember,  array_keys($this->members_used_by_some));
++            $allUids = array_merge($allUids,  array_keys($this->memberUid_used_by_some));
+         }
+-        $allMember = array_values($allMember);
++        $allUids = array_values($allUids);
+ 
+         // To resolve the usernames out of the 'uid' we've to perform ldap queries. 
+         // To keep the amount of queries as short as possible, we combine the query 
+@@ -634,15 +633,15 @@
+             $maxPerRound = count($allUids);
+         }
+ 
+-        for ( $added = 0; $added < count($allMember); $added += $maxPerRound ) {
++        for ( $added = 0; $added < count($allUids); $added += $maxPerRound ) {
+ 
+             // First build the query....
+             $start = $added;
+             $end = $added + $maxPerRound;
+             $filter = "";
+             for ( $done = $start; $done < $end; $done++ ) {
+-                if(!isset($allMember[$done])) break;
+-                $value = $allMember[$done];
++                if(!isset($allUids[$done])) break;
++                $value = $allUids[$done];
+                 $filter .= "(cn=".normalizeLdap($value).")";
+             }
+ 
+@@ -659,7 +658,7 @@
+             if(!isset($this->members[$value])){
+                 $this->members[$value] = "";
+             }
+-        }
++        }  
+     }
+ 
+ 
+@@ -890,16 +889,18 @@
+         }
+ 
+         /* Add member dn's for RFC2307bis Support */
+-        $temp = array();
+-        if (count($this->members)) {
+-            foreach($this->members as $member) {
+-                if ($member['dn'] !== $this->dn) {
+-                    $temp[] = $member['dn'];
+-                }   
+-            }
+-            $this->attrs['member']= $temp;
+-        }else {
+-            $this->attrs['member']= $this->dn;
++        if ($this->rfc2307bis){
++            $temp = array();
++            if (count($this->members)){
++                foreach($this->members as $member) {
++                    if ($member['dn'] !== $this->dn) {
++                        $temp[] = $member['dn'];
++                    }   
++                }
++                $this->attrs['member']= $temp;
++            }else {
++                $this->attrs['member']= $this->dn;
++            }
+         }
+ 
+         /* Save data. Using 'modify' implies that the entry is already present, use 'add' for
+@@ -1146,10 +1147,11 @@
+ 
+                     "sambaGroupType"    => _("Samba group type"),
+                     "sambaDomainName"   => _("Samba domain name"),
+-                    "accessTo"          => _("System trust"),
++                    "accessTo"        => _("System trust"),
+                     "fonGroup"          => _("Phone pickup group"),
+                     "nagiosGroup"       => _("Nagios group"),
+ 
++                    "memberUid"         => _("Group member"),
+                     "member"            => _("Group member"))
+                 ));
+     }
+@@ -1225,7 +1227,7 @@
+         }
+ 
+         $ret['member'] = $this->members;
+-        $ret['members_used_by_some'] = $this->members_used_by_some;
++        $ret['memberUid_used_by_some'] = $this->memberUid_used_by_some;
+         return($ret);
+     }
+ 
+@@ -1242,35 +1244,22 @@
+         plugin::init_multiple_support($attrs,$all);
+         $this->trustModeDialog->init_multiple_support($attrs,$all);
+ 
+-        // sort out members_used_by_some in $diff array
+-        $diff= array_diff($all['member'],$attrs['member'] ?? [""]);
+-
+-        $this->dns = $all['dn'];
+         $this->members = array();
+         $this->members_used_by_some = array();
+-
+-        // fetch Members in all Groups to $members for multiple edit
+-        $ldap = $this->config->get_ldap_link();
+-        $ldap->cd($this->config->current['BASE']);
+         if (isset($attrs['member'])){
+-            foreach ($attrs['member'] as $member => $dn) {
+-                $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
+-                while ($attr = $ldap->fetch()) {
+-                    $this->members[$attr['cn'][0]]= $attr;
+-                }
++            for ($i= 0; $i<$attrs['member']['count']; $i++){
++                $this->members[$attrs['member'][$i]]= $attrs['member'][$i];
+             }
+             ksort($this->members);
+         }
+ 
+-        // fetch all Member in $diff to $members_used_by_some for multiple edit
+-        if (isset($diff)){
+-            foreach ($diff as $member => $dn) {
+-                $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
+-                while ($allAttr = $ldap->fetch()) {
+-                    $this->members_used_by_some[$allAttr['cn'][0]]= $allAttr;
++        if (isset($all['member'])){
++            for ($i= 0; $i<$all['member']['count']; $i++){
++                if(!in_array_strict($all['member'][$i],$this->members)){
++                    $this->memberUid_used_by_some[$all['member'][$i]]= $all['member'][$i];
+                 }
+             }
+-            ksort($this->members_used_by_some);
++            ksort($this->memberUid_used_by_some);
+         }
+ 
+         $this->reload(TRUE);
+@@ -1284,8 +1273,8 @@
+         $this->commonList->setEditable(false);
+         $this->commonList->setWidth("100%");
+         $this->commonList->setHeight("120px");
+-        $this->commonList->setHeader(array('~',_("Common Name"),_("UID")));
+-        $this->commonList->setColspecs(array('20px','*','*','20px'));
++        $this->commonList->setHeader(array('~',_("Given name"),_("Surname"),_("UID")));
++        $this->commonList->setColspecs(array('20px','*','*','*','20px'));
+         $this->commonList->setDefaultSortColumn(1);
+ 
+         $this->partialList = new sortableListing();
+@@ -1294,8 +1283,8 @@
+         $this->partialList->setEditable(false);
+         $this->partialList->setWidth("100%");
+         $this->partialList->setHeight("120px");
+-        $this->partialList->setHeader(array('~',_("Common Name"),_("UID")));
+-        $this->partialList->setColspecs(array('20px','*','*','20px'));
++        $this->partialList->setHeader(array('~',_("Given name"),_("Surname"),_("UID")));
++        $this->partialList->setColspecs(array('20px','*','*','*','20px'));
+         $this->partialList->setDefaultSortColumn(1);
+     }
+ 
+@@ -1376,24 +1365,22 @@
+         $this->trustModeDialog->enable_multiple_support();
+     }
+ 
+-    /* Set all members of edited groups in $members */
++
+     function set_multi_edit_values($attrs)
+     {
+         $users = array();
+ 
+         /* Update groupMembership, keep optinal group */
+-        foreach($attrs['members_used_by_some'] as $member){
+-            if(in_array_strict($member,$this->members)){
+-                $users[] = $member;
++        foreach($attrs['memberUid_used_by_some'] as $uid){
++            if(in_array_strict($uid,$this->members)){
++                $users[$uid] = $uid;
+             }
+         }
+ 
+         /* Update groupMembership, add forced groups */
+-        foreach($attrs['member'] as $member){
+-
+-            $users[] = $member;
++        foreach($attrs['member'] as $uid){
++            $users[$uid] = $uid;
+         }
+-        
+         plugin::set_multi_edit_values($attrs);
+         $this->trustModeDialog->set_multi_edit_values($attrs);
+         $this->members = $users;
+--- a/plugins/admin/groups/userSelect/class_userSelect.inc
++++ b/plugins/admin/groups/userSelect/class_userSelect.inc
+@@ -23,33 +23,26 @@
+ #[\AllowDynamicProperties]
+ class userSelect extends management
+ {
+-    
+     public $plHeadline = "User selection";
+     protected $skipFooter = TRUE;
+     protected $skipHeader = TRUE;
+ 
+-    function __construct($config, $ui, array $dns = null)
++    function __construct($config, $ui)
+     {
+         $this->config = $config;
+         $this->ui = $ui;
+ 
+-        $this->storagePoints = array(get_ou("core", "userRDN"),get_ou("core", "groupRDN"));
+-        # $this->storagePoints = array( get_ou("core", "groupRDN"));
++        $this->storagePoints = array(get_ou("core", "userRDN"));
++
+         // Build filter
+         if (session::global_is_set(get_class($this)."_filter")){
+             $filter= session::global_get(get_class($this)."_filter");
+-            $filter->customConstraints['dn'] = $dns;
+         } else {
+             $filter = new filter(get_template_path("user-filter.xml", true, dirname(__FILE__)));
+             $filter->setObjectStorage($this->storagePoints);
+-            $filter->addConstraint(['dn' => $dns]);
+         }
+-        
+-
+         $this->setFilter($filter);
+ 
+-        
+-
+         // Build headpage
+         $headpage = new listing(get_template_path("user-list.xml", true, dirname(__FILE__)));
+         $headpage->setFilter($filter);
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1019_Revert-Extends-Functionality-to-add-groups-in-groups.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1019_Revert-Extends-Functionality-to-add-groups-in-groups.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1019_Revert-Extends-Functionality-to-add-groups-in-groups.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1019_Revert-Extends-Functionality-to-add-groups-in-groups.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,597 @@
+From a4122ffc1b3a18849f9de619b20bfc78c28e36ed Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Mon, 14 Aug 2023 07:46:42 +0200
+Subject: [PATCH] Revert "Extends Functionality to add groups in groups"
+
+This reverts a variant of commit 4fa70a94f2ce51d908409d30776ecd2883261272.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ plugins/admin/groups/class_group.inc | 297 ++++++++++++---------------
+ 1 file changed, 134 insertions(+), 163 deletions(-)
+
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -3,7 +3,7 @@
+  * This code is part of GOsa (http://www.gosa-project.org)
+  * Copyright (C) 2003-2008 GONICUS GmbH
+  *
+- * ID: $$Id: class_group.inc 20952 2011-07-27 06:38:29Z hickert $$
++ * ID: $$Id$$
+  *
+  * 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
+@@ -25,7 +25,9 @@
+ {
+     /* Group attributes */
+     var $cn= "";
++    var $description= "";
+     var $gidNumber= "";
++    var $memberUid= array();
+     var $memberUid_used_by_some= array();
+ 
+     /* Helpers */
+@@ -40,6 +42,8 @@
+     var $ridBase= 0;
+     var $members= array();
+     var $users= array();
++    var $member= array();
++    var $allusers= array();
+     var $saved_gidNumber= "";
+     var $oldgroupType= "";
+     var $orig_dn= "";
+@@ -52,12 +56,13 @@
+     var $dialog;
+     var $rfc2307bis= FALSE;
+     var $OnlyShowFirstEntries =200;
++    var $dnMapping= array();
+     var $view_logged = FALSE;
+     var $allowGroupsWithSameNameInOtherSubtrees = true;
+     var $baseSelector;
+ 
+     /* attribute list for save action */
+-    var $attributes= array("cn", "description", "gidNumber","sambaGroupType","sambaSID","member");
++    var $attributes= array("cn", "description", "gidNumber", "memberUid", "sambaGroupType","sambaSID");
+     var $objectclasses= array("top");
+ 
+     var $CopyPasteVars  = array("force_gid","fon_group","smbgroup","groupType","sambaSID","sambaDomainName","SID","nagios_group","sambaGroupType");
+@@ -90,25 +95,15 @@
+         $this->orig_cn= $this->cn;
+ 
+         /* Get member list */
+-        if (isset($this->attrs['member'][0])){
++        if (isset($this->attrs['memberUid'][0])){
+             $tmp= array();
+-            for ($i= 0; $i<$this->attrs['member']['count']; $i++){
+-                $tmp[]= $this->attrs['member'][$i];
++            for ($i= 0; $i<$this->attrs['memberUid']['count']; $i++){
++                $tmp[$this->attrs['memberUid'][$i]]= $this->attrs['memberUid'][$i];
+             }
+-            $ldap= $this->config->get_ldap_link();
+-            $ldap->cd($this->config->current['BASE']);
+-            foreach ($tmp as $member => $dn) {
+-                $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
+-                while ($attrs = $ldap->fetch()) {
+-                    $this->members[$attrs['cn'][0]]= $attrs;
+-                }
+-            }
+-            ksort ($this->members);
++            $this->memberUid= $tmp;
++            ksort ($this->memberUid);
+         }
+ 
+-        /* Get group list */
+-
+-
+         /* Save gidNumber for later use */
+         if (isset($this->attrs['gidNumber'])){
+             $this->saved_gidNumber= $this->attrs['gidNumber'][0];
+@@ -213,8 +208,8 @@
+         $this->memberList->setEditable(false);
+         $this->memberList->setWidth("100%");
+         $this->memberList->setHeight("300px");
+-        $this->memberList->setHeader(array('~',_("Common Name"),_("UID")));
+-        $this->memberList->setColspecs(array('20px','*','*','20px'));
++        $this->memberList->setHeader(array('~',_("Surname"),_("Given name"),_("UID")));
++        $this->memberList->setColspecs(array('20px','*','*','*','20px'));
+         $this->memberList->setDefaultSortColumn(1);
+ 
+         $this->reload(TRUE);
+@@ -253,17 +248,12 @@
+ 
+             // Check if list is available, depends on multi- or sinlge- group editing. 
+             if($this->$list){
+-                // ensure we can delete group members if we have
+-                // write permission to the memberUid attribute
+-                $mu_acl = $this->getacl("member");
+-                if (preg_match("/w/",$mu_acl) && !preg_match("/d/",$mu_acl)) {
+-                    $this->$list->setAcl($mu_acl.'d');
+-                }
+                 $this->$list->save_object();
+                 $action = $this->$list->getAction();
+-                if($action['action'] == 'delete' && preg_match("/w/",$this->getacl("member"))){
++                if($action['action'] == 'delete' && preg_match("/w/",$this->getacl("memberUid"))){
+                     foreach ($action['targets'] as $id){
+                         $value = $this->$list->getKey($id);
++                        unset ($this->members["$value"]);
+                         $this->removeUser($value);
+                     }
+                     $this->reload();
+@@ -272,7 +262,7 @@
+         }
+ 
+         /* Add objects? */
+-        if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("member"))){
++        if (isset($_POST["edit_membership"]) && preg_match("/w/",$this->getacl("memberUid"))){
+             $this->userSelect= new userSelect($this->config, get_userinfo());
+         }
+ 
+@@ -289,8 +279,9 @@
+                 $headpage = $this->userSelect->getHeadpage();
+                 foreach($users['targets'] as $dn){
+                     $attrs = $headpage->getEntry($dn);
+-                    $this->addUser($attrs['dn']);                        
+-
++                    $value = $attrs['uid'][0];
++                    $this->addUser($value);
++                    $this->members["$value"]= $this->allusers[$value];
+                     $this->reload();
+                 }
+             }
+@@ -307,6 +298,9 @@
+             return($trustModeDialog);
+         }
+         $smarty->assign("trustModeDialog" , $trustModeDialog);
++
++
++
+         $smarty->assign("nagios", $this->config->pluginEnabled("nagiosAccount") && class_available("nagiosAccount"));
+         $smarty->assign("pickupGroup", $this->config->pluginEnabled("phoneAccount") && class_available("phoneAccount"));
+ 
+@@ -340,39 +334,25 @@
+ 
+         /* Members and users */
+         if(!$this->multiple_support_active){
+-            $this->memberList->setAcl($this->getacl("member"));
++            $this->memberList->setAcl($this->getacl("memberUid"));
+             $data = $lData = array();
+             foreach($this->members as $uid => $member){
+-                if ($uid !== $this->cn) {                
+-                    $data[$uid] = $member;
+-                    $givenName = $sn = $cn = _("Unknown");
+-                    // if(isset($member['sn']) && isset($member['sn'][0])) $sn = $member['sn'][0];
+-                    if (isset($member['cn']) && isset($member['cn'][0])) $cn = $member['cn'][0];
+-                    //if(isset($member['givenName']) && isset($member['givenName'][0])) $givenName = $member['givenName'][0];
+-                    $image = image('images/false.png');
+-                    if(isset($member['sn'])){
+-                        switch ($theme) {
+-                            case 'classic':
+-                                $image = image("plugins/users/images/select_user.png");
+-                                break;
+-                            
+-                            default:
+-                                $image = image("<i class='material-icons'>person</i>");
+-                                break;
+-                        }
+-                    }elseif(isset($member['gidNumber'])){
+-                        switch ($variable) {
+-                            case 'classic':
+-                                $image = image("plugins/groups/images/select_group.png");
+-                                break;
+-                            
+-                            default:
+-                                $image = image("<i class='material-icons'>groups</i>");
+-                                break;
+-                        }
++                $data[$uid] = $member;
++                $givenName = $sn = _("Unknown");
++                if(isset($member['sn']) && isset($member['sn'][0])) $sn = $member['sn'][0];
++                if(isset($member['givenName']) && isset($member['givenName'][0])) $givenName = $member['givenName'][0];
++                $image = image('images/false.png');
++                if(isset($member['sn'])){
++                    switch ($theme) {
++                        case 'classic':
++                            $image = image("plugins/users/images/select_user.png");
++                            break;
++                        default:
++                            $image = image("<i class='material-icons'>person</i>");
++                            break;
+                     }
+-                    $lData[$uid] = array('data' => array($image,$cn/*,$sn,$givenName*/, $data[$uid]['uid'][0] ?? ""));
+                 }
++                $lData[$uid] = array('data' => array($image,$sn, $givenName, $uid));
+             }
+             $this->memberList->setListData($data,$lData);
+             $bool = $this->isRestrictedByDynGroup();
+@@ -381,40 +361,28 @@
+             $smarty->assign("memberList", $this->memberList->render());
+         }else{
+ 
+-            $this->commonList->setAcl($this->getacl("member"));
+-            $this->partialList->setAcl($this->getacl("member"));
++            $this->commonList->setAcl($this->getacl("memberUid"));
++            $this->partialList->setAcl($this->getacl("memberUid"));
+ 
+             $data = $lData = array();
+             foreach($this->members as $uid => $member){
+                 $member = $this->members[$member];
+                 $data[$uid] = $member;
+-                $givenName = $sn = $cn = _("Unknown");
+-                //if(isset($member['sn'][0])) $sn = $member['sn'][0];
+-                if(isset($member['cn'][0])) $cn = $member['cn'][0];
+-                //if(isset($member['givenName'][0])) $givenName = $member['givenName'][0];
++                $givenName = $sn = _("Unknown");
++                if(isset($member['sn'][0])) $sn = $member['sn'][0];
++                if(isset($member['givenName'][0])) $givenName = $member['givenName'][0];
+                 $image = image('images/false.png');
+                 if(isset($member['sn'])){
+                     switch ($theme) {
+                         case 'classic':
+                             $image = image("plugins/users/images/select_user.png");
+                             break;
+-                        
+                         default:
+                             $image = image("<i class='material-icons'>person</i>");
+                             break;
+                     }
+-                }elseif(isset($member['gidNumber'])){
+-                    switch ($theme) {
+-                        case 'classic':
+-                            $image = image("plugins/groups/images/select_group.png");
+-                            break;
+-                        
+-                        default:
+-                            $image = image("<i class='material-icons'>groups</i>");
+-                            break;
+-                    }
+                 }
+-                $lData[$uid] = array('data' => array($image,$cn/*,$sn,$givenName,*/,$uid));
++                $lData[$uid] = array('data' => array($image,$sn ,$givenName, $uid));
+             }
+             $this->commonList->setListData($data,$lData);
+             $this->commonList->update();
+@@ -422,37 +390,24 @@
+ 
+             $data = $lData = array();
+ 
+-            foreach($this->members_used_by_some as $uid => $member){
+-                $member = (isset($this->members[$member])) ?? NULL;
++            foreach($this->memberUid_used_by_some as $uid => $member){
++                $member = (isset($this->members[$member])) ? $this->members[$member] : NULL;
+                 $data[$uid] = $member;
+-                $givenName = $sn = $cn = _("Unknown");
+-                //if(isset($member['sn']) && isset($member['sn'][0])) $sn = $member['sn'][0];
+-                if(isset($member['cn']) && isset($member['cn'][0])) $cn = $member['cn'][0];
+-                //if(isset($member['givenName'][0]) && isset($member['givenName'][0])) $givenName = $member['givenName'][0];
++                $givenName = $sn = _("Unknown");
++                if(isset($member['sn']) && isset($member['sn'][0])) $sn = $member['sn'][0];
++                if(isset($member['givenName'][0]) && isset($member['givenName'][0])) $givenName = $member['givenName'][0];
+                 $image = image('images/false.png');
+                 if(isset($member['sn'])){
+                     switch ($theme) {
+                         case 'classic':
+                             $image = image("plugins/users/images/select_user.png");
+                             break;
+-                        
+                         default:
+                             $image = image("<i class='material-icons'>person</i>");
+                             break;
+                     }
+-                    
+-                }elseif(isset($member['gidNumber'])){
+-                    switch ($theme) {
+-                        case 'classic':
+-                            $image = image("plugins/groups/images/select_group.png");
+-                            break;
+-                        
+-                        default:
+-                            $image = image("<i class='material-icons'>groups</i>");
+-                            break;
+-                    }
+                 }
+-                $lData[$uid] = array('data' => array($image,$cn/*,$sn, $givenName*/, $uid));
++                $lData[$uid] = array('data' => array($image,$sn, $givenName, $uid));
+             }
+             $this->partialList->setListData($data,$lData);
+             $this->partialList->update();
+@@ -521,7 +476,7 @@
+         $bool = $this->isRestrictedByDynGroup();
+         $smarty->assign("restrictedByDynGroup", $bool);
+         if($bool){
+-            $smarty->assign("memberUidACL", preg_replace("/[^r]/","",$this->getacl('member')));
++            $smarty->assign("memberUidACL", preg_replace("/[^r]/","",$this->getacl('memberUid')));
+              
+         }
+         return($smarty->fetch (get_template_path('generic.tpl', TRUE)));
+@@ -532,13 +487,13 @@
+     {
+         $bool = FALSE;
+         if(isset($this->parent->by_object['DynamicLdapGroup'])){
+-            $bool = $this->parent->by_object['DynamicLdapGroup']->isAttributeDynamic('member') ||
++            $bool = $this->parent->by_object['DynamicLdapGroup']->isAttributeDynamic('memberUid') ||
+                 $this->parent->by_object['DynamicLdapGroup']->isAttributeDynamic('member');
+         }
+         return($bool);
+     }
+ 
+-    function addUser($dn)
++    function addUser($uid)
+     {
+         /* In mutliple edit we have to handle two arrays.
+          *  memberUid               : Containing users used in all groups
+@@ -546,41 +501,48 @@
+          * So we have to remove the given $uid from the ..used_by_some array first.
+          */
+         if($this->multiple_support_active){
+-            if(isset($this->memberUid_used_by_some[$dn])){
+-                unset($this->memberUid_used_by_some[$dn]);
++            if(isset($this->memberUid_used_by_some[$uid])){
++                unset($this->memberUid_used_by_some[$uid]);
+             }
+         }  
+ 
+         /* Ensure that the requested object is known to the group class 
+          */
+-        $ldap = $this->config->get_ldap_link();
+-        $ldap->cd($this->config->current['BASE']);
+-        $ldap->cat($dn,array("dn","cn","uid","sn","givenName","gidNumber"));
+-        if($ldap->count() == 0 ){
+-            msg_dialog::display(_("Error"), 
+-                sprintf(_("Adding UID '%s' to group '%s' failed: cannot find user object!"), 
+-                    $uid,$this->cn), 
+-                ERROR_DIALOG);
+-            return;
+-        }elseif($ldap->count() >= 2){
+-            msg_dialog::display(_("Error"), 
+-                sprintf(_("Add UID '%s' to group '%s' failed: UID is used more than once!"),
+-                    $uid,$this->cn), 
+-                ERROR_DIALOG);
+-            return;
+-        }else{
+-            while($attrs = $ldap->fetch()){
+-                $this->members[$attrs['cn'][0]] = $attrs;
++        if(!isset($this->dnMapping[$uid])){
++            $ldap = $this->config->get_ldap_link();
++            $ldap->cd($this->config->current['BASE']);
++            $ldap->search("(&(objectClass=gosaAccount)(uid=".$uid."))",array("dn", "uid","sn","givenName"));
++            if($ldap->count() == 0 ){
++                msg_dialog::display(_("Error"), 
++                        sprintf(_("Adding UID '%s' to group '%s' failed: cannot find user object!"), 
++                            $uid,$this->cn), 
++                        ERROR_DIALOG);
++                return;
++            }elseif($ldap->count() >= 2){
++                msg_dialog::display(_("Error"), 
++                        sprintf(_("Add UID '%s' to group '%s' failed: UID is used more than once!"),
++                            $uid,$this->cn), 
++                        ERROR_DIALOG);
++                return;
++            }else{
++                while($attrs = $ldap->fetch()){
++                    $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
++                    $this->members[$attrs['uid'][0]] = $attrs;
++                    $this->allusers[$attrs['uid'][0]]= $attrs;
++                }
+             }
+         }
+         
++        $this->memberUid[$uid]= $uid;
++        $this->reload();
+     }
+ 
+ 
+-    function removeUser($id)
++    function removeUser($uid)
+     {
+-        if(isset($this->members[$id])){
+-            unset($this->members[$id]);
++        $temp= array();
++        if(isset($this->memberUid[$uid])){
++            unset($this->memberUid[$uid]);
+         }
+ 
+         /* We have two array contianing group members in multiple edit.
+@@ -589,8 +551,8 @@
+          * So we have to remove the specified uid from both arrays.
+          */
+         if($this->multiple_support_active){
+-            if(isset($this->memberUid_used_by_some[$id])){
+-                unset($this->memberUid_used_by_some[$id]);
++            if(isset($this->memberUid_used_by_some[$uid])){
++                unset($this->memberUid_used_by_some[$uid]);
+             }
+         }
+     }
+@@ -612,10 +574,15 @@
+     
+ 
+         // Merge in partial uids in multiple edit
+-        $allUids = array_keys($this->members);
++        $allUids = array_keys($this->memberUid);
+         if($this->multiple_support_active) {
+             $allUids = array_merge($allUids,  array_keys($this->memberUid_used_by_some));
+         }
++
++        // Do not request data for users we've already fetched before.
++        foreach($allUids as $key => $uid){
++            if(isset($this->dnMapping[$uid])) unset($allUids[$key]);
++        }
+         $allUids = array_values($allUids);
+ 
+         // To resolve the usernames out of the 'uid' we've to perform ldap queries. 
+@@ -642,19 +609,21 @@
+             for ( $done = $start; $done < $end; $done++ ) {
+                 if(!isset($allUids[$done])) break;
+                 $value = $allUids[$done];
+-                $filter .= "(cn=".normalizeLdap($value).")";
++                $filter .= "(uid=".normalizeLdap($value).")";
+             }
+ 
+             // Retrieve the data to LDAP
+             $ldap->cd($this->config->current['BASE']);
+-            $ldap->search("(|".$filter."))",array("dn","cn","uid","sn","givenName","gidNumber"));
++            $ldap->search("(&(objectClass=gosaAccount)(|".$filter."))",array("dn", "uid","sn","givenName"));
+             while( $attrs = $ldap->fetch() ) {
+-                $this->members[$attrs['cn'][0]] = $attrs;
++                $this->dnMapping[$attrs['uid'][0]] = $attrs['dn'];
++                $this->members[$attrs['uid'][0]] = $attrs;
++                $this->allusers[$attrs['uid'][0]]= $attrs;
+             }
+         }
+ 
+         /* check if all uids are resolved */
+-        foreach ($this->members as $value){
++        foreach ($this->memberUid as $value){
+             if(!isset($this->members[$value])){
+                 $this->members[$value] = "";
+             }
+@@ -879,9 +848,9 @@
+ 
+         /* Take members array */
+         
+-        /*if (!$this->isRestrictedByDynGroup() && count ($this->memberUid)){
+-            $this->attrs['member']= array_values(array_unique($this->member));
+-        }*/
++        if (!$this->isRestrictedByDynGroup() && count ($this->memberUid)){
++            $this->attrs['memberUid']= array_values(array_unique($this->memberUid));
++        }
+ 
+         /* New accounts need proper 'dn', propagate it to remaining objects */
+         if ($this->dn == 'new'){
+@@ -890,16 +859,15 @@
+ 
+         /* Add member dn's for RFC2307bis Support */
+         if ($this->rfc2307bis){
+-            $temp = array();
+-            if (count($this->members)){
+-                foreach($this->members as $member) {
+-                    if ($member['dn'] !== $this->dn) {
+-                        $temp[] = $member['dn'];
+-                    }   
+-                }
+-                $this->attrs['member']= $temp;
+-            }else {
+-                $this->attrs['member']= $this->dn;
++            $this->attrs['member'] = array();
++            if (count($this->memberUid)){
++                foreach($this->attrs['memberUid'] as $uid) {
++                    if(isset($this->dnMapping[$uid])){
++                        $this->attrs['member'][]= $this->dnMapping[$uid];
++                    }
++                }
++            } else {
++                $this->attrs['member'][]= $this->dn;
+             }
+         }
+ 
+@@ -908,8 +876,8 @@
+         $ldap->cat ($this->dn, array('dn'));
+         if ($ldap->fetch()){
+             /* Modify needs array() to remove values :-( */
+-            if (!count ($this->members)){
+-                $this->attrs['member']= $this->dn;;
++            if (!count ($this->memberUid)){
++                $this->attrs['memberUid']= array();
+             }
+             if (!$this->smbgroup){
+                 $this->attrs['sambaGroupType']= array();
+@@ -927,7 +895,11 @@
+          */
+         if($this->gidNumber != ""){
+             $ldap->cd($this->config->current['BASE']);
+-            $ldap->search("(&(!(cn=".$this->orig_cn."))(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))",array("cn"));
++            $chk_attr = "orig_cn";
++            if ($this->cn != $this->orig_cn) {
++                $chk_attr = "cn";
++            }
++            $ldap->search("(&(!(cn=".$this->$chk_attr."))(objectClass=posixGroup)(gidNumber=".$this->gidNumber."))",array("cn"));
+             if($ldap->count()){
+                 $cns = "";
+                 while($attrs = $ldap->fetch()){
+@@ -1151,8 +1123,7 @@
+                     "fonGroup"          => _("Phone pickup group"),
+                     "nagiosGroup"       => _("Nagios group"),
+ 
+-                    "memberUid"         => _("Group member"),
+-                    "member"            => _("Group member"))
++                    "memberUid"         => _("Group member"))
+                 ));
+     }
+ 
+@@ -1226,7 +1197,7 @@
+             }
+         }
+ 
+-        $ret['member'] = $this->members;
++        $ret['memberUid'] = $this->memberUid;
+         $ret['memberUid_used_by_some'] = $this->memberUid_used_by_some;
+         return($ret);
+     }
+@@ -1244,19 +1215,19 @@
+         plugin::init_multiple_support($attrs,$all);
+         $this->trustModeDialog->init_multiple_support($attrs,$all);
+ 
+-        $this->members = array();
+-        $this->members_used_by_some = array();
+-        if (isset($attrs['member'])){
+-            for ($i= 0; $i<$attrs['member']['count']; $i++){
+-                $this->members[$attrs['member'][$i]]= $attrs['member'][$i];
+-            }
+-            ksort($this->members);
++        $this->memberUid = array();
++        $this->memberUid_used_by_some = array();
++        if (isset($attrs['memberUid'])){
++            for ($i= 0; $i<$attrs['memberUid']['count']; $i++){
++                $this->memberUid[$attrs['memberUid'][$i]]= $attrs['memberUid'][$i];
++            }
++            ksort($this->memberUid);
+         }
+ 
+-        if (isset($all['member'])){
+-            for ($i= 0; $i<$all['member']['count']; $i++){
+-                if(!in_array_strict($all['member'][$i],$this->members)){
+-                    $this->memberUid_used_by_some[$all['member'][$i]]= $all['member'][$i];
++        if (isset($all['memberUid'])){
++            for ($i= 0; $i<$all['memberUid']['count']; $i++){
++                if(!in_array_strict($all['memberUid'][$i],$this->memberUid)){
++                    $this->memberUid_used_by_some[$all['memberUid'][$i]]= $all['memberUid'][$i];
+                 }
+             }
+             ksort($this->memberUid_used_by_some);
+@@ -1341,10 +1312,10 @@
+             $this->sambaSID = $this->getSambaSID(); 
+         } 
+ 
+-        $this->members = array();
+-        if(isset($source['member'])){
+-            for($i = 0 ; $i < $source['member']['count']; $i ++){
+-                $this->members[] = $source['member'][$i];
++        $this->memberUid = array();
++        if(isset($source['memberUid'])){
++            for($i = 0 ; $i < $source['memberUid']['count']; $i ++){
++                $this->memberUid[] = $source['memberUid'][$i];
+             }
+         }
+     }
+@@ -1372,18 +1343,18 @@
+ 
+         /* Update groupMembership, keep optinal group */
+         foreach($attrs['memberUid_used_by_some'] as $uid){
+-            if(in_array_strict($uid,$this->members)){
++            if(in_array_strict($uid,$this->memberUid)){
+                 $users[$uid] = $uid;
+             }
+         }
+ 
+         /* Update groupMembership, add forced groups */
+-        foreach($attrs['member'] as $uid){
++        foreach($attrs['memberUid'] as $uid){
+             $users[$uid] = $uid;
+         }
+         plugin::set_multi_edit_values($attrs);
+         $this->trustModeDialog->set_multi_edit_values($attrs);
+-        $this->members = $users;
++        $this->memberUid = $users;
+     }
+ 
+ 
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1020_plugins-admin-groups-class_group.inc-Re-add-structur.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1020_plugins-admin-groups-class_group.inc-Re-add-structur.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1020_plugins-admin-groups-class_group.inc-Re-add-structur.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1020_plugins-admin-groups-class_group.inc-Re-add-structur.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,24 @@
+From 94f487678116d973ed4bdc56036ecd5d69cce801 Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Mon, 14 Aug 2023 10:28:23 +0200
+Subject: [PATCH 2/2] plugins/admin/groups/class_group.inc: Re-add structural
+ objectClass posixGroup.
+
+This reverts a change that sneaked in via commit 79aa7fe63bc07b468865e103d4bdab9c07e5abbb.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ plugins/admin/groups/class_group.inc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -63,7 +63,7 @@
+ 
+     /* attribute list for save action */
+     var $attributes= array("cn", "description", "gidNumber", "memberUid", "sambaGroupType","sambaSID");
+-    var $objectclasses= array("top");
++    var $objectclasses= array("top", "posixGroup");
+ 
+     var $CopyPasteVars  = array("force_gid","fon_group","smbgroup","groupType","sambaSID","sambaDomainName","SID","nagios_group","sambaGroupType");
+ 
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1021_fix-config-parser-being-null.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1021_fix-config-parser-being-null.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1021_fix-config-parser-being-null.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1021_fix-config-parser-being-null.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,16 @@
+Description: Since PHP 8.x an XML parser must not be null when accessed. It needs to be an instance of XMLParser().
+Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+
+--- a/include/class_config.inc
++++ b/include/class_config.inc
+@@ -134,6 +134,10 @@
+             $this->section= "";
+             $this->currentLocation= "";
+ 
++            if (config::$parser === NULL) {
++                config::$parser = xml_parser_create();
++            }
++
+             xml_set_object(config::$parser, $this);
+             xml_set_element_handler(config::$parser, "tag_open", "tag_close");
+             $this->parse($this->filename);
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1022_fix-implicit-conversions-of-float-to-int.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1022_fix-implicit-conversions-of-float-to-int.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1022_fix-implicit-conversions-of-float-to-int.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1022_fix-implicit-conversions-of-float-to-int.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,128 @@
+--- a/plugins/personal/generic/class_user.inc
++++ b/plugins/personal/generic/class_user.inc
+@@ -347,7 +347,7 @@
+ 
+     /* Get random number for pictures */
+     srand((double)microtime()*1000000); 
+-    $smarty->assign("rand", rand(0, 10000));
++    $smarty->assign("rand", round(rand(0, 10000)));
+ 
+ 
+     /* Do we represent a valid gosaAccount? */
+@@ -1592,7 +1592,7 @@
+ 
+     /* Get random number for pictures */
+     srand((double)microtime()*1000000); 
+-    $rand = rand(0, 10000);
++    $rand = round(rand(0, 10000));
+ 
+     $smarty = get_smarty();
+ 
+--- a/include/functions.inc
++++ b/include/functions.inc
+@@ -3400,7 +3400,7 @@
+ 
+ /*! \brief Returns a random char */
+ function get_random_char () {
+-     $randno = rand (0, 63);
++     $randno = round (rand (0, 63) );
+      if ($randno < 12) {
+          return (chr ($randno + 46)); // Digits, '/' and '.'
+      } else if ($randno < 38) {
+@@ -3988,7 +3988,7 @@
+         // Generate random number
+         if($match[1] == '#'){
+             foreach($rules as $id => $ruleStr){
+-                $genID = rand(pow(10,$match[2] -1),pow(10, ($match[2])) - 1);
++                $genID = round(rand(pow(10,$match[2] -1),pow(10, ($match[2])) - 1));
+                 $rules[$id] = preg_replace("/".preg_quote($match[0],'/')."/", $genID,$ruleStr);
+             }
+         }
+--- a/plugins/generic/statistics/chartClasses/class_memoryUsageChart.inc
++++ b/plugins/generic/statistics/chartClasses/class_memoryUsageChart.inc
+@@ -52,7 +52,7 @@
+             $filename =  $pCache->GetHash(get_class(),$dataSet->GetData());
+             $filename = '/var/spool/gosa/'.$filename;    
+             if(file_exists($filename) && is_readable($filename)){
+-                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).rand(0,99999);
++                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).round(rand(0,99999));
+                 session::set('statistics::graphFile'.$this->graphID,$filename);
+                 return;
+             }
+--- a/plugins/generic/statistics/chartClasses/class_objectCountChart.inc
++++ b/plugins/generic/statistics/chartClasses/class_objectCountChart.inc
+@@ -53,7 +53,7 @@
+             $filename =  $pCache->GetHash(get_class(),$dataSet->GetData());
+             $filename = '/var/spool/gosa/'.$filename;    
+             if(file_exists($filename) && is_readable($filename)){
+-                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).rand(0,99999);
++                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).round(rand(0,99999));
+                 session::set('statistics::graphFile'.$this->graphID,$filename);
+                 return;
+             }
+--- a/setup/class_setupStep_Migrate.inc
++++ b/setup/class_setupStep_Migrate.inc
+@@ -106,7 +106,7 @@
+ 
+         /* Create dummy entry
+          */
+-        $name     = "GOsa_setup_text_entry_".session_id().rand(0,999999);
++        $name     = "GOsa_setup_text_entry_".session_id().round(rand(0,999999));
+         $dn       = "ou=".$name.",".$cv['base'];
+         $testEntry= array();
+         $testEntry['objectClass'][]= "top";
+--- a/plugins/generic/infoPage/class_infoPage.inc
++++ b/plugins/generic/infoPage/class_infoPage.inc
+@@ -162,7 +162,7 @@
+             $smarty->assign("dateOfBirth","");
+         }
+ 
+-        $smarty->assign("rand", rand(0, 99999999));
++        $smarty->assign("rand", round(rand(0, 99999999)));
+         $smarty->assign("personalInfoAllowed", $personalInfoAllowed);
+         $smarty->assign("managers", $this->managers);
+         $smarty->assign("plugins", $this->plugins);
+--- a/plugins/generic/statistics/chartClasses/class_actionSelectChart.inc
++++ b/plugins/generic/statistics/chartClasses/class_actionSelectChart.inc
+@@ -65,7 +65,7 @@
+             $filename =  $pCache->GetHash(get_class(),$dataSet->GetData());
+             $filename = '/var/spool/gosa/'.$filename;    
+             if(file_exists($filename) && is_readable($filename)){
+-                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).rand(0,99999);
++                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).round(rand(0,99999));
+                 session::set('statistics::graphFile'.$this->graphID,$filename);
+                 return;
+             }
+--- a/plugins/generic/statistics/chartClasses/class_categoryActionOverTime.inc
++++ b/plugins/generic/statistics/chartClasses/class_categoryActionOverTime.inc
+@@ -61,7 +61,7 @@
+             $filename =  $pCache->GetHash(get_class(),$allSeriesDataSet->GetData());
+             $filename = '/var/spool/gosa/'.$filename;    
+             if(file_exists($filename) && is_readable($filename)){
+-                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).rand(0,99999);
++                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).round(rand(0,99999));
+                 session::set('statistics::graphFile'.$this->graphID,$filename);
+                 return;
+             }
+--- a/plugins/generic/statistics/chartClasses/class_passwordChangeChart.inc
++++ b/plugins/generic/statistics/chartClasses/class_passwordChangeChart.inc
+@@ -55,7 +55,7 @@
+             $filename =  $pCache->GetHash(get_class(),$dataSet->GetData());
+             $filename = '/var/spool/gosa/'.$filename;    
+             if(file_exists($filename) && is_readable($filename)){
+-                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).rand(0,99999);
++                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).round(rand(0,99999));
+                 session::set('statistics::graphFile'.$this->graphID,$filename);
+                 return;
+             }
+--- a/plugins/generic/statistics/chartClasses/class_pieChart1.inc
++++ b/plugins/generic/statistics/chartClasses/class_pieChart1.inc
+@@ -67,7 +67,7 @@
+             $filename =  $pCache->GetHash(get_class(),$dataSet->GetData());
+             $filename = '/var/spool/gosa/'.$filename;    
+             if(file_exists($filename) && is_readable($filename)){
+-                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).rand(0,99999);
++                $this->graphID = preg_replace("/[^0-9]/","",microtime(TRUE)).round(rand(0,99999));
+                 session::set('statistics::graphFile'.$this->graphID,$filename);
+                 return;
+             }
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1023_fix-icon-labelling-with-default-theme.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1023_fix-icon-labelling-with-default-theme.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1023_fix-icon-labelling-with-default-theme.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1023_fix-icon-labelling-with-default-theme.patch	2023-08-17 06:33:48.000000000 +0200
@@ -0,0 +1,35 @@
+Description: Properly render labelled icons if default materialize CSS theme is used.
+Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+
+--- a/include/functions.inc
++++ b/include/functions.inc
+@@ -3663,6 +3663,14 @@
+   global $BASE_DIR;
+   $label= null;
+ 
++  /* Extract labels from path */
++  preg_match("/(.*\.png)\[(.*)\]$/", $path, $matches);
++
++  if (count($matches) == 3) {
++    $path = $matches[1];
++    $label= $matches[2];
++  }
++
+   $theme = getThemeName();
+ 
+   switch ($theme) {
+@@ -3694,14 +3702,6 @@
+         return "";
+       }
+ 
+-      /* Extract labels from path */
+-      preg_match("/(.*\.png)\[(.*)\]$/", $path, $matches);
+-
+-      if (count($matches) == 3) {
+-        $path = $matches[1];
+-        $label= $matches[2];
+-      }
+-
+       $baseImage = str_replace('['.$label.']', '', $path);
+       if (!array_key_exists($baseImage, $styles)) {
+         return "";
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1024_fix-mess-of-using-and-comparing-int-and-string-values.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1024_fix-mess-of-using-and-comparing-int-and-string-values.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1024_fix-mess-of-using-and-comparing-int-and-string-values.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1024_fix-mess-of-using-and-comparing-int-and-string-values.patch	2023-08-17 06:33:48.000000000 +0200
@@ -0,0 +1,58 @@
+--- a/plugins/personal/posix/class_posixAccount.inc
++++ b/plugins/personal/posix/class_posixAccount.inc
+@@ -155,7 +155,9 @@
+       $this->initially_was_account= $this->is_account;
+ 
+       /* Fill group */
+-      $this->primaryGroup= $this->gidNumber;
++      if ($this->gidNumber !== "") {
++          $this->primaryGroup= intval($this->gidNumber);
++      }
+ 
+       /* Generate status text */
+       $current= date("U");
+@@ -634,10 +636,10 @@
+       /*Save primary group settings */
+       if($this->acl_is_writeable("primaryGroup") && isset($_POST['primaryGroup'])){
+         $data= get_post('primaryGroup');
+-        if ($this->primaryGroup != $data){
++        if ($this->primaryGroup != intval($data)){
+           $this->is_modified= TRUE;
+         }
+-        $this->primaryGroup= get_post('primaryGroup');
++        $this->primaryGroup= intval(get_post('primaryGroup'));
+       }
+ 
+       /* Get seelcted shadow checkboxes */
+@@ -934,7 +936,7 @@
+     }
+ 
+     /* Check ID's if they are forced by user */
+-    if ($this->force_ids == "1"){
++    if ($this->force_ids == 1){
+ 
+       /* Valid uid/gid? */
+       if (!tests::is_id($this->uidNumber)){
+@@ -1239,11 +1241,11 @@
+         $this->is_modified= TRUE;
+       }
+       $this->force_ids= $data;
+-      $data= get_post('primaryGroup');
++      $data= intval(get_post('primaryGroup'));
+       if ($this->primaryGroup != $data){
+         $this->is_modified= TRUE;
+       }
+-      $this->primaryGroup= get_post('primaryGroup');
++      $this->primaryGroup= intval(get_post('primaryGroup'));
+     }
+   }
+ 
+@@ -1354,7 +1356,7 @@
+ 
+     /* Fill group */
+     if(isset($source['gidNumber'][0])){
+-      $this->primaryGroup= $source['gidNumber'][0];
++      $this->primaryGroup= intval($source['gidNumber'][0]);
+     }
+ 
+ 
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1025_fix-icons-in-debugBar.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1025_fix-icons-in-debugBar.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1025_fix-icons-in-debugBar.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1025_fix-icons-in-debugBar.patch	2023-08-17 08:27:32.000000000 +0200
@@ -0,0 +1,18 @@
+Description: Don't use image() method from GOsa²'s function.inc. The debug toolbar is not themed, so hard-code icon img tags.
+Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+
+--- a/include/php_setup.inc
++++ b/include/php_setup.inc
+@@ -102,10 +102,8 @@
+       $error_collector= "<div>";
+     } else {
+ 
+-        $warning_image = (is_callable('image')) ? 
+-            image('images/toolbar-warning.png') : "<image src='images/toolbar-warning.png' border=0>";
+-        $mailto_image = (is_callable('image')) ? 
+-            image('images/mailto.png') : "<image src='images/mailto.png' border=0>";
++        $warning_image = "<img src='images/toolbar-warning.png' border=0>";
++        $mailto_image = "<img src='images/mailto.png' border=0>";
+ 
+         $error_collector= "
+         <table summary=\"\" class='error-collector'>
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1026_dont-access-static-property-non-static.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1026_dont-access-static-property-non-static.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1026_dont-access-static-property-non-static.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1026_dont-access-static-property-non-static.patch	2023-08-17 12:54:48.000000000 +0200
@@ -0,0 +1,11 @@
+--- a/include/class_config.inc
++++ b/include/class_config.inc
+@@ -359,7 +359,7 @@
+      */
+     function get_ldap_link($sizelimit= FALSE)
+     {
+-        if($this->ldap === NULL || !is_resource($this->ldap->cid)){
++        if($this->ldap === NULL || !is_resource($this->ldap::$cid)){
+ 
+             /* Build new connection */
+             $this->ldap= ldap_init ($this->current['SERVER'], $this->current['BASE'],
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1027_include-functions-class_userinfo-.inc-Don-t-referenc.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1027_include-functions-class_userinfo-.inc-Don-t-referenc.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1027_include-functions-class_userinfo-.inc-Don-t-referenc.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1027_include-functions-class_userinfo-.inc-Don-t-referenc.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,50 @@
+From 5f0017257a7c6941a57273712051e36f60330c1a Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Thu, 17 Aug 2023 21:32:49 +0200
+Subject: [PATCH 02/13] include/{functions,class_userinfo}.inc: Don't reference
+ non-variable. Resolves PHP error 'Only variables should be assigned by
+ reference'.
+
+---
+ include/class_userinfo.inc | 2 +-
+ include/functions.inc      | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/class_userinfo.inc b/include/class_userinfo.inc
+index 48784bd..dd0780d 100644
+--- a/include/class_userinfo.inc
++++ b/include/class_userinfo.inc
+@@ -586,7 +586,7 @@ class userinfo
+     }
+ 
+     /* Use cached results if possilbe */
+-    $ACL_CACHE = &session::global_get('ACL_CACHE');
++    $ACL_CACHE = session::global_get('ACL_CACHE');
+ 
+     if(!is_array($module)){
+       $module = array($module);
+diff --git a/include/functions.inc b/include/functions.inc
+index 612c85f..73c8808 100644
+--- a/include/functions.inc
++++ b/include/functions.inc
+@@ -845,7 +845,7 @@ function add_lock($object, $user)
+     return;
+   }
+ 
+-  $cache = &session::global_get("LOCK_CACHE");
++  $cache = session::global_get("LOCK_CACHE");
+   if(isset($_POST['open_readonly'])){
+     $cache['READ_ONLY'][$object] = TRUE;
+     return;
+@@ -915,7 +915,7 @@ function del_lock ($object)
+       skip removing the lock entry, there wasn't any lock created.
+     */
+   if(session::global_is_set("LOCK_CACHE")){
+-    $cache = &session::global_get("LOCK_CACHE");
++    $cache = session::global_get("LOCK_CACHE");
+     if(isset($cache['READ_ONLY'][$object])){
+       unset($cache['READ_ONLY'][$object]);
+       return;
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1028_include-class_listing.inc-Avoid-implicit-array-to-st.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1028_include-class_listing.inc-Avoid-implicit-array-to-st.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1028_include-class_listing.inc-Avoid-implicit-array-to-st.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1028_include-class_listing.inc-Avoid-implicit-array-to-st.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,26 @@
+From 0912797adb120eb4c898df755d4458e8a5dd9c15 Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Thu, 17 Aug 2023 21:41:52 +0200
+Subject: [PATCH 03/13] include/class_listing.inc: Avoid implicit
+ array-to-string conversion.
+
+---
+ include/class_listing.inc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/class_listing.inc b/include/class_listing.inc
+index 543e363..a713911 100644
+--- a/include/class_listing.inc
++++ b/include/class_listing.inc
+@@ -1156,7 +1156,7 @@ class listing
+             }
+ 
+             if ($_param_count > count($params)) {
+-                error_log("ERROR: Number of expected parameters is greater than collected parameters! For match='$match'.");
++                error_log("ERROR: Number of expected parameters is greater than collected parameters! For match='[".implode(', ', $match)."]");
+                 continue;
+             }
+ 
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1029_include-class_session.inc-Only-operate-on-an-element.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1029_include-class_session.inc-Only-operate-on-an-element.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1029_include-class_session.inc-Only-operate-on-an-element.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1029_include-class_session.inc-Only-operate-on-an-element.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,35 @@
+From 8bea4b53f8eaf0c18a0e7a15a7bb012f951a4a7c Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Thu, 17 Aug 2023 21:42:55 +0200
+Subject: [PATCH 04/13] include/class_session.inc: Only operate on an element
+ in $_SESSION if it exists.
+
+---
+ include/class_session.inc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/class_session.inc b/include/class_session.inc
+index ef0a23d..9b943ec 100644
+--- a/include/class_session.inc
++++ b/include/class_session.inc
+@@ -135,7 +135,7 @@ class session {
+ 
+     public static function global_get($name)
+     {
+-        return $_SESSION[$name];
++        return isset($_SESSION[$name]) ? $_SESSION[$name] : "";
+     }
+ 
+     public static function delete($name)
+@@ -159,7 +159,7 @@ class session {
+ 
+     public static function global_delete($name)
+     {
+-        if($_SESSION[$name]){
++        if(isset($_SESSION[$name])){
+             unset($_SESSION[$name]);
+         }
+     }
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1030_class_group.inc-class_trustedModeDialog.inc-class_po.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1030_class_group.inc-class_trustedModeDialog.inc-class_po.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1030_class_group.inc-class_trustedModeDialog.inc-class_po.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1030_class_group.inc-class_trustedModeDialog.inc-class_po.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,54 @@
+From cc145f6a6c68ed52531df1763c6f18634a4ef258 Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Thu, 17 Aug 2023 22:00:01 +0200
+Subject: [PATCH 05/13] class_group.inc, class_trustedModeDialog.inc,
+ class_posixAccount.inc: Only access array elements if they are set.
+
+---
+ plugins/admin/groups/class_group.inc                            | 2 +-
+ plugins/personal/posix/class_posixAccount.inc                   | 2 +-
+ .../personal/posix/trustModeDialog/class_trustModeDialog.inc    | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/plugins/admin/groups/class_group.inc b/plugins/admin/groups/class_group.inc
+index 868f9e1..2f268b7 100644
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -256,7 +256,7 @@ class group extends plugin
+                 }
+                 $this->$list->save_object();
+                 $action = $this->$list->getAction();
+-                if($action['action'] == 'delete' && preg_match("/w/",$this->getacl("memberUid"))){
++                if(isset($action) && ($action['action'] == 'delete') && preg_match("/w/",$this->getacl("memberUid"))){
+                     foreach ($action['targets'] as $id){
+                         $value = $this->$list->getKey($id);
+                         unset ($this->members["$value"]);
+diff --git a/plugins/personal/posix/class_posixAccount.inc b/plugins/personal/posix/class_posixAccount.inc
+index bb3dd68..2d688c0 100644
+--- a/plugins/personal/posix/class_posixAccount.inc
++++ b/plugins/personal/posix/class_posixAccount.inc
+@@ -371,7 +371,7 @@ class posixAccount extends plugin
+     // Remove groups that were removed by list
+     $this->groupList->save_object();
+     $actionL = $this->groupList->getAction();
+-    if($actionL['action'] == "delete") {
++    if(isset($actionL['action']) && ($actionL['action'] == "delete")) {
+         $key = $this->groupList->getData($actionL['targets'][0]);
+         $this->delGroup(array($key));
+     }
+diff --git a/plugins/personal/posix/trustModeDialog/class_trustModeDialog.inc b/plugins/personal/posix/trustModeDialog/class_trustModeDialog.inc
+index 2ac5e82..8ba8164 100644
+--- a/plugins/personal/posix/trustModeDialog/class_trustModeDialog.inc
++++ b/plugins/personal/posix/trustModeDialog/class_trustModeDialog.inc
+@@ -142,7 +142,7 @@ class trustModeDialog extends plugin
+ 
+         // Remove machine from trusted ones.
+         $actionL = $this->trustList->getAction();
+-        if ($actionL['action'] == "delete"){
++        if (isset($actionL['action']) && ($actionL['action'] == "delete")){
+             $this->accessTo = $this->trustList->getMaintainedData();
+             $this->is_modified= TRUE;
+         }
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1031_html-main.php-Fix-bug-where-config-is-a-string-after.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1031_html-main.php-Fix-bug-where-config-is-a-string-after.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1031_html-main.php-Fix-bug-where-config-is-a-string-after.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1031_html-main.php-Fix-bug-where-config-is-a-string-after.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,27 @@
+From 240c597c7d21684a2db5b105f56aebddfdfccd57 Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Tue, 22 Aug 2023 16:06:10 +0200
+Subject: [PATCH 07/13] html/main.php: Fix bug where $config is a string after
+ a while of AFK. GOsa would show PHP crashing.
+
+Can be amended to existing patch!
+---
+ html/main.php | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/html/main.php b/html/main.php
+index e46acda..c2b8cf0 100644
+--- a/html/main.php
++++ b/html/main.php
+@@ -76,7 +76,7 @@ $ui= session::global_get('ui');
+ // }
+ 
+ $config = session::global_get('config');
+-if (!isset($config)) {
++if (!isset($config) || !is_object($config)) {
+   #die("Could not get config object. Please contact your system administrator or try again later.\n");
+   new log("security","login","",array(),"main.php called with empty config object. Logging user out.") ;
+   header ("Location: logout.php");
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1032_include-class_sortableListing.inc-Fix-copy-paste-mis.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1032_include-class_sortableListing.inc-Fix-copy-paste-mis.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1032_include-class_sortableListing.inc-Fix-copy-paste-mis.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1032_include-class_sortableListing.inc-Fix-copy-paste-mis.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,29 @@
+From 9f823cc51137ab5edccc0d8efe5f221660096c68 Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Wed, 23 Aug 2023 15:19:20 +0200
+Subject: [PATCH 10/13] include/class_sortableListing.inc: Fix copy&paste
+ mistake. Don't try to get element 0 of INTEGER $index.
+
+---
+ include/class_sortableListing.inc | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/include/class_sortableListing.inc b/include/class_sortableListing.inc
+index ee4346f..2e4b59f 100644
+--- a/include/class_sortableListing.inc
++++ b/include/class_sortableListing.inc
+@@ -763,9 +763,9 @@ class sortableListing
+     public function getKey($index)
+     {
+         if (is_array($index)) {
+-            return isset($this->keys[$index[0]])?$this->keys[$index[0]]:null;
++            return isset($this->keys[$index[0]]) ? $this->keys[$index[0]] : null;
+         } else {
+-            return isset($this->keys[$index[0]])?$this->keys[$index]:null;
++            return isset($this->keys[$index]) ? $this->keys[$index] : null;
+         }
+     }
+ 
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1033_include-class_acl.inc-Fix-indentation-whitespace-of-.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1033_include-class_acl.inc-Fix-indentation-whitespace-of-.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1033_include-class_acl.inc-Fix-indentation-whitespace-of-.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1033_include-class_acl.inc-Fix-indentation-whitespace-of-.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,25 @@
+From d9fe3af9f503ba567dfd14d927fac909a67e8847 Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Wed, 23 Aug 2023 16:48:19 +0200
+Subject: [PATCH] include/class_acl.inc: Fix indentation + whitespace of
+ execute() block.
+
++ Fix $this->$value -> $this->value (Note: the extra $!)
++ Fix case where $oc would not be initialized.
+---
+ include/class_acl.inc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+--- a/include/class_acl.inc
++++ b/include/class_acl.inc
+@@ -161,9 +161,9 @@
+     /* Objects */
+     $tmp= session::global_get('plist');
+     $plist= $tmp->info;
++    $oc = array();
+     $cats = array();
+     if (isset($this->parent) && $this->parent !== NULL){
+-        $oc= array();
+         foreach ($this->parent->by_object as $key => $obj){
+             if(isset($obj->objectclasses) && is_array($obj->objectclasses)){
+                 $oc= array_merge($oc, $obj->objectclasses);
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1034_include-class_listing.inc-Fix-processElementFilter-n.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1034_include-class_listing.inc-Fix-processElementFilter-n.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1034_include-class_listing.inc-Fix-processElementFilter-n.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1034_include-class_listing.inc-Fix-processElementFilter-n.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,49 @@
+From 8f79138c86b3b9a58b5322fa999e8e1bb6f2b82a Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Fri, 25 Aug 2023 14:11:09 +0200
+Subject: [PATCH 1/3] include/class_listing.inc: Fix processElementFilter() not
+ considering default values for method parameters.
+
+Introduced by c996dc9d1d60c2152 (fix_develop).
+
+Closes: #1050489
+---
+ include/class_listing.inc | 22 +++++++++++++++++++---
+ 1 file changed, 19 insertions(+), 3 deletions(-)
+
+diff --git a/include/class_listing.inc b/include/class_listing.inc
+index a713911..de44ada 100644
+--- a/include/class_listing.inc
++++ b/include/class_listing.inc
+@@ -1155,9 +1155,25 @@ class listing
+                 continue;
+             }
+ 
+-            if ($_param_count > count($params)) {
+-                error_log("ERROR: Number of expected parameters is greater than collected parameters! For match='[".implode(', ', $match)."]");
+-                continue;
++            $_params_count_supplied = count($params);
++            if ($_param_count > $_params_count_supplied) {
++                # Check if method can still be called because of default
++                # parameters values. e.g. foo($required, $optional = "bar");
++
++                $_i = 0;
++                foreach ($reflection->getParameters() as $param) {
++                    # If there are any parameters passed, then skip these.
++                    # We want to check if the parameters after them are optional.
++                    if ($_i < $_params_count_supplied) {
++                        $_i++;
++                        continue;
++                    }
++
++                    if (!$param->isOptional()) {
++                        error_log("ERROR: Number of expected parameters is greater than collected parameters! For match='[".implode(', ', $match)."]");
++                        continue;
++                    }
++                }
+             }
+ 
+             // Replace information
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1035_acl_override_to_allow_delete_of_group_members.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1035_acl_override_to_allow_delete_of_group_members.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1035_acl_override_to_allow_delete_of_group_members.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1035_acl_override_to_allow_delete_of_group_members.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,19 @@
+Description: Support member removal from groups, if someone has the right to edit the group.
+Author: Christian Schwamborn <cs at imap.architektur.tu-darmstadt.de>
+Forwarded: https://github.com/gosa-project/gosa-core/pull/20
+
+--- a/plugins/admin/groups/class_group.inc
++++ b/plugins/admin/groups/class_group.inc
+@@ -248,6 +248,12 @@
+ 
+             // Check if list is available, depends on multi- or sinlge- group editing. 
+             if($this->$list){
++                // ensure we can delete group members if we have
++                // write permission to the memberUid attribute
++                $mu_acl = $this->getacl("memberUid");
++                if (preg_match("/w/",$mu_acl) && !preg_match("/d/",$mu_acl)) {
++                    $this->$list->setAcl($mu_acl.'d');
++                }
+                 $this->$list->save_object();
+                 $action = $this->$list->getAction();
+                 if($action['action'] == 'delete' && preg_match("/w/",$this->getacl("memberUid"))){
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1036_include-class_filter.inc-Define-gridClass-for-defaul.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1036_include-class_filter.inc-Define-gridClass-for-defaul.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1036_include-class_filter.inc-Define-gridClass-for-defaul.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1036_include-class_filter.inc-Define-gridClass-for-defaul.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,34 @@
+From 401da3f49eab97376e8bd6e8a7bc074791766ce6 Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Fri, 25 Aug 2023 14:34:20 +0200
+Subject: [PATCH 3/3] include/class_filter.inc: Define gridClass for default
+ and classic theme.
+
+---
+ include/class_filter.inc | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/include/class_filter.inc b/include/class_filter.inc
+index 376182d..0be86fd 100644
+--- a/include/class_filter.inc
++++ b/include/class_filter.inc
+@@ -446,6 +446,7 @@ class filter
+ 
+     public function renderFilterMenu()
+     {
++        $gridClass = "class='filtermenu'";
+         $script = "";
+ 
+         switch ($this->theme) {
+@@ -568,8 +569,6 @@ class filter
+                                 </li>";
+ 
+                 $result .= "</ul></li></ul>";
+-
+-                $gridClass = "class='filtermenu'";
+                 break;
+         }
+         return "<div $gridClass id='filtermenu'>".$result."</li></ul></div>$script";
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1037_include-php_setup.inc-Hide-ldap_-search-read-Search-.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1037_include-php_setup.inc-Hide-ldap_-search-read-Search-.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1037_include-php_setup.inc-Hide-ldap_-search-read-Search-.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1037_include-php_setup.inc-Hide-ldap_-search-read-Search-.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,33 @@
+From 412105290d6bc56ffe83c53fdc4347d10114eaf1 Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Tue, 29 Aug 2023 20:38:20 +0200
+Subject: [PATCH] include/php_setup.inc: Hide 'ldap_{search,read}(): Search: No
+ such object.' errors. They occur rather often and don't hint to an actual
+ error.
+
+---
+ include/php_setup.inc | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/include/php_setup.inc b/include/php_setup.inc
+index 7aa57f2..429c163 100644
+--- a/include/php_setup.inc
++++ b/include/php_setup.inc
+@@ -52,6 +52,14 @@ function gosaRaiseError($errno, $errstr, $errfile, $errline)
+     }
+   }
+ 
++  /* Hide 'ldap_(search|read)(): Search: No such object' messages */
++  if (preg_match('/ldap_(search|read)/', $errstr)){
++    if (preg_match('/No such object/', $errstr)){
++      set_error_handler('gosaRaiseError', E_WARNING |  E_NOTICE | E_USER_ERROR | E_USER_WARNING | E_USER_NOTICE | E_STRICT) ;
++      return;
++    }
++  }
++
+   /* Error messages are hidden in GOsa, so we only send them to the logging class and abort here */
+   if(isset($config->data) && $config->get_cfg_value("core","displayErrors") != "true"){
+ 
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1038_include-class_pathNavigator.inc-Don-t-send-object-DN.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1038_include-class_pathNavigator.inc-Don-t-send-object-DN.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1038_include-class_pathNavigator.inc-Don-t-send-object-DN.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1038_include-class_pathNavigator.inc-Don-t-send-object-DN.patch	2023-12-03 08:11:48.000000000 +0100
@@ -0,0 +1,26 @@
+From fe0e270135c7d65e2ec391d1eecc8098b3ebc439 Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Tue, 29 Aug 2023 12:55:04 +0200
+Subject: [PATCH] include/class_pathNavigator.inc: Don't send object DN for new
+ objects when registering plugin.
+
+---
+ include/class_pathNavigator.inc | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/include/class_pathNavigator.inc b/include/class_pathNavigator.inc
+index f2003d8..e04bebd 100644
+--- a/include/class_pathNavigator.inc
++++ b/include/class_pathNavigator.inc
+@@ -22,7 +22,7 @@ class pathNavigator
+         // In case of tabs add the 'dn' of the entry
+         if ($class instanceof tabs) {
+             // Convert dn to cn
+-            if (isset($class->dn)) {
++            if (isset($class->dn) && $class->dn !== "new") {
+                 if (!session::is_set("pathNavigator::registerPlugin:{$class->dn}")) {
+                     global $config;
+                     $ldap = $config->get_ldap_link();
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1040_fix-instance-property-typo-in-class_acl-inc.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1040_fix-instance-property-typo-in-class_acl-inc.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1040_fix-instance-property-typo-in-class_acl-inc.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1040_fix-instance-property-typo-in-class_acl-inc.patch	2023-12-03 08:11:48.000000000 +0100
@@ -0,0 +1,15 @@
+Description: Typo fix in accessing instance property.
+Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+
+
+--- a/include/class_acl.inc
++++ b/include/class_acl.inc
+@@ -177,7 +177,7 @@
+             $this->isContainer = TRUE;
+         }
+     } else {
+-        if (is_array($this->$attrs) && in_array('objectClass', $this->attrs)) {
++        if (is_array($this->attrs) && in_array('objectClass', $this->attrs)) {
+             $oc = $this->attrs['objectClass'];
+         }
+     }
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1041_fix-role-selector.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1041_fix-role-selector.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1041_fix-role-selector.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1041_fix-role-selector.patch	2023-12-03 08:11:48.000000000 +0100
@@ -0,0 +1,16 @@
+Author: Guido Berhoerster <guido+freiesoftware at berhoerster.name>
+Description: Fix role selector when using the default theme
+ Add workaround for Matrialize.css which hides <input> elements with type=radio
+ unless wrapped in a <label> and followed by a <span> element.
+Index: gosa/include/class_acl.inc
+===================================================================
+--- gosa.orig/include/class_acl.inc
++++ gosa/include/class_acl.inc
+@@ -872,6 +872,7 @@ class acl extends plugin
+             }else{
+                 $option = "<input type='radio' name='selected_role' value='".base64_encode($dn)."'>";
+             }
++            $option = "<label>" . $option . "<span></span></label>";
+             $data[] = postEncode($dn);
+             $lData[] = array('data'=>array($option, $values['cn'], $values['description']));
+         }
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1042_fix-user-info-default-theme.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1042_fix-user-info-default-theme.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1042_fix-user-info-default-theme.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1042_fix-user-info-default-theme.patch	2023-12-03 08:11:48.000000000 +0100
@@ -0,0 +1,378 @@
+Author: Guido Berhoerster <guido+freiesoftware at berhoerster.name>
+Descripton: Fix user info page when using default theme
+
+Fix styling of user properties.
+Fix plugin list generation. Move openPlugin JS function outside of $menu Smarty
+variable since it used outside of the menu as well and $menu is not rendered in
+the default theme when no menu is requested.
+--- gosa.orig/plugins/generic/infoPage/class_infoPage.inc
++++ gosa/plugins/generic/infoPage/class_infoPage.inc
+@@ -32,20 +32,61 @@ class infoPage extends plugin
+         $plist = session::get('plist');
+         $myAccountID = array_search('MyAccount',$plist->pluginList);
+         $str = "";
+-        foreach($this->config->data['TABS']['MYACCOUNTTABS'] as $pluginData){
+-            $plugin = $pluginData['CLASS'];
+ 
+-            if(!$this->checkAccess($plugin)) continue;
++        switch (getThemeName()) {
++        case 'classic':
++            foreach($this->config->data['TABS']['MYACCOUNTTABS'] as $pluginData){
++                $plugin = $pluginData['CLASS'];
+ 
+-            list($index, $title, $desc, $icon) = $plist->getPlugData($plugin);
+-            $str.= "\n        <div class='icon-menu-item' style='width: 20%;' onclick='openPlugin(\"{$myAccountID}\",\"{$plugin}\")'>";
+-            $str.= "\n          ".image($icon);
+-            $str.= "\n          <div class='dsc'>";
+-            $str.= "\n            <h1>{$title}</h1>";
+-            $str.= "\n            <p>{$desc}</p>";
+-            $str.= "\n          </div>";
+-            $str.= "\n        </div>";
++                if(!$this->checkAccess($plugin)) continue;
+ 
++                list($index, $title, $desc, $icon) = $plist->getPlugData($plugin);
++                $str.= "\n        <div class='icon-menu-item' style='width: 20%;' onclick='openPlugin(\"{$myAccountID}\",\"{$plugin}\")'>";
++                $str.= "\n          ".image($icon);
++                $str.= "\n          <div class='dsc'>";
++                $str.= "\n            <h1>{$title}</h1>";
++                $str.= "\n            <p>{$desc}</p>";
++                $str.= "\n          </div>";
++                $str.= "\n        </div>";
++            }
++            break;
++        default:
++            $row = 0;
++            $plugCount = count($this->config->data['TABS']['MYACCOUNTTABS']);
++
++            $str.= "\n        <div class='row startpage-iconmenu'>";
++            foreach($this->config->data['TABS']['MYACCOUNTTABS'] as $pluginData){
++                $plugin = $pluginData['CLASS'];
++
++                if(!$this->checkAccess($plugin)) continue;
++
++                list($index, $title, $desc, $icon) = $plist->getPlugData($plugin);
++
++                if (($col % 6) == 0 && $col != 0) {
++                    $str.= "\n        <div class='row startpage-iconmenu'>";
++                }
++
++                $str.= "\n            <a class='col s4 xl2 pointer'>";
++                $str.= "\n            <div class='card horizontal valign-wrapper' onclick='openPlugin(\"{$myAccountID}\",\"{$plugin}\")'>";
++                $str.= "\n                <div class='card-image'>";
++                $str.= "\n                    <i class='material-icons md-30'>$icon</i>";
++                $str.= "\n                </div>";
++                $str.= "\n                <div class='card-stacked'>";
++                $str.= "\n                    <div class='card-content'>";
++                $str.= "\n                        <h3 class='card-title'>{$title}</h3>";
++                $str.= "\n                        <p>{$desc}</p>";
++                $str.= "\n                    </div>";
++                $str.= "\n                </div>";
++                $str.= "\n            </div>";
++                $str.= "\n            </a>";
++
++                ++$col;
++                if (($col % 6) == 0 && $col != 0 && $col != $plugCount) {
++                    $str .= "\n        </div>";
++                }
++            }
++            $str .= "\n        </div>";
++            break;
+         }
+         return($str);
+     }
+--- gosa.orig/ihtml/themes/default/framework.tpl
++++ gosa/ihtml/themes/default/framework.tpl
+@@ -1,4 +1,5 @@
+ <body>
++    {$pluginScript}
+     {$php_errors}
+     {$msg_dialogs}
+     <nav class="accent">
+--- gosa.orig/include/class_pluglist.inc
++++ gosa/include/class_pluglist.inc
+@@ -44,6 +44,7 @@ class pluglist
+     // Some cache vars to avoid regenration of the menus.
+     public $pathMenu = '';
+     public $menu = '';
++    public $pluginScript = '';
+     public $iconmenu = '';
+     public $breadcrumb = '';
+ 
+@@ -224,6 +225,29 @@ class pluglist
+         return false;
+     }
+ 
++    /*! \brief    Generate script for opening Plugins from the menu or plugin
++     *            list which prints out warning messages when leaving an
++     *            unsaved form. We do it in here to get the string translated.
++     */
++    public function gen_plugin_script()
++    {
++        if ($this->pluginScript == '') {
++            $this->pluginScript =
++                "\n      <script language='javascript' type='text/javascript'>".
++                "\n        function openPlugin(id, plugin){".
++                "\n          if(plugin){ ".
++                "\n             plugin = '&pluginTab=' +  plugin".
++                "\n          }else{".
++                "\n             plugin = '';".
++                "\n          }".
++                "\n          return question(\""._('You are currently editing a database entry. Do you want to discard the changes?').'",'.
++                "\n            \"main.php?plug=\" + id + \"&reset=1\" + plugin);".
++                "\n        }".
++                "\n      </script>\n";
++        }
++        return $this->pluginScript;
++    }
++
+     /*! \brief    Generate the GOsa Main-Menu here (The menu on the left),
+      *             this usually only done once during login.
+      *            -----------------------------------------------------------------
+@@ -331,21 +355,6 @@ class pluglist
+                     }
+                     break;
+             }
+-
+-            // Add javascript method to print out warning messages while leaving an unsaved form.
+-            // We do it in here to get the string translated.
+-            $this->menu .=
+-                "\n      <script language='javascript' type='text/javascript'>".
+-                "\n        function openPlugin(id, plugin){".
+-                "\n          if(plugin){ ".
+-                "\n             plugin = '&pluginTab=' +  plugin".
+-                "\n          }else{".
+-                "\n             plugin = '';".
+-                "\n          }".
+-                "\n          return question(\""._('You are currently editing a database entry. Do you want to discard the changes?').'",'.
+-                "\n            \"main.php?plug=\" + id + \"&reset=1\" + plugin);".
+-                "\n        }".
+-                "\n      </script>\n";
+         }
+ 
+         // Use javascript to mark the currently selected plugin.
+--- gosa.orig/html/main.php
++++ gosa/html/main.php
+@@ -214,6 +214,7 @@ if (session::global_is_set('plugin_dir')
+ }
+ 
+ // Generate menus
++$plist->gen_plugin_script();
+ $plist->gen_headlines();
+ $plist->gen_menu();
+ $plist->genPathMenu();
+@@ -393,6 +394,7 @@ if($reload_navigation){
+   $plist->menu="";
+ }
+ $smarty->assign ("menu", $plist->gen_menu());
++$smarty->assign ("pluginScript", $plist->gen_plugin_script());
+ $smarty->assign ("plug", "$plug");
+ 
+ 
+--- gosa.orig/ihtml/themes/classic/framework.tpl
++++ gosa/ihtml/themes/classic/framework.tpl
+@@ -1,4 +1,5 @@
+ <body>
++  {$pluginScript}
+   {$php_errors}
+   <div class='title-bar'>
+     <ul>
+@@ -75,4 +76,4 @@
+   </script>
+ </body>
+ 
+-</html>
+\ No newline at end of file
++</html>
+--- gosa.orig/ihtml/themes/default/infoPage.tpl
++++ gosa/ihtml/themes/default/infoPage.tpl
+@@ -1,99 +1,93 @@
+-<div class="information-wrapper">
++<div class="information-wrapper content">
+     {if $personalInfoAllowed}
+ 
+     <h3>{t}User information{/t}</h3>
+ 
+-    <table width="100%">
+-        <tr>
+-            <td style='width:200px; vertical-align: middle;'>
+-                {if $jpegPhoto == ""}
+-                <img src="plugins/users/images/default.jpg" alt=''>
+-                {else}
+-                <img src="getbin.php?rand={$rand}" alt=''
+-                    style='border:1px solid #CCC; max-width:147px; max-height: 200px; vertical-align: middle;'>
+-                {/if}
+-            </td>
+-            <td style="width:40%">
+-                <table>
+-                    {if $uid != ""}<tr>
+-                        <td>{t}User ID{/t}:</td>
+-                        <td><i>{$uid}</i></td>
+-                    </tr>{/if}
+-                    {if $sn != ""}<tr>
+-                        <td>{t}Surname{/t}:</td>
+-                        <td><i>{$sn}</i></td>
+-                    </tr>{/if}
+-                    {if $givenName != ""}<tr>
+-                        <td>{t}Given name{/t}:</td>
+-                        <td><i>{$givenName}</i></td>
+-                    </tr>{/if}
+-                    {if $personalTitle != ""}<tr>
+-                        <td>{t}Personal title{/t}:</td>
+-                        <td><i>{$personalTitle}</i></td>
+-                    </tr>{/if}
+-                    {if $academicTitle != ""}<tr>
+-                        <td>{t}Academic title{/t}:</td>
+-                        <td><i>{$academicTitle}</i></td>
+-                    </tr>{/if}
+-                    {if $homePostalAddress != ""}<tr>
+-                        <td style="padding-top:15px">{t}Home postal address{/t}:</td>
+-                        <td style="padding-top:15px"><i>{$homePostalAddress}</i></td>
+-                    </tr>{/if}
+-                    {if $dateOfBirth != ""}<tr>
+-                        <td style="padding-top:15px">{t}Date of birth{/t}:</td>
+-                        <td style="padding-top:15px"><i>{$dateOfBirth}</i></td>
+-                    </tr>{/if}
+-                    {if $mail != ""}<tr>
+-                        <td style="padding-top:15px">{t}Mail{/t}:</td>
+-                        <td style="padding-top:15px"><i>{$mail}</i></td>
+-                    </tr>{/if}
+-                    {if $homePhone != ""}<tr>
+-                        <td>{t}Home phone number{/t}:</td>
+-                        <td><i>{$homePhone}</i></td>
+-                    </tr>{/if}
+-                </table>
+-            </td>
+-            <td style="border-left:1px solid #CCC; padding-left:10px">
+-                <table>
+-                    {if $o != ""}<tr>
+-                        <td>{t}Organization{/t}:</td>
+-                        <td><i>{$o}</i></td>
+-                    </tr>{/if}
+-                    {if $ou != ""}<tr>
+-                        <td>{t}Organizational Unit{/t}:</td>
+-                        <td><i>{$ou}</i></td>
+-                    </tr>{/if}
+-                    {if $l != ""}<tr>
+-                        <td style="padding-top:15px">{t}Location{/t}:</td>
+-                        <td style="padding-top:15px"><i>{$l}</i></td>
+-                    </tr>{/if}
+-                    {if $street != ""}<tr>
+-                        <td>{t}Street{/t}:</td>
+-                        <td><i>{$street}</i></td>
+-                    </tr>{/if}
+-                    {if $departmentNumber != ""}<tr>
+-                        <td style="padding-top:15px">{t}Department number{/t}:</td>
+-                        <td style="padding-top:15px"><i>{$departmentNumber}</i></td>
+-                    </tr>{/if}
+-
+-                    {if $employeeNumber != ""}<tr>
+-                        <td style="padding-top:15px">{t}Employee number{/t}:</td>
+-                        <td style="padding-top:15px"><i>{$employeeNumber}</i></td>
+-                    </tr>{/if}
+-                    {if $employeeType != ""}<tr>
+-                        <td>{t}Employee type{/t}:</td>
+-                        <td><i>{$employeeType}</i></td>
+-                    </tr>{/if}
+-
+-                </table>
+-            </td>
+-        </tr>
+-    </table>
++    <div class="row">
++        <div class="col s12 xl2 center-align user-image">
++            {if $jpegPhoto == ""}
++            <img src="plugins/users/images/default.jpg" alt='' class="materialboxed">
++            {else}
++            <img src="getbin.php?rand={$rand}" alt='' class="materialboxed">
++            {/if}
++        </div>
++        <div class="col s6 xl5">
++            {if $uid != ""}<div class="input-field">
++                <input type="text" id="uid" value="{$uid}" disabled>
++                <label for="uid">{t}User ID{/t}:</label>
++            </div>{/if}
++            {if $sn != ""}<div class="input-field">
++                <input type="text" id="surname" value="{$sn}" disabled>
++                <label for="surname">{t}Surname{/t}:</label>
++            </div>{/if}
++            {if $givenName != ""}<div class="input-field">
++                <input type="text" id="givenName" value="{$givenName}" disabled>
++                <label for="givenName">{t}Given name{/t}:</label>
++            </div>{/if}
++            {if $personalTitle != ""}<div class="input-field">
++                <input type="text" id="personalTitle" value="{$personalTitle}" disabled>
++                <label for="personalTitle">{t}Personal title{/t}:</label>
++            </div>{/if}
++            {if $academicTitle != ""}<div class="input-field">
++                <input type="text" id="academicTitle" value="{$academicTitle}" disabled>
++                <label for="academicTitle">{t}Academic title{/t}:</label>
++            </div>{/if}
++            {if $homePostalAddress != ""}<div class="input-field">
++                <textarea class="materialize-textarea" id="homePostalAddress" disabled>
++                    {$homePostalAddress}
++                </textarea>
++                <label for="homePostalAddress">{t}Home postal address{/t}:</label>
++            </div>{/if}
++            {if $dateOfBirth != ""}<div class="input-field">
++                <input type="text" id="dateOfBirth" value="{$dateOfBirth}" disabled>
++                <label for="dateOfBirth">{t}Date of birth{/t}:</label>
++            </div>{/if}
++            {if $mail != ""}<div class="input-field">
++                <input type="text" id="mail" value="{$mail}" disabled>
++                <label for="mail">{t}Mail{/t}:</label>
++            </div>{/if}
++            {if $homePhone != ""}<div class="input-field">
++                <input type="text" id="homePhone" value="{$homePhone}" disabled>
++                <label for="homePhone">{t}Home phone number{/t}:</label>
++            </div>{/if}
++        </div>
++        <div class="col s6 xl5">
++            {if $o != ""}<tr>
++                <input type="text" id="o" value="{$o}" disabled>
++                <label for="o">{t}Organization{/t}:</label>
++            </div>{/if}
++            {if $ou != ""}<div class="input-field">
++                <input type="text" id="ou" value="{$ou}" disabled>
++                <label for="ou">{t}Organizational Unit{/t}:</label>
++            </div>{/if}
++            {if $l != ""}<div class="input-field">
++                <input type="text" id="l" value="{$l}" disabled>
++                <label for="l">{t}Location{/t}:</label>
++            </div>{/if}
++            {if $street != ""}<div class="input-field">
++                <input type="text" id="street" value="{$street}" disabled>
++                <label for="street">{t}Street{/t}:</label>
++            </div>{/if}
++            {if $departmentNumber != ""}<div class="input-field">
++                <input type="text" id="departmentNumber" value="{$departmentNumber}" disabled>
++                <label for="departmentNumber">{t}Department number{/t}:</label>
++            </div>{/if}
++
++            {if $employeeNumber != ""}<div class="input-field">
++                <input type="text" id="employeeNumber" value="{$employeeNumber}" disabled>
++                <label for="employeeNumber">{t}Employee number{/t}:</label>
++            </div>{/if}
++            {if $employeeType != ""}<div class="input-field">
++                <input type="text" id="employeeType" value="{$employeeType}" disabled>
++                <label for="employeeType">{t}Employee type{/t}:</label>
++            </div>{/if}
++        </div>
++    </div>
+ 
+     {/if}
+ 
+     {if $plugins != ""}
+-    <hr>
++    <hr class="divider">
+     <h3>{t}User settings{/t}</h3>
+     {$plugins}
+     <div class="clear"></div>
+@@ -107,7 +101,7 @@
+     {/if}
+ 
+     {if $managersCnt != 0}
+-    <hr>
++    <hr class="divider">
+     <h3>{t}Administrative contact{/t}</h3>
+     {foreach from=$managers item=item}
+     <div style='float:left; padding-right:20px;'>
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1043a_Add-setter-for-skipFooter-property-needed-for-mfa-ex.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1043a_Add-setter-for-skipFooter-property-needed-for-mfa-ex.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1043a_Add-setter-for-skipFooter-property-needed-for-mfa-ex.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1043a_Add-setter-for-skipFooter-property-needed-for-mfa-ex.patch	2023-12-03 08:11:48.000000000 +0100
@@ -0,0 +1,29 @@
+From 6e6e435b8b858a72ad17ca31af8221451db45c80 Mon Sep 17 00:00:00 2001
+From: Jochen Schimmelpfennig <jochen at onlinegeneration.com>
+Date: Mon, 13 Nov 2023 11:24:33 +0100
+Subject: [PATCH] Add setter for skipFooter property (needed for mfa extension
+ of usermanagement)
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ include/class_management.inc | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+--- a/include/class_management.inc
++++ b/include/class_management.inc
+@@ -164,6 +164,15 @@
+         return($ret);
+     }
+ 
++    /**
++     * Set a boolean value for the skipFooter control property
++     * @param $skipFooterValue
++     * @return void
++     */
++    public function setSkipFooter(bool $skipFooterValue) {
++        $this->skipFooter = $skipFooterValue;
++    }
++
+ 
+     /*! \brief  Execute this plugin
+      *          Handle actions/events, locking, snapshots, dialogs, tabs,...
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1043b_honour-plugin-property-skipFooter-used-by-mfa-account.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1043b_honour-plugin-property-skipFooter-used-by-mfa-account.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1043b_honour-plugin-property-skipFooter-used-by-mfa-account.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1043b_honour-plugin-property-skipFooter-used-by-mfa-account.patch	2023-12-03 08:11:48.000000000 +0100
@@ -0,0 +1,15 @@
+Description: Honour plugin property skipFooter before drawing buttons.
+Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+
+--- a/include/class_management.inc
++++ b/include/class_management.inc
+@@ -306,6 +306,9 @@
+             if (isset($current->dialog) && (is_object($current->dialog) || $current->dialog)) {
+                 return("");
+             }
++            if (isset($current->skipFooter) && $current->skipFooter) {
++                return("");
++            }
+         }
+ 
+         // Skip footer if requested;
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1044_fix-class-ldap-serialization.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1044_fix-class-ldap-serialization.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1044_fix-class-ldap-serialization.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1044_fix-class-ldap-serialization.patch	2023-12-03 08:11:58.000000000 +0100
@@ -0,0 +1,17 @@
+--- a/include/class_ldap.inc
++++ b/include/class_ldap.inc
+@@ -1557,6 +1557,14 @@
+         return ($result);
+     }
+ 
++    function __serialize(): array
++    {
++        // Quick bug fix, where $this->re contains unserializable data.
++        // Actual fix would be to delete it beforehand (for example in clearResult()).
++        $this->re = [];
++        return (array)$this;
++    }
++
+ }
+ // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
+ ?>
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1045_fix-posixaccount-shadowExpire.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1045_fix-posixaccount-shadowExpire.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1045_fix-posixaccount-shadowExpire.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1045_fix-posixaccount-shadowExpire.patch	2023-12-03 08:11:48.000000000 +0100
@@ -0,0 +1,76 @@
+Author: "Daniel Teichmann" <daniel.teichmann at das-netzwerkteam.de>
+Description: debian/patches/: Add 0003-fix-posixaccount-shadowExpire.patch which fixes shadowExpire always being set to 0. (User can't login then) (Closes: #1053806)
+
+--- a/plugins/personal/posix/class_posixAccount.inc
++++ b/plugins/personal/posix/class_posixAccount.inc
+@@ -213,14 +213,14 @@
+     foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
+           "shadowExpire") as $val){
+ 
+-      if ($this->$val != 0){
++      if ($this->$val != 0 && $this->$val !== "") {
+         $oval= "activate_".$val;
+         $this->$oval= "1";
+       }
+     }
+ 
+     /* Convert shadowExpire for usage */
+-    if ($this->shadowExpire == 0){
++    if ($this->shadowExpire == 0 || $this->shadowExpire == "") {
+       $this->shadowExpire= "";
+     } else {
+       $this->shadowExpire= date('d.m.Y', intval($this->shadowExpire) * 60 * 60 * 24);
+@@ -830,6 +830,9 @@
+     }
+ 
+     foreach(array("shadowMin","shadowMax","shadowWarning","shadowInactive","shadowExpire") as $attr){
++      if (is_string($this->$attr) && empty($this->$attr)) {
++        continue;
++      }
+       $this->$attr = (int) $this->$attr;
+     }
+     /* Call parents save to prepare $this->attrs */
+@@ -1178,7 +1181,7 @@
+     /* Adjust shadow checkboxes */
+     foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
+           "shadowExpire") as $val){
+-      if ($this->$val != 0){
++      if ($this->$val != 0 && $this->$val !== "") {
+         $oval= "activate_".$val;
+         $this->$oval= "1";
+       }
+@@ -1190,7 +1193,7 @@
+     }
+ 
+     /* Convert shadowExpire for usage */
+-    if ($this->shadowExpire == 0){
++    if ($this->shadowExpire == 0 || $this->shadowExpire == "") {
+       $this->shadowExpire= "";
+     } else {
+       $this->shadowExpire= date('d.m.Y', $this->shadowExpire * 60 * 60 * 24);
+@@ -1364,14 +1367,14 @@
+     foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
+                 "shadowExpire") as $val){
+ 
+-        if ($this->$val != 0){
++        if ($this->$val != 0 && $this->$val !== "") {
+             $oval= "activate_".$val;
+             $this->$oval= "1";
+         }
+     }
+ 
+     /* Convert shadowExpire for usage */
+-    if ($this->shadowExpire == 0){
++    if ($this->shadowExpire == 0 || $this->shadowExpire == "") {
+       $this->shadowExpire= "";
+     } else {
+       $this->shadowExpire= date('d.m.Y', $this->shadowExpire * 60 * 60 * 24);
+@@ -1599,7 +1602,7 @@
+     /* Adjust shadow checkboxes */
+     foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
+           "shadowExpire") as $val){
+-      if ($this->$val != 0){
++      if ($this->$val != 0 && $this->$val !== "") {
+         $oval= "activate_".$val;
+         $this->$oval= "1";
+       }
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1060_include-class_acl.inc-Fix-array_keys-being-called-wi.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1060_include-class_acl.inc-Fix-array_keys-being-called-wi.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1060_include-class_acl.inc-Fix-array_keys-being-called-wi.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1060_include-class_acl.inc-Fix-array_keys-being-called-wi.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,28 @@
+From a37b3cf699596bd154b900ce8f67dbc7b701abdc Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Tue, 22 Aug 2023 16:09:02 +0200
+Subject: [PATCH 08/13] include/class_acl.inc: Fix array_keys being called with
+ a string instead of array at param. #1.
+
+Closes: #1049940
+---
+ include/class_acl.inc | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/include/class_acl.inc b/include/class_acl.inc
+index cd77c17..68b0410 100644
+--- a/include/class_acl.inc
++++ b/include/class_acl.inc
+@@ -673,7 +673,8 @@ class acl extends plugin
+                 // Create a map of all used sections, this allows us to simply hide the remove button
+                 //  if no acl is configured for the given section
+                 // e.g. ';all;department/country;users/user;
+-                $usedList = ";".implode(';', array_keys($this->aclContents)).";";
++                $array_keys = array_keys(is_array($this->aclContents) ? $this->aclContents : array());
++                $usedList = ";" . implode(';', $array_keys) . ";";
+ 
+                 /* Add settings for all categories to the (permanent) list */
+                 $data = $lData = array();
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1061_include-class_acl.inc-Fix-convertForListing-by-fixin.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1061_include-class_acl.inc-Fix-convertForListing-by-fixin.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1061_include-class_acl.inc-Fix-convertForListing-by-fixin.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1061_include-class_acl.inc-Fix-convertForListing-by-fixin.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,36 @@
+From de4832cb374698968a1e326cb04ddaaf7414545b Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Thu, 17 Aug 2023 15:48:41 +0200
+Subject: [PATCH 01/13] include/class_acl.inc: Fix convertForListing() by
+ fixing a clerical logic mistake & initialize roleArray as array not as
+ string.
+
+---
+ include/class_acl.inc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/class_acl.inc b/include/class_acl.inc
+index b5fa5ed..cd77c17 100644
+--- a/include/class_acl.inc
++++ b/include/class_acl.inc
+@@ -319,14 +319,14 @@ class acl extends plugin
+     {
+         $member = implode(", ", $entry['members']);
+         if(isset($entry['acl']) && is_array($entry['acl'])){
+-            $acl = implode(array_keys(", ", $entry['acl']));
++            $acl = implode(", ", array_keys($entry['acl']));
+         }else{
+             if($entry['type'] == 'role') {
+-                $roleArray = '';
++                $roleArray = array();
+                 foreach($this->roles[$entry['acl']]['acls'][0]['acl'] as $roleAcl => $key) {
+                      $roleArray[] = $roleAcl;
+                 }
+-                $acl = implode(', ', $roleArray);
++                $acl = implode(", ", $roleArray);
+             } else {
+                 $acl="";
+             }
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1062_include-class_acl.inc-Fixing-typos-invalid-misused-P.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1062_include-class_acl.inc-Fixing-typos-invalid-misused-P.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1062_include-class_acl.inc-Fixing-typos-invalid-misused-P.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1062_include-class_acl.inc-Fixing-typos-invalid-misused-P.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,45 @@
+From 0cafec3b2275371598348ea308587ef863a4167c Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Wed, 23 Aug 2023 16:45:39 +0200
+Subject: [PATCH 12/13] include/class_acl.inc: Fixing typos + invalid/misused
+ PHP syntax.
+
+$this->arr isn't referenced anywhere, guessing they mean $attrs?
+---
+ include/class_acl.inc | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/include/class_acl.inc b/include/class_acl.inc
+index 68b0410..fc06ea4 100644
+--- a/include/class_acl.inc
++++ b/include/class_acl.inc
+@@ -494,7 +494,7 @@ class acl extends plugin
+         if($this->acl_is_writeable("")){
+             foreach (array("aclType","aclFilter", "aclObject", "target") as $key){
+                 if (isset($_POST[$key])){
+-                    $this->$key= get_post($key);
++                    $this->key= get_post($key);
+                 }
+             }
+         }
+@@ -757,7 +757,7 @@ class acl extends plugin
+             /* Assign possible target types */
+             $smarty->assign("targets", $this->targets);
+             foreach ($this->attributes as $attr){
+-                $smarty->assign($attr, set_post($this->$attr));
++                $smarty->assign($attr, set_post($this->attrs));
+             }
+ 
+ 
+@@ -768,7 +768,7 @@ class acl extends plugin
+             }
+             foreach (array("user" => "users", "group" => "groups") as $field => $arr){
+                 if ($this->target == $field){
+-                    foreach ($this->$arr as $key => $value){
++                    foreach ($this->attrs as $key => $value){
+                         if (!isset($this->recipients[$key])){
+                             $tmp[$key]= $value;
+                         }
+-- 
+2.39.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1063_include-class_-listing-acl-.inc-plugins-admin-acl-cl.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1063_include-class_-listing-acl-.inc-plugins-admin-acl-cl.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1063_include-class_-listing-acl-.inc-plugins-admin-acl-cl.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1063_include-class_-listing-acl-.inc-plugins-admin-acl-cl.patch	2023-08-29 21:08:47.000000000 +0200
@@ -0,0 +1,73 @@
+From 2dc13c299515e55d395ba0a47c667533b31c6450 Mon Sep 17 00:00:00 2001
+From: root <root at postoffice.intern>
+Date: Fri, 25 Aug 2023 14:32:39 +0200
+Subject: [PATCH 2/3] include/class_{listing, acl}.inc,
+ plugins/admin/acl/class_aclRole.inc: Fix accessing variables if they are NULL
+ or keys of arrays which arent even set.
+
+---
+ include/class_acl.inc               |  4 ++--
+ include/class_listing.inc           | 12 ++++++++----
+ plugins/admin/acl/class_aclRole.inc |  2 +-
+ 3 files changed, 11 insertions(+), 7 deletions(-)
+
+--- a/include/class_acl.inc
++++ b/include/class_acl.inc
+@@ -364,7 +364,7 @@
+ 
+         /* Act on HTML post and gets here.
+          */
+-        if($lAction['action'] == "edit"){
++        if(isset($lAction) && $lAction['action'] == "edit"){
+             $this->currentIndex = $this->list->getKey($lAction['targets'][0]);
+             $this->dialogState= 'create';
+             $firstedit= TRUE;
+@@ -557,7 +557,7 @@
+ 
+         $this->aclMemberList->save_object();
+         $actionL = $this->aclMemberList->getAction();
+-        if($actionL['action'] == "delete") {
++        if(isset($actionL) && $actionL['action'] == "delete") {
+             $key = $this->aclMemberList->getData($actionL['targets'][0]);
+             unset($this->recipients[$key]);
+             $this->aclMemberList->deleteEntry($actionL['targets'][0]);
+--- a/include/class_listing.inc
++++ b/include/class_listing.inc
+@@ -1354,10 +1354,10 @@
+             // Handle special types
+             if ($action['type'] == 'copypaste' || $action['type'] == 'snapshot') {
+                 $objectType = $this->getObjectType($this->objectTypes, $this->entries[$row]['objectClass']);
+-                $category = $class = null;
++
+                 if ($objectType) {
+-                    $category = $objectType['category'];
+-                    $class = $objectType['class'];
++                    $category = array_key_exists("category", $objectType) ? $objectType['category'] : null;
++                    $class    = array_key_exists("class",    $objectType) ? $objectType['class']    : null;
+                 }
+ 
+                 if ($action['type'] == 'copypaste') {
+@@ -1878,7 +1878,11 @@
+                 // Replace %acl if available
+                 if ($classes) {
+                     $otype = $this->getObjectType($this->objectTypes, $classes);
+-                    $acl = str_replace('%acl', $otype['category'].'/'.$otype['class'], $acl);
++
++                    $_category = array_key_exists("category", $otype) ? $otype['category'] : "";
++                    $_class    = array_key_exists("class",    $otype) ? $otype['class']    : "";
++
++                    $acl = str_replace('%acl', $_category . '/' . $_class, $acl);
+                 }
+ 
+                 // Split for category and plugins if needed
+--- a/plugins/admin/acl/class_aclRole.inc
++++ b/plugins/admin/acl/class_aclRole.inc
+@@ -233,7 +233,7 @@
+     $this->list->save_object();
+     $lAction = $this->list->getAction();
+     $this->gosaAclTemplate = array_values($this->list->getMaintainedData());
+-    if($lAction['action'] == "edit"){
++    if(isset($lAction) && $lAction['action'] == "edit"){
+         $this->currentIndex = $lAction['targets'][0];
+         $this->dialogState= 'create';
+         $firstedit= TRUE;
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1099_remove-debug-code.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1099_remove-debug-code.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1099_remove-debug-code.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1099_remove-debug-code.patch	2023-12-03 08:11:48.000000000 +0100
@@ -0,0 +1,13 @@
+--- a/plugins/admin/users/class_userManagement.inc
++++ b/plugins/admin/users/class_userManagement.inc
+@@ -323,10 +323,6 @@
+             $dn  = $this->dn;
+             $acl = $this->ui->get_permissions($dn, "users/password");
+             $cacl= $this->ui->get_permissions($dn, "users/user");
+-            print($this->dn);
+-            echo '<pre>';
+-            var_dump($this->ui->get_permissions($dn, "users/password"));
+-            echo '</pre>';
+             if (preg_match('/w/', $acl) || preg_match('/c/', $cacl)){
+ 
+                 // Get posted passwords
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1102_style-robustness.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1102_style-robustness.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1102_style-robustness.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1102_style-robustness.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,17 @@
+Description: Make generated image styles more robust
+Author: UNKNOWN
+
+--- a/include/functions.inc
++++ b/include/functions.inc
+@@ -3688,6 +3688,11 @@
+       }
+       $styles= session::global_get('img-styles');
+ 
++      /* If there's nothing available, just return nothing */
++      if (!array_key_exists($path, $styles)) {
++        return "";
++      }
++
+       /* Extract labels from path */
+       preg_match("/(.*\.png)\[(.*)\]$/", $path, $matches);
+ 
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1105_no-image-warning.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1105_no-image-warning.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1105_no-image-warning.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1105_no-image-warning.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,14 @@
+Description: Don't throw warnings in update-gosa on already existing image files
+Author: UNKNOWN
+
+--- a/update-gosa
++++ b/update-gosa
+@@ -547,7 +547,7 @@
+          // Is this image already there?
+          $checksum= md5_file($path);
+          if (in_array($checksum, $checksums)) {
+-           $warnings[]= "! Warning: images $indexPath seems to be a duplicate of ".array_search($checksum, $checksums);
++           #$warnings[]= "! Warning: images $indexPath seems to be a duplicate of ".array_search($checksum, $checksums);
+            $duplicates[$indexPath]= array_search($checksum, $checksums);
+            $duplicates[$greyIndexPath]= preg_replace('/\.png$/', '-grey.png', array_search($checksum, $checksums));
+            continue;
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1137_fix_shadowexpire_checkbox_from_tmplate_setting.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1137_fix_shadowexpire_checkbox_from_tmplate_setting.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1137_fix_shadowexpire_checkbox_from_tmplate_setting.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1137_fix_shadowexpire_checkbox_from_tmplate_setting.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,15 @@
+Description: Propagate shadow expiry from user templates to created user objects.
+Author: Christian Schwamborn <cs at imap.architektur.tu-darmstadt.de>
+
+--- a/plugins/personal/posix/class_posixAccount.inc
++++ b/plugins/personal/posix/class_posixAccount.inc
+@@ -1174,7 +1174,8 @@
+     }
+ 
+     /* Adjust shadow checkboxes */
+-    foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive") as $val){
++    foreach (array("shadowMin", "shadowMax", "shadowWarning", "shadowInactive",
++          "shadowExpire") as $val){
+       if ($this->$val != 0){
+         $oval= "activate_".$val;
+         $this->$oval= "1";
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1138_shadowexpire_in_one_line.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1138_shadowexpire_in_one_line.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1138_shadowexpire_in_one_line.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1138_shadowexpire_in_one_line.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,18 @@
+Description: Show shadow expiry (esp. the calendar icon) in one line on screen (html template adjustment).
+Author: Christian Schwamborn <cs at imap.architektur.tu-darmstadt.de>
+
+--- gosa-2.7.4+reloaded2.a/plugins/personal/posix/classic/posix_shadow.tpl	2010-04-13 13:15:15.000000000 +0000
++++ gosa-2.7.4+reloaded2.b/plugins/personal/posix/classic/posix_shadow.tpl	2018-02-12 13:36:07.283901219 +0000
+@@ -58,10 +58,10 @@
+ 
+     <table summary="{t}Password expiration settings{/t}" border="0" cellpadding="0" cellspacing="0">
+      <tr>
+-      <td>
++      <td style="vertical-align:middle">
+        {t}Password expires on{/t} 
+       </td>
+-      <td style='width:125px'>
++      <td style='width:200px'>
+ 
+        {render acl=$shadowExpireACL}
+         <input type="text" id="shadowExpire" name="shadowExpire" class="date" style='width:100px' value="{$shadowExpire}">
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1143_smarty-add-on-function-param-types.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1143_smarty-add-on-function-param-types.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1143_smarty-add-on-function-param-types.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1143_smarty-add-on-function-param-types.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,91 @@
+Description: Use correct smarty3 API.
+Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Forwarded: https://github.com/gosa-project/gosa-core/pull/25
+Abstract.
+ For the {render} add-on block, drop the &$smarty reference parameter
+ entirely.
+ .
+ Drop the complete {tr} add-on block. Not registered as a plugin, not
+ used.
+ .
+ For the add-on image and add-on factory functions, switch from
+ reference &$smarty to value $smarty.
+
+--- a/include/smartyAddons/block.render.php
++++ b/include/smartyAddons/block.render.php
+@@ -1,6 +1,6 @@
+ <?php
+ 
+-function smarty_block_render($params, $text, &$smarty)
++function smarty_block_render($params, $text)
+ {
+ 	/* Skip closing tag </render> */	
+ 	if(empty($text)) {
+--- a/include/smartyAddons/block.tr.php
++++ /dev/null
+@@ -1,25 +0,0 @@
+-<?php
+-function smarty_block_tr($params, $text, &$smarty)
+-{
+-    $plugin = "";
+-    if(!isset($params['domain'])){
+-        if(strlen($text) != 0){
+-            $trace = debug_backtrace();
+-            $base = preg_replace("/\/html/","",getcwd());
+-            foreach($trace as $t_entry){
+-                if(preg_match("/^".preg_quote($base,'/')."\/plugins\//", $t_entry['file'])){
+-                    $plugin = preg_replace("/^".preg_quote($base,'/')."\/plugins\/([^\/]*).*$/", "\\1", $t_entry['file']);
+-                    break;
+-                }
+-            }
+-        }
+-    }
+-  
+- 
+-    if($plugin != ""){ 
+-        return(dgettext($plugin, $text));
+-    }
+-    return(gettext($text));
+-}
+-
+-?>
+--- a/include/smartyAddons/function.factory.php
++++ b/include/smartyAddons/function.factory.php
+@@ -1,6 +1,6 @@
+ <?php
+ 
+-function smarty_function_factory($params, &$smarty)
++function smarty_function_factory($params, $smarty)
+ {
+ 
+     // Capture params
+--- a/include/smartyAddons/function.image.php
++++ b/include/smartyAddons/function.image.php
+@@ -1,6 +1,6 @@
+ <?php
+ 
+-function smarty_function_image($params, &$smarty)
++function smarty_function_image($params, $smarty)
+ {
+   $path = (isset($params['path']))? $params['path'] :"";
+   $action = (isset($params['action']))? $params['action'] :"";
+--- a/include/smartyAddons/function.msgPool.php
++++ b/include/smartyAddons/function.msgPool.php
+@@ -1,6 +1,6 @@
+ <?php
+ 
+-function smarty_function_msgPool($params, &$smarty)
++function smarty_function_msgPool($params, $smarty)
+ {
+ 	if(class_available("msgPool") && isset($params['type'])){
+ 		$parameter = array();
+--- a/include/php_setup.inc
++++ b/include/php_setup.inc
+@@ -323,7 +323,6 @@
+     if(preg_match("/\.php$/", $file)) require_once("$BASE_DIR/include/smartyAddons/{$file}");
+ }
+ 
+-#$smarty->registerPlugin("block", "tr", "smarty_block_tr");
+ $smarty->registerPlugin("block", "t", "smarty_block_t");
+ $smarty->registerPlugin("block", "render", "smarty_block_render");
+ $smarty->registerPlugin("function", "msgPool", "smarty_function_msgPool");
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1144_crypto-transition-without-mcrypt.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1144_crypto-transition-without-mcrypt.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1144_crypto-transition-without-mcrypt.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1144_crypto-transition-without-mcrypt.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,17 @@
+Description: No need to let this script depend on php-mcrypt
+Author: Dominik George <natureshadow at debian.org>
+Forwarded: https://github.com/gosa-project/gosa-core/pull/27
+
+--- a/bin/gosa-mcrypt-to-openssl-passwords
++++ b/bin/gosa-mcrypt-to-openssl-passwords
+@@ -25,9 +25,7 @@
+ }
+ 
+ function cred_decrypt($input, $password) {
+-  $size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);
+-  $iv = mcrypt_create_iv($size, MCRYPT_DEV_RANDOM);
+-  return rtrim(@openssl_decrypt( pack("H*", $input), "aes-256-ecb" , $password, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv ), "\0\3\4\n");
++  return rtrim(@openssl_decrypt( pack("H*", $input), "aes-256-ecb" , $password, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING ), "\0\3\4\n");
+ }
+ 
+ 
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1145_dont_use_filter_caching.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1145_dont_use_filter_caching.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1145_dont_use_filter_caching.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1145_dont_use_filter_caching.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,31 @@
+Description: Disable flawed filter caching (which works via storing unserialized objects in $_SESSION)
+Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Forwarded: https://github.com/gosa-project/gosa-core/issues/28
+Abstract:
+ All required information is in the above upstream bug report.
+ .
+ This patch has work-around status. It is no proper solution.
+
+--- a/include/class_management.inc
++++ b/include/class_management.inc
+@@ -143,12 +143,16 @@
+         $this->registerAction("saveFilter", "saveFilter");
+         $this->registerAction("cancelFilter", "cancelFilter");
+ 
+-        // To temporay disable the filter caching UNcomment this line.
+-        // !!!!!!! filter settings produce unexpected query behavior !!!!!
+-        # session::global_un_set(get_class($this)."_filter");
++        /*
++         * As a work-around for flawed object storage in the PHP $_SESSION array
++         * the filter caching has been deactivated since gosa 2.7.4+reloaded3-8.
++         *
++         * See: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=907815#31 for
++         * details.
++         */
++         session::global_un_set(get_class($this)."_filter");
+     }
+ 
+-
+     /*! \brief  Returns an array with all ACL-Categories we are responsible for.
+      */
+     public function getAclCategories()
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1149_gosa-fix-filterlocklabelimage.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1149_gosa-fix-filterlocklabelimage.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1149_gosa-fix-filterlocklabelimage.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1149_gosa-fix-filterlocklabelimage.patch	2023-12-03 08:11:48.000000000 +0100
@@ -0,0 +1,23 @@
+Description: Use NULL as default for $userPassword in filterLockImage() and filterLockLabel().
+Author: Frederik Himpe <fhimpe at ai.vub.ac.be>
+
+--- a/plugins/admin/users/class_userManagement.inc
++++ b/plugins/admin/users/class_userManagement.inc
+@@ -907,7 +907,7 @@
+     }
+ 
+ 
+-    static function filterLockImage($userPassword)
++    static function filterLockImage($userPassword=NULL)
+     {
+         $theme = getThemeName();
+ 
+@@ -947,7 +947,7 @@
+     }
+ 
+ 
+-    static function filterLockLabel($userPassword)
++    static function filterLockLabel($userPassword=NULL)
+     {
+         $label= "";
+         if(isset($userPassword[0]) && preg_match("/^\{[^\}]/",$userPassword[0])){
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1151_openldap-gosa-samba3.-Provide-alias-attribute-descri.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1151_openldap-gosa-samba3.-Provide-alias-attribute-descri.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1151_openldap-gosa-samba3.-Provide-alias-attribute-descri.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1151_openldap-gosa-samba3.-Provide-alias-attribute-descri.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,90 @@
+From 1556976d87547a81642593dd74e14287db638aea Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Tue, 25 May 2021 16:55:34 +0200
+Subject: [PATCH] openldap/gosa-samba3.*: Provide 'alias' attribute description
+ by objectClass 'gosaMailAccount'.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+ A very common use case in LDAP stored mail accounts is the definition
+ of a primary mail address and mail address aliases. The add-on module
+ gosa-plugin-mailaddress provides a field for adding e-mail aliases to
+ user mail accounts.
+
+ Up to now, the 'alias' attribute has only been provided to user accounts
+ that were set up as kolabInetOrgPerson based accounts.
+
+ With this change, the 'alias' attribute description gets provided
+ for usual gosaMailAccount based accounts.
+
+ This change comes together with a schema change in GOsa²'s kolab2.schema
+ (where we comment out the 'alias' attribute description). Normally,
+ Kolab Users maintained via GOsa² have the 'gosaMailAccount' objectClass
+ already set, so 'alias' gets provided via gosa-samba3.schema all fine.
+---
+ contrib/openldap/gosa-samba3.ldif   | 12 +++++++++++-
+ contrib/openldap/gosa-samba3.schema | 10 +++++++++-
+ 2 files changed, 20 insertions(+), 2 deletions(-)
+
+diff --git a/contrib/openldap/gosa-samba3.ldif b/contrib/openldap/gosa-samba3.ldif
+index 96ba1b721..95c052321 100644
+--- a/contrib/openldap/gosa-samba3.ldif
++++ b/contrib/openldap/gosa-samba3.ldif
+@@ -571,6 +571,16 @@ olcAttributeTypes: (
+   )
+ #
+ ################################################################################
++olcAttributeTypes: (
++  1.3.6.1.4.1.19414.2.1.3
++  NAME 'alias'
++  DESC 'RFC1274: RFC822 Mailbox'
++  EQUALITY caseIgnoreIA5Match
++  SUBSTR caseIgnoreIA5SubstringsMatch
++  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256}
++)
++#
++################################################################################
+ #
+ olcObjectClasses: (
+   1.3.6.1.4.1.10098.1.2.1.19.1
+@@ -625,7 +635,7 @@ olcObjectClasses: (
+   SUP top
+   AUXILIARY
+   MUST ( mail $ gosaMailServer $ gosaMailDeliveryMode )
+-  MAY ( gosaMailQuota $ gosaMailAlternateAddress $ gosaMailForwardingAddress $ gosaMailMaxSize $ gosaSpamSortLevel $ gosaSpamMailbox $ gosaVacationMessage $ gosaVacationStart $ gosaVacationStop $ gosaSharedFolderTarget $ acl )
++  MAY ( alias $ gosaMailQuota $ gosaMailAlternateAddress $ gosaMailForwardingAddress $ gosaMailMaxSize $ gosaSpamSortLevel $ gosaSpamMailbox $ gosaVacationMessage $ gosaVacationStart $ gosaVacationStop $ gosaSharedFolderTarget $ acl )
+   )
+ #
+ ################################################################################
+diff --git a/contrib/openldap/gosa-samba3.schema b/contrib/openldap/gosa-samba3.schema
+index a36060354..dbdf6aeda 100644
+--- a/contrib/openldap/gosa-samba3.schema
++++ b/contrib/openldap/gosa-samba3.schema
+@@ -302,6 +302,14 @@ attributetype ( 1.3.6.1.4.1.19414.2.1.651
+ 		SUBSTR caseIgnoreIA5SubstringsMatch
+ 	    SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
+ 
++# alias used to provide alternative rfc822 email addresses for kolab users
++attributetype ( 1.3.6.1.4.1.19414.2.1.3
++        NAME 'alias'
++        DESC 'RFC1274: RFC822 Mailbox'
++        EQUALITY caseIgnoreIA5Match
++        SUBSTR caseIgnoreIA5SubstringsMatch
++        SYNTAX 1.3.6.1.4.1.1466.115.121.1.26{256} )
++
+ # Classes
+ objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.1 NAME 'gosaObject' SUP top AUXILIARY
+         DESC 'Class for GOsa settings (v2.7)'
+@@ -324,7 +332,7 @@ objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.4 NAME 'gosaDepartment' SUP top AUXILIA
+ objectclass ( 1.3.6.1.4.1.10098.1.2.1.19.5 NAME 'gosaMailAccount' SUP top AUXILIARY
+         DESC 'Class to mark MailAccounts for GOsa (v2.7)'
+ 	MUST ( mail $ gosaMailServer $ gosaMailDeliveryMode)
+-	MAY  ( gosaMailQuota $ gosaMailAlternateAddress $ gosaMailForwardingAddress $
++	MAY  ( alias $ gosaMailQuota $ gosaMailAlternateAddress $ gosaMailForwardingAddress $
+ 	       gosaMailMaxSize $ gosaSpamSortLevel $ gosaSpamMailbox $
+ 	       gosaVacationMessage $ gosaVacationStart $ gosaVacationStop $ gosaSharedFolderTarget $ acl))
+ 
+-- 
+2.30.2
+
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1154_skip-DN-when-processing-existing-account-settings.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1154_skip-DN-when-processing-existing-account-settings.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1154_skip-DN-when-processing-existing-account-settings.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1154_skip-DN-when-processing-existing-account-settings.patch	2023-08-17 06:24:19.000000000 +0200
@@ -0,0 +1,15 @@
+Description: gosa-core/include/functions.inc: The $initialAttrs array in change_password() contains the result of an LDAP fetch which contains the DN (and this is not an array), so skip that.
+Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+
+--- a/include/functions.inc
++++ b/include/functions.inc
+@@ -2972,7 +2972,8 @@
+         // Prepare a special attribute list, which will be used for event hook calls
+         $attrsEvent = array();
+         foreach($initialAttrs as $name => $value){
+-            if(!is_numeric($name))
++            // $value can contain dn => <dn-string>, so skip that
++            if(!is_numeric($name) && is_array($value))
+                 $attrsEvent[$name] = $value[0];
+         }
+         $attrsEvent['dn'] = $initialAttrs['dn'];
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1155_fix-uid-generation-when-many-uids-have-been-already-taken.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1155_fix-uid-generation-when-many-uids-have-been-already-taken.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1155_fix-uid-generation-when-many-uids-have-been-already-taken.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/1155_fix-uid-generation-when-many-uids-have-been-already-taken.patch	2023-08-17 06:33:48.000000000 +0200
@@ -0,0 +1,92 @@
+From b09b39736366706ac957511bbfc6fd0eccbbddac Mon Sep 17 00:00:00 2001
+From: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+Date: Tue, 27 Jul 2021 08:50:41 +0200
+Subject: [PATCH] include/functions.inc: Resolve UID generation for cases where
+ many UIDs have already been taken.
+
+ While mass creating users these days for a school, I noticed that an
+ idGenerator expression such as "{%sn[6-8]}{%givenName[2-4]}" did not
+ produce expected results if many UIDs have already been taken.
+
+ In my case (making up names here), I had
+
+   sn: Fresher
+   givenName: Jim
+
+ Note that both name parts, sn and givenName, have less then the
+ max number of characters as specified in the idGenerator expression.
+ (i.e. Fresher -> 7 chars, Jim -> 3 chars).
+
+ In my use case excample, the following login name was already in use,
+ so it got excluded by gen_uids() from the list of possible login names::
+
+   fresheji
+
+ So, the expected results for gen_uids() should have been:
+
+  fresherji
+  freshejim
+  fresherjim
+
+ But gen_uids() returned an empty result array().
+
+ This change fixes UID generation and also includes UIDs that have max
+ number of allowed / possible characters as specified by the idGenerator
+ expression.
+
+ Without this change, only UIDs up to max-1 characters (or strlen-1
+ characters) are offered.
+
+Signed-off-by: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+---
+ gosa-core/include/functions.inc | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+--- a/include/functions.inc
++++ b/include/functions.inc
+@@ -3937,10 +3937,10 @@
+ 
+     @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $attributes, "Prepare");
+ 
+-    // Search for '{%...[n-m]}
++    // Search for '{%...[min-max]}'
+     // Get all matching parts of the given string and sort them by
+     //  length, to avoid replacing strings like '%uidNumber' with 'uid'
+-    //  instead of 'uidNumber'; The longest tring at first.
++    //  instead of 'uidNumber'; The longest string at first.
+     preg_match_all('/(\{?%([a-z0-9]+)(\[(([0-9]+)(\-([0-9]+))?)\])?\}?)/i', $rule ,$matches, PREG_SET_ORDER);
+     $replacements = array();
+     foreach($matches as $match){
+@@ -3948,13 +3948,22 @@
+       # initialize the match's replacement array...
+       $replacements[$match[0]] = array();
+ 
++      # parameter 'min': don't allow '0' as start position (if set), rewrite to '1'
++      if (isset ($match[5]) && ($match[5] == 0)) {
++          $match[5] = 1;
++      }
++      # parameter 'max':  don't allow '0' as end position (if set), rewrite to '1'
++      if (isset ($match[7]) && ($match[7] == 0)) {
++          $match[7] = 1;
++      }
++
+       // No start position given, then add the complete value
+       if(!isset($match[7])){
+         $replacements[$match[0]][] = $attributes[$match[2]];
+ 
+         // Start given but no end, so just add a single character
+       }elseif(!isset($match[7])){
+-        if(isset($attributes[$match[2]][$match[5]])){
++        if(isset($attributes[$match[2]][$match[5]-1])){
+           $tmp = " ".$attributes[$match[2]];
+           $replacements[$match[0]][] = trim($tmp[$match[5]]);
+         }
+@@ -3963,7 +3972,7 @@
+       }else{
+         $str = "";
+         for($i=$match[5]; $i<= $match[7]; $i++){
+-          if(isset($attributes[$match[2]][$i])){
++          if(isset($attributes[$match[2]][$i-1])){
+             $tmp = " ".$attributes[$match[2]];
+             $str = substr ($tmp, 1, $i);
+             $replacements[$match[0]][] = trim($str);
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/2009-Revert-Enable-env-to-work.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/2009-Revert-Enable-env-to-work.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/2009-Revert-Enable-env-to-work.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/2009-Revert-Enable-env-to-work.patch	2023-08-17 06:18:08.000000000 +0200
@@ -0,0 +1,34 @@
+From b07a9b01cc31143436b7e4ee82cb1dd0ceacffb5 Mon Sep 17 00:00:00 2001
+From: Guido Berhoerster <guido at berhoerster.name>
+Date: Tue, 8 Aug 2023 14:26:56 +0200
+Subject: [PATCH] Revert "Enable env to work"
+
+This reverts commit 87e54bc6e8e628dd60793e955c4eed9dfa78cbd4.
+Trying to parse a shell command via regex is impossible to get right, the
+current approach fails on trivial things like wrapping a command with sudo.
+This may expose possibly sensitive information to other users via /proc, ps and
+the like.
+---
+ include/class_plugin.inc | 11 +----------
+ 1 file changed, 1 insertion(+), 10 deletions(-)
+
+--- a/include/class_plugin.inc
++++ b/include/class_plugin.inc
+@@ -1701,16 +1701,7 @@
+ 
+               // Try to open the process
+               @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__,$command,"Execute");
+-              preg_match("/^(.* )?(\/.*)$/", $command, $matches);
+-              $command = $matches[2];
+-              $env = Array();
+-              preg_match_all("/ ?([^=]+)=('[^']*')/", $matches[1], $tmp, PREG_SET_ORDER);
+-              foreach($tmp as $e) {
+-                  $env[$e[1]] = trim($e[2], "'");
+-              }
+-
+-              $process = proc_open($command, $descriptorspec, $pipes, NULL, $env);
+-
++              $process = proc_open($command, $descriptorspec, $pipes);
+               if (is_resource($process)) {
+ 
+                   // Write the password to stdin
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/2010_vacation-templates-writeable-path.patch gosa-2.8~git20230203.10abe45+dfsg/debian/patches/2010_vacation-templates-writeable-path.patch
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/2010_vacation-templates-writeable-path.patch	1970-01-01 01:00:00.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/2010_vacation-templates-writeable-path.patch	2023-08-17 07:32:24.000000000 +0200
@@ -0,0 +1,14 @@
+Description: Use a www-data-user-writeable path for vacation templates.
+Author: Mike Gabriel <mike.gabriel at das-netzwerkteam.de>
+
+--- a/include/class_core.inc
++++ b/include/class_core.inc
+@@ -958,7 +958,7 @@
+                         array(
+                                 "name"          => "vacationTemplateDirectory",
+                                 "type"          => "path",
+-                                "default"       => "/etc/gosa/vacation",
++                                "default"       => "/var/lib/gosa/vacation",
+                                 "description"   => _("Directory to store vacation templates. Please read the FAQ file for more information."),
+                                 "check"         => "gosaProperty::isWriteablePath",
+                                 "migrate"       => "",
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/patches/series gosa-2.8~git20230203.10abe45+dfsg/debian/patches/series
--- gosa-2.8~git20230203.10abe45+dfsg/debian/patches/series	2023-07-12 23:11:29.000000000 +0200
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/patches/series	2023-12-03 08:11:48.000000000 +0100
@@ -11,3 +11,60 @@
 1003_php-deprecations.patch
 1005_preg_replace_deprecation.patch
 1006_fix-overflow-debug-print_a-func.patch
+1007_fix_debugLevel_bitwise_and.patch
+1008_main-dont-die-on-empty-config-object.patch
+1009_plugin-callHook-always_output_shell_debugging_msgs.patch
+1010_fix-fix-accept-to-gettext.patch
+2009-Revert-Enable-env-to-work.patch
+1011_Revert-bugfix-for-users-group-membership-after-group.patch
+1012_Revert-fix-member-array-if-no-member-is-present.patch
+1013_Revert-update-for-generic.tpl-to-use-memberACL-inste.patch
+1014_Revert-source-code-and-definition-adjustments-for-th.patch
+1015_Revert-source-code-and-definition-adjustments-for-th.patch
+1016_Revert-source-code-and-definition-adjustments-for-th.patch
+1017_Revert-source-code-and-definition-adjustments-for-th.patch
+1018_Revert-fix-multiple_edit-and-add-custom-Constraint-t.patch
+1019_Revert-Extends-Functionality-to-add-groups-in-groups.patch
+1020_plugins-admin-groups-class_group.inc-Re-add-structur.patch
+1021_fix-config-parser-being-null.patch
+1022_fix-implicit-conversions-of-float-to-int.patch
+1035_acl_override_to_allow_delete_of_group_members.patch
+1099_remove-debug-code.patch
+1102_style-robustness.patch
+1105_no-image-warning.patch
+1137_fix_shadowexpire_checkbox_from_tmplate_setting.patch
+1138_shadowexpire_in_one_line.patch
+1143_smarty-add-on-function-param-types.patch
+1144_crypto-transition-without-mcrypt.patch
+1145_dont_use_filter_caching.patch
+1149_gosa-fix-filterlocklabelimage.patch
+1151_openldap-gosa-samba3.-Provide-alias-attribute-descri.patch
+1154_skip-DN-when-processing-existing-account-settings.patch
+1023_fix-icon-labelling-with-default-theme.patch
+1024_fix-mess-of-using-and-comparing-int-and-string-values.patch
+1155_fix-uid-generation-when-many-uids-have-been-already-taken.patch
+2010_vacation-templates-writeable-path.patch
+1025_fix-icons-in-debugBar.patch
+1026_dont-access-static-property-non-static.patch
+1027_include-functions-class_userinfo-.inc-Don-t-referenc.patch
+1028_include-class_listing.inc-Avoid-implicit-array-to-st.patch
+1029_include-class_session.inc-Only-operate-on-an-element.patch
+1030_class_group.inc-class_trustedModeDialog.inc-class_po.patch
+1031_html-main.php-Fix-bug-where-config-is-a-string-after.patch
+1032_include-class_sortableListing.inc-Fix-copy-paste-mis.patch
+1033_include-class_acl.inc-Fix-indentation-whitespace-of-.patch
+1060_include-class_acl.inc-Fix-array_keys-being-called-wi.patch
+1061_include-class_acl.inc-Fix-convertForListing-by-fixin.patch
+1062_include-class_acl.inc-Fixing-typos-invalid-misused-P.patch
+1063_include-class_-listing-acl-.inc-plugins-admin-acl-cl.patch
+1034_include-class_listing.inc-Fix-processElementFilter-n.patch
+1036_include-class_filter.inc-Define-gridClass-for-defaul.patch
+1037_include-php_setup.inc-Hide-ldap_-search-read-Search-.patch
+1038_include-class_pathNavigator.inc-Don-t-send-object-DN.patch
+1040_fix-instance-property-typo-in-class_acl-inc.patch
+1041_fix-role-selector.patch
+1042_fix-user-info-default-theme.patch
+1043a_Add-setter-for-skipFooter-property-needed-for-mfa-ex.patch
+1043b_honour-plugin-property-skipFooter-used-by-mfa-account.patch
+1044_fix-class-ldap-serialization.patch
+1045_fix-posixaccount-shadowExpire.patch
diff -Nru gosa-2.8~git20230203.10abe45+dfsg/debian/rules gosa-2.8~git20230203.10abe45+dfsg/debian/rules
--- gosa-2.8~git20230203.10abe45+dfsg/debian/rules	2023-01-21 20:52:25.000000000 +0100
+++ gosa-2.8~git20230203.10abe45+dfsg/debian/rules	2023-08-17 06:33:48.000000000 +0200
@@ -46,7 +46,7 @@
 	ln -sf /usr/share/javascript/scriptaculous/prototype.js debian/gosa/usr/share/gosa/html/include/
 
 	# symlink the smarty-gettext plugin
-	ln -sf /usr/share/php/smarty3/plugins/block.t.php debian/gosa/usr/share/gosa/include/smartyAddons/
+	ln -sf /usr/share/php/smarty4/plugins/block.t.php debian/gosa/usr/share/gosa/include/smartyAddons/
 
 	# remove unneeded files
 	rm debian/gosa/usr/share/gosa/html/themes/default/LICENSE


More information about the Debian-edu-pkg-team mailing list