3
* This code is part of GOsa (http://www.gosa-project.org)
4
* Copyright (C) 2003-2008 GONICUS GmbH
6
* ID: $$Id: class_password-methods.inc 20518 2010-12-03 14:23:06Z hickert $$
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.
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.
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
32
function passwordMethod($config, $dn)
36
function create_template_hash($attrs)
38
if($this->get_hash_name() == ""){
39
return("{crypt}N0T$3T4N0W");
41
return('{'.$this->get_hash().'}').'N0T$3T4N0W';
45
function get_hash_name()
50
function is_locked($config,$dn = "")
52
if(!$this->lockable) return FALSE;
54
/* Get current password hash */
57
$ldap = $config->get_ldap_link();
58
$ldap->cd($config->current['BASE']);
60
$attrs = $ldap->fetch();
61
if(isset($attrs['userPassword'][0])){
62
$pwd = $attrs['userPassword'][0];
64
}elseif(isset($this->attrs['userPassword'][0])){
65
$pwd = $this->attrs['userPassword'][0];
67
return(preg_match("/^[^\}]*+\}!/",$pwd));
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
78
function lock_account($config,$dn = "")
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']);
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]: "";
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)){
108
$userPassword = preg_replace("/(^[^\}]+\})(.*$)/","\\1!\\2",$userPassword);
110
// Only lock samba hashes if samba passwords are enabled
111
$smbPasswdEnabled = trim($config->get_cfg_value('core','sambaHashHook')) != "";
112
if($smbPasswdEnabled){
113
$sambaLMPassword = preg_replace("/^[!]*(.*$)/","!\\1",$sambaLMPassword);
114
$sambaNTPassword = preg_replace("/^[!]*(.*$)/","!\\1",$sambaNTPassword);
117
// Call external lock hook
118
$res = $ldap->cat($dn);
119
$hookAttrs = array();
120
foreach($ldap->fetch() as $name => $value){
121
if(is_numeric($name)) continue;
122
if(isset($value[0])) $hookAttrs[$name] = $value[0];
123
if(isset($value) && is_string($value)) $hookAttrs[$name] = $value;
125
$pwdClass = new password($config, $dn);
126
$pwdClass->callHook($pwdClass, 'PRELOCK',$hookAttrs, $ret);
128
// Update the ldap entry
131
$attrs['userPassword'] = $userPassword;
133
// Updated samba hashes if samba hashing is enabled
134
if($smbPasswdEnabled){
135
$attrs['sambaLMPassword'] = $sambaLMPassword;
136
$attrs['sambaNTPassword'] = $sambaNTPassword;
139
$ldap->modify($attrs);
140
if($ldap->success()){
142
// Call the password post-lock hook, if defined.
143
$pwdClass->callHook($pwdClass, 'POSTLOCK',$hookAttrs, $ret);
145
return($ldap->success());
152
/*! \brief Unlocks an account (gosaAccount) which was locked by 'lock_account()'.
153
* For details about the locking mechanism see 'lock_account()'.
155
function unlock_account($config,$dn = "")
157
if(!$this->lockable) return FALSE;
159
/* Get current password hash */
160
$userPassword = $sambaLMPassword = $sambaNTPassword = "";
161
$ldap = $config->get_ldap_link();
162
$ldap->cd($config->current['BASE']);
164
$ldap->cat($dn,array('sambaLMPassword','sambaNTPassword','userPassword'));
165
$attrs = $ldap->fetch();
166
$userPassword = (isset($attrs['userPassword'][0])) ? $attrs['userPassword'][0]: "";
167
$sambaLMPassword = (isset($attrs['sambaLMPassword'][0])) ? $attrs['sambaLMPassword'][0]: "";
168
$sambaNTPassword = (isset($attrs['sambaNTPassword'][0])) ? $attrs['sambaNTPassword'][0]: "";
169
}elseif(isset($this->attrs['userPassword'][0])){
170
$dn = $this->attrs['dn'];
171
$userPassword = (isset($this->attrs['userPassword'][0])) ? $this->attrs['userPassword'][0]: "";
172
$sambaLMPassword = (isset($this->attrs['sambaLMPassword'][0])) ? $this->attrs['sambaLMPassword'][0]: "";
173
$sambaNTPassword = (isset($this->attrs['sambaNTPassword'][0])) ? $this->attrs['sambaNTPassword'][0]: "";
177
/* We can only lock/unlock non-empty passwords */
178
if(!empty($userPassword)){
180
/* Check if this entry is already locked. */
181
if(!preg_match("/^[^\}]*+\}!/",$userPassword)){
187
$userPassword = preg_replace("/(^[^\}]+\})!(.*$)/","\\1\\2",$userPassword);
189
// Update samba hashes only if its enabled.
190
$smbPasswdEnabled = trim($config->get_cfg_value('core','sambaHashHook')) != "";
191
if($smbPasswdEnabled){
192
$sambaLMPassword = preg_replace("/^[!]*(.*$)/","\\1",$sambaLMPassword);
193
$sambaNTPassword = preg_replace("/^[!]*(.*$)/","\\1",$sambaNTPassword);
196
// Call external lock hook
197
$res = $ldap->cat($dn);
198
$hookAttrs = array();
199
foreach($ldap->fetch() as $name => $value){
200
if(is_numeric($name)) continue;
201
if(isset($value[0])) $hookAttrs[$name] = $value[0];
202
if(isset($value) && is_string($value)) $hookAttrs[$name] = $value;
204
$pwdClass = new password($config, $dn);
205
$pwdClass->callHook($pwdClass, 'PREUNLOCK',$hookAttrs, $ret);
207
// Lock the account by modifying the password hash.
210
// Update the ldap entry
212
$attrs['userPassword'] = $userPassword;
214
// Updated samba hashes if samba hashing is enabled
215
if($smbPasswdEnabled){
216
$attrs['sambaLMPassword'] = $sambaLMPassword;
217
$attrs['sambaNTPassword'] = $sambaNTPassword;
220
$ldap->modify($attrs);
222
if($ldap->success()){
224
// Call the password post-lock hook, if defined.
225
$pwdClass = new password($config, $dn);
226
$pwdClass->callHook($pwdClass, 'POSTUNLOCK',$hookAttrs, $ret);
228
return($ldap->success());
234
// this function returns all loaded classes for password encryption
235
static function get_available_methods()
237
global $class_mapping, $config;
242
if(!session::is_set("passwordMethod::get_available_methods")){
243
foreach($class_mapping as $class => $path) {
244
if(preg_match('/passwordMethod/i', $class) && !preg_match("/^passwordMethod$/i", $class)){
245
$name = preg_replace ("/passwordMethod/i", "", $class);
246
$test = new $class($config, "");
247
if($test->is_available()) {
248
$plugs= $test->get_hash_name();
249
if (!is_array($plugs)){
250
$plugs= array($plugs);
253
foreach ($plugs as $plugname){
255
$cfg = $test->is_configurable();
257
$ret['name'][$i]= $plugname;
258
$ret['class'][$i]=$class;
259
$ret['is_configurable'][$i]= $cfg;
260
$ret['object'][$i]= $test;
261
$ret['desc'][$i] = $test->get_description();
262
$ret[$i]['name'] = $plugname;
263
$ret[$i]['class'] = $class;
264
$ret[$i]['object']= $test;
265
$ret[$i]['is_configurable']= $cfg;
266
$ret[$i]['desc'] = $test->get_description();
267
$ret[$plugname]=$class;
273
session::set("passwordMethod::get_available_methods",$ret);
275
return(session::get("passwordMethod::get_available_methods"));
279
function get_description()
285
// Method to let password backends remove additional information besides
286
// the userPassword attribute
287
function remove_from_parent()
292
// Method to let passwords backends manage additional information
293
// besides the userAttribute entry
294
function set_password($password)
300
// Return true if this password method provides a configuration dialog
301
function is_configurable()
307
// Provide a subdialog to configure a password method
314
// Save information to LDAP
320
// Try to find out if it's our hash...
321
static function get_method($password_hash,$dn = "")
325
$methods= passwordMethod::get_available_methods();
327
foreach ($methods['class'] as $class){
329
$test = new $class($config,$dn);
330
# All listed methods are available.
331
# if(!$test->is_available())continue;
332
$method= $test->_extract_method($password_hash);
334
$test->set_hash($method);
339
msg_dialog::display(_("Error"), _("Cannot find a suitable password method for the current hash!"), ERROR_DIALOG);
345
function _extract_method($password_hash)
347
$hash= $this->get_hash_name();
348
if (preg_match("/^\{$hash\}/i", $password_hash)){
356
static function make_hash($password, $hash)
360
$methods= passwordMethod::get_available_methods();
361
$tmp= new $methods[$hash]($config);
362
$tmp->set_hash($hash);
363
return $tmp->generate_hash($password);
367
function set_hash($hash)
378
function adapt_from_template($dn)
384
static function is_harmless($password)
388
if ($config->boolValueIsTrue("core","strictPasswordRules")) {
389
// Do we have UTF8 characters in the password?
390
return ($password == utf8_decode($password));
397
static function getPasswordProposal($config)
399
if($config->configRegistry->propertyExists('core', 'passwordProposalHook')){
400
$value = $config->configRegistry->getPropertyValue('core', 'passwordProposalHook');
401
$core = new core($config);
403
// No execute the hook and fetch the results.
404
plugin::callHook($core, 'passwordProposalHook', $addAttrs= array(), $ret);
405
if(count($ret) && !empty($ret[0])){
414
// vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler: