Code

Prepared statistics to print password changes over time
[gosa.git] / gosa-core / include / password-methods / class_password-methods.inc
1 <?php
2 /*
3  * This code is part of GOsa (http://www.gosa-project.org)
4  * Copyright (C) 2003-2008 GONICUS GmbH
5  *
6  * ID: $$Id$$
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
23 class passwordMethod
24 {
25     var $config = false;
26     var $attrs= array();
27     var $display = FALSE;
28     var $hash= "";
29     var $lockable = TRUE;
31     // Konstructor
32     function passwordMethod($config, $dn)
33     {
34     }
36     function create_template_hash($attrs)
37     {
38         if($this->get_hash_name() == ""){
39             return("{crypt}N0T$3T4N0W");
40         }else{
41             return('{'.$this->get_hash().'}').'N0T$3T4N0W';
42         }
43     }
45     function get_hash_name()
46     {
47     }
50     function is_locked($config,$dn = "")
51     {
52         if(!$this->lockable) return FALSE;
54         /* Get current password hash */
55         $pwd ="";
56         if(!empty($dn)){
57             $ldap = $config->get_ldap_link();
58             $ldap->cd($config->current['BASE']);
59             $ldap->cat($dn);
60             $attrs = $ldap->fetch();
61             if(isset($attrs['userPassword'][0])){
62                 $pwd = $attrs['userPassword'][0];
63             }
64         }elseif(isset($this->attrs['userPassword'][0])){
65             $pwd = $this->attrs['userPassword'][0];
66         }
67         return(preg_match("/^[^\}]*+\}!/",$pwd));
68     }
72     /*! \brief       Locks an account (gosaAccount) by added a '!' as prefix to the password hashes.
73      *               This makes logins impossible, due to the fact that the hash becomes invalid.
74      *                 userPassword: {SHA}!q02NKl9IChNwZEAJxzRdmB6E
75      *                 sambaLMPassword: !EBD223B61F8C259AD3B435B51404EE
76      *                 sambaNTPassword: !98BB35737013AAF181D0FE9FDA09E
77      */               
78     function lock_account($config,$dn = "")
79     {
80         if(!$this->lockable) return FALSE;
82         /* Get current password hash */
83         $userPassword = $sambaLMPassword = $sambaNTPassword = "";
84         $ldap = $config->get_ldap_link();
85         $ldap->cd($config->current['BASE']);
86         if(!empty($dn)){
87             $ldap->cat($dn,array('sambaLMPassword','sambaNTPassword','userPassword'));
88             $attrs = $ldap->fetch();
89             $userPassword = (isset($attrs['userPassword'][0])) ? $attrs['userPassword'][0]: "";
90             $sambaLMPassword = (isset($attrs['sambaLMPassword'][0])) ? $attrs['sambaLMPassword'][0]: "";
91             $sambaNTPassword = (isset($attrs['sambaNTPassword'][0])) ? $attrs['sambaNTPassword'][0]: "";
92         }elseif(isset($this->attrs['userPassword'][0])){
93             $dn = $this->attrs['dn'];
94             $userPassword = (isset($this->attrs['userPassword'][0])) ? $this->attrs['userPassword'][0]: "";
95             $sambaLMPassword = (isset($this->attrs['sambaLMPassword'][0])) ? $this->attrs['sambaLMPassword'][0]: "";
96             $sambaNTPassword = (isset($this->attrs['sambaNTPassword'][0])) ? $this->attrs['sambaNTPassword'][0]: "";
97         }
99         /* We can only lock/unlock non-empty passwords */
100         if(!empty($userPassword)){
102             /* Check if this entry is already locked. */
103             if(preg_match("/^[^\}]*+\}!/",$userPassword)){
104                 return(TRUE);
105             }     
107             /* Lock entry */
108             $userPassword = preg_replace("/(^[^\}]+\})(.*$)/","\\1!\\2",$userPassword);
109             $sambaLMPassword = preg_replace("/^[!]*(.*$)/","!\\1",$sambaLMPassword);
110             $sambaNTPassword = preg_replace("/^[!]*(.*$)/","!\\1",$sambaNTPassword);
111             $ldap->cd($dn);
112             $ldap->modify(
113                     array(
114                         "userPassword" => $userPassword,
115                         "sambaLMPassword" => $sambaLMPassword,
116                         "sambaNTPassword" => $sambaNTPassword));
117             return($ldap->success());
118         }
119         return(FALSE);
120     }
123     /*! \brief       Unlocks an account (gosaAccount) which was locked by 'lock_account()'.
124      *               For details about the locking mechanism see 'lock_account()'.
125      */               
126     function unlock_account($config,$dn = "")
127     {
128         if(!$this->lockable) return FALSE;
130         /* Get current password hash */
131         $userPassword = $sambaLMPassword = $sambaNTPassword = "";
132         $ldap = $config->get_ldap_link();
133         $ldap->cd($config->current['BASE']);
134         if(!empty($dn)){
135             $ldap->cat($dn,array('sambaLMPassword','sambaNTPassword','userPassword'));
136             $attrs = $ldap->fetch();
137             $userPassword = (isset($attrs['userPassword'][0])) ? $attrs['userPassword'][0]: "";
138             $sambaLMPassword = (isset($attrs['sambaLMPassword'][0])) ? $attrs['sambaLMPassword'][0]: "";
139             $sambaNTPassword = (isset($attrs['sambaNTPassword'][0])) ? $attrs['sambaNTPassword'][0]: "";
140         }elseif(isset($this->attrs['userPassword'][0])){
141             $dn = $this->attrs['dn'];
142             $userPassword = (isset($this->attrs['userPassword'][0])) ? $this->attrs['userPassword'][0]: "";
143             $sambaLMPassword = (isset($this->attrs['sambaLMPassword'][0])) ? $this->attrs['sambaLMPassword'][0]: "";
144             $sambaNTPassword = (isset($this->attrs['sambaNTPassword'][0])) ? $this->attrs['sambaNTPassword'][0]: "";
145         }
148         /* We can only lock/unlock non-empty passwords */
149         if(!empty($userPassword)){
151             /* Check if this entry is already locked. */
152             if(!preg_match("/^[^\}]*+\}!/",$userPassword)){
153                 return (TRUE);
154             }     
156             /* Lock entry */
157             $userPassword = preg_replace("/(^[^\}]+\})!(.*$)/","\\1\\2",$userPassword);
158             $sambaLMPassword = preg_replace("/^[!]*(.*$)/","\\1",$sambaLMPassword);
159             $sambaNTPassword = preg_replace("/^[!]*(.*$)/","\\1",$sambaNTPassword);
160             $ldap->cd($dn);
161             $ldap->modify(
162                     array(
163                         "userPassword" => $userPassword,
164                         "sambaLMPassword" => $sambaLMPassword,
165                         "sambaNTPassword" => $sambaNTPassword));
166             return($ldap->success());
167         }
168         return(FALSE);
169     }
172     // this function returns all loaded classes for password encryption
173     static function get_available_methods()
174     {
175         global $class_mapping, $config;
176         $ret =false;
177         $i =0;
179         /* Only */
180         if(!session::is_set("passwordMethod::get_available_methods")){
181             foreach($class_mapping as $class => $path) {
182                 if(preg_match('/passwordMethod/i', $class) && !preg_match("/^passwordMethod$/i", $class)){
183                     $name = preg_replace ("/passwordMethod/i", "", $class);
184                     $test = new $class($config, "");
185                     if($test->is_available()) {
186                         $plugs= $test->get_hash_name();
187                         if (!is_array($plugs)){
188                             $plugs= array($plugs);
189                         }
191                         foreach ($plugs as $plugname){
193                             $cfg = $test->is_configurable();
195                             $ret['name'][$i]= $plugname;
196                             $ret['class'][$i]=$class;
197                             $ret['is_configurable'][$i]= $cfg;
198                             $ret['object'][$i]= $test;
199                             $ret['desc'][$i] = $test->get_description();
200                             $ret[$i]['name']  = $plugname;
201                             $ret[$i]['class'] = $class;
202                             $ret[$i]['object']= $test;
203                             $ret[$i]['is_configurable']= $cfg;
204                             $ret[$i]['desc'] = $test->get_description();
205                             $ret[$plugname]=$class;                    
206                             $i++;
207                         }
208                     }
209                 }
210             }
211             session::set("passwordMethod::get_available_methods",$ret);
212         }
213         return(session::get("passwordMethod::get_available_methods"));
214     }
217     function get_description()
218     {
219         return("");
220     }
223     // Method to let password backends remove additional information besides
224     // the userPassword attribute
225     function remove_from_parent()
226     {
227     }
230     // Method to let passwords backends manage additional information
231     // besides the userAttribute entry
232     function set_password($password)
233     {
234         return(TRUE);
235     }
238     // Return true if this password method provides a configuration dialog
239     function is_configurable()
240     {
241         return FALSE;
242     }
245     // Provide a subdialog to configure a password method
246     function configure()
247     {
248         return "";
249     }
252     // Save information to LDAP
253     function save($dn)
254     {
255     }
258     // Try to find out if it's our hash...
259     static function get_method($password_hash,$dn = "")
260     {
261         global $config;
263         $methods= passwordMethod::get_available_methods();
265         foreach ($methods['class'] as $class){
267             $test = new $class($config,$dn);
268 #        All listed methods are available. 
269 #        if(!$test->is_available())continue;
270             $method= $test->_extract_method($password_hash);
271             if ($method != ""){
272                 $test->set_hash($method);
273                 return $test;
274             }
275         }
277         msg_dialog::display(_("Error"), _("Cannot find a suitable password method for the current hash!"), ERROR_DIALOG);
279         return NULL;
280     }
283     function _extract_method($password_hash)
284     {
285         $hash= $this->get_hash_name();
286         if (preg_match("/^\{$hash\}/i", $password_hash)){
287             return $hash;
288         }
290         return "";
291     }
294     static function make_hash($password, $hash)
295     {
296         global $config;
298         $methods= passwordMethod::get_available_methods();
299         $tmp= new $methods[$hash]($config);
300         $tmp->set_hash($hash);
301         return $tmp->generate_hash($password);
302     }
305     function set_hash($hash)
306     {
307         $this->hash= $hash;
308     }
311     function get_hash()
312     {
313         return $this->hash;
314     }
316     function adapt_from_template($dn)
317     {
318         return($this);
319     }
322     static function is_harmless($password)
323     {
324         global $config;
326         if ($config->boolValueIsTrue("core","strictPasswordRules")) {
327             // Do we have UTF8 characters in the password?
328             return ($password == utf8_decode($password));
329         }
331         return(true);
332     }
335     static function getPasswordProposal($config)
336     {
337         if($config->configRegistry->propertyExists('core', 'passwordProposalHook')){
338             $value = $config->configRegistry->getPropertyValue('core', 'passwordProposalHook');
339             $core = new core($config);
341             // No execute the hook and fetch the results.
342             plugin::callHook($core, 'passwordProposalHook', $addAttrs= array(), $ret);
343             if(count($ret) && !empty($ret[0])){
344                 return($ret[0]);
345             }
346         }
347         return('');
348     }
352 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
353 ?>