@!@
access = "write" if configRegistry.get('ldap/server/type') == "master" else "read"

uidexcludelist = configRegistry.get('ldap/acl/user/passwordreset/protected/uid', '').split(',')

protected_groups = configRegistry.get('ldap/acl/user/passwordreset/protected/gid')
if protected_groups:
    for group in protected_groups.split(','):
        uidexcludelist += configRegistry.get('ldap/acl/user/passwordreset/internal/groupmemberlist/%s' % group, '').split(',')

uidexcludelist.append('*$')
uidexcludestr = ''.join('(uid=%s)' % uid.strip() for uid in uidexcludelist if uid.strip())

grouplist = [
    val
    for key, val in configRegistry.items()
    if key.startswith('ldap/acl/user/passwordreset/accesslist/groups/')
]


def slapd_split_line(line, max_length=1024, split_at=')', only_split_at=True):
    lines = []
    i = 0
    while i < len(line):
        j = i + max_length
        try:
            j = line[i:j].rindex(split_at)
        except ValueError:
            if only_split_at and len(line) > j:
                import sys
                sys.stderr.write("ERROR: Failed splitting line for slapd.conf: %s\n" % (line,))
                return [line]  # return line as is, rather fail starting slapd than adding incorrect whitespaces while splitting attribute values
            j = max_length
        j = i + j + 1
        lines.append(line[i:j])
        i = j
    return lines


def slapd_wrap_lines(lines, prefix=""):
    return ("\n    " + prefix).join(lines)


userfilter_lines = slapd_split_line('(&(|(&(objectClass=posixAccount)(objectClass=shadowAccount))(objectClass=univentionMail)(objectClass=sambaSamAccount)(objectClass=simpleSecurityObject)(&(objectClass=person)(objectClass=organizationalPerson)(objectClass=inetOrgPerson)))(!(uidNumber=0))(!(|%s)))' % uidexcludestr)

attr_fallback = 'krb5Key,userPassword,sambaPwdCanChange,sambaPwdMustChange,sambaLMPassword,sambaNTPassword,sambaPwdLastSet,pwhistory,sambaPasswordHistory,krb5KDCFlags,krb5KeyVersionNumber,krb5PasswordEnd,shadowMax,shadowLastChange'
attrlist = configRegistry.get('ldap/acl/user/passwordreset/attributes', attr_fallback)

nestedgroups = configRegistry.is_true('ldap/acl/nestedgroups', False)

if grouplist:
    print('# helpdesk access: grant access to specified groups for password reset')
    print('access to')
    print('    dn.sub="%(ldap/base)s"' % {'ldap/base': configRegistry.get('ldap/base')})
    print('    filter="%(userfilter)s"' % {'userfilter': slapd_wrap_lines(userfilter_lines)})
    print('    attrs=%(attributelist)s' % {'attributelist': attrlist})
    for dn in grouplist:
        if nestedgroups:
            print('    by set="user & [%s]/uniqueMember*" %s' % (dn, access))
        else:
            print('    by group/univentionGroup/uniqueMember="%s" %s' % (dn, access))
    print('    by * break')
else:
    print('# helpdesk access: grant access to specified groups for password reset')
    print('#                  ==> no group has been specified')
@!@
