zFTPserver is a fast, powerful and extensible Windows FTP server. It is free for both personal and commercial use. zFTPserver can be extended by several extensions, including event-driven scripting, custom authentication scripts and more to come. Download zFTPserver today. * Low on resources * High transfer speed * Remote administration * Virtual filesystem * System service support * Strong SSL/TLS encryption * IP access management * Anti-Hammering * Multiple and complex group memberships * Advanced passive mode Look at the features page for more information. In addition to the free zFTPServer Suite, a Windows FTP Server Västgöta-Data AB now offers extensions to zFTPServer. These extensions add very powerfull features for the expert user. * Events and Messages : Reactive * Events and Messages : Proactive The extensions cover advanced functionality most likely applicable for expert users and businesses with specific needs. The extensions offer great functionality such as scanning files on completed uploads, customized logs, and much more! Look at the extensions page for more information. As a Windows XP FTP Server, or Windows 2003 Server FTP Server. Run your zFTPServer as a system service (Windows NT / Windows 2000 / Windows XP / Windows 2003 Server) or in application mode. zFTPServer supports active and passive mode connections allowing administrators to specify both IP-adresses or host names for servers with dynamic ip adresses and/or behind firewalls (e.g. myserver.no-ip.com) It is possible to customize the messages sent from the FTP Server to the connecting user. This enables the user to, for example, get information of loading statistics, server information and date and time of commands. Administrators can use the built-in scripting facilities to adapt the way zFTPServer reacts to certain events. You can get zFTPServer to enforce your rules and policies. For example, you can script virus checks to be run on all uploaded files, to automatically transform between file formats, and to send notifications about special events. zFTPServer is an enterprise class scriptable Windows FTP Server. Dynamically access user and group account information from your Windows NT Domain Controller or Active Directory, including authentication information, home directories, and other settings. Any changes made to the Windows NT User/Group information will be immediately available in zFTPServer. The most powerful Windows FTP Server. zFTPServer Suite is designed to be easy to use. Most features are self explanatory or explained within the graphical user interface. Some of the more advanced features are explained more in-depth on this page. These scripts utilizes the administration protocol to manage the server from custom applications. This technique may be used to integrate zFTPServer Suite with custom systems, such as web applications or business systems. * Send SMS when a specific user logs in * Scan uploaded files for viruses with AVG * Create thumbnails of uploaded images * Automatically backup a file before it is to be overwritten * Only allow login during office hours * Only allow upload of specific file types * Only allow SAP users to download SAP-documents * Extreme login security using SMS audit. One of those superb applications that can provide you with the free equivalent of a secure commercial FTP server. It is not often you find something so well done, so user friendly and freeware at the same time. zFTPServer is AMAZING. I still can't believe how good it is! zFTPServer Suite is an Enterprise class Windows FTP Server that is constantly under development, as a Windows FTP Server, and have over the years gotten quite a few awards. The most enjoyable awards, of course, are the reactions we get from our satisfied users. We would like to take the opportunity to thank all the people who help us in reporting bugs, that have made suggestions for functionality and that have made translations. Since the key developer now work at Västgöta-Data (a swedish IT consultant company); zFTPServer Suite is now targeted for further development. The server will remain free for both business and home use but with the possibility to buy additional extensions for powerful features. This extension allows the FTP server to authenticate users against a Windows Domain / Server / Active Directory. With this extension enabled Windows users will automatically be able to logon to the FTP server without the need to add them to zFTP! - The users in zFTP will take precedence, so if a user exists in zFTP (and is not connected to a Windows account) then the zFTP account will be used for login. - If Authentication Integration for Windows is enabled, and a user tries to log in, access will be authenticated against the given Windows Domain (or Server). - Access to FTP can also be restricted based on certain Windows group memberships, so it will be very easy to administer which accounts that should be able to login through FTP using only Windows group management (e.g. in the AD)

Control file types for upload/delete/rename using zFTPServer with PHP

This example shows how to restrict which file types users are allowed to work with by using php scripts.
Descriptions for configuring each script is in the code comments.

PHP-Script "BeforeUpload.php":
<?PHP

/**
 * @author Photonensammler  
 */
//pass the username, and the extension of the file to upload
//check whether the upload of this filetype is allowed for user
//be passed as first Parameter the user name and as the 2nd Parameter the filename
//Usage example BeforeUpload.php Username Filename

/*
  command line in ZFTPServer event "BeforeUpload"
  "C:/PHP/php-win.exe" "C:/Program Files/zFTPServer/Scripts/BeforeUpload.php" "%USERNAME%" "%LOCAL_FILENAME%"
 */

/*
  for the user is evaluated the allowed file extension
  if the extension is listed in the array, for the user the upload of this filetype is allowed
  for users with the extension '*' is the upload of arbitrary files allowed
 */

$allow['User_1'] = array('txt'); //rights for user_1
$allow['User_2'] = array('txt', 'jpg', 'jpeg', 'pdf', 'wmv', ''); // rights for User_2
$allow['User_x'] = array('*'); //all rights for User_x
$allow['Administrator'] = array('*'); //all rights for Administrator

