View | Details | Raw Unified | Return to bug 41659 | Differences between
and this patch

Collapse All | Expand All

(-)a/management/univention-directory-manager-modules/debian/python-univention-directory-manager.preinst (-15 / +2 lines)
 Lines 32-52    Link Here 
32
32
33
#DEBHELPER#
33
#DEBHELPER#
34
34
35
if [ "$1" = "upgrade" ] && dpkg --compare-versions "$2" lt 10.0.29-53; then
35
if [ "$1" = "upgrade" ] && dpkg --compare-versions "$2" lt 12.0.17-53; then
36
	ln -s /usr/share/pyshared/univention/admin/policy.py /usr/lib/pymodules/python2.7/univention/admin/policy.py
36
	ln -s /usr/share/pyshared/univention/admin/handlers/computers/base.py /usr/lib/pymodules/python2.7/univention/admin/handlers/computers/base.py
37
fi
38
39
# Bug #38473: workaround only required up to UCS 4.1-0
40
if [ "$1" = "upgrade" ] && dpkg --compare-versions "$2" lt-nl 10.0.30; then
41
	FN="/usr/share/pyshared/univention/admin/handlers/policies/mailquota.py"
42
	FN_BACKUP="${FN}.udm_backup"
43
	if [ -f "$FN" ] ; then
44
		CUR_MD5="$(md5sum "$FN" | cut -d' ' -f1)"
45
		PKG_MD5="$(sed -nre 's,^([a-f0-9]+)\s+usr/share/pyshared/univention/admin/handlers/policies/mailquota.py,\1,p' /var/lib/dpkg/info/python-univention-directory-manager.md5sums)"
46
		if [ -n "$PKG_MD5" -a -n "$CUR_MD5" -a ! "$PKG_MD5" = "$CUR_MD5" ] ; then
47
			cp "$FN" "$FN_BACKUP"
48
		fi
49
	fi
50
fi
37
fi
51
38
52
exit 0
39
exit 0
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/base.py (+351 lines)
Line 0    Link Here 
1
# -*- coding: utf-8 -*-
2
#
3
# Univention Admin Modules
4
#  admin module for generic computer objects
5
#
6
# Copyright 2016 Univention GmbH
7
#
8
# http://www.univention.de/
9
#
10
# All rights reserved.
11
#
12
# The source code of this program is made available
13
# under the terms of the GNU Affero General Public License version 3
14
# (GNU AGPL V3) as published by the Free Software Foundation.
15
#
16
# Binary versions of this program provided by Univention to you as
17
# well as other copyrighted, protected or trademarked materials like
18
# Logos, graphics, fonts, specific documentations and configurations,
19
# cryptographic keys etc. are subject to a license agreement between
20
# you and Univention and not subject to the GNU AGPL V3.
21
#
22
# In the case you use this program under the terms of the GNU AGPL V3,
23
# the program is provided in the hope that it will be useful,
24
# but WITHOUT ANY WARRANTY; without even the implied warranty of
25
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26
# GNU Affero General Public License for more details.
27
#
28
# You should have received a copy of the GNU Affero General Public
29
# License with the Debian GNU/Linux or Univention distribution in file
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
32
33
import time
34
from ldap.filter import filter_format
35
36
import univention.admin.filter
37
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
43
import univention.admin.handlers.groups.group
44
import univention.admin.handlers.dns.forward_zone
45
import univention.admin.handlers.dns.reverse_zone
46
import univention.admin.handlers.networks.network
47
48
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
49
_ = translation.translate
50
51
52
class computerBase(univention.admin.handlers.simpleComputer, nagios.Support):
53
	CONFIG_NAME = None
54
	SERVER_ROLE = None
55
	SERVER_TYPE = None
56
	SAMBA_ACCOUNT_FLAG = None
57
	DEFAULT_OCS = []
58
59
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
60
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
61
		nagios.Support.__init__(self)
62
63
	def open(self):
64
		univention.admin.handlers.simpleComputer.open(self)
65
		self.nagios_open()
66
67
		if self.exists():
68
			if 'posix' in self.options and not self.info.get('primaryGroup'):
69
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
70
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
71
				if primaryGroupNumber:
72
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
73
					if primaryGroupResult:
74
						self['primaryGroup'] = primaryGroupResult[0]
75
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
76
					else:
77
						self['primaryGroup'] = None
78
						self.save()
79
						raise univention.admin.uexceptions.primaryGroup
80
				else:
81
					self['primaryGroup'] = None
82
					self.save()
83
					raise univention.admin.uexceptions.primaryGroup
84
			if 'samba' in self.options:
85
				sid = self.oldattr.get('sambaSID', [''])[0]
86
				pos = sid.rfind('-')
87
				self.info['sambaRID'] = sid[pos + 1:]
88
89
		self.modifypassword = 0
90
		if self.exists():
91
			userPassword = self.oldattr.get('userPassword', [''])[0]
92
			if userPassword:
93
				self.info['password'] = userPassword
94
				self.modifypassword = 0
95
			self.save()
96
		else:
97
			self.modifypassword = 0
98
			if 'posix' in self.options:
99
				res = univention.admin.config.getDefaultValue(self.lo, self.CONFIG_NAME, position=self.position)
100
				if res:
101
					self['primaryGroup'] = res
102
103
	def _ldap_pre_create(self):
104
		super(object, self)._ldap_pre_create()
105
		if not self['password']:
106
			self['password'] = self.oldattr.get('password', [''])[0]
107
			self.modifypassword = 0
108
109
	def _ldap_addlist(self):
110
		self.check_required_options()
111
		ocs = list(self.DEFAULT_OCS)
112
		al = []
113
		if 'kerberos' in self.options:
114
			domain = univention.admin.uldap.domain(self.lo, self.position)
115
			realm = domain.getKerberosRealm()
116
117
			if realm:
118
				al.append(('krb5MaxLife', '86400'))
119
				al.append(('krb5MaxRenew', '604800'))
120
				al.append(('krb5KDCFlags', '126'))
121
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
122
				al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
123
			else:
124
				# can't do kerberos
125
				self._remove_option('kerberos')
126
		if 'posix' in self.options:
127
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
128
			self.alloc.append(('uidNumber', self.uidNum))
129
			gidNum = self.get_gid_for_primary_group()
130
			al.append(('uidNumber', [self.uidNum]))
131
			al.append(('gidNumber', [gidNum]))
132
133
		if self.modifypassword or self['password']:
134
			if 'kerberos' in self.options:
135
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
136
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
137
			if 'posix' in self.options:
138
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
139
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
140
			if 'samba' in self.options:
141
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
142
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
143
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
144
				sambaPwdLastSetValue = str(long(time.time()))
145
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
146
			self.modifypassword = 0
147
		if 'samba' in self.options:
148
			acctFlags = univention.admin.samba.acctFlags(flags={self.SAMBA_ACCOUNT_FLAG: 1})
149
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
150
			self.alloc.append(('sid', self.machineSid))
151
			al.append(('sambaSID', [self.machineSid]))
152
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
153
			al.append(('displayName', self.info['name']))
154
155
		al.insert(0, ('objectClass', ocs))
156
		if self.SERVER_ROLE:
157
			al.append(('univentionServerRole', '', self.SERVER_ROLE))
158
		return al
159
160
	def check_required_options(self):
161
		pass
162
163
	def _ldap_post_create(self):
164
		if 'posix' in self.options:
165
			if hasattr(self, 'uid') and self.uid:
166
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
167
			univention.admin.handlers.simpleComputer.primary_group(self)
168
			univention.admin.handlers.simpleComputer.update_groups(self)
169
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
170
		self.nagios_ldap_post_create()
171
172
	def _ldap_pre_remove(self):
173
		self.open()
174
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
175
			self.uidNum = self.oldattr['uidNumber'][0]
176
177
	def _ldap_post_remove(self):
178
		if 'posix' in self.options:
179
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
180
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember', [self.dn]))
181
		if groupObjects:
182
			for i in range(0, len(groupObjects)):
183
				groupObjects[i].open()
184
				if self.dn in groupObjects[i]['users']:
185
					groupObjects[i]['users'].remove(self.dn)
186
					groupObjects[i].modify(ignore_license=1)
187
188
		self.nagios_ldap_post_remove()
189
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
190
		# Need to clean up oldinfo. If remove was invoked, because the
191
		# creation of the object has failed, the next try will result in
192
		# a 'object class violation' (Bug #19343)
193
		self.oldinfo = {}
194
195
	def krb5_principal(self):
196
		domain = univention.admin.uldap.domain(self.lo, self.position)
197
		realm = domain.getKerberosRealm()
198
		if 'domain' in self.info and self.info['domain']:
199
			kerberos_domain = self.info['domain']
200
		else:
201
			kerberos_domain = domain.getKerberosRealm()
202
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
203
204
	def _ldap_post_modify(self):
205
		univention.admin.handlers.simpleComputer.primary_group(self)
206
		univention.admin.handlers.simpleComputer.update_groups(self)
207
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
208
		self.nagios_ldap_post_modify()
209
210
	def _ldap_pre_modify(self):
211
		if self.hasChanged('password'):
212
			if not self['password']:
213
				self['password'] = self.oldattr.get('password', [''])[0]
214
				self.modifypassword = 0
215
			elif not self.info['password']:
216
				self['password'] = self.oldattr.get('password', [''])[0]
217
				self.modifypassword = 0
218
			else:
219
				self.modifypassword = 1
220
		self.nagios_ldap_pre_modify()
221
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
222
223
	def _ldap_modlist(self):
224
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
225
226
		self.nagios_ldap_modlist(ml)
227
228
		if self.hasChanged('name'):
229
			if 'posix' in self.options:
230
				if hasattr(self, 'uidNum'):
231
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
232
				requested_uid = "%s$" % self['name']
233
				try:
234
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
235
				except Exception:
236
					self.cancel()
237
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
238
239
				self.alloc.append(('uid', self.uid))
240
241
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
242
243
			if 'samba' in self.options:
244
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
245
246
			if 'kerberos' in self.options:
247
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
248
249
		if self.modifypassword and self['password']:
250
			if 'kerberos' in self.options:
251
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
252
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
253
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
254
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
255
			if 'posix' in self.options:
256
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
257
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
258
			if 'samba' in self.options:
259
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
260
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
261
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
262
				sambaPwdLastSetValue = str(long(time.time()))
263
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
264
265
		# add samba option
266
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
267
			acctFlags = univention.admin.samba.acctFlags(flags={self.SAMBA_ACCOUNT_FLAG: 1})
268
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
269
			self.alloc.append(('sid', self.machineSid))
270
			ml.append(('sambaSID', '', [self.machineSid]))
271
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
272
			ml.append(('displayName', '', self.info['name']))
273
			sambaPwdLastSetValue = str(long(time.time()))
274
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
275
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
276
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
277
				if self.oldattr.get(key, []):
278
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
279
280
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
281
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
282
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
283
284
		return ml
285
286
	def cleanup(self):
287
		self.open()
288
		self.nagios_cleanup()
289
		univention.admin.handlers.simpleComputer.cleanup(self)
290
291
	def cancel(self):
292
		for i, j in self.alloc:
293
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
294
			univention.admin.allocators.release(self.lo, self.position, i, j)
295
296
	def link(self):
297
		result = []
298
		if self['ip'] and len(self['ip']) > 0 and self['ip'][0]:
299
			result = [{
300
				'url': 'https://%s/univention-management-console/' % self['ip'][0],
301
				'ipaddr': self['ip'][0],
302
			}]
303
		if 'dnsEntryZoneForward' in self and self['dnsEntryZoneForward'] and len(self['dnsEntryZoneForward']) > 0:
304
			zone = univention.admin.uldap.explodeDn(self['dnsEntryZoneForward'][0], 1)[0]
305
			if not result:
306
				result = [{'url': 'https://%s.%s/univention-management-console/' % (self['name'], zone)}]
307
			result[0]['fqdn'] = '%s.%s' % (self['name'], zone)
308
		if result:
309
			result[0]['name'] = _('Open Univention Management Console on this computer')
310
			return result
311
		return None
312
313
	@classmethod
314
	def rewrite(cls, filter, mapping):
315
		if filter.variable == 'ip':
316
			filter.variable = 'aRecord'
317
		else:
318
			univention.admin.mapping.mapRewrite(filter, cls.mapping)
319
320
	@classmethod
321
	def lookup_filter(cls, filter_s=None, lo=None):
322
		filter_s = univention.admin.filter.replace_fqdn_filter(filter_s)
323
		if str(filter_s).find('(dnsAlias=') != -1:
324
			filter_s = univention.admin.handlers.dns.alias.lookup_alias_filter(lo, filter_s)
325
			if filter_s:
326
				return cls.lookup_filter(filter_s, lo)
327
			else:
328
				return None
329
		lookup_filter_obj = univention.admin.filter.conjunction('&', [x for x in [
330
			univention.admin.filter.expression('objectClass', 'univentionHost'),
331
			univention.admin.filter.expression('objectClass', cls.SERVER_TYPE),
332
			None if not cls.SERVER_ROLE else univention.admin.filter.expression('univentionServerRole', cls.SERVER_ROLE),
333
		] if x is not None])
334
335
		# ATTENTION: has its own rewrite function.
336
		lookup_filter_obj.append_unmapped_filter_string(filter_s, cls.rewrite, cls.mapping)
337
		return lookup_filter_obj
338
339
	@classmethod
340
	def lookup(cls, co, lo, filter_s, base='', superordinate=None, scope='sub', unique=0, required=0, timeout=-1, sizelimit=0):
341
		filter = cls.lookup_filter(filter_s, lo)
342
		if filter is None:
343
			return []
344
		res = []
345
		for dn, attrs in lo.search(unicode(filter), base, scope, [], unique, required, timeout, sizelimit):
346
			res.append(cls(co, lo, None, dn, attributes=attrs))
347
		return res
348
349
	@classmethod
350
	def identify(cls, dn, attr, canonical=0):
