Ho creato questo script per risolvere un problema che si è presentato durante la fase di cambio password da computer in un dominio NT4 gestito tramite samba-3 + LDAP (questo in realtà gestito tramite un 389-ds) su una CentOS 5.6.


Sono state applicate le password policies su ldap e su samba.
Ho notato che cambiando la password direttamente dal client Windows, alcune applicazioni che si autenticano tramite LDAP, restituivano degli errori.

Indagando, su cosa cambiasse nella struttura LDAP dell’utente, ho trovato che quando si cambia la password dal client, un campo di LDAP, nello specifico passwordexpirationtime, veniva resettato al valore di default corrispondente al 1 Gennaio 1970.

Dal momento che non è prevedibile sapere quando qualcuno decide di cambiare la password, ho creato questo semplice ma efficace script di shell che viene lanciato via crontab.

#!/bin/bash
source ~/.bash_profile
FILE_REPORT=/var/log/aggiusta_scadenza_pwd.log
ERROR_REPORT=/root/tmp/errori_scadenze_password.log

TEST=0 # 0 -> ESEGUE …. 1 -> TEST
#  
GIORNI_DALLA_SCADENZA=15
# Ripuliamo i nostri files di reportistica
echo "" > $FILE_REPORT
echo "" > $ERROR_REPORT
function convertiMeseNum(){
                # Convertiamo il mese da letterale a numerico
                case $1 in
                        "gen")
                                MESE="01"
                        ;;
                        "feb")
                                MESE="02"
                        ;;
                        "mar")
                                MESE="03"
                        ;;
                        "apr")
                                MESE="04"
                        ;;
                        "mag")
                                MESE="05"
                        ;;
                        "giu")
                                MESE="06"
                        ;;
                        "lug")
                                MESE="07"
                        ;;
                        "ago")
                                MESE="08"
                        ;;
                        "set")
                                MESE="09"
                        ;;
                        "ott")
                                MESE="10"
                        ;;
                        "nov")
                                MESE="11"
                        ;;
                        "dic")
                                MESE="12"
                        ;;
                esac
}

function allineaScadenzaPwd(){
        TMP_LDIF_DIR=/root/tmp
        if [ -d $TMP_FILE_DIR ]
        then
                mkdir -p $TMP_LDIF_DIR
        fi
       
        # Estraiamo la data da samba e rendiamola utilizzabile dal comanda date
        DATA_SCADENZA=`pdbedit -v $1 | grep "Password must change:" | awk -F ": " ‘{ print $2 }’`
        case "$DATA_SCADENZA" in
                # Questo è il caso in cui l’utente non ha una scadenza della password
                "never")
                        echo "L’utente $1 NON ha scadenza password" >> $ERROR_REPORT
                ;;
                # Nel caso in cui non è settata la data di scadenza
                "0")
                        echo "L’utente $1 NON HA IMPOSTATO una data di scadenza!! (Verificare) " >> $ERROR_REPORT
                ;;

                # Case di default
                *)

                        MESE_SCADENZA="`echo $DATA_SCADENZA | awk ‘{ print $3 }’`"
                        GIORNO_SCADENZA="`echo $DATA_SCADENZA | awk ‘{ print $2 }’`"
                        ANNO_SCADENZA="`echo $DATA_SCADENZA | awk ‘{ print $4 }’`"
                        ORARIO_SCADENZA="`echo $DATA_SCADENZA | awk ‘{ print $5 }’`"
               
                        # Estraiamo il mese numerico dal mese di scadenza
                        convertiMeseNum $MESE_SCADENZA
                       
                        # Trasformiamo la data ottenuta in formato unix timestamp      
                        SCADENZA_PASSWORD=`date -d "$ANNO_SCADENZA-$MESE-$GIORNO_SCADENZA $ORARIO_SCADENZA" "+%s"`
                        # Su LDAP il campo di segnalazione scadenza è impostato a 15 giorni prima della scadenza reale dell’account
                        SCADENZA_CALCOLATA=`date -d @$(( $SCADENZA_PASSWORD – $(( $GIORNI_DALLA_SCADENZA * 86400 )) ))`
                        MESE_SCADENZA_1="`echo $SCADENZA_CALCOLATA | awk ‘{ print $2 }’`"
       
                        convertiMeseNum $MESE_SCADENZA_1
       
                        GIORNO_SCADENZA_1="`echo $SCADENZA_CALCOLATA | awk ‘{ print $3 }’`"
                        if [ $((GIORNO_SCADENZA_1)) -lt 10 ]
                        then
                                # Trovato numero minore di 10 per utente $1 … converto
                                GIORNO_SCADENZA_1="0"$GIORNO_SCADENZA_1
                                # echo "Giorno scadenza 1 -> $GIORNO_SCADENZA_1" >> $FILE_REPORT
                        fi
                        ORARIO_SCADENZA_1="`echo $SCADENZA_CALCOLATA | awk ‘{ print $4 }’ | sed ‘s/://g’`"
                        ANNO_SCADENZA_1="`echo $SCADENZA_CALCOLATA | awk ‘{ print $6 }’`"
                        SCADENZA_REALE=$ANNO_SCADENZA_1$MESE$GIORNO_SCADENZA_1$ORARIO_SCADENZA_1
                        SCADENZA_PASSWORD_Z=$SCADENZA_REALE"Z"
                        # echo $1 $DATA_SCADENZA $SCADENZA_CALCOLATA >> $FILE_REPORT
       
                        if [ $SCADENZA_PASSWORD ]
                        then
                                echo "Modifico data di scadenza per $1 -> $DATA_SCADENZA in data $SCADENZA_PASSWORD_Z" >> $FILE_REPORT
                                TMP_LDAP_FILE=$TMP_LDIF_DIR/$1.modify.ldif
                                echo "dn: uid=$1,ou=People,dc=dominio" > $TMP_LDAP_FILE
                                echo "changetype: modify" >> $TMP_LDAP_FILE
                                echo "replace: passwordexpirationtime" >> $TMP_LDAP_FILE
                                echo "passwordexpirationtime: $SCADENZA_PASSWORD_Z" >> $TMP_LDAP_FILE
                                echo "-" >> $TMP_LDAP_FILE
                                echo "changetype: modify" >> $TMP_LDAP_FILE
                                echo "replace: passwordexpwarned" >> $TMP_LDAP_FILE
                                echo "passwordexpwarned: 0" >> $TMP_LDAP_FILE

                                # Se questa non è l’esecuzione di un test, applichiamo le modifiche a LDAP
                                if [ $TEST -eq 0 ]
                                then
                                        /usr/bin/ldapmodify -x -Z -D "cn=Directory Manager" -w lamiapassword -f $TMP_LDAP_FILE
                                fi
                        fi
                ;;
        esac
}

#
# Eseguiamo una scansione sull’albero LDAP ed estraiamo tutti gli utenti di dominio attivi
for uid in `ldapsearch -x -Z -b ou=People,dc=dominio "(&(uid=*)(!(sambaAcctFlags=[DU*]))(passwordexpirationtime=19700101000000Z))" | grep uid: | awk -F ": " ‘{ print $2 }’`
do
        allineaScadenzaPwd $uid
done

L’esecuzione di questo script anche con qualche migliaio di utenti censiti, impiega pochi secondi.

Buon Divertimento.

Free PDF    Invia l'articolo in formato PDF