#!/usr/share/ucs-test/runner python2.7
## desc: Test hijacking uidNumber=0
## roles-not:
##  - memberserver
##  - basesystem
## packages:
##  - python-univention-lib
##  - python-ldap
## exposure: dangerous

from univention.testing.utils import fail
from univention.testing.udm import UCSTestUDM
import univention.testing.strings as uts
from univention.config_registry import ConfigRegistry
import univention.uldap
import ldap
import sys

ucr = ConfigRegistry()
ucr.load()

add_uids=(uts.random_username(), uts.random_username(),)
add_testcases = (
	(	## case 0
		"uid=%s,cn=idmap,cn=univention,%s" % (add_uids[0], ucr.get('ldap/base'),),
		(
			("uid", add_uids[0]),
			("objectClass", [
				"top",
				"person",
				"posixAccount",
				]
			),
			("sn", "foo"),
			("cn", "foo"),
			("description", "foo"),
			("homeDirectory", "foo"),
			("uidNumber", "0"),
			("gidNumber", "5002"),
		)
	),
	(	## case 1
		"uid=%s,cn=computers,%s" % (add_uids[1], ucr.get('ldap/base'),),
		(
			("uid", add_uids[1]),
			("objectClass", [
				"top",
				"person",
				"posixAccount",
				]
			),
			("sn", "foo"),
			("cn", "foo"),
			("description", "foo"),
			("homeDirectory", "foo"),
			("uidNumber", "0"),
			("gidNumber", "5002"),
		)
	),
)

modify_uids=(uts.random_username(),)
modify_testcases = (
	(	## case 0
		"cn=Windows Hosts,cn=groups,%s" % ucr.get('ldap/base'),
		(
			("objectClass", "", "posixAccount"),
			("uid", "", modify_uids[0]),
			("uidNumber", "", "0"),
			("homeDirectory", "", "foo"),
		)
	),
)

if __name__ == "__main__":
	udm = UCSTestUDM()

	with open('/etc/machine.secret') as pwdfile:
		lo = univention.uldap.access( host=ucr.get('ldap/master'), port=int(ucr.get('ldap/master/port', '7389')), base=ucr.get('ldap/base'), binddn=ucr.get('ldap/hostdn'), bindpw=pwdfile.read())

	
	for dn, al in add_testcases:
		try:
			lo.add(dn, al)
		except ldap.INSUFFICIENT_ACCESS:
			print "OK: ldapadd of %s denied" % (dn,)
			pass
		else:
			fail('uidNumber=0 hijacking by ldapadd succeded: %s' % (dn,))
			lo.delete(dn)
			sys.exit(100)

	for dn, ml in modify_testcases:
		try:
			lo.modify(dn, ml)
		except ldap.INSUFFICIENT_ACCESS:
			print "OK: ldapmodify of %s denied" % (dn,)
			pass
		else:
			fail('uidNumber=0 hijacking by ldapmodify succeded: %s' % (dn,))
			rml = [ (attr, new, old) for (attr, old, new) in ml ]
			lo.modify(dn, rml)
			sys.exit(100)

# vim: set ft=python :
