Esempio n. 1
0
File: dns.py Progetto: B-Rich/smart
def s4_srv_record_create(s4connector, object):                                                                                                                                                     
	_d=ud.function('s4_srv_record_create')

	dnsRecords=[]

	zoneDn, zoneName=__create_default_s4_zone_dn(s4connector, object)

	relativeDomainName=object['attributes'].get('relativeDomainName')
	relativeDomainName=univention.s4connector.s4.compatible_list(relativeDomainName)

	# ucr set connector/s4/mapping/dns/srv_record/_ldap._tcp.test.local/location='100 0 389 foobar.test.local.'
	# ucr set connector/s4/mapping/dns/srv_record/_ldap._tcp.test.local/location='100 0 389 foobar.test.local. 100 0 389 foobar2.test.local.'
	ucr_locations = s4connector.configRegistry.get('connector/s4/mapping/dns/srv_record/%s.%s/location' % (relativeDomainName[0].lower(),zoneName[0].lower()))
	ud.debug(ud.LDAP, ud.INFO, 's4_srv_record_create: ucr_locations for connector/s4/mapping/dns/srv_record/%s.%s/location: %s' % (relativeDomainName[0].lower(),zoneName[0].lower(),ucr_locations))
	if ucr_locations:
		if ucr_locations.lower() == 'ignore':
			return
		# Convert ucr variable
		priority=None; weight=None; port=None; target=None
		for v in ucr_locations.split(' '):
			# Check explicit for None, because the int values may be 0
			if priority == None: priority=int(v)
			elif weight == None: weight=int(v)
			elif port == None: port=int(v)
			elif not target: target=__remove_dot(v)
			if priority != None and weight != None and port != None and target:
				ud.debug(ud.LDAP, ud.INFO, 'priority=%d weight=%d port=%d target=%s' % (priority,weight,port,target))
				s=SRVRecord(target, port, priority, weight)
				dnsRecords.append(ndr_pack(s))
				priority=None; weight=None; port=None; target=None

	else:
		__pack_sRVrecord(object, dnsRecords)

	dnsNodeDn=s4_dns_node_base_create(s4connector, object, dnsRecords)
Esempio n. 2
0
File: dns.py Progetto: B-Rich/smart
def __create_s4_forward_zone(s4connector, zoneDn, zoneName):
	al=[]
	al.append(('objectClass', ['top', 'dnsZone']))
	al.append(('DC', univention.s4connector.s4.compatible_list(zoneName)))

	ud.debug(ud.LDAP, ud.INFO, '_dns_zone_forward_con_create: dn: %s' % zoneDn)
	ud.debug(ud.LDAP, ud.INFO, '_dns_zone_forward_con_create: al: %s' % al)
	s4connector.lo_s4.lo.add_s(zoneDn, al)
Esempio n. 3
0
File: dc.py Progetto: B-Rich/smart
def con2ucs (s4connector, key, object):
	_d=ud.function('dns: con2ucs')

	ud.debug(ud.LDAP, ud.INFO, 'dc con2ucs: Object (%s): %s' % (object['dn'], object))

	# Search sambaDomainname object via sambaSID
	sambadomainnameObject = univention.admin.handlers.settings.sambadomain.lookup(None, s4connector.lo, 'sambaSID=%s' % object['attributes'].get('objectSid', [])[0])

	if len(sambadomainnameObject) > 1:
		ud.debug(ud.LDAP, ud.WARN, 'dc con2ucs: Found more than one sambaDomainname object with sambaSID %s' % object['attributes'].get('objectSid', [])[0])
	elif len(sambadomainnameObject) == 1:

		# Use the first sambaDomain
		sambadomainnameObject = sambadomainnameObject[0]

		# Do we modify this UCS object
		modify = False

		sync_times = [ ('maxPasswordAge', 'maxPwdAge'), ('minPasswordAge', 'minPwdAge'), ('lockoutDuration', 'lockoutDuration') ]
		for (ucs_attr, s4_attr) in sync_times:
			ucs_time = _unixTimeInverval2seconds(sambadomainnameObject.get(ucs_attr, 0))
			s4_time = _nano2s(long(object['attributes'].get(s4_attr, [0])[0]) * -1)

			if ucs_time != s4_time:
				sambadomainnameObject[ucs_attr] = [str(s4_time), 'seconds']
				modify = True
		
		sync_integers = [ ('passwordHistory', 'pwdHistoryLength'), ('passwordLength', 'minPwdLength') ]
		for (ucs_attr, s4_attr) in sync_integers:
			ucs_val = sambadomainnameObject.get(ucs_attr, 0)
			s4_val = object['attributes'].get(s4_attr, [None])[0]
			if ucs_val != s4_val:
				sambadomainnameObject[ucs_attr] = s4_val
				modify = True
			
		if modify:
			sambadomainnameObject.modify()
		

	if s4connector.configRegistry.is_true('connector/s4/mapping/gpo', True):
		# Search DC object via ldap search

		dn,attr = s4connector.lo.search('objectClass=*', scope='base')[0]
		ml = []

		ucs_val = attr.get('msGPOLink')
		s4_val = object['attributes'].get('gPLink')

		if ucs_val != s4_val:
			if not 'msGPO' in attr.get('objectClass', []):
				ml.append(('objectClass', '', 'msGPO'))

			ml.append(('msGPOLink', ucs_val, s4_val))

		if ml:
			s4connector.lo.modify(dn, ml)

	return True
Esempio n. 4
0
File: dns.py Progetto: B-Rich/smart
def __pack_mxRecord(object, dnsRecords):
	for mXRecord in object['attributes'].get('mXRecord', []):
		if mXRecord:
			ud.debug(ud.LDAP, ud.INFO, '__pack_mxRecord: %s' % mXRecord)
			mXRecord=univention.s4connector.s4.compatible_modstring(mXRecord)
			mx=mXRecord.split(' ')
			priority=mx[0]
			name=mx[1]
			mx_record=MXRecord(name, int(priority))
			dnsRecords.append(ndr_pack(mx_record))
			ud.debug(ud.LDAP, ud.INFO, '__pack_mxRecord: %s' % ndr_pack(mx_record))
Esempio n. 5
0
File: dns.py Progetto: B-Rich/smart
def ucs_host_record_create(s4connector, object):
	_d=ud.function('ucs_host_record_create')
	ud.debug(ud.LDAP, ud.INFO, 'ucs_host_record_create: object: %s' % object)

	zoneName, relativeDomainName=__split_s4_dn(object['dn'])

	# unpack the host record
	a=__unpack_aRecord(object)

	# Does a host record for this zone already exist?
	searchResult=s4connector.lo.search(filter='(&(relativeDomainName=%s)(zoneName=%s))' % (relativeDomainName, zoneName), unique=1)
	if len(searchResult) > 0:
		superordinate=s4connector_get_superordinate('dns/host_record', s4connector.lo, searchResult[0][0])
		newRecord= univention.admin.handlers.dns.host_record.object(None, s4connector.lo, position=None, dn=searchResult[0][0], superordinate=superordinate, attributes=[], update_zone=False)
		newRecord.open()
		if set(newRecord['a']) != set(a):
			newRecord['a']=a
			newRecord.modify()
		else:
			ud.debug(ud.LDAP, ud.INFO, 'ucs_host_record_create: do not modify host record')
	else:
		zoneDN='zoneName=%s,%s' % (zoneName, s4connector.property['dns'].ucs_default_dn)

		ud.debug(ud.LDAP, ud.INFO, 'ucs_host_record_create: zoneDN: %s' % zoneDN)
		superordinate=s4connector_get_superordinate('dns/host_record', s4connector.lo, zoneDN)
		ud.debug(ud.LDAP, ud.INFO, 'ucs_host_record_create: superordinate: %s' % superordinate)

		position=univention.admin.uldap.position(zoneDN)

		newRecord= univention.admin.handlers.dns.host_record.object(None, s4connector.lo, position, dn=None, superordinate=superordinate, attributes=[], update_zone=False)
		newRecord.open()
		newRecord['name']=relativeDomainName
		newRecord['a']=a
		newRecord.create()
Esempio n. 6
0
File: dns.py Progetto: B-Rich/smart
def ucs2con (s4connector, key, object):
	_d=ud.function('dns: ucs2con')

	dns_type=_identify_dns_ucs_object(s4connector, object)
	
	if not dns_type:
		# unknown object -> ignore
		ud.debug(ud.LDAP, ud.INFO, 'dns ucs2con: Ignore unkown dns object: %s' % object['dn'])
		return True

	ud.debug(ud.LDAP, ud.INFO, 'dns ucs2con: Object (%s) is from type %s' % (object['dn'], dns_type))
		
	if dns_type == 'forward_zone' or dns_type == 'reverse_zone':
		if object['modtype'] in ['add', 'modify']:
			s4_zone_create(s4connector, object)
		elif object['modtype'] in ['delete']:
			s4_zone_delete(s4connector, object)
		# ignore move

	elif dns_type == 'host_record':
		if object['modtype'] in ['add', 'modify']:
			s4_host_record_create(s4connector, object)
		elif object['modtype'] in ['delete']:
			s4_dns_node_base_delete(s4connector, object)
		# ignore move

	elif dns_type == 'alias':
		if object['modtype'] in ['add', 'modify']:
			s4_cname_create(s4connector, object)
		elif object['modtype'] in ['delete']:
			s4_dns_node_base_delete(s4connector, object)
		# ignore move

	elif dns_type == 'srv_record':
		if object['modtype'] in ['add', 'modify']:
			s4_srv_record_create(s4connector, object)
		elif object['modtype'] in ['delete']:
			s4_dns_node_base_delete(s4connector, object)
		# ignore move

	elif dns_type == 'ptr_record':
		if object['modtype'] in ['add', 'modify']:
			s4_ptr_record_create(s4connector, object)
		elif object['modtype'] in ['delete']:
			s4_dns_node_base_delete(s4connector, object)
		# ignore move

	return True
