[tpop3d-discuss] tpop3d, auth-other, php auth script and heavy
load
Ivan Matveyev
hobot at zebratelecom.ru
Tue, 11 Mar 2003 09:00:27 +0300 (MSK)
On Tue, 4 Mar 2003, Chris Lightfoot wrote:
> Don't do that. tpop3d will hold off restarting the
> authentication child to avoid an out-of-control script
> consuming system resources. That's probably why you're
> seeing poor performance under heavier load.
Chris, I have new version. ;-) It works fine on a busy server with more
than 300k accounts.
#!/usr/local/bin/php -q
<?
/*
For example, for domain1 and domain2 we want web auth, for any other domain
we try regarding file in /etc/teapop.
/etc/teapop/$domain file format is:
"login:password:mailbox"
Web auth returns "YES" if the user is allowed, and "NO" in other case.
Also, I had to modify auth_other_send_request function in auth_other.c
to make it work properly with the php auth module.
int auth_other_send_request(const int nvars, ...) {
va_list ap;
int i, ret = 0;
char buffer[MAX_DATA_SIZE] = {0};
char *p;
size_t nn;
if (!authchild_pid) return 0;
va_start(ap, nvars);
for (i = 0, p = buffer, nn = 0; i < nvars; ++i) {
const char *key, *val;
key = va_arg(ap, const char *);
nn += strlen(key) + 1;
if (nn > sizeof(buffer)) goto fail;
memcpy(p, key, strlen(key));
p += strlen(key);
memcpy(p,"=",1);
p++;
val = va_arg(ap, const char *);
nn += strlen(val) + 1;
if (nn > sizeof(buffer)) goto fail;
memcpy(p, val, strlen(val));
p += strlen(val);
memcpy(p," ",1);
p++;
}
memcpy(p,"\n",1);
p++;
nn++;
if (nn > sizeof(buffer)) {
log_print(LOG_ERR, _("auth_other_send_request: total size of request would exceed %d bytes"), sizeof(buffer));
goto fail;
}
/* Since write operations are atomic, this will either succeed entirely or
* fail. In the latter case, it may be with EAGAIN because the child
* process is blocking; we interpret this as a protocol error. */
if (try_write(authchild_wr, buffer, nn)) ret = 1;
else {
if (errno == EAGAIN)
log_print(LOG_ERR, _("auth_other_send_request: write: write on pipe blocked; killing child"));
else
log_print(LOG_ERR, _("auth_other_send_request: write: %m; killing child"));
auth_other_kill_child();
}
fail:
va_end(ap);
return ret;
}
If you have any questions, mail hobot@moecho.org
*/
error_reporting(0);
set_time_limit(0);
function array_get($what,$array)
{
foreach($array as $val)
{
if(ereg("^".$what,$val))
{
list($none,$value)=split("=",$val);
return $value;
}
}
}
function array_get_pw($what,$array)
{
foreach($array as $val)
{
if(ereg("^".$what,$val))
{
list($none,$value,$none)=split(":",$val);
return $value;
}
}
}
function logs($in)
{
$what=date("D M j G:i:s T Y ").$in."\n";
$fp = fopen ("pop-auth.log","a");
fwrite ($fp,$what);
fclose($fp);
}
function stdout($what)
{
$stdout=fopen("php://stdout","w");
fwrite($stdout,$what);
fclose($stdout);
}
$stdin=fopen("php://stdin","r");
$term=fscanf($stdin,"%s %s %s %s %s %s %s %s %s %s %s\n");
while($term)
{
//foreach($term as $val) logs($val);
$username=array_get("user",$term);
$password=array_get("pass",$term);
$ip=array_get("clienthost",$term);
$answer="NO";
$mailbox="";
list($local_part,$domain)=explode("@",$username);
if($domain==""||$domain=="domain1"||$domain=="domain2")
{
$string="http://some.url?user_name=$local_part&password=$password";
$tmp=file($string);
$answer=str_replace("\n","",$tmp[0]);
}
else
{
$em_pw_db=file("/etc/teapop/$domain");
if($password==array_get_pw($local_part,$em_pw_db)) $answer="YES";
else $answer="NO";
$mailbox="mailbox\0/var/mail/$domain/$local_part\0";
}
if($answer=="YES")
{
stdout("result\0YES\0uid\0mail\0gid\0mail\0$mailbox\0");
}
if($answer=="NO")
{
stdout("result\0NO\0\0");
}
//logs("$username $password ($local_part $domain) $answer");
$term=fscanf($stdin,"%s %s %s %s %s %s %s %s %s %s %s\n");
//$term=fgets($stdin,399);
}
fclose($stdin);
?>
--
Ivan Matveyev, Zebra Telecom
Tech Dept, +7(095)741-0001