if (isset($_SERVER['argc']) && $_SERVER['argc'] > 2) {
  $user = $_SERVER['argv'][1]; //username
  if (isset($allow[$user])) {//test whether user exists
    if ($allow[$user][0] == '*') {
      die(0); //everything is allowed, exit with errorlevel 0
    } else {
      $ext = preg_split('/\./', $_SERVER['argv'][2]);
      if (count($ext) == 1) {
        $ext[1] = ''; //for files without extension
      }
      $ext = strtolower($ext[count($ext) - 1]);
      foreach ($allow[$user] as $test_ext) {
        if (strtolower($test_ext) == $ext) {
          die(0); //is allowed for this user, terminate with errorlevel 0 
        }
      }
    }
  }
}
die(1); //not allowed
?>

PHP-Script "BeforeRename.php":
<?PHP

/**
 * @author Photonensammler  
 */
//pass the username, and the extension of the old filename and the new filename to rename
//check whether the rename of this filetype is allowed for user
//be passed as first Parameter the user name, as the 2nd Parameter the old filename and as the 3td parameter the new filename
//Usage example BeforeRename.php Username Filenameold Filenamenew

/*
  command line in ZFTPServer event "BeforeRename"
  "C:/PHP/php-win.exe" "C:/Program Files/zFTPServer/Scripts/BeforeRename.php" "%USERNAME%" "%LOCAL_FILENAME%" "%LOCAL_FILENAME_NEW%"
 */
/*
  for the user is evaluated the allowed file extension
  if the extension is listed in the array, for the user the rename of this filetype is allowed
  for users with the extension '*' is the rename of arbitrary files allowed
 */

$allow['User_1'] = array('txt'); //rights for user_1
$allow['User_2'] = array('txt', 'jpg', 'jpeg', 'pdf', 'wmv', ''); // rights for User_2
$allow['User_x'] = array('*'); //all rights for User_x
$allow['Administrator'] = array('*'); //all rights for Administrator

if (isset($_SERVER['argc']) && $_SERVER['argc'] > 3) {
  $user = $_SERVER['argv'][1]; //username
  if (isset($allow[$user])) {//test whether user exists
    if ($allow[$user][0] == '*') {
      die(0); //everything is allowed, exit with errorlevel 0
    } else {
      $ext_old = preg_split('/\./', $_SERVER['argv'][2]);
      if (count($ext_old) == 1) {
        $ext_old[1] = ''; //for files without extension
      }
      $ext_new = preg_split('/\./', $_SERVER['argv'][3]);
      if (count($ext_new) == 1) {
        $ext_new[1] = ''; //for files without extension
      }
      $ext_old = strtolower($ext_old[count($ext_old) - 1]);
      $ext_new = strtolower($ext_new[count($ext_new) - 1]);
      foreach ($allow[$user] as $test_ext) {
        if (strtolower($test_ext) == $ext_old) {
          foreach ($allow[$user] as $test_ext) {
            if (strtolower($test_ext) == $ext_new) {
              die(0); //is allowed for this user, terminate with errorlevel 0 
            }
          }
          die(1); //not allowed
        }
      }
    }
  }
}
die(1); //not allowed
?>

PHP-Script "BeforeRemoveFile.php":
<?PHP

/**
 * @author Photonensammler  
 */
//pass the username, and the extension of the file to delete
//check whether the deleting of this filetype is allowed for user
//be passed as first Parameter the user name and as the 2nd Parameter the filename
//Usage example BeforeRemoveFile.php Username Filename

/*
  command line in ZFTPServer event "BeforeRemoveFile"
  "C:/PHP/php-win.exe" "C:/Program Files/zFTPServer/Scripts/BeforeRemoveFile.php" "%USERNAME%" "%LOCAL_FILENAME%"
 */

/*
  for the user is evaluated the allowed file extension
  if the extension is listed in the array, for the user the deleting of this filetype is allowed
  for users with the extension '*' is the deleting of arbitrary files allowed
 */

$allow['User_1'] = array('txt'); //rights for user_1
$allow['User_2'] = array('txt', 'jpg', 'jpeg', 'pdf', 'wmv', ''); // rights for User_2
$allow['User_x'] = array('*'); //all rights for User_x
$allow['Administrator'] = array('*'); //all rights for Administrator

if (isset($_SERVER['argc']) && $_SERVER['argc'] > 2) {
  $user = $_SERVER['argv'][1]; //username
  if (isset($allow[$user])) {//test whether user exists
    if ($allow[$user][0] == '*') {
      die(0); //everything is allowed, exit with errorlevel 0
    } else {
      $ext = preg_split('/\./', $_SERVER['argv'][2]);
      if (count($ext) == 1) {
        $ext[1] = ''; //for files without extension
      }
      $ext = strtolower($ext[count($ext) - 1]);
      foreach ($allow[$user] as $test_ext) {
        if (strtolower($test_ext) == $ext) {
          die(0); //is allowed for this user, terminate with errorlevel 0 
        }
      }
    }
  }
}
die(1); //not allowed
?>

