Lines 68-126
if listener.baseConfig['ldap/server/type'] == 'slave':
|
Link Here
|
---|
|
68 |
if listener.baseConfig['ldap/slave/filter']: |
68 |
if listener.baseConfig['ldap/slave/filter']: |
69 |
filter=listener.baseConfig['ldap/slave/filter'] |
69 |
filter=listener.baseConfig['ldap/slave/filter'] |
70 |
|
70 |
|
71 |
# |
|
|
72 |
# init flatmode if enabled |
73 |
# |
74 |
flatmode = False |
75 |
flatmode_ldap={ 'lo': None } |
76 |
flatmode_mapping = [] |
77 |
flatmode_container = {} |
78 |
flatmode_module_prefix = 'ldap/replication/flatmode/module/' |
79 |
flatmode_container_prefix = 'ldap/replication/flatmode/container/' |
80 |
|
81 |
univention.debug.debug( |
82 |
univention.debug.LISTENER, |
83 |
univention.debug.INFO, |
84 |
'replication flatmode enabled by UCR: %s' % listener.baseConfig.get('ldap/replication/flatmode','no')) |
85 |
|
86 |
if listener.baseConfig.is_true('ldap/replication/flatmode', False): |
87 |
# flatmode is enabled |
88 |
try: |
89 |
import univention.admin.uldap |
90 |
import univention.admin.objects |
91 |
import univention.admin.modules |
92 |
except Exception, ex: |
93 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.ERROR, 'cannot import univention directory manager modules: %s' % str(ex)) |
94 |
else: |
95 |
# all modules imported |
96 |
for key_mod in listener.baseConfig.keys(): |
97 |
# iterate over all UCR variables |
98 |
if key_mod.startswith( flatmode_module_prefix ): |
99 |
# found module entry |
100 |
id=key_mod[ len( flatmode_module_prefix ) : ] |
101 |
val_mod = listener.baseConfig[ key_mod ] |
102 |
# find container entry |
103 |
key_cn = '%s%s' % (flatmode_container_prefix, id) |
104 |
if listener.baseConfig.get(key_cn): |
105 |
val_cn = listener.baseConfig[ key_cn ] |
106 |
# get module |
107 |
mod = univention.admin.modules.get( val_mod ) |
108 |
if not mod: |
109 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.ERROR, 'replication flatmode: could not get module %s' % val_mod) |
110 |
else: |
111 |
entry = { 'module': mod, 'type': val_mod, 'container': val_cn } |
112 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.WARN, 'replication flatmode: saving objects of type %s in %s' % (val_mod, val_cn)) |
113 |
flatmode_mapping.append( entry ) |
114 |
flatmode_container[ val_cn ] = False |
115 |
flatmode = True |
116 |
else: |
117 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.ERROR, 'replication flatmode: cannot find UCR variable %s' % key_cn) |
118 |
|
119 |
univention.debug.debug( |
120 |
univention.debug.LISTENER, |
121 |
univention.debug.INFO, |
122 |
'replication flatmode activated: %s' % flatmode) |
123 |
|
124 |
STATE_DIR = '/var/lib/univention-directory-replication' |
71 |
STATE_DIR = '/var/lib/univention-directory-replication' |
125 |
LDIF_FILE = os.path.join(STATE_DIR, 'failed.ldif') |
72 |
LDIF_FILE = os.path.join(STATE_DIR, 'failed.ldif') |
126 |
|
73 |
|
|
561 |
|
508 |
|
562 |
local_ip='127.0.0.1' |
509 |
local_ip='127.0.0.1' |
563 |
local_port=listener.baseConfig.get('slapd/port', '7389').split(',')[0] |
510 |
local_port=listener.baseConfig.get('slapd/port', '7389').split(',')[0] |
564 |
|
511 |
|
565 |
try: |
512 |
try: |
566 |
connection=ldap.open(local_ip, int(local_port)) |
513 |
connection=ldap.open(local_ip, int(local_port)) |
567 |
connection.simple_bind_s('cn=update,'+listener.baseConfig['ldap/base'], pw) |
514 |
connection.simple_bind_s('cn=update,'+listener.baseConfig['ldap/base'], pw) |
Lines 625-632
def update_schema(attr):
|
Link Here
|
---|
|
625 |
finally: |
572 |
finally: |
626 |
listener.unsetuid() |
573 |
listener.unsetuid() |
627 |
|
574 |
|
628 |
queue = [] |
|
|
629 |
|
630 |
print >>fp, '# This schema was automatically replicated from the master server' |
575 |
print >>fp, '# This schema was automatically replicated from the master server' |
631 |
print >>fp, '# Please do not edit this file\n' |
576 |
print >>fp, '# Please do not edit this file\n' |
632 |
subschema = ldap.schema.SubSchema(attr) |
577 |
subschema = ldap.schema.SubSchema(attr) |
Lines 674-810
def getOldValues( ldapconn, dn ):
|
Link Here
|
---|
|
674 |
|
619 |
|
675 |
return old |
620 |
return old |
676 |
|
621 |
|
677 |
# check if target container exists; this function creates required containers if they are missing |
|
|
678 |
def flatmodeCreateContainer( ldapconn, dn ): |
679 |
if dn in flatmode_container: |
680 |
if flatmode_container[dn]: |
681 |
return |
682 |
|
683 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.WARN, 'replication flatmode: testing required container: %s' % dn) |
684 |
old = getOldValues( ldapconn, dn ) |
685 |
|
686 |
if not old: |
687 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.WARN, 'replication flatmode: required container does not exist: %s' % dn) |
688 |
tmpdn='' |
689 |
dnparts = univention.admin.uldap.explodeDn(dn, 0) |
690 |
dnparts.reverse() |
691 |
for dnpart in dnparts: |
692 |
if tmpdn: |
693 |
tmpdn = '%s,%s' % (dnpart, tmpdn) |
694 |
else: |
695 |
tmpdn = dnpart |
696 |
|
697 |
tmpold = {} |
698 |
tmpnew = {} |
699 |
objtype, objname = dnpart.split('=',1) |
700 |
if objtype == 'cn' or objtype == 'ou': |
701 |
# check if object exists in local ldap tree |
702 |
tmpold = getOldValues( ldapconn, tmpdn ) |
703 |
|
704 |
if objtype == 'cn' and not tmpold: |
705 |
tmpnew = { 'cn': [ objname ], 'objectClass': [ 'top', 'organizationalRole' ] } |
706 |
elif objtype == 'ou' and not tmpold: |
707 |
tmpnew = { 'ou': [ objname ], 'objectClass': [ 'top', 'organizationalUnit' ] } |
708 |
|
709 |
if tmpnew: |
710 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.WARN, 'replication flatmode: creating required container: %s' % tmpdn) |
711 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.INFO, 'replication flatmode: calling handle( %s, tmpnew, tmpold ):\ntmpnew=%s' % (tmpdn, tmpnew)) |
712 |
handler( tmpdn, tmpnew, tmpold ) |
713 |
flatmode_container[dn] = True |
714 |
|
715 |
|
716 |
# This function converts object dn and object attributes for flatmode. |
717 |
# Special convertions for aach module type have to be added here. |
718 |
# "new" is modified "by reference" |
719 |
# the new value for "dn" is returned ("call by value") |
720 |
def flatmodeConvertObject( entry, dn, new ): |
721 |
global flatmode_mapping |
722 |
|
723 |
# map DN |
724 |
rdn = univention.admin.uldap.explodeDn(dn, 0)[0] |
725 |
dn = '%s,%s' % (rdn, entry['container']) |
726 |
|
727 |
# correct entryDN |
728 |
if new: |
729 |
new['entryDN'][0] = dn |
730 |
|
731 |
if new.get('uniqueMember'): |
732 |
if flatmode_ldap['lo'] is None: |
733 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.ERROR, 'replication flatmode: second ldap connection is not established - local replica may be corrupt!') |
734 |
else: |
735 |
newMemberDNs = [] |
736 |
# convert all existing uniqueMember DNs |
737 |
for memberdn in new['uniqueMember']: |
738 |
try: |
739 |
obj = flatmode_ldap['lo'].get(memberdn,[]) |
740 |
except Exception, ex: |
741 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.WARN, 'replication flatmode: could not get member %s' % memberdn) |
742 |
obj = None |
743 |
|
744 |
newmember = memberdn |
745 |
if obj: |
746 |
for entry in flatmode_mapping: |
747 |
# test if memberdn should also be remapped |
748 |
if entry['module'].identify( memberdn, obj ) or entry['module'].identify( memberdn, obj ): |
749 |
|
750 |
rdn = univention.admin.uldap.explodeDn(memberdn, 0)[0] |
751 |
newmember = '%s,%s' % (rdn, entry['container']) |
752 |
break |
753 |
|
754 |
newMemberDNs.append( newmember ) |
755 |
# set new DNs |
756 |
new['uniqueMember'] = newMemberDNs |
757 |
|
758 |
return dn |
759 |
|
760 |
# if flatmode is enabled handlerFlatmode checks for every object if mapping is required |
761 |
# if examined object matches to mapping "dn" and "new" are converted by flatmodeConvertObject |
762 |
def handlerFlatmode( ldapconn, dn, new, old ): |
763 |
global flatmode |
764 |
global flatmode_mapping |
765 |
global flatmode_container |
766 |
|
767 |
if not flatmode: |
768 |
return dn |
769 |
newdn = dn |
770 |
|
771 |
if dn in flatmode_container: |
772 |
flatmode_container[dn] = True |
773 |
|
774 |
for entry in flatmode_mapping: |
775 |
if entry['module'].identify( dn, new ) or entry['module'].identify( dn, old ): |
776 |
|
777 |
newdn = flatmodeConvertObject( entry, dn, new ) |
778 |
|
779 |
# test if required container is present |
780 |
if not flatmode_container[ entry['container'] ]: |
781 |
flatmodeCreateContainer( ldapconn, entry['container'] ) |
782 |
|
783 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.INFO, 'replication flatmode: mapped %s to %s' % (dn, newdn)) |
784 |
return newdn |
785 |
|
786 |
return newdn |
787 |
|
788 |
|
789 |
def flatmode_reconnect(): |
790 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.WARN, 'replication flatmode: ldap reconnect triggered') |
791 |
if ( flatmode_ldap.get('ldapserver') and \ |
792 |
flatmode_ldap.get('basedn') and \ |
793 |
flatmode_ldap.get('binddn') and \ |
794 |
flatmode_ldap.get('bindpw')): |
795 |
try: |
796 |
flatmode_ldap['lo'] = univention.uldap.access( host = flatmode_ldap['ldapserver'], |
797 |
base = flatmode_ldap['basedn'], |
798 |
binddn = flatmode_ldap['binddn'], |
799 |
bindpw = flatmode_ldap['bindpw'], |
800 |
start_tls = 2 ) |
801 |
except Exception, ex: |
802 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.ERROR, 'replication flatmode: ldap reconnect failed: %s' % str(ex)) |
803 |
flatmode_ldap['lo'] = None |
804 |
else: |
805 |
if flatmode_ldap['lo'] is None: |
806 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.ERROR, 'replication flatmode: ldap reconnect failed') |
807 |
|
808 |
def _delete_dn_recursive(l, dn): |
622 |
def _delete_dn_recursive(l, dn): |
809 |
try: |
623 |
try: |
810 |
l.delete_s(dn) |
624 |
l.delete_s(dn) |
Lines 824-842
def _backup_dn_recursive(l, dn):
|
Link Here
|
---|
|
824 |
if not os.path.exists(backup_directory): |
638 |
if not os.path.exists(backup_directory): |
825 |
os.makedirs(backup_directory) |
639 |
os.makedirs(backup_directory) |
826 |
os.chmod(backup_directory, 0700) |
640 |
os.chmod(backup_directory, 0700) |
827 |
|
641 |
|
828 |
backup_file = os.path.join(backup_directory, str(time.time())) |
642 |
backup_file = os.path.join(backup_directory, str(time.time())) |
829 |
fd = open(backup_file, 'w+') |
643 |
fd = open(backup_file, 'w+') |
830 |
fd.close() |
644 |
fd.close() |
831 |
os.chmod(backup_file, 0600) |
645 |
os.chmod(backup_file, 0600) |
832 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.PROCESS, 'replication: dump %s to %s' % (dn, backup_file)) |
646 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.PROCESS, 'replication: dump %s to %s' % (dn, backup_file)) |
833 |
|
647 |
|
834 |
fd = open(backup_file, 'w+') |
648 |
fd = open(backup_file, 'w+') |
835 |
ldif_writer = ldifparser.LDIFWriter(fd) |
649 |
ldif_writer = ldifparser.LDIFWriter(fd) |
836 |
for dn,entry in l.search_s(dn, ldap.SCOPE_SUBTREE, '(objectClass=*)', attrlist=['*', '+']): |
650 |
for dn,entry in l.search_s(dn, ldap.SCOPE_SUBTREE, '(objectClass=*)', attrlist=['*', '+']): |
837 |
ldif_writer.unparse(dn,entry) |
651 |
ldif_writer.unparse(dn,entry) |
838 |
fd.close() |
652 |
fd.close() |
839 |
|
653 |
|
840 |
def _get_current_modrdn_link(): |
654 |
def _get_current_modrdn_link(): |
841 |
return os.path.join(STATE_DIR, 'current_modrdn') |
655 |
return os.path.join(STATE_DIR, 'current_modrdn') |
842 |
|
656 |
|
Lines 874-880
def _read_dn_from_file(filename):
|
Link Here
|
---|
|
874 |
def handler(dn, new, listener_old, operation): |
688 |
def handler(dn, new, listener_old, operation): |
875 |
global reconnect |
689 |
global reconnect |
876 |
global slave |
690 |
global slave |
877 |
global flatmode |
|
|
878 |
if not slave: |
691 |
if not slave: |
879 |
return 1 |
692 |
return 1 |
880 |
|
693 |
|
Lines 908-916
def handler(dn, new, listener_old, operation):
|
Link Here
|
---|
|
908 |
else: |
721 |
else: |
909 |
connected=1 |
722 |
connected=1 |
910 |
|
723 |
|
911 |
if flatmode: |
|
|
912 |
dn = handlerFlatmode( l, dn, new, listener_old ) |
913 |
|
914 |
try: |
724 |
try: |
915 |
|
725 |
|
916 |
if listener.baseConfig.get('ldap/replication/filesystem/check', 'false').lower() in ['true', 'yes']: |
726 |
if listener.baseConfig.get('ldap/replication/filesystem/check', 'false').lower() in ['true', 'yes']: |
Lines 1035-1041
def handler(dn, new, listener_old, operation):
|
Link Here
|
---|
|
1035 |
_delete_dn_recursive(l, old_dn) |
845 |
_delete_dn_recursive(l, old_dn) |
1036 |
else: |
846 |
else: |
1037 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.WARN, 'replication: no old dn has been found') |
847 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.WARN, 'replication: no old dn has been found') |
1038 |
|
848 |
|
1039 |
if not old: |
849 |
if not old: |
1040 |
_add_object_from_new(l, dn, new) |
850 |
_add_object_from_new(l, dn, new) |
1041 |
elif old: |
851 |
elif old: |
Lines 1214-1234
def init_slapd(arg):
|
Link Here
|
---|
|
1214 |
listener.run('/etc/init.d/slapd', ['slapd', arg], uid=0) |
1024 |
listener.run('/etc/init.d/slapd', ['slapd', arg], uid=0) |
1215 |
time.sleep(1) |
1025 |
time.sleep(1) |
1216 |
|
1026 |
|
1217 |
def setdata(key, value): |
|
|
1218 |
if key == 'bindpw': |
1219 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.INFO, 'replication: listener passed key="%s" value="<HIDDEN>"' % key) |
1220 |
else: |
1221 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.INFO, 'replication: listener passed key="%s" value="%s"' % (key, value)) |
1222 |
|
1223 |
if key in [ 'ldapserver', 'basedn', 'binddn', 'bindpw' ]: |
1224 |
flatmode_ldap[ key ] = value |
1225 |
else: |
1226 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.INFO, 'replication: listener passed unknown data (key="%s" value="%s")' % (key, value)) |
1227 |
|
1228 |
if key == 'ldapserver': |
1229 |
univention.debug.debug(univention.debug.LISTENER, univention.debug.WARN, 'replication: ldap server changed to %s' % value) |
1230 |
if flatmode: |
1231 |
flatmode_reconnect() |
1232 |
|
1027 |
|
1233 |
if __name__ == '__main__': |
1028 |
if __name__ == '__main__': |
1234 |
handler('foo', {'foo': 'bar'}, {'foo': 'baz'}) |
1029 |
handler('foo', {'foo': 'bar'}, {'foo': 'baz'}) |