Esempio n. 7
0
File: dns.py Progetto: B-Rich/smart
def ucs_srv_record_delete(s4connector, object):
	_d=ud.function('ucs_srv_record_delete')
	ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_delete: object: %s' % object)

	zoneName, relativeDomainName=__split_s4_dn(object['dn'])

	searchResult=s4connector.lo.search(filter='(&(relativeDomainName=%s)(zoneName=%s))' % (relativeDomainName, zoneName), unique=1)
	if len(searchResult) > 0:
		superordinate=s4connector_get_superordinate('dns/srv_record', s4connector.lo, searchResult[0][0])
		newRecord= univention.admin.handlers.dns.srv_record.object(None, s4connector.lo, position=None, dn=searchResult[0][0], superordinate=superordinate, attributes=[], update_zone=False)
		newRecord.open()
		newRecord.delete()
	else:
		ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_delete: Object was not found, filter was: ((&(relativeDomainName=%s)(zoneName=%s))' % (relativeDomainName, zoneName))

	return True
Esempio n. 8
0
def sid_to_s4(s4connector, key, object):
	ud.debug(ud.LDAP, ud.INFO, "sid_to_s4 object: %s" % object)

	sidAttribute='sambaSID'
	if s4connector.configRegistry.is_false('connector/s4/mapping/sid', False):
		ud.debug(ud.LDAP, ud.INFO, 'sid_to_s4: SID mapping is disabled via UCR: connector/s4/mapping/sid')
		sidAttribute='univentionSamba4SID'
	else:
		# This case will be handled by direct mapping
		return

	# object dn was already mapped to the s4 DN:
	s4_dn = object['dn']
	modlist = []
	
	# search the ucs object via 
	if not object['attributes'].has_key(sidAttribute):
		ud.debug(ud.LDAP, ud.INFO, 'sid_to_s4: UCS object does not have a %s' % sidAttribute)
		return


	sambaSID = object['attributes'][sidAttribute]
	# get the ad sid
	(s4_dn, s4_attributes) = s4connector.lo_s4.lo.search_s(s4_dn, ldap.SCOPE_BASE, '(objectSid=*)', ['objectSid'] )[0]
	objectSid = s4_attributes.get('objectSid')
	if objectSid:
		# decoded_s4_sid = univention.s4connector.s4.decode_sid(objectSid[0])
		s4_objectSid = ndr_unpack(security.dom_sid, objectSid[0])
		decoded_s4_sid = str(s4_objectSid)
		if decoded_s4_sid == sambaSID[0]:
			ud.debug(ud.LDAP, ud.INFO, 'sid_to_s4: objectSid and %s are equal' % sidAttribute)
			return

		### change objectSID
		#	http://serverfault.com/questions/53717/how-can-i-change-the-sid-of-a-user-account-in-the-active-directory
		#	http://technet.microsoft.com/en-us/library/cc961998.aspx

		ud.debug(ud.LDAP, ud.INFO, 'sid_to_s4: changing objectSid from %s to %s' % (decoded_s4_sid, sambaSID[0]) )
		new_objectSid_ndr = ndr_pack(security.dom_sid(sambaSID[0]))
	 	modlist.append((ldap.MOD_REPLACE, 'objectSid', new_objectSid_ndr))

		# objectSid modification for an Samba4 object is only possible with the "provision" control:
		LDB_CONTROL_PROVISION_OID = '1.3.6.1.4.1.7165.4.3.16'
		controls = [ LDAPControl(LDB_CONTROL_PROVISION_OID,criticality=0) ]
		s4connector.lo_s4.lo.modify_ext_s(s4_dn, modlist, serverctrls=controls)

	pass
Esempio n. 9
0
def sid_to_s4_mapping(s4connector, key, object):
	ud.debug(ud.LDAP, ud.INFO, "sid_to_s4_mapping")
	sidAttribute='sambaSID'
	if s4connector.configRegistry.is_false('connector/s4/mapping/sid', False):
		ud.debug(ud.LDAP, ud.INFO, 'sid_to_s4: SID mapping is disabled via UCR: connector/s4/mapping/sid')
		sidAttribute='univentionSamba4SID'

	sambaSID = object['attributes'][sidAttribute]
		
	# Two diffrent cases are possible, the user sid contains the
	# domain sid or not.
	if sambaSID[0].startswith('S-'):
		new_objectSid_ndr = ndr_pack(security.dom_sid('%s' % (sambaSID[0])))
	else:
		new_objectSid_ndr = ndr_pack(security.dom_sid('%s-%s' % (s4connector.s4_sid, sambaSID[0])))

	return [new_objectSid_ndr]
Esempio n. 10
0
File: dc.py Progetto: B-Rich/smart
def _unixTimeInverval2seconds(unixTime):
	if type(unixTime) != type([]):
		return unixTime

	if len(unixTime) != 2:
		ud.debug(ud.LDAP, ud.WARN, 'dc _unixTimeInverval2seconds: Not a valid time format: %s' % unixTime)
		return 0

	if unixTime[1] == 'seconds':
		return unixTime[0]
	elif unixTime[1] == 'minutes':
		return unixTime[0] * 60
	elif unixTime[1] == 'hours':
		return unixTime[0] * 3600 # 60 * 60
	elif unixTime[1] == 'days':
		return unixTime[0] * 86400 # 60 * 60 * 24
	else:
		ud.debug(ud.LDAP, ud.WARN, 'dc _unixTimeInverval2seconds: Not a valid time unit: %s' % unixTime)
		return 0
Esempio n. 11
0
File: dns.py Progetto: B-Rich/smart
def con2ucs (s4connector, key, object):
	_d=ud.function('dns: con2ucs')

	ud.debug(ud.LDAP, ud.INFO, 'dns con2ucs: Object (%s): %s' % (object['dn'], object))
	
	dns_type=_identify_dns_con_object(s4connector, object)

	if not dns_type:
		# unknown object -> ignore
		ud.debug(ud.LDAP, ud.INFO, 'dns con2ucs: Ignore unkown dns object: %s' % object['dn'])
		return True

	ud.debug(ud.LDAP, ud.INFO, 'dns con2ucs: Object (%s) is from type %s' % (object['dn'], dns_type))

	if dns_type == 'host_record':
		if object['modtype'] in ['add', 'modify']:
			ucs_host_record_create(s4connector, object)
		elif object['modtype'] in ['delete']:
			ucs_host_record_delete(s4connector, object)
		# ignore move
	elif dns_type == 'ptr_record':
		if object['modtype'] in ['add', 'modify']:
			ucs_ptr_record_create(s4connector, object)
		elif object['modtype'] in ['delete']:
			ucs_ptr_record_create(s4connector, object)
		# ignore move
	elif dns_type == 'alias':
		if object['modtype'] in ['add', 'modify']:
			ucs_cname_create(s4connector, object)
		elif object['modtype'] in ['delete']:
			ucs_cname_create(s4connector, object)
		# ignore move
	elif dns_type == 'srv_record':
		if object['modtype'] in ['add', 'modify']:
			ucs_srv_record_create(s4connector, object)
		elif object['modtype'] in ['delete']:
			ucs_srv_record_delete(s4connector, object)
		# ignore move
	if dns_type in ['forward_zone', 'reverse_zone']:
		if object['modtype'] in ['add', 'modify']:
			ucs_zone_create(s4connector, object, dns_type)
		elif object['modtype'] in ['delete']:
			ucs_zone_delete(s4connector, object, dns_type)
		# ignore move

	return True
Esempio n. 12
0
def password_sync_s4_to_ucs(s4connector, key, ucs_object, modifyUserPassword=True):
	_d=ud.function('ldap.s4.password_sync_s4_to_ucs')
	ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs called")

	object=s4connector._object_mapping(key, ucs_object, 'ucs')
	res=s4connector.lo_s4.lo.search_s(univention.s4connector.s4.compatible_modstring(object['dn']), ldap.SCOPE_BASE, '(objectClass=*)',['objectSid','pwdLastSet'])

	pwdLastSet = None
	if res[0][1].has_key('pwdLastSet'):
		pwdLastSet = long(res[0][1]['pwdLastSet'][0])
	ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: pwdLastSet from S4: %s (%s)" % (pwdLastSet,res))
	objectSid = univention.s4connector.s4.decode_sid(res[0][1]['objectSid'][0])

	# rid = None
	# if res[0][1].has_key('objectSid'):
	# 	rid = str(univention.s4connector.s4.decode_sid(res[0][1]['objectSid'][0]).split('-')[-1])

	res=s4connector.lo_s4.lo.search_s(s4connector.lo_s4.base, ldap.SCOPE_SUBTREE, univention.s4connector.s4.compatible_modstring('(objectSid=%s)' % objectSid), ['unicodePwd', 'supplementalCredentials', 'msDS-KeyVersionNumber', 'dBCSPwd'])
	unicodePwd_attr = res[0][1].get('unicodePwd', [None])[0]
	if unicodePwd_attr:
		ntPwd = binascii.b2a_hex(unicodePwd_attr).upper()

		lmPwd = ''
		dBCSPwd = res[0][1].get('dBCSPwd', [None])[0]
		if dBCSPwd:
			lmPwd = binascii.b2a_hex(dBCSPwd).upper()

		supplementalCredentials = res[0][1].get('supplementalCredentials', [None])[0]
		msDS_KeyVersionNumber = res[0][1].get('msDS-KeyVersionNumber', [0])[0]

		ntPwd_ucs = ''
		lmPwd_ucs = ''
		krb5Principal = ''
		userPassword = ''
		modlist=[]
		res=s4connector.lo.search(base=ucs_object['dn'], attr=['sambaPwdMustChange', 'sambaPwdLastSet','sambaNTPassword', 'sambaLMPassword', 'krb5PrincipalName', 'krb5Key', 'krb5KeyVersionNumber', 'userPassword', 'shadowLastChange', 'shadowMax', 'krb5PasswordEnd'])

		if res[0][1].has_key('sambaNTPassword'):
			ntPwd_ucs = res[0][1]['sambaNTPassword'][0]
		if res[0][1].has_key('sambaLMPassword'):
			lmPwd_ucs = res[0][1]['sambaLMPassword'][0]
		if res[0][1].has_key('krb5PrincipalName'):
			krb5Principal=res[0][1]['krb5PrincipalName'][0]
		if res[0][1].has_key('userPassword'):
			userPassword=res[0][1]['userPassword'][0]
		sambaPwdLastSet = None
		if res[0][1].has_key('sambaPwdLastSet'):
			sambaPwdLastSet=res[0][1]['sambaPwdLastSet'][0]
		ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: sambaPwdLastSet: %s" % sambaPwdLastSet)
		sambaPwdMustChange = ''
		if res[0][1].has_key('sambaPwdMustChange'):
			sambaPwdMustChange=res[0][1]['sambaPwdMustChange'][0]
		ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: sambaPwdMustChange: %s" % sambaPwdMustChange)
		krb5Key_ucs=res[0][1].get('krb5Key', [])
		userPassword_ucs=res[0][1].get('userPassword', [None])[0]
		krb5KeyVersionNumber=res[0][1].get('krb5KeyVersionNumber', [None])[0]

		pwd_changed = False
		if ntPwd != ntPwd_ucs:
			pwd_changed = True
			modlist.append(('sambaNTPassword', ntPwd_ucs, str(ntPwd)))

		if lmPwd != lmPwd_ucs:
			pwd_changed = True
			modlist.append(('sambaLMPassword', lmPwd_ucs, str(lmPwd)))

		if pwd_changed:
			if krb5Principal:
				## decoding of Samba4 supplementalCredentials
				krb5Key_new = calculate_krb5key(unicodePwd_attr, supplementalCredentials, int(msDS_KeyVersionNumber))
				
				modlist.append(('krb5Key', krb5Key_ucs, krb5Key_new))
				if int(msDS_KeyVersionNumber) != int(krb5KeyVersionNumber):
					modlist.append(('krb5KeyVersionNumber', krb5KeyVersionNumber, msDS_KeyVersionNumber))

			## Append modification as well to modlist, to apply in one transaction
			if modifyUserPassword:
				modlist.append(('userPassword', userPassword_ucs, '{K5KEY}'))

			# Remove the POSIX and Kerberos password expiry interval
			if res[0][1].has_key('shadowLastChange'):
				modlist.append(('shadowLastChange', res[0][1]['shadowLastChange'][0], None))
			if res[0][1].has_key('shadowMax'):
				modlist.append(('shadowMax', res[0][1]['shadowMax'][0], None))
			if res[0][1].has_key('krb5PasswordEnd'):
				modlist.append(('krb5PasswordEnd', res[0][1]['krb5PasswordEnd'][0], None))
		else:
			ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: No password change to sync to UCS")

		if pwd_changed and (pwdLastSet or pwdLastSet == 0):
			newSambaPwdMustChange = sambaPwdMustChange
			if pwdLastSet == 0: # pwd change on next login
				newSambaPwdMustChange = str(pwdLastSet)
				newSambaPwdLastSet = str(pwdLastSet)
			else:
				newSambaPwdLastSet = str(univention.s4connector.s4.s42samba_time(pwdLastSet))
				userobject = s4connector.get_ucs_object('user', ucs_object['dn'])
				if not userobject:
					ud.debug(ud.LDAP, ud.ERROR, "password_sync_s4_to_ucs: couldn't get user-object from UCS")
					return False
				sambaPwdMustChange=sambaPwdMustChange.strip()
				if not sambaPwdMustChange.isdigit():
					pass
				elif pwd_changed or (long(sambaPwdMustChange) < time.time() and not pwdLastSet == 0):
					pwhistoryPolicy = userobject.loadPolicyObject('policies/pwhistory')
					try:
						expiryInterval=int(pwhistoryPolicy['expiryInterval'])
						newSambaPwdMustChange = str(long(newSambaPwdLastSet)+(expiryInterval*3600*24) )
					except: # FIXME: which exception is to be caught?
						# expiryInterval is empty or no legal int-string
						pwhistoryPolicy['expiryInterval']=''
						expiryInterval=-1
						newSambaPwdMustChange = ''

					ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: pwhistoryPolicy: expiryInterval: %s" %
										   expiryInterval)


			if sambaPwdLastSet:
				if sambaPwdLastSet != newSambaPwdLastSet:
					modlist.append(('sambaPwdLastSet', sambaPwdLastSet, newSambaPwdLastSet))
					ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: sambaPwdLastSet in modlist (replace): %s" %
										newSambaPwdLastSet)
			else:
				modlist.append(('sambaPwdLastSet', '', newSambaPwdLastSet ))
				ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: sambaPwdLastSet in modlist (set): %s" %
									newSambaPwdLastSet)

			if sambaPwdMustChange != newSambaPwdMustChange:
				# change if password has changed or "change pwd on next login" is not set
				# set sambaPwdMustChange regarding to the univention-policy
				if sambaPwdMustChange:
					modlist.append(('sambaPwdMustChange', sambaPwdMustChange, newSambaPwdMustChange))
					ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: sambaPwdMustChange in modlist (replace): %s" %
							       newSambaPwdMustChange)
				else:
					modlist.append(('sambaPwdMustChange', '', newSambaPwdMustChange))
					ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: sambaPwdMustChange in modlist (set): %s" %
							       newSambaPwdMustChange)

		if len(modlist)>0:	
			ud.debug(ud.LDAP, ud.INFO, "password_sync_s4_to_ucs: modlist: %s" % modlist)
			s4connector.lo.lo.modify(ucs_object['dn'], modlist)


	else:
		ud.debug(ud.LDAP, ud.WARN, "password_sync_ucs_s4_to_ucs: Failed to get Password-Hash from S4")
