Re: [Freeipa-devel] [PATCH] 185-188 Let replicas install without DNS
On Thu, 2012-01-05 at 16:36 -0500, Rob Crittenden wrote: Martin Kosek wrote: Patches 185-186 are needed to make ipa-replica-install run without crashes. How to test: on server: 1) install the server (ipa.example.com is not resolvable) # ipa-server-install -p kokos123 -a kokos123 --no-host-dns --hostname=ipa.example.com 2) Add a record for replica.example.com to /etc/hosts 3) Prepare the replica (without 188 it refuses to create the replica file) # ipa-replica-prepare replica.example.com on replica: 1) Add a record for ipa.example.com to /etc/hosts 2) Install replica (replica.example.com is not resolvable) # ipa-replica-install --no-host-dns --ip-address=IP_ADDRESS REPLICA_FILE The installer now use IP_ADDRESS to create a record /etc/hosts and make the replica resolvable Let ipa-replica-prepare and ipa-replica-install work without proper DNS records as records in /etc/hosts are sufficient for DS replication. 1) ipa-replica-prepare now just checks if the replica hostname is resolvable (DNS records are not required). It is now able to prepare a replica file even when the replica IP address is present in /etc/hosts only. 2) ipa-replica-install is now able to proceed when the hostname is not resolvable. It uses an IP address passed in a new option --ip-address to create a record in /etc/hosts in the same way as ipa-server-install does. https://fedorahosted.org/freeipa/ticket/2139 NACK on patch 185. The exceptions need to be changed to catch DuplicateEntry instead of ALREADY_EXISTS Otherwise looks ok. rob Good catch, Rob! Attaching an updated set of patches. Martin From 67bec667b2046f81015ee2149392588ba7fe63d2 Mon Sep 17 00:00:00 2001 From: Martin Kosek mko...@redhat.com Date: Wed, 4 Jan 2012 19:47:52 +0100 Subject: [PATCH 1/4] Fix LDAP add calls in replication module Replace conn.add_s(entry) with conn.addEntry(entry) to avoid function calls with an invalid number of parameters. https://fedorahosted.org/freeipa/ticket/2139 --- ipaserver/install/replication.py | 22 +++--- 1 files changed, 11 insertions(+), 11 deletions(-) diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py index a139fd0fbe7168193dcfa6ba5f4d19f20d395c52..74685ef0fdcd2f6a8c56e46619576a1ba74948e7 100644 --- a/ipaserver/install/replication.py +++ b/ipaserver/install/replication.py @@ -227,8 +227,8 @@ class ReplicationManager(object): ent.setValues(sn, replication manager pseudo user) try: -conn.add_s(ent) -except ldap.ALREADY_EXISTS: +conn.addEntry(ent) +except errors.DuplicateEntry: conn.modify_s(dn, [(ldap.MOD_REPLACE, userpassword, pw)]) pass @@ -277,7 +277,7 @@ class ReplicationManager(object): entry.setValues('nsds5replicabinddn', [replica_binddn]) entry.setValues('nsds5replicalegacyconsumer', off) -conn.add_s(entry) +conn.addEntry(entry) def setup_changelog(self, conn): dn = cn=changelog5, cn=config @@ -287,8 +287,8 @@ class ReplicationManager(object): entry.setValues('cn', changelog5) entry.setValues('nsslapd-changelogdir', dirpath) try: -conn.add_s(entry) -except ldap.ALREADY_EXISTS: +conn.addEntry(entry) +except errors.DuplicateEntry: return def setup_chaining_backend(self, conn): @@ -310,11 +310,11 @@ class ReplicationManager(object): entry.setValues('nsmultiplexorbinddn', self.repl_man_dn) entry.setValues('nsmultiplexorcredentials', self.repl_man_passwd) -self.conn.add_s(entry) +self.conn.addEntry(entry) done = True -except ldap.ALREADY_EXISTS: +except errors.DuplicateEntry: benum += 1 -except ldap.LDAPError, e: +except errors.ExecutionError, e: print Could not add backend entry + dn, e raise @@ -378,7 +378,7 @@ class ReplicationManager(object): entry.setValues(objectclass, [account, simplesecurityobject]) entry.setValues(uid, passsync) entry.setValues(userPassword, password) -conn.add_s(entry) +conn.addEntry(entry) # Add it to the list of users allowed to bypass password policy extop_dn = cn=ipa_pwd_extop,cn=plugins,cn=config @@ -476,7 +476,7 @@ class ReplicationManager(object): if iswinsync: self.setup_winsync_agmt(entry, win_subtree) -a_conn.add_s(entry) +a_conn.addEntry(entry) try: mod = [(ldap.MOD_ADD, 'nsDS5ReplicatedAttributeListTotal', @@ -765,7 +765,7 @@ class ReplicationManager(object): entry.setValues(ipaConfigString, winsync:%s % self.hostname) try: -self.conn.add_s(entry) +
Re: [Freeipa-devel] [PATCH] 918, 919 update sudo schema
Dne 14.12.2011 16:21, Rob Crittenden napsal(a): Jan Cholasta wrote: Dne 14.12.2011 15:23, Rob Crittenden napsal(a): Jan Cholasta wrote: Dne 14.12.2011 05:20, Rob Crittenden napsal(a): The sudo schema now defines sudoOrder, sudoNotBefore and sudoNotAfter but these weren't available in the sudorule plugin. I've added support for these. sudoOrder enforces uniqueness because duplicates are undefined. I also added support for a GeneralizedTime parameter type. This is similar to the existing AccessTime parameter but it only handles a single time value. You should parse the date/time part of the value with time.strptime(timestr, '%Y%m%d%H%M%S') instead of doing it manually, that way you'll get most of the validation for free. Yes but it gives a crappy error message, just saying that some data is left over not what is wrong. IMHO having a separate error message for every field in the time string (like you do in the patch) is an overkill, simple invalid time and/or unknown time format should suffice (we don't have errors like invalid 3rd octet for IP adresses either). Well, the work is done, hard to go back on a better error message. Also, it would be nice to be able to enter the value in more user-friendly format (e.g. 2011-12-14 13:01:25 +0100) and normalize that to LDAP generalized time. When dealing with time there are so many ways to input and display the same values this becomes difficult. I'd expect that the times for these two attributes will be relatively simple and I somehow doubt users are going to want seconds, leap seconds or fractions, but we'll need to consider how to do it for future consistency (otherwise we could have a case where time is entered in one format for some attributes and another for others). If we input in a nice way we need to output in the same way. We could make the preferred input/output time format user-configurable, defaulting to current locale time format. This format would be used for output. For input, we could go over a list of formats (first the user-configured format, then current locale format, then a handful of standard formats like -MM-DD HH:MM:SS) and use the first format that can be successfully used to parse the time string. See how far you get into the rabbit hole with even this simple format? I don't mind, as long as it is the right thing to do (IMHO) :) Anyway, I think this could be done on the client side, so we might use your patch without changes. However, I would prefer if the parameter class was more generic, so we could use it (hypothetically) to store time in some other way than LDAP generalized time attribute (at least name it DateTime please). The LDAP GeneralizedTime needs to be either in GMT or include a differential. This gets us into the territory where the client could be in a different timezone than the server which leads us to why we dropped AccessTime in the first place. Speaking of time zones, the differential alone is not a sufficient time zone description, as it doesn't account for DST. Is there a way to store time in LDAP with full time zone name (just in case it's needed sometime in future)? So I'd like the user to supply the timezone themselves so I don't have to guess (wrongly) and let them worry about differing timezones. We don't have to guess, IIRC there is a way to get the local timezone differential in both Python and JavaScript, so the client could supply it automatically if necessary. rob Honza -- Jan Cholasta ___ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel
[Freeipa-devel] [PATCH] 189 Fix selfservice-find crashes
Ignore empty options when performing an ACI search so that the find command does not crash. https://fedorahosted.org/freeipa/ticket/2011 https://fedorahosted.org/freeipa/ticket/2012 From 5cf61984f4209adc4eff49f4da6ec4a0173e00bd Mon Sep 17 00:00:00 2001 From: Martin Kosek mko...@redhat.com Date: Fri, 6 Jan 2012 12:44:59 +0100 Subject: [PATCH 1/2] Fix selfservice-find crashes Ignore empty options when performing an ACI search so that the find command does not crash. https://fedorahosted.org/freeipa/ticket/2011 https://fedorahosted.org/freeipa/ticket/2012 --- ipalib/plugins/aci.py| 22 +++--- tests/test_xmlrpc/test_selfservice_plugin.py | 19 +++ 2 files changed, 30 insertions(+), 11 deletions(-) diff --git a/ipalib/plugins/aci.py b/ipalib/plugins/aci.py index 4b85bc93cbf309dd4ddcb0b0dfd5b1d45c807239..54e3f43a61fb2dea38b518c17a3160813cebabfe 100644 --- a/ipalib/plugins/aci.py +++ b/ipalib/plugins/aci.py @@ -687,21 +687,21 @@ class aci_find(crud.Search): else: results = list(acis) -if 'aciname' in kw: +if kw.get('aciname'): for a in acis: prefix, name = _parse_aci_name(a.name) if name != kw['aciname']: results.remove(a) acis = list(results) -if 'aciprefix' in kw: +if kw.get('aciprefix'): for a in acis: prefix, name = _parse_aci_name(a.name) if prefix != kw['aciprefix']: results.remove(a) acis = list(results) -if 'attrs' in kw: +if kw.get('attrs'): for a in acis: if not 'targetattr' in a.target: results.remove(a) @@ -714,7 +714,7 @@ class aci_find(crud.Search): results.remove(a) acis = list(results) -if 'permission' in kw: +if kw.get('permission'): try: self.api.Command['permission_show']( kw['permission'] @@ -727,7 +727,7 @@ class aci_find(crud.Search): results.remove(a) acis = list(results) -if 'permissions' in kw: +if kw.get('permissions'): for a in acis: alist1 = sorted(a.permissions) alist2 = sorted(kw['permissions']) @@ -735,7 +735,7 @@ class aci_find(crud.Search): results.remove(a) acis = list(results) -if 'memberof' in kw: +if kw.get('memberof'): try: dn = _group_from_memberof(kw['memberof']) except errors.NotFound: @@ -750,7 +750,7 @@ class aci_find(crud.Search): else: results.remove(a) -if 'type' in kw: +if kw.get('type'): for a in acis: if 'target' in a.target: target = a.target['target']['expression'] @@ -768,7 +768,7 @@ class aci_find(crud.Search): except ValueError: pass -if 'selfaci' in kw and kw['selfaci'] == True: +if kw.get('selfaci', False) is True: for a in acis: if a.bindrule['expression'] != u'ldap:///self': try: @@ -776,7 +776,7 @@ class aci_find(crud.Search): except ValueError: pass -if 'group' in kw: +if kw.get('group'): for a in acis: groupdn = a.bindrule['expression'] groupdn = groupdn.replace('ldap:///','') @@ -790,7 +790,7 @@ class aci_find(crud.Search): except ValueError: pass -if 'targetgroup' in kw: +if kw.get('targetgroup'): for a in acis: found = False if 'target' in a.target: @@ -807,7 +807,7 @@ class aci_find(crud.Search): except ValueError: pass -if 'filter' in kw: +if kw.get('filter'): if not kw['filter'].startswith('('): kw['filter'] = unicode('('+kw['filter']+')') for a in acis: diff --git a/tests/test_xmlrpc/test_selfservice_plugin.py b/tests/test_xmlrpc/test_selfservice_plugin.py index 6a304a9858abaae9ceaa90d43fc762a420b2d1b2..bdfa8e4e9129df697c3a7a0874a02dc61a277005 100644 --- a/tests/test_xmlrpc/test_selfservice_plugin.py +++ b/tests/test_xmlrpc/test_selfservice_plugin.py @@ -139,6 +139,25 @@ class test_selfservice(Declarative): dict( +desc='Search for %r with empty attrs and permissions' % selfservice1, +command=('selfservice_find', [selfservice1], {'attrs' : None, 'permissions' : None}), +expected=dict( +count=1, +truncated=False, +summary=u'1 selfservice matched', +
[Freeipa-devel] [PATCH] 190 Restore ACI when aci_mod fails
aci_mod command is composed of 2 ACI commands: aci_del which deletes the old ACI and aci_add which adds the new modified ACI. However, if aci_add command fails then both new and the old ACI are lost. Old ACI must be restored in this case. https://fedorahosted.org/freeipa/ticket/2013 https://fedorahosted.org/freeipa/ticket/2014 From 4c2915097425758ea53d7de738429b21a32fd8e2 Mon Sep 17 00:00:00 2001 From: Martin Kosek mko...@redhat.com Date: Fri, 6 Jan 2012 13:58:01 +0100 Subject: [PATCH 2/2] Restore ACI when aci_mod fails aci_mod command is composed of 2 ACI commands: aci_del which deletes the old ACI and aci_add which adds the new modified ACI. However, if aci_add command fails then both new and the old ACI are lost. Old ACI must be restored in this case. https://fedorahosted.org/freeipa/ticket/2013 https://fedorahosted.org/freeipa/ticket/2014 --- ipalib/plugins/aci.py| 22 ++ tests/test_xmlrpc/test_selfservice_plugin.py | 25 + 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/ipalib/plugins/aci.py b/ipalib/plugins/aci.py index 54e3f43a61fb2dea38b518c17a3160813cebabfe..ebeea0160f477c6af6429c06ccee9973e899014e 100644 --- a/ipalib/plugins/aci.py +++ b/ipalib/plugins/aci.py @@ -117,6 +117,7 @@ must include all existing attributes as well. When doing an aci-mod the targetattr REPLACES the current attributes, it does not add to them. +from copy import deepcopy from ipalib import api, crud, errors from ipalib import Object, Command @@ -614,14 +615,18 @@ class aci_mod(crud.Update): # The strategy here is to convert the ACI we're updating back into # a series of keywords. Then we replace any keywords that have been # updated and convert that back into an ACI and write it out. -newkw = _aci_to_kw(ldap, aci) +oldkw = _aci_to_kw(ldap, aci) +newkw = deepcopy(oldkw) if 'selfaci' in newkw and newkw['selfaci'] == True: # selfaci is set in aci_to_kw to True only if the target is self kw['selfaci'] = True for k in kw.keys(): newkw[k] = kw[k] -if 'aciname' in newkw: -del newkw['aciname'] +for acikw in (oldkw, newkw): +try: +del acikw['aciname'] +except KeyError: +pass # _make_aci is what is run in aci_add and validates the input. # Do this before we delete the existing ACI. @@ -631,7 +636,16 @@ class aci_mod(crud.Update): self.api.Command['aci_del'](aciname, **kw) -result = self.api.Command['aci_add'](aciname, **newkw)['result'] +try: +result = self.api.Command['aci_add'](aciname, **newkw)['result'] +except Exception, e: +# ACI could not be added, try to restore the old deleted ACI and +# report the ADD error back to user +try: +self.api.Command['aci_add'](aciname, **oldkw) +except: +pass +raise e if kw.get('raw', False): result = dict(aci=unicode(newaci)) diff --git a/tests/test_xmlrpc/test_selfservice_plugin.py b/tests/test_xmlrpc/test_selfservice_plugin.py index bdfa8e4e9129df697c3a7a0874a02dc61a277005..adc361d9f3eac83d31c7cc6f79137e3948cb2962 100644 --- a/tests/test_xmlrpc/test_selfservice_plugin.py +++ b/tests/test_xmlrpc/test_selfservice_plugin.py @@ -192,6 +192,31 @@ class test_selfservice(Declarative): dict( +desc='Try to update %r with empty permissions' % selfservice1, +command=( +'selfservice_mod', [selfservice1], dict(permissions=None) +), +expected=errors.RequirementError(name='permissions'), +), + + +dict( +desc='Retrieve %r to verify invalid update' % selfservice1, +command=('selfservice_show', [selfservice1], {}), +expected=dict( +value=selfservice1, +summary=None, +result={ +'attrs': [u'street', u'c', u'l', u'st', u'postalcode'], +'permissions': [u'read'], +'selfaci': True, +'aciname': selfservice1, +}, +), +), + + +dict( desc='Delete %r' % selfservice1, command=('selfservice_del', [selfservice1], {}), expected=dict( -- 1.7.7.5 ___ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel
Re: [Freeipa-devel] [PATCH] 336 Added policies into user details page.
On 01/06/2012 06:14 AM, Endi Sukma Dewata wrote: The user details page has been modified to show the password policy and Kerberos ticket policy that apply to the user. The policy are displayed as read-only since they may affect other users. Changing a policy should be done in the respective policy details page. Ticket #703 NACK 1) you are calling krbtpolicy-show without any user specific information so it always get the global policy. It should be call with an user argument. Minor: 2) Why not call pwpolicy-show --user=user_login instead of getting the policy's name from dn? Combining 1), 2) and user-show will allow to get all necessary information for the facet in a single batch at refresh. Otherwise it seems fine. -- Petr Vobornik ___ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel
Re: [Freeipa-devel] [PATCH] 335 Added account status into user search facet.
On 01/06/2012 06:14 AM, Endi Sukma Dewata wrote: On 1/5/2012 10:21 AM, Endi Sukma Dewata wrote: The user search facet has been modified to show the account status. The IPA.boolean_format has been converted into a class to allow behavior customization. Ticket #1996 Fixed jslint warning. ACK and pushed to master. (improvement) But before closing the ticket I must ask if it covers all parts of the ticket? Especially the part: easy identifiable from the list they are in. For examply by an icon, or in a change in font color. Right now the information is there, but is it easy identifiable? Should we ask UXD for an input? -- Petr Vobornik ___ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel
[Freeipa-devel] [PATCH] 921 fix existing replication agreements
A bug when creating replication agreements has caused memberOf to be dropped from the exclusion list. This patch adds a tool that will find and fix the agreements. It will be run when the package is installed so end-users should never need to do anything, but it is harmless if run multiple times. rob From b855277c1c0689d386175f8378cb857aeb28e860 Mon Sep 17 00:00:00 2001 From: Rob Crittenden rcrit...@redhat.com Date: Fri, 6 Jan 2012 11:31:31 -0500 Subject: [PATCH] Add tool to add memberOf to replication attribute exclusion list https://fedorahosted.org/freeipa/ticket/2218 --- freeipa.spec.in|4 + install/tools/Makefile.am |1 + install/tools/ipa-fixreplica | 132 install/tools/man/Makefile.am |1 + install/tools/man/ipa-fixreplica.1 | 51 ++ ipaserver/install/replication.py | 29 +--- 6 files changed, 206 insertions(+), 12 deletions(-) create mode 100755 install/tools/ipa-fixreplica create mode 100644 install/tools/man/ipa-fixreplica.1 diff --git a/freeipa.spec.in b/freeipa.spec.in index 46aefe1..2efb79f 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -391,6 +391,8 @@ fi # This must be run in posttrans so that updates from previous # execution that may no longer be shipped are not applied. /usr/sbin/ipa-ldap-updater --upgrade /dev/null 21 || : +# Make sure replication agreements are correct +/usr/sbin/ipa-fixreplica /dev/null 21 || : %preun server if [ $1 = 0 ]; then @@ -473,6 +475,7 @@ fi %{_sbindir}/ipa-replica-install %{_sbindir}/ipa-replica-prepare %{_sbindir}/ipa-replica-manage +%{_sbindir}/ipa-fixreplica %{_sbindir}/ipa-csreplica-manage %{_sbindir}/ipa-server-certinstall %{_sbindir}/ipa-ldap-updater @@ -552,6 +555,7 @@ fi %{_mandir}/man1/ipa-replica-conncheck.1.gz %{_mandir}/man1/ipa-replica-install.1.gz %{_mandir}/man1/ipa-replica-manage.1.gz +%{_mandir}/man1/ipa-fixreplica.1.gz %{_mandir}/man1/ipa-csreplica-manage.1.gz %{_mandir}/man1/ipa-replica-prepare.1.gz %{_mandir}/man1/ipa-server-certinstall.1.gz diff --git a/install/tools/Makefile.am b/install/tools/Makefile.am index 7f1504c..57b51b6 100644 --- a/install/tools/Makefile.am +++ b/install/tools/Makefile.am @@ -13,6 +13,7 @@ sbin_SCRIPTS = \ ipa-replica-install \ ipa-replica-prepare \ ipa-replica-manage \ + ipa-fixreplica \ ipa-csreplica-manage \ ipa-server-certinstall \ ipactl \ diff --git a/install/tools/ipa-fixreplica b/install/tools/ipa-fixreplica new file mode 100755 index 000..daca29c --- /dev/null +++ b/install/tools/ipa-fixreplica @@ -0,0 +1,132 @@ +#!/usr/bin/python +# Authors: Rob Crittenden rcrit...@redhat.com +# +# Copyright (C) 2012 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/. +# + +import sys +import os +import pwd +try: +from optparse import OptionParser +from ipapython import ipautil, config +from ipaserver import ipaldap +from ipaserver.install import installutils, replication +from ipaserver.plugins.ldap2 import ldap2 +from ipapython.ipa_log_manager import * +from ipalib import api, errors +except ImportError: +print sys.stderr, \ +There was a problem importing one of the required Python modules. The +error was: + +%s + % sys.exc_value +sys.exit(1) + +def parse_options(): +usage = %prog [options]\n +parser = OptionParser(usage=usage, formatter=config.IPAFormatter()) + +parser.add_option(-t, --test, action=store_true, dest=test, + help=Run in test mode, no changes are applied) +parser.add_option(-d, --debug, action=store_true, dest=debug, + help=Display debugging information about the update(s)) +parser.add_option(-y, dest=password, + help=File containing the Directory Manager password) + +config.add_standard_options(parser) +options, args = parser.parse_args() + +config.init_config(options) + +return options, args + +def get_dirman_password(): +Prompt the user for the Directory Manager password and verify its + correctness. + +password = installutils.read_password(Directory Manager, confirm=False, validate=False) + +return password + +def main(): +retval = 0 + +options, args = parse_options() + +standard_logging_setup(None,
Re: [Freeipa-devel] [PATCH] 335 Added account status into user search facet.
On 1/6/2012 8:33 AM, Petr Vobornik wrote: ACK and pushed to master. (improvement) But before closing the ticket I must ask if it covers all parts of the ticket? Especially the part: easy identifiable from the list they are in. For examply by an icon, or in a change in font color. Right now the information is there, but is it easy identifiable? Should we ask UXD for an input? I sent the question to Kyle, waiting for a response now. Using icon or color are some methods suggested by the ticket, but I don't think it's a requirement. At least this patch addresses the missing functionality asked by the ticket: being able to identify disabled entries without going into the details page. -- Endi S. Dewata ___ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel
Re: [Freeipa-devel] [PATCH] 335 Added account status into user search facet.
On 01/06/2012 09:33 AM, Petr Vobornik wrote: On 01/06/2012 06:14 AM, Endi Sukma Dewata wrote: On 1/5/2012 10:21 AM, Endi Sukma Dewata wrote: The user search facet has been modified to show the account status. The IPA.boolean_format has been converted into a class to allow behavior customization. Ticket #1996 Fixed jslint warning. ACK and pushed to master. (improvement) But before closing the ticket I must ask if it covers all parts of the ticket? Especially the part: easy identifiable from the list they are in. For examply by an icon, or in a change in font color. Right now the information is there, but is it easy identifiable? Should we ask UXD for an input? I will ask Kyle. -- Thank you, Dmitri Pal Sr. Engineering Manager IPA project, Red Hat Inc. --- Looking to carve out IT costs? www.redhat.com/carveoutcosts/ ___ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel