[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 }
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;
114 /* If we have a running SI-Server which support kerberos support
115 skip this ldap based method.
116 Only method can win.
117 */
118 if(class_available("passwordMethodMIT")){
119 $tmp = new passwordMethodMIT($config);
120 if($tmp->is_available()) return(FALSE);
121 }
123 $cmd = "";
124 if($this->config->get_cfg_value("heimdal_keygen") != ""){
125 $cmd = $this->config->get_cfg_value("heimdal_keygen");
126 if(!check_command($cmd)){
127 new msg_dialog(_("Heimdal"), msgPool::cmdinvalid("HEIMDAL_KEYGEN",$cmd,_("Heimdal")),WARNING_DIALOG);
128 }
129 }
130 if(isset($config->data['SERVERS']['KERBEROS']['REALM']) && check_command($cmd)){
131 return TRUE;
132 }else{
133 return FALSE;
134 }
135 }
138 function generate_hash($pwd)
139 {
140 $mode= "kerberos";
141 if ($this->config->get_cfg_value("krbsasl") == "true"){
142 $mode= "sasl";
143 }
145 return "{".$mode."}".$this->attrs['uid'][0]."@".$cfg= $this->config->data['SERVERS']['KERBEROS']['REALM'];
146 }
149 function remove_from_parent()
150 {
151 if($this->is_account && $this->dn != "new"){
152 $ldap = $this->config->get_ldap_link();
153 $ldap->cat($this->dn,array("dn"));
154 if($ldap->count()){
155 $ldap->rmdir($this->dn);
156 if (!$ldap->success()){
157 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $this->dn, LDAP_DEL, get_class()));
158 }
159 }
160 }
161 }
164 function set_password($password)
165 {
166 #TODO
167 # Add or modify kerberos entry below $this->dn
168 # See https://oss.gonicus.de/labs/gosa/ticket/223
169 # Order: create entries, then call the heimdal_keygen hook with the realm (returned by generate_hash)
170 # to let it add the missing kerberos keys.
172 global $config;
173 $cmd = "";
174 if($this->config->get_cfg_value("heimdal_keygen") != ""){
175 $cmd = $this->config->get_cfg_value("heimdal_keygen");
176 if(!check_command($cmd)){
177 new msg_dialog(_("Heimdal"), msgPool::cmdinvalid("HEIMDAL_KEYGEN",$cmd,_("Heimdal")),WARNING_DIALOG);
178 }
179 }
180 if ($cmd != ""){
182 /* Display in error message */
183 $cmdd = $cmd." '".$this->generate_hash($password)."' 'PASSWORD'";
185 /* Execute command and check return value */
186 $cmd = $cmd." '".$this->generate_hash($password)."' '".$password."'" ;
187 exec($cmd,$out,$res);
188 if($res != 0){
189 new msg_dialog(_("Heimdal"), msgPool::cmdexecfailed("HEIMDAL_KEYGEN",$cmd,_("Heimdal")),WARNING_DIALOG);
190 }
191 }
192 return(TRUE);
193 }
196 function get_hash_name()
197 {
198 $mode= "kerberos";
199 if ($this->config->get_cfg_value("krbsasl") == "true"){
200 $mode= "sasl";
201 }
202 return "$mode";
203 }
206 function is_configurable()
207 {
208 return TRUE;
209 }
212 function configure()
213 {
214 $this->save_object();
216 /* Cancel heimdal options */
217 if (isset($_POST['pw_abort'])){
218 return "";
219 }
221 /* Cancel heimdal options */
222 if (isset($_POST['pw_save'])){
223 $msgs = $this->check();
224 if(count($msgs)){
225 foreach($msgs as $msg){
226 msg_dialog::display(_("Heimdal"),$msg,WARNING_DIALOG);
227 }
228 }else{
229 $this->display = FALSE;
230 return "";
231 }
232 }
234 $years = array();
235 $start = date("Y")-1;
236 for($i = $start; $i < ($start +20) ; $i++){
237 $years[$i] = $i;
238 }
239 $month= array();
240 for($i = 1; $i <= 12 ; $i++){
241 $month[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
242 }
243 $days= array();
244 for($i = 1; $i <= 31 ; $i++){
245 $days[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
246 }
247 $hours= array();
248 for($i = 0; $i <= 23 ; $i++){
249 $hours[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
250 }
251 $minutes= array();
252 for($i = 0; $i <= 59 ; $i++){
253 $minutes[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
254 }
257 $smarty = get_smarty();
258 $smarty->assign("years",$years);
259 $smarty->assign("month",$month);
260 $smarty->assign("days",$days);
261 $smarty->assign("hours",$hours);
262 $smarty->assign("minutes",$minutes);
264 $date_values = array("krb5ValidStart","krb5ValidEnd","krb5PasswordEnd");
265 foreach($date_values as $date_val){
266 $clear = $date_val."_clear";
267 $smarty->assign($date_val."_clear",$this->$clear);
268 $smarty->assign($date_val."_y",substr($this->$date_val,0,4));
269 $smarty->assign($date_val."_m",substr($this->$date_val,4,2));
270 $smarty->assign($date_val."_d",substr($this->$date_val,6,2));
271 $smarty->assign($date_val."_h",substr($this->$date_val,8,2));
272 $smarty->assign($date_val."_i",substr($this->$date_val,10,2));
273 }
275 foreach($this->attributes as $attr){
276 $smarty->assign($attr ,$this->$attr);
277 }
278 foreach($this->flag_list as $key => $name){
279 $val = pow(2,$key);
280 if($this->krb5KDCFlags & $val){
281 $smarty->assign("krb5KDCFlags_".$key,TRUE);
282 }else{
283 $smarty->assign("krb5KDCFlags_".$key,FALSE);
284 }
285 }
287 return($smarty->fetch(get_template_path("pwd_heimdal.tpl")));
288 }
291 function save_object()
292 {
293 if(isset($_POST['pwd_heimdal_posted'])){
295 $date_values = array("krb5ValidStart","krb5ValidEnd","krb5PasswordEnd");
296 foreach($date_values as $date_value){
297 $clear = $date_value."_clear";
298 if(isset($_POST[$date_value."_clear"])){
299 $this->$clear = TRUE;
300 }else{
301 $this->$clear = FALSE;
302 $str = "";
303 foreach(array("y","m","d","h","i") as $val){
304 if(isset($_POST[$date_value."_".$val])){
305 $str .= $_POST[$date_value."_".$val];
306 }
307 }
308 $this->$date_value = $str."Z";
309 }
310 }
312 foreach($this->attributes as $attr){
313 if(isset($_POST[$attr])){
314 $this->$attr = get_post($attr);
315 }
316 }
318 $int = "";
319 foreach($this->flag_list as $key => $name){
320 $post = "krb5KDCFlags_".$key;
321 if(isset($_POST[$post])){
322 $int |= pow(2,$key);
323 }
324 }
325 $this->krb5KDCFlags = $int;
326 }
327 }
329 function check()
330 {
331 $message = array();
332 if(!is_numeric($this->krb5MaxLife) && !empty($this->krb5MaxLife)){
333 $message[] = msgPool::invalid(_("Max life"),$this->krb5MaxLife,"/[0-9]/");
334 }
335 if(!is_numeric($this->krb5MaxRenew) && !empty($this->krb5MaxRenew)){
336 $message[] = msgPool::invalid(_("Max renew"),$this->krb5MaxRenew,"/[0-9]/");
337 }
338 if(!$this->krb5ValidStart_clear && !$this->chk_times($this->krb5ValidStart)){
339 $message[] = msgPool::invalid(_("Valid start"),$this->krb5ValidStart,"/[0-9]/");
340 }
341 if(!$this->krb5ValidEnd_clear && !$this->chk_times($this->krb5ValidEnd)){
342 $message[] = msgPool::invalid(_("Valid end"),$this->krb5ValidEnd,"/[0-9]/");
343 }
344 if(!$this->krb5PasswordEnd_clear && !$this->chk_times($this->krb5PasswordEnd)){
345 $message[] = msgPool::invalid(_("Valid password"),$this->krb5PasswordEnd,"/[0-9]/");
346 }
347 return($message);
348 }
351 function chk_times($str)
352 {
353 if(preg_match("/^([0-9]){12,12}[a-z]$/i",$str)){
354 return(true);
355 }
356 return(false);
357 }
360 function save($dn)
361 {
362 $realm = $this->config->data['SERVERS']['KERBEROS']['REALM'];
364 $ldap = $this->config->get_ldap_link();
365 $ldap->cd($dn);
366 $ldap->cat($dn,array('uid'));
367 $attrs = $ldap->fetch();
368 if(isset($attrs['uid'][0])){
370 $uid = $attrs['uid'][0];
371 $name = $uid."@".strtoupper($realm);
372 $dn = "krb5PrincipalName=".$name.",".$dn;
374 $data = array();
375 $data['krb5PrincipalName'] = $name;
376 $data['objectClass'] = array("top","account","krb5Principal","krb5KDCEntry");
377 $data['krb5PrincipalName'] =$name;
378 $data['uid'] = $uid;
379 $data['krb5KeyVersionNumber'] = rand(100000,99999999);
381 if($this->is_account){
382 foreach($this->attributes as $attr){
383 $data[$attr] = array();
384 }
385 }
387 /* Append Flags */
388 $data['krb5KDCFlags'] = $this->krb5KDCFlags;
389 if(!empty($this->krb5MaxLife)){
390 $data['krb5MaxLife'] = $this->krb5MaxLife;
391 }
392 if(!empty($this->krb5MaxRenew)){
393 $data['krb5MaxRenew'] = $this->krb5MaxRenew;
394 }
395 if(!$this->krb5ValidStart_clear){
396 $data['krb5ValidStart'] = $this->krb5ValidStart;
397 }
398 if(!$this->krb5ValidEnd_clear){
399 $data['krb5ValidEnd'] = $this->krb5ValidEnd;
400 }
401 if(!$this->krb5PasswordEnd_clear){
402 $data['krb5PasswordEnd']= $this->krb5PasswordEnd;
403 }
405 /* Add / Updated data */
406 $ldap->cd($dn);
407 if(!$this->is_account){
408 $ldap->add($data);
409 }else{
410 $ldap->modify($data);
411 }
412 if (!$ldap->success()){
413 msg_dialog::display(_("LDAP error"), msgPool::ldaperror($ldap->get_error(), $dn, 0, get_class()));
414 }
415 }
416 }
417 }
419 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
420 ?>