Alternc  3.2
Alternc logiel libre pour l'hébergement
 All Data Structures Namespaces Files Functions Variables Pages
m_hta.php
Go to the documentation of this file.
1 <?php
2 /*
3  $Id: m_hta.php,v 1.5 2004/11/29 17:15:37 anonymous Exp $
4  ----------------------------------------------------------------------
5  AlternC - Web Hosting System
6  Copyright (C) 2002 by the AlternC Development Team.
7  http://alternc.org/
8  ----------------------------------------------------------------------
9  Based on:
10  Valentin Lacambre's web hosting softwares: http://altern.org/
11  ----------------------------------------------------------------------
12  LICENSE
13 
14  This program is free software; you can redistribute it and/or
15  modify it under the terms of the GNU General Public License (GPL)
16  as published by the Free Software Foundation; either version 2
17  of the License, or (at your option) any later version.
18 
19  This program is distributed in the hope that it will be useful,
20  but WITHOUT ANY WARRANTY; without even the implied warranty of
21  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  GNU General Public License for more details.
23 
24  To read the license please visit http://www.gnu.org/copyleft/gpl.html
25  ----------------------------------------------------------------------
26  Original Author of file:
27  Purpose of file:
28  ----------------------------------------------------------------------
29 */
30 
31 /**
32 * This class handle folder web restricted access through .htaccess/.htpassword
33 * files.
34 *
35 * Copyleft {@link http://alternc.net/ AlternC Team}
36 *
37 * @copyright AlternC-Team 2002-11-01 http://alternc.org/
38 *
39 */
40 class m_hta {
41 
42 
43  /*---------------------------------------------------------------------------*/
44  /**
45  * Constructor
46  */
47  function m_webaccess() {
48  }
49 
50 
51  /**
52  * Password kind used in this class (hook for admin class)
53  */
55  return array("hta"=>"Protected folders passwords");
56  }
57 
58  function hook_menu() {
59  $obj = array(
60  'title' => _("Protected folders"),
61  'ico' => 'images/password.png',
62  'link' => 'hta_list.php',
63  'pos' => 50,
64  ) ;
65 
66  return $obj;
67  }
68 
69 
70  /*---------------------------------------------------------------------------*/
71  /**
72  * Create a protected folder (.htaccess et .htpasswd)
73  * @param string $dir Folder to protect (relative to user root)
74  * @return boolean TRUE if the folder has been protected, or FALSE if an error occurred
75  */
76  function CreateDir($dir) {
77  global $mem,$bro,$err;
78  $err->log("hta","createdir",$dir);
79  $absolute=$bro->convertabsolute($dir,0);
80  if (!$absolute) {
81  $err->raise("hta",printf(_("The folder '%s' does not exist"),$dir));
82  return false;
83  }
84  if (!file_exists($absolute)) {
85  @mkdir($absolute,00777);
86  }
87  if (!file_exists("$absolute/.htaccess")) {
88  if (!@touch("$absolute/.htaccess")) {
89  $err->raise("hta",_("File already exist"));
90  return false;
91  }
92  $file = @fopen("$absolute/.htaccess","r+");
93  if (!$file) {
94  $err->raise("hta",_("File already exist"));
95  return false;
96  }
97  fseek($file,0);
98  $param="AuthUserFile \"$absolute/.htpasswd\"\nAuthName \""._("Restricted area")."\"\nAuthType Basic\nrequire valid-user\n";
99  fwrite($file, $param);
100  fclose($file);
101  }
102  if (!file_exists("$absolute/.htpasswd")) {
103  if (!touch("$absolute/.htpasswd")) {
104  $err->raise("hta",_("File already exist"));
105  return false;
106  }
107  return true;
108  }
109  return true;
110  }
111 
112 
113  /*---------------------------------------------------------------------------*/
114  /**
115  * Returns the list of all user folder currently protected by a .htpasswd file
116  * @return array Array containing user folder list
117  */
118 
119  function ListDir(){
120  global$err,$mem;
121  $err->log("hta","listdir");
122  $sortie=array();
123  $absolute=ALTERNC_HTML."/".substr($mem->user["login"],0,1)."/".$mem->user["login"];
124  exec("find $absolute -name .htpasswd|sort",$sortie);
125  if(!count($sortie)){
126  $err->raise("hta",_("No protected folder"));
127  return false;
128  }
129  $pattern="/^".preg_quote(ALTERNC_HTML,"/")."\/.\/[^\/]*\/(.*)\/\.htpasswd/";
130  for($i=0;$i<count($sortie);$i++){
131  preg_match($pattern,$sortie[$i],$matches);
132  $tmpm=isset($matches[1])?'/'.$matches[1]:'';
133  $r[$i]=$tmpm."/";
134  }
135  return $r;
136  }
137 
138  /*---------------------------------------------------------------------------*/
139  /**
140  * Tells if a folder is protected.
141  * @param string $dir Folder to check
142  * @return TRUE if the folder is protected, or FALSE if it is not
143  */
144  function is_protected($dir){
145  global $mem,$err;
146  $err->log("hta","is_protected",$dir);
147  $absolute=ALTERNC_HTML."/".substr($mem->user["login"],0,1)."/".$mem->user["login"]."/$dir";
148  $sortie=array();
149  if (file_exists("$absolute/.htpasswd")){
150  return true;
151  }
152  else {
153  return false;
154  }
155  }
156 
157 
158  /*---------------------------------------------------------------------------*/
159  /**
160  * Returns the list of login for a protected folder.
161  * @param string $dir The folder to lookup (relative to user root)
162  * @return array An array containing the list of logins from the .htpasswd file, or FALSE
163  */
164  function get_hta_detail($dir) {
165  global $mem,$err;
166  $err->log("hta","get_hta_detail");
167  $absolute=ALTERNC_HTML."/".substr($mem->user["login"],0,1)."/".$mem->user["login"]."/$dir";
168  if (file_exists("$absolute/.htaccess")) {
169  /* if (!_reading_htaccess($absolute)) {
170  return false;
171  }
172  */ }
173  $file = @fopen("$absolute/.htpasswd","r");
174  $i=0;
175  $res=array();
176  if (!$file) {
177  return false;
178  }
179  // TODO: Tester la validité du .htpasswd
180  while (!feof($file)) {
181  $s=fgets($file,1024);
182  $t=explode(":",$s);
183  if ($t[0]!=$s) {
184  $res[$i]=$t[0];
185  $i=$i+1;
186  }
187  }
188  fclose($file);
189  return $res;
190  }
191 
192 
193  /*---------------------------------------------------------------------------*/
194  /**
195  * Unprotect a folder
196  * @param string $dir Folder to unprotect, relative to user root
197  * @return boolean TRUE if the folder has been unprotected, or FALSE if an error occurred
198  */
199  function DelDir($dir) {
200  global $mem,$bro,$err;
201  $err->log("hta","deldir",$dir);
202  $dir=$bro->convertabsolute($dir,0);
203  if (!$dir) {
204  $err->raise("hta",printf(("The folder '%s' does not exist"),$dir));
205  return false;
206  }
207  if (!@unlink("$dir/.htaccess")) {
208  $err->raise("hta",printf(_("I cannot delete the file '%s/.htaccess'"),$dir));
209  return false;
210  }
211  if (!@unlink("$dir/.htpasswd")) {
212  $err->raise("hta",printf(_("I cannot delete the file '%s/.htpasswd'"),$dir));
213  return false;
214  }
215  return true;
216  }
217 
218 
219  /*---------------------------------------------------------------------------*/
220  /**
221  * Add a user to a protected folder
222  * @param string $login The user login to add
223  * @param string $password The password to add (cleartext)
224  * @param string $dir The folder we add it to (relative to user root).
225  * @return boolean TRUE if the user has been added, or FALSE if an error occurred
226  */
227  function add_user($user,$password,$dir) {
228  global $err, $bro, $admin;
229  $err->log("hta","add_user",$user."/".$dir);
230  if (empty($user)) {
231  $err->raise('hta',_("Please enter a user"));
232  return false;
233  }
234  if (empty($password)) {
235  $err->raise('hta',_("Please enter a password"));
236  return false;
237  }
238  $absolute=$bro->convertabsolute($dir,0);
239  if (!file_exists($absolute)) {
240  $err->raise("hta",printf(("The folder '%s' does not exist"),$dir));
241  return false;
242  }
243  if (checkloginmail($user)){
244  // Check this password against the password policy using common API :
245  if (is_callable(array($admin,"checkPolicy"))) {
246  if (!$admin->checkPolicy("hta",$user,$password)) {
247  return false; // The error has been raised by checkPolicy()
248  }
249  }
250 
251  $file = @fopen("$absolute/.htpasswd","a+");
252  if (!$file) {
253  $err->raise("hta",_("File already exist"));
254  return false;
255  }
256  fseek($file,0);
257  while (!feof($file)) {
258  $s=fgets($file,1024);
259  $t=explode(":",$s);
260  if ($t[0]==$user) {
261  $err->raise("hta",_("The user '%s' already exist for this folder"),$user);
262  return false;
263  }
264  }
265  fseek($file,SEEK_END);
266  if ( empty($t[1]) || substr($t[1],-1)!="\n") {
267  fwrite($file,"\n");
268  }
269  fwrite($file, "$user:"._md5cr($password)."\n");
270  fclose($file);
271  return true;
272  } else {
273  $err->raise("hta",_("Please enter a valid username"));
274  return false;
275  }
276  }
277 
278 
279  /*---------------------------------------------------------------------------*/
280  /**
281  * Delete a user from a protected folder.
282  * @param array $lst An array with login to delete.
283  * @param string $dir The folder, relative to user root, where we want to delete users.
284  * @return boolean TRUE if users has been deleted, or FALSE if an error occurred.
285  */
286  function del_user($lst,$dir) {
287  global $bro,$err;
288  $err->log("hta","del_user",$lst."/".$dir);
289  $absolute=$bro->convertabsolute($dir,0);
290  if (!file_exists($absolute)) {
291  $err->raise("hta",printf(_("The folder '%s' does not exist"),$dir));
292  return false;
293  }
294  touch("$absolute/.htpasswd.new");
295  $file = fopen("$absolute/.htpasswd","r");
296  $newf = fopen("$absolute/.htpasswd.new","a");
297  if (!$file || !$newf) {
298  $err->raise("hta",_("File already exist"));
299  return false;
300  }
301  reset($lst);
302  fseek($file,0);
303  while (!feof($file)) {
304  $s=fgets($file,1024);
305  $t=explode(":",$s);
306  if (!in_array($t[0],$lst) && ($t[0]!="\n")) {
307  fseek($newf,0);
308  fwrite($newf, "$s");
309  }
310  }
311  fclose($file);
312  fclose($newf);
313  unlink("$absolute/.htpasswd");
314  rename("$absolute/.htpasswd.new", "$absolute/.htpasswd");
315  return true;
316  }
317 
318 
319  /*---------------------------------------------------------------------------*/
320  /**
321  * Change the password of a user in a protected folder
322  * @param string $user The users whose password should be changed
323  * @param string $newpass The new password of this user
324  * @param string $dir The folder, relative to user root, in which we will change a password
325  * @return boolean TRUE if the password has been changed, or FALSE if an error occurred
326  */
327  function change_pass($user,$newpass,$dir) {
328  global $bro,$err,$admin;
329  $err->log("hta","change_pass",$user."/".$dir);
330  $absolute=$bro->convertabsolute($dir,0);
331  if (!file_exists($absolute)) {
332  $err->raise("hta",printf(_("The folder '%s' does not exist"),$dir));
333  return false;
334  }
335 
336  // Check this password against the password policy using common API :
337  if (is_callable(array($admin,"checkPolicy"))) {
338  if (!$admin->checkPolicy("hta",$user,$newpass)) {
339  return false; // The error has been raised by checkPolicy()
340  }
341  }
342 
343  touch("$absolute/.htpasswd.new");
344  $file = fopen("$absolute/.htpasswd","r");
345  $newf = fopen("$absolute/.htpasswd.new","a");
346  if (!$file || !$newf) {
347  $err->raise("hta",_("File already exist"));
348  return false;
349  }
350  while (!feof($file)) {
351  $s=fgets($file,1024);
352  $t=explode(":",$s);
353  if ($t[0]!=$user) {
354  fwrite($newf, "$s");
355  }
356  }
357  fwrite($newf, "$user:"._md5cr($newpass)."\n");
358  fclose($file);
359  fclose($newf);
360  unlink("$absolute/.htpasswd");
361  rename("$absolute/.htpasswd.new", "$absolute/.htpasswd");
362  return true;
363  }
364 
365 
366  /*---------------------------------------------------------------------------*/
367  /**
368  * Check that a .htaccess file is valid (for authentication)
369  * @param string $absolute Folder we want to check (relative to user root)
370  * @return boolean TRUE is the .htaccess is protecting this folder, or FALSE else
371  * @access private
372  */
373  function _reading_htaccess($absolute) {
374  global $err;
375  $err->log("hta","_reading_htaccess",$absolute);
376  $file = fopen("$absolute/.htaccess","r+");
377  $lignes=array(1,1,1);
378  $errr=0;
379  if (!$file) {
380  return false;
381  }
382  while (!feof($file) && !$errr) {
383  $s=fgets($file,1024);
384  if (substr($s,0,12)!="RewriteCond " && substr($s,0,14)!="ErrorDocument " && substr($s,0,12)!="RewriteRule " && substr($s,0,14)!="RewriteEngine " && trim($s)!="") {
385  $errr=1;
386  }
387  if (strtolower(trim($s))==strtolower("authuserfile $absolute/.htpasswd")) {
388  $lignes[0]=0;
389  $errr=0;
390  } // authuserfile
391  if (strtolower(trim($s))=="require valid-user") {
392  $lignes[1]=0;
393  $errr=0;
394  } //require
395  if (strtolower(trim($s))=="authtype basic") {
396  $lignes[2]=0;
397  $errr=0;
398  } //authtype
399  } // Reading config file
400  fclose($file);
401  if ($errr || in_array(0,$lignes)) {
402  $err->raise("hta",_("An incompatible .htaccess file exists in this folder"));
403  return false;
404  }
405  return true;
406  }
407 
408 } /* CLASS m_hta */
409 
410