ActiveState Code

Recipe 108479: php htaccess


The htaccess class manages the htaccess functions of Apache Webservers. Without knowing much knowledge of Apache, users can be added or deleted, groups can be created anddeleted, .htaccess files can be created with this class etc.

PHP
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
<?

/**
* Class for handling htaccess of Apache
* @author    Sven Wagener <sven.wagener@intertribe.de>
* @copyright Intertribe - Internetservices Germany
* @include 	 Funktion:_include_
*/

class htaccess{
    var $fHtaccess=""; // path and filename for htaccess file
    var $fHtgroup="";  // path and filename for htgroup file
    var $fPasswd="";   // path and filename for passwd file
    
    var $authType="Basic"; // Default authentification type
    var $authName="Internal area"; // Default authentification name

    /**
    * Initialising class htaccess
    */
    function htaccess(){
    }

    /**
    * Sets the filename and path of .htaccess to work with
    * @param string	$filename    the name of htaccess file
    */
    function setFHtaccess($filename){
        $this->fHtaccess=$filename;
    }
    
    /**
    * Sets the filename and path of the htgroup file for the htaccess file
    * @param string	$filename    the name of htgroup file
    */
    function setFHtgroup($filename){
        $this->fHtgroup=$filename;
    }
    
    /**
    * Sets the filename and path of the password file for the htaccess file
    * @param string	$filename    the name of htgroup file
    */
    function setFPasswd($filename){
        $this->fPasswd=$filename;
    }

    /**
    * Adds a user to the password file
    * @param string $username     Username
    * @param string $password     Password for Username
    * @param string $group        Groupname for User (optional)
    * @return boolean $created         Returns true if user have been created otherwise false
    */
    function addUser($username,$password,$group){
        // checking if user already exists
        $file=@fopen($this->fPasswd,"r");
        $isAlready=false;
        while($line=@fgets($file,200)){
            $lineArr=explode(":",$line);
            if($username==$lineArr[0]){
                $isAlready=true;
             }
        }
        
        if($isAlready==false){
            $file=fopen($this->fPasswd,"a");

            $password=crypt($password);
            $newLine=$username.":".$password."\n";

            fputs($file,$newLine);
            fclose($file);
            return true;
        }else{
            return false;
        }
    }

    /**
    * Adds a group to the htgroup file
    * @param string $groupname     Groupname
    */
    function addGroup($groupname){
        $file=fopen($this->fHtgroup,"a");
        fclose($file);
    }

    /**
    * Deletes a user in the password file
    * @param string $username     Username to delete
    * @return boolean $deleted    Returns true if user have been deleted otherwise false
    */
    function delUser($username){
        // Reading names from file
        $file=fopen($path.$this->fPasswd,"r");
        $i=0;
        while($line=fgets($file,200)){
            $lineArr=explode(":",$line);
            if($username!=$lineArr[0]){
                $newUserlist[$i][0]=$lineArr[0];
                $newUserlist[$i][1]=$lineArr[1];
                $i++;
            }else{
                $deleted=true;
            }
        }
        fclose($file);

        // Writing names back to file (without the user to delete)
        $file=fopen($path.$this->fPasswd,"w");
        for($i=0;$i<count($newUserlist);$i++){
            fputs($file,$newUserlist[$i][0].":".$newUserlist[$i][1]."\n");
        }
        fclose($file);
        
        if($deleted==true){
            return true;
        }else{
            return false;
        }
    }
    
    /**
    * Returns an array of all users in a password file
    * @return array $users         All usernames of a password file in an array
    * @see setFPasswd()
    */
    function getUsers(){
    }
    
    /**
    * Sets a password to the given username
    * @param string $username     The name of the User for changing password
    * @param string $password     New Password for the User
    * @return boolean $isSet      Returns true if password have been set
    */    
    function setPasswd($username,$new_password){
        // Reading names from file
        $newUserlist="";
        
        $file=fopen($this->fPasswd,"r");
        $x=0;
        for($i=0;$line=fgets($file,200);$i++){
            $lineArr=explode(":",$line);
            if($username!=$lineArr[0] && $lineArr[0]!="" && $lineArr[1]!=""){
                $newUserlist[$i][0]=$lineArr[0];
                $newUserlist[$i][1]=$lineArr[1];
                $x++;
            }else if($lineArr[0]!="" && $lineArr[1]!=""){
                $newUserlist[$i][0]=$lineArr[0];
                $newUserlist[$i][1]=crypt($new_password)."\n";
                $isSet=true;
                $x++;
            }
        }
        fclose($file);

        unlink($this->fPasswd);

        /// Writing names back to file (with new password)
        $file=fopen($this->fPasswd,"w");
        for($i=0;$i<count($newUserlist);$i++){
            $content=$newUserlist[$i][0].":".$newUserlist[$i][1];
            fputs($file,$content);
        }
        fclose($file);

        if($isSet==true){
            return true;
        }else{
            return false;
        }
    }

    /**
    * Sets the Authentification type for Login
    * @param string $authtype     Authentification type as string
    */
    function setAuthType($authtype){
        $this->authType=$authtype;
    }

    /**
    * Sets the Authentification Name (Name of the login area)
    * @param string $authname     Name of the login area
  	*/
    function setAuthName($authname){
        $this->authName=$authname;
    }