Esempio n. 13
0
def calculate_krb5key(unicodePwd, supplementalCredentials, kvno=0):
	up_blob = unicodePwd
	sc_blob = supplementalCredentials

	keys = []
	keytypes = []
	context = heimdal.context()

	if up_blob:
		#ud.debug(ud.LDAP, ud.INFO, "calculate_krb5key: up_blob: %s" % binascii.b2a_base64(up_blob))
		assert len(up_blob) == 16
		key = heimdal.keyblock_raw(context, 23, up_blob)
		keys.append(heimdal.asn1_encode_key(key, None, kvno))

	if sc_blob:
		#ud.debug(ud.LDAP, ud.INFO, "calculate_krb5key: sc_blob: %s" % binascii.b2a_base64(sc_blob))
		try:
			sc = ndr_unpack(drsblobs.supplementalCredentialsBlob, sc_blob)
			for p in sc.sub.packages:
				krb = None
				ud.debug(ud.LDAP, ud.INFO, "calculate_krb5key: parsing %s blob" % p.name)
				if p.name == "Primary:Kerberos":
					krb_blob = binascii.unhexlify(p.data)
					krb = ndr_unpack(drsblobs.package_PrimaryKerberosBlob, krb_blob)
					assert krb.version == 3

					for k in krb.ctr.keys:
						if k.keytype not in keytypes:
							ud.debug(ud.LDAP, ud.INFO, "calculate_krb5key: ctr3.key.keytype: %s" % k.keytype)
							try:
								key = heimdal.keyblock_raw(context, k.keytype, k.value)
								krb5SaltObject = heimdal.salt_raw(context, krb.ctr.salt.string)
								keys.append(heimdal.asn1_encode_key(key, krb5SaltObject, kvno))
								keytypes.append(k.keytype)
							except:
								if k.keytype == 4294967156:	## in all known cases W2k8 AD uses keytype 4294967156 (=-140L) for this
									if k.value == up_blob:	## the known case
										ud.debug(ud.LDAP, ud.INFO, "calculate_krb5key: ignoring arc4 NThash with special keytype %s in %s" % (k.keytype, p.name))
									else:					## unknown special case
										ud.debug(ud.LDAP, ud.INFO, "calculate_krb5key: ignoring unknown key with special keytype %s in %s" % (k.keytype, p.name))
								else:
									traceback.print_exc()
									ud.debug(ud.LDAP, ud.ERROR, "calculate_krb5key: krb5Key with keytype %s could not be parsed in %s. Ignoring this keytype." % (k.keytype, p.name))

				elif p.name == "Primary:Kerberos-Newer-Keys":
					krb_blob = binascii.unhexlify(p.data)
					krb = ndr_unpack(drsblobs.package_PrimaryKerberosBlob, krb_blob)
					assert krb.version == 4

					for k in krb.ctr.keys:
						if k.keytype not in keytypes:
							ud.debug(ud.LDAP, ud.INFO, "calculate_krb5key: ctr4.key.keytype: %s" % k.keytype)
							try:
								key = heimdal.keyblock_raw(context, k.keytype, k.value)
								krb5SaltObject = heimdal.salt_raw(context, krb.ctr.salt.string)
								keys.append(heimdal.asn1_encode_key(key, krb5SaltObject, kvno))
								keytypes.append(k.keytype)
							except:
								if k.keytype == 4294967156:	## in all known cases W2k8 AD uses keytype 4294967156 (=-140L) for this
									if k.value == up_blob:	## the known case
										ud.debug(ud.LDAP, ud.INFO, "calculate_krb5key: ignoring arc4 NThash with special keytype %s in %s" % (k.keytype, p.name))
									else:					## unknown special case
										ud.debug(ud.LDAP, ud.INFO, "calculate_krb5key: ignoring unknown key with special keytype %s in %s" % (k.keytype, p.name))
								else:
									traceback.print_exc()
									ud.debug(ud.LDAP, ud.ERROR, "calculate_krb5key: krb5Key with keytype %s could not be parsed in %s. Ignoring this keytype." % (k.keytype, p.name))

		except Exception:
			import sys
			exc = sys.exc_info()[1]
			if type(exc.args) == type(()) and len(exc.args) == 2 and exc.args[1] == 'Buffer Size Error':
				ud.debug(ud.LDAP, ud.WARN, "calculate_krb5key: '%s' while unpacking supplementalCredentials:: %s" % ( exc, binascii.b2a_base64(sc_blob) ) )
				ud.debug(ud.LDAP, ud.WARN, "calculate_krb5key: the krb5Keys from the PrimaryKerberosBlob could not be parsed. Continuing anyway.")
			else:
				traceback.print_exc()
				ud.debug(ud.LDAP, ud.ERROR, "calculate_krb5key: the krb5Keys from the PrimaryKerberosBlob could not be parsed. Continuing anyway.")

	return keys
