Filezilla ftp server user deactivation

Published:
Have you ever stumbled upon a software that is so great that you just love? It happened to me. Love at first sight. Filezilla Server.
 
Ok its not the most advanced ftp server I've came across. But its a fairly simple piece of software to get the job done on a windows machine.

My problem was that you cannot somehow "expire" inactive users. I found out that all the settings where saved on an xml named FileZilla Server.xml.  I played a lot with this and found out that its not an actual xml file , meaning the structure is not strict. So I've decided to find a way to expire inactive users that I've created after a grace period of 14 days.

prequisities:

1) windows xp sp3 (or any windows machine for that matter as long as you adapt the paths of the aforementioned files)

2) A working installation of Filezilla server  in version 0.9.34.0 (i am referring to this version because the produced xml might not work on another version)

3) Enabled logs. under settings,logging , enable logging to file and use differend log file every day. It can work by deleting logs after 14 days but i like history!

4) A installation of perl . Can be found in the xampp package http://www.apachefriends.org/en/xampp.html or www.perl.org .
perl modules used: XML::Simple, Data::Dumper , Time::Local, Date::Calc .  

5) Make sure you have the above modules installed. You can install by runnning Cpan and install XML::Simple , install Data::Dumper, Time::Local ,Date::Calc . and exit.


About the code.

I know its messy. I know it can be optimized in a number of ways. but.. it works...and there is nothing like this anywhere at the moment... and its my first program in perl!  I discovered why perl bears names like the "swiss army knife chainsaw" of languages. Once you master it you can do anything!

My code works like this.
1) It reads the xml file.
2) keeps in an array the active users.
3) removes from the array the "safe" users.
4) opens the last log files (14 days) and compares users with the rows of every file.
5) if user is found , it removes it from the array.
6) when is finished with the files it disables every user left on the array ,
7) exports the xml file to the same location and reloads config of filezilla (so to not interrupt its operation)

So you need to know where is your filezillaServer.xml lies, where your logs are saved, who to keep, and what is your grace period.
 