    /**
    * Writes the htaccess file to the given Directory and protects it
    * @see setFhtaccess()
  	*/
    function addLogin(){
       $file=fopen($this->fHtaccess,"w+");
       fputs($file,"Order allow,deny\n");
       fputs($file,"Allow from all\n");
       fputs($file,"AuthType        ".$this->authType."\n");
       fputs($file,"AuthUserFile    ".$this->fPasswd."\n\n");
       fputs($file,"AuthName        \"".$this->authName."\"\n");
       fputs($file,"require valid-user\n");
       fclose($file);
    }

    /**
    * Deletes the protection of the given directory
    * @see setFhtaccess()
    */
    function delLogin(){
        unlink($this->fHtaccess);
    }
}
?>

Discussion

setFPasswd("/var/www/htpasswd");

// Setting up path of password file $ht->setFHtaccess("/var/www/.htaccess");

// Adding user $ht->addUser("username","0815");

// Changing password for User $ht->setPasswd("username","newPassword");

// Deleting user $ht->delUser("username");

// Setting authenification type // If you don't set, the default type will be "Basic" $ht->setAuthType("Basic");

// Setting authenification area name // If you don't set, the default name will be "Internal Area" $ht->setAuthName("My private Area");

//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // finally you have to process addLogin() // to write out the .htaccess file $ht->addLogin();

// To delete a Login use the delLogin function $ht->delLogin();

?>

Comments

  1. 1. At 5:48 p.m. on 22 feb 2002, Mark Nenadov said:

    Nice! Nice. I see where this could really come in handy!!!

    A few comments, though: Is there any reason why the developer shouldn't be able to include password in addUser()? Also, this may be going overboard, but it would be nice to break this down into more objects For example, it would be nice to have users as object (ie. you could add 'user' objects to the htaccess class). Using that method it would be easy to store users and syndicate them across various servers.

  2. 2. At 9:01 a.m. on 21 apr 2002, Marc Hensel said:

    Good Work. Very helpfull scripting - I used parts of it to add usernames on the fly and to remove them. I found an error while deleting a username:

    fputs($file,$newUserlist[$i][0].":".$newUserlist[$i][0]."\n");

    Should be:

    fputs($file,$newUserlist[$i][0].":".$newUserlist[$i][1]."\n");

    Otherwise it writes

    username:username

    into the .htpasswd file. Also if you leave "\n" out you get

    username:password

    username:password

    I found this out since my htpasswd file contains around 600 usernames/passwords.

  3. 3. At 6:34 a.m. on 25 apr 2002, Sven Wagener (the author) said:

    Bug in delUser function. Thank you! I fixed the bug!

  4. 4. At 4:09 a.m. on 29 jan 2004, Richard said:

    Didn't quite work. I had to change the line in question from:

    fputs($file,$newUserlist[$i][0].":".$newUserlist[$i][1]."\n");

    to:

    fputs($file,$newUserlist[$i][0].":".$newUserlist[$i][1]);

    ... or else it put an extra line between each user:passwd in the .htpasswd file. And it fell over when I had about 800 users in the file.

  5. 5. At 7:08 a.m. on 30 mar 2004, Philip Price said:

    PHP interface to authentification. Is there a php script that will interface with the htaccess authentification so that the login can be contained on a form on the php page, instead of the popup windows that defaults with Linux systems?

  6. 6. At 8:30 a.m. on 30 mar 2004, Philip Price said:

    bypass the HTTP authentification. What I am asking is for a way to bypass the HTTP authentification by passing login information via php wcript to the server. This will maintain the directory protection at the server level and allow a single login (in a form on the page).

  7. 7. At 5:50 a.m. on 24 nov 2004, Andreas Kloss said:

    Shamelessly lifted from a comment in the PHP manual. Here is some code that mimics the standard behaviour:

    function authenticate(){
      header("WWW-Authenticate: Basic realm=\"Members\"");
      header('HTTP/1.0 401 Unauthorized');
      echo "Please enter a valid user name and password.";
      exit;
    }
    
    for(; 1; authenticate()){
      if (!isset($HTTP_SERVER_VARS['PHP_AUTH_USER'])) continue;
      $user = $HTTP_SERVER_VARS['PHP_AUTH_USER'];
      if(!($authUserLine =
        array_shift(preg_grep("/$user:.*$/",
        file("/home/kloss/html/test/.htpasswd"))))) continue;
      preg_match("/$user:((..).*)$/", $authUserLine, $matches);
      $authPW = $matches[1];
      $salt = $matches[2];
      $submittedPW = crypt($HTTP_SERVER_VARS['PHP_AUTH_PW'], $salt);
      if($submittedPW != $authPW) continue;
      break;
    }
    

    Changing the authenticate method to show your login form and checking for the user/passwd form variables instead of PHP_AUTH_USER/PW should do the trick.

  8. 8. At 7:30 a.m. on 13 jul 2005, Dagfinn Haslebrekk said:

    HOWTO?? bypass the HTTP authentification. Hi!

    I have just read your tutorial on how to create a htaccess class, and i like it :-) But could you please describe in more detail how you bypass the http authentification popup form? I did not quite understand how I could do this with the code lifted from the php manual.

    Thanks!

  9. 9. At 1:13 a.m. on 16 may 2006, abu aslam said:

    HOWTO?? bypass the HTTP authentification. Dear All,

    This is a very nice document. Thanks for this to the writer and the viewer for their comments. I will wonder if any once can inform the way to by pass the htaccess authentication from the Web Login form. I mean, vistors will supply their user name and passsword in a php page and and will authenticate the htaccess and allow the authorized users.

    Regards,

    Aslam

Sign in to comment