Code

Updated policy stuff for heimdal
[gosa.git] / gosa-plugins / heimdal / admin / systems / services / kerberos / class_password-methods-heimdal.inc
1 <?php
2 /*
3    This code is part of GOsa (https://gosa.gonicus.de)
4    Copyright (C) 2007 Cajus Pollmeier
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  */
22 class passwordMethodheimdal extends passwordMethod
23 {
25   var $krb5MaxLife      = "";
26   var $krb5MaxRenew     = "";
27   var $krb5ValidStart   = "";
28   var $krb5ValidEnd     = "";
29   var $krb5PasswordEnd  = "";
30   var $krb5ValidStart_clear   = TRUE;
31   var $krb5ValidEnd_clear     = TRUE;
32   var $krb5PasswordEnd_clear  = TRUE;
34   var $display = TRUE;
36   var $flag_list = array(
37       "0"=>"initial" , 
38       "1"=>"forwardable" , 
39       "2"=>"proxiable" , 
40       "3"=>"renewable" , 
41       "4"=>"postdate" , 
42       "5"=>"server" , 
43       "6"=>"client" , 
44       "7"=>"invalid" , 
45       "8"=>"require-preauth" , 
46       "9"=>"change-pw" , 
47       "10"=>"require-hwauth" , 
48       "11"=>"ok-as-delegate" , 
49       "12"=>"user-to-user" , 
50       "13"=>"immutable");
51   var $krb5KDCFlags     = 123;
53   var $dn                     = "new";
54   var $parent_dn              = "new";
55   var $attributes             = array("krb5MaxLife","krb5MaxRenew","krb5KDCFlags",
56                                       "krb5ValidStart","krb5ValidEnd","krb5PasswordEnd");
57   var $attrs                  = array();
58   var $is_account             = FALSE;
60         function passwordMethodheimdal(&$config,$dn = "new")  
61         {
62     $this->config= $config;
63     $this->parent_dn = $dn;
65     $this->is_account = FALSE;
66     $this->krb5MaxLife    = 86400;
67     $this->krb5MaxRenew   = 604800;
68     $this->krb5ValidStart = date("Ymd",time())."0000Z";
69     $this->krb5ValidEnd   = date("Ymd",time())."0000Z";
70     $this->krb5PasswordEnd= date("Ymd",time())."0000Z";
72     if(!is_object($config)){
73       return;
74     }  
75     
77     /* Load existing entries */
78     if($dn != "new"){
79       $ldap = $this->config->get_ldap_link();
81       $ldap->cd($dn);
82       $ldap->ls("objectClass=krb5Principal",$dn,array("*"));
83       if($ldap->count()==1){
84         $this->is_account = TRUE;
85         $this->attrs = $ldap->fetch();
86         $this->dn = $this->attrs['dn'];
87         foreach($this->attributes as $attr){
88           if(isset($this->attrs[$attr][0])){
89             $this->$attr = $this->attrs[$attr][0];
90           }else{
91             $this->$attr = "";
92           }
93         }
94         $date_values = array("krb5ValidStart","krb5ValidEnd","krb5PasswordEnd");
95         foreach($date_values as $date_val){
96           $clear = $date_val."_clear";
97           if(empty($this->$date_val)){
98             $this->$clear = TRUE;
99           }else{
100             $this->$clear = FALSE;
101           }
102         }
103       }elseif($ldap->count() >= 2){
104         new msg_dialog(_("Heimdal"),sprintf(_("Error loading heimdal configuration, more than one configuration entry was found for '%s'."),$this->parent_dn));
105       }
106     }
107         }
110         function is_available()
111         {
112     global $config;
113     $cmd = "";
114     if(isset($config->current['HEIMDAL_KEYGEN'])){
115       $cmd = $config->current['HEIMDAL_KEYGEN'];
116       if(!check_command($cmd)){
117         new msg_dialog(_("Heimdal"), msgPool::cmdinvalid("HEIMDAL_KEYGEN",$cmd,_("Heimdal")),WARNING_DIALOG);
118       }
119     }
120     if(isset($this->config->data['MAIN']['HEIMDAL_KEYGEN'])){
121       $cmd = $this->config->data['MAIN']['HEIMDAL_KEYGEN'];
122       if(!check_command($cmd)){
123         new msg_dialog(_("Heimdal"), msgPool::cmdinvalid("HEIMDAL_KEYGEN",$cmd,_("Heimdal")),WARNING_DIALOG);
124       }
125     }
126     if(isset($config->data['SERVERS']['KERBEROS']['REALM']) && check_command($cmd)){
127       return TRUE;
128     }else{
129       return FALSE;
130     }
131   }
134         function generate_hash($pwd)
135         {
136     $mode= "kerberos";
137     if (isset($this->config->current['KRBSASL']) && preg_match('/^true$/i', $this->config->current['KRBSASL'])){
138       $mode= "sasl";
139     }
141     return "{".$mode."}".$this->attrs['uid'][0]."@".$cfg= $this->config->data['SERVERS']['KERBEROS']['REALM'];
142         }
145   function remove_from_parent()
146   {
147     if($this->is_account && $this->dn != "new"){
148       $ldap = $this->config->get_ldap_link();
149       $ldap->cat($this->dn,array("dn"));
150       if($ldap->count()){
151         $ldap->rmdir($this->dn);
152         if (!$ldap->success()){
153           msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
154         }
155       }
156     }
157   }
160   function set_password($password)
161   {
162     #TODO
163     # Add or modify kerberos entry below $this->dn
164     # See https://oss.gonicus.de/labs/gosa/ticket/223
165     # Order: create entries, then call the heimdal_keygen hook with the realm (returned by generate_hash)
166     #        to let it add the missing kerberos keys.
168     global $config;
169     $cmd = "";
170     if(isset($config->current['HEIMDAL_KEYGEN'])){
171       $cmd = $config->current['HEIMDAL_KEYGEN'];
172       if(!check_command($cmd)){
173         new msg_dialog(_("Heimdal"), msgPool::cmdinvalid("HEIMDAL_KEYGEN",$cmd,_("Heimdal")),WARNING_DIALOG);
174       }
175     }
176     if(isset($this->config->data['MAIN']['HEIMDAL_KEYGEN'])){
177       $cmd = $this->config->data['MAIN']['HEIMDAL_KEYGEN'];
178       if(!check_command($cmd)){
179         new msg_dialog(_("Heimdal"), msgPool::cmdinvalid("HEIMDAL_KEYGEN",$cmd,_("Heimdal")),WARNING_DIALOG);
180       }
181     }
182     if ($cmd != ""){
184       /* Display in error message */
185       $cmdd = $cmd." '".$this->generate_hash($password)."' 'PASSWORD'";
187       /* Execute command and check return value */
188       $cmd  = $cmd." '".$this->generate_hash($password)."' '".$password."'" ;
189       exec($cmd,$out,$res);
190       if($res != 0){
191         new msg_dialog(_("Heimdal"), msgPool::cmdexecfailed("HEIMDAL_KEYGEN",$cmd,_("Heimdal")),WARNING_DIALOG);
192       }
193     }
194   }
197   function get_hash_name()
198   {
199     $mode= "kerberos";
200     if (isset($this->config->current['KRBSASL']) && preg_match('/^true$/i', $this->config->current['KRBSASL'])){
201       $mode= "sasl";
202     }
203     return "$mode";
204   }
207   function is_configurable()
208   {
209     return TRUE;
210   }
213   function configure()
214   {
215     $this->save_object();
217     /* Cancel heimdal options */
218     if (isset($_POST['pw_abort'])){
219       return "";
220     }
222     /* Cancel heimdal options */
223     if (isset($_POST['pw_save'])){
224       $msgs = $this->check();
225       if(count($msgs)){
226         foreach($msgs as $msg){
227           msg_dialog::display(_("Heimdal"),$msg,WARNING_DIALOG);
228         }
229       }else{
230         $this->display = FALSE;
231         return "";
232       }
233     }
235     $years = array();
236     $start = date("Y")-1;
237     for($i = $start; $i < ($start +20) ; $i++){
238       $years[$i] = $i;
239     }
240     $month= array();
241     for($i = 1; $i <= 12  ; $i++){
242       $month[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
243     }
244     $days= array();
245     for($i = 1; $i <= 31  ; $i++){
246       $days[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
247     }
248     $hours= array();
249     for($i = 0; $i <= 23  ; $i++){
250       $hours[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
251     }
252     $minutes= array();
253     for($i = 0; $i <= 59  ; $i++){
254       $minutes[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
255     }
256   
258     $smarty = get_smarty();
259     $smarty->assign("years",$years);
260     $smarty->assign("month",$month);
261     $smarty->assign("days",$days);
262     $smarty->assign("hours",$hours);
263     $smarty->assign("minutes",$minutes);
265     $date_values = array("krb5ValidStart","krb5ValidEnd","krb5PasswordEnd");
266     foreach($date_values as $date_val){
267       $clear = $date_val."_clear";
268       $smarty->assign($date_val."_clear",$this->$clear);
269       $smarty->assign($date_val."_y",substr($this->$date_val,0,4));
270       $smarty->assign($date_val."_m",substr($this->$date_val,4,2));
271       $smarty->assign($date_val."_d",substr($this->$date_val,6,2));
272       $smarty->assign($date_val."_h",substr($this->$date_val,8,2));
273       $smarty->assign($date_val."_i",substr($this->$date_val,10,2));
274     }
276     foreach($this->attributes as $attr){
277       $smarty->assign($attr ,$this->$attr);
278     }
279     foreach($this->flag_list as $key => $name){
280       $val = pow(2,$key);
281       if($this->krb5KDCFlags & $val){
282         $smarty->assign("krb5KDCFlags_".$key,TRUE);
283       }else{
284         $smarty->assign("krb5KDCFlags_".$key,FALSE);
285       }
286     }
288     return($smarty->fetch(get_template_path("pwd_heimdal.tpl")));
289   }
291   
292   function save_object()
293   {
294     if(isset($_POST['pwd_heimdal_posted'])){
296       $date_values = array("krb5ValidStart","krb5ValidEnd","krb5PasswordEnd");
297       foreach($date_values as $date_value){
298         $clear = $date_value."_clear";
299         if(isset($_POST[$date_value."_clear"])){
300           $this->$clear = TRUE;
301         }else{
302           $this->$clear = FALSE;
303           $str = "";
304           foreach(array("y","m","d","h","i") as $val){
305             if(isset($_POST[$date_value."_".$val])){
306               $str .= $_POST[$date_value."_".$val]; 
307             }
308           }
309           $this->$date_value = $str."Z";
310         }
311       }
313       foreach($this->attributes as $attr){
314         if(isset($_POST[$attr])){
315           $this->$attr = get_post($attr);
316         }
317       }
318   
319       $int = "";
320       foreach($this->flag_list as $key => $name){
321         $post = "krb5KDCFlags_".$key;
322         if(isset($_POST[$post])){
323           $int |= pow(2,$key);
324         }
325       }
326       $this->krb5KDCFlags = $int;
327     }
328   }
330   function check()
331   {
332     $message = array();
333     if(!is_numeric($this->krb5MaxLife) && !empty($this->krb5MaxLife)){
334       $message[] = msgPool::invalid(_("Max life"),$this->krb5MaxLife,"/[0-9]/");
335     }
336     if(!is_numeric($this->krb5MaxRenew) && !empty($this->krb5MaxRenew)){
337       $message[] = msgPool::invalid(_("Max renew"),$this->krb5MaxRenew,"/[0-9]/");
338     }
339    if(!$this->krb5ValidStart_clear && !$this->chk_times($this->krb5ValidStart)){
340      $message[] = msgPool::invalid(_("Valid start"),$this->krb5ValidStart,"/[0-9]/");
341    }
342    if(!$this->krb5ValidEnd_clear && !$this->chk_times($this->krb5ValidEnd)){
343      $message[] = msgPool::invalid(_("Valid end"),$this->krb5ValidEnd,"/[0-9]/");
344    }
345    if(!$this->krb5PasswordEnd_clear && !$this->chk_times($this->krb5PasswordEnd)){
346      $message[] = msgPool::invalid(_("Valid password"),$this->krb5PasswordEnd,"/[0-9]/");
347    }
348     return($message);
349   }
352   function chk_times($str)
353   {
354     if(preg_match("/^([0-9]){12,12}[a-z]$/i",$str)){
355       return(true);
356     }
357     return(false);
358   }
359  
360  
361   function save($dn)
362   {
363     $realm = $this->config->data['SERVERS']['KERBEROS']['REALM'];
365     $ldap = $this->config->get_ldap_link();
366     $ldap->cd($dn);
367     $ldap->cat($dn,array('uid'));
368     $attrs = $ldap->fetch();
369     if(isset($attrs['uid'][0])){
371       $uid  = $attrs['uid'][0];
372       $name = $uid."@".strtoupper($realm); 
373       $dn   = "krb5PrincipalName=".$name.",".$dn;
375       $data = array();
376       $data['krb5PrincipalName'] = $name;
377       $data['objectClass']  = array("top","account","krb5Principal","krb5KDCEntry");
378       $data['krb5PrincipalName'] =$name;
379       $data['uid'] = $uid;
380       $data['krb5KeyVersionNumber'] = rand(100000,99999999);
382       if($this->is_account){ 
383         foreach($this->attributes as $attr){
384           $data[$attr] = array();
385         }
386       }
388       /* Append Flags */
389       $data['krb5KDCFlags']   = $this->krb5KDCFlags;
390       if(!empty($this->krb5MaxLife)){
391         $data['krb5MaxLife']    = $this->krb5MaxLife;
392       }
393       if(!empty($this->krb5MaxRenew)){
394         $data['krb5MaxRenew']   = $this->krb5MaxRenew;
395       }
396       if(!$this->krb5ValidStart_clear){
397         $data['krb5ValidStart'] = $this->krb5ValidStart;
398       }
399       if(!$this->krb5ValidEnd_clear){
400         $data['krb5ValidEnd']   = $this->krb5ValidEnd;
401       }
402       if(!$this->krb5PasswordEnd_clear){
403         $data['krb5PasswordEnd']= $this->krb5PasswordEnd;
404       }
406       /* Add / Updated data */
407       $ldap->cd($dn);
408       if(!$this->is_account){ 
409         $ldap->add($data);
410       }else{
411         $ldap->modify($data);
412       }
413       if (!$ldap->success()){
414         msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, 0, get_class()));
415       }
416     }
417   }
420 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
421 ?>