88683616057caae6e929838818c914b8bd850dfa
1 <?php
3 class faiHook extends plugin
4 {
5 /* attribute list for save action */
6 var $ignore_account = TRUE;
8 /* Attributes for this Object */
9 var $attributes = array("cn","description");
11 /* ObjectClasses for this Object*/
12 var $objectclasses = array("top","FAIclass","FAIhook");
14 /* Class name of the Ldap ObjectClass for the Sub Object */
15 var $subClass = "FAIhookEntry";
16 var $subClasses = array("top","FAIclass","FAIhookEntry");
18 /* Class name of the php class which allows us to edit a Sub Object */
19 var $subClassName = "faiHookEntry";
21 /* Attributes to initialise for each subObject */
22 var $subAttributes = array("cn","description","FAItask");
23 var $sub_Load_Later = array("FAIscript");
24 var $sub64coded = array();
25 var $subBinary = array("FAIscript");
27 /* Specific attributes */
28 var $cn = ""; // The class name for this object
29 var $description = ""; // The description for this set of partitions
30 var $is_dialog = false; // specifies which buttons will be shown to save or abort
31 var $SubObjects = array(); // All leafobjects of this object
32 var $view_logged = FALSE;
33 var $FAIstate = "";
34 var $ui;
36 function faiHook (&$config, $dn= NULL)
37 {
38 /* Load Attributes */
39 plugin::plugin ($config, $dn);
41 /* If "dn==new" we try to create a new entry
42 * Else we must read all objects from ldap which belong to this entry.
43 */
44 if($dn != "new"){
45 $this->dn =$dn;
47 /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
48 */
49 $res = FAI::get_all_objects_for_given_base($this->dn,"(&(objectClass=FAIclass)(objectClass=".$this->subClass."))");
50 foreach($res as $obj){
51 $objects = array();
52 $objects['status'] = "FreshLoaded";
53 $objects['dn'] = $obj['dn'];
54 $objects = $this->get_object_attributes($objects,$this->subAttributes);
55 $this->SubObjects[$objects['cn']] = $objects;
56 }
57 }
58 $this->is_new = FALSE;
59 if($this->dn == "new"){
60 $this->is_new =TRUE;
61 }
62 $this->ui = get_userinfo();
63 }
66 /* Reload some attributes */
67 function get_object_attributes($object,$attributes)
68 {
69 $ldap = $this->config->get_ldap_link();
70 $ldap->cd($this->config->current['BASE']);
71 $ldap->cat($object['dn'],$attributes);
72 $tmp = $ldap->fetch();
74 foreach($attributes as $attrs){
75 if(isset($tmp[$attrs][0])){
76 $var = $tmp[$attrs][0];
78 /* Check if we must decode some attributes */
79 if(in_array_ics($attrs,$this->sub64coded)){
80 $var = base64_decode($var);
81 }
83 /* check if this is a binary entry */
84 if(in_array_ics($attrs,$this->subBinary)){
85 $var = $ldap->get_attribute($object['dn'], $attrs,$r_array=0);
86 }
88 /* Fix slashes */
89 $var = addslashes($var);
90 $object[$attrs] = $var;
91 }
92 }
93 return($object);
94 }
97 function acl_base_for_current_object($dn)
98 {
99 if($dn == "new"){
100 if($this->dn == "new"){
101 $dn = session::get('CurrentMainBase');
102 }else{
103 $dn = $this->dn;
104 }
105 }
106 return($dn);
107 }
110 function getUsedFAItask($cn)
111 {
112 $ret = array();
113 foreach($this->SubObjects as $name => $class){
114 if($class['cn'] == $cn){
115 continue;
116 }
117 if($class['status'] != "delete"){
118 $ret[$class['FAItask']] = $class['FAItask'];
119 }
120 }
121 return($ret);
122 }
124 function execute()
125 {
126 /* Call parent execute */
127 plugin::execute();
129 if($this->is_account && !$this->view_logged){
130 $this->view_logged = TRUE;
131 new log("view","fai/".get_class($this),$this->dn);
132 }
134 /* Fill templating stuff */
135 $smarty= get_smarty();
136 $display= "";
138 /* New Listhandling
139 */
140 $once = true;
141 foreach($_POST as $name => $value){
142 if(preg_match("/^editscript_/",$name)&&($once)){
143 $once = false;
144 $entry = preg_replace("/^editscript_/","",$name);
145 $entry = base64_decode(preg_replace("/_.*/","",$entry));
147 $obj = $this->SubObjects[$entry];
148 if($obj['status'] == "FreshLoaded"){
149 $obj = $this->get_object_attributes($obj,$this->sub_Load_Later);
150 }
152 $this->dialog= new $this->subClassName($this->config,$this->dn,$obj);
153 $this->dialog->FAIstate = $this->FAIstate;
154 $this->dialog->set_acl_base($this->acl_base_for_current_object($obj['dn']));
155 $this->dialog->set_acl_category("fai");
157 session::set('objectinfo',$obj['dn']);
158 $this->dialog->parent = &$this;
159 $this->is_dialog=true;
160 }
161 if(preg_match("/^deletescript_/",$name)&&($once)){
162 $entry = preg_replace("/^deletescript_/","",$name);
163 $entry = base64_decode(preg_replace("/_.*/","",$entry));
165 $dn = $this->acl_base_for_current_object($this->SubObjects[$entry]['dn']);
166 $acl = $this->ui -> get_permissions($dn,"fai/faiScriptEntry") ;
168 if(preg_match("/d/",$acl)){
169 $once = false;
171 $status = $this->SubObjects[$entry]['status'];
172 if($status == "edited" || $status == "FreshLoaded"){
173 $this->SubObjects[$entry]['status']= "delete";
174 }else{
175 unset($this->SubObjects[$entry]);
176 }
177 }
178 }
179 }
181 /* File download requested */
182 if(isset($_GET['getFAIHook'])){
183 if(isset($this->SubObjects[base64_decode($_GET['getFAIHook'])])){
184 $obj = $this->SubObjects[base64_decode($_GET['getFAIHook'])];
185 $obj = $this->get_object_attributes($obj,$this->sub_Load_Later);
186 send_binary_content(stripslashes($obj['FAIscript']),$obj['cn'].".FAIhook");
187 }
188 }
190 /* Edit entries via GET */
191 if(isset($_GET['act']) && isset($_GET['id'])){
192 if($_GET['act'] == "edit" && isset($this->SubObjects[base64_decode($_GET['id'])])){
193 $obj = $this->SubObjects[base64_decode($_GET['id'])];
194 if($obj['status'] == "FreshLoaded"){
195 $obj = $this->get_object_attributes($obj,$this->sub_Load_Later);
196 }
197 $this->dialog= new $this->subClassName($this->config,$this->dn,$obj);
198 $this->dialog->FAIstate = $this->FAIstate;
199 $this->dialog->acl = $this->acl;
200 session::set('objectinfo',$obj['dn']);
201 $this->dialog->parent = &$this;
202 $this->is_dialog=true;
203 }
204 }
206 ///// Ende new list handling
208 /* Add new sub object */
209 if(isset($_POST['AddSubObject'])){
211 $c_dn = $this->acl_base_for_current_object($this->dn);
212 $this->dialog= new $this->subClassName($this->config,"new");
213 $this->dialog->set_acl_base($c_dn);
214 $this->dialog->FAIstate = $this->FAIstate;
215 $this->dialog->set_acl_category("fai");
216 $this->dialog->parent = &$this;
217 $this->is_dialog=true;
218 }
221 /* Save Dialog */
222 if(isset($_POST['SaveSubObject'])){
224 /* Perform post check*/
225 $this->dialog->save_object();
227 /* Get messages */
228 $msgs = $this->dialog->check();
230 /* print errors */
231 if(count($msgs)>0){
232 foreach($msgs as $msg){
233 msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
234 }
235 }else{
237 /* Get return object */
238 $obj = $this->dialog->save();
239 if(isset($obj['remove'])){
241 $old_stat = $this->SubObjects[$obj['remove']['from']]['status'];
243 /* Depending on status, set new status */
244 if($old_stat == "edited" || $old_stat == "FreshLoaded"){
245 $this->SubObjects[$obj['remove']['from']]['status'] = "delete";
246 }elseif($this->SubObjects[$obj['remove']['from']]['status']=="new"){
247 unset($this->SubObjects[$obj['remove']['from']]);
248 }
249 $obj['status'] = "new";
250 $this->SubObjects[$obj['remove']['to']] = $obj;
251 unset($this->SubObjects[$obj['remove']['to']]['remove']);
252 }else{
253 if($obj['status'] == "FreshLoaded"){
254 $obj['status'] = "edited";
255 }
256 $this->SubObjects[$obj['cn']]=$obj;
257 }
258 $this->is_dialog=false;
259 unset($this->dialog);
260 $this->dialog=FALSE;
261 }
262 }
264 /* Sort entries */
265 $tmp = $keys = array();
266 foreach($this->SubObjects as $key => $entry){
267 $keys[$key]=$key;
268 }
269 natcasesort($keys);
270 foreach($keys as $key){
271 $tmp[$key]=$this->SubObjects[$key];
272 }
273 $this->SubObjects = $tmp;
275 /* Cancel Dialog */
276 if(isset($_POST['CancelSubObject'])){
277 $this->is_dialog=false;
278 unset($this->dialog);
279 $this->dialog=FALSE;
280 }
282 /* Print dialog if $this->dialog is set */
283 if(is_object($this->dialog)){
284 $this->dialog->save_object();
285 $display = $this->dialog->execute();
286 return($display);
287 }
291 /* Divlist added 28.02.2006
292 Containing FAIscripts
293 */
295 $divlist = new divSelectBox("FAIhooks");
296 $divlist->setHeight(400);
298 foreach($this->getList(true) as $key => $name){
300 $dn= $this->acl_base_for_current_object($name['dn']);
301 $acl = $this->ui->get_permissions($dn,"fai/faiHookEntry") ;
302 $act = "";
304 /* Check if this object is freezed, in this case hide the delete icon */
305 if(preg_match("/^freeze/", $this->FAIstate)){
306 $act .= "<input type='image' src='images/lists/edit.png' name='editscript_%s' title='"._("Edit")."' alt='"._("Edit")."'>";
307 }else{
308 $act .= "<input type='image' src='images/lists/edit.png' name='editscript_%s' title='"._("Edit")."' alt='"._("Edit")."'>";
309 if(preg_match("/d/",$acl)){
310 $act .="<input type='image' src='images/lists/trash.png' name='deletescript_%s' title='"._("Delete")."' alt='"._("Delete")."'>";
311 }
312 }
314 /* Check if we are allowed to use the export button for this object */
315 $s_acl = $this->ui->get_permissions($dn,"fai/faiHookEntry","FAIscript") ;
316 if(($this->SubObjects[$key]['status'] == "new") || ($this->SubObjects[$key]['dn'] == "new") || !preg_match("/r/",$s_acl)){
317 $down = "";
318 }else{
319 $down = "<a href='?plug=".$_GET['plug']."&getFAIHook=".base64_encode($key)."'>
320 <img src='images/save.png' alt='"._("Download")."' title='"._("Download")."' border=0>
321 </a>";
322 }
324 /* Check if we are allowed to view the object */
325 $s_acl = $this->ui->get_permissions($dn,"fai/faiHookEntry","cn") ;
326 if(preg_match("/r/",$s_acl)){
328 $edit_link = "<a href='?plug=".$_GET['plug']."&act=edit&id=".base64_encode($key)."'>".$name['name']."</a>";
329 $divlist->AddEntry(array( array("string"=>$edit_link),
330 array("string"=>$down , "attach" => "style='width:20px;'"),
331 array("string"=>str_replace("%s",base64_encode($key),$act),
332 "attach"=>"style='border-right: 0px;width:50px;text-align:right;'")));
333 }
334 }
335 $smarty->assign("Entry_divlist",$divlist->DrawList());
336 /* Divlist creation complete
337 */
339 $smarty->assign("SubObjects",$this->getList());
341 /* Magic quotes GPC, escapes every ' " \, to solve some security risks
342 * If we post the escaped strings they will be escaped again
343 */
344 foreach($this->attributes as $attrs){
345 if(get_magic_quotes_gpc()){
346 $smarty->assign($attrs,stripslashes($this->$attrs));
347 }else{
348 $smarty->assign($attrs,($this->$attrs));
349 }
350 }
352 $tmp = $this->plInfo();
354 $c_dn = $this->acl_base_for_current_object($this->dn);
355 $smarty->assign("sub_object_is_addable", preg_match("/c/",$this->ui->get_permissions($c_dn,"fai/faiHookEntry")) && !preg_match('/^freeze/', $this->FAIstate));
356 foreach($tmp['plProvidedAcls'] as $name => $translation){
357 $smarty->assign($name."ACL",$this->getacl($name));
358 }
360 $display.= $smarty->fetch(get_template_path('faiHook.tpl', TRUE));
361 return($display);
362 }
364 /* Generate listbox friendly SubObject list
365 */
366 function getList($use_dns=false){
367 $a_return=array();
368 foreach($this->SubObjects as $obj){
369 if($obj['status'] != "delete"){
371 $cn = stripslashes($obj['cn']);
372 $desc = "";
374 if((isset($obj['description']))&&(!empty($obj['description']))){
375 $desc = " [".stripslashes($obj['description'])."]";
376 }
378 if($use_dns){
379 $a_return[$obj['cn']]['name']= $cn.$desc;
380 $a_return[$obj['cn']]['dn']= $obj['dn'];
381 }else{
382 $a_return[$obj['cn']] = $cn.$desc;
383 }
384 }
385 }
386 return($a_return);
387 }
390 /* Delete me, and all my subtrees
391 */
392 function remove_from_parent()
393 {
394 if($this->acl_is_removeable()){
395 $ldap = $this->config->get_ldap_link();
396 $ldap->cd ($this->dn);
397 $release = $this->parent->parent->fai_release;
398 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $release, $this->dn);
399 new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
400 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
402 foreach($this->SubObjects as $name => $obj){
403 $use_dn = preg_replace("/".normalizePreg(FAI::get_release_dn($this->dn))."/i", $release, $obj['dn']);
404 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
405 }
406 $this->handle_post_events("remove");
407 }
408 }
411 /* Save data to object
412 */
413 function save_object()
414 {
415 if((isset($_POST['FAIhook_posted'])) && !preg_match("/^freeze/", $this->FAIstate)){
416 plugin::save_object();
417 foreach($this->attributes as $attrs){
418 if(isset($_POST[$attrs])){
419 $this->$attrs = $_POST[$attrs];
420 }
421 }
422 }
423 }
426 /* Check supplied data */
427 function check()
428 {
429 /* Call common method to give check the hook */
430 $message= plugin::check();
432 /* Ensure that we do not overwrite an allready existing entry
433 */
434 if($this->is_new){
435 $release = $this->parent->parent->fai_release;
436 $new_dn= 'cn='.$this->cn.",".get_ou('faihookou').get_ou('faiou').$release;
437 $res = faiManagement::check_class_name("FAIhook",$this->cn,$new_dn);
438 if(isset($res[$this->cn])){
439 $message[] = msgPool::duplicated(_("Name"));
440 }
441 }
443 return ($message);
444 }
447 /* Save to LDAP */
448 function save()
449 {
450 plugin::save();
452 $ldap = $this->config->get_ldap_link();
454 FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
456 if($this->initially_was_account){
457 new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
458 }else{
459 new log("create","fai/".get_class($this),$this->dn,$this->attributes);
460 }
462 $ldap->cd($this->dn);
464 /* Prepare FAIscriptEntry to write it to ldap
465 * First sort array.
466 * Because we must delete old entries first.
467 * After deletion, we perform add and modify
468 */
469 $Objects = array();
471 /* We do not need to save untouched objects */
472 foreach($this->SubObjects as $name => $obj){
473 if($obj['status'] != "FreshLoaded"){
474 $Objects[$name] = $obj;
475 }
476 }
478 foreach($Objects as $name => $obj){
480 foreach($this->sub64coded as $codeIt){
481 $obj[$codeIt]=base64_encode(stripslashes($obj[$codeIt]));
482 }
484 $tmp = array();
485 $attributes = array_merge($this->sub_Load_Later,$this->subAttributes);
486 foreach($attributes as $attrs){
487 if(empty($obj[$attrs])){
488 $obj[$attrs] = array();
489 }
490 if(!is_array($obj[$attrs])){
491 $tmp[$attrs] = stripslashes($obj[$attrs]);
492 }else{
493 $tmp[$attrs] = $obj[$attrs];
494 }
495 }
497 $tmp['objectClass'] = $this->subClasses;
499 $sub_dn = "cn=".$obj['cn'].",".$this->dn;
501 if($obj['status']=="new"){
502 $ldap->cat($sub_dn,array("objectClass"));
503 if($ldap->count()){
504 $obj['status']="edited";
505 }
506 }
508 /* Tag object */
509 $this->tag_attrs($tmp, $sub_dn, $this->gosaUnitTag);
511 if($obj['status'] == "delete"){
512 FAI::prepare_to_save_FAI_object($sub_dn,array(),true);
513 $this->handle_post_events("remove");
514 }elseif($obj['status'] == "edited"){
515 FAI::prepare_to_save_FAI_object($sub_dn,$tmp);
516 $this->handle_post_events("modify");
517 }elseif($obj['status']=="new"){
518 FAI::prepare_to_save_FAI_object($sub_dn,$tmp);
519 $this->handle_post_events("add");
520 }
521 }
522 }
525 function PrepareForCopyPaste($source)
526 {
527 plugin::PrepareForCopyPaste($source);
529 /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
530 */
531 $ldap = $this->config->get_ldap_link();
532 $ldap->cd ($source['dn']);
534 $attrs_to_search = $this->subAttributes;
535 $attrs_to_search[] = "FAIstate";
536 $ldap->search("(&(objectClass=FAIclass)(objectClass=".$this->subClass."))",$attrs_to_search);
538 while($object = $ldap->fetch()){
540 /* Skip objects, that are tagged as removed */
541 if(isset($object['FAIstate'][0])){
542 if(preg_match("/removed$/",$object['FAIstate'][0])){
543 continue;
544 }
545 }
547 /* Set status for save management */
548 $objects = array();
549 $objects['status'] = "edited";
550 $objects['dn'] = $object['dn'];
551 $objects = $this->get_object_attributes($objects,$this->subAttributes);
552 $objects = $this->get_object_attributes($objects,$this->sub_Load_Later);
554 $this->SubObjects[$objects['cn']] = $objects;
555 }
556 }
559 /* Return plugin informations for acl handling */
560 static function plInfo()
561 {
562 return (array(
563 "plShortName" => _("Hook"),
564 "plDescription" => _("FAI hook"),
565 "plSelfModify" => FALSE,
566 "plDepends" => array(),
567 "plPriority" => 20,
568 "plSection" => array("administration"),
569 "plCategory" => array("fai"),
570 "plProvidedAcls" => array(
571 "cn" => _("Name")." ("._("Read only").")",
572 "description" => _("Description"))
573 ));
574 }
577 /*! \brief Used for copy & paste.
578 Returns a HTML input mask, which allows to change the cn of this entry.
579 @param Array Array containing current status && a HTML template.
580 */
581 function getCopyDialog()
582 {
583 $vars = array("cn");
584 $smarty = get_smarty();
585 $smarty->assign("cn", htmlentities($this->cn));
586 $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
587 $ret = array();
588 $ret['string'] = $str;
589 $ret['status'] = "";
590 return($ret);
591 }
594 /*! \brief Used for copy & paste.
595 Some entries must be renamed to avaoid duplicate entries.
596 */
597 function saveCopyDialog()
598 {
599 if(isset($_POST['cn'])){
600 $this->cn = get_post('cn');
601 }
602 }
603 }
605 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
606 ?>