Ik ben bezig een script te maken waarin gebruikers toegang krijgen op basis van hun gebrukersnaam en wachtwoord zoals ze in /etc/passwd en /etc/shadow staan.

Om niet alle users door apache/php uit te laten lezen maak ik gebruik van een perl script dat deze bestanden uit leest. Via de cron wordt om de zo veel tijd alles uitgelezen en op de server in een map geplaatst.

Perl Script:

#!/usr/bin/perl
#

open(PASSWD,"/etc/passwd");
open(SHADOW,"/etc/shadow");
open(FLATFILE,">/etc/passwd.httpd");
while(<SHADOW>){
chop;
($uname,$temppass)=split(/:/);
$pass{$uname}=$temppass;
}
while(<PASSWD>){
chop;
($uname,$temppass,$uid,$gid,$fn,$homedir,$shell)=split(/:/);
if ($temppass ne 'x'){ $pass{$uname}=$temppass; }
if ($uid>=500) {
print FLATFILE
"$uname:$pass{$uname}:$uid:$gid:$fn:$homedir:$shell\n";
}
}

close(PASSWD);
close(SHADOW);
close(FLATFILE);
chmod(0400,"/etc/passwd.httpd");
chown(65534,65534,"/etc/passwd.httpd");

Via een php script probeer ik vervolgens de users en de hashes, zoals ze in het bestand staan, te laten matchen. Daarvoor gebruik ik dit script:

<?php

$user = ($_POST['username']);
$password = ($_POST['password']);
$autharray = file("/home/httpd/vhosts/domein.nl/httpdocs/passwd.httpd");

for ($x = 0; $x < count($autharray); $x++)
{
if (eregi("^$user:", $autharray[$x]))
{
$passwd = explode(":", $autharray[$x]);
$salt = substr($passwd[1],0,2);
$cryptpw = crypt($pass,$salt);
if ($cryptpw == $passwd[1]) {
print "succes";
} else {
print "fout";
}
}
}
?>

Echter als ik deze waardes via echo laat uitlezen komen deze totaal niet overeen met de hashes zoals ze in het perl gemaakte script staan. Misschien zit er ergens een fout in het script of moet ik nog een extra waarde meegeven. Ik hoop dat hier iemand is die mij verder op weg kan helpen. De uiteindelijke code zal ik hier publiceren.
Wat ik doe is inderdaad het maken van een kopie van de shadow file. Echter filer ik alle ID onder de 500 er uit. Het gebruiken van pam_auth vind ik echter ook een kwalijke zaak omdat apache dan de /etc/shadow file moet uitlezen. Ik doe dit dan liever met een kopie.

Ik ben weer iets verder. Wat blijkt is dat het script random hashes creert en dus niet een enkele hash ter vergelijking met de perl gegenereerde file. Weet er iemand wat er mis kan zijn?
Je begrijpt het principe van pam kennelijk niet. Wanneer iemand inlogt wordt altijd door een libary een shadow file uitgelezen. Maar alleen via speciale libaries zijn deze leesbaar. (DWZ: de shadow wordt alleen indicenteel gelezen naar 1 user/password via de libary.)

Apache leest dus niet, en kan dus niet, de shadow file lezen

Wanneer je een kopie maakt is deze voor jouw opzet WEL geheel leesbaar en is het bijvoorbeeld mogelijk (veel gemakkelijker) om een aparte kopie te maken, doordat apache leesrechten moet hebben over je shadow file. PAM is er juist voor om dit te voorkomen.

Een oplossing met een Authen::SimplePAM en ExecCGI lijkt mij de veiligste oplossing.

Reageren