PHP-Script "BeforeDownload.php":
<?PHP

/**
 * @author Photonensammler  
 */
//pass the username, and the extension of the file to download
//check whether the download of this filetype is allowed for user
//be passed as first Parameter the user name and as the 2nd Parameter the filename
//Usage example BeforeDownload.php Username Filename

/*
  command line in ZFTPServer event "BeforeDownload"
  "C:/PHP/php-win.exe" "C:/Program Files/zFTPServer/Scripts/BeforeDownload.php" "%USERNAME%" "%LOCAL_FILENAME%"
 */

/*
  for the user is evaluated the allowed file extension
  if the extension is listed in the array, for the user the download of this filetype is allowed
  for users with the extension '*' is the download of arbitrary files allowed
 */

$allow['User_1'] = array('txt'); //rights for user_1
$allow['User_2'] = array('txt', 'jpg', 'jpeg', 'pdf', 'wmv', ''); // rights for User_2
$allow['User_x'] = array('*'); //all rights for User_x
$allow['Administrator'] = array('*'); //all rights for Administrator

if (isset($_SERVER['argc']) && $_SERVER['argc'] > 2) {
  $user = $_SERVER['argv'][1]; //username
  if (isset($allow[$user])) {//test whether user exists
    if ($allow[$user][0] == '*') {
      die(0); //everything is allowed, exit with errorlevel 0
    } else {
      $ext = preg_split('/\./', $_SERVER['argv'][2]);
      if (count($ext) == 1) {
        $ext[1] = ''; //for files without extension
      }
      $ext = strtolower($ext[count($ext) - 1]);
      foreach ($allow[$user] as $test_ext) {
        if (strtolower($test_ext) == $ext) {
          die(0); //is allowed for this user, terminate with errorlevel 0 
        }
      }
    }
  }
}
die(1); //not allowed
?>

PHP-Script "BeforeCreateDirectory.php":
<?PHP

/**
 * @author Photonensammler  
 */
//pass the username, check whether the creation of Directorys is allowed for this user

/*
  command line in ZFTPServer event "BeforeCreateDirectory"
  "C:/PHP/php-win.exe" "C:/Program Files/zFTPServer/Scripts/BeforeCreateDirectory.php" "%USERNAME%"
 */

/*
  for the user is only evaluated '*', for users with '*' is the creation of Directorys allowed
  users without '*' dont have authorization to create Directorys
 */
$allow['User_1'] = ''; //no rights for user_1
$allow['User_2'] = ''; //no rights for User_2
$allow['User_x'] = '*'; //all rights for User_x
$allow['Administrator'] = '*'; //all rights for Administrator
//this is the compact code
die(isset($_SERVER['argc']) ? (isset($allow[$_SERVER['argv'][1]]) ? ($allow[$_SERVER['argv'][1]] == '*' ? 0 : 1) : 1) : 1);


/* This is the clear code
  if(!isset($_SERVER['argc'])){
  die(1); //errorlevel 1 -> called without parameters
  }
  $user=$_SERVER['argv'][1]; //username
  if(!isset($allow[$user])){//test whether user exists
  die(1); //no user
  }else{
  if($allow[$user]=='*'){
  die(0); //is allowed to exit with errorlevel 0
  }
  }
  die(1); //not allowed
 */
?>

PHP-Script "BeforeRemoveDirectory.php":
<?PHP
/**
 * @author Photonensammler  
 */
//pass the username, check whether the deletion of Directorys is allowed for this user

/*
  command line in ZFTPServer event "BeforeRemoveDirectorys"
  "C:/PHP/php-win.exe" "C:/Program Files/zFTPServer/Scripts/BeforeRemoveDirectory.php" "%USERNAME%"
 */

/*
  for the user is only evaluated '*', for users with '*' is the deletion of Directorys allowed
  users without '*' dont have authorization to delete Directorys
 */
$allow['User_1'] = ''; //no rights for user_1
$allow['User_2'] = ''; //no rights for User_2
$allow['User_x'] = '*'; //all rights for User_x
$allow['Administrator'] = '*'; //all rights for Administrator
//this is the compact code
die(isset($_SERVER['argc']) ? (isset($allow[$_SERVER['argv'][1]]) ? ($allow[$_SERVER['argv'][1]] == '*' ? 0 : 1) : 1) : 1);


/* This is the clear code
  if(!isset($_SERVER['argc'])){
  die(1); //errorlevel 1 -> called without parameters
  }
  $user=$_SERVER['argv'][1]; //username
  if(!isset($allow[$user])){//test whether user exists
  die(1); //no user
  }else{
  if($allow[$user]=='*'){
  die(0); //is allowed to exit with errorlevel 0
  }
  }
  die(1); //not allowed
 */
?>
Script submitted by Jörg Borch www.photonensammler.eu