Authentication against a bunch of files..needs to be fast

I am going for broke here.... but I really need this:

I need to create a simple HTML authentication screen with username and password.  When the user enters their user/pass I need to check about 200 files in a directory in my server to make sure that they are registered.

Let's say the files are in the:  /opt/mymembers/ directory
and their filenames are like:  00001.cgi, 00002.cgi, 00003.cgi...etc....(one for each registered user)
and the contents of these files looks like:  (each file is 12 lines long, but I only care about the first two for authentication, but might want to extract the "otherdata" lines for use later):

USERNAME
PASSWORD
otherdata
otherdata
otherdata
otherdata
otherdata
otherdata
otherdata
otherdata
otherdata
otherdata

BTW - if it helps there is another file is this mymember directory that is kind of a master cross reference with just the usernames and a pointer to their file... one on each line... looks like:  (it is called mymemberlist.cgi)

USERNAME1|!!|00001
USERNAME2|!!|00002
USERNAME3|!!|00003

I will up the points even more for a fast solution.
georgiaAsked:
Who is Participating?

Improve company productivity with a Business Account.Sign Up

x
 
maneshrConnect With a Mentor Commented:
here is your solution...

i have also attached some sample data files for your testing.

===========check_password.pl
#!/usr/local/bin/perl

use CGI;

$query=new CGI;

$username=$query->param('username');
$pass=$query->param('pass');

if ($query->param){
  open(PASS,"/home/webuser/manesh/tmp/passwd") || die $!;
  print "Content-type: text/html\n\n";

  while(<PASS>){
    ($uname,$junk,$file)=split(/\|/,$_);
    $file=~ s/\s+//g; ##  Remove any white spaces from the file name

    if ($uname=~ /^$username$/){  ##  Matching username found
      ##  Now Open the password file and validate!!
      $pwd_file="/home/webuser/manesh/tmp/$file.cgi";
      open(PWD,$pwd_file) || die $!;
      @lines=<PWD>; ##  Read ALL the lines of the file
      close(PWD);
      if ($lines[1]=~ /^$pass$/){ ##  Password matches
        print "<B>Welcome $username \n<br>\n";
        exit;
      }else{
        close(PASS);
      }
    }
  }
  close(PASS);
  print "<B>Invalid Username/Password</B><BR>\n";
}else{
  print "Content-type: text/html\n\n";
  print qq{
  <TITLE>Login Page</TITLE>
  <FORM METHOD=POST ACTION=$ENV{SCRIPT_NAME}>
  <B>Username:</B><INPUT TYPE=TEXT NAME=username><BR>
  <B>Password:</B><INPUT TYPE=password NAME=pass><P>
  <INPUT TYPE=SUBMIT VALUE=Login>
  </FORM>
  };
}

==============passwd
aaa|junk|0001
123|junk|0002
man|junk|0003


===========0001.cgi
aaa
pass1
1
2
3
4
4
5
6
7
8
9


==============0002.cgi
123
some_pass1
1
2
3
4
4
5
6
7
8
9


===============0003.cgi
man
maneshr
1
2
3
4
4
5
6
7
8
9
0
 
grommettCommented:
Ok, this answer works well for systems I've built. I can't say how scalable it is, but it would be faster than checking individual files I think.

This subroutine as written checks a user name and password, but I think you can probably tweak it how you want.

I have a form asking for user name and password and then call a cgi with this subroutine. Another subroutine then builds an validation html page with a hidden value being the area they are authenticated for.

Obviously, you'll need to have code in the cgi to deciper posts from a form.

======
 # This subroutine will not only check validation, but also return
 # another field in the your bar delimited database. You can use this returned value as
 # a hidden value to send the person to a particular page after they are validated.
 
 # for example, if I have a master list like your's and I want the 4 field
 # returned for the $division variable, I'd do this:
 # (in this example, I've parsed the values for a form the person submitted
 # and the form had a user and pswd field to enter).
 
 # $division = &return_password_match($dbase_pswd, $FORM{'user'}, "1", $FORM{'pswd'}, "2", "4");
 
 # terms:
 # $dbase_pswd = the name of the master file to check
 # $FORM{'user'} = the user name
 # "1"           = the field in the master file where user names are found
 # $FORM{'pswd'} = the password
 # "2"           = the field in the master file where passwords are found
 # "4"           = if a match is found, the field to return
 
 # An empty string returned means they aren't registered.
 
  sub return_password_match
   {
   
   my ($db_file_name, $matchone, $fieldone, $matchtwo, $fieldtwo, $fieldreturn) = @_;
   
   my (@all, $line, @field, $selected, $output, $item);
   
   # convert string of items separated by $delimiter to array
   @selectfields = split(/$delimiter/, $selected_items);
   
   open(FILE, "$db_file_name");
   
   while(<FILE>)
      {
         chop;      
            
         @all = split(/\n/);
         foreach $line (@all)
          {
          @field = split(/\|/, $line);
   

           # We're setting this up for a case insensitive search
           # $field[$itm] =~ /.*$keyword.*/i
           # if ($selectvalue eq $item) {$selected = "1";}
           if ($matchone eq $field[$fieldone])
              {
              if ($matchtwo eq $field[$fieldtwo])
                 {
                 $output = $field[$fieldreturn];
                 close(FILE);
                 return $output;
                 }
              }

          }#end of file loop  
       }#end of while file loop
       close(FILE);          
      
   return $output;
   }
0
 
georgiaAuthor Commented:
thanks grommett, but manshr's solution seems totally complete to me, since I don't have to modify it much....
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
georgiaAuthor Commented:
maneshr...  this seems perfect, but I have a couple errors when I don't explicitly run "perl check_password.cgi".....  can you take a look?

bach:~/www/cgi-bin$ ./check_password.cgi
../check_password.cgi: use: command not found
../check_password.cgi: =new: command not found
../check_password.cgi: syntax error near unexpected token `$username=$query->para
m(''
../check_password.cgi: ./check_password.cgi: line 8: `$username=$query->param('us
ername');'
bach:~/www/cgi-bin$        
0
 
georgiaAuthor Commented:
Adjusted points from 300 to 350
0
 
georgiaAuthor Commented:
I made a couple small changes and got rid of the errors... thanks!
0
 
maneshrCommented:
i think the change that you made might have to do with the location of the PERL file ie. its located on a diff directory on your server, right??
0
 
georgiaAuthor Commented:
not really... I am an oldschool perl guy and I have never messed with modules, but I think it had to do with trying to use the CGI module, I don't think they had it - if that makes any sense.  I basically chopped up everything anyway and integrated it with another piece of code, worked out pretty well - I appreciate your help.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.