Esempio n. 14
0
def password_sync_ucs_to_s4(s4connector, key, object):
	_d=ud.function('ldap.s4.password_sync_ucs_to_s4')
	ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4 called")
	
	compatible_modstring = univention.s4connector.s4.compatible_modstring
	try:
		ud.debug(ud.LDAP, ud.INFO, "Object DN=%s" % object['dn'])
	except: # FIXME: which exception is to be caught?
		ud.debug(ud.LDAP, ud.INFO, "Object DN not printable")
		
	ucs_object = s4connector._object_mapping(key, object, 'con')

	try:
		ud.debug(ud.LDAP, ud.INFO, "   UCS DN = %s" % ucs_object['dn'])
	except: # FIXME: which exception is to be caught?
		ud.debug(ud.LDAP, ud.INFO, "   UCS DN not printable")

	try:
		res = s4connector.lo.lo.search(base=ucs_object['dn'], scope='base', attr=['sambaLMPassword', 'sambaNTPassword','sambaPwdLastSet','sambaPwdMustChange', 'krb5PrincipalName', 'krb5Key', 'shadowLastChange', 'shadowMax', 'krb5PasswordEnd', 'univentionService'])
	except ldap.NO_SUCH_OBJECT:
		ud.debug(ud.LDAP, ud.PROCESS, "password_sync_ucs_to_s4: The UCS object (%s) was not found. The object was removed." % ucs_object['dn'])
		return
	
	services=res[0][1].get('univentionService', [])
	if 'Samba 4' in services:
		ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: %s is a S4 server, skip password sync" % ucs_object['dn'])
		return
			
	sambaPwdLastSet = None
	if res[0][1].has_key('sambaPwdLastSet'):
		sambaPwdLastSet = long(res[0][1]['sambaPwdLastSet'][0])
	ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: sambaPwdLastSet: %s" % sambaPwdLastSet)
	
	sambaPwdMustChange = -1
	if res[0][1].has_key('sambaPwdMustChange'):
		sambaPwdMustChange = long(res[0][1]['sambaPwdMustChange'][0])
	ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: sambaPwdMustChange: %s" % sambaPwdMustChange)

	ucsLMhash = res[0][1].get('sambaLMPassword', [None])[0]
	ucsNThash = res[0][1].get('sambaNTPassword', [None])[0]
	krb5Principal = res[0][1].get('krb5PrincipalName', [None])[0]
	krb5Key = res[0][1].get('krb5Key', [])

	if not ucsNThash:
		ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: sambaNTPassword missing in UCS LDAP, trying krb5Key")
		ucsNThash = extract_NThash_from_krb5key(krb5Key)

	if not ucsNThash:
		ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: Failed to get NT Password-Hash from UCS LDAP")

	# ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: Password-Hash from UCS: %s" % ucsNThash)

	res=s4connector.lo_s4.lo.search_s(univention.s4connector.s4.compatible_modstring(object['dn']), ldap.SCOPE_BASE, '(objectClass=*)',['pwdLastSet','objectSid'])
	pwdLastSet = None
	if res[0][1].has_key('pwdLastSet'):
		pwdLastSet = long(res[0][1]['pwdLastSet'][0])
	objectSid = univention.s4connector.s4.decode_sid(res[0][1]['objectSid'][0])
	ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: pwdLastSet from S4 : %s" % pwdLastSet)
	# rid = None
	# if res[0][1].has_key('objectSid'):
	# 	rid = str(univention.s4connector.s4.decode_sid(res[0][1]['objectSid'][0]).split('-')[-1])

	pwd_set = False
	res=s4connector.lo_s4.lo.search_s(s4connector.lo_s4.base, ldap.SCOPE_SUBTREE, compatible_modstring('(objectSid=%s)' % objectSid), ['unicodePwd', 'userPrincipalName', 'supplementalCredentials', 'msDS-KeyVersionNumber', 'dBCSPwd'])
	unicodePwd_attr = res[0][1].get('unicodePwd', [None])[0]
	dBCSPwd_attr = res[0][1].get('dBCSPwd', [None])[0]
	userPrincipalName_attr = res[0][1].get('userPrincipalName', [None])[0]
	supplementalCredentials = res[0][1].get('supplementalCredentials', [None])[0]
	msDS_KeyVersionNumber = res[0][1].get('msDS-KeyVersionNumber', [0])[0]
	# ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: Password-Hash from S4: %s" % unicodePwd_attr)

	s4NThash = None
	if unicodePwd_attr:
		s4NThash = binascii.b2a_hex(unicodePwd_attr).upper()
	else:
		ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: Failed to get NT Password-Hash from S4")

	s4LMhash = None
	if dBCSPwd_attr:
		s4LMhash = binascii.b2a_hex(dBCSPwd_attr).upper()
	else:
		ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: Failed to get LM Password-Hash from S4")

	modlist=[]
	if krb5Principal != userPrincipalName_attr:
		if krb5Principal:
			if not userPrincipalName_attr:	## new and not old
				modlist.append((ldap.MOD_ADD, 'userPrincipalName', krb5Principal))
			else:				## new and old differ
				if krb5Principal.lower() != userPrincipalName_attr.lower():
					ud.debug(ud.LDAP, ud.WARN, "password_sync_ucs_to_s4: userPrincipalName != krb5Principal: '%s' != '%s'" % (userPrincipalName_attr, krb5Principal))
				modlist.append((ldap.MOD_REPLACE, 'userPrincipalName', krb5Principal))
		else:
			if userPrincipalName_attr:	## old and not new
				modlist.append((ldap.MOD_DELETE, 'userPrincipalName', userPrincipalName_attr))

	if not ucsNThash == s4NThash:
		ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: NT Hash S4: %s NT Hash UCS: %s" % (s4NThash, ucsNThash))
		## Now if ucsNThash is empty there should at least some timestamp in UCS,
		## otherwise it's probably not a good idea to remove the unicodePwd.
		## Usecase: LDB module on ucs_3.0-0-ucsschool slaves creates XP computers/windows in UDM without password
		if ucsNThash or sambaPwdLastSet:
			pwd_set = True
			if unicodePwd_attr:
				modlist.append((ldap.MOD_DELETE, 'unicodePwd', unicodePwd_attr))
			if ucsNThash:
				unicodePwd_new = binascii.a2b_hex(ucsNThash)
				modlist.append((ldap.MOD_ADD, 'unicodePwd', unicodePwd_new))

	if not ucsLMhash == s4LMhash:
		ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: LM Hash S4: %s LM Hash UCS: %s" % (s4LMhash, ucsLMhash))
		pwd_set = True
		if dBCSPwd_attr:
			modlist.append((ldap.MOD_DELETE, 'dBCSPwd', dBCSPwd_attr))
		if ucsLMhash:
			dBCSPwd_new = binascii.a2b_hex(ucsLMhash)
			modlist.append((ldap.MOD_ADD, 'dBCSPwd', dBCSPwd_new))

	if pwd_set or not supplementalCredentials:
		if krb5Principal:
			## encoding of Samba4 supplementalCredentials
			if supplementalCredentials:
				modlist.append((ldap.MOD_DELETE, 'supplementalCredentials', supplementalCredentials))
			if krb5Key:
				supplementalCredentials_new = calculate_supplementalCredentials(krb5Key, supplementalCredentials)
				if supplementalCredentials_new:
					modlist.append((ldap.MOD_ADD, 'supplementalCredentials', supplementalCredentials_new))
				else:
					ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: no supplementalCredentials_new")
				#if supplementalCredentials:
				#	modlist.append((ldap.MOD_REPLACE, 'msDS-KeyVersionNumber', krb5KeyVersionNumber))
				#else:
				#	modlist.append((ldap.MOD_ADD, 'msDS-KeyVersionNumber', krb5KeyVersionNumber))

		if sambaPwdMustChange >= 0 and sambaPwdMustChange < time.time():
			# password expired, must be changed on next login
			ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: samba pwd expired, set newpwdLastSet to 0")
			newpwdlastset = "0"
		else:
			if sambaPwdLastSet == None:
				sambaPwdLastSet = int(time.time())
				newpwdlastset = str(univention.s4connector.s4.samba2s4_time(sambaPwdLastSet))
			elif sambaPwdLastSet in [0, 1]:
				newpwdlastset = "0"
			else:
				newpwdlastset = str(univention.s4connector.s4.samba2s4_time(sambaPwdLastSet))
		ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: pwdlastset in modlist: %s" % newpwdlastset)
		modlist.append((ldap.MOD_REPLACE, 'pwdlastset', newpwdlastset))

	else:
		ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: No password change to sync to S4 ")

		# check pwdLastSet
		if sambaPwdLastSet != None:
			newpwdlastset = str(univention.s4connector.s4.samba2s4_time(sambaPwdLastSet))
			ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: sambaPwdLastSet: %d" % sambaPwdLastSet)
			ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: newpwdlastset  : %s" % newpwdlastset)
			ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: pwdLastSet (AD): %s" % pwdLastSet)
			if sambaPwdLastSet in [0, 1]:
				modlist.append((ldap.MOD_REPLACE, 'pwdlastset', "0"))
			elif pwdLastSet != newpwdlastset:
				modlist.append((ldap.MOD_REPLACE, 'pwdlastset', newpwdlastset))

	## TODO: Password History
	ctrl_bypass_password_hash = LDAPControl('1.3.6.1.4.1.7165.4.3.12',criticality=0)
	ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs_to_s4: modlist: %s" % modlist)
	if modlist:
		s4connector.lo_s4.lo.modify_ext_s(compatible_modstring(object['dn']), modlist, serverctrls=[ ctrl_bypass_password_hash ])
