Visualizzazione dei risultati da 1 a 7 su 7
  1. #1

    Modifica script per autenticazione via PAM

    Buongiorno A tutti!
    Sono un neofita completo con il PERL è perciò vi chiedo una mano per risolvere un problemino:

    Utilizzo questo script (authpam.pl ver. 1.0 che molti sicuremente conosceranno) per autenticare gli utenti di un mail server su linux:

    use Authen::PAM;
    $| = 1; #force STDOUT autoflush after each write

    my ($seq,$vrfy,$mode,$user,$passw);

    sub pam_conv_func {
    my @res;
    while ( @_ ) {
    my $msg_type = shift;
    my $msg = shift;
    #print $msg;
    push @res, 0;
    push @res, $passw;
    }
    push @res, PAM_SUCCESS;
    return @res;
    }

    while(<STDIN>) {

    ($seq,$vrfy,$mode,$user,$passw) = split(/ /);

    unless($mode =~ /^\(.*\)$/) {
    $passw=$user; $user=$mode;
    }

    unless($seq && $vrfy && $user && $passw) {
    print "$seq ERROR Wrong arguments\n";
    } elsif($vrfy ne 'VRFY') {
    print "$seq ERROR Only clear text passwords supported\n";
    } else {
    my ($res,$pamh);
    chomp($passw);
    if($user =~/(.+)\@.+/) {$user=$1;}
    if(($res=pam_start("login", $user, \&pam_conv_func, $pamh))!=PAM_SUCCESS ||
    ($res=pam_authenticate($pamh, 0))!=PAM_SUCCESS ||
    ($res=pam_end($pamh, 0))!=PAM_SUCCESS) {
    print "$seq ERROR ".pam_strerror($pamh,$res)."\n";
    } else {
    print "$seq OK \n";
    }
    }

    }

    Funziona tutto benissimo, ma...la riga: if($user =~/(.+)\@.+/) {$user=$1;} fa si che se l'utente da autenticare è 'mionome@miodominio.it' lo script passa al PAM 'mionome'. Mi piacerebbe riuscire ad autenticare utenti di diversi domini, in pratica vorrei che lo script lavorasse così: se l'utente è mioutente@miodominio1.it al PAM venga passato ad esempio MIODOMINIO1.LOCAL\\mioutente e se invece lutente è mioutente@miodominio2.com al venga passato ad esempio MIODOM2.PRIV\\mioutente ecc.
    Che modifiche posso fare per ottenere questo risultato?
    Grazie a tutti.

  2. #2
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    21,188
    Non mi intendo di autenticazioni, ma capisco qualcosa sulle RE.
    Prova a modificare il tuo pezzo:
    codice:
      if($user =~/(.+)\@.+/) {
        $user=$1;
      }
    in:
    codice:
      if($user =~/(.+)\@(.+?)\./) {
        $user = $1;
        my $domi = $2;
        print "utente: $user == dominio: $domi \n";
      }
    Nota che ho dichiarato la variabile $domi dentro la routine, cosa che probabilmente non ti va bene (dovrai dichiararla fuori da qualche parte, altrimenti non riesci ad usarla)
    Ho aggiunto il print per controllo, poi andra` tolto.
    Non so come potrai usare $domi, ma credo dovrai avere una lista di domini ammessi (che deve essere scritta nel codice in modo che non possa venir modificata da altri) e verificare che sia uno di quelli.


    PS: quando posti codice, usa il tag VB CODE, che puoi inserire anche tramite il bottone CODE sopra l'area di testo
    Nuova politica di maggiore severita` sui titoli delle discussioni: (ri)leggete il regolamento
    No domande tecniche in messaggi privati

  3. #3

    Grazie mille!

    Grazie mille per la risposta velocissima.
    Ci provo subito e faccio sapere
    Scusate per il 'tag' mancante...
    mAx

  4. #4
    In base alle mie esigenze e a ciò che ho capito (soprattutto grazie alla risposta di Mich_) ho fatto le seguenti modifiche (righe con commento "***mAx***"):

    codice:
     use Authen::PAM;
     $| = 1; #force STDOUT autoflush after each write
     my ($seq,$vrfy,$mode,$user,$passw);
     sub pam_conv_func {
       my @res;
       while ( @_ ) {  
         my $msg_type = shift;
         my $msg = shift;
         #print $msg;
         push @res, 0;
         push @res, $passw;
       }
       push @res, PAM_SUCCESS;
       return @res;
     }
    
     while(<STDIN>) {
        ($seq,$vrfy,$mode,$user,$passw) = split(/ /);
        unless($mode =~ /^\(.*\)$/) {
         $passw=$user; $user=$mode;
      }
        unless($seq && $vrfy && $user && $passw) {
         print "$seq ERROR Wrong arguments\n";
      } elsif($vrfy ne 'VRFY') {
        print "$seq ERROR Only clear text passwords supported\n";
      } else {
        my ($res,$pamh,$domi);  # ***mAx*** aggiunta dichiarazione variabile 'domi'
        chomp($passw);
        if($user =~/(.+)\@.+/) {$user=$1; $domi=$2}  # strip the domain name if necessary + ***mAx*** assegnazione della seconda parte della stringa a $domi
        if($domi eq "\@dominio3.com") {$domi = "DOM3\\\\"}  # ***mAx*** verifica se il dominio è il 3 e se si lo chiama DOM3
        elsif($domi eq "\@dominio2.it") {$domi = "DOM2\\\\"}  # ***mAx*** verifica se il dominio è il 2 e se si lo chiama DOM2
        else {$domi = "DOM1\\\\"}  # ***mAx*** Il dominio è il n. 1 e lo chiama DOM1
        $user = $domi.$user \n;  # ***mAx*** l'utente si chiama DOMINIOn\\utente
        if(($res=pam_start("login", $user, \&pam_conv_func, $pamh))!=PAM_SUCCESS ||
          ($res=pam_authenticate($pamh, 0))!=PAM_SUCCESS ||
          ($res=pam_end($pamh, 0))!=PAM_SUCCESS) {
        print "$seq ERROR ".pam_strerror($pamh,$res)."\n";
        } else {
        print "$seq OK \n";
         }
       }
     }
    Ho dei seri dubbi sulla correttezza della sintassi delle mie modifiche, in particolare della parte riguardante i caratteri speciali all'interno delle stringhe (il risultato finale in $user vorrei che fosse es. DOM1\\giovanni).
    Ha un minimo di senso quello che ho scritto? (prima di darlo in pasto al mailserver...).

    Ancora grazie a tutti.
    mAx

  5. #5
    Utente di HTML.it
    Registrato dal
    Sep 2001
    Messaggi
    21,188
    Ho due perplessita`:una sul metodo usato per definire il dominio e una sulla variabile che darai in pasto al sistema.

    METODO sw
    Piu` che una serie di if, che in caso di modifica ti obbligano a rivedere tutto il codice, io avrei usato una hash: una cosa del tipo:
    codice:
    my %domini = ('DOM1','dominio1.com' , 'DOM2','dominio2.it' , 'DOM3','dominio3.com');  # nella parte iniziale del file
    ...
    
      if($user =~/(.+)\@(.+)/) {$user=$1; $domi=$2; }   # occhio che qui ti mancava una parentesi
      foreach($k=keys(%domini)) {
        if($domini{$k} eq $domi) { $domi = $k; break; }   # controlla la sintassi !!
      }
      $user = '\@'.$domi.'\\\\'.$user;
      if(($res=pam_start("login", $user, \&pam_conv_func, $pamh))!=PAM_SUCCESS ...
    VARIABILE
    Nel tuo sistema vecchio (funzionante) tu davi in pasto alla funzione pam_start il singolo nome dell'utente (se ho capito giusto), mentre ora dai una coppia @dominio\\user: non so se il sistema lo accetta


    E comunque fatti sempre fare una stampa (magari commenta anche la riga che chiama il pam), in modo da verificare cosa effettivamente contengono le variabili ch edai in pasto alla "scatola nera".
    Nuova politica di maggiore severita` sui titoli delle discussioni: (ri)leggete il regolamento
    No domande tecniche in messaggi privati

  6. #6
    Di nuovo grazie Mich_
    Si, passando l'informazione al PAM in questo modo (senza @ davanti a DOM3\\utente però), l'autenticazione funziona (ovviamente a patto che il DOM2, DOM3, ecc. (che sono domini AD) siano in relazione di trust con il main domain).

    il sistema che mi suggerisci di usare (hash) mi pare comodo ed elegante. Purtroppo, come anticipato nel post originale, non so quasi nulla di perl...quindi questi suggerimenti sono più che graditi.

    Ora cerco di capire bene come funzionano le modifiche che mi suggerisci, provo e...vi dico

    Ancora grazie a tutti.
    mAx.

  7. #7

    FUNZIA!!!

    Buongiorno a tutti!
    Dopo lunghi e faticosi tentativi ...vi posto la prima versione funzionante dello script, script che attualmente è in test sul mail server:

    codice:
    #!/usr/bin/perl -w
    
    use Authen::PAM;
    $| = 1; #force STDOUT autoflush after each write
    
    my ($seq,$vrfy,$mode,$user,$passw);
    
    sub pam_conv_func {
      my @res;
      while ( @_ ) {
        my $msg_type = shift;
        my $msg = shift;
        #print $msg;
        push @res, 0;
        push @res, $passw;
      }
      push @res, PAM_SUCCESS;
      return @res;
    }
    
    while(<STDIN>) {
    
      ($seq,$vrfy,$mode,$user,$passw) = split(/ /);
    
      unless($mode =~ /^\(.*\)$/) {
        $passw=$user; $user=$mode;  
      }
    
    print "contenuto di passwd prima delle verifiche $passwd\n";
    print "contenuto di user prima delle verifiche $user\n";
      
      unless($seq && $vrfy && $user && $passw) {
        print "$seq ERROR Wrong arguments\n";
      } elsif($vrfy ne 'VRFY') {
        print "$seq ERROR Only clear text passwords supported\n";
      } else {
        my ($res,$pamh,$domi);  # ***mAx*** aggiunta dichiarazione variabile 'domi'
        chomp($passw);
        if($user =~/(.+)\@(.+)/) {$user=$1; $domi=$2}  # strip the domain name if necessary + ***mAx*** assegnazione della seconda parte della stringa a $domi
        if($domi eq "dominio3.com") {$user = "DOM3"."\\".$user}  # ***mAx*** se dominio 3 lo chiama DOM3
        elsif($domi eq "dominio2.it") {$user = "DOM2"."\\".$user}  # ***mAx*** se dominio 2 lo chiama DOM2
        elsif($domi eq "dominio1.eu") {$user = "DOM1"."\\".$user}  # ***mAx*** se dominio 1 lo chiama DOM1
    
    print "contenuto di user $user\n";
    
           if(($res=pam_start("login", $user, \&pam_conv_func, $pamh))!=PAM_SUCCESS ||
           ($res=pam_authenticate($pamh, 0))!=PAM_SUCCESS ||
           ($res=pam_end($pamh, 0))!=PAM_SUCCESS) {
          print "$seq ERROR ".pam_strerror($pamh,$res)."\n";
        } else {
          print "$seq OK \n";
        }   
      }
    
    }
    Come si può vedere non è ancora la "versione elegante"...e mancano ancora un paio di cosine, ma a cercare di sistemare il tutto mi ci metto ora...
    Quanto sopra, unitamente alla corretta configurazione di kerberos e samba, fa il lavoro che volevo...e anche velocemente...almeno in ambiente di test...
    Grazie davvero a tutti!!!
    mAx

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.