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 $this->is_account = FALSE;
63 $this->krb5MaxLife = 86400;
64 $this->krb5MaxRenew = 604800;
65 $this->krb5ValidStart = date("YmdHi",time())."Z";
66 $this->krb5ValidEnd = date("YmdHi",time())."Z";
67 $this->krb5PasswordEnd= date("YmdHi",time())."Z";
69 /* Load existing entries */
70 if($dn != "new"){
71 $ldap = $this->config->get_ldap_link();
72 $ldap->cd($dn);
73 $ldap->ls("objectClass=krb5Principal",$dn,array("*"));
74 if($ldap->count()==1){
75 $this->is_account = TRUE;
76 $this->attrs = $ldap->fetch();
77 $this->dn = $this->attrs['dn'];
78 foreach($this->attributes as $attr){
79 if(isset($this->attrs[$attr][0])){
80 $this->$attr = $this->attrs[$attr][0];
81 }else{
82 $this->$attr = "";
83 }
84 }
85 }elseif($ldap->count() >= 2){
86 new msg_dialog(_("Heimdal"),sprintf(_("Error loading heimdal configuration, more than one configuration entry was found for '%s'."),$this->parent_dn));
87 }
88 }
89 }
92 function is_available()
93 {
94 global $config;
95 $cmd = "";
96 if(isset($config->current['HEIMDAL_KEYGEN'])){
97 $cmd = $config->current['HEIMDAL_KEYGEN'];
98 if(!check_command($cmd)){
99 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' is not a valid command."),$cmd),WARNING_DIALOG);
100 }
101 }
102 if(isset($this->config->data['MAIN']['HEIMDAL_KEYGEN'])){
103 $cmd = $this->config->data['MAIN']['HEIMDAL_KEYGEN'];
104 if(!check_command($cmd)){
105 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' is not a valid command."),$cmd),WARNING_DIALOG);
106 }
107 }
108 if(isset($config->data['SERVERS']['KERBEROS']['REALM']) && check_command($cmd)){
109 return TRUE;
110 }else{
111 return FALSE;
112 }
113 }
116 function generate_hash($pwd)
117 {
118 $mode= "kerberos";
119 if (isset($this->config->current['KRBSASL']) && preg_match('/^true$/i', $this->config->current['KRBSASL'])){
120 $mode= "sasl";
121 }
123 return "{".$mode."}".$this->attrs['uid'][0]."@".$cfg= $this->config->data['SERVERS']['KERBEROS']['REALM'];
124 }
127 function remove_from_parent()
128 {
129 if($this->is_account && $this->dn != "new"){
130 $ldap = $this->config->get_ldap_link();
131 $ldap->cat($this->dn,array("dn"));
132 if($ldap->count()){
133 $ldap->rmdir($this->dn);
134 show_ldap_error($ldap->get_error(),_("Tried to remove heimdal extension."));
135 }
136 }
137 }
140 function set_password($password)
141 {
142 #TODO
143 # Add or modify kerberos entry below $this->dn
144 # See https://oss.gonicus.de/labs/gosa/ticket/223
145 # Order: create entries, then call the heimdal_keygen hook with the realm (returned by generate_hash)
146 # to let it add the missing kerberos keys.
148 global $config;
149 $cmd = "";
150 if(isset($config->current['HEIMDAL_KEYGEN'])){
151 $cmd = $config->current['HEIMDAL_KEYGEN'];
152 if(!check_command($cmd)){
153 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' is not a valid command."),$cmd),WARNING_DIALOG);
154 }
155 }
156 if(isset($this->config->data['MAIN']['HEIMDAL_KEYGEN'])){
157 $cmd = $this->config->data['MAIN']['HEIMDAL_KEYGEN'];
158 if(!check_command($cmd)){
159 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' is not a valid command."),$cmd),WARNING_DIALOG);
160 }
161 }
162 if ($cmd != ""){
164 /* Display in error message */
165 $cmdd = $cmd." '".$this->generate_hash($password)."' 'PASSWORD'";
167 /* Execute command and check return value */
168 $cmd = $cmd." '".$this->generate_hash($password)."' '".$password."'" ;
169 exec($cmd,$out,$res);
170 if($res != 0){
171 new msg_dialog(_("Heimdal"),sprintf(_("The configured HEIMDAL_KEYGEN '%s' wasn't successfully executed. Command does not return 0."),$cmdd),WARNING_DIALOG);
172 }
173 }
174 }
177 function get_hash_name()
178 {
179 $mode= "kerberos";
180 if (isset($this->config->current['KRBSASL']) && preg_match('/^true$/i', $this->config->current['KRBSASL'])){
181 $mode= "sasl";
182 }
183 return "$mode";
184 }
187 function is_configurable()
188 {
189 return TRUE;
190 }
193 function configure()
194 {
195 $this->save_object();
197 /* Cancel heimdal options */
198 if (isset($_POST['pw_abort'])){
199 return "";
200 }
202 /* Cancel heimdal options */
203 if (isset($_POST['pw_save'])){
204 $msgs = $this->check();
205 if(count($msgs)){
206 foreach($msgs as $msg){
207 msg_dialog::display(_("Heimdal"),$msg,WARNING_DIALOG);
208 }
209 }else{
210 $this->display = FALSE;
211 return "";
212 }
213 }
215 $smarty = get_smarty();
216 foreach($this->attributes as $attr){
217 $smarty->assign($attr ,$this->$attr);
218 }
219 foreach($this->flag_list as $key => $name){
220 $val = pow(2,$key);
221 if($this->krb5KDCFlags & $val){
222 $smarty->assign("krb5KDCFlags_".$key,TRUE);
223 }else{
224 $smarty->assign("krb5KDCFlags_".$key,FALSE);
225 }
226 }
228 return($smarty->fetch(get_template_path("pwd_heimdal.tpl")));
229 }
232 function save_object()
233 {
234 if(isset($_POST['pwd_heimdal_posted'])){
235 foreach($this->attributes as $attr){
236 if(isset($_POST[$attr])){
237 $this->$attr = get_post($attr);
238 }
239 }
241 $int = "";
242 foreach($this->flag_list as $key => $name){
243 $post = "krb5KDCFlags_".$key;
244 if(isset($_POST[$post])){
245 $int |= pow(2,$key);
246 }
247 }
248 $this->krb5KDCFlags = $int;
249 }
250 }
252 function check()
253 {
254 $message = array();
255 if(!is_numeric($this->krb5MaxLife) && !empty($this->krb5MaxLife)){
256 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Max life"));
257 }
258 if(!is_numeric($this->krb5MaxRenew) && !empty($this->krb5MaxRenew)){
259 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Max renew"));
260 }
261 if(!empty($this->krb5ValidStart) && !$this->chk_times($this->krb5ValidStart)){
262 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Valid start"));
263 }
264 if(!empty($this->krb5ValidEnd) && !$this->chk_times($this->krb5ValidEnd)){
265 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Valid end"));
266 }
267 if(!empty($this->krb5PasswordEnd) && !$this->chk_times($this->krb5PasswordEnd)){
268 $message[] = sprintf(_("Please specify a numeric value for %s."),_("Valid password"));
269 }
270 return($message);
271 }
274 function chk_times($str)
275 {
276 if(preg_match("/^([0-9]){12,12}[a-z]$/i",$str)){
277 return(true);
278 }
279 return(false);
280 }
283 function save($dn)
284 {
285 $realm = $this->config->data['SERVERS']['KERBEROS']['REALM'];
287 $ldap = $this->config->get_ldap_link();
288 $ldap->cd($dn);
289 $ldap->cat($dn,array('uid'));
290 $attrs = $ldap->fetch();
291 if(isset($attrs['uid'][0])){
293 $uid = $attrs['uid'][0];
294 $name = $uid."@".strtoupper($realm);
295 $dn = "krb5PrincipalName=".$name.",".$dn;
297 $data = array();
298 $data['krb5PrincipalName'] = $name;
299 $data['objectClass'] = array("top","account","krb5Principal","krb5KDCEntry");
300 $data['krb5PrincipalName'] =$name;
301 $data['uid'] = $uid;
302 $data['krb5KeyVersionNumber'] = rand(100000,99999999);
304 if($this->is_account){
305 foreach($this->attributes as $attr){
306 $data[$attr] = array();
307 }
308 }
310 /* Append Flags */
311 $data['krb5KDCFlags'] = $this->krb5KDCFlags;
312 if(!empty($this->krb5MaxLife)){
313 $data['krb5MaxLife'] = $this->krb5MaxLife;
314 }
315 if(!empty($this->krb5MaxRenew)){
316 $data['krb5MaxRenew'] = $this->krb5MaxRenew;
317 }
318 if(!empty($this->krb5ValidStart)){
319 $data['krb5ValidStart'] = $this->krb5ValidStart;
320 }
321 if(!empty($this->krb5ValidEnd)){
322 $data['krb5ValidEnd'] = $this->krb5ValidEnd;
323 }
324 if(!empty($this->krb5PasswordEnd)){
325 $data['krb5PasswordEnd']= $this->krb5PasswordEnd;
326 }
328 /* Add / Updated data */
329 $ldap->cd($dn);
330 if(!$this->is_account){
331 $ldap->add($data);
332 }else{
333 $ldap->modify($data);
334 }
335 show_ldap_error($ldap->get_error(),_("Could not add or update heimdal extensions."));
336 }
337 }
338 }
340 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
341 ?>