Esempio n. 15
0
def calculate_supplementalCredentials(ucs_krb5key, old_supplementalCredentials):

	old_krb = {}
	if old_supplementalCredentials:
		sc = ndr_unpack(drsblobs.supplementalCredentialsBlob, old_supplementalCredentials)

		for p in sc.sub.packages:
			ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: parsing %s blob" % p.name)
			if p.name == "Primary:Kerberos":
				krb_blob = binascii.unhexlify(p.data)
				try:
					krb = ndr_unpack(drsblobs.package_PrimaryKerberosBlob, krb_blob)
					assert krb.version == 3
					old_krb['ctr3'] = krb.ctr
					for k in krb.ctr.keys:	
						ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: ctr3.key.keytype: %s" % k.keytype)
				except:
					ud.debug(ud.LDAP, ud.ERROR, "calculate_supplementalCredentials: ndr_unpack of S4 Primary:Kerberos blob failed. Traceback:")
					traceback.print_exc()
					ud.debug(ud.LDAP, ud.ERROR, "calculate_supplementalCredentials: Continuing anyway, Primary:Kerberos (DES keys) blob will be missing in supplementalCredentials ctr3.old_keys.")
			elif p.name == "Primary:Kerberos-Newer-Keys":
				krb_blob = binascii.unhexlify(p.data)
				try:
					krb = ndr_unpack(drsblobs.package_PrimaryKerberosBlob, krb_blob)
					assert krb.version == 4
					old_krb['ctr4'] = krb.ctr
					for k in krb.ctr.keys:	
						ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: ctr4.key.keytype: %s" % k.keytype)
				except:
					ud.debug(ud.LDAP, ud.ERROR, "calculate_supplementalCredentials: ndr_unpack of S4 Primary:Kerberos-Newer-Keys blob failed. Traceback:")
					traceback.print_exc()
					ud.debug(ud.LDAP, ud.ERROR, "calculate_supplementalCredentials: Continuing anyway, Primary:Kerberos-Newer-Keys (AES and DES keys) blob will be missing in supplementalCredentials ctr4.old_keys.")

	krb5_aes256 = ''
	krb5_aes128 = ''
	krb5_des_md5 = ''
	krb5_des_crc = ''
	krb_ctr3_salt = ''
	krb_ctr4_salt = ''
	for k in ucs_krb5key:
		(keyblock, salt, kvno) = heimdal.asn1_decode_key(k)

		key_data = keyblock.keyvalue()
		saltstring = salt.saltvalue()
		enctype = keyblock.keytype()
		enctype_id = enctype.toint()
		ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: krb5_keytype: %s (%d)" % (enctype, enctype_id))
		if enctype_id == 18:
			krb5_aes256 = key_data
			if not krb_ctr4_salt:
				krb_ctr4_salt = saltstring
		elif enctype_id == 17:
			krb5_aes128 = key_data
			if not krb_ctr4_salt:
				krb_ctr4_salt = saltstring
		elif enctype_id == 3:
			krb5_des_md5 = key_data
			if not krb_ctr3_salt:
				krb_ctr3_salt = saltstring
		elif enctype_id == 1:
			krb5_des_crc = key_data
			if not krb_ctr3_salt:
				krb_ctr3_salt = saltstring

	## build new drsblobs.supplementalCredentialsBlob

	sc_blob = None
	cred_List = []
	package_names = []
	
	## Primary:Kerberos-Newer-Keys : AES keys
	if krb5_aes256 or krb5_aes128:
		ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: building Primary:Kerberos-Newer-Keys blob")
		kerberosKey4list = []
		
		if krb5_aes256:
			assert len(krb5_aes256) == 32
			next_key = drsblobs.package_PrimaryKerberosKey4()
			next_key.keytype = 18
			next_key.value = krb5_aes256
			next_key.value_len = len(krb5_aes256)
			kerberosKey4list.append(next_key)
		if krb5_aes128:
			assert len(krb5_aes128) == 16
			next_key = drsblobs.package_PrimaryKerberosKey4()
			next_key.keytype = 17
			next_key.value = krb5_aes128
			next_key.value_len = len(krb5_aes128)
			kerberosKey4list.append(next_key)
		if krb5_des_md5:
			assert len(krb5_des_md5) == 8
			next_key = drsblobs.package_PrimaryKerberosKey4()
			next_key.keytype = 3
			next_key.value = krb5_des_md5
			next_key.value_len = len(krb5_des_md5)
			kerberosKey4list.append(next_key)
		if krb5_des_crc:
			assert len(krb5_des_crc) == 8
			next_key = drsblobs.package_PrimaryKerberosKey4()
			next_key.keytype = 1
			next_key.value = krb5_des_crc
			next_key.value_len = len(krb5_des_crc)
			kerberosKey4list.append(next_key)

		salt4 = drsblobs.package_PrimaryKerberosString()
		salt4.string = krb_ctr4_salt

		ctr4 = drsblobs.package_PrimaryKerberosCtr4()
		ctr4.salt = salt4
		ctr4.num_keys = len(kerberosKey4list)
		ctr4.keys = kerberosKey4list

		if old_krb.get('ctr4'):
			## Backup old_keys to s4_old_keys
			s4_num_old_keys = old_krb['ctr4'].num_old_keys
			s4_old_keys = []
			for key in old_krb['ctr4'].old_keys:
				s4_old_keys.append(key)

			## keys -> old_keys
			if len(old_krb['ctr4'].keys) != ctr4.num_keys:
				cleaned_old_keys = []
				for key in old_krb['ctr4'].keys:
					if key.keytype == 4294967156:	## in all known cases W2k8 AD uses keytype 4294967156 (=-140L) to include the arc4 hash
						ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: Primary:Kerberos-Newer-Keys filtering keytype %s from old_keys" % key.keytype)
						continue
					else:	# TODO: can we do something better at this point to make old_keys == num_keys ?
						cleaned_old_keys.append(key)
					
				ctr4.old_keys = cleaned_old_keys
				ctr4.num_old_keys = len(cleaned_old_keys)
			else:
				ctr4.old_keys = old_krb['ctr4'].keys
				ctr4.num_old_keys = old_krb['ctr4'].num_keys

			## s4_old_keys -> older_keys
			if ctr4.num_old_keys != ctr4.num_older_keys:
				cleaned_older_keys = []
				for key in s4_old_keys:
					if key.keytype == 4294967156:	## in all known cases W2k8 AD uses keytype 4294967156 (=-140L) to include the arc4 hash
						ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: Primary:Kerberos-Newer-Keys filtering keytype %s from older_keys" % key.keytype)
						continue
					else:	# TODO: can we do something better at this point to make old_keys == num_keys ?
						cleaned_older_keys.append(key)
					
				ctr4.older_keys = cleaned_older_keys
				ctr4.num_older_keys = len(cleaned_older_keys)
			else:
				ctr4.older_keys = s4_old_keys
				ctr4.num_older_keys = s4_num_old_keys

		if ctr4.num_old_keys != 0 and ctr4.num_old_keys != ctr4.num_keys:
			# TODO: Recommended policy is to fill up old_keys to match num_keys, this will result in a traceback, can we do something better?
			ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: Primary:Kerberos-Newer-Keys num_keys = %s" % ctr4.num_keys)
			for k in ctr4.keys:
				ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: ctr4.key.keytype: %s" % k.keytype)
			ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: Primary:Kerberos-Newer-Keys num_old_keys = %s" % ctr4.num_old_keys)
			for k in ctr4.old_keys:
				ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: ctr4.old_key.keytype: %s" % k.keytype)

		if ctr4.num_older_keys != 0 and ctr4.num_older_keys != ctr4.num_old_keys:
			# TODO: Recommended policy is to fill up old_keys to match num_keys, this will result in a traceback, can we do something better?
			ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: Primary:Kerberos-Newer-Keys num_old_keys = %s" % ctr4.num_old_keys)
			for k in ctr4.old_keys:
				ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: ctr4.old_key.keytype: %s" % k.keytype)
			ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: Primary:Kerberos-Newer-Keys num_older_keys = %s" % ctr4.num_older_keys)
			for k in ctr4.older_keys:
				ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: ctr4.older_key.keytype: %s" % k.keytype)

		krb_Primary_Kerberos_Newer = drsblobs.package_PrimaryKerberosBlob()
		krb_Primary_Kerberos_Newer.version = 4
		krb_Primary_Kerberos_Newer.ctr = ctr4 

		krb_blob_Primary_Kerberos_Newer = ndr_pack(krb_Primary_Kerberos_Newer)
		creddata_Primary_Kerberos_Newer = binascii.hexlify(krb_blob_Primary_Kerberos_Newer)
		credname_Primary_Kerberos_Newer = "Primary:Kerberos-Newer-Keys"

		cred_Primary_Kerberos_Newer = drsblobs.supplementalCredentialsPackage()
		cred_Primary_Kerberos_Newer.name = credname_Primary_Kerberos_Newer
		cred_Primary_Kerberos_Newer.name_len = len(credname_Primary_Kerberos_Newer)
		cred_Primary_Kerberos_Newer.data = creddata_Primary_Kerberos_Newer
		cred_Primary_Kerberos_Newer.data_len = len(creddata_Primary_Kerberos_Newer)
		cred_Primary_Kerberos_Newer.reserved = 1
		cred_List.append(cred_Primary_Kerberos_Newer)
		package_names.append('Kerberos-Newer-Keys')

	## Primary:Kerberos : MD5 and CRC keys
	if krb5_des_md5 or krb5_des_crc:
		ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: building Primary:Kerberos blob")
		kerberosKey3list = []
		
		if krb5_des_md5:
			next_key = drsblobs.package_PrimaryKerberosKey3()
			next_key.keytype = 3
			next_key.value = krb5_des_md5
			next_key.value_len = len(krb5_des_md5)
			kerberosKey3list.append(next_key)
		if krb5_des_crc:
			next_key = drsblobs.package_PrimaryKerberosKey3()
			next_key.keytype = 1
			next_key.value = krb5_des_crc
			next_key.value_len = len(krb5_des_crc)
			kerberosKey3list.append(next_key)

		salt = drsblobs.package_PrimaryKerberosString()
		salt.string = krb_ctr3_salt

		ctr3 = drsblobs.package_PrimaryKerberosCtr3()
		ctr3.salt = salt
		ctr3.num_keys = len(kerberosKey3list)
		ctr3.keys = kerberosKey3list

		if old_krb.get('ctr3'):
			## keys -> old_keys
			if len(old_krb['ctr3'].keys) != ctr3.num_keys:
				cleaned_ctr3_old_keys = []
				for key in old_krb['ctr3'].keys:
					if key.keytype == 4294967156:	## in all known cases W2k8 AD uses keytype 4294967156 (=-140L) to include the arc4 hash
						ud.debug(ud.LDAP, ud.INFO, "calculate_supplementalCredentials: Primary:Kerberos filtering keytype %s from old_keys" % key.keytype)
						continue
					else:	# TODO: can we do something better at this point to make old_keys == num_keys ?
						cleaned_ctr3_old_keys.append(key)
					
				ctr3.old_keys = cleaned_ctr3_old_keys
				ctr3.num_old_keys = len(cleaned_ctr3_old_keys)
			else:
				ctr3.old_keys = old_krb['ctr3'].keys
				ctr3.num_old_keys = old_krb['ctr3'].num_keys

		if ctr3.num_old_keys != 0 and ctr3.num_old_keys != ctr3.num_keys:
			# TODO: Recommended policy is to fill up old_keys to match num_keys, this will result in a traceback, can we do something better?
			ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: Primary:Kerberos num_keys = %s" % ctr3.num_keys)
			for k in ctr4.keys:
				ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: ctr3.key.keytype: %s" % k.keytype)
			ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: Primary:Kerberos num_old_keys = %s" % ctr3.num_old_keys)
			for k in ctr4.old_keys:
				ud.debug(ud.LDAP, ud.WARN, "calculate_supplementalCredentials: ctr3.old_key.keytype: %s" % k.keytype)

		krb = drsblobs.package_PrimaryKerberosBlob()
		krb.version = 3
		krb.ctr = ctr3 
		krb3_blob = ndr_pack(krb)

		creddata_Primary_Kerberos = binascii.hexlify(krb3_blob)
		credname_Primary_Kerberos = "Primary:Kerberos"

		cred_Primary_Kerberos = drsblobs.supplementalCredentialsPackage()
		cred_Primary_Kerberos.name = credname_Primary_Kerberos
		cred_Primary_Kerberos.name_len = len(credname_Primary_Kerberos)
		cred_Primary_Kerberos.data = creddata_Primary_Kerberos
		cred_Primary_Kerberos.data_len = len(creddata_Primary_Kerberos)
		cred_Primary_Kerberos.reserved = 1
		cred_List.append(cred_Primary_Kerberos)
		package_names.append('Kerberos')

	if package_names:
		package_names_carray = (ctypes.c_char_p * len(package_names))(*package_names)
		package_names_PyCObject = _PyCObject_FromVoidPtr(ctypes.cast(package_names_carray, ctypes.POINTER(ctypes.c_char_p)), None) 
		krb_Packages = drsblobs.package_PackagesBlob() 
		krb_Packages.names = package_names_PyCObject
		krb_blob_Packages = ndr_pack(krb_Packages)
		# krb_blob_Packages = '\0'.join(package_names).encode('utf-16le')       # this pretty much simulates it
		cred_PackagesBlob_data = binascii.hexlify(krb_blob_Packages).upper()
		cred_PackagesBlob_name = "Packages"
		cred_PackagesBlob = drsblobs.supplementalCredentialsPackage()
		cred_PackagesBlob.name = cred_PackagesBlob_name
		cred_PackagesBlob.name_len = len(cred_PackagesBlob_name)
		cred_PackagesBlob.data = cred_PackagesBlob_data
		cred_PackagesBlob.data_len = len(cred_PackagesBlob_data)
		cred_PackagesBlob.reserved = 2
		cred_List.insert(-1, cred_PackagesBlob)

		sub = drsblobs.supplementalCredentialsSubBlob()
		sub.num_packages = len(cred_List)
		sub.packages = cred_List
		sub.signature = drsblobs.SUPPLEMENTAL_CREDENTIALS_SIGNATURE
		sub.prefix = drsblobs.SUPPLEMENTAL_CREDENTIALS_PREFIX

		sc = drsblobs.supplementalCredentialsBlob()
		sc.sub = sub
		sc_blob = ndr_pack(sc)

	return sc_blob
