|
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 |
|
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) |
|
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', []) |