Code

Updated Krb services
[gosa.git] / gosa-core / include / class_gosaSupportDaemon.inc
1 <?php
2 /*
3  * This code is part of GOsa (http://www.gosa-project.org)
4  * Copyright (C) 2003-2008 GONICUS GmbH
5  *
6  * ID: $$Id$$
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
23 class gosaSupportDaemon
24 {
25   private $s_host       = "";
26   private $i_port       = 0;
27   private $s_encryption_key = "";
29   private $o_sock       = NULL;
30   private $f_timeout    = 2;
31   private $s_error      = "";
32   private $b_error      = FALSE;
34   private $is_connected     = FALSE;
37   /*! \brief  Creates a new gosaSupportDaemon object.
38     @param string   Host    The Host where the daemon is running on.  
39     @param integer  Port    The port which the daemon use.
40     @param string   Key     The encryption string.
41     @param boolean  Connect Directly connect to daemon socket.
42     @param float    Timeout The timelimit for all socket actions.
43    */
44   public function __construct($connect=TRUE,$timeout=10)
45   {
46     #FIXME: bad idea about referencing global variables from within classes
47     global $config;
49     # load from config, store statically
50     if (isset($config->current['GOSA_SI'])){
52       if ($this->s_host == ""){
53         $this->s_host= preg_replace("/^.*@([^:]+):.*$/", "$1", $config->current['GOSA_SI']);
54         $this->i_port= preg_replace("/^.*@[^:]+:(.*)$/", "$1", $config->current['GOSA_SI']);
55         $this->s_encryption_key = preg_replace("/^(.*)@[^:]+:.*$/", "$1", $config->current['GOSA_SI']);
56       }
58       $this->f_timeout = $timeout;
59       if($connect){
60         $this->connect();
61       }
62     }
63   }
66   /*! \brief  Establish daemon connection. 
67     @return boolean Returns true if the connection was succesfully established. 
68    */
69   public function connect()
70   {
71     if(!empty($this->s_host) && !empty($this->i_port)){
72       $this->o_sock = new Socket_Client($this->s_host,$this->i_port,TRUE,$this->f_timeout);
73       if($this->o_sock->connected()){ 
74         $this->o_sock->setEncryptionKey($this->s_encryption_key); 
75         $this->is_connected = TRUE;
76       }else{
77         $this->set_error($this->o_sock->get_error());
78         $this->disconnect();
79         new log("debug","gosaSupportDaemon::connect()", "Cannot connect to si-server", array(),$this->get_error());
80       }
81     }else{
82       $this->set_error(msgPool::cmdnotfound("GOSA_SI",_("GOsa support daemon")));
83     }
84     return($this->is_connected);
85   }
88   /*! \brief  Disconnect from gosa daemon.
89    */
90   public function disconnect()
91   {
92     $this->o_sock->close();
93     $this->is_connected = FALSE;
94   }
97   /*! \brief  Sets an error message, which can be returned with get_error().
98     @param  string  The Error message,
99    */
100   private function set_error($str)
101   {
102     $this->b_error = TRUE;
103     $this->s_error = $str;
104   }
107   /*! \brief  Sets an error message, which can be returned with get_error().
108     @param  string  The Error message,
109    */
110   private function reset_error()
111   {
112     $this->b_error = FALSE;
113     $this->s_error = "";
114   }
117   /*! \brief  Checks if an error occured.
118     @return boolean returns TRUE or FALSE, whether there is an error or not.
119    */
120   public function is_error()
121   {
122     return($this->b_error);
123   }
126   /*! \brief  Returns the last error. 
127     @return Returns the last error.
128    */
129   public function get_error()
130   {
131     $str = $this->s_error;
132     $str = preg_replace("/ /","&nbsp;",$str);
133     return($str);
134   }
137   public function FAI_get_kernels($release)
138   {
139     $xml_msg = 
140       "<xml>".
141       "<header>gosa_get_available_kernel</header>".
142       "<source>GOSA</source>".
143       "<target>GOSA</target>".
144       "<release>".$release."</release>".
145       "</xml>";
147     $ret = array();
148     if($this->connect()){
149       $this->o_sock->write($xml_msg);
150       $str = trim($this->o_sock->read());
152       /* Check if something went wrong while reading */
153       if($this->o_sock->is_error()){
154         $this->set_error($this->o_sock->get_error());
155         return($ret);
156       }
158       $entries = $this->xml_to_array($str);
159       if(isset($entries['XML']) && is_array($entries['XML'])){
161         /* Check if returned values represent a valid answer */
162         if(isset($entries['XML'])){
163           if(isset($entries['XML']['ERROR_STRING'])) {
164             $this->set_error($entries['XML']['ERROR_STRING']);
165             new log("debug","GOsa-si",
166                 get_class($this)."::".__FUNCTION__, array(),
167                 "FAILED error was ".$this->get_error());
168             return($ret);
169           }
171           /* Unset header tags */
172           $ret = $entries['XML'];
173           foreach($ret as $key => $entry){
174             if(!preg_match("/^answer/i",$key)){
175               unset($ret[$key]);
176             }
177           }
178         }
179       }
180     }
181     return($ret);
182   }
185   public function FAI_get_package_sections($release)
186   {
187     $xml_msg = "<xml><header>gosa_query_packages_list</header><target>GOSA</target><source>GOSA</source>".
188       "<select>distinct section</select>".
189       "<where><clause><phrase><distribution>".$release."</distribution></phrase></clause></where></xml>";
191     $ret = array();
192     if($this->connect()){
193       $this->o_sock->write($xml_msg);
194       $str = trim($this->o_sock->read());
196       /* Check if something went wrong while reading */
197       if($this->o_sock->is_error()){
198         $this->set_error($this->o_sock->get_error());
199         return($ret);
200       }
202       $entries = $this->xml_to_array($str);
203       if(isset($entries['XML']) && is_array($entries['XML'])){
205         /* Check if returned values represent a valid answer */
206         if(isset($entries['XML'])){
207           if(isset($entries['XML']['ERROR_STRING'])) {
208             $this->set_error($entries['XML']['ERROR_STRING']);
209             new log("debug","GOsa-si",
210                 get_class($this)."::".__FUNCTION__, array(),
211                 "FAILED error was ".$this->get_error());
212             return($ret);
213           }
215           /* Unset header tags */
216           foreach(array("HEADER","SOURCE","TARGET","SESSION_ID") as $type){
217             if(isset($entries['XML'][$type])){
218               unset($entries['XML'][$type]);
219             }
220           }
221           $ret = $entries['XML'];
222         }
223       }
224     }
225     return($ret);
226   }
229   public function FAI_get_packages($release,$attrs,$package,$from=-1,$to=-1)
230   {
231     $this->reset_error();
232     $ret = array();
234     /* Check Parameter */
235     if(!is_array($attrs) || !count($attrs)){
236       trigger_error("Second parameter must be an array. With at least one attribute name.");
237       return($ret);
238     }
240     /* Check Parameter */
241     if(!is_array($package)){
242       trigger_error("Third parameter must be an array. With at least one attribute name.");
243       return($ret);
244     }
246     /* Create list of attributes to fetch */
247     $attr = ""; 
248     foreach($attrs as $at){
249       $attr.= "<select>".$at."</select>";
250     }
252     /* If no package is given, search for all */
253     if(!count($package)) $package = array("%");
255     /* Create limit tag */
256     if($from == -1){
257       $limit =""; 
258     }else{
259       $limit = "<limit><from>".$from."</from><to>".$to."</to></limit>";
260     }
262     /* Create list of attributes to fetch */
263     $pkgs = ""; 
264     foreach($package as $pkg){
265       $pkgs .="<phrase><operator>like</operator><package>".$pkg."</package></phrase>";
266     }
268     $xml_msg = "<xml><header>gosa_query_packages_list</header><target>GOSA</target><source>GOSA</source>".
269       $attr.
270       "<where>
271       <clause><phrase><distribution>".$release."</distribution></phrase></clause>
272       <clause><connector>OR</connector>
273       ".$pkgs."
274       </clause>
275       </where>".
276       $limit.
277       "</xml>";
279     if($this->connect()){
280       $this->o_sock->write($xml_msg);
281       $str = trim($this->o_sock->read());
283       /* Check if something went wrong while reading */
284       if($this->o_sock->is_error()){
285         $this->set_error($this->o_sock->get_error());
286         return($ret);
287       }
289       $entries = $this->xml_to_array($str);
290       if(isset($entries['XML']) && is_array($entries['XML'])){
292         /* Check if returned values represent a valid answer */
293         if(isset($entries['XML'])){
294           if(isset($entries['XML']['ERROR_STRING'])) {
295             $this->set_error($entries['XML']['ERROR_STRING']);
296             new log("debug","GOsa-si",
297                 get_class($this)."::".__FUNCTION__, array(),
298                 "FAILED error was ".$this->get_error());
299             return($ret);
300           }
302           /* Unset header tags */
303           foreach(array("HEADER","SOURCE","TARGET","SESSION_ID") as $type){
304             if(isset($entries['XML'][$type])){
305               unset($entries['XML'][$type]);
306             }
307           }
308           $ret = $entries['XML'];
309         }
310       }
311     }
312     return($ret);
314     
315   }
318   public function FAI_get_server($name = "")
319   {
320     $this->reset_error();
322     $xml_msg = "<xml><header>gosa_query_fai_server</header><target>GOSA</target><source>GOSA</source></xml>";
323     $ret = array();
324     if($this->connect()){
325       $this->o_sock->write($xml_msg);
326       $str = trim($this->o_sock->read());
328       /* Check if something went wrong while reading */
329       if($this->o_sock->is_error()){
330         $this->set_error($this->o_sock->get_error());
331         return($ret);
332       }
334       $entries = $this->xml_to_array($str);
335       if(isset($entries['XML']) && is_array($entries['XML'])){
337         /* Check if returned values represent a valid answer */
338         if(isset($entries['XML'])){
339           if(isset($entries['XML']['ERROR_STRING'])) {
340             $this->set_error($entries['XML']['ERROR_STRING']);
341             new log("debug","GOsa-si", 
342               get_class($this)."::".__FUNCTION__, array(),
343               "FAILED error was ".$this->get_error());
344             return($ret);
345           }
347           /* Unset header tags */
348           foreach(array("HEADER","SOURCE","TARGET","SESSION_ID") as $type){
349             if(isset($entries['XML'][$type])){
350               unset($entries['XML'][$type]);
351             }
352           }
353           $ret = $entries['XML']; 
354         }
355       }
356     }
357     return($ret);
358   }
361   public function FAI_get_classes($name)
362   {
363     $this->reset_error();
364     $xml_msg = "<xml><header>gosa_query_fai_release</header><target>GOSA</target><source>GOSA</source>".
365                   "<where><clause><phrase><release>".$name."</release></phrase></clause></where></xml>";;
366     $ret = array();
367     if($this->connect()){
368       $this->o_sock->write($xml_msg);
369       $str = trim($this->o_sock->read());
371       /* Check if something went wrong while reading */
372       if($this->o_sock->is_error()){
373         $this->set_error($this->o_sock->get_error());
374         return($ret);
375       }
377       $entries = $this->xml_to_array($str);
378       if(isset($entries['XML']) && is_array($entries['XML'])){
380         /* Check if returned values represent a valid answer */
381         if(isset($entries['XML'])){
382           if(isset($entries['XML']['ERROR_STRING'])) {
383             $this->set_error($entries['XML']['ERROR_STRING']);
384             new log("debug","GOsa-si", 
385               get_class($this)."::".__FUNCTION__, array($name),
386               "FAILED error was ".$this->get_error());
387             return($ret);
388           }
390           /* Unset header tags */
391           foreach(array("HEADER","SOURCE","TARGET","SESSION_ID") as $type){
392             if(isset($entries['XML'][$type])){
393               unset($entries['XML'][$type]);
394             }
395           }
396           $ret = $entries['XML']; 
397         }
398       }
399     }
400     return($ret);
401   }
404   /*! \brief  Returns an array containing all queued entries.
405     @return Array All queued entries as an array.
406    */
407   public function get_queued_entries($event_types = array("*"),$from=-1,$to=-1,$sort="timestamp DESC")
408   {
409     $this->reset_error();
410     $ret = array();
412     $tags = "";
413     foreach($event_types as $type){
414       $tags .= "<phrase><headertag>".$type."</headertag></phrase>";
415     }
416     if(count($event_types) > 1){
417       $tags = "<connector>or</connector>".$tags;
418     }
419     if(count($event_types)){
420       $tags = "<where><clause>".$tags."</clause></where>";
421     }
423     $xml_msg = 
424       "<xml>
425       <header>gosa_query_jobdb</header>
426       <target>GOSA</target>
427       <source>GOSA</source>
428       ".$tags."
430       <orderby>".$sort."</orderby>";
431     if($from != -1 && $to != -1){
432       $xml_msg.= "
433         <limit>
434         <from>".$from."</from>
435         <to>".$to."</to>
436         </limit>";
437     }
438     $xml_msg.= "
439       </xml>";
441     if($this->connect()){
442       $this->o_sock->write($xml_msg);
443       $str = trim($this->o_sock->read());
445       /* Check if something went wrong while reading */
446       if($this->o_sock->is_error()){
447         $this->set_error($this->o_sock->get_error());
448         return($ret);
449       }
451       $entries = $this->xml_to_array($str);
452       if(isset($entries['XML']) && is_array($entries['XML'])){
454         /* Check if returned values represent a valid answer */
455         if(isset($entries['XML'])){
456           
457           /* Unset header tags */
458           foreach(array("HEADER","SOURCE","TARGET") as $type){
459             unset($entries['XML'][$type]);
460           }
461           $ret = $entries['XML']; 
462         }
463       }
464     }
465     
466     /* Remove session ID. No one is interested in this... */
467     unset($ret['SESSION_ID']);
469     return($ret);
470   }
473   /*! \brief  Checks if the given ids are used queue ids.
474     @param  Array   The ids we want to check..
475     @return Array   An array containing all ids as index and TRUE/FALSE as value. 
476    */
477   public function ids_exist($ids)
478   {
479     if(!is_array($ids)){
480       trigger_error("Requires an array as parameter.");
481       return;
482     }
483     $this->reset_error();
485     $ret = array();
487     $xml_msg = "<xml>
488       <header>gosa_query_jobdb</header>
489       <target>GOSA</target>
490       <source>GOSA</source>
491       <where>
492       <clause>
493       <connector>or</connector>";
494     foreach($ids as $id){
495       $xml_msg .= "<phrase>
496         <operator>eq</operator>
497         <id>".$id."</id>
498         </phrase>";
499     }
500     $xml_msg .= "</clause>
501       </where>
502       </xml>";
504     if($this->connect()){
505       $this->o_sock->write($xml_msg);
506       $str = trim($this->o_sock->read());
508       /* Check if something went wrong while reading */
509       if($this->o_sock->is_error()){
510         $this->set_error($this->o_sock->get_error());
511         return($ret);
512       }
514       $entries = $this->xml_to_array($str);
515       if(isset($entries['XML']) && is_array($entries['XML'])){
516         foreach($entries['XML'] as $entry){
517           if(isset($entry['ID'])){
518             $ret[] = $entry['ID'];
519           }
520         }
521       }
522     }
523     return($ret);
524   }
527   /*! \brief  Returns an entry containing all requested ids.
528     @param  Array   The IDs of the entries we want to return.
529     @return Array   Of the requested entries. 
530    */
531   public function get_entries_by_mac($macs)
532   {
533     if(!is_array($macs)){
534       trigger_error("Requires an array as parameter.");
535       return;
536     }
537     $this->reset_error();
539     $ret = array();
541     $xml_msg = "<xml>
542       <header>gosa_query_jobdb</header>
543       <target>GOSA</target>
544       <source>GOSA</source>
545       <where>
546       <clause>
547       <connector>or</connector>";
548     foreach($macs as $mac){
549       $xml_msg .= "<phrase>
550         <operator>eq</operator>
551         <macaddress>".$mac."</macaddress>
552         </phrase>";
553     }
554     $xml_msg .= "</clause>
555       </where>
556       </xml>";
558     if($this->connect()){
559       $this->o_sock->write($xml_msg);
560       $str = trim($this->o_sock->read());
562       /* Check if something went wrong while reading */
563       if($this->o_sock->is_error()){
564         $this->set_error($this->o_sock->get_error());
565         return($ret);
566       }
568       $entries = $this->xml_to_array($str); 
569       if(isset($entries['XML'])){
570         foreach($entries['XML'] as $name => $entry){
571           if(preg_match("/^ANSWER[0-9]*$/",$name)){
572             $ret[$name] = $entry;
573           }
574         }
575       }
576     }
577     return($ret);
578   }
581   /*! \brief  Returns an entry containing all requested ids.
582     @param  Array   The IDs of the entries we want to return.
583     @return Array   Of the requested entries. 
584    */
585   public function get_entries_by_id($ids)
586   {
587     if(!is_array($ids)){
588       trigger_error("Requires an array as parameter.");
589       return;
590     }
591     $this->reset_error();
593     $ret = array();
595     $xml_msg = "<xml>
596       <header>gosa_query_jobdb</header>
597       <target>GOSA</target>
598       <source>GOSA</source>
599       <where>
600       <clause>
601       <connector>or</connector>";
602     foreach($ids as $id){
603       $xml_msg .= "<phrase>
604         <operator>eq</operator>
605         <id>".$id."</id>
606         </phrase>";
607     }
608     $xml_msg .= "</clause>
609       </where>
610       </xml>";
612     if($this->connect()){
613       $this->o_sock->write($xml_msg);
614       $str = trim($this->o_sock->read());
616       /* Check if something went wrong while reading */
617       if($this->o_sock->is_error()){
618         $this->set_error($this->o_sock->get_error());
619         return($ret);
620       }
622       $entries = $this->xml_to_array($str); 
623       if(isset($entries['XML'])){
624         foreach($entries['XML'] as $name => $entry){
625           if(preg_match("/^ANSWER[0-9]*$/",$name)){
626             $ret[$name] = $entry;
627           }
628         }
629       }
630     }
631     return($ret);
632   }
635   /*! \brief  Checks if the given id is in use.
636     @param  Integer The ID of the entry.
637     @return Boolean TRUE if entry exists. 
638    */
639   public function id_exists($id)
640   {
641     if(!is_numeric($id)){
642       trigger_error("Requires an integer as parameter.");
643       return;
644     }
646     $this->reset_error();
648     $xml_msg = "<xml>
649       <header>gosa_query_jobdb</header>
650       <target>GOSA</target>
651       <source>GOSA</source>
652       <where>
653       <clause>
654       <phrase>
655       <operator>eq</operator>
656       <id>".$id."</id>
657       </phrase>
658       </clause>
659       </where>
660       </xml>";
662     if($this->connect()){
663       $this->o_sock->write($xml_msg);
664       $str = trim($this->o_sock->read());
666       /* Check if something went wrong while reading */
667       if($this->o_sock->is_error()){
668         $this->set_error($this->o_sock->get_error());
669         return(FALSE);
670       }
672       $entries = $this->xml_to_array($str); 
673       if( isset($entries['XML']['HEADER']) && 
674           $entries['XML']['HEADER']=="answer" && 
675           isset($entries['XML']['ANSWER1'])){
676         return(TRUE);
677       }
678     }
679     return(FALSE);
680   }
683   /*! \brief  Returns an entry from the gosaSupportQueue
684     @param  Integer The ID of the entry we want to return.
685     @return Array   Of the requested entry. 
686    */
687   public function get_entry_by_id($id)
688   {
689     if(!is_numeric($id)){
690       trigger_error("Requires an integer as parameter.");
691       return;
692     }
693     $this->reset_error();
694   
695     $ret = array();
696     $xml_msg = "<xml>
697       <header>gosa_query_jobdb</header>
698       <target>GOSA</target>
699       <source>GOSA</source>
700       <where>
701       <clause>
702       <phrase>
703       <operator>eq</operator>
704       <id>".$id."</id>
705       </phrase>
706       </clause>
707       </where>
708       </xml>";
709     if($this->connect()){
710       $this->o_sock->write($xml_msg);
711       $str = trim($this->o_sock->read());
713       /* Check if something went wrong while reading */
714       if($this->o_sock->is_error()){
715         $this->set_error($this->o_sock->get_error());
716         return($ret);
717       }
719       $entries = $this->xml_to_array($str); 
720       if( isset($entries['XML']['HEADER']) &&
721           $entries['XML']['HEADER']=="answer" &&
722           isset($entries['XML']['ANSWER1'])){
723         $ret = $entries['XML']['ANSWER1'];
724       }
725     }
726     return($ret);
727   }
730   /*! \brief  Removes a set of entries from the GOsa support queue. 
731     @param  Array The IDs to remove.
732     @return Boolean True on success.
733    */
734   public function remove_entries($ids)
735   {
736     if(!is_array($ids)){
737       trigger_error("Requires an array as parameter.");
738       return;
739     }
741     $this->reset_error();
743     $ret = array();
745     $xml_msg = "<xml>
746       <header>gosa_delete_jobdb_entry</header>
747       <target>GOSA</target>
748       <source>GOSA</source>
749       <where>
750       <clause>
751       <connector>or</connector>";
752     foreach($ids as $id){
753       $xml_msg .= "<phrase>
754         <operator>eq</operator>
755         <id>".$id."</id>
756         </phrase>";
757     }
758     $xml_msg .= "</clause>
759       </where>
760       </xml>";
762     if($this->connect()){
763       $this->o_sock->write($xml_msg);
764       $str = $this->o_sock->read();
766       /* Check if something went wrong while reading */
767       if($this->o_sock->is_error()){
768         $this->set_error($this->o_sock->get_error());
769         return($ret);
770       }
772       $entries = $this->xml_to_array($str);
773       if(isset($entries['XML']) || isset($entries['COUNT'])){
774         new log("debug","DaemonEvent (IDS) ", "gosaSupportDaemon::remove_entries()", $ids,"SUCCESS");
775         return(TRUE);
776       }else{
777         new log("debug","DaemonEvent (IDS) ", "gosaSupportDaemon::remove_entries()", $ids,"FAILED ".$this->get_error());
778       }
779     }
780     return(FALSE);
781   }
785   /*! \brief  Removes an entry from the GOsa support queue. 
786     @param  Integer The ID of the entry we want to remove.
787     @return Boolean True on success.
788    */
789   public function remove_entry($id)
790   {
791     return($this->remove_entries(array($id)));
792   }
795   /*! \brief  Parses the given xml string into an array 
796     @param  String XML string  
797     @return Array Returns an array containing the xml structure. 
798    */
799   private function xml_to_array($xml)
800   {
801     $params = array();
802     $level = array();
803     $parser  = xml_parser_create_ns();
804     xml_parse_into_struct($parser, $xml, $vals, $index);
806     $err_id = xml_get_error_code($parser);
807     if($err_id){
808       xml_parser_free($parser);
809     }else{
810       xml_parser_free($parser);
812       foreach ($vals as $xml_elem) {
813         if ($xml_elem['type'] == 'open') {
814           if (array_key_exists('attributes',$xml_elem)) {
815             list($level[$xml_elem['level']],$extra) = array_values($xml_elem['attributes']);
816           } else {
817             $level[$xml_elem['level']] = $xml_elem['tag'];
818           }
819         }
820         if ($xml_elem['type'] == 'complete') {
821           $start_level = 1;
822           $test2 = &$params;
823           while($start_level < $xml_elem['level']) {
824             $test2 = &$test2[$level[$start_level]];
825             $start_level++;
826           }
827           if(!isset($test2[$xml_elem['tag']])){
828             if(isset($xml_elem['value'])){
829               $test2[$xml_elem['tag']] = $xml_elem['value'];
830             }
831           }else{
832             if(!is_array($test2[$xml_elem['tag']])){
833               $test2[$xml_elem['tag']] = array($test2[$xml_elem['tag']]);
834             }
835             $test2[$xml_elem['tag']][] = $xml_elem['value'];
836           }
837         }
838       }
839     }
841     if(!isset($params['XML'])){
842       if (!array_key_exists('XML', $params)){
843         $this->set_error(_("Cannot not parse XML!"));
844       }
845       $params = array("COUNT" => 0);
846     }
848     return($params); 
849   }
852   /*! \brief  Updates an entry with a set of new values, 
853     @param  Integer The ID of the entry, we want to update.
854     @param  Array   The variables to update.   
855     @return Boolean Returns TRUE on success. 
856    */
857   public function update_entries($ids,$data)
858   {
859     $this->reset_error();
860     if(!is_array($ids)){
861       trigger_error("Requires an array as first parameter.");
862       return;
863     }
865     if(!is_array($data)){
866       trigger_error("Requires an array as second parameter.");
867       return;
868     }
870     $attr = "";
871     foreach($data as $key => $value){
872       if(is_array($value)){
873         foreach($value as $sub_value){
874           $attr.= "<$key>".strtolower($sub_value)."</$key>\n";
875         }
876       }else{
877         $attr.= "<$key>".strtolower($value)."</$key>\n";
878       }
879     }
881     $xml_msg = "<xml>
882       <header>gosa_update_status_jobdb_entry</header>
883       <target>GOSA</target>
884       <source>GOSA</source>
885       <where>
886       <clause>
887       <connector>or</connector>";
888     foreach($ids as $id){
889       $xml_msg .= "<phrase>
890         <operator>eq</operator>
891         <id>".$id."</id>
892         </phrase>";
893     }
894     $xml_msg .= "</clause>
895       </where>
896       <update>
897       ".$attr." 
898       </update>
899       </xml>";
901     if($this->connect()){
903       $this->o_sock->write($xml_msg);
904       $str      = trim($this->o_sock->read());
906       /* Check if something went wrong while reading */
907       if($this->o_sock->is_error()){
908         $this->set_error($this->o_sock->get_error());
909         return(FALSE);
910       }
912       $entries = $this->xml_to_array($str);
913       if(isset($entries['XML'])){
914         if(isset($entries['XML']['ERROR_STRING'])) {
915           $this->set_error($entries['XML']['ERROR_STRING']);
916           new log("debug","DaemonEvent (IDS) ", "gosaSupportDaemon::update_entries()", $ids,"FAILED setting (".$attr.") error was ".$this->get_error());
917           return(FALSE);
918         }
919         new log("debug","DaemonEvent (IDS) ", "gosaSupportDaemon::update_entries()", $ids,"SUCCESS");
920         return(TRUE);
921       }
922     }
923     return(FALSE);
924   }
927   /*! \brief  Returns the number of currently queued objects.
928       @return Integer  
929    */
930   public function number_of_queued_entries($event_types)
931   {
932     $tags = "";
933     foreach($event_types as $type){
934       $tags .= "<phrase><headertag>".$type."</headertag></phrase>";
935     }
936     if(count($event_types) > 1){
937       $tags = "<connector>or</connector>".$tags;
938     }
939     if(count($event_types)){
940       $tags = "<where><clause>".$tags."</clause></where>";
941     }
944     $xml_msg =
945       "<xml>".
946       "<header>gosa_query_jobdb</header>".
947       "<target>GOSA</target>".
948       "<source>GOSA</source>".
949       "<select> count ID</select>".
950       $tags.
951       "</xml>";
953     $xml_msg ="<xml><header>gosa_count_jobdb</header><target>GOSA</target><source>GOSA</source></xml>";
954     $this->connect();
955     if($this->connect()){
956       $this->o_sock->write($xml_msg);
957       $str     = trim($this->o_sock->read());
959       /* Check if something went wrong while reading */
960       if($this->o_sock->is_error()){
961         $this->set_error($this->o_sock->get_error());
962         return(0);
963       }
965       $entries = $this->xml_to_array($str);
966       if(isset($entries['XML'])){
967         return($entries['XML']['COUNT']);
968       }
969     }
970     return(-1);
971   } 
974   public function send_data($header, $to, $data= array(), $answer_expected = FALSE)
975   {
976     $xml_message= "";
978     /* Prepare data */
979     foreach ($data as $key => $value){
980       if(is_array($value)){
981         foreach($value as $sub_value){
982           $xml_message.= "<$key>$sub_value</$key>";
983         }
984       }else{
985         $xml_message.= "<$key>$value</$key>";
986       }
987     }
989     /* Multiple targets? */
990     if (!is_array($to)){
991       $to_targets= array($to);
992     } else {
993       $to_targets= $to;
994     }
996     /* Build target strings */
997     $target ="";
998     foreach($to_targets as $to){
999       $target.= "<target>$to</target>";
1000     }
1002     return $this->_send("<xml><header>$header</header><source>GOSA</source>$target".$xml_message."</xml>",$answer_expected);
1003   }
1006   /* Allows simply appending a new DaemonEvent 
1007    */
1008   public function append($event)
1009   {
1010     if(!($event instanceof DaemonEvent)){
1011       return(FALSE);
1012     }
1013   
1014     $this->reset_error();
1016     /* Add to queue if new 
1017      */
1018     if($event->is_new()){
1020       $request_answer = FALSE;
1021       if($event->get_type() == SCHEDULED_EVENT){
1022         $action = $event->get_schedule_action();
1023       }elseif($event->get_type() == TRIGGERED_EVENT){
1024         $action = $event->get_trigger_action();
1025       }else{
1026         trigger_error("Unknown type of queue event given.");
1027         return(FALSE);
1028       }
1030       /* Get event informations, like targets..
1031        */
1032       $targets    = $event->get_targets();
1033       $data       = $event->save();
1035       /* Append an entry for each target 
1036        */
1037       foreach($targets as $target){
1038         $data['macaddress'] = $target;
1039         $this->send_data($action,$target,$data,$request_answer);
1041         if($this->is_error()){
1042           return(FALSE);
1043         }
1044       }
1045       return(TRUE);
1046     }else{
1048       /* Updated edited entry.
1049        */
1050       $id                 = $event->get_id();
1051       $data               = $event->save();
1052       return($this->update_entries(array($id),$data));
1053     }
1055     return(FALSE);
1056   }
1059 /*! \brief  Returns an array containing all queued entries.
1060     @return Array All queued entries as an array.
1061    */
1062   public function _send($data, $answer_expected= FALSE)
1063   {
1064     $this->reset_error();
1065     $ret = array();
1067     if($this->connect()){
1068       $this->o_sock->write($data);
1069       if ($answer_expected){
1070         $str = trim($this->o_sock->read());
1072         /* Check if something went wrong while reading */
1073         if($this->o_sock->is_error()){
1074           $this->set_error($this->o_sock->get_error());
1075           return($ret);
1076         }
1078         $entries = $this->xml_to_array($str);
1079         if(isset($entries['XML']) && is_array($entries['XML'])){
1080           $ret = $entries;
1081           if(isset($entries['XML']['ERROR_STRING'])) {
1082             $this->set_error($entries['XML']['ERROR_STRING']);
1083             new log("debug","DaemonEvent (IDS) ", "gosaSupportDaemon::_send()", array($data=>$data),"FAILED ".$this->get_error());
1084           }elseif(isset($entries['XML']['ERROR'])){
1085             $this->set_error($entries['XML']['ERROR']);
1086             new log("debug","DaemonEvent (IDS) ", "gosaSupportDaemon::_send()", array($data=>$data),"FAILED ".$this->get_error());
1087           }else{
1088             new log("debug","DaemonEvent (IDS) ", "gosaSupportDaemon::_send()", array($data=>$data),"SUCCESS");
1089           }
1090         }
1091       }else{
1092         new log("debug","DaemonEvent (IDS) ", "gosaSupportDaemon::_send()", array($data=>$data),"Fire & forget, not result.! ".$this->get_error());
1093       }
1094     }
1095     return($ret);
1096   }
1099   static function send($header, $to, $data= array(), $answer_expected = FALSE)
1100   {
1101     $xml_message= "";
1103     /* Get communication object */
1104     $d= new gosaSupportDaemon(TRUE,10);
1106     /* Prepare data */
1107     foreach ($data as $key => $value){
1108       if(is_array($value)){
1109         foreach($value as $sub_val){
1110           $xml_message.= "<$key>$sub_value</$key>";
1111         }
1112       }else{
1113         $xml_message.= "<$key>$value</$key>";
1114       }
1115     }
1117     /* Multiple targets? */
1118     if (!is_array($to)){
1119       $to_targets= array($to);
1120     } else {
1121       $to_targets= $to;
1122     }
1124     /* Build target strings */
1125     $target ="";
1126     foreach($to_targets as $to){
1127       $target.= "<target>$to</target>";
1128     }
1130     return $d->_send("<xml><header>$header</header><source>GOSA</source>$target".$xml_message."</xml>",$answer_expected);
1131   }
1134   /*! \brief  Removes all jobs from the queue that are tiggered with a specific macAddress.
1135       @param  String  $mac  The mac address for which we want to remove all jobs.      
1136    */
1137   function clean_queue_from_mac($mac)
1138   {
1139     global $config;
1141     /* First of all we have to check which jobs are startet 
1142      *  for $mac 
1143      */
1144     $xml_msg ="<xml><header>gosa_query_jobdb</header><target>GOSA</target><source>GOSA</source><where><clause><phrase><macaddress>".$mac."</macaddress></phrase></clause></where></xml>";  
1145     
1146     new log("debug","DaemonEvent ", "gosaSupportDaemon::clean_queue_from_mac()", array($mac => $mac)," start cleaning.");
1147  
1148     $data = $this->_send($xml_msg,TRUE);
1149     if(is_array($data) && isset($data['XML'])){
1150       $already_aborted = FALSE;
1151       foreach($data['XML']  as $name => $entry){
1152         if(preg_match("/answer[0-9]*/i",$name)){
1153           $entry['STATUS'] = strtoupper($entry['STATUS']);
1154           switch($entry['STATUS']){
1156             case 'PROCESSING' :
1158               /* Send abort event, but only once 
1159                */
1160               if($already_aborted){
1161                 break;
1162               }elseif(class_available("DaemonEvent_faireboot")){
1163                 $already_aborted = TRUE;
1164                 $tmp = new DaemonEvent_faireboot($config);
1165                 $tmp->add_targets(array($mac));
1166                 $tmp->set_type(TRIGGERED_EVENT);
1167                 if(!$this->append($tmp)){
1168                   msg_dialog::display(_("Error"), sprintf(_("Cannot send abort event for entry %s!"),$entry['ID']) , ERROR_DIALOG);
1169                   new log("debug","DaemonEvent ", "gosaSupportDaemon::clean_queue_from_mac()", array($mac => $mac),
1170                       "FAILED, could not send 'DaemonEvent_faireboot' for entry ID (".$entry['ID'].") - ".$this->get_error());
1171                 }else{
1172                   new log("debug","DaemonEvent ", "gosaSupportDaemon::clean_queue_from_mac()", array($mac => $mac),
1173                       "SUCCESS, send 'DaemonEvent_faireboot' for entry ID (".$entry['ID'].")");
1174                 }
1175                 ;break;
1176               }else{
1177                 /* Couldn't find abort event, just remove entry */
1178               }
1180             case 'WAITING':
1181             case 'ERROR':
1182             default :
1183             
1184               /* Simply remove entries from queue. 
1185                *  Failed or waiting events, can be removed without any trouble.
1186                */ 
1187               if(!$this->remove_entries(array($entry['ID']))){
1188                 msg_dialog::display(_("Error"), sprintf(_("Cannot remove entry %s!"),$entry['ID']) , ERROR_DIALOG);
1189               }
1190               ;break;
1191           }
1192     
1193         }
1194       }
1195     }
1196   }
1199   static function ping($target)
1200   {
1201     if (tests::is_mac($target)){
1202       /* Get communication object */
1203       $d= new gosaSupportDaemon(TRUE,0.5);
1204       $answer= $d->_send("<xml><header>gosa_ping</header><source>GOSA</source><target>$target</target></xml>", TRUE);
1205       return (count($answer) ? TRUE:FALSE);
1206     }
1207     return (FALSE);
1208   }
1212   /*! \brief  Returns a list of all configured principals. 
1213               (Uses the GOsa support daemon instead of the ldap database.)
1214       @return Array  A list containing the names of all configured principals.
1215    */
1216   public function krb5_list_principals($server)
1217   {
1218     $res = array();  
1220     /* Prepare request event 
1221      */ 
1222     $xml_msg = 
1223       "<xml>".
1224       "<header>gosa_krb5_list_principals</header>".
1225       "<source>GOSA</source>".
1226       "<target>".$server."</target>".
1227       "</xml>";
1228     
1229     return($this->_send($xml_msg,TRUE));
1230   }
1233   /*! \brief  Returns the configuration settings for a given principal name. 
1234               (Uses the GOsa support daemon instead of the ldap database.)
1235       @pram   String The name of the requested principal. (e.g. peter@EXAMPLE.DE)
1236       @return Array  A list containing the names of all configured principals.
1237    */
1238   public function krb5_get_principal($name)
1239   {
1240     $ret = array();
1242     /* Check if the given name is a valid request value 
1243      */
1244     if(!is_string($name) || empty($name)){
1245       trigger_error("The given principal name is not of type string or it is empty.");
1246       return($ret);
1247     }
1249     /* Prepare request event 
1250      */ 
1251     $xml_msg = 
1252       "<xml>".
1253       "<header>gosa_krb5_get_principal</header>".
1254       "<principal>".$name."</principal>".
1255       "<source>GOSA</source>".
1256       "<target>GOSA</target>".
1257       "</xml>";
1259     return($this->_send($xml_msg,TRUE));
1260   }
1263   /*! \brief  Creates/Updates a given principal with a set of configuration settings.
1264               For a list of configurable attributes have a look at 'krb5_get_principal()'.
1265               (Uses the GOsa support daemon instead of the ldap database.)
1266       @pram   String The name of the principal to update. (e.g. peter@EXAMPLE.DE)
1267       @return Boolean   TRUE on success else FALSE. 
1268    */
1269   public function krb5_set_principal($name,$values)
1270   {
1271     $ret = FALSE;  
1273     /* Check if the given name is a valid request value 
1274      */
1275     if(!is_string($name) || empty($name)){
1276       trigger_error("The given principal name is not of type string or it is empty.");
1277       return($ret);
1278     }
1279     if(!is_array($values) || !count($values)){
1280       trigger_error("No valid update settings given. The parameter must be of type array and must contain at least one entry");
1281       return($ret);
1282     }
1284     $attrs = "";
1285     foreach($values as $name => $value){
1286       if(empty($name) || is_numeric($name)){
1287         trigger_error("Invalid configuration attribute given '".$name."=".$value."'.");
1288         return($ret);
1289       }
1290       $attrs = "<$name>$value</$name>\n";
1291     }
1293     /* Prepare request event 
1294      */ 
1295     $xml_msg = 
1296       "<xml>".
1297       "<header>gosa_krb5_set_principal</header>".
1298       "<principal>".$name."</principal>".
1299       $attrs.
1300       "<source>GOSA</source>".
1301       "<target>GOSA</target>".
1302       "</xml>";
1304     return($this->_send($xml_msg,TRUE));
1305   }
1308   /*! \brief  Removes the given principal.
1309               (Uses the GOsa support daemon instead of the ldap database.)
1310       @pram   String The name of the principal. (e.g. peter@EXAMPLE.DE)
1311       @return Boollean   TRUE on success else FALSE
1312    */
1313   public function krb5_del_principal($name)
1314   {
1315     $ret = FALSE;  
1317     /* Check if the given name is a valid request value 
1318      */
1319     if(!is_string($name) || empty($name)){
1320       trigger_error("The given principal name is not of type string or it is empty.");
1321       return($ret);
1322     }
1324     /* Prepare request event 
1325      */ 
1326     $xml_msg = 
1327       "<xml>".
1328       "<header>gosa_krb5_del_principal</header>".
1329       "<principal>".$name."</principal>".
1330       "<source>GOSA</source>".
1331       "<target>GOSA</target>".
1332       "</xml>";
1334     
1335     return($this->_send($xml_msg,TRUE));
1336   }
1339   /*! \brief  Returns a list of configured password policies.
1340               (Uses the GOsa support daemon instead of the ldap database.)
1341       @return Array A list of all configured password policies.
1342    */
1343   public function krb5_list_policies($server)
1344   {
1345     $res = array();  
1347     /* Prepare request event 
1348      */ 
1349     $xml_msg = 
1350       "<xml>".
1351       "<header>gosa_krb5_list_policies</header>".
1352       "<source>GOSA</source>".
1353       "<target>".$server."</target>".
1354       "</xml>";
1355     
1356     $res = $this->_send($xml_msg,TRUE);
1357     
1358     /* Check if there are results for POLICY 
1359      */
1360     if(isset($res['XML']['POLICY'])){
1361       
1362       /* Ensure that we return an array 
1363        */
1364       $tmp = $res['XML']['POLICY'];
1365       if(!is_array($tmp)){
1366         $tmp = array($tmp);
1367       }
1368       return($tmp);
1369     }else{
1370       return(array());
1371     }
1372   }
1375   /*! \brief  Returns a list of configured password policies.
1376               (Uses the GOsa support daemon instead of the ldap database.)
1377       @return Array The policy settings for the given policy name.
1378    */
1379   public function krb5_get_policy($server,$name)
1380   {
1381     $res = array();  
1383     /* Check if the given name is a valid request value 
1384      */
1385     if(!is_string($name) || empty($name)){
1386       trigger_error("The given policy name is not of type string or it is empty.");
1387       return($ret);
1388     }
1390     /* Check if the given server is a valid mac address
1391      */
1392     if(!tests::is_mac($server)){
1393       trigger_error("The given server address '".$server."' is invalid, it must be a valid mac address");
1394       return($ret);
1395     }
1397     /* Prepare request event 
1398      */ 
1399     $xml_msg = 
1400       "<xml>".
1401       "<header>gosa_krb5_get_policy</header>".
1402       "<policy>".$name."</policy>".
1403       "<source>GOSA</source>".
1404       "<target>".$server."</target>".
1405       "</xml>";
1407     /* Possible attributes */
1408     $attrs = array("MASK","POLICY","PW_HISTORY_NUM","PW_MAX_LIFE",
1409         "PW_MIN_CLASSES","PW_MIN_LENGTH","PW_MIN_LIFE","POLICY_REFCNT");
1411   
1412     $tmp = $this->_send($xml_msg,TRUE);
1413     if(isset($tmp['XML'])){
1414       foreach($attrs as $attr){
1415         if(isset($tmp['XML'][$attr])){
1416           $ret[$attr] = $tmp['XML'][$attr];
1417         }else{
1418           $ret[$attr] = "";
1419         }
1420       }
1421     }
1422     return($ret);
1423   }
1425   
1426   /*! \brief  Creates a new policy with a given set of configuration settings.
1427               For a list of configurable attributes have a look at 'krb5_get_policy()'.
1428               (Uses the GOsa support daemon instead of the ldap database.)
1429       @pram   String The name of the policy to update.
1430       @pram   Array  The attributes to update
1431       @return Boolean   TRUE on success else FALSE. 
1432    */
1433   public function krb5_add_policy($server,$name,$values)
1434   {
1435     $ret = FALSE;  
1437     /* Check if the given name is a valid request value 
1438      */
1439     if(!is_string($name) || empty($name)){
1440       trigger_error("The given policy name is not of type string or it is empty.");
1441       return($ret);
1442     }
1443     if(!is_array($values) || !count($values)){
1444       trigger_error("No valid policy settings given. The parameter must be of type array and must contain at least one entry");
1445       return($ret);
1446     }
1448     /* Check if the given server is a valid mac address
1449      */
1450     if(!tests::is_mac($server)){
1451       trigger_error("The given server address '".$server."' is invalid, it must be a valid mac address");
1452       return($ret);
1453     }
1456     /* Transform array into <xml>
1457      */
1458     $attrs = "";
1459     foreach($values as $id => $value){
1460       if(empty($id) || is_numeric($id)){
1461         trigger_error("Invalid policy configuration attribute given '".$id."=".$value."'.");
1462         return($ret);
1463       }
1464       $attrs.= "<$id>$value</$id>\n";
1465     }
1467     /* Prepare request event 
1468      */ 
1469     $xml_msg = 
1470       "<xml>".
1471       "<header>gosa_krb5_create_policy</header>".
1472       "<policy>".$name."</policy>".
1473       $attrs.
1474       "<source>GOSA</source>".
1475       "<target>".$server."</target>".
1476       "</xml>";
1478     return($this->_send($xml_msg,TRUE) == TRUE && !$this->is_error());
1479   }
1482   /*! \brief  Updates a given policy with a set of configuration settings.
1483               For a list of configurable attributes have a look at 'krb5_get_policy()'.
1484               (Uses the GOsa support daemon instead of the ldap database.)
1485       @pram   String The name of the policy to update.
1486       @return Boolean   TRUE on success else FALSE. 
1487    */
1488   public function krb5_set_policy($server,$name,$values)
1489   {
1490     $ret = FALSE;  
1492     /* Check if the given name is a valid request value 
1493      */
1494     if(!is_string($name) || empty($name)){
1495       trigger_error("The given policy name is not of type string or it is empty.");
1496       return($ret);
1497     }
1498     if(!is_array($values) || !count($values)){
1499       trigger_error("No valid policy settings given. The parameter must be of type array and must contain at least one entry");
1500       return($ret);
1501     }
1503     /* Check if the given server is a valid mac address
1504      */
1505     if(!tests::is_mac($server)){
1506       trigger_error("The given server address '".$server."' is invalid, it must be a valid mac address");
1507       return($ret);
1508     }
1510     /* Transform array into <xml>
1511      */
1512     $attrs = "";
1513     foreach($values as $id => $value){
1514       if(preg_match("/^policy$/i",$id)) continue;
1515       if(empty($id) || is_numeric($id)){
1516         trigger_error("Invalid policy configuration attribute given '".$id."=".$value."'.");
1517         return($ret);
1518       }
1519       $attrs.= "<$id>$value</$id>\n";
1520     }
1522     /* Prepare request event 
1523      */ 
1524     $xml_msg = 
1525       "<xml>".
1526       "<header>gosa_krb5_modify_policy</header>".
1527       "<policy>".$name."</policy>".
1528       $attrs.
1529       "<source>GOSA</source>".
1530       "<target>".$server."</target>".
1531       "</xml>";
1533     return($this->_send($xml_msg,TRUE) == TRUE && !$this->is_error());
1534   }
1536   
1537   /*! \brief  Removes the given password policy. 
1538               (Uses the GOsa support daemon instead of the ldap database.)
1539       @return Boolean  TRUE on success else FALSE
1540    */
1541   public function krb5_del_policy($name)
1542   {
1543     $ret = FALSE;
1545     /* Check if the given name is a valid request value 
1546      */
1547     if(!is_string($name) || empty($name)){
1548       trigger_error("The given policy name is not of type string or it is empty.");
1549       return($ret);
1550     }
1552     /* Prepare request event 
1553      */ 
1554     $xml_msg = 
1555       "<xml>".
1556       "<header>gosa_krb5_del_policy</header>".
1557       "<policy>".$name."</policy>".
1558       "<source>GOSA</source>".
1559       "<target>GOSA</target>".
1560       "</xml>";
1561     return($this->_send($xml_msg,TRUE) == TRUE && !$this->is_error());
1562   }
1566 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
1567 ?>