Esempio n. 16
0
def sid_to_ucs_mapping(s4connector, key, s4_object):
	ud.debug(ud.LDAP, ud.INFO, "sid_to_ucs_mapping")
	object_sid=s4_object['attributes']['objectSid'][0]
	return object_sid.split('-')[-1]
Esempio n. 17
0
def sid_to_ucs(s4connector, key, s4_object):
	ud.debug(ud.LDAP, ud.INFO, "sid_to_ucs S4 object: %s" % s4_object)
	ud.debug(ud.LDAP, ud.INFO, "sid_to_ucs S4 key: %s" % key)

	sidAttribute='sambaSID'
	if s4connector.configRegistry.is_false('connector/s4/mapping/sid', False):
		ud.debug(ud.LDAP, ud.INFO, 'sid_to_ucs: SID mapping is disabled via UCR: connector/s4/mapping/sid')
		sidAttribute='univentionSamba4SID'
	else:
		# This case will be handled by direct mapping
		return

	# modlist
	ml = []

	# object dn is already mapped to the UCS DN:
	if not s4_object.get('dn'):
		return # ignore
	ucs_dn = s4_object['dn']
	ud.debug(ud.LDAP, ud.INFO, "sid_to_s4: UCS DN %s" % ucs_dn)
	
	if s4_object.has_key('attributes') and s4_object['attributes'].has_key('objectSid'):
		ud.debug(ud.LDAP, ud.INFO, 'sid_to_ucs: objectSid found: %s' % s4_object['attributes']['objectSid'])
	else:
		ud.debug(ud.LDAP, ud.INFO, 'sid_to_ucs: objectSid not found in attributes!')
		return

	(ucs_dn, ucs_attributes) = s4connector.lo.lo.search(base=ucs_dn, scope='base', attr=[sidAttribute, 'objectClass'])[0]

	if not ucs_dn:
		ud.debug(ud.LDAP, ud.WARN, 'sid_to_ucs: UCS object (%s) not found' % ucs_dn)
		return

	objectSid = s4_object['attributes'].get('objectSid')
	sambaSID = ucs_attributes.get(sidAttribute)
	if not sambaSID or objectSid != sambaSID:
		ml.append((sidAttribute, sambaSID, s4_object['attributes'].get('objectSid')))
		if 'user' in s4_object['attributes'].get('objectClass', []):
			if not 'sambaSamAccount' in ucs_attributes.get('objectClass'):
				ml.append(('objectClass',ucs_attributes.get('objectClass'), ucs_attributes.get('objectClass')+['sambaSamAccount']))
		if 'group' in s4_object['attributes'].get('objectClass', []):
			if not 'sambaGroupMapping' in ucs_attributes.get('objectClass'):
				ml.append(('objectClass',ucs_attributes.get('objectClass'), ucs_attributes.get('objectClass')+['sambaGroupMapping']))
	if ml:
		ud.debug(ud.LDAP, ud.INFO, 'sid_to_ucs: modlist = %s' % ml)
		s4connector.lo.lo.modify(ucs_dn, ml)

	return
