#!/usr/bin/python2.7
# -*- coding: utf-8 -*-
#
# Univention Directory Manager Modules
#  check for unused dhcp records
#
# Copyright 2004-2014 Univention GmbH
#
# http://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.


import ldap, string, sys

import univention.baseconfig

baseConfig=univention.baseconfig.baseConfig()
baseConfig.load()

baseDN=baseConfig['ldap/base']

lo=ldap.open('localhost', 7389)
bindpw=open('/etc/ldap.secret').read()
lo.simple_bind_s("cn=admin,"+baseDN, bindpw.strip('\n\r'))

# check for dhcp records without matching computer object

computers=lo.search_s(baseDN, ldap.SCOPE_SUBTREE, 'objectClass=univentionDhcpHost', ['dhcpHWAddress'])

print "Found no computer objects for these dhcp records:\n"

for comp in computers:
	mac = comp[1]["dhcpHWAddress"][0]
	if mac.find(" ")>=0:
		mac = mac.split(" ")[1]
	
	match_cmp_rec = lo.search_s(baseDN, ldap.SCOPE_SUBTREE, '(&(objectClass=univentionHost)(macAddress=%s))'%mac,[])

	if len(match_cmp_rec)==0:
		print "\t%s"%comp[0]
print

# check for dns host records without matching computers objects (match IP)

deadEndRecords={}	# needed later for reverse lookup checks
allRecords={}

computers=lo.search_s(baseDN, ldap.SCOPE_SUBTREE, 'objectClass=dNSZone', ['aRecord', 'relativeDomainName', 'zoneName'])

print "Found no computer objects for these dns records:\n"

for comp in computers:
	if comp[1].has_key("aRecord"):
		relative_domain_name=comp[1]['relativeDomainName'][0]
		zone_name=comp[1]['zoneName'][0]
		allRecords[relative_domain_name + "." + zone_name]=comp
		match_cmp_rec = lo.search_s(baseDN, ldap.SCOPE_SUBTREE, '(&(objectClass=univentionHost)(aRecord=%s))'%comp[1]["aRecord"][0], [])
		if len(match_cmp_rec)==0:
			deadEndRecords[relative_domain_name + "." + zone_name]=comp
			print "\t%s"%comp[0]
print

# check for dns reverse lookup records without match computer names

computers=lo.search_s(baseDN, ldap.SCOPE_SUBTREE, 'objectClass=dNSZone', ['pTRRecord'])

print "Found no computer objects for theses dns reverse lookup records:\n"

for comp in computers:
	if comp[1].has_key('pTRRecord'):
		parts = comp[1]['pTRRecord'][0].split(".")
		relative_domain_name = parts[0]
		zone_name = ".".join(parts[1:-1])
		
		# check if there is a corresponding valid forward entry for this object
		if deadEndRecords.has_key(relative_domain_name + "." + zone_name):
			print "\t%s"%comp[0]
		elif not(allRecords.has_key(relative_domain_name + "." + zone_name)):
			print "\t%s"%comp[0]
