#!/usr/bin/python
# -*- coding: utf-8 -*-

import ldap, signal, sys, time, os

# Pequeno programa para verificar se o servidor de LDAP bloqueou
# CIIST - João Poupino ???
# CIIST - José Calhariz 2004/10/19
# CIIST - Nuno Rodrigues 2006/09/22

# TODO
#
# Era bom tornar este script independente da distribuição como o
# slapdcheck
#
#

TIMEOUT = 5
lista_atributos = ["uid", "mail"]
base = "uid=nuno.rodrigues, ou=tdi, dc=tagus, dc=ist, dc=utl, dc=pt"

#Variᶥis de Erro
ERRO_GENERICO = -1
#Variᶥis do nagios
service_status="SERVICE STATUS: "
NAGIOS_OK = 0
NAGIOS_CRITICAL = 2
NAGIOS = "nagios"
NAGIOS_ALARME = 1
#Variᶥis do Keepalive
KA_ERROR = 1
KA_OK = 0
KA = "ka"
#Variᶥis de host onde corre o ldap
LOCAL = "localhost"

def timeout(signal, frame):
	erro = -1
	# Foi recebido um signal
	# Vamos ver onde estᠡ correr este script, para fazer o procedimento certo
	prog = sys.argv[1]
	# Para o nagios devolve CRITICAL
	if prog == NAGIOS :
		erro = NAGIOS_CRITICAL
	# Para o Keepalive devolve ERRO
	elif prog == KA :
		erro = KA_ERROR
	
	# Numa mᱵina a correr o ldap, deve matar o ldap!
	if prog == LOCAL :
		print "slapdtimeout: slapd timed out!"
		print "killing ldap..."
		os.system("/etc/init.d/ldap stop > /dev/null 2>&1")
		time.sleep(2)
		print "slapdtimeout: killing it again..."
		os.system("/etc/init.d/ldap stop > /dev/null 2>&1")
		sys.exit("slapdtimeout: slapd killed")

	# Retorno para aplica絥s tipo nagios/keepalive
	print service_status + "Timed out while trying to reach the server"
	sys.exit(erro) # Critical return in case of timeout

# Fun磯 verifiy(where,host)
# Recebe	- A aplica磯 que o estᠡ correr
#		- O host que deve testar
# Devolve	- Erro ou sucesso, consoantes a aplica磯 que o estiver a correr/host
#
def verify(where,host,time):
	erro = -1
	sucesso = -1

	# Definir variaveis ERRO/SUCESSO
	if where == KA :
		erro = KA_ERROR
		sucesso = KA_OK
	elif where == NAGIOS :
		erro = NAGIOS_CRITICAL
		sucesso = NAGIOS_OK

	# Armar os signals
	signal.signal(signal.SIGALRM, timeout)
	
	signal.alarm(time)

	try:
		# Fazer a ligacao ao ldap
		l = ldap.initialize("ldap://"+host) 
		l.simple_bind_s("", "") 
		# Se tudo correr bem, continuar...
	except ldap.LDAPError:
		# Excep磯 apanhada -> Erro
		print service_status + "CRITICAL, can't connect to ldap server"
		sys.exit(erro) # This is a critical return
	signal.alarm(time)
	try:
		# Vamos ent㯠fazer uma pesquisa...
		result = l.search_s(base, ldap.SCOPE_BASE, "(&(objectClass=tdiPerson)(uid=nuno.rodrigues))", lista_atributos, 0)

		# Se tudo correr bem, vamos devolver sucesso
		print service_status + "OK, LDAP is working on "+host
		sys.exit(sucesso)
	except ldap.LDAPError:
		# Erro na pesquisa
		print service_status + "CRITICAL, can't perform the search"
		sys.exit(erro) # Return Critical

def verifica_argumentos(lista_argumentos):
	#lista com as possibilidades
	validos = [NAGIOS,KA,LOCAL]

	# Verifica磯 do n de argumentos que s㯠passados ࠡplica磯
	if len(lista_argumentos) > 4 :
		print "Erro: Utiliza磯: " + sys.argv[0] + " <application> <host> [timeout]"
		print "applcation: nagios|ka|localhost\n"
		sys.exit(ERRO_GENERICO)
	
	if len(lista_argumentos) < 3 :
		print "Erro: Utiliza磯: " + sys.argv[0] + " <application> <host> [timeout]"
		print "applcation: nagios|ka|localhost\n"
		sys.exit(ERRO_GENERICO)

	if len(lista_argumentos) == 4 :
		try:
			time = int(sys.argv[3])
		except :
			print "Erro. O timeout tem de ser um inteiro"
			sys.exit(ERRO_GENERICO)
	else : 
		time = TIMEOUT

	# Vamos verificar se 頰ara o nagios/localhost/keepalive
	for i in validos :
		if i == lista_argumentos[1]:
			return time;
	print "Argumento invᬩdo: "+lista_argumentos[1]
	sys.exit(ERRO_GENERICO)

# Vamos fazer uma verifica磯 de argumentos, antes de prosseguir
time = verifica_argumentos(sys.argv)

verify(sys.argv[1],sys.argv[2],time)