Esempio n. 18
0
def password_sync_ucs(connector, key, object):
	_d=ud.function('ldap.ad.password_sync_ucs')
	# externes Programm zum Überptragen des Hash aufrufen
	# per ldapmodify pwdlastset auf -1 setzen
	
	compatible_modstring = univention.connector.ad.compatible_modstring
	try:
		ud.debug(ud.LDAP, ud.INFO, "Object DN=%s" % object['dn'])
	except: # FIXME: which exception is to be caught?
		ud.debug(ud.LDAP, ud.INFO, "Object DN not printable")
		
	ucs_object = connector._object_mapping(key, object, 'con')

	try:
		ud.debug(ud.LDAP, ud.INFO, "   UCS DN = %s" % ucs_object['dn'])
	except: # FIXME: which exception is to be caught?
		ud.debug(ud.LDAP, ud.INFO, "   UCS DN not printable")

	try:
		res = connector.lo.lo.search(base=ucs_object['dn'], scope='base', attr=['sambaLMPassword', 'sambaNTPassword','sambaPwdLastSet'])
	except ldap.NO_SUCH_OBJECT:
		ud.debug(ud.LDAP, ud.PROCESS, "password_sync_ucs: The UCS object (%s) was not found. The object was removed." % ucs_object['dn'])
		return
	
	sambaPwdLastSet = None
	if res[0][1].has_key('sambaPwdLastSet'):
		sambaPwdLastSet = long(res[0][1]['sambaPwdLastSet'][0])
	ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs: sambaPwdLastSet: %s" % sambaPwdLastSet)
	
	pwd = None
	if res[0][1].has_key('sambaNTPassword'):
		pwd=res[0][1]['sambaNTPassword'][0]
	else:
		pwd='NO PASSWORDXXXXXX'
		ud.debug(ud.LDAP, ud.WARN, "password_sync_ucs: Failed to get NT Hash from UCS")

	if res[0][1].has_key('sambaLMPassword'):
		pwd+=res[0][1]['sambaLMPassword'][0]
	else:
		pwd+='NO PASSWORDXXXXX'
		ud.debug(ud.LDAP, ud.WARN, "password_sync_ucs: Failed to get LM Hash from UCS")

	res=connector.lo_ad.lo.search_s(univention.connector.ad.compatible_modstring(object['dn']), ldap.SCOPE_BASE, '(objectClass=*)',['pwdLastSet','objectSid'])
	pwdLastSet = None
	if res[0][1].has_key('pwdLastSet'):
		pwdLastSet = long(res[0][1]['pwdLastSet'][0])
	ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs: pwdLastSet from AD : %s" % pwdLastSet)
	rid = None
	if res[0][1].has_key('objectSid'):
		rid = str(univention.connector.ad.decode_sid(res[0][1]['objectSid'][0]).split('-')[-1])

	# Only sync passwords from UCS to AD when the password timestamp in UCS is newer
	if connector.baseConfig.is_true('%s/ad/password/timestamp/check' % connector.CONFIGBASENAME, False):
		ad_password_last_set = 0
		# If sambaPwdLast was set to 1 the password must be changed on next login. In this
		# case the timestamp is ignored and the password will be synced. This behaviour can
		# be disbled by setting connector/ad/password/timestamp/syncreset/ucs to false. This
		# might be necessary if the connector is configured in read mode and the password will be
		# synced in two ways: Bug #22653
		if sambaPwdLastSet > 1 or ( sambaPwdLastSet <= 2 and connector.baseConfig.is_false('%s/ad/password/timestamp/syncreset/ucs' % connector.CONFIGBASENAME, False)):
			ad_password_last_set = univention.connector.ad.ad2samba_time(pwdLastSet)
			if sambaPwdLastSet:
				if long(ad_password_last_set) >= long(sambaPwdLastSet):
					# skip
					ud.debug(ud.LDAP, ud.PROCESS, "password_sync: Don't sync the password from UCS to AD because the AD password equal or is newer.")
					ud.debug(ud.LDAP, ud.INFO, "password_sync:  AD pwdlastset: %s (original (%s))" % (ad_password_last_set, pwdLastSet))
					ud.debug(ud.LDAP, ud.INFO, "password_sync: UCS pwdlastset: %s" % (sambaPwdLastSet))
					return

		ud.debug(ud.LDAP, ud.INFO, "password_sync: Sync the passwords from UCS to AD.")
		ud.debug(ud.LDAP, ud.INFO, "password_sync:  AD pwdlastset: %s (original (%s))" % (ad_password_last_set, pwdLastSet))
		ud.debug(ud.LDAP, ud.INFO, "password_sync: UCS pwdlastset: %s" % (sambaPwdLastSet))
	
	pwd_set = False
	pwd_ad_res = get_password_from_ad(connector, rid)
	pwd_ad = ''
	if len(pwd_ad_res) >3 and _get_integer(pwd_ad_res[4:]) == 0:
		pwd_ad = pwd_ad_res[12:].split(':')[1].strip().upper()
	else:
		ud.debug(ud.LDAP, ud.WARN, "password_sync_ucs: Failed to get Password-Hash from AD")
	res = ''

	ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs: Hash AD: %s Hash UCS: %s"%(pwd_ad,pwd))
	if not pwd == pwd_ad:
		pwd_set = True
		res = set_password_in_ad(connector, object['attributes']['sAMAccountName'][0], pwd)

	if not pwd_set or len(res) >3 and _get_integer(res[4:]) == 0 :
		newpwdlastset = "-1" # if pwd was set in ad we need to set pwdlastset to -1 or it will be 0		
		#if sambaPwdMustChange >= 0 and sambaPwdMustChange < time.time():
		#	# password expired, must be changed on next login
		#	ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs: samba pwd expired, set newpwdLastSet to 0")
		#	newpwdlastset = "0"
		if sambaPwdLastSet <= 1:
			newpwdlastset = "0" # User must change his password
		elif pwdLastSet and int(pwdLastSet) > 0 and not pwd_set:
			newpwdlastset = "1"
		if long(newpwdlastset) != 1:
			ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs: pwdlastset in modlist: %s" % newpwdlastset)
			connector.lo_ad.lo.modify_s(compatible_modstring(object['dn']), [(ldap.MOD_REPLACE, 'pwdlastset', newpwdlastset)])
		else:
			ud.debug(ud.LDAP, ud.INFO, "password_sync_ucs: don't modify pwdlastset")
	else:
		ud.debug(ud.LDAP, ud.ERROR, "password_sync_ucs: Failed to sync Password from AD ")
Esempio n. 19
0
def password_sync(connector, key, ucs_object):
	_d=ud.function('ldap.ad.password_sync')
	# externes Programm zum holen des Hash aufrufen
	# "kerberos_now"

	object=connector._object_mapping(key, ucs_object, 'ucs')
	res=connector.lo_ad.lo.search_s(univention.connector.ad.compatible_modstring(object['dn']), ldap.SCOPE_BASE, '(objectClass=*)',['objectSid','pwdLastSet'])

	pwdLastSet = None
	if res[0][1].has_key('pwdLastSet'):
		pwdLastSet = long(res[0][1]['pwdLastSet'][0])
	ud.debug(ud.LDAP, ud.INFO, "password_sync: pwdLastSet from AD: %s (%s)" % (pwdLastSet,res))

	rid = None
	if res[0][1].has_key('objectSid'):
		rid = str(univention.connector.ad.decode_sid(res[0][1]['objectSid'][0]).split('-')[-1])

	ucs_result=connector.lo.search(base=ucs_object['dn'], attr=['sambaPwdLastSet','sambaNTPassword', 'sambaLMPassword', 'krb5PrincipalName', 'shadowLastChange', 'shadowMax', 'krb5PasswordEnd'])

	sambaPwdLastSet = None
	if ucs_result[0][1].has_key('sambaPwdLastSet'):
		sambaPwdLastSet=ucs_result[0][1]['sambaPwdLastSet'][0]
	ud.debug(ud.LDAP, ud.INFO, "password_sync: sambaPwdLastSet: %s" % sambaPwdLastSet)

	if connector.baseConfig.is_true('%s/ad/password/timestamp/check' % connector.CONFIGBASENAME, False):
		# Only sync the passwords from AD to UCS when the pwdLastSet timestamps in AD are newer
		ad_password_last_set = 0

		# If pwdLastSet was set to 0 the password must be changed on next login. In this
		# case the timestamp is ignored and the password will be synced. This behaviour can
		# be disabled by setting connector/ad/password/timestamp/syncreset/ad to false. This
		# might be necessary if the connector is configured in read mode and the password will be
		# synced in two ways: Bug #22653
		if (pwdLastSet > 1) or (pwdLastSet in [0,1] and connector.baseConfig.is_false('%s/ad/password/timestamp/syncreset/ad' % connector.CONFIGBASENAME, False)):
			ad_password_last_set = univention.connector.ad.ad2samba_time(pwdLastSet)
			if sambaPwdLastSet:
				if long(sambaPwdLastSet) >= long(ad_password_last_set) and long(sambaPwdLastSet) != 1:
					# skip
					ud.debug(ud.LDAP, ud.PROCESS, "password_sync: Don't sync the passwords from AD to UCS because the UCS password is equal or newer.")
					ud.debug(ud.LDAP, ud.INFO, "password_sync:  AD pwdlastset: %s (original (%s))" % (ad_password_last_set, pwdLastSet))
					ud.debug(ud.LDAP, ud.INFO, "password_sync: UCS pwdlastset: %s" % (sambaPwdLastSet))
					return

		ud.debug(ud.LDAP, ud.INFO, "password_sync: Sync the passwords from AD to UCS.")
		ud.debug(ud.LDAP, ud.INFO, "password_sync:  AD pwdlastset: %s (original (%s))" % (ad_password_last_set, pwdLastSet))
		ud.debug(ud.LDAP, ud.INFO, "password_sync: UCS pwdlastset: %s" % (sambaPwdLastSet))

	res = get_password_from_ad(connector, rid)

	if len(res) >3 and _get_integer(res[4:]) == 0:
		ntPwd_ucs = ''
		lmPwd_ucs = ''
		krb5Principal = ''
		userPassword = ''

		data = res[12:].split(':')[1].strip()
		ntPwd = data[:32]
		lmPwd = data[32:]
		modlist=[]

		if ucs_result[0][1].has_key('sambaLMPassword'):
			lmPwd_ucs = ucs_result[0][1]['sambaLMPassword'][0]
		if ucs_result[0][1].has_key('sambaNTPassword'):
			ntPwd_ucs = ucs_result[0][1]['sambaNTPassword'][0]
		if ucs_result[0][1].has_key('krb5PrincipalName'):
			krb5Principal=ucs_result[0][1]['krb5PrincipalName'][0]
		if ucs_result[0][1].has_key('userPassword'):
			userPassword=ucs_result[0][1]['userPassword'][0]

		pwd_changed = False

 		if lmPwd.upper() != lmPwd_ucs.upper():
			if not lmPwd in ['00000000000000000000000000000000', 'NO PASSWORD*********************']:
				pwd_changed = True
				modlist.append(('sambaLMPassword', lmPwd_ucs, str(lmPwd.upper())))
		if ntPwd.upper() != ntPwd_ucs.upper():
			if ntPwd in ['00000000000000000000000000000000', 'NO PASSWORD*********************']:
				ud.debug(ud.LDAP, ud.WARN, "password_sync: AD connector password daemon retured 0 for the nt hash. Please check the AD settings.")
			else:
				ud.debug(ud.LDAP, ud.WARN, "password_sync: %s" % ntPwd)
				pwd_changed = True
				modlist.append(('sambaNTPassword', ntPwd_ucs, str(ntPwd.upper())))
				if krb5Principal:
					connector.lo.lo.lo.modify_s(univention.connector.ad.compatible_modstring(ucs_object['dn']),
									[(ldap.MOD_REPLACE, 'krb5Key', nt_password_to_arcfour_hmac_md5(ntPwd.upper()))])
		if pwd_changed:
			connector.lo.lo.lo.modify_s(univention.connector.ad.compatible_modstring(ucs_object['dn']), [(ldap.MOD_REPLACE, 'userPassword', '{K5KEY}')])
			# Remove the POSIX and Kerberos password expiry interval
			if ucs_result[0][1].has_key('shadowLastChange'):
				modlist.append(('shadowLastChange', ucs_result[0][1]['shadowLastChange'][0], None))
			if ucs_result[0][1].has_key('shadowMax'):
				modlist.append(('shadowMax', ucs_result[0][1]['shadowMax'][0], None))
			if ucs_result[0][1].has_key('krb5PasswordEnd'):
				modlist.append(('krb5PasswordEnd', ucs_result[0][1]['krb5PasswordEnd'][0], None))

			if pwdLastSet or pwdLastSet == 0:
				newSambaPwdLastSet = str(univention.connector.ad.ad2samba_time(pwdLastSet))

				if sambaPwdLastSet:
					if sambaPwdLastSet != newSambaPwdLastSet:
						modlist.append(('sambaPwdLastSet', sambaPwdLastSet, newSambaPwdLastSet))
						ud.debug(ud.LDAP, ud.INFO, "password_sync: sambaPwdLastSet in modlist (replace): %s" %
											newSambaPwdLastSet)
				else:
					modlist.append(('sambaPwdLastSet', '', newSambaPwdLastSet ))
					ud.debug(ud.LDAP, ud.INFO, "password_sync: sambaPwdLastSet in modlist (set): %s" %
										newSambaPwdLastSet)

		if len(modlist)>0:	
			connector.lo.lo.modify(ucs_object['dn'], modlist)


	else:
		ud.debug(ud.LDAP, ud.ERROR, "password_sync: sync failed, no result from AD" )
