d46e4e3b1fdb2569d83b21f5df33dc8436267b13
[gosa.git] / gosa-plugins / heimdal / 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;
35 var $si_error_msg = "";
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 $flags = array(
46 "DISALLOW_POSTDATED" , // Pohibit postdated tickets
47 "DISALLOW_FORWARDABLE", // Prohibit forwardable tickets
48 "DISALLOW_RENEWABLE" , // Prohibit renewable tickets
49 "DISALLOW_PROXIABLE" , // Disallow proxiable tickets
50 "DISALLOW_DUP_SKEY" , // Disallow user to user authentification
51 "REQUIRES_PRE_AUTH" , // Preauthentication required
52 "REQUIRES_HW_AUTH" , // Hardware preauthentication
53 "DISALLOW_SVR" , // Prohibit issuance of service tickets
54 "DISALLOW_TGT_BASED" , // Disallow Ticket-Granting Service
55 "DISALLOW_ALL_TIX" , // Forbid ticket issuance
56 "REQUIRES_PWCHANGE" , // Force a password change
57 "PWCHANGE_SERVICE" ); // Password change service
59 var $readonly = array(
60 "FAIL_AUTH_COUNT", // The number of failed logins
61 "KVNO", // Key version number
62 "LAST_FAILED", // Last failed login time
63 "LAST_PWD_CHANGE", // Password last change time
64 "LAST_SUCCESS", // Last successful login
65 "MOD_DATE"); // Last modification time
68 var $POLICY = "";
69 var $POLICIES = array(); // Policies provided by the corrently selected realm/server
71 var $PRINC_EXPIRE_TIME = 0;
72 var $PW_EXPIRATION = 0;
73 var $PRINC_EXPIRE_TIME_clear = TRUE;
74 var $PW_EXPIRATION_clear = TRUE;
75 var $MAX_LIFE = 0;
76 var $MAX_RENEWABLE_LIFE = 0;
77 var $MASK = "";
79 var $DISALLOW_POSTDATED = FALSE;
80 var $DISALLOW_FORWARDABLE = FALSE;
81 var $DISALLOW_RENEWABLE = FALSE;
82 var $DISALLOW_PROXIABLE = FALSE;
83 var $DISALLOW_DUP_SKEY = FALSE;
84 var $REQUIRES_PRE_AUTH = FALSE;
85 var $REQUIRES_HW_AUTH = FALSE;
86 var $DISALLOW_SVR = FALSE;
87 var $DISALLOW_TGT_BASED = FALSE;
88 var $DISALLOW_ALL_TIX = FALSE;
89 var $REQUIRES_PWCHANGE = FALSE;
90 var $PWCHANGE_SERVICE = FALSE;
92 var $FAIL_AUTH_COUNT = 0;
93 var $KVNO = "";
94 var $LAST_FAILED = 0;
95 var $LAST_PWD_CHANGE = 0;
96 var $LAST_SUCCESS = 0;
97 var $MOD_DATE = 0;
99 function __construct(&$config,$dn = "new")
100 {
101 $this->config= $config;
102 $this->parent_dn = $dn;
104 /* No config object given, this may be the case
105 if there is only a is_available() request triggered.
106 */
107 if(!is_object($config)){
108 return;
109 }
111 /* Keep cache until we try to configure a principal
112 */
113 if($dn != "new" && $dn != ""){
114 session::un_set("MIT_CACHE");
115 }
117 /* Get a list of all kerberos servers, defined in ldap
118 and get a list of principals they are providing.
119 */
120 $ldap = $this->config->get_ldap_link();
121 $ldap->cd($this->config->current['BASE']);
122 $ldap->search("(&(objectClass=goServer)(objectClass=goKrbServer))",array("goKrbRealm","cn","description","macAddress"));
123 $this->server_list = array();
124 while($attrs = $ldap->fetch()){
125 if(!isset($attrs['macAddress'][0])) continue;
126 if(!isset($attrs['description'][0])) $attrs['description'][0] ="";
128 $principals = $this->load_principals_for_server($attrs['macAddress'][0]);
130 /* Create Realm/Server/Principal mapping.
131 */
132 foreach($principals as $principal){
133 $this->map["PRINCIPAL_SERVER"][$principal] = $attrs['cn'][0];
134 $this->map["PRINCIPAL_REALM"] [$principal] = $attrs['goKrbRealm'][0];
135 }
136 $this->map["SERVER_REALM"][$attrs['cn'][0]] = $attrs['goKrbRealm'][0];
137 $this->map["REALM_SERVER"][$attrs['goKrbRealm'][0]] = $attrs['cn'][0];
139 /* Create Server list
140 */
141 $this->server_list[$attrs['cn'][0]] = array("macAddress" => $attrs['macAddress'][0],
142 "description"=> $attrs['description'][0],
143 "dn" => $attrs['dn'],
144 "principals" => $principals,
145 "goKrbRealm" => $attrs['goKrbRealm'][0],
146 "cn" => $attrs['cn'][0]);
147 }
149 /* Load object data from ldap && initialize this class
150 */
151 $this->is_new = TRUE;
152 if($dn != "new" && $dn != ""){
153 $ldap = $this->config->get_ldap_link();
154 $ldap->cd($dn);
155 $ldap->cat($dn);
156 $this->attrs = $ldap->fetch();
157 if(isset($this->attrs['userPassword'])){
159 $p_name = preg_replace("/^\{".$this->get_hash_name()."\}/","",$this->attrs['userPassword'][0]);
161 /* Try to detect server our principal is configured on
162 */
163 if($this->map['PRINCIPAL_SERVER'][$p_name]){
164 $server= $this->map['PRINCIPAL_SERVER'][$p_name];
165 $this->goKrbRealm = $this->map['SERVER_REALM'][$server];
166 $this->principal = $p_name;
168 /* Load policies */
169 $server_name = $this->map['REALM_SERVER'][$this->goKrbRealm];
170 $server_mac = $this->server_list[$server_name]['macAddress'];
171 $this->POLICIES = $this->load_policies_for_server($server_mac);
173 /* Load principal */
174 $this->load_principal($this->server_list[$server]['macAddress'],$p_name);
175 $this->is_new = FALSE;
176 }
177 }
178 }
179 }
182 /*! \brief Load this plugin with the values of the given principal
183 @param String The macAddress of the kerberos server.
184 @param String The name of the principal to load.
185 */
186 public function load_principal($server,$name)
187 {
188 $o = new gosaSupportDaemon();
189 $tmp = array();
190 $tmp = $o->krb5_get_principal($server,$name);
191 if($o->is_error()){
193 $this->si_error = TRUE;
194 $this->si_error_msg = $o->get_error();
195 msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);
196 }else{
198 /* Load flags
199 */
200 if(isset($tmp['ATTRIBUTES'])){
201 foreach($this->flags as $flag){
202 if(in_array($flag,$tmp['ATTRIBUTES'])){
203 $this->$flag = TRUE;
204 }
205 }
206 }
208 /* Load readonly attributes
209 */
210 foreach($this->readonly as $attr){
211 if(isset($tmp[$attr])){
212 $this->$flag = $tmp[$attr];
213 }
214 }
216 /* Load modifyable attributes
217 */
218 foreach($this->values as $attr){
219 if(isset($tmp[$attr])){
220 $this->$flag = $tmp[$attr];
221 }
222 }
223 }
224 }
227 /*! \brief get list of all configured principals
228 for a given server.
229 The results will cached.
230 */
231 public function load_principals_for_server($server)
232 {
233 if(!session::is_set("MIT_PRINCIPAL_CACHE")){
234 session::set("MIT_PRINCIPAL_CACHE",array());
235 }
236 $cache = session::get("MIT_PRINCIPAL_CACHE");
237 if(!isset($cache[$server])){
238 $o = new gosaSupportDaemon();
239 $tmp = $o->krb5_list_principals($server);
240 if($o->is_error()){
241 $this->si_error = TRUE;
242 $this->si_error_msg = $o->get_error();
243 msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);
244 }else{
245 $cache[$server] = $tmp;
246 }
247 session::set("MIT_PRINCIPAL_CACHE",$cache);
248 }
249 return($cache[$server]);
250 }
253 /*! \brief get list of all configured policies
254 for a given server.
255 The results will cached.
256 */
257 public function load_policies_for_server($server)
258 {
259 if(!session::is_set("MIT_POLICY_CACHE")){
260 session::set("MIT_POLICY_CACHE",array());
261 }
262 $cache = session::get("MIT_POLICY_CACHE");
263 if(!isset($cache[$server])){
264 $o = new gosaSupportDaemon();
265 $tmp = $o->krb5_list_policies($server);
266 if($o->is_error()){
267 $this->si_error = TRUE;
268 $this->si_error_msg = $o->get_error();
269 msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);
270 }else{
271 $cache[$server] = array();
272 $cache[$server]["_none_"] = _("none");
273 foreach($tmp as $policy){
274 $cache[$server][$policy] = $policy;
275 }
276 ksort($cache[$server]);
277 }
278 session::set("MIT_POLICY_CACHE",$cache);
279 }
280 return($cache[$server]);
281 }
284 /*! \brief Check if this password method is useable.
285 This is the case if there is a si server running and at least one server configured.
286 kerberos support.
287 */
288 function is_available()
289 {
290 $o = new gosaSupportDaemon(FALSE);
291 if(count($this->server_list) && $o->connect()){
292 return TRUE;
293 }
294 return(FALSE);
295 }
298 function generate_hash($pwd)
299 {
300 $mode= "kerberos";
301 if (isset($this->config->current['KRBSASL']) && preg_match('/^true$/i', $this->config->current['KRBSASL'])){
302 $mode= "sasl";
303 }
304 return "{".$mode."}".$this->attrs['uid'][0]."@".$this->goKrbRealm;
305 }
308 function remove_from_parent()
309 {
310 if(!empty($this->principal) && $this->goKrbRealm){
311 $server = $this->map['REALM_SERVER'][$this->goKrbRealm];
312 $o = new gosaSupportDaemon();
313 if(!$o->krb5_del_principal($this->server_list[$server]['macAddress'],$this->principal)){
314 $this->si_error = TRUE;
315 $this->si_error_msg = $o->get_error();
316 msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);
317 }
318 }
319 }
322 function set_password($password)
323 {
324 if(!empty($this->principal) && $this->goKrbRealm){
325 $server = $this->map['REALM_SERVER'][$this->goKrbRealm];
326 $o = new gosaSupportDaemon();
328 echo "Not implemented yet";
329 $attrs = array("password" => $password);
331 # if(!$o->krb5_set_principal($this->server_list[$server]['macAddress'],$this->principal,$attrs)){
332 # msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);
333 # }
334 }
335 }
338 function get_hash_name()
339 {
340 $mode= "kerberos";
341 if (isset($this->config->current['KRBSASL']) && preg_match('/^true$/i', $this->config->current['KRBSASL'])){
342 $mode= "sasl";
343 }
344 return "$mode";
345 }
348 function is_configurable()
349 {
350 return TRUE;
351 }
354 function configure()
355 {
356 $this->save_object();
358 $years = array();
359 $start = date("Y")-1;
360 for($i = $start; $i < ($start +20) ; $i++){
361 $years[$i] = $i;
362 }
363 $month= array();
364 for($i = 1; $i <= 12 ; $i++){
365 $month[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
366 }
367 $days= array();
368 for($i = 1; $i <= 31 ; $i++){
369 $days[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
370 }
371 $hours= array();
372 for($i = 0; $i <= 23 ; $i++){
373 $hours[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
374 }
375 $minutes= array();
376 for($i = 0; $i <= 59 ; $i++){
377 $minutes[str_pad($i,2,"0",STR_PAD_LEFT)] = $i;
378 }
381 /* Cancel heimdal options */
382 if (isset($_POST['pw_abort']) || $this->display == FALSE){
383 $this->display = FALSE;
384 return("");
385 }
387 /* Cancel heimdal options */
388 if (isset($_POST['pw_save'])){
389 $msgs = $this->check();
390 if(count($msgs)){
391 foreach($msgs as $msg){
392 msg_dialog::display(_("Heimdal"),$msg,WARNING_DIALOG);
393 }
394 }else{
395 $this->display = FALSE;
396 return "";
397 }
398 }
401 $smarty = get_smarty();
403 $smarty->assign("si_error",$this->si_error);
404 $smarty->assign("si_error_msg",$this->si_error_msg);
406 $smarty->assign("years",$years);
407 $smarty->assign("month",$month);
408 $smarty->assign("days",$days);
409 $smarty->assign("hours",$hours);
410 $smarty->assign("minutes",$minutes);
412 $smarty->assign("server_list",$this->server_list);
413 $smarty->assign("POLICY" ,$this->POLICY);
414 $smarty->assign("goKrbRealm" , $this->goKrbRealm);
416 $server_name = $this->map['REALM_SERVER'][$this->goKrbRealm];
417 $server_mac = $this->server_list[$server_name]['macAddress'];
418 $this->POLICIES = $this->load_policies_for_server($server_mac);
419 $smarty->assign("POLICIES" ,$this->POLICIES);
421 foreach($this->values as $attr){
422 $smarty->assign($attr ,$this->$attr);
423 }
424 foreach($this->readonly as $attr){
425 $smarty->assign($attr ,$this->$attr);
426 }
427 foreach($this->flags as $attr){
428 $smarty->assign($attr,$this->$attr);
429 }
431 $date_values = array("PRINC_EXPIRE_TIME","PW_EXPIRATION");
432 foreach($date_values as $date_val){
433 $clear = $date_val."_clear";
434 $smarty->assign($date_val."_clear",$this->$clear);
435 $smarty->assign($date_val."_y",substr($this->$date_val,0,4));
436 $smarty->assign($date_val."_m",substr($this->$date_val,4,2));
437 $smarty->assign($date_val."_d",substr($this->$date_val,6,2));
438 $smarty->assign($date_val."_h",substr($this->$date_val,8,2));
439 $smarty->assign($date_val."_i",substr($this->$date_val,10,2));
440 }
443 return($smarty->fetch(get_template_path("pwd_kerberos_mit.tpl")));
444 }
447 function save_object()
448 {
449 /* If the communication with the si server failed,
450 you are able to retry to connect to the server.
451 Here we hanlde those requests.
452 */
453 if(isset($_POST['retry_si'])){
454 $this->si_error= FALSE;
455 $this->si_error_msg= "";
456 session::un_set("MIT_PRINCIPAL_CACHE");
457 session::un_set("MIT_POLICY_CACHE");
458 $this->__construct($this->config,$this->parent_dn);
459 }
461 /* Only handle posts for this plugin, it its content was posted
462 */
463 if(isset($_POST['pwd_heimdal_posted'])){
465 if(isset($_POST['goKrbRealm'])){
466 $this->goKrbRealm = get_post("goKrbRealm");
467 }
469 foreach($this->flags as $attr){
470 $this->$attr = isset($_POST[$attr]);
471 }
473 foreach(array("MAX_LIFE","MAX_RENEWABLE_LIFE","POLICY") as $attr){
474 if(isset($_POST[$attr])){
475 $this->$attr = get_post($attr);
476 }
477 }
479 $date_values = array("PW_EXPIRATION","PRINC_EXPIRE_TIME");
480 foreach($date_values as $date_value){
481 $clear = $date_value."_clear";
482 if(isset($_POST[$date_value."_clear"])){
483 $this->$clear = TRUE;
484 }else{
485 $this->$clear = FALSE;
486 $str = "";
487 foreach(array("y","m","d","h","i") as $val){
488 if(isset($_POST[$date_value."_".$val])){
489 $str .= $_POST[$date_value."_".$val];
490 }
491 }
492 $this->$date_value = $str."Z";
493 }
494 }
495 }
496 }
498 function check()
499 {
500 $message = array();
501 echo "Checks missing";
502 return($message);
503 }
506 function chk_times($str)
507 {
508 if(preg_match("/^([0-9]){12,12}[a-z]$/i",$str)){
509 return(true);
510 }
511 return(false);
512 }
515 function save($dn)
516 {
517 $realm = $this->config->data['SERVERS']['KERBEROS']['REALM'];
519 $ldap = $this->config->get_ldap_link();
520 $ldap->cd($dn);
521 $ldap->cat($dn,array('uid'));
522 $attrs = $ldap->fetch();
523 if(isset($attrs['uid'][0])){
525 /* Get servers mac */
526 $server_name = $this->map['REALM_SERVER'][$this->goKrbRealm];
527 $server_mac = $this->server_list[$server_name]['macAddress'];
529 $uid = $attrs['uid'][0];
530 $principal = $uid."@".strtoupper($this->goKrbRealm);
531 $policy = $this->POLICY;
533 /* Collect flags */
534 $flags = array();
535 $entry = array();
536 foreach($this->flags as $flag){
537 if($this->$flag){
538 $flags[] = $flag;
539 }
540 }
541 if(count($flags)){
542 $entry['ATTRIBUTES'] = $flags;
543 }
545 /* Append other values */
546 foreach($this->values as $attr){
547 if($attr == "POLICY") continue;
548 $entry[$attr] = $this->$attr;
549 }
551 /* Prepare entry to be saved */
552 if($policy != "_none_"){
553 $entry['POLICY'] = $policy;
554 }
556 /* Save principal changes */
557 $o = new gosaSupportDaemon();
558 if($this->is_new){
559 $o->krb5_add_principal($server_mac,$principal,$entry);
560 }else{
561 $o->krb5_set_principal($server_mac,$principal,$entry);
562 }
563 if($o->is_error()){
564 $this->si_error = TRUE;
565 $this->si_error_msg = $o->get_error();
566 msg_dialog::display(_("Service infrastructure"),msgPool::siError($o->get_error()),ERROR_DIALOG);
567 }
568 }
569 }
570 }
571 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
572 ?>