Package: src:gosa
Severity: important
Version: 2.7.4+reloaded3-8+deb10u2
Tags: patch

While mass creating users these days for a school customer, I noticed that an idGenerator expression such as "{%sn[6-8]}{%givenName[2-4]}" does not produce expected results if many UIDs have already been taken.

In my case (making up names here), I had

  sn: Fresher
  givenName: Jim

The following login name was already in use:

  fresheji

So, the expected results for gen_uids() would have been:

  fresherji
  freshejim
  fresherjim

But gen_uids() returned an empty result array().

This is caused by an off-by-one string element check in gen_uids().

Patch attached.

Mike
--

DAS-NETZWERKTEAM
c\o Technik- und Ökologiezentrum Eckernförde
Mike Gabriel, Marienthaler Str. 17, 24340 Eckernförde
mobile: +49 (1520) 1976 148
landline: +49 (4351) 850 8940

GnuPG Fingerprint: 9BFB AEE8 6C0A A5FF BF22  0782 9AF4 6B30 2577 1B31
mail: mike.gabr...@das-netzwerkteam.de, http://das-netzwerkteam.de

>From b09b39736366706ac957511bbfc6fd0eccbbddac Mon Sep 17 00:00:00 2001
From: Mike Gabriel <mike.gabr...@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.gabr...@das-netzwerkteam.de>
---
 include/functions.inc | 18 ++++++++++++++----
 1 file changed, 14 insertions(+), 4 deletions(-)

diff --git a/include/functions.inc b/include/functions.inc
index 046bbed75..2e686c243 100644
--- a/include/functions.inc
+++ b/include/functions.inc
@@ -3866,10 +3866,10 @@ function gen_uids($rule, $attributes)
     
     @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){
@@ -3877,13 +3877,23 @@ function gen_uids($rule, $attributes)
       # 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]]);
         }
@@ -3892,7 +3902,7 @@ function gen_uids($rule, $attributes)
       }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);
-- 
2.30.2

Attachment: pgpPvx7F48kxm.pgp
Description: Digitale PGP-Signatur

Reply via email to