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