1 <?php
2 /*
3 This code is part of GOsa (https://gosa.gonicus.de)
4 Copyright (C) 2004 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 passwordMethod
23 {
24 var $config = false;
26 // Konstructor
27 function passwordMethod($config)
28 {
29 }
31 // Loads Methods in annother way as get_available_methods do, (For setup ..)
32 // and loads them,.
33 function get_available_methods_if_not_loaded($path_to_load="../include")
34 {
35 $oh = opendir($path_to_load);
36 $i = 0;
37 $ret = false;
38 while ($file = readdir($oh)) {
39 $one = strtolower($file);
40 if((strstr($one,"class_password-methods-" ))&&($one[0]!=".")){
41 require_once($file);
42 }
43 }
44 return(passwordMethod::get_available_methods());
45 }
50 // Crypts a single string, with given Method
51 function crypt_single_str($string,$method)
52 {
53 $available = passwordMethod::get_available_methods();
54 if(!is_array($available))
55 {
56 $available = passwordMethod::get_available_methods_if_not_loaded();
57 }
59 $test = new $available[$method](false);
60 $newpass = $test->generate_hash($string);
61 return( $newpass);
62 }
65 // this function returns all loaded classes for password encryption
66 function get_available_methods()
67 {
68 $ret =false;
69 $all = (get_declared_classes());
70 $i = 0;
71 foreach($all as $one) {
72 if((strstr($one,"passwordmethod" ))&&($one != "passwordmethod")){
73 $name = str_replace ("passwordmethod","",$one);
74 $test = new $one(false);
75 if($test->is_available()) {
76 $ret['name'][$i]=str_replace ("passwordmethod","",$one);
77 $ret['class'][$i]=$one;
78 $ret[$i]['name']=str_replace ("passwordmethod","",$one);
79 $ret[$i]['class']=$one;
80 $ret[str_replace ("passwordmethod","",$one)]=$one;
81 $i++;
82 }
83 }
84 }
85 return($ret);
86 }
88 }
90 // change_password, changes the Password, of the given dn
91 function change_password ($dn, $password, $mode=0, $hash= "")
92 {
94 global $config;
95 $newpass= "";
98 // Get all available encryption Methods
99 $available = passwordMethod::get_available_methods();
102 // read current password entry for $dn, to detect the encryption Method
103 $ldap = $config->get_ldap_link();
104 $ldap->cat ($dn);
105 $attrs = $ldap->fetch ();
107 // Set encryption type to clear if required
108 if (isset($attrs['userPassword'][0]) && preg_match('/^[^{}]+$/', $attrs['userPassword'][0]) && $hash == ""){
109 $hash= "clear";
110 }
114 // Detect the encryption Method
115 if ( (isset($attrs['userPassword'][0]) && preg_match ("/^{([^}]+)}(.+)/", $attrs['userPassword'][0], $matches)) || $hash != ""){
117 /* Check for supported algorithm */
118 mt_srand((double) microtime()*1000000);
120 /* Extract used hash */
121 if ($hash == ""){
122 $hash= strtolower($matches[1]);
123 }
126 // Crypt with the detected Method
127 $test = new $available[$hash]($config);
128 $newpass = $test->generate_hash($password);
130 } else {
131 // Crypt it by default
132 $test = new $available['md5']($config);
133 $newpass = $test->generate_hash($password);
134 }
138 // Update shadow timestamp?
139 if (isset($attrs["shadowLastChange"][0])){
140 $shadow= (int)(date("U") / 86400);
141 } else {
142 $shadow= 0;
143 }
145 // Write back modified entry
146 $ldap->cd($dn);
147 $attrs= array();
149 // Not for groups
150 if ($mode == 0){
152 if ($shadow != 0){
153 $attrs['shadowLastChange']= $shadow;
154 }
156 // Create SMB Password
157 $attrs = generate_smb_nt_hash($password);
158 }
160 $attrs['userPassword']= array();
161 $attrs['userPassword']= $newpass;
164 $ldap->modify($attrs);
167 if ($ldap->error != 'Success')
168 {
169 print_red(sprintf(_("Setting the password failed. LDAP server says '%s'."),
170 $ldap->get_error()));
171 }
172 }
175 // Retrun something like array['sambaLMPassword']= "lalla..."
176 function generate_smb_nt_hash($password)
177 {
178 global $config;
179 $tmp= $config->data['MAIN']['SMBHASH']." ".escapeshellarg($password);
180 @DEBUG (DEBUG_LDAP, __LINE__, __FUNCTION__, __FILE__, $tmp, "Execute");
182 exec($tmp, $ar);
183 flush();
184 reset($ar);
185 $hash= current($ar);
186 if ($hash == "")
187 {
188 print_red (_("Setting for SMBHASH in gosa.conf is incorrect! Can't change Samba password."));
189 }
190 else
191 {
192 list($lm,$nt)= split (":", trim($hash));
194 if ($config->current['SAMBAVERSION'] == 3)
195 {
196 $attrs['sambaLMPassword']= $lm;
197 $attrs['sambaNTPassword']= $nt;
198 $attrs['sambaPwdLastSet']= date('U');
199 $attrs['sambaBadPasswordCount']= "0";
200 $attrs['sambaBadPasswordTime']= "0";
201 } else {
202 $attrs['lmPassword']= $lm;
203 $attrs['ntPassword']= $nt;
204 $attrs['pwdLastSet']= date('U');
205 }
206 return($attrs);
207 }
208 }
210 function crypt_single($string,$enc_type )
211 {
212 if(!class_exists("passwordMethod")){
213 require_once("class_password-methods.inc");
214 }
215 return( passwordMethod::crypt_single_str($string,$enc_type));
216 }
218 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
219 ?>