#Filezilla Inactive User Cleanup (FIUC) 
                      #Copyright (c) 2011 Stergios Psathas stergios99@gmail.com
                      #This is free software, and you are welcome to redistribute it , 
                      #as long as copyright information remains intact.
                      #!/usr/bin/perl
                      #use warnings;
                      # use module
                      use XML::Simple;
                      use Data::Dumper;
                      use Time::Local;
                      use Date::Calc qw(Delta_Days);
                      $xml = new XML::Simple();
                      # read XML file
                      $data = $xml->XMLin("c:/program files/FileZilla Server/FileZilla Server.xml",
                      					ForceArray => ['Permission','IpFilter','Allowed','Disallowed','IP'],
                      					ForceContent => 0,KeepRoot =>1,
                      					KeyAttr =>['Item'],
                      					SuppressEmpty => 0  ); #<--------where to read the xml file
                      #print Dumper $data;
                      $i=0;
                      $count=0;
                      $countinactive=0;
                      foreach $user (@{$data->{'FileZillaServer'}->{'Users'}->{'User'}}){
                      if ($data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Option'}->[5]{'content'} == 1 ){
                      $username=$data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Name'};
                      $enabled=$data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Option'}->[5]{'content'};
                      if ( length($data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Name'}) >2){
                      @activeusers[$count]=$data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Name'};
                      $count++;}
                      }else{
                      $username=$data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Name'};
                      $enabled=$data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Option'}->[5]{'content'};
                      if ( length($data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Name'}) >2){
                      $countinactive++;
                      }}$i++;}
                      $totalcount=$count+$countinactive;
                      print "total active user count -> ". $count. " \n"; 
                      print "total inactive user count -> ". $countinactive. " \n"; 
                      undef $i; 
                      my @tokeep=('user1','user2','...');  # <---------list with "safe" ftp users;
                      my $i=0;
                      my $j=0;
                      for (my $i=0;$i <=scalar(@activeusers);++$i){ 
                      	for (my $j=0;$j <=scalar(@tokeep);++$j){
                      	$keep=@tokeep[$j];
                      	$list=@activeusers[$i];
                      		if ($keep eq $list){
                      		delete @activeusers[$i]; 
                      		}
                      
                      	}
                      }
                      undef $i; 
                      my $i=0;
                      for(my $i=0;$i <=scalar(@activeusers); ++$i){
                      #print $i . " \n";
                      if (defined(@activeusers[$i])){} else{
                      splice(@activeusers,$i,1);
                      #print $i."\n"; 
                      if (scalar(@activeusers)==$i){}else{$i--;}
                      }}
                      print "number of active users AFTER EXCEPTIONS: ".scalar(@activeusers)." \n";
                      $numofactiveusers=scalar(@activeusers);
                         @files = <c:/'program files'/'filezilla server'/logs/*>;
                         my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
                         @limitdate=localtime(time-1209600);#" to deactivate \n"; 14 days before. #useless. comparisson done in delta_days
                         @currentday=localtime(time);
                         #print Dumper @limitdate;
                      $year+=1900; $mon+=1; $mon=sprintf("%02d",$mon); $mday=sprintf("%02d",$mday);
                      foreach $file (@files) { 
                      $fileyr=substr($file,43,4);   
                      $filemo=substr($file,48,2);  
                      $fileday=substr($file,51,2);
                      print $file. " diff-> ". Delta_Days($fileyr,$filemo,$fileday,$year,$mon,$mday)."\n";
                      $i++;
                       if ( Delta_Days($fileyr,$filemo,$fileday,$year,$mon,$mday) < 15){ 
                        open (AFILE,$file);# or die ("could not open file");
                        @raw_data=<AFILE>;
                        NEXTROW:
                        undef $i;
                      	undef $p;
                           foreach $row (@raw_data){
                      #print Dumper @activeusers;	 
                      	 $p=0;
                      	for (;$p <scalar(@activeusers);++$p){
                      	
                      		if((rindex $row,@activeusers[$p])==-1 ) 
                      		{} else{
                      		print "found ".@activeusers[$p]." ".$p. "  @ " . $fileday.$filemo.$fileyr."\n";
                      			delete @activeusers[$p]; 
                      			splice (@activeusers,$p,1);
                      			#print $p;
                      			#$p--;
                      				}	}	}
                        close AFILE;
                        }
                      }
                      undef $i;
                      $i=0;
                      foreach $user2 (@{$data->{'FileZillaServer'}->{'Users'}->{'User'}}){
                      $k=0;
                      for (;$k<=scalar(@activeusers);$k++){
                      	if ($data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Name'} eq @activeusers[$k]){
                      	print "deactivating .. ->".@activeusers[$k]."\n";
                      		$data->{'FileZillaServer'}->{'Users'}->{'User'}[$i]->{'Option'}->[5]{'content'}=0;
                      		} else{
                      		} }
                      $i++;}
                      #print Dumper $data;
                      $xml->XMLout($data,OutputFile => "c:/Program Files/FileZilla Server/FileZilla Server.xml",KeepRoot => 1,NoSort => 0,SuppressEmpty => 0,);
                      #exec `c:/xampp/FileZillaFTP/FileZillaServer.exe /start`;#<-start server
                      exec `c:/reloadconfigftp.cmd`;#<-on started server reload config with a batch file containing only one line this -> "c:\Program Files\FileZilla Server\FileZilla Server.exe" /reload-config

Open in new window


In detail...
Line 14 needs the full path of the xml file.
Line 40 needs the safe user list. the users that will be excluded from deactivating.
Line 64 needs the path to the log files to check.
Line 110 needs the output xml file. usually same as source at line 14.
Line 112 runs a cmd file to reload configuration for filezilla and thus activate your changes.

Notes:
1) The c:\reloadconfigftp.cmd contains only one line (with the quotes) "c:\Program Files\FileZilla Server\FileZilla Server.exe" /reload-config
2) take copies and backups before you start altering your own production environment

I hope this Article helps you.
0
3,538 Views

Comments (0)

Have a question about something in this article? You can receive help directly from the article author. Sign up for a free trial to get started.