Esempio n. 20
0
File: dns.py Progetto: B-Rich/smart
def ucs_srv_record_create(s4connector, object):
	_d=ud.function('ucs_srv_record_create')
	ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_create: object: %s' % object)

	zoneName, relativeDomainName=__split_s4_dn(object['dn'])

	# unpack the host record
	srv=__unpack_sRVrecord(object)

	# ucr set connector/s4/mapping/dns/srv_record/_ldap._tcp.test.local/location='100 0 389 foobar.test.local. 100 0 389 foobar2.test.local.'
	ucr_locations = s4connector.configRegistry.get('connector/s4/mapping/dns/srv_record/%s.%s/location' % (relativeDomainName.lower(),zoneName.lower()))
	ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_create: ucr_locations for connector/s4/mapping/dns/srv_record/%s.%s/location: %s' % (relativeDomainName.lower(),zoneName.lower(),ucr_locations))

	if ucr_locations and ucr_locations.lower() == 'ignore':
		return

	# Does a host record for this zone already exist?
	searchResult=s4connector.lo.search(filter='(&(relativeDomainName=%s)(zoneName=%s))' % (relativeDomainName, zoneName), unique=1)
	if len(searchResult) > 0:
		superordinate=s4connector_get_superordinate('dns/srv_record', s4connector.lo, searchResult[0][0])
		newRecord= univention.admin.handlers.dns.srv_record.object(None, s4connector.lo, position=None, dn=searchResult[0][0], superordinate=superordinate, attributes=[], update_zone=False)
		newRecord.open()
		if ucr_locations:
			ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_create: do not write SRV record back from S4 to UCS because location of SRV record have been overwritten by UCR')
		else:
			ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_create: location: %s' % newRecord['location'])
			ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_create: srv     : %s' % srv)
			srv.sort()
			newRecord['location'].sort()
			if srv != newRecord['location']:
				newRecord['location']=srv
				newRecord.modify()
			else:
				ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_create: do not modify host record')
	else:
		zoneDN='zoneName=%s,%s' % (zoneName, s4connector.property['dns'].ucs_default_dn)

		superordinate=s4connector_get_superordinate('dns/srv_record', s4connector.lo, zoneDN)
		ud.debug(ud.LDAP, ud.INFO, 'ucs_srv_record_create: superordinate: %s' % superordinate)

		position=univention.admin.uldap.position(zoneDN)

		newRecord= univention.admin.handlers.dns.srv_record.object(None, s4connector.lo, position, dn=None, superordinate=superordinate, attributes=[], update_zone=False)
		newRecord.open()
		# Make syntax UDM compatible
		service=string.join(relativeDomainName.split('.')[:-1], '.')
		if service.startswith('_'):
			service=service[1:] 
		protocol=relativeDomainName.split('.')[-1]
		if protocol.startswith('_'):
			protocol=protocol[1:] 
		ud.debug(ud.LDAP, ud.INFO, 'SRV create: service="%s" protocol="%s"' % (service, protocol))
		newRecord['name']=[service, protocol]
		newRecord['location']=srv
		newRecord.create()
Esempio n. 21
0
File: dns.py Progetto: B-Rich/smart
def __get_zone_name(object):
	zoneName=object['attributes'].get('zoneName')
	if not zoneName:
		ud.debug(ud.LDAP, ud.WARN, 'Failed to get zone name for object %s' % (object['dn']))
		raise 
	return zoneName
Esempio n. 22
0
File: dc.py Progetto: B-Rich/smart
def ucs2con (s4connector, key, object):
	_d=ud.function('dc: ucs2con')

	ud.debug(ud.LDAP, ud.INFO, 'dc ucs2con: Object (%s): %s' % (object['dn'], object))
	s4base_dn,s4base_attr = s4connector.lo_s4.lo.search_s(s4connector.s4_ldap_base, ldap.SCOPE_BASE, '(objectClass=*)')[0]
	ud.debug(ud.LDAP, ud.INFO, 'dc ucs2con: S4 object: %s' % (s4base_dn))
	ud.debug(ud.LDAP, ud.INFO, 'dc ucs2con: S4 object: %s' % (s4base_attr))

	if 'univentionBase' in object['attributes'].get('objectClass'):
		# DC object → sync GPO
	 	if s4connector.configRegistry.is_true('connector/s4/mapping/gpo', True):
			ucs_val = object['attributes'].get('msGPOLink', [None])[0]	# msGPOLink is a single value
			s4_val = s4base_attr.get('msGPOLink')
			if ucs_val != s4_val:
				s4connector.lo_s4.lo.modify_s(s4connector.s4_ldap_base, [(ldap.MOD_REPLACE, 'gPLink', univention.s4connector.s4.compatible_modstring(ucs_val))])
		
	elif 'sambaDomain' in object['attributes'].get('objectClass'):
		# Samba Domain object

		ml = []

		sync_times = [ ('sambaMaxPwdAge', 'maxPwdAge'), ('sambaMinPwdAge', 'minPwdAge'), ('sambaLockoutDuration', 'lockoutDuration') ]
		for (ucs_attr, s4_attr) in sync_times:
			ucs_time = long(object['attributes'].get(ucs_attr, [0])[0])
			s4_time = _nano2s(long(s4base_attr.get(s4_attr, [0])[0]) * -1)

			ud.debug(ud.LDAP, ud.INFO, 'dc ucs2con: ucs_time (%s): %s' % (ucs_attr, ucs_time))
			ud.debug(ud.LDAP, ud.INFO, 'dc ucs2con: s4-time (%s): %s' % (s4_attr, s4_time))

			if ucs_time != s4_time:
				ml.append( (ldap.MOD_REPLACE, s4_attr, [ str(_s2nano(ucs_time) * -1) ] ) )
		
		sync_integers = [ ('sambaPwdHistoryLength', 'pwdHistoryLength'), ('sambaMinPwdLength', 'minPwdLength') ]
		for (ucs_attr, s4_attr) in sync_integers:
			ucs_val = object['attributes'].get(ucs_attr, str(0))
			s4_val = s4base_attr.get(s4_attr, [0])[0]
			if ucs_val != s4_val:
				ml.append( (ldap.MOD_REPLACE, s4_attr, ucs_val ) )

		if ml:
			ud.debug(ud.LDAP, ud.INFO, 'dc ucs2con: S4 object modlist: %s' % (ml))
			s4connector.lo_s4.lo.modify_s(s4connector.s4_ldap_base, univention.s4connector.s4.compatible_modlist(ml))
		
	return True
Esempio n. 23
0
# 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 univention.debug2 as ud

ud.init( '/tmp/univention.debug2.log', 1, 1)
ud.set_level( ud.PROCESS, ud.ERROR )
ud.set_level( ud.LISTENER, ud.WARN )
ud.set_level( ud.NETWORK, ud.PROCESS )
ud.set_level( ud.LDAP, ud.INFO )
ud.set_level( ud.ADMIN, ud.ALL )

for lvl in [ ud.ERROR, ud.WARN, ud.PROCESS, ud.INFO, ud.ALL ]:
	for mod in [ ud.ADMIN, ud.PROCESS, ud.LISTENER, ud.NETWORK, ud.LDAP ]:
		ud.debug( mod, lvl, '==> send msg to %s with level %s' % (mod, lvl) )


ud.set_level( ud.ADMIN, ud.ERROR )
ud.debug( ud.ADMIN, ud.ERROR, '==> admin error' )
ud.debug( ud.ADMIN, ud.WARN, '==> admin warn' )
ud.debug( ud.ADMIN, ud.PROCESS, '==> admin process' )
ud.debug( ud.ADMIN, ud.INFO, '==> admin info' )
ud.debug( ud.ADMIN, ud.ALL, '==> admin all' )

ud.set_level( ud.LDAP, ud.INFO )
ud.debug( ud.LDAP, ud.ERROR, '==> ldap error' )
ud.debug( ud.LDAP, ud.WARN, '==> ldap warn' )
ud.debug( ud.LDAP, ud.PROCESS, '==> ldap process' )
ud.debug( ud.LDAP, ud.INFO, '==> ldap info' )
ud.debug( ud.LDAP, ud.ALL, '==> ldap all' )