351
		return 'univentionHost' in attr.get('objectClass', []) and cls.SERVER_TYPE in attr.get('objectClass', []) and (True if not cls.SERVER_ROLE else cls.SERVER_ROLE in attr.get('univentionServerRole', []))
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/domaincontroller_backup.py (-304 / +14 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from ldap.filter import filter_format
34
35
from univention.admin.layout import Tab, Group
33
from univention.admin.layout import Tab, Group
36
import univention.admin.filter
34
import univention.admin.filter
37
import univention.admin.handlers
35
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
36
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
37
import univention.admin.nagios as nagios
43
import univention.admin.handlers.dns.forward_zone
38
from univention.admin.handlers.computers.base import computerBase
44
import univention.admin.handlers.dns.reverse_zone
45
import univention.admin.handlers.groups.group
46
import univention.admin.handlers.networks.network
47
import time
48
39
49
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
40
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
50
_ = translation.translate
41
_ = translation.translate
 Lines 401-698    Link Here 
401
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
392
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
402
393
403
394
404
class object(univention.admin.handlers.simpleComputer, nagios.Support):
395
class object(computerBase):
405
	module = module
396
	module = module
406
397
	mapping = mapping
407
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
398
	CONFIG_NAME = 'univentionDefaultDomainControllerMasterGroup'
408
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
399
	DEFAULT_OCS = ['top', 'person', 'univentionHost', 'univentionDomainController']
409
		nagios.Support.__init__(self)
400
	SAMBA_ACCOUNT_FLAG = 'S'
410
401
	SERVER_TYPE = 'univentionDomainController'
411
	def open(self):
402
	SERVER_ROLE = 'backup'
412
		univention.admin.handlers.simpleComputer.open(self)
403
413
		self.nagios_open()
404
414
405
rewrite = object.rewrite
415
		self.modifypassword = 0
406
lookup_filter = object.lookup_filter
416
		if self.exists():
407
lookup = object.lookup
417
			userPassword = self.oldattr.get('userPassword', [''])[0]
408
identify = object.identify
418
			if userPassword:
419
				self.info['password'] = userPassword
420
				self.modifypassword = 0
421
422
		if self.exists():
423
424
			if 'posix' in self.options and not self.info.get('primaryGroup'):
425
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
426
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
427
				if primaryGroupNumber:
428
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
429
					if primaryGroupResult:
430
						self['primaryGroup'] = primaryGroupResult[0]
431
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
432
					else:
433
						self['primaryGroup'] = None
434
						self.save()
435
						raise univention.admin.uexceptions.primaryGroup
436
				else:
437
					self['primaryGroup'] = None
438
					self.save()
439
					raise univention.admin.uexceptions.primaryGroup
440
			if 'samba' in self.options:
441
				sid = self.oldattr.get('sambaSID', [''])[0]
442
				pos = sid.rfind('-')
443
				self.info['sambaRID'] = sid[pos + 1:]
444
445
			self.save()
446
447
		else:
448
			self.modifypassword = 0
449
			if 'posix' in self.options:
450
				res = univention.admin.config.getDefaultValue(self.lo, 'univentionDefaultDomainControllerMasterGroup', position=self.position)
451
				if res:
452
					self['primaryGroup'] = res
453
					# self.save()
454
455
	def _ldap_pre_create(self):
456
		super(object, self)._ldap_pre_create()
457
		if not self['password']:
458
			self['password'] = self.oldattr.get('password', [''])[0]
459
			self.modifypassword = 0
460
461
	def _ldap_addlist(self):
462
		ocs = ['top', 'person', 'univentionHost', 'univentionDomainController']
463
		al = []
464
		if 'kerberos' in self.options:
465
			domain = univention.admin.uldap.domain(self.lo, self.position)
466
			realm = domain.getKerberosRealm()
467
468
			if realm:
469
				al.append(('krb5MaxLife', '86400'))
470
				al.append(('krb5MaxRenew', '604800'))
471
				al.append(('krb5KDCFlags', '126'))
472
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
473
				al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
474
			else:
475
				# can't do kerberos
476
				self._remove_option('kerberos')
477
		if 'posix' in self.options:
478
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
479
			self.alloc.append(('uidNumber', self.uidNum))
480
			gidNum = self.get_gid_for_primary_group()
481
			al.append(('uidNumber', [self.uidNum]))
482
			al.append(('gidNumber', [gidNum]))
483
484
		if self.modifypassword or self['password']:
485
			if 'kerberos' in self.options:
486
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
487
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
488
			if 'posix' in self.options:
489
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
490
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
491
			if 'samba' in self.options:
492
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
493
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
494
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
495
				sambaPwdLastSetValue = str(long(time.time()))
496
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
497
			self.modifypassword = 0
498
		if 'samba' in self.options:
499
			acctFlags = univention.admin.samba.acctFlags(flags={'S': 1})
500
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
501
			self.alloc.append(('sid', self.machineSid))
502
			al.append(('sambaSID', [self.machineSid]))
503
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
504
			al.append(('displayName', self.info['name']))
505
506
		al.insert(0, ('objectClass', ocs))
507
		al.append(('univentionServerRole', '', 'backup'))
508
		return al
509
510
	def _ldap_post_create(self):
511
		if 'posix' in self.options:
512
			if hasattr(self, 'uid') and self.uid:
513
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
514
			univention.admin.handlers.simpleComputer.primary_group(self)
515
			univention.admin.handlers.simpleComputer.update_groups(self)
516
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
517
		self.nagios_ldap_post_create()
518
519
	def _ldap_pre_remove(self):
520
		self.open()
521
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
522
			self.uidNum = self.oldattr['uidNumber'][0]
523
524
	def _ldap_post_remove(self):
525
		if 'posix' in self.options:
526
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
527
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember=%s', [self.dn]))
528
		if groupObjects:
529
			for i in range(0, len(groupObjects)):
530
				groupObjects[i].open()
531
				if self.dn in groupObjects[i]['users']:
532
					groupObjects[i]['users'].remove(self.dn)
533
					groupObjects[i].modify(ignore_license=1)
534
535
		self.nagios_ldap_post_remove()
536
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
537
		# Need to clean up oldinfo. If remove was invoked, because the
538
		# creation of the object has failed, the next try will result in
539
		# a 'object class violation' (Bug #19343)
540
		self.oldinfo = {}
541
542
	def krb5_principal(self):
543
		domain = univention.admin.uldap.domain(self.lo, self.position)
544
		realm = domain.getKerberosRealm()
545
		if self.info.has_key('domain') and self.info['domain']:
546
			kerberos_domain = self.info['domain']
547
		else:
548
			kerberos_domain = domain.getKerberosRealm()
549
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
550
551
	def _ldap_post_modify(self):
552
		univention.admin.handlers.simpleComputer.primary_group(self)
553
		univention.admin.handlers.simpleComputer.update_groups(self)
554
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
555
		self.nagios_ldap_post_modify()
556
557
	def _ldap_pre_modify(self):
558
		if self.hasChanged('password'):
559
			if not self['password']:
560
				self['password'] = self.oldattr.get('password', [''])[0]
561
				self.modifypassword = 0
562
			elif not self.info['password']:
563
				self['password'] = self.oldattr.get('password', [''])[0]
564
				self.modifypassword = 0
565
			else:
566
				self.modifypassword = 1
567
		self.nagios_ldap_pre_modify()
568
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
569
570
	def _ldap_modlist(self):
571
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
572
573
		self.nagios_ldap_modlist(ml)
574
575
		if self.hasChanged('name'):
576
			if 'posix' in self.options:
577
				if hasattr(self, 'uidNum'):
578
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
579
				requested_uid = "%s$" % self['name']
580
				try:
581
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
582
				except Exception:
583
					self.cancel()
584
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
585
					return []
586
587
				self.alloc.append(('uid', self.uid))
588
589
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
590
591
			if 'samba' in self.options:
592
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
593
594
			if 'kerberos' in self.options:
595
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
596
597
		if self.modifypassword and self['password']:
598
			if 'kerberos' in self.options:
599
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
600
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
601
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
602
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
603
			if 'posix' in self.options:
604
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
605
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
606
			if 'samba' in self.options:
607
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
608
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
609
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
610
				sambaPwdLastSetValue = str(long(time.time()))
611
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
612
613
		# add samba option
614
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
615
			acctFlags = univention.admin.samba.acctFlags(flags={'S': 1})
616
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
617
			self.alloc.append(('sid', self.machineSid))
618
			ml.append(('sambaSID', '', [self.machineSid]))
619
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
620
			ml.append(('displayName', '', self.info['name']))
621
			sambaPwdLastSetValue = str(long(time.time()))
622
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
623
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
624
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
625
				if self.oldattr.get(key, []):
626
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
627
628
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
629
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
630
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
631
632
		return ml
633
634
	def cleanup(self):
635
		self.open()
636
		self.nagios_cleanup()
637
		univention.admin.handlers.simpleComputer.cleanup(self)
638
639
	def cancel(self):
640
		for i, j in self.alloc:
641
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
642
			univention.admin.allocators.release(self.lo, self.position, i, j)
643
644
	def link(self):
645
		result = []
646
		if self['ip'] and len(self['ip']) > 0 and self['ip'][0]:
647
			result = [{'url': 'https://%s/univention-management-console/' % self['ip'][0], 'ipaddr': self['ip'][0], }]
648
		if self.has_key('dnsEntryZoneForward') and self['dnsEntryZoneForward'] and len(self['dnsEntryZoneForward']) > 0:
649
			zone = univention.admin.uldap.explodeDn(self['dnsEntryZoneForward'][0], 1)[0]
650
			if not result:
651
				result = [{'url': 'https://%s.%s/univention-management-console/' % (self['name'], zone)}]
652
			result[0]['fqdn'] = '%s.%s' % (self['name'], zone)
653
		if result:
654
			result[0]['name'] = _('Open Univention Management Console on this computer')
655
			return result
656
		return None
657
658
659
def rewrite(filter, mapping):
660
	if filter.variable == 'ip':
661
		filter.variable = 'aRecord'
662
	else:
663
		univention.admin.mapping.mapRewrite(filter, mapping)
664
665
666
def lookup_filter(filter_s=None, lo=None):
667
	filter_s = univention.admin.filter.replace_fqdn_filter(filter_s)
668
	if str(filter_s).find('(dnsAlias=') != -1:
669
		filter_s = univention.admin.handlers.dns.alias.lookup_alias_filter(lo, filter_s)
670
		if filter_s:
671
			return lookup_filter(filter_s, lo)
672
		else:
673
			return None
674
	lookup_filter_obj = \
675
		univention.admin.filter.conjunction('&', [
676
			univention.admin.filter.expression('objectClass', 'univentionHost'),
677
			univention.admin.filter.expression('objectClass', 'univentionDomainController'),
678
			univention.admin.filter.expression('univentionServerRole', 'backup'),
679
		])
680
681
	# ATTENTION: has its own rewrite function.
682
	lookup_filter_obj.append_unmapped_filter_string(filter_s, rewrite, mapping)
683
	return lookup_filter_obj
684
685
686
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
687
688
	filter = lookup_filter(filter_s, lo)
689
	if filter is None:
690
		return []
691
	res = []
692
	for dn, attrs in lo.search(unicode(filter), base, scope, [], unique, required, timeout, sizelimit):
693
		res.append(object(co, lo, None, dn, attributes=attrs))
694
	return res
695
696
697
def identify(dn, attr, canonical=0):
698
	return 'univentionHost' in attr.get('objectClass', []) and 'univentionDomainController' in attr.get('objectClass', []) and 'backup' in attr.get('univentionServerRole', [])
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/domaincontroller_master.py (-298 / +14 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from ldap.filter import filter_format
34
35
from univention.admin.layout import Tab, Group
33
from univention.admin.layout import Tab, Group
36
import univention.admin.filter
34
import univention.admin.filter
37
import univention.admin.handlers
35
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
36
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
37
import univention.admin.nagios as nagios
43
import univention.admin.handlers.dns.forward_zone
38
from univention.admin.handlers.computers.base import computerBase
44
import univention.admin.handlers.dns.reverse_zone
45
import univention.admin.handlers.groups.group
46
import univention.admin.handlers.networks.network
47
import time
48
39
49
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
40
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
50
_ = translation.translate
41
_ = translation.translate
 Lines 401-692    Link Here 
401
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
392
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
402
393
403
394
404
class object(univention.admin.handlers.simpleComputer, nagios.Support):
395
class object(computerBase):
405
	module = module
396
	module = module
406
397
	mapping = mapping
407
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
398
	CONFIG_NAME = 'univentionDefaultDomainControllerMasterGroup'
408
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
399
	DEFAULT_OCS = ['top', 'person', 'univentionHost', 'univentionDomainController']
409
		nagios.Support.__init__(self)
400
	SAMBA_ACCOUNT_FLAG = 'S'
410
401
	SERVER_TYPE = 'univentionDomainController'
411
	def open(self):
402
	SERVER_ROLE = 'master'
412
		univention.admin.handlers.simpleComputer.open(self)
403
413
		self.nagios_open()
404
414
405
rewrite = object.rewrite
415
		self.modifypassword = 0
406
lookup_filter = object.lookup_filter
416
		if self.exists():
407
lookup = object.lookup
417
			userPassword = self.oldattr.get('userPassword', [''])[0]
408
identify = object.identify
418
			if userPassword:
419
				self.info['password'] = userPassword
420
				self.modifypassword = 0
421
422
		if self.exists():
423
424
			if 'posix' in self.options and not self.info.get('primaryGroup'):
425
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
426
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
427
				if primaryGroupNumber:
428
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
429
					if primaryGroupResult:
430
						self['primaryGroup'] = primaryGroupResult[0]
431
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
432
					else:
433
						self['primaryGroup'] = None
434
						self.save()
435
						raise univention.admin.uexceptions.primaryGroup
436
				else:
437
					self['primaryGroup'] = None
438
					self.save()
439
					raise univention.admin.uexceptions.primaryGroup
440
			if 'samba' in self.options:
441
				sid = self.oldattr.get('sambaSID', [''])[0]
442
				pos = sid.rfind('-')
443
				self.info['sambaRID'] = sid[pos + 1:]
444
445
			self.save()
446
447
		else:
448
			self.modifypassword = 0
449
			if 'posix' in self.options:
450
				res = univention.admin.config.getDefaultValue(self.lo, 'univentionDefaultDomainControllerMasterGroup', position=self.position)
451
				if res:
452
					self['primaryGroup'] = res
453
					# self.save()
454
455
	def _ldap_pre_create(self):
456
		super(object, self)._ldap_pre_create()
457
		if not self['password']:
458
			self['password'] = self.oldattr.get('password', [''])[0]
459
			self.modifypassword = 0
460
461
	def _ldap_addlist(self):
462
		ocs = ['top', 'person', 'univentionHost', 'univentionDomainController']
463
		al = []
464
		if 'kerberos' in self.options:
465
			al.append(('krb5MaxLife', '86400'))
466
			al.append(('krb5MaxRenew', '604800'))
467
			al.append(('krb5KDCFlags', '126'))
468
			krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
469
			al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
470
471
		if 'posix' in self.options:
472
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
473
			self.alloc.append(('uidNumber', self.uidNum))
474
			gidNum = self.get_gid_for_primary_group()
475
			al.append(('uidNumber', [self.uidNum]))
476
			al.append(('gidNumber', [gidNum]))
477
478
		if self.modifypassword or self['password']:
479
			if 'kerberos' in self.options:
480
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
481
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
482
			if 'posix' in self.options:
483
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
484
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
485
			if 'samba' in self.options:
486
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
487
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
488
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
489
				sambaPwdLastSetValue = str(long(time.time()))
490
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
491
			self.modifypassword = 0
492
		if 'samba' in self.options:
493
			acctFlags = univention.admin.samba.acctFlags(flags={'S': 1})
494
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
495
			self.alloc.append(('sid', self.machineSid))
496
			al.append(('sambaSID', [self.machineSid]))
497
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
498
			al.append(('displayName', self.info['name']))
499
500
		al.insert(0, ('objectClass', ocs))
501
		al.append(('univentionServerRole', '', 'master'))
502
		return al
503
504
	def _ldap_post_create(self):
505
		if 'posix' in self.options:
506
			if hasattr(self, 'uid') and self.uid:
507
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
508
			univention.admin.handlers.simpleComputer.primary_group(self)
509
			univention.admin.handlers.simpleComputer.update_groups(self)
510
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
511
		self.nagios_ldap_post_create()
512
513
	def _ldap_pre_remove(self):
514
		self.open()
515
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
516
			self.uidNum = self.oldattr['uidNumber'][0]
517
518
	def _ldap_post_remove(self):
519
		if 'posix' in self.options:
520
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
521
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember=%s', [self.dn]))
522
		if groupObjects:
523
			for i in range(0, len(groupObjects)):
524
				groupObjects[i].open()
525
				if self.dn in groupObjects[i]['users']:
526
					groupObjects[i]['users'].remove(self.dn)
527
					groupObjects[i].modify(ignore_license=1)
528
529
		self.nagios_ldap_post_remove()
530
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
531
		# Need to clean up oldinfo. If remove was invoked, because the
532
		# creation of the object has failed, the next try will result in
533
		# a 'object class violation' (Bug #19343)
534
		self.oldinfo = {}
535
536
	def krb5_principal(self):
537
		domain = univention.admin.uldap.domain(self.lo, self.position)
538
		realm = domain.getKerberosRealm()
539
		if self.info.has_key('domain') and self.info['domain']:
540
			kerberos_domain = self.info['domain']
541
		else:
542
			kerberos_domain = domain.getKerberosRealm()
543
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
544
545
	def _ldap_post_modify(self):
546
		univention.admin.handlers.simpleComputer.primary_group(self)
547
		univention.admin.handlers.simpleComputer.update_groups(self)
548
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
549
		self.nagios_ldap_post_modify()
550
551
	def _ldap_pre_modify(self):
552
		if self.hasChanged('password'):
553
			if not self['password']:
554
				self['password'] = self.oldattr.get('password', [''])[0]
555
				self.modifypassword = 0
556
			elif not self.info['password']:
557
				self['password'] = self.oldattr.get('password', [''])[0]
558
				self.modifypassword = 0
559
			else:
560
				self.modifypassword = 1
561
		self.nagios_ldap_pre_modify()
562
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
563
564
	def _ldap_modlist(self):
565
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
566
567
		self.nagios_ldap_modlist(ml)
568
569
		if self.hasChanged('name'):
570
			if 'posix' in self.options:
571
				if hasattr(self, 'uidNum'):
572
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
573
				requested_uid = "%s$" % self['name']
574
				try:
575
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
576
				except Exception:
577
					self.cancel()
578
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
579
					return []
580
581
				self.alloc.append(('uid', self.uid))
582
583
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
584
585
			if 'samba' in self.options:
586
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
587
588
			if 'kerberos' in self.options:
589
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
590
591
		if self.modifypassword and self['password']:
592
			if 'kerberos' in self.options:
593
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
594
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
595
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
596
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
597
			if 'posix' in self.options:
598
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
599
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
600
			if 'samba' in self.options:
601
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
602
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
603
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
604
				sambaPwdLastSetValue = str(long(time.time()))
605
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
606
607
		# add samba option
608
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
609
			acctFlags = univention.admin.samba.acctFlags(flags={'S': 1})
610
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
611
			self.alloc.append(('sid', self.machineSid))
612
			ml.append(('sambaSID', '', [self.machineSid]))
613
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
614
			ml.append(('displayName', '', self.info['name']))
615
			sambaPwdLastSetValue = str(long(time.time()))
616
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
617
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
618
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
619
				if self.oldattr.get(key, []):
620
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
621
622
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
623
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
624
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
625
626
		return ml
627
628
	def cleanup(self):
629
		self.open()
630
		self.nagios_cleanup()
631
		univention.admin.handlers.simpleComputer.cleanup(self)
632
633
	def cancel(self):
634
		for i, j in self.alloc:
635
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
636
			univention.admin.allocators.release(self.lo, self.position, i, j)
637
638
	def link(self):
639
		result = []
640
		if self['ip'] and len(self['ip']) > 0 and self['ip'][0]:
641
			result = [{'url': 'https://%s/univention-management-console/' % self['ip'][0], 'ipaddr': self['ip'][0], }]
642
		if self.has_key('dnsEntryZoneForward') and self['dnsEntryZoneForward'] and len(self['dnsEntryZoneForward']) > 0:
643
			zone = univention.admin.uldap.explodeDn(self['dnsEntryZoneForward'][0], 1)[0]
644
			if not result:
645
				result = [{'url': 'https://%s.%s/univention-management-console/' % (self['name'], zone)}]
646
			result[0]['fqdn'] = '%s.%s' % (self['name'], zone)
647
		if result:
648
			result[0]['name'] = _('Open Univention Management Console on this computer')
649
			return result
650
		return None
651
652
653
def rewrite(filter, mapping):
654
	if filter.variable == 'ip':
655
		filter.variable = 'aRecord'
656
	else:
657
		univention.admin.mapping.mapRewrite(filter, mapping)
658
659
660
def lookup_filter(filter_s=None, lo=None):
661
	filter_s = univention.admin.filter.replace_fqdn_filter(filter_s)
662
	if str(filter_s).find('(dnsAlias=') != -1:
663
		filter_s = univention.admin.handlers.dns.alias.lookup_alias_filter(lo, filter_s)
664
		if filter_s:
665
			return lookup_filter(filter_s, lo)
666
		else:
667
			return None
668
	lookup_filter_obj = \
669
		univention.admin.filter.conjunction('&', [
670
			univention.admin.filter.expression('objectClass', 'univentionHost'),
671
			univention.admin.filter.expression('objectClass', 'univentionDomainController'),
672
			univention.admin.filter.expression('univentionServerRole', 'master'),
673
		])
674
675
	# ATTENTION: has its own rewrite function.
676
	lookup_filter_obj.append_unmapped_filter_string(filter_s, rewrite, mapping)
677
	return lookup_filter_obj
678
679
680
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
681
682
	filter = lookup_filter(filter_s, lo)
683
	if filter is None:
684
		return []
685
	res = []
686
	for dn, attrs in lo.search(unicode(filter), base, scope, [], unique, required, timeout, sizelimit):
687
		res.append(object(co, lo, None, dn, attributes=attrs))
688
	return res
689
690
691
def identify(dn, attr, canonical=0):
692
	return 'univentionHost' in attr.get('objectClass', []) and 'univentionDomainController' in attr.get('objectClass', []) and 'master' in attr.get('univentionServerRole', [])
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/domaincontroller_slave.py (-304 / +14 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from ldap.filter import filter_format
34
35
from univention.admin.layout import Tab, Group
33
from univention.admin.layout import Tab, Group
36
import univention.admin.filter
34
import univention.admin.filter
37
import univention.admin.handlers
35
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
36
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
37
import univention.admin.nagios as nagios
43
import univention.admin.handlers.dns.forward_zone
38
from univention.admin.handlers.computers.base import computerBase
44
import univention.admin.handlers.dns.reverse_zone
45
import univention.admin.handlers.groups.group
46
import univention.admin.handlers.networks.network
47
import time
48
39
49
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
40
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
50
_ = translation.translate
41
_ = translation.translate
 Lines 401-698    Link Here 
401
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
392
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
402
393
403
394
404
class object(univention.admin.handlers.simpleComputer, nagios.Support):
395
class object(computerBase):
405
	module = module
396
	module = module
406
397
	mapping = mapping
407
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
398
	CONFIG_NAME = 'univentionDefaultDomainControllerGroup'
408
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
399
	DEFAULT_OCS = ['top', 'person', 'univentionHost', 'univentionDomainController']
409
		nagios.Support.__init__(self)
400
	SAMBA_ACCOUNT_FLAG = 'S'
410
401
	SERVER_TYPE = 'univentionDomainController'
411
	def open(self):
402
	SERVER_ROLE = 'slave'
412
		univention.admin.handlers.simpleComputer.open(self)
403
413
		self.nagios_open()
404
414
405
rewrite = object.rewrite
415
		self.modifypassword = 0
406
lookup_filter = object.lookup_filter
416
		if self.exists():
407
lookup = object.lookup
417
			userPassword = self.oldattr.get('userPassword', [''])[0]
408
identify = object.identify
418
			if userPassword:
419
				self.info['password'] = userPassword
420
				self.modifypassword = 0
421
422
		if self.exists():
423
424
			if 'posix' in self.options and not self.info.get('primaryGroup'):
425
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
426
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
427
				if primaryGroupNumber:
428
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
429
					if primaryGroupResult:
430
						self['primaryGroup'] = primaryGroupResult[0]
431
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
432
					else:
433
						self['primaryGroup'] = None
434
						self.save()
435
						raise univention.admin.uexceptions.primaryGroup
436
				else:
437
					self['primaryGroup'] = None
438
					self.save()
439
					raise univention.admin.uexceptions.primaryGroup
440
			if 'samba' in self.options:
441
				sid = self.oldattr.get('sambaSID', [''])[0]
442
				pos = sid.rfind('-')
443
				self.info['sambaRID'] = sid[pos + 1:]
444
445
			self.save()
446
447
		else:
448
			self.modifypassword = 0
449
			if 'posix' in self.options:
450
				res = univention.admin.config.getDefaultValue(self.lo, 'univentionDefaultDomainControllerGroup', position=self.position)
451
				if res:
452
					self['primaryGroup'] = res
453
					# self.save()
454
455
	def _ldap_pre_create(self):
456
		super(object, self)._ldap_pre_create()
457
		if not self['password']:
458
			self['password'] = self.oldattr.get('password', [''])[0]
459
			self.modifypassword = 0
460
461
	def _ldap_addlist(self):
462
		ocs = ['top', 'person', 'univentionHost', 'univentionDomainController']
463
		al = []
464
		if 'kerberos' in self.options:
465
			domain = univention.admin.uldap.domain(self.lo, self.position)
466
			realm = domain.getKerberosRealm()
467
468
			if realm:
469
				al.append(('krb5MaxLife', '86400'))
470
				al.append(('krb5MaxRenew', '604800'))
471
				al.append(('krb5KDCFlags', '126'))
472
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
473
				al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
474
			else:
475
				# can't do kerberos
476
				self._remove_option('kerberos')
477
		if 'posix' in self.options:
478
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
479
			self.alloc.append(('uidNumber', self.uidNum))
480
			gidNum = self.get_gid_for_primary_group()
481
			al.append(('uidNumber', [self.uidNum]))
482
			al.append(('gidNumber', [gidNum]))
483
484
		if self.modifypassword or self['password']:
485
			if 'kerberos' in self.options:
486
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
487
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
488
			if 'posix' in self.options:
489
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
490
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
491
			if 'samba' in self.options:
492
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
493
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
494
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
495
				sambaPwdLastSetValue = str(long(time.time()))
496
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
497
			self.modifypassword = 0
498
		if 'samba' in self.options:
499
			acctFlags = univention.admin.samba.acctFlags(flags={'S': 1})
500
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
501
			self.alloc.append(('sid', self.machineSid))
502
			al.append(('sambaSID', [self.machineSid]))
503
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
504
			al.append(('displayName', self.info['name']))
505
506
		al.insert(0, ('objectClass', ocs))
507
		al.append(('univentionServerRole', '', 'slave'))
508
		return al
509
510
	def _ldap_post_create(self):
511
		if 'posix' in self.options:
512
			if hasattr(self, 'uid') and self.uid:
513
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
514
			univention.admin.handlers.simpleComputer.primary_group(self)
515
			univention.admin.handlers.simpleComputer.update_groups(self)
516
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
517
		self.nagios_ldap_post_create()
518
519
	def _ldap_pre_remove(self):
520
		self.open()
521
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
522
			self.uidNum = self.oldattr['uidNumber'][0]
523
524
	def _ldap_post_remove(self):
525
		if 'posix' in self.options:
526
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
527
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember=%s', [self.dn]))
528
		if groupObjects:
529
			for i in range(0, len(groupObjects)):
530
				groupObjects[i].open()
531
				if self.dn in groupObjects[i]['users']:
532
					groupObjects[i]['users'].remove(self.dn)
533
					groupObjects[i].modify(ignore_license=1)
534
535
		self.nagios_ldap_post_remove()
536
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
537
		# Need to clean up oldinfo. If remove was invoked, because the
538
		# creation of the object has failed, the next try will result in
539
		# a 'object class violation' (Bug #19343)
540
		self.oldinfo = {}
541
542
	def krb5_principal(self):
543
		domain = univention.admin.uldap.domain(self.lo, self.position)
544
		realm = domain.getKerberosRealm()
545
		if self.info.has_key('domain') and self.info['domain']:
546
			kerberos_domain = self.info['domain']
547
		else:
548
			kerberos_domain = domain.getKerberosRealm()
549
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
550
551
	def _ldap_post_modify(self):
552
		univention.admin.handlers.simpleComputer.primary_group(self)
553
		univention.admin.handlers.simpleComputer.update_groups(self)
554
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
555
		self.nagios_ldap_post_modify()
556
557
	def _ldap_pre_modify(self):
558
		if self.hasChanged('password'):
559
			if not self['password']:
560
				self['password'] = self.oldattr.get('password', [''])[0]
561
				self.modifypassword = 0
562
			elif not self.info['password']:
563
				self['password'] = self.oldattr.get('password', [''])[0]
564
				self.modifypassword = 0
565
			else:
566
				self.modifypassword = 1
567
		self.nagios_ldap_pre_modify()
568
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
569
570
	def _ldap_modlist(self):
571
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
572
573
		self.nagios_ldap_modlist(ml)
574
575
		if self.hasChanged('name'):
576
			if 'posix' in self.options:
577
				if hasattr(self, 'uidNum'):
578
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
579
				requested_uid = "%s$" % self['name']
580
				try:
581
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
582
				except Exception:
583
					self.cancel()
584
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
585
					return []
586
587
				self.alloc.append(('uid', self.uid))
588
589
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
590
591
			if 'samba' in self.options:
592
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
593
594
			if 'kerberos' in self.options:
595
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
596
597
		if self.modifypassword and self['password']:
598
			if 'kerberos' in self.options:
599
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
600
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
601
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
602
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
603
			if 'posix' in self.options:
604
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
605
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
606
			if 'samba' in self.options:
607
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
608
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
609
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
610
				sambaPwdLastSetValue = str(long(time.time()))
611
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
612
613
		# add samba option
614
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
615
			acctFlags = univention.admin.samba.acctFlags(flags={'S': 1})
616
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
617
			self.alloc.append(('sid', self.machineSid))
618
			ml.append(('sambaSID', '', [self.machineSid]))
619
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
620
			ml.append(('displayName', '', self.info['name']))
621
			sambaPwdLastSetValue = str(long(time.time()))
622
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
623
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
624
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
625
				if self.oldattr.get(key, []):
626
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
627
628
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
629
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
630
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
631
632
		return ml
633
634
	def cleanup(self):
635
		self.open()
636
		self.nagios_cleanup()
637
		univention.admin.handlers.simpleComputer.cleanup(self)
638
639
	def cancel(self):
640
		for i, j in self.alloc:
641
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
642
			univention.admin.allocators.release(self.lo, self.position, i, j)
643
644
	def link(self):
645
		result = []
646
		if self['ip'] and len(self['ip']) > 0 and self['ip'][0]:
647
			result = [{'url': 'https://%s/univention-management-console/' % self['ip'][0], 'ipaddr': self['ip'][0], }]
648
		if self.has_key('dnsEntryZoneForward') and self['dnsEntryZoneForward'] and len(self['dnsEntryZoneForward']) > 0:
649
			zone = univention.admin.uldap.explodeDn(self['dnsEntryZoneForward'][0], 1)[0]
650
			if not result:
651
				result = [{'url': 'https://%s.%s/univention-management-console/' % (self['name'], zone)}]
652
			result[0]['fqdn'] = '%s.%s' % (self['name'], zone)
653
		if result:
654
			result[0]['name'] = _('Open Univention Management Console on this computer')
655
			return result
656
		return None
657
658
659
def rewrite(filter, mapping):
660
	if filter.variable == 'ip':
661
		filter.variable = 'aRecord'
662
	else:
663
		univention.admin.mapping.mapRewrite(filter, mapping)
664
665
666
def lookup_filter(filter_s=None, lo=None):
667
	filter_s = univention.admin.filter.replace_fqdn_filter(filter_s)
668
	if str(filter_s).find('(dnsAlias=') != -1:
669
		filter_s = univention.admin.handlers.dns.alias.lookup_alias_filter(lo, filter_s)
670
		if filter_s:
671
			return lookup_filter(filter_s, lo)
672
		else:
673
			return None
674
	lookup_filter_obj = \
675
		univention.admin.filter.conjunction('&', [
676
			univention.admin.filter.expression('objectClass', 'univentionHost'),
677
			univention.admin.filter.expression('objectClass', 'univentionDomainController'),
678
			univention.admin.filter.expression('univentionServerRole', 'slave'),
679
		])
680
681
	# ATTENTION: has its own rewrite function.
682
	lookup_filter_obj.append_unmapped_filter_string(filter_s, rewrite, mapping)
683
	return lookup_filter_obj
684
685
686
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
687
688
	filter = lookup_filter(filter_s, lo)
689
	if filter is None:
690
		return []
691
	res = []
692
	for dn, attrs in lo.search(unicode(filter), base, scope, [], unique, required, timeout, sizelimit):
693
		res.append(object(co, lo, None, dn, attributes=attrs))
694
	return res
695
696
697
def identify(dn, attr, canonical=0):
698
	return 'univentionHost' in attr.get('objectClass', []) and 'univentionDomainController' in attr.get('objectClass', []) and 'slave' in attr.get('univentionServerRole', [])
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/linux.py (-252 / +11 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from ldap.filter import filter_format
34
35
from univention.admin.layout import Tab, Group
33
from univention.admin.layout import Tab, Group
36
import univention.admin.filter
34
import univention.admin.filter
37
import univention.admin.handlers
35
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
36
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
37
import univention.admin.nagios as nagios
43
import univention.admin.handlers.dns.forward_zone
38
from univention.admin.handlers.computers.base import computerBase
44
import univention.admin.handlers.dns.reverse_zone
45
import univention.admin.handlers.groups.group
46
import univention.admin.handlers.networks.network
47
import time
48
39
49
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
40
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
50
_ = translation.translate
41
_ = translation.translate
 Lines 340-592    Link Here 
340
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
331
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
341
332
342
333
343
class object(univention.admin.handlers.simpleComputer, nagios.Support):
334
class object(computerBase):
344
	module = module
335
	module = module
336
	mapping = mapping
337
	CONFIG_NAME = 'univentionDefaultClientGroup'
338
	DEFAULT_OCS = ['top', 'person', 'univentionHost', 'univentionLinuxClient']
339
	SAMBA_ACCOUNT_FLAG = 'W'
340
	SERVER_TYPE = 'univentionLinuxClient'
345
341
346
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
342
	def check_required_options(self):
347
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
348
		nagios.Support.__init__(self)
349
350
	def open(self):
351
		univention.admin.handlers.simpleComputer.open(self)
352
		self.nagios_open()
353
354
		if self.exists():
355
356
			if 'posix' in self.options and not self.info.get('primaryGroup'):
357
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
358
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
359
				if primaryGroupNumber:
360
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
361
					if primaryGroupResult:
362
						self['primaryGroup'] = primaryGroupResult[0]
363
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
364
					else:
365
						self['primaryGroup'] = None
366
						self.save()
367
						raise univention.admin.uexceptions.primaryGroup
368
				else:
369
					self['primaryGroup'] = None
370
					self.save()
371
					raise univention.admin.uexceptions.primaryGroup
372
			if 'samba' in self.options:
373
				sid = self.oldattr.get('sambaSID', [''])[0]
374
				pos = sid.rfind('-')
375
				self.info['sambaRID'] = sid[pos + 1:]
376
377
		self.modifypassword = 0
378
		if self.exists():
379
			userPassword = self.oldattr.get('userPassword', [''])[0]
380
			if userPassword:
381
				self.info['password'] = userPassword
382
				self.modifypassword = 0
383
			self.save()
384
385
		else:
386
			self.modifypassword = 0
387
			if 'posix' in self.options:
388
				res = univention.admin.config.getDefaultValue(self.lo, 'univentionDefaultClientGroup', position=self.position)
389
				if res:
390
					self['primaryGroup'] = res
391
392
	def _ldap_pre_create(self):
393
		super(object, self)._ldap_pre_create()
394
		if not self['password']:
395
			self['password'] = self.oldattr.get('password', [''])[0]
396
			self.modifypassword = 0
397
398
	def _ldap_addlist(self):
399
		if not set(self.options) & set(['posix', 'kerberos']):
343
		if not set(self.options) & set(['posix', 'kerberos']):
400
			raise univention.admin.uexceptions.invalidOptions(_(' At least posix or kerberos is required.'))
344
			raise univention.admin.uexceptions.invalidOptions(_('At least posix or kerberos is required.'))
401
402
		ocs = ['top', 'person', 'univentionHost', 'univentionLinuxClient']
403
		al = []
404
		if 'kerberos' in self.options:
405
			domain = univention.admin.uldap.domain(self.lo, self.position)
406
			realm = domain.getKerberosRealm()
407
408
			if realm:
409
				al.append(('krb5MaxLife', '86400'))
410
				al.append(('krb5MaxRenew', '604800'))
411
				al.append(('krb5KDCFlags', '126'))
412
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
413
				al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
414
			else:
415
				# can't do kerberos
416
				self._remove_option('kerberos')
417
		if 'posix' in self.options:
418
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
419
			self.alloc.append(('uidNumber', self.uidNum))
420
			gidNum = self.get_gid_for_primary_group()
421
			al.append(('uidNumber', [self.uidNum]))
422
			al.append(('gidNumber', [gidNum]))
423
424
		if self.modifypassword or self['password']:
425
			if 'kerberos' in self.options:
426
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
427
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
428
			if 'posix' in self.options:
429
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
430
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
431
			if 'samba' in self.options:
432
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
433
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
434
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
435
				sambaPwdLastSetValue = str(long(time.time()))
436
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
437
			self.modifypassword = 0
438
		if 'samba' in self.options:
439
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
440
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
441
			self.alloc.append(('sid', self.machineSid))
442
			al.append(('sambaSID', [self.machineSid]))
443
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
444
			al.append(('displayName', self.info['name']))
445
446
		al.insert(0, ('objectClass', ocs))
447
448
		return al
449
450
	def _ldap_post_create(self):
451
		if 'posix' in self.options:
452
			if hasattr(self, 'uid') and self.uid:
453
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
454
			univention.admin.handlers.simpleComputer.primary_group(self)
455
			univention.admin.handlers.simpleComputer.update_groups(self)
456
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
457
		self.nagios_ldap_post_create()
458
459
	def _ldap_pre_remove(self):
460
		self.open()
461
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
462
			self.uidNum = self.oldattr['uidNumber'][0]
463
464
	def _ldap_post_remove(self):
465
		if 'posix' in self.options:
466
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
467
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember=%s', [self.dn]))
468
		if groupObjects:
469
			for i in range(0, len(groupObjects)):
470
				groupObjects[i].open()
471
				if self.dn in groupObjects[i]['users']:
472
					groupObjects[i]['users'].remove(self.dn)
473
					groupObjects[i].modify(ignore_license=1)
474
475
		self.nagios_ldap_post_remove()
476
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
477
		# Need to clean up oldinfo. If remove was invoked, because the
478
		# creation of the object has failed, the next try will result in
479
		# a 'object class violation' (Bug #19343)
480
		self.oldinfo = {}
481
345
482
	def krb5_principal(self):
483
		domain = univention.admin.uldap.domain(self.lo, self.position)
484
		realm = domain.getKerberosRealm()
485
		if self.info.has_key('domain') and self.info['domain']:
486
			kerberos_domain = self.info['domain']
487
		else:
488
			kerberos_domain = domain.getKerberosRealm()
489
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
490
346
491
	def _ldap_post_modify(self):
347
del object.link
492
		univention.admin.handlers.simpleComputer.primary_group(self)
348
rewrite = object.rewrite
493
		univention.admin.handlers.simpleComputer.update_groups(self)
494
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
495
		self.nagios_ldap_post_modify()
496
497
	def _ldap_pre_modify(self):
498
		if self.hasChanged('password'):
499
			if not self['password']:
500
				self['password'] = self.oldattr.get('password', [''])[0]
501
				self.modifypassword = 0
502
			elif not self.info['password']:
503
				self['password'] = self.oldattr.get('password', [''])[0]
504
				self.modifypassword = 0
505
			else:
506
				self.modifypassword = 1
507
		self.nagios_ldap_pre_modify()
508
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
509
510
	def _ldap_modlist(self):
511
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
512
513
		self.nagios_ldap_modlist(ml)
514
515
		if self.hasChanged('name'):
516
			if 'posix' in self.options:
517
				if hasattr(self, 'uidNum'):
518
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
519
				requested_uid = "%s$" % self['name']
520
				try:
521
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
522
				except Exception:
523
					self.cancel()
524
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
525
					return []
526
527
				self.alloc.append(('uid', self.uid))
528
529
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
530
531
			if 'samba' in self.options:
532
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
533
534
			if 'kerberos' in self.options:
535
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
536
537
		if self.modifypassword and self['password']:
538
			if 'kerberos' in self.options:
539
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
540
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
541
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
542
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
543
			if 'posix' in self.options:
544
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
545
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
546
			if 'samba' in self.options:
547
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
548
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
549
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
550
				sambaPwdLastSetValue = str(long(time.time()))
551
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
552
553
		# add samba option
554
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
555
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
556
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
557
			self.alloc.append(('sid', self.machineSid))
558
			ml.append(('sambaSID', '', [self.machineSid]))
559
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
560
			ml.append(('displayName', '', self.info['name']))
561
			sambaPwdLastSetValue = str(long(time.time()))
562
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
563
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
564
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
565
				if self.oldattr.get(key, []):
566
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
567
568
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
569
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
570
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
571
572
		return ml
573
574
	def cleanup(self):
575
		self.open()
576
		self.nagios_cleanup()
577
		univention.admin.handlers.simpleComputer.cleanup(self)
578
579
	def cancel(self):
580
		for i, j in self.alloc:
581
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
582
			univention.admin.allocators.release(self.lo, self.position, i, j)
583
584
585
def rewrite(filter, mapping):
586
	if filter.variable == 'ip':
587
		filter.variable = 'aRecord'
588
	else:
589
		univention.admin.mapping.mapRewrite(filter, mapping)
590
349
591
350
592
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
351
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/macos.py (-257 / +12 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from ldap.filter import filter_format
34
35
from univention.admin.layout import Tab, Group
33
from univention.admin.layout import Tab, Group
36
import univention.admin.filter
34
import univention.admin.filter
37
import univention.admin.handlers
35
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
36
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
37
import univention.admin.nagios as nagios
43
import univention.admin.handlers.dns.forward_zone
38
from univention.admin.handlers.computers.base import computerBase
44
import univention.admin.handlers.dns.reverse_zone
45
import univention.admin.handlers.groups.group
46
import univention.admin.handlers.networks.network
47
import time
48
39
49
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
40
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
50
_ = translation.translate
41
_ = translation.translate
 Lines 328-594    Link Here 
328
mapping = univention.admin.mapping.mapping()
319
mapping = univention.admin.mapping.mapping()
329
mapping.register('name', 'cn', None, univention.admin.mapping.ListToString)
320
mapping.register('name', 'cn', None, univention.admin.mapping.ListToString)
330
mapping.register('description', 'description', None, univention.admin.mapping.ListToString)
321
mapping.register('description', 'description', None, univention.admin.mapping.ListToString)
331
mapping.register('operatingSystem', 'univentionOperatingSystem', None, univention.admin.mapping.ListToString)
332
mapping.register('operatingSystemVersion', 'univentionOperatingSystemVersion', None, univention.admin.mapping.ListToString)
333
mapping.register('domain', 'associatedDomain', None, univention.admin.mapping.ListToString)
322
mapping.register('domain', 'associatedDomain', None, univention.admin.mapping.ListToString)
334
mapping.register('inventoryNumber', 'univentionInventoryNumber')
323
mapping.register('inventoryNumber', 'univentionInventoryNumber')
335
mapping.register('mac', 'macAddress')
324
mapping.register('mac', 'macAddress')
336
mapping.register('network', 'univentionNetworkLink', None, univention.admin.mapping.ListToString)
325
mapping.register('network', 'univentionNetworkLink', None, univention.admin.mapping.ListToString)
337
mapping.register('unixhome', 'homeDirectory', None, univention.admin.mapping.ListToString)
326
mapping.register('unixhome', 'homeDirectory', None, univention.admin.mapping.ListToString)
338
mapping.register('shell', 'loginShell', None, univention.admin.mapping.ListToString)
327
mapping.register('shell', 'loginShell', None, univention.admin.mapping.ListToString)
328
mapping.register('operatingSystem', 'univentionOperatingSystem', None, univention.admin.mapping.ListToString)
329
mapping.register('operatingSystemVersion', 'univentionOperatingSystemVersion', None, univention.admin.mapping.ListToString)
339
330
340
# add Nagios extension
331
# add Nagios extension
341
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
332
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
342
333
343
# WARNING: do not change class order if there are still super() calls
344
334
345
335
class object(computerBase):
346
class object(univention.admin.handlers.simpleComputer, nagios.Support):
347
	module = module
336
	module = module
337
	mapping = mapping
338
	CONFIG_NAME = 'univentionDefaultClientGroup'
339
	DEFAULT_OCS = ['top', 'person', 'univentionHost', 'univentionMacOSClient']
340
	SAMBA_ACCOUNT_FLAG = 'W'
341
	SERVER_TYPE = 'univentionMacOSClient'
348
342
349
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
350
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
351
		nagios.Support.__init__(self)
352
353
	def open(self):
354
		univention.admin.handlers.simpleComputer.open(self)
355
		self.nagios_open()
356
357
		self.modifypassword = 0
358
		if self.exists():
359
			userPassword = self.oldattr.get('userPassword', [''])[0]
360
			if userPassword:
361
				self.info['password'] = userPassword
362
				self.modifypassword = 0
363
364
		if self.exists():
365
366
			if 'posix' in self.options and not self.info.get('primaryGroup'):
367
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
368
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
369
				if primaryGroupNumber:
370
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
371
					if primaryGroupResult:
372
						self['primaryGroup'] = primaryGroupResult[0]
373
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
374
					else:
375
						self['primaryGroup'] = None
376
						self.save()
377
						raise univention.admin.uexceptions.primaryGroup
378
				else:
379
					self['primaryGroup'] = None
380
					self.save()
381
					raise univention.admin.uexceptions.primaryGroup
382
			if 'samba' in self.options:
383
				sid = self.oldattr.get('sambaSID', [''])[0]
384
				pos = sid.rfind('-')
385
				self.info['sambaRID'] = sid[pos + 1:]
386
387
			self.save()
388
389
		else:
390
			self.modifypassword = 0
391
			if 'posix' in self.options:
392
				res = univention.admin.config.getDefaultValue(self.lo, 'univentionDefaultClientGroup', position=self.position)
393
				if res:
394
					self['primaryGroup'] = res
395
					# self.save()
396
397
	def _ldap_pre_create(self):
398
		super(object, self)._ldap_pre_create()
399
		if not self['password']:
400
			self['password'] = self.oldattr.get('password', [''])[0]
401
			self.modifypassword = 0
402
403
	def _ldap_addlist(self):
404
		ocs = ['top', 'person', 'univentionHost', 'univentionMacOSClient']
405
		al = []
406
		if 'kerberos' in self.options:
407
			domain = univention.admin.uldap.domain(self.lo, self.position)
408
			realm = domain.getKerberosRealm()
409
410
			if realm:
411
				al.append(('krb5MaxLife', '86400'))
412
				al.append(('krb5MaxRenew', '604800'))
413
				al.append(('krb5KDCFlags', '126'))
414
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
415
				al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
416
			else:
417
				# can't do kerberos
418
				self._remove_option('kerberos')
419
		if 'posix' in self.options:
420
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
421
			self.alloc.append(('uidNumber', self.uidNum))
422
			gidNum = self.get_gid_for_primary_group()
423
			al.append(('uidNumber', [self.uidNum]))
424
			al.append(('gidNumber', [gidNum]))
425
426
		if self.modifypassword or self['password']:
427
			if 'kerberos' in self.options:
428
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
429
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
430
			if 'posix' in self.options:
431
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
432
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
433
			if 'samba' in self.options:
434
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
435
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
436
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
437
				sambaPwdLastSetValue = str(long(time.time()))
438
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
439
			self.modifypassword = 0
440
		if 'samba' in self.options:
441
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
442
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
443
			self.alloc.append(('sid', self.machineSid))
444
			al.append(('sambaSID', [self.machineSid]))
445
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
446
			al.append(('displayName', self.info['name']))
447
448
		al.insert(0, ('objectClass', ocs))
449
450
		return al
451
452
	def _ldap_post_create(self):
453
		if 'posix' in self.options:
454
			if hasattr(self, 'uid') and self.uid:
455
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
456
			univention.admin.handlers.simpleComputer.primary_group(self)
457
			univention.admin.handlers.simpleComputer.update_groups(self)
458
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
459
		self.nagios_ldap_post_create()
460
461
	def _ldap_pre_remove(self):
462
		self.open()
463
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
464
			self.uidNum = self.oldattr['uidNumber'][0]
465
343
466
	def _ldap_post_remove(self):
344
del object.link
467
		if 'posix' in self.options:
345
rewrite = object.rewrite
468
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
346
identify = object.identify
469
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember=%s', [self.dn]))
470
		if groupObjects:
471
			for i in range(0, len(groupObjects)):
472
				groupObjects[i].open()
473
				if self.dn in groupObjects[i]['users']:
474
					groupObjects[i]['users'].remove(self.dn)
475
					groupObjects[i].modify(ignore_license=1)
476
477
		self.nagios_ldap_post_remove()
478
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
479
		# Need to clean up oldinfo. If remove was invoked, because the
480
		# creation of the object has failed, the next try will result in
481
		# a 'object class violation' (Bug #19343)
482
		self.oldinfo = {}
483
484
	def krb5_principal(self):
485
		domain = univention.admin.uldap.domain(self.lo, self.position)
486
		realm = domain.getKerberosRealm()
487
		if self.info.has_key('domain') and self.info['domain']:
488
			kerberos_domain = self.info['domain']
489
		else:
490
			kerberos_domain = domain.getKerberosRealm()
491
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
492
493
	def _ldap_post_modify(self):
494
		univention.admin.handlers.simpleComputer.primary_group(self)
495
		univention.admin.handlers.simpleComputer.update_groups(self)
496
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
497
		self.nagios_ldap_post_modify()
498
499
	def _ldap_pre_modify(self):
500
		if self.hasChanged('password'):
501
			if not self['password']:
502
				self['password'] = self.oldattr.get('password', [''])[0]
503
				self.modifypassword = 0
504
			elif not self.info['password']:
505
				self['password'] = self.oldattr.get('password', [''])[0]
506
				self.modifypassword = 0
507
			else:
508
				self.modifypassword = 1
509
		self.nagios_ldap_pre_modify()
510
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
511
512
	def _ldap_modlist(self):
513
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
514
515
		self.nagios_ldap_modlist(ml)
516
517
		if self.hasChanged('name'):
518
			if 'posix' in self.options:
519
				if hasattr(self, 'uidNum'):
520
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
521
				requested_uid = "%s$" % self['name']
522
				try:
523
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
524
				except Exception:
525
					self.cancel()
526
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
527
					return []
528
529
				self.alloc.append(('uid', self.uid))
530
531
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
532
533
			if 'samba' in self.options:
534
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
535
536
			if 'kerberos' in self.options:
537
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
538
539
		if self.modifypassword and self['password']:
540
			if 'kerberos' in self.options:
541
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
542
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
543
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
544
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
545
			if 'posix' in self.options:
546
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
547
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
548
			if 'samba' in self.options:
549
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
550
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
551
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
552
				sambaPwdLastSetValue = str(long(time.time()))
553
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
554
555
		# add samba option
556
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
557
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
558
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
559
			self.alloc.append(('sid', self.machineSid))
560
			ml.append(('sambaSID', '', [self.machineSid]))
561
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
562
			ml.append(('displayName', '', self.info['name']))
563
			sambaPwdLastSetValue = str(long(time.time()))
564
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
565
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
566
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
567
				if self.oldattr.get(key, []):
568
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
569
570
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
571
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
572
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
573
574
		return ml
575
576
	def cleanup(self):
577
		self.open()
578
		self.nagios_cleanup()
579
		univention.admin.handlers.simpleComputer.cleanup(self)
580
581
	def cancel(self):
582
		for i, j in self.alloc:
583
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
584
			univention.admin.allocators.release(self.lo, self.position, i, j)
585
586
587
def rewrite(filter, mapping):
588
	if filter.variable == 'ip':
589
		filter.variable = 'aRecord'
590
	else:
591
		univention.admin.mapping.mapRewrite(filter, mapping)
592
347
593
348
594
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
349
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/memberserver.py (-304 / +15 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from ldap.filter import filter_format
34
35
from univention.admin.layout import Tab, Group
33
from univention.admin.layout import Tab, Group
36
import univention.admin.filter
34
import univention.admin.filter
37
import univention.admin.handlers
35
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
36
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
37
import univention.admin.nagios as nagios
43
import univention.admin.handlers.dns.forward_zone
38
from univention.admin.handlers.computers.base import computerBase
44
import univention.admin.handlers.dns.reverse_zone
45
import univention.admin.handlers.groups.group
46
import univention.admin.handlers.networks.network
47
import time
48
39
49
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
40
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
50
_ = translation.translate
41
_ = translation.translate
 Lines 385-393    Link Here 
385
mapping.register('name', 'cn', None, univention.admin.mapping.ListToString)
376
mapping.register('name', 'cn', None, univention.admin.mapping.ListToString)
386
mapping.register('description', 'description', None, univention.admin.mapping.ListToString)
377
mapping.register('description', 'description', None, univention.admin.mapping.ListToString)
387
mapping.register('domain', 'associatedDomain', None, univention.admin.mapping.ListToString)
378
mapping.register('domain', 'associatedDomain', None, univention.admin.mapping.ListToString)
388
mapping.register('inventoryNumber', 'univentionInventoryNumber')
389
mapping.register('serverRole', 'univentionServerRole')
379
mapping.register('serverRole', 'univentionServerRole')
390
mapping.register('mac', 'macAddress')
380
mapping.register('mac', 'macAddress')
381
mapping.register('inventoryNumber', 'univentionInventoryNumber')
391
mapping.register('reinstall', 'univentionServerReinstall', None, univention.admin.mapping.ListToString)
382
mapping.register('reinstall', 'univentionServerReinstall', None, univention.admin.mapping.ListToString)
392
mapping.register('instprofile', 'univentionServerInstallationProfile', None, univention.admin.mapping.ListToString)
383
mapping.register('instprofile', 'univentionServerInstallationProfile', None, univention.admin.mapping.ListToString)
393
mapping.register('reinstalloption', 'univentionServerInstallationOption', None, univention.admin.mapping.ListToString)
384
mapping.register('reinstalloption', 'univentionServerInstallationOption', None, univention.admin.mapping.ListToString)
 Lines 402-698    Link Here 
402
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
393
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
403
394
404
395
405
class object(univention.admin.handlers.simpleComputer, nagios.Support):
396
class object(computerBase):
406
	module = module
397
	module = module
407
398
	mapping = mapping
408
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
399
	CONFIG_NAME = 'univentionDefaultMemberserverGroup'
409
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
400
	DEFAULT_OCS = ['top', 'person', 'univentionHost', 'univentionMemberServer']
410
		nagios.Support.__init__(self)
401
	SAMBA_ACCOUNT_FLAG = 'W'
411
402
	SERVER_TYPE = 'univentionMemberServer'
412
	def open(self):
403
	SERVER_ROLE = 'member'
413
		univention.admin.handlers.simpleComputer.open(self)
404
414
		self.nagios_open()
405
415
406
rewrite = object.rewrite
416
		self.modifypassword = 0
407
lookup_filter = object.lookup_filter
417
408
lookup = object.lookup
418
		if self.exists():
409
identify = object.identify
419
420
			if 'posix' in self.options and not self.info.get('primaryGroup'):
421
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
422
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
423
				if primaryGroupNumber:
424
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
425
					if primaryGroupResult:
426
						self['primaryGroup'] = primaryGroupResult[0]
427
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
428
					else:
429
						self['primaryGroup'] = None
430
						self.save()
431
						raise univention.admin.uexceptions.primaryGroup
432
				else:
433
					self['primaryGroup'] = None
434
					self.save()
435
					raise univention.admin.uexceptions.primaryGroup
436
			if 'samba' in self.options:
437
				sid = self.oldattr.get('sambaSID', [''])[0]
438
				pos = sid.rfind('-')
439
				self.info['sambaRID'] = sid[pos + 1:]
440
441
		if self.exists():
442
			userPassword = self.oldattr.get('userPassword', [''])[0]
443
			if userPassword:
444
				self.info['password'] = userPassword
445
				self.modifypassword = 0
446
			self.save()
447
448
		else:
449
			self.modifypassword = 0
450
			if 'posix' in self.options:
451
				res = univention.admin.config.getDefaultValue(self.lo, 'univentionDefaultMemberserverGroup', position=self.position)
452
				if res:
453
					self['primaryGroup'] = res
454
					# self.save()
455
456
	def _ldap_pre_create(self):
457
		super(object, self)._ldap_pre_create()
458
		if not self['password']:
459
			self['password'] = self.oldattr.get('password', [''])[0]
460
			self.modifypassword = 0
461
462
	def _ldap_addlist(self):
463
		ocs = ['top', 'person', 'univentionHost', 'univentionMemberServer']
464
		al = []
465
		if 'kerberos' in self.options:
466
			domain = univention.admin.uldap.domain(self.lo, self.position)
467
			realm = domain.getKerberosRealm()
468
469
			if realm:
470
				al.append(('krb5MaxLife', '86400'))
471
				al.append(('krb5MaxRenew', '604800'))
472
				al.append(('krb5KDCFlags', '126'))
473
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
474
				al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
475
			else:
476
				# can't do kerberos
477
				self._remove_option('kerberos')
478
		if 'posix' in self.options:
479
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
480
			self.alloc.append(('uidNumber', self.uidNum))
481
			gidNum = self.get_gid_for_primary_group()
482
			al.append(('uidNumber', [self.uidNum]))
483
			al.append(('gidNumber', [gidNum]))
484
485
		if self.modifypassword or self['password']:
486
			if 'kerberos' in self.options:
487
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
488
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
489
			if 'posix' in self.options:
490
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
491
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
492
			if 'samba' in self.options:
493
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
494
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
495
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
496
				sambaPwdLastSetValue = str(long(time.time()))
497
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
498
			self.modifypassword = 0
499
		if 'samba' in self.options:
500
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
501
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
502
			self.alloc.append(('sid', self.machineSid))
503
			al.append(('sambaSID', [self.machineSid]))
504
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
505
			al.append(('displayName', self.info['name']))
506
507
		al.insert(0, ('objectClass', ocs))
508
		al.append(('univentionServerRole', '', 'member'))
509
		return al
510
511
	def _ldap_post_create(self):
512
		if 'posix' in self.options:
513
			if hasattr(self, 'uid') and self.uid:
514
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
515
			univention.admin.handlers.simpleComputer.primary_group(self)
516
			univention.admin.handlers.simpleComputer.update_groups(self)
517
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
518
		self.nagios_ldap_post_create()
519
520
	def _ldap_pre_remove(self):
521
		self.open()
522
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
523
			self.uidNum = self.oldattr['uidNumber'][0]
524
525
	def _ldap_post_remove(self):
526
		if 'posix' in self.options:
527
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
528
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember=%s', [self.dn]))
529
		if groupObjects:
530
			for i in range(0, len(groupObjects)):
531
				groupObjects[i].open()
532
				if self.dn in groupObjects[i]['users']:
533
					groupObjects[i]['users'].remove(self.dn)
534
					groupObjects[i].modify(ignore_license=1)
535
536
		self.nagios_ldap_post_remove()
537
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
538
		# Need to clean up oldinfo. If remove was invoked, because the
539
		# creation of the object has failed, the next try will result in
540
		# a 'object class violation' (Bug #19343)
541
		self.oldinfo = {}
542
543
	def krb5_principal(self):
544
		domain = univention.admin.uldap.domain(self.lo, self.position)
545
		realm = domain.getKerberosRealm()
546
		if self.info.has_key('domain') and self.info['domain']:
547
			kerberos_domain = self.info['domain']
548
		else:
549
			kerberos_domain = domain.getKerberosRealm()
550
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
551
552
	def _ldap_post_modify(self):
553
		univention.admin.handlers.simpleComputer.primary_group(self)
554
		univention.admin.handlers.simpleComputer.update_groups(self)
555
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
556
		self.nagios_ldap_post_modify()
557
558
	def _ldap_pre_modify(self):
559
		if self.hasChanged('password'):
560
			if not self['password']:
561
				self['password'] = self.oldattr.get('password', [''])[0]
562
				self.modifypassword = 0
563
			elif not self.info['password']:
564
				self['password'] = self.oldattr.get('password', [''])[0]
565
				self.modifypassword = 0
566
			else:
567
				self.modifypassword = 1
568
		self.nagios_ldap_pre_modify()
569
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
570
571
	def _ldap_modlist(self):
572
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
573
574
		self.nagios_ldap_modlist(ml)
575
576
		if self.hasChanged('name'):
577
			if 'posix' in self.options:
578
				if hasattr(self, 'uidNum'):
579
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
580
				requested_uid = "%s$" % self['name']
581
				try:
582
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
583
				except Exception:
584
					self.cancel()
585
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
586
					return []
587
588
				self.alloc.append(('uid', self.uid))
589
590
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
591
592
			if 'samba' in self.options:
593
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
594
595
			if 'kerberos' in self.options:
596
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
597
598
		if self.modifypassword and self['password']:
599
			if 'kerberos' in self.options:
600
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
601
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
602
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
603
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
604
			if 'posix' in self.options:
605
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
606
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
607
			if 'samba' in self.options:
608
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
609
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
610
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
611
				sambaPwdLastSetValue = str(long(time.time()))
612
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
613
614
		# add samba option
615
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
616
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
617
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
618
			self.alloc.append(('sid', self.machineSid))
619
			ml.append(('sambaSID', '', [self.machineSid]))
620
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
621
			ml.append(('displayName', '', self.info['name']))
622
			sambaPwdLastSetValue = str(long(time.time()))
623
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
624
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
625
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
626
				if self.oldattr.get(key, []):
627
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
628
629
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
630
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
631
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
632
633
		return ml
634
635
	def cleanup(self):
636
		self.open()
637
		self.nagios_cleanup()
638
		univention.admin.handlers.simpleComputer.cleanup(self)
639
640
	def cancel(self):
641
		for i, j in self.alloc:
642
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
643
			univention.admin.allocators.release(self.lo, self.position, i, j)
644
645
	def link(self):
646
		result = []
647
		if self['ip'] and len(self['ip']) > 0 and self['ip'][0]:
648
			result = [{'url': 'https://%s/univention-management-console/' % self['ip'][0], 'ipaddr': self['ip'][0], }]
649
		if self.has_key('dnsEntryZoneForward') and self['dnsEntryZoneForward'] and len(self['dnsEntryZoneForward']) > 0:
650
			zone = univention.admin.uldap.explodeDn(self['dnsEntryZoneForward'][0], 1)[0]
651
			if not result:
652
				result = [{'url': 'https://%s.%s/univention-management-console/' % (self['name'], zone)}]
653
			result[0]['fqdn'] = '%s.%s' % (self['name'], zone)
654
		if result:
655
			result[0]['name'] = _('Open Univention Management Console on this computer')
656
			return result
657
		return None
658
659
660
def rewrite(filter, mapping):
661
	if filter.variable == 'ip':
662
		filter.variable = 'aRecord'
663
	else:
664
		univention.admin.mapping.mapRewrite(filter, mapping)
665
666
667
def lookup_filter(filter_s=None, lo=None):
668
	filter_s = univention.admin.filter.replace_fqdn_filter(filter_s)
669
	if str(filter_s).find('(dnsAlias=') != -1:
670
		filter_s = univention.admin.handlers.dns.alias.lookup_alias_filter(lo, filter_s)
671
		if filter_s:
672
			return lookup_filter(filter_s, lo)
673
		else:
674
			return None
675
	lookup_filter_obj = \
676
		univention.admin.filter.conjunction('&', [
677
			univention.admin.filter.expression('objectClass', 'univentionHost'),
678
			univention.admin.filter.expression('objectClass', 'univentionMemberServer'),
679
		])
680
681
	# ATTENTION: has its own rewrite function.
682
	lookup_filter_obj.append_unmapped_filter_string(filter_s, rewrite, mapping)
683
	return lookup_filter_obj
684
685
686
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
687
688
	filter = lookup_filter(filter_s, lo)
689
	if filter is None:
690
		return []
691
	res = []
692
	for dn, attrs in lo.search(unicode(filter), base, scope, [], unique, required, timeout, sizelimit):
693
		res.append(object(co, lo, None, dn, attributes=attrs))
694
	return res
695
696
697
def identify(dn, attr, canonical=0):
698
	return 'univentionHost' in attr.get('objectClass', []) and 'univentionMemberServer' in attr.get('objectClass', [])
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/ubuntu.py (-254 / +11 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from ldap.filter import filter_format
34
35
from univention.admin.layout import Tab, Group
33
from univention.admin.layout import Tab, Group
36
import univention.admin.filter
34
import univention.admin.filter
37
import univention.admin.handlers
35
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
36
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
37
import univention.admin.nagios as nagios
43
import univention.admin.handlers.dns.forward_zone
38
from univention.admin.handlers.computers.base import computerBase
44
import univention.admin.handlers.dns.reverse_zone
45
import univention.admin.handlers.groups.group
46
import univention.admin.handlers.networks.network
47
import time
48
39
49
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
40
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
50
_ = translation.translate
41
_ = translation.translate
 Lines 340-594    Link Here 
340
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
331
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
341
332
342
333
343
class object(univention.admin.handlers.simpleComputer, nagios.Support):
334
class object(computerBase):
344
	module = module
335
	module = module
336
	mapping = mapping
337
	CONFIG_NAME = 'univentionDefaultClientGroup'
338
	DEFAULT_OCS = ['top', 'person', 'univentionHost', 'univentionUbuntuClient']
339
	SAMBA_ACCOUNT_FLAG = 'W'
340
	SERVER_TYPE = 'univentionUbuntuClient'
345
341
346
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
342
	def check_required_options(self):
347
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
348
		nagios.Support.__init__(self)
349
350
	def open(self):
351
		global options
352
		univention.admin.handlers.simpleComputer.open(self)
353
		self.nagios_open()
354
355
		self.modifypassword = 0
356
357
		if self.exists():
358
359
			if 'posix' in self.options and not self.info.get('primaryGroup'):
360
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
361
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
362
				if primaryGroupNumber:
363
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
364
					if primaryGroupResult:
365
						self['primaryGroup'] = primaryGroupResult[0]
366
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
367
					else:
368
						self['primaryGroup'] = None
369
						self.save()
370
						raise univention.admin.uexceptions.primaryGroup
371
				else:
372
					self['primaryGroup'] = None
373
					self.save()
374
					raise univention.admin.uexceptions.primaryGroup
375
			if 'samba' in self.options:
376
				sid = self.oldattr.get('sambaSID', [''])[0]
377
				pos = sid.rfind('-')
378
				self.info['sambaRID'] = sid[pos + 1:]
379
380
		if self.exists():
381
			userPassword = self.oldattr.get('userPassword', [''])[0]
382
			if userPassword:
383
				self.info['password'] = userPassword
384
				self.modifypassword = 0
385
			self.save()
386
387
		else:
388
			self.modifypassword = 0
389
			if 'posix' in self.options:
390
				res = univention.admin.config.getDefaultValue(self.lo, 'univentionDefaultClientGroup', position=self.position)
391
				if res:
392
					self['primaryGroup'] = res
393
394
	def _ldap_pre_create(self):
395
		super(object, self)._ldap_pre_create()
396
		if not self['password']:
397
			self['password'] = self.oldattr.get('password', [''])[0]
398
			self.modifypassword = 0
399
400
	def _ldap_addlist(self):
401
		if not set(self.options) & set(['posix', 'kerberos']):
343
		if not set(self.options) & set(['posix', 'kerberos']):
402
			raise univention.admin.uexceptions.invalidOptions(_(' At least posix or kerberos is required.'))
344
			raise univention.admin.uexceptions.invalidOptions(_('At least posix or kerberos is required.'))
403
404
		ocs = ['top', 'person', 'univentionHost', 'univentionUbuntuClient']
405
		al = []
406
		if 'kerberos' in self.options:
407
			domain = univention.admin.uldap.domain(self.lo, self.position)
408
			realm = domain.getKerberosRealm()
409
410
			if realm:
411
				al.append(('krb5MaxLife', '86400'))
412
				al.append(('krb5MaxRenew', '604800'))
413
				al.append(('krb5KDCFlags', '126'))
414
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
415
				al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
416
			else:
417
				# can't do kerberos
418
				self._remove_option('kerberos')
419
		if 'posix' in self.options:
420
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
421
			self.alloc.append(('uidNumber', self.uidNum))
422
			gidNum = self.get_gid_for_primary_group()
423
			al.append(('uidNumber', [self.uidNum]))
424
			al.append(('gidNumber', [gidNum]))
425
426
		if self.modifypassword or self['password']:
427
			if 'kerberos' in self.options:
428
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
429
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
430
			if 'posix' in self.options:
431
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
432
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
433
			if 'samba' in self.options:
434
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
435
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
436
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
437
				sambaPwdLastSetValue = str(long(time.time()))
438
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
439
			self.modifypassword = 0
440
		if 'samba' in self.options:
441
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
442
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
443
			self.alloc.append(('sid', self.machineSid))
444
			al.append(('sambaSID', [self.machineSid]))
445
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
446
			al.append(('displayName', self.info['name']))
447
448
		al.insert(0, ('objectClass', ocs))
449
450
		return al
451
452
	def _ldap_post_create(self):
453
		if 'posix' in self.options:
454
			if hasattr(self, 'uid') and self.uid:
455
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
456
			univention.admin.handlers.simpleComputer.primary_group(self)
457
			univention.admin.handlers.simpleComputer.update_groups(self)
458
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
459
		self.nagios_ldap_post_create()
460
461
	def _ldap_pre_remove(self):
462
		self.open()
463
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
464
			self.uidNum = self.oldattr['uidNumber'][0]
465
466
	def _ldap_post_remove(self):
467
		if 'posix' in self.options:
468
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
469
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember=%s', [self.dn]))
470
		if groupObjects:
471
			for i in range(0, len(groupObjects)):
472
				groupObjects[i].open()
473
				if self.dn in groupObjects[i]['users']:
474
					groupObjects[i]['users'].remove(self.dn)
475
					groupObjects[i].modify(ignore_license=1)
476
477
		self.nagios_ldap_post_remove()
478
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
479
		# Need to clean up oldinfo. If remove was invoked, because the
480
		# creation of the object has failed, the next try will result in
481
		# a 'object class violation' (Bug #19343)
482
		self.oldinfo = {}
483
345
484
	def krb5_principal(self):
485
		domain = univention.admin.uldap.domain(self.lo, self.position)
486
		realm = domain.getKerberosRealm()
487
		if self.info.has_key('domain') and self.info['domain']:
488
			kerberos_domain = self.info['domain']
489
		else:
490
			kerberos_domain = domain.getKerberosRealm()
491
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
492
346
493
	def _ldap_post_modify(self):
347
del object.link
494
		univention.admin.handlers.simpleComputer.primary_group(self)
348
rewrite = object.rewrite
495
		univention.admin.handlers.simpleComputer.update_groups(self)
496
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
497
		self.nagios_ldap_post_modify()
498
499
	def _ldap_pre_modify(self):
500
		if self.hasChanged('password'):
501
			if not self['password']:
502
				self['password'] = self.oldattr.get('password', [''])[0]
503
				self.modifypassword = 0
504
			elif not self.info['password']:
505
				self['password'] = self.oldattr.get('password', [''])[0]
506
				self.modifypassword = 0
507
			else:
508
				self.modifypassword = 1
509
		self.nagios_ldap_pre_modify()
510
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
511
512
	def _ldap_modlist(self):
513
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
514
515
		self.nagios_ldap_modlist(ml)
516
517
		if self.hasChanged('name'):
518
			if 'posix' in self.options:
519
				if hasattr(self, 'uidNum'):
520
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
521
				requested_uid = "%s$" % self['name']
522
				try:
523
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
524
				except Exception:
525
					self.cancel()
526
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
527
					return []
528
529
				self.alloc.append(('uid', self.uid))
530
531
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
532
533
			if 'samba' in self.options:
534
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
535
536
			if 'kerberos' in self.options:
537
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
538
539
		if self.modifypassword and self['password']:
540
			if 'kerberos' in self.options:
541
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
542
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
543
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
544
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
545
			if 'posix' in self.options:
546
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
547
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
548
			if 'samba' in self.options:
549
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
550
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
551
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
552
				sambaPwdLastSetValue = str(long(time.time()))
553
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
554
555
		# add samba option
556
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
557
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
558
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
559
			self.alloc.append(('sid', self.machineSid))
560
			ml.append(('sambaSID', '', [self.machineSid]))
561
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
562
			ml.append(('displayName', '', self.info['name']))
563
			sambaPwdLastSetValue = str(long(time.time()))
564
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
565
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
566
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
567
				if self.oldattr.get(key, []):
568
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
569
570
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
571
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
572
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
573
574
		return ml
575
576
	def cleanup(self):
577
		self.open()
578
		self.nagios_cleanup()
579
		univention.admin.handlers.simpleComputer.cleanup(self)
580
581
	def cancel(self):
582
		for i, j in self.alloc:
583
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
584
			univention.admin.allocators.release(self.lo, self.position, i, j)
585
586
587
def rewrite(filter, mapping):
588
	if filter.variable == 'ip':
589
		filter.variable = 'aRecord'
590
	else:
591
		univention.admin.mapping.mapRewrite(filter, mapping)
592
349
593
350
594
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
351
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/windows.py (-261 / +13 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from ldap.filter import filter_format
34
35
from univention.admin.layout import Tab, Group
33
from univention.admin.layout import Tab, Group
36
import univention.admin.filter
34
import univention.admin.filter
37
import univention.admin.handlers
35
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
36
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
37
import univention.admin.nagios as nagios
43
import univention.admin.handlers.dns.forward_zone
38
from univention.admin.handlers.computers.base import computerBase
44
import univention.admin.handlers.dns.reverse_zone
45
import univention.admin.handlers.groups.group
46
import univention.admin.handlers.networks.network
47
import time
48
39
49
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
40
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
50
_ = translation.translate
41
_ = translation.translate
 Lines 342-618    Link Here 
342
mapping = univention.admin.mapping.mapping()
333
mapping = univention.admin.mapping.mapping()
343
mapping.register('name', 'cn', None, univention.admin.mapping.ListToString)
334
mapping.register('name', 'cn', None, univention.admin.mapping.ListToString)
344
mapping.register('description', 'description', None, univention.admin.mapping.ListToString)
335
mapping.register('description', 'description', None, univention.admin.mapping.ListToString)
345
mapping.register('operatingSystem', 'univentionOperatingSystem', None, univention.admin.mapping.ListToString)
346
mapping.register('operatingSystemVersion', 'univentionOperatingSystemVersion', None, univention.admin.mapping.ListToString)
347
mapping.register('domain', 'associatedDomain', None, univention.admin.mapping.ListToString)
336
mapping.register('domain', 'associatedDomain', None, univention.admin.mapping.ListToString)
348
mapping.register('inventoryNumber', 'univentionInventoryNumber')
337
mapping.register('inventoryNumber', 'univentionInventoryNumber')
349
mapping.register('mac', 'macAddress')
338
mapping.register('mac', 'macAddress')
350
mapping.register('network', 'univentionNetworkLink', None, univention.admin.mapping.ListToString)
339
mapping.register('network', 'univentionNetworkLink', None, univention.admin.mapping.ListToString)
351
mapping.register('unixhome', 'homeDirectory', None, univention.admin.mapping.ListToString)
340
mapping.register('unixhome', 'homeDirectory', None, univention.admin.mapping.ListToString)
352
mapping.register('shell', 'loginShell', None, univention.admin.mapping.ListToString)
341
mapping.register('shell', 'loginShell', None, univention.admin.mapping.ListToString)
342
mapping.register('operatingSystem', 'univentionOperatingSystem', None, univention.admin.mapping.ListToString)
343
mapping.register('operatingSystemVersion', 'univentionOperatingSystemVersion', None, univention.admin.mapping.ListToString)
353
344
354
# add Nagios extension
345
# add Nagios extension
355
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
346
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
356
347
357
348
358
class object(univention.admin.handlers.simpleComputer, nagios.Support):
349
class object(computerBase):
359
	module = module
350
	module = module
360
351
	mapping = mapping
361
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
352
	CONFIG_NAME = 'computerGroup'
362
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
353
	DEFAULT_OCS = ['top', 'person', 'univentionHost', 'univentionWindows']
363
		nagios.Support.__init__(self)
354
	SAMBA_ACCOUNT_FLAG = 'W'
364
355
	SERVER_TYPE = 'univentionWindows'
365
	def open(self):
356
	SERVER_ROLE = 'windows_client'
366
		univention.admin.handlers.simpleComputer.open(self)
367
		self.nagios_open()
368
369
		self.modifypassword = 0
370
		if self.exists():
371
			userPassword = self.oldattr.get('userPassword', [''])[0]
372
			if userPassword:
373
				self.info['password'] = userPassword
374
				self.modifypassword = 0
375
376
		if self.exists():
377
378
			if 'posix' in self.options and not self.info.get('primaryGroup'):
379
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
380
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
381
				if primaryGroupNumber:
382
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
383
					if primaryGroupResult:
384
						self['primaryGroup'] = primaryGroupResult[0]
385
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
386
					else:
387
						self['primaryGroup'] = None
388
						self.save()
389
						raise univention.admin.uexceptions.primaryGroup
390
				else:
391
					self['primaryGroup'] = None
392
					self.save()
393
					raise univention.admin.uexceptions.primaryGroup
394
			if 'samba' in self.options:
395
				sid = self.oldattr.get('sambaSID', [''])[0]
396
				pos = sid.rfind('-')
397
				self.info['sambaRID'] = sid[pos + 1:]
398
399
			self.save()
400
401
		else:
402
			self.modifypassword = 0
403
			if 'posix' in self.options:
404
				res = univention.admin.config.getDefaultValue(self.lo, 'computerGroup', position=self.position)
405
				if res:
406
					self['primaryGroup'] = res
407
					# self.save()
408
409
	def _ldap_pre_create(self):
410
		super(object, self)._ldap_pre_create()
411
		if not self['password']:
412
			self['password'] = self.oldattr.get('password', [''])[0]
413
			self.modifypassword = 0
414
415
	def _ldap_addlist(self):
416
		ocs = ['top', 'person', 'univentionHost', 'univentionWindows']
417
		al = []
418
		if 'kerberos' in self.options:
419
			domain = univention.admin.uldap.domain(self.lo, self.position)
420
			realm = domain.getKerberosRealm()
421
422
			if realm:
423
				ocs.extend(['krb5Principal', 'krb5KDCEntry'])
424
				al.append(('krb5MaxLife', '86400'))
425
				al.append(('krb5MaxRenew', '604800'))
426
				al.append(('krb5KDCFlags', '126'))
427
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
428
				al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
429
			else:
430
				# can't do kerberos
431
				self._remove_option('kerberos')
432
		if 'posix' in self.options:
433
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
434
			self.alloc.append(('uidNumber', self.uidNum))
435
			gidNum = self.get_gid_for_primary_group()
436
			ocs.extend(['posixAccount', 'shadowAccount'])
437
			al.append(('uidNumber', [self.uidNum]))
438
			al.append(('gidNumber', [gidNum]))
439
440
		if self.modifypassword or self['password']:
441
			if 'kerberos' in self.options:
442
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
443
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
444
			if 'posix' in self.options:
445
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
446
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
447
			if 'samba' in self.options:
448
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
449
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
450
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
451
				sambaPwdLastSetValue = str(long(time.time()))
452
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
453
			self.modifypassword = 0
454
		if 'samba' in self.options:
455
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
456
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
457
			self.alloc.append(('sid', self.machineSid))
458
			ocs.append('sambaSamAccount')
459
			al.append(('sambaSID', [self.machineSid]))
460
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
461
			al.append(('displayName', self.info['name']))
462
463
		al.insert(0, ('objectClass', ocs))
464
		# new since UCS 3.0, old Windows clients don't have this attribute
465
		al.append(('univentionServerRole', '', 'windows_client'))
466
		return al
467
468
	def _ldap_post_create(self):
469
		if 'posix' in self.options:
470
			if hasattr(self, 'uid') and self.uid:
471
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
472
			univention.admin.handlers.simpleComputer.primary_group(self)
473
			univention.admin.handlers.simpleComputer.update_groups(self)
474
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
475
		self.nagios_ldap_post_create()
476
477
	def _ldap_pre_remove(self):
478
		self.open()
479
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
480
			self.uidNum = self.oldattr['uidNumber'][0]
481
482
	def _ldap_post_remove(self):
483
		if 'posix' in self.options:
484
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
485
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember=%s', [self.dn]))
486
		if groupObjects:
487
			for i in range(0, len(groupObjects)):
488
				groupObjects[i].open()
489
				if self.dn in groupObjects[i]['users']:
490
					groupObjects[i]['users'].remove(self.dn)
491
					groupObjects[i].modify(ignore_license=1)
492
493
		self.nagios_ldap_post_remove()
494
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
495
		# Need to clean up oldinfo. If remove was invoked, because the
496
		# creation of the object has failed, the next try will result in
497
		# a 'object class violation' (Bug #19343)
498
		self.oldinfo = {}
499
500
	def krb5_principal(self):
501
		domain = univention.admin.uldap.domain(self.lo, self.position)
502
		realm = domain.getKerberosRealm()
503
		if self.info.has_key('domain') and self.info['domain']:
504
			kerberos_domain = self.info['domain']
505
		else:
506
			kerberos_domain = domain.getKerberosRealm()
507
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
508
509
	def _ldap_post_modify(self):
510
		univention.admin.handlers.simpleComputer.primary_group(self)
511
		univention.admin.handlers.simpleComputer.update_groups(self)
512
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
513
		self.nagios_ldap_post_modify()
514
515
	def _ldap_pre_modify(self):
516
		if self.hasChanged('password'):
517
			if not self['password']:
518
				self['password'] = self.oldattr.get('password', [''])[0]
519
				self.modifypassword = 0
520
			elif not self.info['password']:
521
				self['password'] = self.oldattr.get('password', [''])[0]
522
				self.modifypassword = 0
523
			else:
524
				self.modifypassword = 1
525
		self.nagios_ldap_pre_modify()
526
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
527
357
528
	def _ldap_modlist(self):
358
	def _ldap_modlist(self):
529
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
359
		ml = super(object, self)._ldap_modlist()
530
531
		self.nagios_ldap_modlist(ml)
532
533
		if self.hasChanged('ntCompatibility') and self['ntCompatibility'] == '1':
360
		if self.hasChanged('ntCompatibility') and self['ntCompatibility'] == '1':
534
			self['password'] = self['name'].replace('$', '').lower()
361
			self['password'] = self['name'].replace('$', '').lower()
535
			self.modifypassword = 1
362
			self.modifypassword = 1
536
537
		if self.hasChanged('name'):
538
			if 'posix' in self.options:
539
				if hasattr(self, 'uidNum'):
540
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
541
				requested_uid = "%s$" % self['name']
542
				try:
543
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
544
				except Exception:
545
					self.cancel()
546
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
547
					return []
548
549
				self.alloc.append(('uid', self.uid))
550
551
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
552
553
			if 'samba' in self.options:
554
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
555
556
			if 'kerberos' in self.options:
557
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
558
559
		if self.modifypassword and self['password']:
560
			if 'kerberos' in self.options:
561
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
562
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
563
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
564
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
565
			if 'posix' in self.options:
566
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
567
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
568
			if 'samba' in self.options:
569
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
570
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
571
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
572
				sambaPwdLastSetValue = str(long(time.time()))
573
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
574
575
		# add samba option
576
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
577
			acctFlags = univention.admin.samba.acctFlags(flags={'W': 1})
578
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
579
			self.alloc.append(('sid', self.machineSid))
580
			ml.insert(0, ('objectClass', '', 'sambaSamAccount'))
581
			ml.append(('sambaSID', '', [self.machineSid]))
582
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
583
			ml.append(('displayName', '', self.info['name']))
584
			sambaPwdLastSetValue = str(long(time.time()))
585
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
586
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
587
			ocs = self.oldattr.get('objectClass', [])
588
			if 'sambaSamAccount' in ocs:
589
				ml.insert(0, ('objectClass', 'sambaSamAccount', ''))
590
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
591
				if self.oldattr.get(key, []):
592
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
593
594
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
595
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
596
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
597
598
		return ml
363
		return ml
599
364
600
	def cleanup(self):
601
		self.open()
602
		self.nagios_cleanup()
603
		univention.admin.handlers.simpleComputer.cleanup(self)
604
605
	def cancel(self):
606
		for i, j in self.alloc:
607
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
608
			univention.admin.allocators.release(self.lo, self.position, i, j)
609
365
610
366
del object.link
611
def rewrite(filter, mapping):
367
rewrite = object.rewrite
612
	if filter.variable == 'ip':
613
		filter.variable = 'aRecord'
614
	else:
615
		univention.admin.mapping.mapRewrite(filter, mapping)
616
368
617
369
618
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
370
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
(-)a/management/univention-directory-manager-modules/modules/univention/admin/handlers/computers/windows_domaincontroller.py (-259 / +10 lines)
 Lines 30-50    Link Here 
30
# /usr/share/common-licenses/AGPL-3; if not, see
30
# /usr/share/common-licenses/AGPL-3; if not, see
31
# <http://www.gnu.org/licenses/>.
31
# <http://www.gnu.org/licenses/>.
32
32
33
from ldap.filter import filter_format
34
35
from univention.admin.layout import Tab, Group
33
from univention.admin.layout import Tab, Group
36
import univention.admin.filter
34
import univention.admin.filter
37
import univention.admin.handlers
35
import univention.admin.handlers
38
import univention.admin.password
39
import univention.admin.allocators
40
import univention.admin.localization
36
import univention.admin.localization
41
import univention.admin.uldap
42
import univention.admin.nagios as nagios
37
import univention.admin.nagios as nagios
43
import univention.admin.handlers.dns.forward_zone
38
from univention.admin.handlers.computers.base import computerBase
44
import univention.admin.handlers.dns.reverse_zone
45
import univention.admin.handlers.groups.group
46
import univention.admin.handlers.networks.network
47
import time
48
39
49
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
40
translation = univention.admin.localization.translation('univention.admin.handlers.computers')
50
_ = translation.translate
41
_ = translation.translate
 Lines 364-617    Link Here 
364
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
355
nagios.addPropertiesMappingOptionsAndLayout(property_descriptions, mapping, options, layout)
365
356
366
357
367
class object(univention.admin.handlers.simpleComputer, nagios.Support):
358
class object(computerBase):
368
	module = module
359
	module = module
360
	mapping = mapping
361
	CONFIG_NAME = 'univentionDefaultDomainControllerGroup'
362
	DEFAULT_OCS = ['top', 'person', 'univentionHost', 'univentionWindows']
363
	SAMBA_ACCOUNT_FLAG = 'S'
364
	SERVER_TYPE = 'univentionWindows'
365
	SERVER_ROLE = 'windows_domaincontroller'
369
366
370
	def __init__(self, co, lo, position, dn='', superordinate=None, attributes=[]):
371
		univention.admin.handlers.simpleComputer.__init__(self, co, lo, position, dn, superordinate, attributes)
372
		nagios.Support.__init__(self)
373
374
	def open(self):
375
		univention.admin.handlers.simpleComputer.open(self)
376
		self.nagios_open()
377
378
		self.modifypassword = 0
379
		if self.exists():
380
			userPassword = self.oldattr.get('userPassword', [''])[0]
381
			if userPassword:
382
				self.info['password'] = userPassword
383
				self.modifypassword = 0
384
385
		if self.exists():
386
387
			if 'posix' in self.options and not self.info.get('primaryGroup'):
388
				primaryGroupNumber = self.oldattr.get('gidNumber', [''])[0]
389
				univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'primary group number = %s' % (primaryGroupNumber))
390
				if primaryGroupNumber:
391
					primaryGroupResult = self.lo.searchDn(filter_format('(&(objectClass=posixGroup)(gidNumber=%s))', [primaryGroupNumber]))
392
					if primaryGroupResult:
393
						self['primaryGroup'] = primaryGroupResult[0]
394
						univention.debug.debug(univention.debug.ADMIN, univention.debug.INFO, 'Set primary group = %s' % (self['primaryGroup']))
395
					else:
396
						self['primaryGroup'] = None
397
						self.save()
398
						raise univention.admin.uexceptions.primaryGroup
399
				else:
400
					self['primaryGroup'] = None
401
					self.save()
402
					raise univention.admin.uexceptions.primaryGroup
403
			if 'samba' in self.options:
404
				sid = self.oldattr.get('sambaSID', [''])[0]
405
				pos = sid.rfind('-')
406
				self.info['sambaRID'] = sid[pos + 1:]
407
408
			self.save()
409
410
		else:
411
			self.modifypassword = 0
412
			if 'posix' in self.options:
413
				res = univention.admin.config.getDefaultValue(self.lo, 'univentionDefaultDomainControllerGroup', position=self.position)
414
				if res:
415
					self['primaryGroup'] = res
416
					# self.save()
417
418
	def _ldap_pre_create(self):
419
		super(object, self)._ldap_pre_create()
420
		if not self['password']:
421
			self['password'] = self.oldattr.get('password', [''])[0]
422
			self.modifypassword = 0
423
424
	def _ldap_addlist(self):
425
		ocs = ['top', 'person', 'univentionHost', 'univentionWindows']
426
		al = []
427
		if 'kerberos' in self.options:
428
429
			ocs.extend(['krb5Principal', 'krb5KDCEntry'])
430
			al.append(('krb5MaxLife', '86400'))
431
			al.append(('krb5MaxRenew', '604800'))
432
			al.append(('krb5KDCFlags', '126'))
433
			krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
434
			al.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
435
436
		if 'posix' in self.options:
437
			self.uidNum = univention.admin.allocators.request(self.lo, self.position, 'uidNumber')
438
			self.alloc.append(('uidNumber', self.uidNum))
439
			gidNum = self.get_gid_for_primary_group()
440
			ocs.extend(['posixAccount', 'shadowAccount'])
441
			al.append(('uidNumber', [self.uidNum]))
442
			al.append(('gidNumber', [gidNum]))
443
444
		if self.modifypassword or self['password']:
445
			if 'kerberos' in self.options:
446
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
447
				al.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
448
			if 'posix' in self.options:
449
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
450
				al.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
451
			if 'samba' in self.options:
452
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
453
				al.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
454
				al.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
455
				sambaPwdLastSetValue = str(long(time.time()))
456
				al.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
457
			self.modifypassword = 0
458
		if 'samba' in self.options:
459
			acctFlags = univention.admin.samba.acctFlags(flags={'S': 1})
460
			self.machineSid = self.getMachineSid(self.lo, self.position, self.uidNum, self.get('sambaRID'))
461
			self.alloc.append(('sid', self.machineSid))
462
			ocs.append('sambaSamAccount')
463
			al.append(('sambaSID', [self.machineSid]))
464
			al.append(('sambaAcctFlags', [acctFlags.decode()]))
465
			al.append(('displayName', self.info['name']))
466
467
		al.insert(0, ('objectClass', ocs))
468
		al.append(('univentionServerRole', '', 'windows_domaincontroller'))
469
		return al
470
471
	def _ldap_post_create(self):
472
		if 'posix' in self.options:
473
			if hasattr(self, 'uid') and self.uid:
474
				univention.admin.allocators.confirm(self.lo, self.position, 'uid', self.uid)
475
			univention.admin.handlers.simpleComputer.primary_group(self)
476
			univention.admin.handlers.simpleComputer.update_groups(self)
477
		univention.admin.handlers.simpleComputer._ldap_post_create(self)
478
		self.nagios_ldap_post_create()
479
480
	def _ldap_pre_remove(self):
481
		self.open()
482
		if 'posix' in self.options and self.oldattr.get('uidNumber'):
483
			self.uidNum = self.oldattr['uidNumber'][0]
484
485
	def _ldap_post_remove(self):
486
		if 'posix' in self.options:
487
			univention.admin.allocators.release(self.lo, self.position, 'uidNumber', self.uidNum)
488
		groupObjects = univention.admin.handlers.groups.group.lookup(self.co, self.lo, filter_s=filter_format('uniqueMember=%s', [self.dn]))
489
		if groupObjects:
490
			for i in range(0, len(groupObjects)):
491
				groupObjects[i].open()
492
				if self.dn in groupObjects[i]['users']:
493
					groupObjects[i]['users'].remove(self.dn)
494
					groupObjects[i].modify(ignore_license=1)
495
496
		self.nagios_ldap_post_remove()
497
		univention.admin.handlers.simpleComputer._ldap_post_remove(self)
498
		# Need to clean up oldinfo. If remove was invoked, because the
499
		# creation of the object has failed, the next try will result in
500
		# a 'object class violation' (Bug #19343)
501
		self.oldinfo = {}
502
503
	def krb5_principal(self):
504
		domain = univention.admin.uldap.domain(self.lo, self.position)
505
		realm = domain.getKerberosRealm()
506
		if self.info.has_key('domain') and self.info['domain']:
507
			kerberos_domain = self.info['domain']
508
		else:
509
			kerberos_domain = domain.getKerberosRealm()
510
		return 'host/' + self['name'] + '.' + kerberos_domain.lower() + '@' + realm
511
512
	def _ldap_post_modify(self):
513
		univention.admin.handlers.simpleComputer.primary_group(self)
514
		univention.admin.handlers.simpleComputer.update_groups(self)
515
		univention.admin.handlers.simpleComputer._ldap_post_modify(self)
516
		self.nagios_ldap_post_modify()
517
367
518
	def _ldap_pre_modify(self):
368
rewrite = object.rewrite
519
		if self.hasChanged('password'):
369
identify = object.identify
520
			if not self['password']:
521
				self['password'] = self.oldattr.get('password', [''])[0]
522
				self.modifypassword = 0
523
			elif not self.info['password']:
524
				self['password'] = self.oldattr.get('password', [''])[0]
525
				self.modifypassword = 0
526
			else:
527
				self.modifypassword = 1
528
		self.nagios_ldap_pre_modify()
529
		univention.admin.handlers.simpleComputer._ldap_pre_modify(self)
530
531
	def _ldap_modlist(self):
532
		ml = univention.admin.handlers.simpleComputer._ldap_modlist(self)
533
534
		self.nagios_ldap_modlist(ml)
535
536
		if self.hasChanged('name'):
537
			if 'posix' in self.options:
538
				if hasattr(self, 'uidNum'):
539
					univention.admin.allocators.confirm(self.lo, self.position, 'uidNumber', self.uidNum)
540
				requested_uid = "%s$" % self['name']
541
				try:
542
					self.uid = univention.admin.allocators.request(self.lo, self.position, 'uid', value=requested_uid)
543
				except Exception:
544
					self.cancel()
545
					raise univention.admin.uexceptions.uidAlreadyUsed(': %s' % requested_uid)
546
					return []
547
548
				self.alloc.append(('uid', self.uid))
549
550
				ml.append(('uid', self.oldattr.get('uid', [None])[0], self.uid))
551
552
			if 'samba' in self.options:
553
				ml.append(('displayName', self.oldattr.get('displayName', [None])[0], self['name']))
554
555
			if 'kerberos' in self.options:
556
				ml.append(('krb5PrincipalName', self.oldattr.get('krb5PrincipalName', []), [self.krb5_principal()]))
557
558
		if self.modifypassword and self['password']:
559
			if 'kerberos' in self.options:
560
				krb_keys = univention.admin.password.krb5_asn1(self.krb5_principal(), self['password'])
561
				krb_key_version = str(int(self.oldattr.get('krb5KeyVersionNumber', ['0'])[0]) + 1)
562
				ml.append(('krb5Key', self.oldattr.get('password', ['1']), krb_keys))
563
				ml.append(('krb5KeyVersionNumber', self.oldattr.get('krb5KeyVersionNumber', []), krb_key_version))
564
			if 'posix' in self.options:
565
				password_crypt = "{crypt}%s" % (univention.admin.password.crypt(self['password']))
566
				ml.append(('userPassword', self.oldattr.get('userPassword', [''])[0], password_crypt))
567
			if 'samba' in self.options:
568
				password_nt, password_lm = univention.admin.password.ntlm(self['password'])
569
				ml.append(('sambaNTPassword', self.oldattr.get('sambaNTPassword', [''])[0], password_nt))
570
				ml.append(('sambaLMPassword', self.oldattr.get('sambaLMPassword', [''])[0], password_lm))
571
				sambaPwdLastSetValue = str(long(time.time()))
572
				ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
573
574
		# add samba option
575
		if self.exists() and self.option_toggled('samba') and 'samba' in self.options:
576
			acctFlags = univention.admin.samba.acctFlags(flags={'S': 1})
577
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
578
			self.alloc.append(('sid', self.machineSid))
579
			ml.insert(0, ('objectClass', '', 'sambaSamAccount'))
580
			ml.append(('sambaSID', '', [self.machineSid]))
581
			ml.append(('sambaAcctFlags', '', [acctFlags.decode()]))
582
			ml.append(('displayName', '', self.info['name']))
583
			sambaPwdLastSetValue = str(long(time.time()))
584
			ml.append(('sambaPwdLastSet', self.oldattr.get('sambaPwdLastSet', [''])[0], sambaPwdLastSetValue))
585
		if self.exists() and self.option_toggled('samba') and 'samba' not in self.options:
586
			ocs = self.oldattr.get('objectClass', [])
587
			if 'sambaSamAccount' in ocs:
588
				ml.insert(0, ('objectClass', 'sambaSamAccount', ''))
589
			for key in ['sambaSID', 'sambaAcctFlags', 'sambaNTPassword', 'sambaLMPassword', 'sambaPwdLastSet', 'displayName']:
590
				if self.oldattr.get(key, []):
591
					ml.insert(0, (key, self.oldattr.get(key, []), ''))
592
593
		if self.hasChanged('sambaRID') and not hasattr(self, 'machineSid'):
594
			self.machineSid = self.getMachineSid(self.lo, self.position, self.oldattr['uidNumber'][0], self.get('sambaRID'))
595
			ml.append(('sambaSID', self.oldattr.get('sambaSID', ['']), [self.machineSid]))
596
597
		return ml
598
599
	def cleanup(self):
600
		self.open()
601
		self.nagios_cleanup()
602
		univention.admin.handlers.simpleComputer.cleanup(self)
603
604
	def cancel(self):
605
		for i, j in self.alloc:
606
			univention.debug.debug(univention.debug.ADMIN, univention.debug.WARN, 'cancel: release (%s): %s' % (i, j))
607
			univention.admin.allocators.release(self.lo, self.position, i, j)
608
609
610
def rewrite(filter, mapping):
611
	if filter.variable == 'ip':
612
		filter.variable = 'aRecord'
613
	else:
614
		univention.admin.mapping.mapRewrite(filter, mapping)
615
370
616
371
617
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
372
def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=False, required=False, timeout=-1, sizelimit=0):
 Lines 637-643   def lookup(co, lo, filter_s, base='', superordinate=None, scope='sub', unique=Fa Link Here 
637
		for dn, attrs in lo.search(unicode(filter), base, scope, [], unique, required, timeout, sizelimit):
392
		for dn, attrs in lo.search(unicode(filter), base, scope, [], unique, required, timeout, sizelimit):
638
			res.append(object(co, lo, None, dn, attributes=attrs))
393
			res.append(object(co, lo, None, dn, attributes=attrs))
639
	return res
394
	return res
640
641
642
def identify(dn, attr, canonical=0):
643
	return 'univentionHost' in attr.get('objectClass', []) and 'univentionWindows' in attr.get('objectClass', []) and 'windows_domaincontroller' in attr.get('univentionServerRole', [])

Return to bug 41659