scripts/surveillance/derniere_connexion.py
Daniel STAN 66f3fd0707 derniere_connexion: catche EnvironmentError
Au moins, on ne crashera pas lamentablement au milieu de la boucle... Ce qui
permet d'être sûr qu'on màj tous les comptes nécessaires.
De toute façon, si on rencontre cette erreur sur un adh, c'est qu'un autre
script est en train de s'exécuter de manière concurrente.
2015-04-07 19:54:58 +02:00

97 lines
3.6 KiB
Python
Executable file

#!/bin/bash /usr/scripts/python.sh
# -*- coding: utf-8 -*-
#
# derniere_connexion.py
# -----------------
#
# Copyright (C) 2013-2015 Raphaël-David Lasseri <lasseri@crans.org>,
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
import re
import sys
import os
import datetime
from time import mktime
from time import strptime
from lc_ldap import shortcuts
# Requete ldap pour récupérer tout les adhérents en mode read-write
db = shortcuts.lc_ldap_admin()
# Expression régulière sur les logs de connexion pour l'intranet et pour le CAS
# Pour le CAS on prends comme entrée cat ~/cas.log | grep -B 2 -A 2 "ACTION: AUTHENTICATION_SUCCESS"| grep 'WHEN\|WHO'|sed 'N;s/\n/ /'
COMPILE_REGEX = lambda x:re.compile(x)
COMPILED_REGEX = map(COMPILE_REGEX, [
r'^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}).*(?:'r'dovecot.*Login: user=<|'r'sshd.*Accepted.*for 'r')([^ >]+).*$',
r'^(.*) LOGIN INFO User logged in : (.*)',
r'WHO: \[username: (.*)\] WHEN: (.*) (?:CEST|CET) (.*)',
])
def parse_logs(logfile):
"""
Parse les logs sur l'entrée standard et rempli un dictionnaire
ayant pour clef l'uid de l adherent
"""
parsed_log = {}
for line in logfile:
m0 = COMPILED_REGEX[0].match(line)
m1 = COMPILED_REGEX[1].match(line)
m2 = COMPILED_REGEX[2].match(line)
if m0:
parsed_log[m0.group(2)]=int(mktime(strptime(m0.group(1),"%Y-%m-%dT%H:%M:%S")))
if m1:
parsed_log[m1.group(2)]=int(mktime(strptime(m1.group(1),"%d/%b/%Y:%H:%M:%S")))
if m2:
parsed_log[m2.group(1)]=int(mktime(strptime(m2.group(2)+m2.group(3),"%a %b %d %H:%M:%S%Y")))
return parsed_log
def update_connexion(dico):
"""
Fonction qui met a jour la base ldap.
Si la date présente dans ldap est inférieure à celle des logs
parsés sur le serveur ou ce script est executé on met à jour
l'attribut avec la nouvelle valeur
"""
for adh in db.search(u'(&(uid=*)(aid=*))',mode='rw',sizelimit=60000):
with adh:
uid = adh.get(u'uid',None)[0].value
last_connexion = adh.get(u'derniereConnexion',None)
if uid in dico:
date_log_int = dico[u'%s'%uid]
date_log=datetime.datetime.fromtimestamp(date_log_int)
if last_connexion:
date_ldap=datetime.datetime.fromtimestamp(last_connexion[0].value)
if date_log > date_ldap:
last_connexion.pop()
last_connexion.append(date_log_int)
else: last_connexion.append(date_log_int)
try:
adh.save()
except EnvironmentError as err:
print "Cannot update %r. EnvironmentError(%r)" % (adh, err)
print "Maybe you should fix your damn cron ?"
if __name__ == "__main__":
parsed_log=parse_logs(sys.stdin)
update_connexion(parsed_log)