X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=include%2Fclass_plugin.inc;h=a17378c8775ef3438a36317e288a9fc7820462f8;hb=8f3634c3e357e7a324ef9d28d181fceb275afbf5;hp=103a6c1fc6a82ebf0d800bb2a3dc0eea6c9c3ab2;hpb=03dcb2603d87fd4f997603feb116c6b84030aae0;p=gosa.git diff --git a/include/class_plugin.inc b/include/class_plugin.inc index 103a6c1fc..a17378c87 100644 --- a/include/class_plugin.inc +++ b/include/class_plugin.inc @@ -83,6 +83,12 @@ class plugin */ var $attrs= array(); + /* Keep set of conflicting plugins */ + var $conflicts= array(); + + /* Save unit tags */ + var $gosaUnitTag= ""; + var $skipTagging= FALSE; /*! \brief Used standard values @@ -102,6 +108,9 @@ class plugin var $new= TRUE; var $saved_attributes= array(); + /* This can be set to render the tabulators in another stylesheet */ + var $pl_notify= FALSE; + /*! \brief plugin constructor If 'dn' is set, the node loads the given 'dn' from LDAP @@ -109,7 +118,7 @@ class plugin \param dn Distinguished name to initialize plugin from \sa plugin() */ - function plugin ($config, $dn= NULL) + function plugin ($config, $dn= NULL, $parent= NULL) { /* Configuration is fine, allways */ $this->config= $config; @@ -125,18 +134,26 @@ class plugin if ($dn != NULL){ /* Load data to 'attrs' and save 'dn' */ - $ldap->cat ($dn); - $this->attrs= $ldap->fetch(); + if ($parent != NULL){ + $this->attrs= $parent->attrs; + } else { + $ldap->cat ($dn); + $this->attrs= $ldap->fetch(); + } /* Copy needed attributes */ foreach ($this->attributes as $val){ - #if (isset($this->attrs["$val"][0])){ $found= array_key_ics($val, $this->attrs); if ($found != ""){ $this->$val= $this->attrs["$found"][0]; } } + /* gosaUnitTag loading... */ + if (isset($this->attrs['gosaUnitTag'][0])){ + $this->gosaUnitTag= $this->attrs['gosaUnitTag'][0]; + } + /* Set the template flag according to the existence of objectClass gosaUserTemplate */ if (isset($this->attrs['objectClass'])){ @@ -200,9 +217,13 @@ class plugin { # This one is empty currently. Fabian - please fill in the docu code $_SESSION['current_class_for_help'] = get_class($this); + /* Reset Lock message POST/GET check array, to prevent perg_match errors*/ + $_SESSION['LOCK_VARS_TO_USE'] =array(); } - /* remove object from parent */ + /*! \brief execute plugin + Removes object from parent + */ function remove_from_parent() { /* include global link_info */ @@ -251,7 +272,7 @@ class plugin foreach ($this->attributes as $val){ if (chkacl ($this->acl, "$val") == "" && isset ($_POST["$val"])){ /* Check for modifications */ - if (get_magic_quotes_gpc()) { + if ((get_magic_quotes_gpc()) && !is_array($_POST["$val"])) { $data= stripcslashes($_POST["$val"]); } else { $data= $this->$val = $_POST["$val"]; @@ -315,50 +336,131 @@ class plugin } } + /* Handle tagging */ + $this->tag_attrs(&$this->attrs); } + function cleanup() { foreach ($this->attrs as $index => $value){ + /* Convert arrays with one element to non arrays, if the saved + attributes are no array, too */ + if (is_array($this->attrs[$index]) && + count ($this->attrs[$index]) == 1 && + isset($this->saved_attributes[$index]) && + !is_array($this->saved_attributes[$index])){ + + $tmp= $this->attrs[$index][0]; + $this->attrs[$index]= $tmp; + } + /* Remove emtpy arrays if they do not differ */ - if (is_array($this->attrs[$index]) && count($this->attrs[$index]) == 0 && !isset($this->saved_attributes[$index])){ + if (is_array($this->attrs[$index]) && + count($this->attrs[$index]) == 0 && + !isset($this->saved_attributes[$index])){ + unset ($this->attrs[$index]); continue; } /* Remove single attributes that do not differ */ - if (!is_array($this->attrs[$index]) && isset($this->saved_attributes[$index]) - && !is_array($this->saved_attributes[$index]) && $value == $this->saved_attributes[$index]){ + if (!is_array($this->attrs[$index]) && + isset($this->saved_attributes[$index]) && + !is_array($this->saved_attributes[$index]) && + $this->attrs[$index] == $this->saved_attributes[$index]){ + unset ($this->attrs[$index]); continue; } /* Remove arrays that do not differ */ - if (is_array($this->attrs[$index]) && isset($this->saved_attributes[$index]) && is_array($this->saved_attributes[$index])){ - $dst= $this->attrs[$index]; - $src= $this->saved_attributes[$index]; - sort($dst); - sort($src); - if (count(array_diff($src, $dst))==0 ){ + if (is_array($this->attrs[$index]) && + isset($this->saved_attributes[$index]) && + is_array($this->saved_attributes[$index])){ + + if (!array_differs($this->attrs[$index],$this->saved_attributes[$index])){ unset ($this->attrs[$index]); continue; } } } - ####################################################### - ; if (count($this->attrs)!=0){ ; - ; echo "--- DEBUG: changes ---
" ; - ; print_a ($this->attrs) ; - ; } ; - ####################################################### + /* Update saved attributes and ensure that next cleanups will be successful too */ + foreach($this->attrs as $name => $value){ + $this->saved_attributes[$name] = $value; + } } /* Check formular input */ function check() { $message= array(); + + /* Skip if we've no config object */ + if (!isset($this->config)){ + return $message; + } + + /* Find hooks entries for this class */ + $command= search_config($this->config->data['MENU'], get_class($this), "CHECK"); + if ($command == "" && isset($this->config->data['TABS'])){ + $command= search_config($this->config->data['TABS'], get_class($this), "CHECK"); + } + + if ($command != ""){ + + if (!check_command($command)){ + $message[]= sprintf(_("Command '%s', specified as CHECK hook for plugin '%s' doesn't seem to exist."), $command, + get_class($this)); + } else { + + /* Generate "ldif" for check hook */ + $ldif= "dn: $this->dn\n"; + + /* ... objectClasses */ + foreach ($this->objectclasses as $oc){ + $ldif.= "objectClass: $oc\n"; + } + + /* ... attributes */ + foreach ($this->attributes as $attr){ + if ($this->$attr == ""){ + continue; + } + if (is_array($this->$attr)){ + foreach ($this->$attr as $val){ + $ldif.= "$attr: $val\n"; + } + } else { + $ldif.= "$attr: ".$this->$attr."\n"; + } + } + + /* Append empty line */ + $ldif.= "\n"; + + /* Feed "ldif" into hook and retrieve result*/ + $descriptorspec = array( 0 => array("pipe", "r"), 1 => array("pipe", "w"), 2 => array("pipe", "w")); + $fh= proc_open($command, $descriptorspec, $pipes); + if (is_resource($fh)) { + fwrite ($pipes[0], $ldif); + fclose($pipes[0]); + + $result= stream_get_contents($pipes[1]); + if ($result != ""){ + $message[]= $result; + } + + fclose($pipes[1]); + fclose($pipes[2]); + proc_close($fh); + } + } + + } + return ($message); } @@ -415,20 +517,25 @@ class plugin /* Show header message for tab dialogs */ function show_header($button_text, $text, $disabled= FALSE) { + $state = "disabled"; + if($this->is_account && $this->acl == "#all#"){ + $state= ""; + }elseif(!$this->is_account && chkacl($this->acl,"create") == ""){ + $state= ""; + } + if ($disabled == TRUE){ $state= "disabled"; - } else { - $state= ""; } + $display= "\n

$text

\n"; - $display.= "acl, "all")." ".$state. - ">

 

"; + $display.= "". + "

 

"; return($display); } - function postcreate() + function postcreate($add_attrs= array()) { /* Find postcreate entries for this class */ $command= search_config($this->config->data['MENU'], get_class($this), "POSTCREATE"); @@ -437,18 +544,28 @@ class plugin } if ($command != ""){ + + /* Additional attributes */ + foreach ($add_attrs as $name => $value){ + $command= preg_replace("/%$name( |$)/", "$value ", $command); + } + /* Walk through attribute list */ foreach ($this->attributes as $attr){ if (!is_array($this->$attr)){ - $command= preg_replace("/%$attr/", $this->$attr, $command); + $command= preg_replace("/%$attr( |$)/", $this->$attr." ", $command); } } - $command= preg_replace("/%dn/", $this->dn, $command); + $command= preg_replace("/%dn( |$)/", $this->dn." ", $command); + if (check_command($command)){ @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execute"); - - exec($command); + exec($command,&$arr); + foreach($arr as $str){ + @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, + $command, "Result: ".$str); + } } else { $message= sprintf(_("Command '%s', specified as POSTCREATE for plugin '%s' doesn't seem to exist."), $command, get_class($this)); print_red ($message); @@ -456,7 +573,7 @@ class plugin } } - function postmodify() + function postmodify($add_attrs= array()) { /* Find postcreate entries for this class */ $command= search_config($this->config->data['MENU'], get_class($this), "POSTMODIFY"); @@ -465,18 +582,29 @@ class plugin } if ($command != ""){ + + /* Additional attributes */ + foreach ($add_attrs as $name => $value){ + $command= preg_replace("/%$name( |$)/", "$value ", $command); + } + /* Walk through attribute list */ foreach ($this->attributes as $attr){ if (!is_array($this->$attr)){ - $command= preg_replace("/%$attr/", $this->$attr, $command); + $command= preg_replace("/%$attr( |$)/", $this->$attr." ", $command); } } - $command= preg_replace("/%dn/", $this->dn, $command); + $command= preg_replace("/%dn( |$)/", $this->dn." ", $command); + if (check_command($command)){ @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execute"); - exec($command); + exec($command,&$arr); + foreach($arr as $str){ + @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, + $command, "Result: ".$str); + } } else { $message= sprintf(_("Command '%s', specified as POSTMODIFY for plugin '%s' doesn't seem to exist."), $command, get_class($this)); print_red ($message); @@ -484,7 +612,7 @@ class plugin } } - function postremove() + function postremove($add_attrs= array()) { /* Find postremove entries for this class */ $command= search_config($this->config->data['MENU'], get_class($this), "POSTREMOVE"); @@ -493,18 +621,29 @@ class plugin } if ($command != ""){ + + /* Additional attributes */ + foreach ($add_attrs as $name => $value){ + $command= preg_replace("/%$name( |$)/", "$value ", $command); + } + /* Walk through attribute list */ foreach ($this->attributes as $attr){ if (!is_array($this->$attr)){ - $command= preg_replace("/%$attr/", $this->$attr, $command); + $command= preg_replace("/%$attr( |$)/", $this->$attr." ", $command); } } - $command= preg_replace("/%dn/", $this->dn, $command); + $command= preg_replace("/%dn( |$)/", $this->dn." ", $command); + if (check_command($command)){ @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, $command, "Execute"); - exec($command); + exec($command,&$arr); + foreach($arr as $str){ + @DEBUG (DEBUG_SHELL, __LINE__, __FUNCTION__, __FILE__, + $command, "Result: ".$str); + } } else { $message= sprintf(_("Command '%s', specified as POSTREMOVE for plugin '%s' doesn't seem to exist."), $command, get_class($this)); print_red ($message); @@ -520,7 +659,7 @@ class plugin /* Try to use plain entry first */ $dn= "$attribute=".$this->$attribute.",$base"; - $ldap->cat ($dn); + $ldap->cat ($dn, array('dn')); if (!$ldap->fetch()){ return ($dn); } @@ -532,7 +671,7 @@ class plugin } $dn= "$attribute=".$this->$attribute."+$attr=".$this->$attr.",$base"; - $ldap->cat ($dn); + $ldap->cat ($dn, array('dn')); if (!$ldap->fetch()){ return ($dn); } @@ -561,7 +700,7 @@ class plugin { /* Rename dn in possible object groups */ $ldap= $this->config->get_ldap_link(); - $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.$src_dn.'))', + $ldap->search('(&(objectClass=gosaGroupOfNames)(member='.@LDAP::prepare4filter($src_dn).'))', array('cn')); while ($attrs= $ldap->fetch()){ $og= new ogroup($this->config, $ldap->getDN()); @@ -573,16 +712,15 @@ class plugin $ldap->cat($dst_dn); $attrs= $ldap->fetch(); if (count($attrs)){ - trigger_error("Trying to overwrite $dst_dn, which already exists.", + trigger_error("Trying to overwrite ".@LDAP::fix($dst_dn).", which already exists.", E_USER_WARNING); return (FALSE); } $ldap->cat($src_dn); - $attrs= array(); $attrs= $ldap->fetch(); if (!count($attrs)){ - trigger_error("Trying to move $src_dn, which does not seem to exist.", + trigger_error("Trying to move ".@LDAP::fix($src_dn).", which does not seem to exist.", E_USER_WARNING); return (FALSE); } @@ -596,7 +734,7 @@ class plugin $r=ldap_bind($ds,$this->config->current['ADMIN'], $this->config->current['PASSWORD']); error_reporting (0); - $sr=ldap_read($ds, $src_dn, "objectClass=*"); + $sr=ldap_read($ds, @LDAP::fix($src_dn), "objectClass=*"); /* Fill data from LDAP */ $new= array(); @@ -624,12 +762,28 @@ class plugin /* Adapt naming attribute */ $dst_name= preg_replace("/^([^=]+)=.*$/", "\\1", $dst_dn); $dst_val = preg_replace("/^[^=]+=([^,+]+).*,.*$/", "\\1", $dst_dn); - $new[$dst_name]= $dst_val; + $new[$dst_name]= @LDAP::fix($dst_val); + + /* Check if this is a department. + * If it is a dep. && there is a , override in his ou + * change \2C to , again, else this entry can't be saved ... + */ + if((isset($new['ou'])) &&( preg_match("/\\,/",$new['ou']))){ + $new['ou'] = preg_replace("/\\\\,/",",",$new['ou']); + } /* Save copy */ $ldap->connect(); $ldap->cd($this->config->current['BASE']); + $ldap->create_missing_trees(preg_replace('/^[^,]+,/', '', $dst_dn)); + + /* FAIvariable=.../..., cn=.. + could not be saved, because the attribute FAIvariable was different to + the dn FAIvariable=..., cn=... */ + if(in_array_ics("FAIdebconfInfo",$new['objectClass'])){ + $new['FAIvariable'] = $ldap->fix($new['FAIvariable']); + } $ldap->cd($dst_dn); $ldap->add($new); @@ -645,6 +799,12 @@ class plugin function move($src_dn, $dst_dn) { + + /* Do not copy if only upper- lowercase has changed */ + if(strtolower($src_dn) == strtolower($dst_dn)){ + return(TRUE); + } + /* Copy source to destination */ if (!$this->copy($src_dn, $dst_dn)){ return (FALSE); @@ -670,7 +830,7 @@ class plugin $ldap= $this->config->get_ldap_link(); /* Check if destination exists - abort */ - $ldap->cat($dst_dn); + $ldap->cat($dst_dn, array('dn')); if ($ldap->fetch()){ trigger_error("recursive_move $dst_dn already exists.", E_USER_WARNING); @@ -706,24 +866,226 @@ class plugin } - function handle_post_events($mode) + function handle_post_events($mode, $add_attrs= array()) { switch ($mode){ case "add": - $this->postcreate(); + $this->postcreate($add_attrs); break; case "modify": - $this->postmodify(); + $this->postmodify($add_attrs); break; case "remove": - $this->postremove(); + $this->postremove($add_attrs); break; } } -} + function saveCopyDialog(){ + } + + + function getCopyDialog(){ + return(array("string"=>"","status"=>"")); + } + + + function PrepareForCopyPaste($source){ + $todo = $this->attributes; + if(isset($this->CopyPasteVars)){ + $todo = array_merge($todo,$this->CopyPasteVars); + } + $todo[] = "is_account"; + foreach($todo as $var){ + if (isset($source->$var)){ + $this->$var= $source->$var; + } + } + } + + + function tag_attrs($at, $dn= "", $tag= "", $show= false) + { + /* Skip tagging? + If this is called from departmentGeneric, we have to skip this + tagging procedure. + */ + if($this->skipTagging){ + return; + } + + /* No dn? Self-operation... */ + if ($dn == ""){ + $dn= $this->dn; + + /* No tag? Find it yourself... */ + if ($tag == ""){ + $len= strlen($dn); + + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "No tag for $dn - looking for one...", "Tagging"); + $relevant= array(); + foreach ($this->config->adepartments as $key => $ntag){ + + /* This one is bigger than our dn, its not relevant... */ + if ($len <= strlen($key)){ + continue; + } + + /* This one matches with the latter part. Break and don't fix this entry */ + if (preg_match('/(^|,)'.normalizePreg($key).'$/', $dn)){ + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "DEBUG: Possibly relevant: $key", "Tagging"); + $relevant[strlen($key)]= $ntag; + continue; + } + + } + + /* If we've some relevant tags to set, just get the longest one */ + if (count($relevant)){ + ksort($relevant); + $tmp= array_keys($relevant); + $idx= end($tmp); + $tag= $relevant[$idx]; + $this->gosaUnitTag= $tag; + } + } + } + + /* Remove tags that may already be here... */ + remove_objectClass("gosaAdministrativeUnitTag", &$at); + if (isset($at['gosaUnitTag'])){ + unset($at['gosaUnitTag']); + } + + /* Set tag? */ + if ($tag != ""){ + add_objectClass("gosaAdministrativeUnitTag", &$at); + $at['gosaUnitTag']= $tag; + } + } + + + function handle_object_tagging($dn= "", $tag= "", $show= false) + { + //FIXME: How to optimize this? We have at least two + // LDAP accesses per object. It would be a good + // idea to have it integrated. + + /* No dn? Self-operation... */ + if ($dn == ""){ + $dn= $this->dn; + + /* No tag? Find it yourself... */ + if ($tag == ""){ + $len= strlen($dn); + + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "No tag for $dn - looking for one...", "Tagging"); + $relevant= array(); + foreach ($this->config->adepartments as $key => $ntag){ + + /* This one is bigger than our dn, its not relevant... */ + if ($len <= strlen($key)){ + continue; + } + + /* This one matches with the latter part. Break and don't fix this entry */ + if (preg_match('/(^|,)'.normalizePreg($key).'$/', $dn)){ + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "DEBUG: Possibly relevant: $key", "Tagging"); + $relevant[strlen($key)]= $ntag; + continue; + } + + } + + /* If we've some relevant tags to set, just get the longest one */ + if (count($relevant)){ + ksort($relevant); + $tmp= array_keys($relevant); + $idx= end($tmp); + $tag= $relevant[$idx]; + $this->gosaUnitTag= $tag; + } + } + } + + + /* Set tag? */ + if ($tag != ""){ + /* Set objectclass and attribute */ + $ldap= $this->config->get_ldap_link(); + $ldap->cat($dn, array('gosaUnitTag', 'objectClass')); + $attrs= $ldap->fetch(); + if(isset($attrs['gosaUnitTag'][0]) && $attrs['gosaUnitTag'][0] == $tag){ + if ($show) { + echo sprintf(_("Object '%s' is already tagged"), @LDAP::fix($dn))."
"; + flush(); + } + return; + } + if (count($attrs)){ + if ($show){ + echo sprintf(_("Adding tag (%s) to object '%s'"), $tag, @LDAP::fix($dn))."
"; + flush(); + } + $nattrs= array("gosaUnitTag" => $tag); + $nattrs['objectClass']= array(); + for ($i= 0; $i<$attrs['objectClass']['count']; $i++){ + $oc= $attrs['objectClass'][$i]; + if ($oc != "gosaAdministrativeUnitTag"){ + $nattrs['objectClass'][]= $oc; + } + } + $nattrs['objectClass'][]= "gosaAdministrativeUnitTag"; + $ldap->cd($dn); + $ldap->modify($nattrs); + show_ldap_error($ldap->get_error(), _("Handle object tagging failed")); + } else { + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "Not tagging ($tag) $dn - seems to have moved away", "Tagging"); + } + + } else { + /* Remove objectclass and attribute */ + $ldap= $this->config->get_ldap_link(); + $ldap->cat($dn, array('gosaUnitTag', 'objectClass')); + $attrs= $ldap->fetch(); + if (isset($attrs['objectClass']) && !in_array_ics("gosaAdministrativeUnitTag", $attrs['objectClass'])){ + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "$dn is not tagged", "Tagging"); + return; + } + if (count($attrs)){ + if ($show){ + echo sprintf(_("Removing tag from object '%s'"), @LDAP::fix($dn))."
"; + flush(); + } + $nattrs= array("gosaUnitTag" => array()); + $nattrs['objectClass']= array(); + for ($i= 0; $i<$attrs['objectClass']['count']; $i++){ + $oc= $attrs['objectClass'][$i]; + if ($oc != "gosaAdministrativeUnitTag"){ + $nattrs['objectClass'][]= $oc; + } + } + $ldap->cd($dn); + $ldap->modify($nattrs); + show_ldap_error($ldap->get_error(), _("Handle object tagging failed")); + } else { + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, "Not removing tag ($tag) $dn - seems to have moved away", "Tagging"); + } + } + + } + + + /* Add possibility to stop remove process */ + function allow_remove() + { + $reason= ""; + return $reason; + } + +} // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: ?>