X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-core%2Finclude%2Ffunctions.inc;h=893d1431d386971e9c26885bb3daf41109d5f324;hb=9773098162a69430e5c427eb458578bb39e15560;hp=338ab70da6afc6a643082332abee24394e37a9aa;hpb=58a2dec2c61ba451d9c2e41f451d99c90185b5f8;p=gosa.git diff --git a/gosa-core/include/functions.inc b/gosa-core/include/functions.inc index 338ab70da..893d1431d 100644 --- a/gosa-core/include/functions.inc +++ b/gosa-core/include/functions.inc @@ -1981,186 +1981,6 @@ function netmask_to_bits($netmask) } -/*! \brief Recursion helper for gen_id() */ -function recurse($rule, $variables) -{ - $result= array(); - - if (!count($variables)){ - return array($rule); - } - - reset($variables); - $key= key($variables); - $val= current($variables); - unset ($variables[$key]); - - foreach($val as $possibility){ - $nrule= str_replace("{$key}", $possibility, $rule); - $result= array_merge($result, recurse($nrule, $variables)); - } - - return ($result); -} - - -/*! \brief Expands user ID based on possible rules - * - * Unroll given rule string by filling in attributes. - * - * \param string 'rule' The rule string from gosa.conf. - * \param array 'attributes' A dictionary of attribute/value mappings - * \return string Expanded string, still containing the id keyword. - */ -function expand_id($rule, $attributes) -{ - /* Check for id rule */ - if(preg_match('/^id(:|#|!)\d+$/',$rule)){ - return (array("{$rule}")); - } - - /* Check for clean attribute */ - if (preg_match('/^%[a-zA-Z0-9]+$/', $rule)){ - $rule= preg_replace('/^%/', '', $rule); - $val= rewrite(str_replace(' ', '', strtolower($attributes[$rule]))); - return (array($val)); - } - - /* Check for attribute with parameters */ - if (preg_match('/^%[a-zA-Z0-9]+\[[0-9-]+\]$/', $rule)){ - $param= preg_replace('/^[^[]+\[([^]]+)]$/', '\\1', $rule); - $part= preg_replace('/^%/', '', preg_replace('/\[.*$/', '', $rule)); - $val= rewrite(str_replace(' ', '', strtolower($attributes[$part]))); - $start= preg_replace ('/-.*$/', '', $param); - $stop = preg_replace ('/^[^-]+-/', '', $param); - - /* Assemble results */ - $result= array(); - for ($i= $start; $i<= $stop; $i++){ - $result[]= substr($val, 0, $i); - } - return ($result); - } - - echo "Error in idGenerator string: don't know how to handle rule $rule.\n"; - return (array($rule)); -} - - -/*! \brief Generate a list of uid proposals based on a rule - * - * Unroll given rule string by filling in attributes and replacing - * all keywords. - * - * \param string 'rule' The rule string from gosa.conf. - * \param array 'attributes' A dictionary of attribute/value mappings - * \return array List of valid not used uids - */ -function gen_uids($rule, $attributes) -{ - global $config; - - // Strip out non ascii chars - foreach($attributes as $name => $value){ - $value = iconv('UTF-8', 'US-ASCII//TRANSLIT', $value); - $value = preg_replace('/[^(\x20-\x7F)]*/','',$value); - $attributes[$name] = $value; - } - - /* Search for keys and fill the variables array with all - possible values for that key. */ - $part= ""; - $trigger= false; - $stripped= ""; - $variables= array(); - - for ($pos= 0, $l= strlen($rule); $pos < $l; $pos++){ - - if ($rule[$pos] == "{" ){ - $trigger= true; - $part= ""; - continue; - } - - if ($rule[$pos] == "}" ){ - $variables[$pos]= expand_id($part, $attributes); - $stripped.= "{".$pos."}"; - $trigger= false; - continue; - } - - if ($trigger){ - $part.= $rule[$pos]; - } else { - $stripped.= $rule[$pos]; - } - } - - /* Recurse through all possible combinations */ - $proposed= recurse($stripped, $variables); - - /* Get list of used ID's */ - $ldap= $config->get_ldap_link(); - $ldap->cd($config->current['BASE']); - - /* Remove used uids and watch out for id tags */ - $ret= array(); - foreach($proposed as $uid){ - - /* Check for id tag and modify uid if needed */ - if(preg_match('/\{id(:|!)\d+}/',$uid, $m)){ - $size= preg_replace('/^.*{id(:|!)(\d+)}.*$/', '\\2', $uid); - - $start= $m[1]==":"?0:-1; - for ($i= $start, $p= pow(10,$size)-1; $i < $p; $i++){ - if ($i == -1) { - $number= ""; - } else { - $number= sprintf("%0".$size."d", $i+1); - } - $res= preg_replace('/{id(:|!)\d+}/', $number, $uid); - - $ldap->search("(uid=".preg_replace('/[{}]/', '', $res).")",array('dn')); - if($ldap->count() == 0){ - $uid= $res; - break; - } - } - - /* Remove link if nothing has been found */ - $uid= preg_replace('/{id(:|!)\d+}/', '', $uid); - } - - if(preg_match('/\{id#\d+}/',$uid)){ - $size= preg_replace('/^.*{id#(\d+)}.*$/', '\\1', $uid); - - while (true){ - mt_srand((double) microtime()*1000000); - $number= sprintf("%0".$size."d", mt_rand(0, pow(10, $size)-1)); - $res= preg_replace('/{id#(\d+)}/', $number, $uid); - $ldap->search("(uid=".preg_replace('/[{}]/', '', $res).")",array('dn')); - if($ldap->count() == 0){ - $uid= $res; - break; - } - } - - /* Remove link if nothing has been found */ - $uid= preg_replace('/{id#\d+}/', '', $uid); - } - - /* Don't assign used ones */ - $ldap->search("(uid=".preg_replace('/[{}]/', '', $uid).")",array('dn')); - if($ldap->count() == 0){ - /* Add uid, but remove {} first. These are invalid anyway. */ - $ret[]= preg_replace('/[{}]/', '', $uid); - } - } - - return(array_unique($ret)); -} - - /*! \brief Convert various data sizes to bytes * * Given a certain value in the format n(g|m|k), where n @@ -3863,8 +3683,10 @@ function detectLdapSpecialCharHandling() /*! \brief Replaces placeholder in a given string. * For example: * '%uid@gonicus.de' Replaces '%uid' with 'uid'. - * '%uid{0}@gonicus.de' Replaces '%uid{0}' with the first char of 'uid'. - * '%uid{2:4}@gonicus.de' Replaces '%uid{2:4}' with three chars from 'uid' starting from the second. + * '{%uid[0]@gonicus.de}' Replaces '%uid[0]' with the first char of 'uid'. + * '%uid[2-4]@gonicus.de' Replaces '%uid[2-4]' with three chars from 'uid' starting from the second. + * + * The surrounding {} in example 2 are optional. * * @param String The string to perform the action on. * @param Array An array of replacements. @@ -3872,7 +3694,7 @@ function detectLdapSpecialCharHandling() */ function fillReplacements($str, $attrs, $shellArg = FALSE, $default = "") { - // Search for '%...{...} + // Search for '{%...[n-m]} // 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. @@ -3909,5 +3731,123 @@ function fillReplacements($str, $attrs, $shellArg = FALSE, $default = "") return($str); } + +/*! \brief Generate a list of uid proposals based on a rule + * + * Unroll given rule string by filling in attributes and replacing + * all keywords. + * + * \param string 'rule' The rule string from gosa.conf. + * \param array 'attributes' A dictionary of attribute/value mappings + * \return array List of valid not used uids + */ +function gen_uids($rule, $attributes) +{ + global $config; + $ldap = $config->get_ldap_link(); + $ldap->cd($config->current['BASE']); + + + // Strip out non ascii chars + foreach($attributes as $name => $value){ + $value = iconv('UTF-8', 'US-ASCII//TRANSLIT', $value); + $value = preg_replace('/[^(\x20-\x7F)]*/','',$value); + $attributes[$name] = strtolower($value); + } + + // Search for '{%...[n-m]} + // 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. + preg_match_all('/(\{?%([a-z0-9]+)(\[(([0-9]+)(\-([0-9]+))?)\])?\}?)/i', $rule ,$matches, PREG_SET_ORDER); + $replacements = array(); + foreach($matches as $match){ + + // No start position given, then add the complete value + if(!isset($match[5])){ + $replacements[$match[0]][] = $attributes[$match[2]]; + + // Start given but no end, so just add a simple character + }elseif(!isset($match[7])){ + if(isset($attributes[$match[2]][$match[5]])){ + $replacements[$match[0]][] = $attributes[$match[2]][$match[5]]; + } + + // Add all values in range + }else{ + $str = ""; + for($i=$match[5]; $i<= $match[7]; $i++){ + if(isset($attributes[$match[2]][$i])){ + $str .= $attributes[$match[2]][$i]; + $replacements[$match[0]][] = $str; + } + } + } + } + + // Create proposal array + $rules = array($rule); + foreach($replacements as $tag => $values){ + $rules = gen_uid_proposals($rules, $tag,$values); + } + + + // Search for id tags {id:3} / {id#3} + preg_match_all('/\{id(#|:)([0-9])+\}/i', $rule ,$matches, PREG_SET_ORDER); + $idReplacements = array(); + foreach($matches as $match){ + if(count($match) != 3) continue; + + // Generate random number + if($match[1] == '#'){ + foreach($rules as $id => $ruleStr){ + $genID = rand(pow(10,$match[2] -1),pow(10, ($match[2])) - 1); + $rules[$id] = preg_replace("/".preg_quote($match[0],'/')."/", $genID,$ruleStr); + } + } + + // Search for next free id + if($match[1] == ':'){ + + // Walk through rules and replace all occurences of {id:..} + foreach($rules as $id => $ruleStr){ + $genID = 0; + $start = TRUE; + while($start || $ldap->count()){ + $start = FALSE; + $number= sprintf("%0".$match[2]."d", $genID); + $testRule = preg_replace("/".preg_quote($match[0],'/')."/",$number,$ruleStr); + $ldap->search('uid='.normalizeLdap($testRule)); + $genID ++; + } + $rules[$id] = preg_replace("/".preg_quote($match[0],'/')."/",$number,$ruleStr); + } + } + } + + // Create result set by checking which uid is already used and which is free. + $ret = array(); + foreach($rules as $rule){ + $ldap->search('uid='.normalizeLdap($rule)); + if(!$ldap->count()){ + $ret[] = $rule; + } + } + + return($ret); +} + + +function gen_uid_proposals(&$rules, $tag, $values) +{ + $newRules = array(); + foreach($rules as $rule){ + foreach($values as $value){ + $newRules[] = preg_replace("/".preg_quote($tag,'/')."/", $value, $rule); + } + } + return($newRules); +} + // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: ?>