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 = "";
31 var $display = TRUE;
33 var $flag_list = array(
34 "0"=>"initial" ,
35 "1"=>"forwardable" ,
36 "2"=>"proxiable" ,
37 "3"=>"renewable" ,
38 "4"=>"postdate" ,
39 "5"=>"server" ,
40 "6"=>"client" ,
41 "7"=>"invalid" ,
42 "8"=>"require-preauth" ,
43 "9"=>"change-pw" ,
44 "10"=>"require-hwauth" ,
45 "11"=>"ok-as-delegate" ,
46 "12"=>"user-to-user" ,
47 "13"=>"immutable");
48 var $krb5KDCFlags = 123;
50 var $dn = "new";
51 var $parent_dn = "new";
52 var $attributes = array("krb5MaxLife","krb5MaxRenew","krb5KDCFlags",
53 "krb5ValidStart","krb5ValidEnd","krb5PasswordEnd");
54 var $attrs = array();
55 var $is_account = FALSE;
57 function passwordMethodheimdal(&$config,$dn = "new")
58 {
59 $this->config= $config;
60 $this->parent_dn = $dn;
62 /* Load existing entries */
63 $this->krb5MaxLife = "86400";
64 $this->krb5MaxRenew = "604800";
65 if($dn == "new"){
66 $this->is_account = FALSE;
67 }else{
68 $ldap = $this->config->get_ldap_link();
69 $ldap->cd($dn);
70 $ldap->ls("objectClass=krb5Principal",$dn,array("*"));
71 if($ldap->count()==1){
72 $this->is_account = TRUE;
73 $this->attrs = $ldap->fetch();
74 $this->dn = $this->attrs['dn'];
75 foreach($this->attributes as $attr){
76 if(isset($this->attrs[$attr][0])){
77 $this->$attr = $this->attrs[$attr][0];
78 }
79 }
80 }elseif($ldap->count() >= 2){
81 new msg_dialog(_("Heimdal"),sprintf(_("Error loading heimdal configuration, more than one configuration entry was found for '%s'."),$this->parent_dn));
82 }
83 }
84 }
87 function is_available()
88 {
89 global $config;
90 $cmd = "";
91 if(isset($config->current['HEIMDAL_KEYGEN'])){
92 $cmd = $config->current['HEIMDAL_KEYGEN'];
93 if(!check_command($cmd)){
94 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' is not a valid command."),$cmd),WARNING_DIALOG);
95 }
96 }
97 if(isset($this->config->data['MAIN']['HEIMDAL_KEYGEN'])){
98 $cmd = $this->config->data['MAIN']['HEIMDAL_KEYGEN'];
99 if(!check_command($cmd)){
100 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' is not a valid command."),$cmd),WARNING_DIALOG);
101 }
102 }
103 if(isset($config->data['SERVERS']['KERBEROS']['REALM']) && check_command($cmd)){
104 return TRUE;
105 }else{
106 return FALSE;
107 }
108 }
111 function generate_hash($pwd)
112 {
113 $mode= "kerberos";
114 if (isset($this->config->current['KRBSASL']) && preg_match('/^true$/i', $this->config->current['KRBSASL'])){
115 $mode= "sasl";
116 }
118 return "{".$mode."}".$this->attrs['uid'][0]."@".$cfg= $this->config->data['SERVERS']['KERBEROS']['REALM'];
119 }
122 function remove_from_parent()
123 {
124 if($this->is_account && $this->dn != "new"){
125 $ldap = $this->config->get_ldap_link();
126 $ldap->cat($this->dn,array("dn"));
127 if($ldap->count()){
128 $ldap->rmdir($this->dn);
129 show_ldap_error($ldap->get_error(),_("Tried to remove heimdal extension."));
130 }
131 }
132 }
135 function set_password($password)
136 {
137 #TODO
138 # Add or modify kerberos entry below $this->dn
139 # See https://oss.gonicus.de/labs/gosa/ticket/223
140 # Order: create entries, then call the heimdal_keygen hook with the realm (returned by generate_hash)
141 # to let it add the missing kerberos keys.
143 global $config;
144 $cmd = "";
145 if(isset($config->current['HEIMDAL_KEYGEN'])){
146 $cmd = $config->current['HEIMDAL_KEYGEN'];
147 if(!check_command($cmd)){
148 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' is not a valid command."),$cmd),WARNING_DIALOG);
149 }
150 }
151 if(isset($this->config->data['MAIN']['HEIMDAL_KEYGEN'])){
152 $cmd = $this->config->data['MAIN']['HEIMDAL_KEYGEN'];
153 if(!check_command($cmd)){
154 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' is not a valid command."),$cmd),WARNING_DIALOG);
155 }
156 }
157 if ($cmd != ""){
159 /* Display in error message */
160 $cmdd = $cmd." '".$this->generate_hash($password)."' 'PASSWORD'";
162 /* Execute command and check return value */
163 $cmd = $cmd." '".$this->generate_hash($password)."' '".$password."'" ;
164 exec($cmd,$out,$res);
165 if($res != 0){
166 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' wasn't successfully executed. Command does not return 0."),$cmdd),WARNING_DIALOG);
167 }
168 }
169 }
172 function get_hash_name()
173 {
174 $mode= "kerberos";
175 if (isset($this->config->current['KRBSASL']) && preg_match('/^true$/i', $this->config->current['KRBSASL'])){
176 $mode= "sasl";
177 }
178 return "$mode";
179 }
182 function is_configurable()
183 {
184 return TRUE;
185 }
188 function configure()
189 {
190 $this->save_object();
192 /* Cancel heimdal options */
193 if (isset($_POST['pw_abort'])){
194 return "";
195 }
197 /* Cancel heimdal options */
198 if (isset($_POST['pw_save'])){
199 $msgs = $this->check();
200 if(count($msgs)){
201 foreach($msgs as $msg){
202 msg_dialog::display(_("Heimdal"),$msg,WARNING_DIALOG);
203 }
204 }else{
205 $this->display = FALSE;
206 return "";
207 }
208 }
210 $smarty = get_smarty();
211 foreach($this->attributes as $attr){
212 $smarty->assign($attr ,$this->$attr);
213 }
214 foreach($this->flag_list as $key => $name){
215 $val = pow(2,$key);
216 if($this->krb5KDCFlags & $val){
217 $smarty->assign("krb5KDCFlags_".$key,TRUE);
218 }else{
219 $smarty->assign("krb5KDCFlags_".$key,FALSE);
220 }
221 }
223 return($smarty->fetch(get_template_path("pwd_heimdal.tpl")));
224 }
227 function save_object()
228 {
229 if(isset($_POST['pwd_heimdal_posted'])){
230 foreach($this->attributes as $attr){
231 if(isset($_POST[$attr])){
232 $this->$attr = get_post($attr);
233 }
234 }
236 $int = "";
237 foreach($this->flag_list as $key => $name){
238 $post = "krb5KDCFlags_".$key;
239 if(isset($_POST[$post])){
240 $int |= pow(2,$key);
241 }
242 }
243 $this->krb5KDCFlags = $int;
244 }
245 }
247 function check()
248 {
249 $message = array();
250 if(!is_numeric($this->krb5MaxLife) && !empty($this->krb5MaxLife)){
251 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Max life"));
252 }
253 if(!is_numeric($this->krb5MaxRenew) && !empty($this->krb5MaxRenew)){
254 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Max renew"));
255 }
256 if(!empty($this->krb5ValidStart) && !$this->chk_times($this->krb5ValidStart)){
257 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Valid start"));
258 }
259 if(!empty($this->krb5ValidEnd) && !$this->chk_times($this->krb5ValidEnd)){
260 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Valid end"));
261 }
262 if(!empty($this->krb5PasswordEnd) && !$this->chk_times($this->krb5PasswordEnd)){
263 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Valid password"));
264 }
265 return($message);
266 }
269 function chk_times($str)
270 {
271 if(preg_match("/^([0-9]){12,12}[a-z]$/i",$str)){
272 return(true);
273 }
274 return(false);
275 }
278 function save($dn)
279 {
280 $realm = $this->config->data['SERVERS']['KERBEROS']['REALM'];
282 $ldap = $this->config->get_ldap_link();
283 $ldap->cd($dn);
284 $ldap->cat($dn,array('uid'));
285 $attrs = $ldap->fetch();
286 if(isset($attrs['uid'][0])){
288 $uid = $attrs['uid'][0];
289 $name = $uid."@".strtoupper($realm);
290 $dn = "krb5PrincipalName=".$name.",".$dn;
292 $data = array();
293 $data['krb5PrincipalName'] = $name;
294 $data['objectClass'] = array("top","account","krb5Principal","krb5KDCEntry");
295 $data['krb5PrincipalName'] =$name;
296 $data['uid'] = $uid;
297 $data['krb5KeyVersionNumber'] = rand(100000,99999999);
299 if($this->is_account){
300 foreach($this->attributes as $attr){
301 $data[$attr] = array();
302 }
303 }
305 /* Append Flags */
306 $data['krb5KDCFlags'] = $this->krb5KDCFlags;
307 if(!empty($this->krb5MaxLife)){
308 $data['krb5MaxLife'] = $this->krb5MaxLife;
309 }
310 if(!empty($this->krb5MaxRenew)){
311 $data['krb5MaxRenew'] = $this->krb5MaxRenew;
312 }
313 if(!empty($this->krb5ValidStart)){
314 $data['krb5ValidStart'] = $this->krb5ValidStart;
315 }
316 if(!empty($this->krb5ValidEnd)){
317 $data['krb5ValidEnd'] = $this->krb5ValidEnd;
318 }
319 if(!empty($this->krb5PasswordEnd)){
320 $data['krb5PasswordEnd']= $this->krb5PasswordEnd;
321 }
323 /* Add / Updated data */
324 $ldap->cd($dn);
325 if(!$this->is_account){
326 $ldap->add($data);
327 }else{
328 $ldap->modify($data);
329 }
330 show_ldap_error($ldap->get_error(),_("Could not add or update heimdal extensions."));
331 }
332 }
333 }
335 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
336 ?>