Script per allineare scadenza password tra 389-ds (LDAP) e Samba
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.
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.



Twitter
LinkedIn
Digg
Delicious
Leave a Reply