Code

Added property class to get_cfg_requests
[gosa.git] / gosa-plugins / mit-krb5 / admin / systems / services / kerberos / class_password-methods-MIT.inc
1 <?php
2 /*
3    This code is part of GOsa (https://gosa.gonicus.de)
4    Copyright (C) 2008 Fabian Hickert
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
21 class passwordMethodMIT extends passwordMethod
22 {
24   var $dn             = "new";   // DN of the current object
25   var $parent_dn      = "new";   // parents DN
26   var $is_account     = FALSE;   // This is TRUE if this object already has a krb extension
27   var $server_list    = array(); // A list with all configured servers
28   var $map            = array(); // Mapping array, maps SERVER-REALM, REALM-SERVER ...
30   var $goKrbRealm     = "";      // The realm name this principal belongs to
31   var $principal      = "";      // The principals name (e.g. user@MY-DOMAIN.SYS)
32   var $is_new         = TRUE;    // Is TRUE if principal is new 
34   var $si_error       = FALSE;   // TRUE is daemon communication failed
35   var $si_error_msg   = "";      // The last error message if above attribute is TRUE.
37   var $values = array(
38       "PRINC_EXPIRE_TIME",      // Expiry date of this principal
39       "PW_EXPIRATION",          // Password expiration 
40       "MAX_LIFE",               // Ticket lifetime
41       "MASK",                   // I'dont know 
42       "MAX_RENEWABLE_LIFE",     // Max ticket lifetime when renewed
43       "POLICY");                // The policy used by this principal
45   var $PRINC_EXPIRE_TIME        = 0;
46   var $PW_EXPIRATION            = 0;
47   var $PRINC_EXPIRE_TIME_clear  = TRUE;
48   var $PW_EXPIRATION_clear      = TRUE;
49   var $MAX_LIFE                 = 36000;
50   var $MAX_RENEWABLE_LIFE       = 604800;
51   var $MASK                     = 0;
53   var $flags = array(
54       "DISALLOW_POSTDATED"    =>0x00000001 ,  // Pohibit postdated tickets
55       "DISALLOW_FORWARDABLE"  =>0x00000002 ,  // Prohibit forwardable tickets
56       "DISALLOW_TGT_BASED"    =>0x00000004 ,  // Disallow Ticket-Granting Service
57       "DISALLOW_RENEWABLE"    =>0x00000008 ,  // Prohibit renewable tickets
58       "DISALLOW_PROXIABLE"    =>0x00000010 ,  // Disallow proxiable tickets
59       "DISALLOW_DUP_SKEY"     =>0x00000020 ,  // Disallow user to user authentification
60       "DISALLOW_ALL_TIX"      =>0x00000040 ,  // Forbid ticket issuance
61       "REQUIRES_PRE_AUTH"     =>0x00000080 ,  // Preauthentication required
62       "REQUIRES_HW_AUTH"      =>0x00000100 ,  // Hardware preauthentication
63       "REQUIRES_PWCHANGE"     =>0x00000200 ,  // Force a password change
64       "UNKNOWN_0x00000400"    =>0x00000400 ,  // ? 
65       "UNKNOWN_0x00000800"    =>0x00000800 ,  // ?
66       "DISALLOW_SVR"          =>0x00001000 ,  // Prohibit issuance of service tickets
67       "PWCHANGE_SERVICE"      =>0x00002000 ,  // Password change service
68       "SUPPORT_DESMD5"        =>0x00004000 ,  // ?
69       "NEW_PRINC"             =>0x00008000 ); // ?
70   
71   var $used_flags = 128;        // Flags, see below
73   var $readonly = array(
74       "FAIL_AUTH_COUNT",        // The number of failed logins 
75       "KVNO",                   // Key version number
76       "LAST_FAILED",            // Last failed login time
77       "LAST_PWD_CHANGE",        // Password last change time
78       "LAST_SUCCESS",           // Last successful login 
79       "MOD_DATE");              // Last modification time
81   var $FAIL_AUTH_COUNT          = 0;
82   var $KVNO                     = "";
83   var $LAST_FAILED              = 0;
84   var $LAST_PWD_CHANGE          = 0;
85   var $LAST_SUCCESS             = 0;
86   var $MOD_DATE                 = 0;
88   var $POLICY                   = "_none_";
89   var $POLICIES                 = array(); // Policies provided by the corrently selected realm/server
91   public function is_locked($config,$dn = "")
92   {
93     return(FALSE);
94   }
96   public function lock_account($config,$dn = "")
97   {
98     return(FALSE);
99   }
101   public function unlock_account($config,$dn = "")
102   {
103     return(FALSE);
104   }
106   public function __construct(&$config,$dn = "new")  
107   {
108     $this->config= $config;
109     $this->parent_dn = $dn;
111     /* No config object given, this may be the case 
112        if there is only a is_available() request triggered.
113      */
114     if(!is_object($this->config)){
115       return;
116     }  
118     /* Keep the cached valued and skip loading principals 
119         from si until this method gets configured.
120      */
121     $skip_si_access = TRUE;
122     if($dn != "new" && $dn != ""){
123       session::un_set("MIT_CACHE");
124       session::un_set("MIT_PRINCIPAL_CACHE");
125       session::un_set("MIT_POLICY_CACHE");
126       $this->clear_cache();
127       $skip_si_access = FALSE;
128     }
130     /* Get a list of all kerberos servers, defined in ldap
131        and get a list of principals they are providing. 
132      */
133     $ldap = $this->config->get_ldap_link();
134     $ldap->cd($this->config->current['BASE']);
135     $ldap->search("(&(objectClass=goServer)(objectClass=goKrbServer))",array("goKrbRealm","cn","description","macAddress"));
136     $this->server_list = array();
137     while($attrs = $ldap->fetch()){
138       if(!isset($attrs['macAddress'][0])) continue;
139       if(!isset($attrs['description'][0])) $attrs['description'][0] ="";
141       if($skip_si_access){
142         $principals = array();
143       }else{
144         $principals = $this->load_principals_for_server($attrs['macAddress'][0]);
145       }
147       /* Create Realm/Server/Principal mapping.
148        */
149       foreach($principals as $principal){
150         $this->map["PRINCIPAL_SERVER"][$principal] = $attrs['cn'][0];
151         $this->map["PRINCIPAL_REALM"] [$principal] = $attrs['goKrbRealm'][0];
152       }
153       $this->map["SERVER_REALM"][$attrs['cn'][0]] = $attrs['goKrbRealm'][0];
154       $this->map["REALM_SERVER"][$attrs['goKrbRealm'][0]] = $attrs['cn'][0];
156       /* Set first realm as selected.  
157        */
158       if($this->goKrbRealm == ""){
159         $this->goKrbRealm = $attrs['goKrbRealm'][0];
160       }
162       /* Create Server list
163        */
164       $this->server_list[$attrs['cn'][0]] = array("macAddress" => $attrs['macAddress'][0],
165           "description"=> $attrs['description'][0],
166           "dn"         => $attrs['dn'],
167           "principals" => $principals,
168           "goKrbRealm" => $attrs['goKrbRealm'][0],
169           "cn"         => $attrs['cn'][0]);
170     }
172     /*  If this methods is initialized with a valid object dn then 
173          load the object data from ldap and the SI daemon && initialize this class.
174      */
175     $this->is_new = TRUE;
176     if(!$skip_si_access){
177       $ldap = $this->config->get_ldap_link();
178       $ldap->cd($dn);
179       $ldap->cat($dn);
180       $this->attrs = $ldap->fetch();
182       /* Set initial pwd hash which take effect if no password method was set yet.  
183          Will be overwritten by the following lines, if the user has already a valid principal.
184        */
185       $this->principal = $this->attrs['uid'][0]."@".$this->goKrbRealm;
187       if(isset($this->attrs['userPassword']) && preg_match("/^\{".$this->get_hash_name()."\}/",$this->attrs['userPassword'][0])){
189         /* Extract principal name out of userPassword attribute 
190          */
191         $p_name = preg_replace("/^\{".$this->get_hash_name()."\}/","",$this->attrs['userPassword'][0]);
193         /* Try to detect server our principal is configured on
194          */
195         if(isset($this->map['PRINCIPAL_SERVER'][$p_name])){
196           $server= $this->map['PRINCIPAL_SERVER'][$p_name];
197           $this->goKrbRealm = $this->map['SERVER_REALM'][$server];
198           $this->principal  = $p_name;
200           /* Load policies */
201           $server_name = $this->map['REALM_SERVER'][$this->goKrbRealm];
202           $server_mac  = $this->server_list[$server_name]['macAddress'];
203           $this->POLICIES = $this->load_policies_for_server($server_mac);
205           /* Load principal */
206           $this->load_principal($this->server_list[$server]['macAddress'],$p_name);
207           $this->is_new = FALSE;
208         }
209       }
210     }
211   }
214   public static function clear_cache()
215   {
216     session::un_set("MIT_CACHE");
217     session::un_set("MIT_PRINCIPAL_CACHE");
218     session::un_set("MIT_POLICY_CACHE");
219   }
222   /*! \brief  Load a specific principal from the si daemon 
223                and initialize this plugin with it.
224     @param  String  The macAddress of the kerberos server.
225     @param  String  The name of the principal to load.
226    */
227   public function load_principal($server,$name)
228   {
229     $o = new gosaSupportDaemon();
230     $tmp = array();
231     $tmp = $o->krb5_get_principal($server,$name);
232   
233     if($o->is_error()){
234       $this->si_error     = TRUE;
235       $this->si_error_msg = sprintf(_("Cannot load principal '%s', from server '%s'!"),$name,$server).":&nbsp;<br>".$o->get_error(); 
236       msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);      
237     }else{
239       /* Load flags 
240        */
241       if(isset($tmp['ATTRIBUTES'])){
242         $this->used_flags = $tmp['ATTRIBUTES'];
243       }
245       /* Load readonly attributes 
246        */
247       foreach($this->readonly as $attr){
248         if(isset($tmp[$attr])){
249           $this->$attr = $tmp[$attr];
250         }
251       } 
253       /* Load modifyable attributes
254        */
255       foreach($this->values as $attr){
256         if(isset($tmp[$attr])){
257           $this->$attr = $tmp[$attr];
258         }
259       } 
261       /* Update time checkboxes 
262        */
263       $date_values = array("PW_EXPIRATION","PRINC_EXPIRE_TIME");
264       foreach($date_values as $value){
265         if(!empty($this->$value)){
266           $clear = $value."_clear";
267           $this->$clear = FALSE;
268         }
269       }
270     }
271   }
274   /*! \brief  Get the list of all configured principals for a given server.
275       @param  String The servers mac address.
276       @return Array A list with all principals
277       The results will cached.  
278    */
279   public function load_principals_for_server($server)
280   {
281     if(!session::is_set("MIT_PRINCIPAL_CACHE")){
282       session::set("MIT_PRINCIPAL_CACHE",array());
283     }
284     $cache = session::get("MIT_PRINCIPAL_CACHE");
285     if(!isset($cache[$server])){
286       $o = new gosaSupportDaemon();
287       if($o->is_configured()){
288         $tmp = $o->krb5_list_principals($server);
289         if($o->is_error()){
290           $this->si_error     = TRUE;
291           $this->si_error_msg = sprintf(_("Cannot load principals from server '%s'!"),$server).":&nbsp;<br>".$o->get_error(); 
292           msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);
293           return(array());
294         }else{
295           $cache[$server] = $tmp;
296         }
297       }
298       session::set("MIT_PRINCIPAL_CACHE",$cache);
299     }
300     return($cache[$server]);
301   }
304   /*! \brief get list of all configured policies
305     for a given server. 
306     The results will cached.  
307    */
308   public function load_policies_for_server($server)
309   {
310     if(!session::is_set("MIT_POLICY_CACHE")){
311       session::set("MIT_POLICY_CACHE",array());
312     }
313     $cache = session::get("MIT_POLICY_CACHE");
314     if(!isset($cache[$server])){
315       $o = new gosaSupportDaemon();
316       $tmp = $o->krb5_list_policies($server);
317       if($o->is_error()){
318         $this->si_error     = TRUE;
319         $this->si_error_msg = sprintf(_("Cannot load policies from server '%s'!"),$server).":&nbsp;<br>".$o->get_error(); 
320         msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);
321         return(array());
322       }else{
323         $cache[$server] = array();
324         $cache[$server]["_none_"] = _("none"); 
325         foreach($tmp as $policy){
326           $cache[$server][$policy] = $policy;
327         }
328         ksort($cache[$server]);
329       }
330       session::set("MIT_POLICY_CACHE",$cache);
331     }
332     return($cache[$server]);
333   }
336   /*! \brief Check if this password method is useable. 
337     This is the case if there is a si server running and at least one server configured.
338     kerberos support. 
339    */ 
340   public function is_available()
341   {
342     global $config;
343   
344     /* No config object given, this may be the case 
345        if there is only a is_available() request triggered.
346      */
347     if(!is_object($config)){
348        return;
349     }
352     $o = new gosaSupportDaemon(FALSE);
354     if(count($this->server_list) && $o->connect() && $o->is_configured()){
355       return TRUE; 
356     }
357     return(FALSE);  
358   }
361   /*! \brief Create the password hash. In this case: {kerberos/sasl}name@RELAM 
362       @param  String  The password -in this case unusued.             
363       @return String  The generated hash
364    */
365   public function generate_hash($pwd = "")
366   {
367     $mode= "kerberos";
369     /* No config object given, this may be the case 
370        if there is only a is_available() request triggered.
371      */
372     if (is_object($this->config) && $this->config->get_cfg_value("core","useSaslForKerberos") == "true"){
373       $mode= "sasl";
374     }
375     return "{".$mode."}".$this->attrs['uid'][0]."@".$this->goKrbRealm;
376   }
378   
379   public function create_template_hash($attrs)
380   {
381     return($this->generate_hash());
382   }
385   /*! \brief  Removes this principal.
386    */
387   public function remove_from_parent()
388   {
389     if(!empty($this->principal) && $this->goKrbRealm){
390       $server = $this->map['REALM_SERVER'][$this->goKrbRealm];
391       $o = new gosaSupportDaemon();
392       if(!$o->krb5_del_principal($this->server_list[$server]['macAddress'],$this->principal)){
393         $this->si_error     = TRUE;
394         $this->si_error_msg = $o->get_error();
395         msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);      
396       }
397     }
398   }
401   /*! \brief  Set a new password for this principal 
402       @param  String The new password.
403    */
404   public function set_password($password)
405   {
406     if(!empty($this->principal) && $this->goKrbRealm){
407       $server = $this->map['REALM_SERVER'][$this->goKrbRealm];
408       $o = new gosaSupportDaemon();
409       if(!$o->krb5_set_password($this->server_list[$server]['macAddress'],$this->principal,$password)){
410         msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);      
411         return(FALSE);
412       }
413     }
414     return(TRUE);
415   }
418   /*! \brief  Return the hash name of this mehtod,  e.g. to identify methods.
419       @return String  The hash used by this method.
420     */
421   public function get_hash_name()
422   {
423     $mode= "kerberos";
425     /* No config object given, this may be the case 
426        if there is only a is_available() request triggered.
427      */
428     if (is_object($this->config) && $this->config->get_cfg_value("core","useSaslForKerberos") == "true"){
429       $mode= "sasl";
430     }
431     return "$mode";
432   }
435   /*! \brief  Returns TRUE if this method is configurable else FALSE
436       @retrun Boolena TRUE if configurable, else FALSE.
437    */
438   public function is_configurable()
439   {
440     return TRUE;
441   }
444   /*! \brief  Additional info displayed in the users password method drop down.
445       @retunr String  Additional password method info.
446    */
447   public function get_description()
448   {
449     return(_("Daemon based"));
450   }
453   /*! \brief  Display a HTML based configuration dialog for this plugin
454       @return String  HTML.
455    */
456   public function configure()
457   {
458     $this->save_object();
460     $years = array();
461     $start = date("Y")-1;
462     for($i = $start; $i < ($start +20) ; $i++){
463       $years[$i] = $i;
464     }
465     $month= array();
466     for($i = 1; $i <= 12  ; $i++){
467       $month[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
468     }
469     $days= array();
470     for($i = 1; $i <= 31  ; $i++){
471       $days[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
472     }
473     $hours= array();
474     for($i = 0; $i <= 23  ; $i++){
475       $hours[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
476     }
477     $minutes= array();
478     for($i = 0; $i <= 59  ; $i++){
479       $minutes[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
480     }
483     /* Cancel heimdal options */
484     if (isset($_POST['pw_abort']) || $this->display == FALSE){
485       $this->display = FALSE;
486       return("");
487     }
489     /* Cancel heimdal options */
490     if (isset($_POST['pw_save'])){
491       $msgs = $this->check();
492       if(count($msgs)){
493         foreach($msgs as $msg){
494           msg_dialog::display(_("Kerberos"),$msg,WARNING_DIALOG);
495         }
496       }else{
497         $this->display = FALSE;
498         return "";
499       }
500     }
502     $smarty = get_smarty();
503     $smarty->assign("si_error",$this->si_error);
504     $smarty->assign("si_error_msg",$this->si_error_msg);
505     $smarty->assign("years",$years);
506     $smarty->assign("month",$month);
507     $smarty->assign("days",$days);
508     $smarty->assign("hours",$hours);
509     $smarty->assign("minutes",$minutes);
510     $smarty->assign("server_list",$this->server_list);
511     $smarty->assign("POLICY"  ,$this->POLICY);
512     $smarty->assign("goKrbRealm" , $this->goKrbRealm);
513     $server_name = $this->map['REALM_SERVER'][$this->goKrbRealm];
514     $server_mac  = $this->server_list[$server_name]['macAddress'];
515     $this->POLICIES = $this->load_policies_for_server($server_mac);
516     $smarty->assign("POLICIES"  ,$this->POLICIES);
518     foreach($this->values as $attr){
519       $smarty->assign($attr ,$this->$attr);
520     }
521     foreach($this->readonly as $attr){
522       $smarty->assign($attr ,$this->$attr);
523     }
524     foreach($this->flags as $attr => $hex){
525       $smarty->assign($attr, ($this->used_flags & $hex ));
526     }
528     $date_values = array("PRINC_EXPIRE_TIME","PW_EXPIRATION");
529     foreach($date_values as $date_val){
530       $clear = $date_val."_clear";
531       $smarty->assign($date_val."_clear",$this->$clear);
532       $smarty->assign($date_val."_y",date("Y",$this->$date_val));
533       $smarty->assign($date_val."_m",date("m",$this->$date_val));
534       $smarty->assign($date_val."_d",date("d",$this->$date_val));
535       $smarty->assign($date_val."_h",date("h",$this->$date_val));
536       $smarty->assign($date_val."_i",date("i",$this->$date_val));
537     }
539     return($smarty->fetch(get_template_path("pwd_kerberos_mit.tpl",TRUE,dirname(__FILE__))));
540   }
543   /*! \brief  Saves all relevant HTML posts for this plugin
544    */
545   public function save_object()
546   {
547     /* If the communication with the si server failed, 
548         you are able to retry to connect to the server.
549        Here we hanlde those requests.
550      */
551     if(isset($_POST['retry_si'])){
552       $this->si_error= FALSE;
553       $this->si_error_msg= "";
554       session::un_set("MIT_PRINCIPAL_CACHE");
555       session::un_set("MIT_POLICY_CACHE");
556       $this->__construct($this->config,$this->parent_dn);
557     }
559     /* Only handle posts for this plugin, it its content was posted
560      */
561     if(isset($_POST['pwd_heimdal_posted'])){
563       if(isset($_POST['goKrbRealm'])){
564         $this->goKrbRealm = get_post("goKrbRealm");
565       }
567       $this->used_flags = 0;
568       foreach($this->flags as $attr => $hex){
569         if(isset($_POST[$attr])){
570           $this->used_flags |= $hex; 
571         }
572       }
574       foreach(array("MAX_LIFE","MAX_RENEWABLE_LIFE","POLICY") as $attr){
575         if(isset($_POST[$attr])){
576           $this->$attr = get_post($attr);
577         }
578       }
580       $date_values = array("PW_EXPIRATION","PRINC_EXPIRE_TIME");
581       foreach($date_values as $date_value){
582         $clear = $date_value."_clear";
583         if(isset($_POST[$date_value."_clear"])){
584           $this->$clear = TRUE;
585         }else{
586           $this->$clear = FALSE;
587           $this->$date_value = gmmktime(  
588               $_POST[$date_value."_h"],
589               $_POST[$date_value."_i"],
590               0,
591               $_POST[$date_value."_m"],
592               $_POST[$date_value."_d"],
593               $_POST[$date_value."_y"]);
594         }
595       }
596     }
597   }
600   /*! \brief  Checks the values specified in the configuration dialog. 
601       @return Array Containing all error messages.
602    */
603   public function check()
604   {
605     $message = array();
607     if(!preg_match("/^[0-9]*$/",$this->MAX_LIFE)){
608       $message[] = msgPool::invalid(_("Ticket max life"),$this->MAX_LIFE,"/[0-9]/");
609     }
610     if(!preg_match("/^[0-9]*$/",$this->MAX_RENEWABLE_LIFE)){
611       $message[] = msgPool::invalid(_("Ticket max renew"),$this->MAX_RENEWABLE_LIFE,"/[0-9]/");
612     }
613     return($message);
614   }
617   /*! \brief  Adapt account settings from given dn 
618    */ 
619   public function adapt_from_template ($dn)
620   {
621     $source = new passwordMethodMIT($this->config,$dn);
622     $attrs = array("PRINC_EXPIRE_TIME","PW_EXPIRATION","POLICY","MAX_LIFE","MAX_RENEWABLE_LIFE","MASK","used_flags");
623      foreach($attrs as $attr){
624       $this->$attr = $source->$attr;
625     }
626   }
629   /*! \brief Saves changes back to the SI daemon.
630    */
631   public function save($dn)
632   {
633     $ldap = $this->config->get_ldap_link();
634     $ldap->cd($dn);
635     $ldap->cat($dn,array('uid'));
636     $attrs = $ldap->fetch();
638     if(isset($attrs['uid'][0])){
640       /* Get servers mac */
641       $server_name = $this->map['REALM_SERVER'][$this->goKrbRealm];
642       $server_mac  = $this->server_list[$server_name]['macAddress'];
644       $uid       = $attrs['uid'][0];
645       $principal = $uid."@".strtoupper($this->goKrbRealm); 
646       $policy    = $this->POLICY;
648       /* Collect flags */
649       $flags = array();
650       $entry = array();
652       $entry['ATTRIBUTES'] = $this->used_flags;
654       /* Append other values */
655       foreach($this->values as $attr){
656         if($attr == "POLICY") continue;
657         $entry[$attr] = $this->$attr;
658       }
660       /* Prepare entry to be saved */
661       if($policy != "_none_"){
662         $entry['POLICY'] = $policy;
663       }
665       /* Set date values 
666        */
667      $date_values = array("PW_EXPIRATION","PRINC_EXPIRE_TIME");
668       foreach($date_values as $value){
669         $clear = $value."_clear";
670         if($this->$clear){
671           $entry[$value] = 0;
672         }
673       }    
676       /* Save principal changes */
677       $o = new gosaSupportDaemon();
678       if(in_array($principal,$this->server_list[$server_name]['principals'])){
679         $this->is_new = FALSE;
680       }
682       if($this->is_new){
683         $o->krb5_add_principal($server_mac,$principal,$entry);
684       }else{
685         $o->krb5_set_principal($server_mac,$principal,$entry);
686       }
687       if($o->is_error()){
688         $this->si_error     = TRUE;
689         $this->si_error_msg = $o->get_error();
690         msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);      
691       }
692     }
693   }
695   
698 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
699 ?>