User Tools

Site Tools


howtos:pure-ftpd

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
howtos:pure-ftpd [d/m/Y H:i]
domingo
howtos:pure-ftpd [d/m/Y H:i] (current)
Line 1: Line 1:
 +====== Pure-FTPd with MySQL ======
  
 +This is how I setup my ftp server with Pure-FTPd and MySQL as backend for authentication and user profiles
 + and sOLARiZ PureFTPd Manager as interface to MySQL.
 +
 +===== Pure-FTPd Setup =====
 +
 +Install Pure-FTPd the way you like it. As I use SuSE 9.3 I use the version bundled with the distribution and hence use the "SuSE Standard" for file locations. 
 +
 +Start out by editing the ///etc/pure-ftpd/pure-ftpd.conf// file to make use of MySQL as backend. 
 +Mine looks like this:
 +
 +<file>
 +ChrootEveryone              yes
 +BrokenClientsCompatibility  no
 +MaxClientsNumber            10
 +Daemonize                   yes
 +MaxClientsPerIP             3
 +VerboseLog                  no
 +AllowDotFiles               yes
 +DisplayDotFiles             yes
 +AnonymousOnly               no
 +NoAnonymous                 yes
 +SyslogFacility              ftp
 +DontResolve                 yes
 +MaxIdleTime                 15
 +MySQLConfigFile               /etc/pure-ftpd/pureftpd-mysql.conf
 +LimitRecursion              2000 8
 +AnonymousCanCreateDirs      no
 +MaxLoad                     4
 +Umask                       177:077
 +MinUID                      100
 +AllowUserFXP                no
 +AllowAnonymousFXP           no
 +ProhibitDotFilesWrite       no
 +ProhibitDotFilesRead        no
 +AutoRename                  yes
 +AnonymousCantUpload         yes
 +NoChmod                     yes
 +CreateHomeDir               yes
 +MaxDiskUsage               99
 +NoRename                  yes
 +CustomerProof              yes
 +</file>
 +
 +
 +Lets create ///etc/pure-ftpd/pureftpd-mysql.conf//:
 +
 +<file>
 +MYSQLServer     localhost
 +MYSQLPort       3306
 +MYSQLUser       ftpd
 +MYSQLPassword   123456
 +MYSQLDatabase   System
 +MYSQLCrypt      md5
 +MYSQLGetPW      SELECT Password FROM ftpd WHERE User="\L" AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
 +MYSQLGetUID     SELECT Uid FROM ftpd WHERE User="\L" AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
 +MYSQLGetGID     SELECT Gid FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
 +MYSQLGetDir     SELECT Dir FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
 +MySQLGetBandwidthUL SELECT ULBandwidth FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
 +MySQLGetBandwidthDL SELECT DLBandwidth FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
 +MySQLGetQTASZ   SELECT QuotaSize FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
 +MySQLGetQTAFS   SELECT QuotaFiles FROM ftpd WHERE User="\L"AND status="1" AND (ipaccess = "*" OR ipaccess LIKE "\R")
 +</file>
 +
 +
 +
 +
 +===== MySQL =====
 +
 +Install MySQL on a server or use a already installed one. Again I use the one following SuSE 9.3.
 +
 +I use a thirdparty PHP interface to the MySQL database called [[http://www.solariz.de/|sOLARiZ PureFTPd Manager]], so I also have Apache2 with PHP and PHP-mysql installed. You can also download it here {{:howtos:pureftp-mgr.tar|pureftp-mgr.tar}}
 +
 +You can configure the MySQL database in many ways and make use of a lot of Pure-FTPd's features, but as I'm using PureFTPd Manager I'm bound to its design. 
 +
 +Create a database:
 +
 +<code>
 +# mysqladmin -u root -p create System
 +</code>
 +
 +Next make the following file called //create.sql//:
 +
 +<file>
 + DROP TABLE IF EXISTS ftpd;
 +                CREATE TABLE ftpd (
 +                User varchar(16) NOT NULL default '',
 +                status enum('0','1') NOT NULL default '0',
 +                Password varchar(64) NOT NULL default '',
 +                Uid varchar(11) NOT NULL default '-1',
 +                Gid varchar(11) NOT NULL default '-1',
 +                Dir varchar(128) NOT NULL default '',
 +                ULBandwidth smallint(5) NOT NULL default '0',
 +                DLBandwidth smallint(5) NOT NULL default '0',
 +                comment tinytext NOT NULL,
 +                ipaccess varchar(15) NOT NULL default '*',
 +                QuotaSize smallint(5) NOT NULL default '0',
 +                QuotaFiles int(11) NOT NULL default 0,
 +                PRIMARY KEY (User),
 +                UNIQUE KEY User (User)
 +                ) TYPE=MyISAM;
 +</file>
 +
 +Use this file to create the our user table:
 +
 +<code>
 +# mysql -u root -p System < create.sql
 +</code>
 +
 +Use this file, //create-user.sql//, to create the ftpd user and its rights:
 +
 +<file>
 +USE mysql;
 +INSERT INTO user (Host, User, Password) VALUES ('localhost','ftpd',password('123456'));
 +INSERT INTO db (Host, Db, User, Select_priv, Insert_priv, Update_priv, Delete_priv) VALUES ('localhost', 'System', 'ftpd', 'Y', 'Y', 'Y', 'Y');
 +FLUSH PRIVILEGES;
 +GRANT SELECT, INSERT, DELETE, UPDATE ON System.* TO ftpd@localhost;
 +</file>
 +
 +Now run it:
 +
 +<code>
 +# mysql -u root -p -h localhost < create-ftpd.sql
 +</code>
 +
 +===== Apache2 =====
 +
 +Now copy the sOLARiZ PureFTPd Manager files into your documentroot somewhere. As we are dealing with usernames and passwords I like to use https. With SuSE 9.3 the tool //gensslcert// will make the certificate for you. If you aren't using SuSE, look at the manpages for openssl. To make use of this I have created ///etc/apache2/vhosts.d/pureftpd.conf//:
 +
 +<file>
 +Listen 666
 +<VirtualHost _default_:666>
 +DocumentRoot "/srv/www/htdocs/pureftpd"
 +ServerName localhost:666
 +ServerAdmin you@example.com
 +ErrorLog /var/log/apache2/pureftpd_error_log
 +TransferLog /var/log/apache2/pureftpd_access_log
 +SSLEngine on
 +SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
 +SSLCertificateFile /etc/apache2/ssl.crt/server.crt
 +SSLCertificateKeyFile /etc/apache2/ssl.key/server.key
 +<Directory "/srv/www/htdocs/pureftpd">
 +    SSLOptions +StdEnvVars
 +    SSLRequireSSL
 +</Directory>
 +SetEnvIf User-Agent ".*MSIE.*" \
 +         nokeepalive ssl-unclean-shutdown \
 +         downgrade-1.0 force-response-1.0
 +CustomLog /var/log/apache2/postfixadmin_request_log \
 +          "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
 +<Directory /srv/www/htdocs/pureftpd>
 +    AllowOverride AuthConfig
 +    Order deny,allow
 +    Allow from all
 +</Directory>
 +</VirtualHost>
 +</file>
 +
 +This creates an https webinterface listening on port 666/tcp. To enter this interface you browse to https://yourserver:666
 +
 +I would like to be the only one accessing this interface and therfor we need some authentication. Create .htaccess in the documentroot /srv/www/htdocs/pureftpd/:
 +
 +<file>
 +AuthUserFile /srv/www/htdocs/pureftpd/.htpasswd
 +AuthGroupFile /dev/null
 +AuthName "Pure-ftpd Admin"
 +AuthType Basic
 +
 +<limit GET POST>
 +require valid-user
 +</limit>
 +</file>
 +
 +Create the htpasswd file and create a admin user:
 +
 +<code>
 +# htpasswd2 -c /srv/www/htdocs/pureftpd/.htpasswd admin
 +</code>
 +
 +===== PureFTPd Manager =====
 +
 +Create a user and group called "//pureftpd//".
 +
 +Extract the PureFTPd Manager files into "///srv/www/htdocs/pureftpd//".
 +
 +To make use of md5 instead of crypt I changed "//index.php//" to:
 +
 +<file>
 +<?
 +// Aenderungen 25.5. Uwe Ahrendt
 +// www.bildpartner.de
 +
 +// READ THE README !!!
 +/****************************************************
 + * PureFTP - PHP USer Manager by solariz
 + * Source (c) 2002 - www.solariz.de
 + ****************************************************
 + CheckOut:  http://www.solariz.de
 +*/
 +
 +include("pureftp.config.php");
 +
 +#################################################################
 +############### NO NEED FOR CHANGES BELOW HERE ##################
 +#################################################################
 +// Config einlesen
 +        if(!file_exists($PUREFTP_CONFIG_FILE)) DIE("FATAL ERROR: Pure FTPD Config file not found.<br />$PUREFTP_CONFIG_FILE");
 +        $USERARRAY = array();
 +        $raw = file($PUREFTP_CONFIG_FILE);
 +        foreach($raw AS $zeile):
 +                if(!ereg("^#",$zeile)): #skip comments
 +                        // Einlesen der einzelnen Zeilen als Variable
 +                                $tmp = split(" ",trim($zeile));
 +                                // UNIX Tab workaround
 +                                if(count($tmp) < 2)
 +                                        $tmp = explode("\t",trim($zeile));
 +                                $var = strtoupper(trim($tmp[0]));
 +                                for($n=1;$n<count($tmp);++$n) {
 +                                        if(!empty($tmp[$n])) {
 +                                                $$var = trim($tmp[$n]);
 +                                                break;
 +                                        }#end if
 +                                }#end for
 +                        // Einlesen der Tabelle
 +                                if(empty($DB_TABLE) AND eregi("FROM\ [[:alnum:]]{1,20}\ WHERE",$zeile)):
 +                                        $tmp2 = split("FROM ",$zeile);
 +                                        $tmp2 = split(" WHERE",trim($tmp2[1]));
 +                                        $DB_TABLE = trim($tmp2[0]);
 +                                        unset($tmp2);
 +                                EndIF;
 +                EndIf;
 +        EndForEach;
 +        if(empty($MYSQLSERVER)) $MYSQLSERVER = "localhost";
 +        if(empty($DB_TABLE))    DIE("ERROR: Config error in pureftpd config file. No table specified.");
 +// UA
 +        if ($MYSQLCRYPT == "md5") {$PW = TRUE;} else {$PW = FALSE;}
 +
 +// Current Version
 +        $VERSION = "2.50";
 +        $BUILD          = "1018";
 +
 +// Setein header
 +        PAGE_HEADER();
 +
 +// SQL Connection herstellen
 +        DB_OPEN();
 +
 +
 +// FORM SUBIT AUSWERTUNG // Globals
 +        $action         = get_var("action");
 +        $user           = get_var("user");
 +
 +if( $action == "edit" || $action == "add" ) {
 +        // ADD value setter
 +
 +                if($action == "add"):
 +                                $USERARRAY['User'             = $DefaultUser;
 +// UA
 +                                if ($PW) {$USERARRAY['Password'       = md5($DefaultPass); }
 +                                        else {$USERARRAY['Password'   = $DefaultPass; }
 +                                $USERARRAY['Password' = $DefaultPass;
 +                                $USERARRAY['Uid'              = $DefaultUid;
 +                                $USERARRAY['Gid'              = $DefaultGid;
 +                                $USERARRAY['Dir'              = $DefaultDir;
 +                                $USERARRAY['ULBandwidth'      = $DefaultUL;
 +                                $USERARRAY['DLBandwidth'      = $DefaultDL;
 +                                $USERARRAY['ipaccess' = $Defaultip;
 +                                $USERARRAY['QuotaSize'] = $DefaultQS;
 +// UA
 +                                $USERARRAY['QuotaFiles'       = $DefaultQF;
 +        $USERARRAY['comment'       = $Defaultcmt;
 +                                else:
 +                                unset($USERARRAY);
 +                EndIf;
 +
 +                if(!empty($user) AND $user != "0") {
 +                                $USERARRAY=@MYSQL_FETCH_ARRAY(DB_QUERY("SELECT * FROM `$DB_TABLE` WHERE User LIKE '$user'"));
 +                }#end if
 +                if(!is_array($USERARRAY)) DIE("User Not found or DB error.<br />".mysql_error());
 +
 +        echo '<form method=post action="'.$SELF_URL.'" onSubmit="return checkrequired(this)">';
 +
 +        if(!empty($user))       echo '<input type="hidden" name="requireduser" value="'.stripslashes($USERARRAY['User']).'">';
 +        else                                            echo '<input type="hidden" name="addnew" value="True">';
 +        echo '<input type="hidden" name="action" value="save">';
 +        echo '<table width="100%" class=TABLE>';
 +        echo '<tr><th>Status</th><td class=TD><input type="radio" name="status" value="0"';
 +        if($USERARRAY['status'] == 0) echo ' checked';
 +        echo '> Inactive&nbsp;&nbsp;&nbsp;<input type="radio" name="status" value="1"';
 +        if($USERARRAY['status'] == 1) echo ' checked';
 +        echo '> Active</td></tr>';
 +
 +        if(!empty($user))       {
 +                echo '<tr><th>Delete user ?</th><td class=TD><input type="checkbox" name="delete"> Yes, i am know exactly what i am doing! (NO UNDO)</td></tr>';
 +                echo '<tr><th>Username</th><td class=TD>'.stripslashes($USERARRAY['User']).'</td></tr>';
 +        }
 +
 +        else
 +
 +        echo '<tr><th>Username</th><td class=TD><input type="text" name="requireduser" class="input"></td></tr>';
 +        echo '<tr>';
 +        echo '<th>Password</th>';
 +// UA
 +        if ($PW) {
 +                echo '<td class=TD><input type="text" name="requiredpass" value="<crypted>" class="input"></td></tr>';
 +        } else {
 +                echo '<td class=TD><input type="text" name="requiredpass" value="'.stripslashes($USERARRAY['Password']).'" class="input"></td></tr>';
 +        }
 +        echo '<tr><th>UID</th><td class=TD><input type="text" name="requireduid" value="'.stripslashes($USERARRAY['Uid']).'" class="input"></td></tr>';
 +        echo '<tr><th>GID</th><td class=TD><input type="text" name="requiredgid" value="'.stripslashes($USERARRAY['Gid']).'" class="input"></td></tr>';
 +        echo '<tr><th>DIR</th><td class=TD><input type="text" name="requireddir" value="'.stripslashes($USERARRAY['Dir']).'" class="input"></td></tr>';
 +    echo '<tr><th>UL Throttle kb/s</th><td class=TD><input type="text" name="requiredulthrottle" value="'.stripslashes($USERARRAY['ULBandwidth']).'" class="input"></td></tr>';
 +    echo '<tr><th>DL Throttle kb/s</th><td class=TD><input type="text" name="requireddlthrottle" value="'.stripslashes($USERARRAY['DLBandwidth']).'" class="input"></td></tr>';
 +        echo '<tr><th>IP ACCESS</th><td class=TD><input type="text" name="requiredipaccess" value="'.stripslashes($USERARRAY['ipaccess']).'" class="input"><br /><small>Type in <b>*</b> for any IP</td></tr>';
 +// UA
 +        echo '<tr><th>QuotaSize in MB</th><td class=TD><input type="text" name="requiredQuotaSize" value="'.stripslashes($USERARRAY['QuotaSize']).'" class="input"><br /><small>Type in <b>0</b> for NO VirtualQuotaSize</td></tr>';
 +// UA
 +        echo '<tr><th>QuotaFiles Anzahl</th><td class=TD><input type="text" name="requiredQuotaFiles" value="'.stripslashes($USERARRAY['QuotaFiles']).'" class="input"><br /><small>Type in <b>0</b> for NO VirtualQuotaFiles</td></tr>';
 +        echo '<tr><th>COMMENT</th><td class=TD><textarea name="comment" rows="6" cols="20" class="input">'.stripslashes($USERARRAY['comment']).'</textarea></td></tr>';
 +        echo '</table>';
 +        echo '<center><input type="submit" value="Save" class="button" width="100%"></center></form>';
 +
 +}#end edit
 +
 +elseif($action == "save") {
 +        $addnew         = addslashes( get_var("addnew") );
 +        $User           = addslashes(get_var("requireduser"));
 +
 +        // UA - MG Optimized ;)
 +        $Password = addslashes(get_var("requiredpass"));
 +
 +        IF($Password == '<crypted>'   $Password = '';
 +        ELSEif($PW)                                             $Password = md5($Password);
 +
 +        $Uid            = addslashes(get_var("requireduid"));
 +        $Gid            = addslashes(get_var("requiredgid"));
 +        $Dir            = addslashes(get_var("requireddir"));
 +    $ULThrottle        = addslashes(get_var("requiredulthrottle"));
 +    $DLThrottle        = addslashes(get_var("requireddlthrottle"));
 +        $QuotaSize      = addslashes(get_var("requiredQuotaSize"));
 +// UA
 +        $QuotaFiles     = addslashes(get_var("requiredQuotaFiles"));
 +        $comment        = addslashes(get_var("comment"));
 +        $status         = addslashes(get_var("status"));
 +        $delete         = addslashes(get_var("delete"));
 +        $ipaccess   = addslashes(get_var("requiredipaccess"));
 +        if(empty($User) ||  empty($Uid) || empty($Gid) || empty($Dir)) DIE("Invalid or missing data entered...");
 +        if(empty($delete)) {
 +                // Mini workarounds
 +                        if($Password)   $PW_QUERY = ",Password='$Password'";
 +                        if(!$status)            $status = (string) '0';
 +                        if(!$ULBandwidth)       $ULBandwidth = (string) '0';
 +                        if(!$DLBandwidth)       $DLBandwidth = (string) '0';
 +                        if(!$QuotaSize)         $QuotaSize = (string) '0';
 +                        if(!$QuotaFiles)        $QuotaFiles = (string) '0';
 +                if($addnew == False) {
 +                        $SQL    = "UPDATE `$DB_TABLE` SET status='$status'".$PW_QUERY.",Uid='$Uid',Gid='$Gid',Dir='$Dir',ULBandwidth='$ULThrottle',DLBandwidth='$DLThrottle',comment='$comment',ipaccess='$ipaccess',QuotaSize='$QuotaSize',QuotaFiles='$QuotaFiles' WHERE User LIKE '$User' LIMIT 1";
 +                        $Q              = DB_QUERY($SQL);
 +                        if($Q)  echo "<SCRIPT LANGUAGE=\"JavaScript\">\n<!--\nalert(\"User updated.\");\n//-->\n</SCRIPT>\n";
 +                }#end if
 +                else{
 +                        $Q              = DB_QUERY("INSERT INTO `$DB_TABLE` SET User='$User',status='$status'".$PW_QUERY.",Uid='$Uid',Gid='$Gid',Dir='$Dir',ULBandwidth='$ULThrottle',DLBandwidth='$DLThrottle',comment='$comment',ipaccess='$ipaccess',QuotaSize='$QuotaSize',QuotaFiles='$QuotaFiles'");
 +                        if($Q)  echo "<SCRIPT LANGUAGE=\"JavaScript\">\n<!--\nalert(\"User added.\");\n//-->\n</SCRIPT>\n";
 +                }#end if
 +
 +        }#end if
 +        elseif($User && !empty($delete)){#DELETE
 +                        $Q              = DB_QUERY("DELETE FROM `$DB_TABLE` WHERE User LIKE '$User' LIMIT 1");
 +                        if($Q)  echo "<SCRIPT LANGUAGE=\"JavaScript\">\n<!--\nalert(\"User deleted.\");\n//-->\n</SCRIPT>\n";
 +        }#end if
 +        echo "<SCRIPT LANGUAGE=\"JavaScript\">\n<!--\nopener.location.reload();close();\n//-->\n</SCRIPT>\n";
 +}#end else (save)
 +
 +######
 +elseif($action == "ftpwho") {
 +
 +echo '<table border="4">';
 + exec($FTP_WHO." -s", $ftpresult );
 + $arraySize = sizeof($ftpresult);
 + $x = 0;
 +echo '<table width="100%" class=TABLE>';
 +echo '<th class=THsmall>PID</td>';
 +echo '<th class=THsmall>user</td>';
 +echo '<th class=THsmall>min\'s</td>';
 +echo '<th class=THsmall>state</td>';
 +echo '<th class=THsmall>file</td>';
 +echo '<th class=THsmall>IP</td>';
 +echo '<th class=THsmall>current</td>';
 +echo '<th class=THsmall>total</td>';
 +echo '<th class=THsmall>%</td>';
 +echo '<th class=THsmall>bw.</td>';
 +while($x < $arraySize):
 +         $ftpwho = $ftpresult[$x];
 +         list($pid, $user, $mins, $state, $file, $host, $port,$h, $current, $total, $percent, $bandwidth ) = explode("|", $ftpwho );
 +         $mins = round($mins / 60);
 +         if (empty($file) or !isset($file)) {
 +                 ( $file = "---" );
 +                 ++$ftp_activity;
 +         }
 +         else {
 +                if(strlen($file) > 10)
 +                        $file_short = substr($file,0,10);
 +                        $file = "<a href=\"#\" onClick=\"javascript:alert('$file');\">$file_short...</a>";
 +         }#end else
 +         $host = gethostbyname($host);
 +                echo '<tr>';
 +                echo '<td class=TDsmall>' .$pid. '</td>';
 +                echo '<td class=TDsmall>' .$user. '</td>';
 +                echo '<td class=TDsmall>' .$mins. '</td>';
 +                echo '<td class=TDsmall>' .$state. '</td>';
 +                echo '<td class=TDsmall>' .$file. '</td>';
 +                echo '<td class=TDsmall>' .$host. '</td>';
 +                echo '<td class=TDsmall>' .$current. '</td>';
 +                echo '<td class=TDsmall>' .$total. '</td>';
 +                echo '<td class=TDsmall>' .$percent. '</td>';
 +                echo '<td class=TDsmall>' .$bandwidth. ' kb/s</td>';
 +                echo '</tr>';
 +          $x++;
 +EndWhile;
 +echo '</table>';
 +if(!$ftp_activity) echo 'No users currenty using the FTP.<br>';
 +
 +echo '<p><center><input type=button value=" Close " onclick=self.close()>';
 +echo '<input type=button value=" Refresh " onClick=" JavaScript : window.location.reload()"></center>';
 +
 +
 +}#end else (ftpwho)
 +######
 +elseif($action == "info") {
 +?>
 +        <font color=gray face="Verdana,Arial">
 +        <b>sOLARiZ PureFTPd Manager</b><br>
 +        Version <?=$VERSION?> Build <?=$BUILD?><br><br>
 +        About
 +        <ul class="small_font">
 +          The first version of this Script was developed roughly at the end of 2001 in need of a simplyfied remote FTP administration. Since this many user submited changes / updates were integrated. If you got special wishes please let me know via mail.<br>
 +          One thing to note; I don't take any guarantee either I'm not liable for possible caused damage. This script is free no need to pay for it. But if you like it im be glad for a donation. Everything is welcome e.g. a PayPAL donation:<br>
 +          <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
 +          <input type="hidden" name="cmd" value="_xclick">
 +          <input type="hidden" name="business" value="paypal@solariz.de">
 +          <input type="hidden" name="item_name" value="PureFTPd Manager Donation">
 +          <input type="hidden" name="no_note" value="1">
 +          <input type="hidden" name="currency_code" value="EUR">
 +          <input type="hidden" name="tax" value="0">
 +          <input type="image" src="http://www.solariz.de/x-click-but04.gif" border="0" name="submit" alt="Zahlen Sie mit PayPal - schnell, kostenlos und sicher!">
 +          </form>
 +          <br>
 +          For Information or other stuff regarding pureFTPd Manager or other scripts please visit <a href="http://www.solariz.de" target=_blank>www.solariz.de</a>
 +        </ul>
 +              ChangeLog
 +                                <ul class="small_font">
 +                                <?
 +                                        $raw = file("history.txt");
 +                                        foreach($raw AS $hline):
 +                                                        echo stripslashes($hline)."<br>\n";
 +                                        EndForEach;
 +                                ?>
 +                                </ul>
 +
 +<?
 +}
 +ELSE {
 +// User auslesen und in Table darstellen
 +        $viewpw = get_var("viewpw");
 +        $Q=DB_QUERY("SELECT * FROM `$DB_TABLE` ORDER BY User");
 +        echo '<table width="100%" class=TABLE>';
 +        echo '<tr><th>LOGIN</th>';
 +        if($viewpw) echo '<th>PASSWORD</th>';
 +// UA
 +        echo '<th>UID</th><th>GID</th><th>DIR</th><th>UL/ks</th><th>DL/ks</th><th>Quota Size</th><th>Quota Files</th><th>IP Access</th><th>Status</th><th>&nbsp;</th></tr>';
 +        WHILE($R=MYSQL_FETCH_ARRAY($Q)) {
 +                echo '<tr>';
 +                echo '<td class=TD>'.$R['User'].'</td>';
 +                if($viewpw) echo '<td class=TDPW>'.$R['Password'].'</td>';
 +                echo '<td class=TD>'.$R['Uid'].'</td>';
 +                echo '<td class=TD>'.$R['Gid'].'</td>';
 +                echo '<td class=TD>'.$R['Dir'].'</td>';
 +                if($R['ULBandwidth'])   echo '<td class=TD>'.$R['ULBandwidth'].'</td>';
 +                ELSE                                                            echo '<td class=TD>-</td>';
 +                if($R['DLBandwidth'])   echo '<td class=TD>'.$R['DLBandwidth'].'</td>';
 +                ELSE                                                            echo '<td class=TD>-</td>';
 +                if($R['QuotaSize'])     echo '<td class=TD>'.$R['QuotaSize'].' MB</td>';
 +                ELSE                                                    echo '<td class=TD>-</td>';
 +// UA
 +                if($R['QuotaFiles'])    echo '<td class=TD>'.$R['QuotaFiles'].'</td>';
 +                ELSE                                                    echo '<td class=TD>-</td>';
 +                echo '<td class=TD>'.$R['ipaccess'].'</td>';
 +                if($R['status'] == '0'        echo '<td class="inactive">inactive</td>';
 +                elseif($R['status'] == '1'    echo '<td class="active">active</td>';
 +                echo "<td width=30 class=TD><img src=\"gfx/ed.gif\" onClick=\"javascript:fenster('$SELF_URL?action=edit&user=".$R['User']."')\"></td>";
 +
 +                echo "</tr>\n";
 +        }#end while
 +        echo '</table>';
 +        ?>
 +                <table width="100%" class=TABLE2>
 +                        <tr>
 +                                <td align=left>
 +        <font color=gray>
 +                                        PureFTP User Management.<br />
 +                                        v<?=$VERSION?> written by sOLARiZ <br />
 +                                        [<a href="javascript:fenster('<?=$SELF_URL?>?action=info')"><font color=#BA031B size=1>Information</font></a>]<br />
 +                                </td>
 +                                <td>&nbsp;</td>
 +                                <td align=right valign=top>
 +        <?
 +        // Nav Button stuff
 +                echo "<table cellspacing=0 cellpadding=0><tr>";
 +                // Add User Button
 +                                ECHO "<td><input type=\"image\" src=\"gfx/addusr.gif\" class=button onClick=\"javascript:fenster('$SELF_URL?action=add')\"></td>";
 +                // View Password Button
 +                                echo '<form method=post action="'.$PHP_SELF.'">';
 +                                if($viewpw)     echo '<input type="hidden" value=0 name="viewpw">';
 +                                ELSE                            echo '<input type="hidden" value=1 name="viewpw">';
 +                                ECHO '<td><input type="image" src="gfx/passwd.gif" value="View Passwords" alt="Toggle Passworddisplay"';
 +                                if(!$viewpw) echo ' class=button';
 +                                ECHO '></td>';
 +                                echo '</form>';
 +                // Status Button
 +                                ECHO "<td><input type=\"image\" src=\"gfx/status.gif\" class=button onClick=\"javascript:fenster('$SELF_URL?action=ftpwho')\"></td>";
 +                // Update Button
 +                                ECHO "<td><input type=\"image\" src=\"gfx/updates.gif\" class=button onClick=\"javascript:fenster('http://www.solariz.de/updates/pureftpdm.php?ver=$VERSION&ab=$BUILD')\"></td>";
 +                echo "</tr></table>";
 +########
 +
 +        echo '</td></tr></table>';
 +}#end else
 +
 +// SQL Verbindung schliessen
 +        DB_CLOSE();
 +
 +
 +// Seite abschliessen
 +PAGE_FOOTER();
 +
 +
 +
 +
 +
 +
 +
 +// EOC <--*
 +
 +
 +
 +
 +
 +
 +
 +// Funktionen
 +
 +        function PAGE_HEADER() {
 +    GLOBAL $VERSION, $BUILD;
 +    include("inc/top.php");
 +  }#end func
 +
 +        function PAGE_FOOTER() {
 +      include("inc/bottom.php");
 +  }#end func
 +
 +        function DB_OPEN() {
 +                GLOBAL $MYSQLSERVER,$MYSQLUSER,$MYSQLPASSWORD,$MYSQLDATABASE,$MYSQLCON;
 +                        $MYSQLCON = @mysql_connect($MYSQLSERVER,$MYSQLUSER,$MYSQLPASSWORD);
 +                        if(!$MYSQLCON OR @mysql_error()) DIE("Can't establish DB connection.<br />".mysql_error());
 +                        if(!@mysql_select_Db($MYSQLDATABASE)) DIE("Can't establish DB connection.<br />".mysql_error());
 +        }#end func
 +
 +        function DB_CLOSE() {
 +                GLOBAL $MYSQLCON;
 +                RETURN @mysql_close($MYSQLCON);
 +        }#end func
 +
 +        function DB_QUERY($sql) {
 +                GLOBAL $MYSQLCON,$MYSQLDATABASE;
 +                $Q = @MySql_DB_query($MYSQLDATABASE,$sql,$MYSQLCON);
 +                if(@mysql_error()) DIE("<b>MySQL Error during Query !</b><br /><br />[$sql]<br />".mysql_error());
 +                return $Q;
 +        }#end func
 +
 +        function get_var($var){
 +                GLOBAL $$var;
 +                GLOBAL $_POST,$_GET,$HTTP_POST_VAR,$HTTP_GET_VAR;
 +                $inhalt = $$var;
 +                # This function checks if the _GET or _POST var is set or if an old PHP version used
 +                if($_POST[$var]) RETURN $_POST[$var];
 +                elseif($HTTP_POST_VAR[$var]) RETURN $HTTP_POST_VAR[$var];
 +                elseif($_GET[$var]) RETURN $_GET[$var];
 +                elseif($HTTP_GET_VAR[$var]) RETURN $HTTP_GET_VAR[$var];
 +                elseif($inhalt) RETURN $inhalt;
 +        }#end func
 +?>
 +</file>
 +
 +My "//pureftp.config.php//" looks like this:
 +
 +<file>
 +<?php
 +######################
 +####### SETUP ########
 +######################
 +
 +        // Your exactly located mysql config file for pureftpd
 +        $PUREFTP_CONFIG_FILE    = '/etc/pure-ftpd/pureftpd-mysql.conf';
 +
 +        // The location where all the Forms directed to. (Mayby no change needed)
 +        $SELF_URL                               = '/index.php';
 +
 +        // The location of your pure-ftpdwho binary  (set this to chmod 4711)
 +        $FTP_WHO                                = "/usr/sbin/pure-ftpwho";
 +
 +#######################
 +# DEFAULT NEW-USER PARAMS #
 +#######################
 +
 +        $DefaultUser = "";              # Default User Logon
 +        $DefaultPass = "";                          # Default User Password
 +        $DefaultUid = "pureftpd";                       # Default User ID ( must be a real user acct )
 +        $DefaultGid = "pureftpd";                 # Default Group ID ( must be a real group acct )
 +        $DefaultDir = "/srv/ftp/";                                  # Default User Dir ( use /./ at the end to chroot )
 +        $DefaultUL = "0";                                   # Default Upload Throttle ( 0 disables it )
 +        $DefaultDL = "0";                                   # Default Download Throttle ( 0 disables it )
 +        $Defaultip = "*";                                   # Default IP restrictions  ( * = any IP )
 +        $DefaultQS = "0";                             # Default Quota Size ( 0 disables it )
 +        $Defaultcmt = "";                                   # Default Comment for user
 +
 +// UA
 +        $DefaultQF = "0";                       # Default Quota Files ( 0 disables it )
 +        $PWC = "55";                              # Vorsatz fuerr Crypt Password
 +?>
 +</file>
 +
 +
 +This is basically it. Point your browser at //https://yourwebserver:666//, login and start sharing diskspace :-P \\ 
 +
 +
 +An alternate Pure-Ftpd GUI can be found at http://machiel.generaal.net/index.php?subject=user_manager_pureftpd.