get_ldap_link();
$ldap->cd($config->current['BASE']);
/* Collect some basic informations and initialize some variables */
$base_release = get_release_dn($Current_DN);
$previous_releases = array_reverse(get_previous_releases_of_this_release($base_release,true));
$res = array();
$tmp = array();
/* We must also include the given release dn */
$previous_releases[] = $base_release;
/* Walk through all releases */
foreach($previous_releases as $release){
/* Get fai departments */
$deps_to_search = get_FAI_departments($release);
/* For every single department (ou=hoos,ou ..) */
foreach($deps_to_search as $fai_base){
/* Ldap search for fai classes specified in this release */
$ldap->cd($fai_base);
$ldap->search($filter,array("dn","objectClass","FAIstate"));
/* check the returned objects, and add/replace them in our return vareable */
while($attr = $ldap->fetch()){
$buffer = array();
$name = str_ireplace($release,"",$attr['dn']);
if(isset($attr['FAIstate'][0])){
if(preg_match("/removed$/",$attr['FAIstate'][0])){
if(isset($res[$name])){
unset($res[$name]);
}
continue;
}
}
/* In detailed mode are some additonal informations visible */
if($detailed){
/* Create list of parents */
if(isset($res[$name])){
$buffer = $res[$name];
$buffer['parents'][] = $res[$name]['dn'];
}else{
$buffer['parents'] = array();
}
/* Append objectClass to resulsts */
$buffer['objectClass'] = $attr['objectClass'];
unset($buffer['objectClass'][0]);
}
/* Add this object to our list */
$buffer['dn'] = $attr['dn'];
$res[$name] = $buffer;
}
}
}
return($res);
}
/* Return the object defining ObjectClass e.g. FAIscriptEntry */
function get_FAI_type($attr)
{
$arr = array( "FAIprofile","FAIpartitionTable", "FAIpartitionDisk","FAIpartitionEntry","FAIhook","FAIhookEntry",
"FAIscriptEntry","FAIscript","FAIvariable","FAIvariableEntry","FAIpackageList","FAItemplate",
"FAItemplateEntry","FAIdebconfInfo","FAIrepository","FAIrepositoryServer","FAIbranch","FAIreleaseTag");
foreach($arr as $name){
if(in_array($name,$attr['objectClass'])){
preg_match("");
return($name);
}
}
echo "Not found";
return("");
}
/* Return all relevant FAI departments */
function get_FAI_departments($suffix = "")
{
$arr = array("hooks","scripts","disk","packages","profiles","templates","variables");
$tmp = array();
if(preg_match("/^,/",$suffix)){
$suffix = preg_replace("/^,/","",$suffix);
}
foreach($arr as $name){
if(empty($suffix)){
$tmp[$name] = "ou=".$name;
}else{
$tmp[$name] = "ou=".$name.",".$suffix;
}
}
return($tmp);
}
function get_all_releases_from_base($dn)
{
global $config;
$base = "ou=fai,ou=configs,ou=systems,".$dn;
$res = array();
$ldap = $config->get_ldap_link();
$ldap->cd($base);
$ldap->search("(objectClass=FAIbranch)",array("ou","dn"));
while($attrs = $ldap->fetch()){
$res[$attrs['dn']] = $attrs['ou'][0];
}
return($res);
}
/* This function does everything to be able to save the given dn.
!!!!!!! No functionality just output
*/
function prepare_to_save_FAI_object($Current_DN,$objectAttrs,$removed = false)
{
/* Get ldap object */
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
/* Get some basic informations */
$base_release = get_release_dn($Current_DN);
$sub_releases = get_sub_releases_of_this_release($base_release,true);
$parent_obj = get_parent_release_object($Current_DN);
$following_releases = get_sub_releases_of_this_release($base_release,true);
/* Check if given dn exists or if is a new entry */
$ldap->cat($Current_DN);
if(!$ldap->count()){
$is_new = true;
}else{
$is_new = false;
}
/* if parameter removed is true, we have to add FAIstate to the current attrs
FAIstate should end with ...|removed after this operation */
if($removed ){
$ldap->cat($Current_DN);
if((!$ldap->count()) && !empty($parent_obj)){
$ldap->cat($parent_obj);
}
if(!$ldap->count()){
echo "Error can't remove this object ".$Current_DN;
return;
}else{
$objectAttrs = prepare_ldap_fetch_to_be_saved($ldap->fetch());
if(isset($objectAttrs['FAIstate'][0])){
if(!preg_match("/removed$/",$objectAttrs['FAIstate'][0])){
$objectAttrs['FAIstate'][0] .= "|removed";
}
}else{
$objectAttrs['FAIstate'][0] = "|removed";
}
}
}
/* Check if this a leaf release or not */
if(count($following_releases) == 0 ){
/* This is a leaf object. It isn't unherited by any other object */
echo "Saving directly, is a leaf object
".$Current_DN;
print_a($objectAttrs);
save_FAI_object($Current_DN,$objectAttrs);
}else{
/* This object is inherited by some sub releases */
/* Get all releases, that inherit this object */
$r = get_following_releases_that_inherit_this_object($Current_DN);
/* Get parent object */
$ldap->cat($parent_obj);
$parent_attrs = prepare_ldap_fetch_to_be_saved($ldap->fetch());
/* New objects require special handling */
if($is_new){
/* check if there is already an entry named like this,
in one of our parent releases */
if(!empty($parent_obj)){
echo "There is already an entry named like this.
";
echo "Saving main object".$Current_DN;
print_a($objectAttrs);
save_FAI_object($Current_DN,$objectAttrs);
foreach($r as $key){
echo "Saving parent to following release ".$key;
print_a($parent_attrs);
save_FAI_object($key,$parent_attrs);
}
}else{
echo "Saving main object".$Current_DN;
print_a($objectAttrs);
save_FAI_object($Current_DN,$objectAttrs);
if(isset($objectAttrs['FAIstate'])){
$objectAttrs['FAIstate'] .= "|removed";
}else{
$objectAttrs['FAIstate'] = "|removed";
}
foreach($r as $key ){
echo "Create an empty placeholder in follwing release ".$key;
print_a($objectAttrs);
save_FAI_object($key,$objectAttrs);
}
}
}else{
/* check if we must patch the follwing release */
if(!empty($r)){
foreach($r as $key ){
echo "Copy current objects original attributes to next release ".$key;
print_a($parent_attrs);
save_FAI_object($key,$parent_attrs);
}
}
echo "Saving current object".$parent_obj;
print_a($objectAttrs);
save_FAI_object($parent_obj,$objectAttrs);
if($parent_obj != $Current_DN){
echo "Error they must be equal : ".$parent_obj."
and
".$Current_DN."
";
}
}
}
echo "
.--------------------------------------------------------------------.
";
}
function prepare_ldap_fetch_to_be_saved($attrs)
{
foreach($attrs as $key => $value){
if(is_numeric($key) || ($key == "count") || ($key == "dn")){
unset($attrs[$key]);
}
if(is_array($value) && isset($value['count'])){
unset($attrs[$key]['count']);
}
}
return($attrs);
}
function save_FAI_object($dn,$attrs)
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $dn));
$ldap->cd($dn);
$ldap->cat($dn,array("dn"));
if($ldap->count()){
$ldap->modify($attrs);
}else{
$ldap->add($attrs);
}
show_ldap_error($ldap->get_error(),sprintf(_("Release management failed, can't save '%s'"),$dn));
}
function get_following_releases_that_inherit_this_object($dn)
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$ret = array();
/* Get base release */
$base_release = get_release_dn($dn);
/* Get previous release dns */
$sub_releases = get_sub_releases_of_this_release($base_release);
/* Get dn suffix. Example "FAIvairableEntry=keksdose,FAIvariable=Keksregal," */
$dn_suffix = str_ireplace($base_release,"",$dn);
/* Check if given object also exists whitin one of these releases */
foreach($sub_releases as $p_release => $name){
$check_dn = $dn_suffix.$p_release;
$ldap->cat($check_dn,array("dn","objectClass"));
if($ldap->count()){
//return($ret);
}else{
$ret[$check_dn]=$check_dn;
}
}
return($ret);
}
/* Get previous version of the object dn */
function get_parent_release_object($dn)
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$previous_releases= array();
/* Get base release */
$base_release = get_release_dn($dn);
$previous_releases[] = $base_release;
/* Get previous release dns */
$tmp = get_previous_releases_of_this_release($base_release,true);
foreach($tmp as $release){
$previous_releases[] = $release;
}
/* Get dn suffix. Example "FAIvairableEntry=keksdose,FAIvariable=Keksregal," */
$dn_suffix = str_ireplace($base_release,"",$dn);
/* Check if given object also exists whitin one of these releases */
foreach($previous_releases as $p_release){
$check_dn = $dn_suffix.$p_release;
$ldap->cat($check_dn,array("dn","objectClass"));
if($ldap->count()){
return($check_dn);
}
}
return("");
}
/* return release names of all parent releases */
function get_previous_releases_of_this_release($dn,$flat)
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$ret = array();
/* Explode dns into pieces, to be able to build parent dns */
$dns_to_check = ldap_explode_dn(str_ireplace(",".$config->current['BASE'],"",$dn),0);
if(!is_array($dns_to_check)){
return;
}
/* Unset first entry which represents the given dn */
unset($dns_to_check['count']);
unset($dns_to_check[key($dns_to_check)]);
/* Create dns addresses and check if this dn is a release dn */
$id = 0;
while(count($dns_to_check)){
/* build parent dn */
$new_dn = "";
foreach($dns_to_check as $part){
$new_dn .= $part.",";
}
$new_dn .= $config->current['BASE'];
/* check if this dn is a release */
if(is_release_department($new_dn)){
if($flat){
$ret[$id] = $new_dn;
}else{
$ret = array($new_dn=>$ret);
}
$id ++;
}else{
return($ret);
}
reset($dns_to_check);
unset($dns_to_check[key($dns_to_check)]);
}
return($ret);
}
/* This function returns all sub release names, recursivly */
function get_sub_releases_of_this_release($dn,$flat = false)
{
global $config;
$res = array();
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$ldap->ls("(objectClass=FAIbranch)",$dn,array("objectClass","dn","ou"));
while($attr = $ldap->fetch()){
/* Append department name */
if($flat){
$res[$attr['dn']] = $attr['ou'][0];
}else{
$res[$attr['dn']] = array();
}
/* Get sub release departments of this department */
if(in_array("FAIbranch",$attr['objectClass'])) {
if($flat){
$tmp = get_sub_releases_of_this_release($attr['dn'],$flat);
foreach($tmp as $dn => $value){
$res[$dn]=$value;
}
}else{
$res[$attr['dn']] = get_sub_releases_of_this_release($attr['dn']);
}
}
}
return($res);
}
/* Check if the given department is a release department */
function is_release_department($dn)
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
$ldap->cat($dn,array("objectClass","ou"));
/* Check objectClasses and name to check if this is a release department */
if($ldap->count()){
$attrs = $ldap->fetch();
$ou = "";
if(isset($attrs['ou'][0])){
$ou = $attrs['ou'][0];
}
if((in_array("FAIbranch",$attrs['objectClass'])) || ($ou == "fai")){
return($attrs['dn']);
}
}
return(false);
}
/* This function returns the dn of the object release */
function get_release_dn($Current_DN)
{
global $config;
$ldap = $config->get_ldap_link();
$ldap->cd($config->current['BASE']);
/* Split dn into pices */
$dns_to_check = ldap_explode_dn(str_ireplace(",".$config->current['BASE'],"",$Current_DN),0);
if(!is_array($dns_to_check)){
return;
}
/* Use dn pieces, to create sub dns like
ou=test,ou=1,ou=0...
ou=1,ou=0...
ou=0...
To check which dn is our release container.
*/
unset($dns_to_check['count']);
while(count($dns_to_check)){
/* Create dn */
$new_dn = "";
foreach($dns_to_check as $part){
$new_dn .= $part.",";
}
$new_dn .= $config->current['BASE'];
/* Check if this dn is a release dn */
if(is_release_department($new_dn)){
return($new_dn);
}
/* Remove first element of dn pieces */
reset($dns_to_check);
unset($dns_to_check[key($dns_to_check)]);
}
return("");
}
// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
?>