Ola,
fiz um pequeno programa em perl que acredito ser de interesse de todos
que adminstram o squid.
Muitas vezes as solu��es disponiveis n�o atendem as nossas necessidades.
N�o sou muito de seguir um estilo de indenta��o.
Podia aportar somente para um link, mas links costumam sumir com o tempo.
:)
-->come�a aqui <--
#!/usr/bin/perl
# usar o suidperl, eu sei, isso e inseguro, mas sem ele a autentica��o pelo
# PAM n�o funciona.
# O script eo suidperl tem que estar com o SUID bit ativo.
#
# Autor : Paulino Kenji Sato
# Data : Agosto/Setembro de 2002
# Licen�a : Escolha uma das aceitas pela fsf. :)
#
# O objetivo desse programa e prover a autentica��o para o squid
# consultando duas bases de usu�rios distintas.
# A base consultada depender� do formato do nome de usu�rio.
# Caso o nome do usu�rio case com uma expres�o regular, o mesmo ser�
# validado consultando uma base sql, caso contrario ser� verificado no
# cadastro de usu�rio do sistema, atravez do PAM.
#
use Authen::PAM;
use DBI;
use POSIX qw(strftime);
#use strict; #Devia ter levado � s�rio isso. :)
$|=1; # n�o faz o "buffering"
# intercepta o sinal, n�o descobri qual o sinal que o squid usa para
# encerrar os programas auxiliares.
$SIG{HUP} = \&finalizar;
$SIG{INT} = \&finalizar;
$SIG{QUIT} = \&finalizar;
$SIG{TERM} = \&finalizar;
#Local do arquivo de log
$logfilename = "/tmp/squid_auth.log";
#Conex�o ao banco de dados, aqui esta sendo usando o interbase.
#Pode ser usado qualquer outro sgdbm que o modulo DBI suporte.
#Uma lida na documenta��o do DBI � recomendado.
#Conex�o padr�o e com o autocommit ligado.
$dsn ="dbi:InterBase:dbname=banco_de_dados.gdb;ib_charset=ISO8859_1";
$dbh = DBI->connect($dsn, "sysdba", "masterkey");
&printlog("Inicializado.\n");
#la�o principal, le o par username/password do stdin
#Leia a documenta��o do squid para enteder isso.
while (<>) {
chop;
($u,$p) = split;
#para evitar reposta falsa.
$aut="";
#verifica se o username eo password foram informados
if ($u && $p) {
# Uma RE que verifica se o username esta no formato 12.12.1234
# Talvez essa RE precise de uma revis�o.
if ($u =~ /[0-9]{2}\.[0-9]{2}\.[0-9]{4}$/) {
#se casa com a RE, usa a autentica��o sql.
$aut=&checa_sql($u,$p);
} else {
#se n�o tenta pelo pam.
$aut=&checa_unix($u,$p);
};
};
# a variavel $aut existe?
if ($aut) {
# ent�o imprime o conteudo dela.
print "$aut\n";
&printlog("$u $aut\n");
} else {
#n�o existe
print "ERR\n";
};
#limpa as variaveis $p e $u, para evitar repeti��o da �tilma entrada.
$p='';
$u='';
}
#sub rotina que atualiza o log.
sub printlog {
open(LOGFILE, ">> $logfilename") || print "failed";
$acttime = strftime "%d/%m/%y %H:%M:%S", localtime;
print LOGFILE "$acttime squid_auth[$$] @_";
close(LOGFILE);
};
# Rotina que verifica no banco de dados sql
sub checa_sql {
local($u,$p) = @_;
# A query adequado a tabela em uso
$sth=$dbh->prepare("select PASS from MATRICULA where RA='$u'
and STATUS='A';");
$sth->execute();
# a query retornou alguma coisa?
if ($ref = $sth->fetchrow_hashref()) {
#remove os espa�os no final da string.
($pass=$ref->{'PASS'}) =~ s/\s+$//;
# verifica se a senha do db est� iqual ao fornecido
# para simplificar n�o foi usando nenhum tipo de cifragem nas senhas.
# a base de dados a mantida por um programa desenvolvido em Delphi.
if ($pass eq $p) {
return "OK";
} else {
&printlog("$u senha invalida.\n");
return "ERR";
};
} else {
# A query n�o retornou nada.
&printlog("$u n�o est� ativo.\n");
return "ERR";
};
$sth->finish;
};
#checa o usuario atravez do PAM (usuarios do sistema)
# grande parte dessa rotina foi copiado dos exemplos/faq do modulo
# Authen::PAM
sub checa_unix {
local($username,$password) = @_;
$service = "system-auth";
ref($pamh = new Authen::PAM($service, $username, \&my_conv_func)) ||
die "Error code $pamh during PAM init!";
$res = $pamh->pam_authenticate;
#Verifica o resultado
if ($res == PAM_SUCCESS()) {
return "OK";
} else {
return "ERR";
};
};
# rotina auxiliar do Authen::PAM
# leia a documenta��o do modulo Authen::PAM para entender.
sub my_conv_func {
my @res;
while ( @_ ) {
my $code = shift;
my $msg = shift;
my $ans = "";
$ans = $username if ($code == PAM_PROMPT_ECHO_ON() );
$ans = $password if ($code == PAM_PROMPT_ECHO_OFF() );
push @res, (PAM_SUCCESS(),$ans);
}
push @res, PAM_SUCCESS();
return @res;
}
# Era para encerrar amigavelmente o script quando o squid e ecerrado,
# mas parece que o squid manda um sigkill ou outro sinal.
sub finalizar {
local ($s) = @_;
$sth->finish if defined $sth;
$dbh->disconnect;
&printlog("Finalizado com $s.\n");
exit;
}
# Sei-la o que isso ta fezendo aqui. :)
$dbh->disconnect;
---> termina aqui <---
Paulino
_________________________________ ________________________________________
Paulino Kenji Sato | Universidade Estadual de Maringa
mailto:[EMAIL PROTECTED] | Departamento de Fisica
http://www.dfi.uem.br/~paulino | Maringa Pr Brasil
http://br.geocities.com/linosam/ | Linux user 56176
Assinantes em 03/09/2002: 2227
Mensagens recebidas desde 07/01/1999: 181622
Historico e [des]cadastramento: http://linux-br.conectiva.com.br
Assuntos administrativos e problemas com a lista:
mailto:[EMAIL PROTECTED]