diff options
Diffstat (limited to 'lib/openldap')
-rw-r--r-- | lib/openldap | 6 |
1 files changed, 6 insertions, 0 deletions
diff --git a/lib/openldap b/lib/openldap index 0a8df96..7293b23 100644 --- a/lib/openldap +++ b/lib/openldap @@ -45,40 +45,41 @@ indexedAttributes = frozenset([ # Instead, we use their parent as a pase, and search for the *unique* # match with the same ObjectClass and the matching extra attributes. # ('%s' in the attribute value is replaced with the value of the source # entry.) indexedDN = { 'olcSchemaConfig': [('cn', '{*}%s')], 'olcHdbConfig': [('olcDbDirectory', '%s' )], 'olcOverlayConfig': [('olcOverlay', '%s' )], } # Allow for flexible ACLs for user using SASL's EXTERNAL mechanism. # "username=postfix,cn=peercred,cn=external,cn=auth" is replaced by # "gidNumber=106+uidNumber=102,cn=peercred,cn=external,cn=auth" where # 102 is postfix's UID and 106 its primary GID. # (Regular expressions are not allowed.) sasl_ext_re = re.compile( r"""(?P<start>\sby\s+dn(?:\.exact)?)= (?P<quote>['\"]?)username=(?P<user>[a-z][-a-z0-9_]*), (?P<end>cn=peercred,cn=external,cn=auth) (?P=quote)\s""" , re.VERBOSE ) +multispaces = re.compile( r"\s+" ) pwd_dict = {} def acl_sasl_ext(m): u = m.group('user') if u not in pwd_dict.keys(): pwd_dict[u] = pwd.getpwnam(u) return '%s="gidNumber=%d+uidNumber=%d,%s" ' % ( m.group('start') , pwd_dict[u].pw_gid , pwd_dict[u].pw_uid , m.group('end') ) # Run the given callback on each DN seen. If its return value is not # None, update the changed variable. class LDIFCallback(LDIFParser): def __init__(self, module, input, callback): LDIFParser.__init__(self,input) self.callback = callback self.changed = False @@ -143,40 +144,45 @@ def flexibleSearch(module, l, dn, entry): v2 = entry[a][0] f.append ( filter_format(a+'='+v, [v2]) ) if len(f) == 1: f = f[0] else: f = '(&(' + ')('.join(f) + '))' r = l.search_s( base, scope, filterstr=f ) if len(r) > 1: module.fail_json(msg="Multiple results found! This is a bug. Please report.") elif r: return r.pop() # Add or modify (only the attributes that differ from those in the # directory) the entry for that DN. # l must be an LDAPObject, and should provide an open connection to the # directory with disclose/search/write access. def processEntry(module, l, dn, entry): changed = False + + for x in indexedAttributes.intersection(entry.keys()): + # remove useless extra spaces in ACLs etc + entry[x] = map( partial(multispaces.sub, ' '), entry[x] ) + r = flexibleSearch( module, l, dn, entry ) if r is None: changed = True if module.check_mode: module.exit_json(changed=changed, msg="add DN %s" % dn) if 'olcAccess' in entry.keys(): # replace "username=...,cn=peercred,cn=external,cn=auth" # by a DN with proper gidNumber and uidNumber entry['olcAccess'] = map ( partial(sasl_ext_re.sub, acl_sasl_ext) , entry['olcAccess'] ) l.add_s( dn, addModlist(entry) ) else: d,e = r fst = str2dn(dn).pop(0)[0][0] diff = [] for a,v in e.iteritems(): if a not in entry.keys(): if a != fst: # delete all values except for the first attribute, # which is implicit |