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]

Responder a