On Mon, 30 Jul 2012, Martin Kosek wrote:
On 07/30/2012 01:34 PM, Alexander Bokovoy wrote:
On Fri, 27 Jul 2012, Rob Crittenden wrote:
Alexander Bokovoy wrote:
On Thu, 26 Jul 2012, Alexander Bokovoy wrote:
Hi,

When setting up AD trusts support, ipa-adtrust-install utility
needs to be run as:
 - root, for performing Samba configuration and using LDAPI/autobind
 - kinit-ed IPA admin user, to ensure proper ACIs are granted to
   fetch keytab

As result, we can get rid of Directory Manager credentials in
ipa-adtrust-install

https://fedorahosted.org/freeipa/ticket/2815

This ticket also simplifies a bit the way we handle admin connection in
Service class and particulary in Service._ldap_mod() by defaulting to
LDAPI/autobind in case of running as root and to GSSAPI otherwise.
Except few cases in remote replica management (not applicable in
_ldap_mod() case) we always run installation tools as root and can
benefit from using autobind feature. Unfortunately, it is not yet
possible to get away from using DM credentials for all cases as the same
class is used to perform initial directory server instance
configuration.

One side effect is explicit disconnect and reconnect in
Service.add_cert_to_service() due to way how SimpleLDAPObject class
handles stale connections (no handling at all). I've put some comments
in place so that others would not try to err out optimizing it in
future.

Finally, with next patch series which will introduce syncing ipaNTHash
attribute with RC4 key in existing kerberos credentials, we can remove
requirements to change passwords or re-kinit for majority of trust
cases. This should then conclude our trusts content for beta2 release.

Patch updated, fixed small typo (auth_parms was initialized as
auth_params which led to non-existing auth_parms in ipa-adtrust-install
case).

Nack, a couple of minor issues:

The exception handling is rather unusual in
ensure_kerberos_admin_rights(api). I'm not sure if this is any more efficient
than a series of excepts...
I've rewrote this code and put it directly in the main.

You don't need to pass in api, it's a global.
Fixed.


It may be safe to see if the user is in the group the way you are doing it, I
wonder if it would be clearer to cast those into DN objects.
Not sure if checking DNs would be sustaining in long run. Ideally we
should check ACI here, not just hardcoded group name. I'd like to keep
it explicit with memberof for now because it shows what exactly we want
to check.

In the Service class what is the point of ldapi if it is going to be ignored
in the case we know the realm? What if I really, really just want to use a
password?
LDAPI bind in IPAAdmin.__local_init() requires that there is realm known.
No realm -- no LDAPI use because we otherwise cannot construct the
socket name. For 'just want to use a password' case you can simply set
self.dm_password.

However, I've changed the code in Service.ldap_connect() to do
following:

1. if DM password is provided, we'll try to use it
2. Otherwise, if LDAPI is asked for and realm is set, we'll use LDAPI and realm
3. Otherwise (ldapi was False or realm not provided), we'll try to
   connect to fqdn:389 with GSSAPI

I think this covers all cases.

And later where it forces ldapi, it seems better to either commit all the way
and drop the ldapi argument or convert it to a better name (like autobind).
ldapi requires realm but can be used with either GSSAPI or autobind.
Calling it autobind isn't really correct as autobind only available on
ldapi under root.


Works fine, I also have just few minor-ish issues:

1) Uncatched exception

We may want to also catch for DatabaseException in this section:

+        api.Backend.ldap2.connect(ccache.name)
+    except errors.ACIError, e:
+        sys.exit("Outdated Kerberos credentials. Use kdestroy and kinit to
update your ticket")

Otherwise ipa-adtrust-install throws unexpected exception when IPA is down:

# ipactl stop
# ipa-adtrust-install
...
NetBIOS domain name [IDM]:

Unexpected error - see /var/log/ipaserver-install.log for details:
DatabaseError: Can't contact LDAP server:


2) Wrong indentation:
...
+    except errors.RequirementError, e:
+           sys.exit("Must have administrative privileges to setup AD trusts on
server")
+    except Exception, e:
+           sys.exit("Unrecognized error during check of admin rights: %s" %
(str(e)))
Updated patch, includes fixes for issues mentioned above and also
implements autobind suggestions by Simo.

We have SimpleServiceInstance() that doesn't have realm known by default
and this means certain protection is needed for missing realm. Also DS
and CA DS instances cannot use LDAPI and autobind when being setup, only
DM password. The patch handles these cases too.

--
/ Alexander Bokovoy
>From 29bfb9491614afba470787df05a150f424a4e26f Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <aboko...@redhat.com>
Date: Fri, 13 Jul 2012 18:12:48 +0300
Subject: [PATCH 2/6] Ensure ipa-adtrust-install is run with Kerberos ticket
 for admin user

When setting up AD trusts support, ipa-adtrust-install utility
needs to be run as:
   - root, for performing Samba configuration and using LDAPI/autobind
   - kinit-ed IPA admin user, to ensure proper ACIs are granted to
     fetch keytab

As result, we can get rid of Directory Manager credentials in 
ipa-adtrust-install

https://fedorahosted.org/freeipa/ticket/2815
---
 install/tools/ipa-adtrust-install       |  46 +++++++------
 install/tools/man/ipa-adtrust-install.1 |   3 -
 ipaserver/install/adtrustinstance.py    |  21 +++---
 ipaserver/install/cainstance.py         |   3 +-
 ipaserver/install/dsinstance.py         |   2 +-
 ipaserver/install/krbinstance.py        |   2 +-
 ipaserver/install/service.py            | 114 +++++++++++++++++++++-----------
 7 files changed, 115 insertions(+), 76 deletions(-)

diff --git a/install/tools/ipa-adtrust-install 
b/install/tools/ipa-adtrust-install
index 
6678018e6346d75d5042894cfb833d38079d3f21..02a309306fb5743c94b651ab22afa06b5eb2cc8b
 100755
--- a/install/tools/ipa-adtrust-install
+++ b/install/tools/ipa-adtrust-install
@@ -24,7 +24,7 @@
 from ipaserver.plugins.ldap2 import ldap2
 from ipaserver.install import adtrustinstance
 from ipaserver.install.installutils import *
-from ipaserver.install import installutils
+from ipaserver.install import service
 from ipapython import version
 from ipapython import ipautil, sysrestore
 from ipalib import api, errors, util
@@ -37,8 +37,6 @@ log_file_name = "/var/log/ipaserver-install.log"
 
 def parse_options():
     parser = IPAOptionParser(version=version.VERSION)
-    parser.add_option("-p", "--ds-password", dest="dm_password",
-                      sensitive=True, help="directory manager password")
     parser.add_option("-d", "--debug", dest="debug", action="store_true",
                       default=False, help="print debugging information")
     parser.add_option("--ip-address", dest="ip_address",
@@ -98,7 +96,7 @@ def main():
     root_logger.debug('%s was invoked with options: %s' % (sys.argv[0], 
safe_options))
     root_logger.debug("missing options might be asked for interactively 
later\n")
 
-    installutils.check_server_configuration()
+    check_server_configuration()
 
     global fstore
     fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore')
@@ -194,24 +192,34 @@ def main():
     if not options.unattended and ( not netbios_name or not 
options.netbios_name):
         netbios_name = read_netbios_name(netbios_name)
 
-    dm_password = options.dm_password or read_password("Directory Manager",
-                                             confirm=False, validate=False)
-    smb = adtrustinstance.ADTRUSTInstance(fstore, dm_password)
+    try:
+        ctx = krbV.default_context()
+        ccache = ctx.default_ccache()
+        principal = ccache.principal()
+    except krbV.Krb5Error, e:
+        sys.exit("Must have Kerberos credentials to setup AD trusts on server")
 
-    # try the connection
     try:
-        smb.ldap_connect()
-        smb.ldap_disconnect()
-    except ldap.INVALID_CREDENTIALS, e:
-        sys.exit("Password is not valid!")
+        api.Backend.ldap2.connect(ccache.name)
+    except errors.ACIError, e:
+        sys.exit("Outdated Kerberos credentials. Use kdestroy and kinit to 
update your ticket")
+    except errors.DatabaseError, e:
+        sys.exit("Cannot connect to the LDAP database. Please check if IPA is 
running")
 
-    if smb.dm_password:
-        api.Backend.ldap2.connect(bind_dn="cn=Directory Manager", 
bind_pw=smb.dm_password)
-    else:
-        # See if our LDAP server is up and we can talk to it over GSSAPI
-        ccache = krbV.default_context().default_ccache().name
-        api.Backend.ldap2.connect(ccache)
+    try:
+        user = api.Command.user_show(unicode(principal[0]))['result']
+        group = api.Command.group_show(u'admins')['result']
+        if not (user['uid'][0] in group['member_user'] and
+                group['cn'][0] in user['memberof_group']):
+            raise errors.RequirementError(name='admins group membership')
+    except errors.RequirementError, e:
+        sys.exit("Must have administrative privileges to setup AD trusts on 
server")
+    except Exception, e:
+        sys.exit("Unrecognized error during check of admin rights: %s" % 
(str(e)))
 
+    smb = adtrustinstance.ADTRUSTInstance(fstore)
+    smb.realm = api.env.realm
+    smb.autobind = service.ENABLED
     smb.setup(api.env.host, ip_address, api.env.realm, api.env.domain,
               netbios_name, options.rid_base, options.secondary_rid_base,
               options.no_msdcs)
@@ -250,5 +258,5 @@ information"""
     return 0
 
 if __name__ == '__main__':
-    installutils.run_script(main, log_file_name=log_file_name,
+    run_script(main, log_file_name=log_file_name,
             operation_name='ipa-adtrust-install')
diff --git a/install/tools/man/ipa-adtrust-install.1 
b/install/tools/man/ipa-adtrust-install.1
index 
b61da19088b40d6a9e53784f9a061913ecda4321..22337c3df8827670657bf405b6c49ba2f8624d6d
 100644
--- a/install/tools/man/ipa-adtrust-install.1
+++ b/install/tools/man/ipa-adtrust-install.1
@@ -27,9 +27,6 @@ trust to an Active Directory domain. This requires that the 
IPA server is
 already installed and configured.
 .SH "OPTIONS"
 .TP
-\fB\-p\fR \fIDM_PASSWORD\fR, \fB\-\-ds\-password\fR=\fIDM_PASSWORD\fR
-The password to be used by the Directory Server for the Directory Manager user
-.TP
 \fB\-d\fR, \fB\-\-debug\fR
 Enable debug logging when more verbose output is needed
 .TP
diff --git a/ipaserver/install/adtrustinstance.py 
b/ipaserver/install/adtrustinstance.py
index 
20feec4df309b5793aa1c29fdf18bc5bfe180943..9dcbec2d61d935f90e74cc65b30a0f1d0c0f9d2a
 100644
--- a/ipaserver/install/adtrustinstance.py
+++ b/ipaserver/install/adtrustinstance.py
@@ -96,10 +96,9 @@ class ADTRUSTInstance(service.Service):
     OBJC_GROUP = "ipaNTGroupAttrs"
     OBJC_DOMAIN = "ipaNTDomainAttrs"
 
-    def __init__(self, fstore=None, dm_password=None):
+    def __init__(self, fstore=None):
         self.fqdn = None
         self.ip_address = None
-        self.realm_name = None
         self.domain_name = None
         self.netbios_name = None
         self.no_msdcs = None
@@ -118,7 +117,7 @@ class ADTRUSTInstance(service.Service):
         self.rid_base = None
         self.secondary_rid_base = None
 
-        service.Service.__init__(self, "smb", dm_password=dm_password)
+        service.Service.__init__(self, "smb", dm_password=None, ldapi=True)
 
         if fstore:
             self.fstore = fstore
@@ -436,6 +435,8 @@ class ADTRUSTInstance(service.Service):
         # We do not let the system start IPA components on its own,
         # Instead we reply on the IPA init script to start only enabled
         # components as found in our LDAP configuration tree
+        # Note that self.dm_password is None for ADTrustInstance because
+        # we ensure to be called as root and using ldapi to use autobind
         try:
             self.ldap_enable('ADTRUST', self.fqdn, self.dm_password, \
                              self.suffix)
@@ -449,7 +450,7 @@ class ADTRUSTInstance(service.Service):
             root_logger.info("EXTID Service startup entry already exists.")
 
     def __setup_sub_dict(self):
-        self.sub_dict = dict(REALM = self.realm_name,
+        self.sub_dict = dict(REALM = self.realm,
                              SUFFIX = self.suffix,
                              NETBIOS_NAME = self.netbios_name,
                              SMB_DN = self.smb_dn,
@@ -460,16 +461,16 @@ class ADTRUSTInstance(service.Service):
               rid_base, secondary_rid_base, no_msdcs=False, smbd_user="samba"):
         self.fqdn = fqdn
         self.ip_address = ip_address
-        self.realm_name = realm_name
+        self.realm = realm_name
         self.domain_name = domain_name
         self.netbios_name = netbios_name
         self.rid_base = rid_base
         self.secondary_rid_base = secondary_rid_base
         self.no_msdcs = no_msdcs
         self.smbd_user = smbd_user
-        self.suffix = ipautil.realm_to_suffix(self.realm_name)
+        self.suffix = ipautil.realm_to_suffix(self.realm)
         self.ldapi_socket = "%%2fvar%%2frun%%2fslapd-%s.socket" % \
-                            realm_to_serverid(self.realm_name)
+                            realm_to_serverid(self.realm)
 
         self.smb_conf = "/etc/samba/smb.conf"
 
@@ -479,7 +480,7 @@ class ADTRUSTInstance(service.Service):
         self.trust_dn = str(DN(api.env.container_trusts, self.suffix))
         self.smb_dom_dn = str(DN(('cn', self.domain_name),
                                  api.env.container_cifsdomains, self.suffix))
-        self.cifs_principal = "cifs/" + self.fqdn + "@" + self.realm_name
+        self.cifs_principal = "cifs/" + self.fqdn + "@" + self.realm
         self.cifs_agent = str(DN(('krbprincipalname', 
self.cifs_principal.lower()),
                                  api.env.container_service,
                                  self.suffix))
@@ -522,11 +523,11 @@ class ADTRUSTInstance(service.Service):
                              "range.\nAdd local ID range manually and try " \
                              "again!")
 
-        entry = ipaldap.Entry(str(DN(('cn', ('%s_id_range' % self.realm_name)),
+        entry = ipaldap.Entry(str(DN(('cn', ('%s_id_range' % self.realm)),
                                      api.env.container_ranges,
                                      self.suffix)))
         entry.setValue('objectclass', 'ipaDomainIDRange')
-        entry.setValue('cn', ('%s_id_range' % self.realm_name))
+        entry.setValue('cn', ('%s_id_range' % self.realm))
         entry.setValue('ipaBaseID', str(base_id))
         entry.setValue('ipaIDRangeSize', str(id_range_size))
         self.admin_conn.addEntry(entry)
diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py
index 
62c1dc4d082df740f675d8447a7dd13d69f2ec88..e011c9ad593cea3e421deb8a4d914d389e4916a9
 100644
--- a/ipaserver/install/cainstance.py
+++ b/ipaserver/install/cainstance.py
@@ -224,10 +224,9 @@ def get_outputList(data):
 
 class CADSInstance(service.Service):
     def __init__(self, host_name=None, realm_name=None, domain_name=None, 
dm_password=None):
-        service.Service.__init__(self, "pkids")
+        service.Service.__init__(self, "pkids", dm_password=dm_password, 
ldapi=False, autobind=service.DISABLED)
         self.serverid = "PKI-IPA"
         self.realm_name = realm_name
-        self.dm_password = dm_password
         self.sub_dict = None
         self.domain = domain_name
         self.fqdn = host_name
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 
25c449a6e865de01d789a739b31906cb70c6f212..9f3ae7252e45ab3289a85711a2b1202bbe04e137
 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -160,7 +160,7 @@ info: IPA V2.0
 
 class DsInstance(service.Service):
     def __init__(self, realm_name=None, domain_name=None, dm_password=None, 
fstore=None):
-        service.Service.__init__(self, "dirsrv", dm_password=dm_password)
+        service.Service.__init__(self, "dirsrv", dm_password=dm_password, 
ldapi=False, autobind=service.DISABLED)
         self.realm_name = realm_name
         self.sub_dict = None
         self.domain = domain_name
diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py
index 
2faf8e19693f891f28838df967399f0bfe2b51a4..8cc50fba4b0ba8d760cc892a624bd64ef09541a6
 100644
--- a/ipaserver/install/krbinstance.py
+++ b/ipaserver/install/krbinstance.py
@@ -178,7 +178,7 @@ class KrbInstance(service.Service):
         self.start_creation("Configuring Kerberos KDC", 30)
 
         self.kpasswd = KpasswdInstance()
-        self.kpasswd.create_instance('KPASSWD', self.fqdn, 
self.admin_password, self.suffix)
+        self.kpasswd.create_instance('KPASSWD', self.fqdn, 
self.admin_password, self.suffix, realm=self.realm)
 
     def create_replica(self, realm_name,
                        master_fqdn, host_name,
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
index 
5c2699e3fa4c115c972528d4c2cc6aa170711837..403dee907891eccda8c2a8c6309041f4c660bea7
 100644
--- a/ipaserver/install/service.py
+++ b/ipaserver/install/service.py
@@ -35,6 +35,11 @@ from ipapython.ipa_log_manager import *
 
 CACERT = "/etc/ipa/ca.crt"
 
+# Autobind modes
+AUTO = 1
+ENABLED = 2
+DISABLED = 3
+
 # The service name as stored in cn=masters,cn=ipa,cn=etc. In the tuple
 # the first value is the *nix service name, the second the start order.
 SERVICE_LIST = {
@@ -55,13 +60,14 @@ def print_msg(message, output_fd=sys.stdout):
 
 
 class Service(object):
-    def __init__(self, service_name, sstore=None, dm_password=None, 
ldapi=False):
+    def __init__(self, service_name, sstore=None, dm_password=None, 
ldapi=True, autobind=AUTO):
         self.service_name = service_name
         self.service = ipaservices.service(service_name)
         self.steps = []
         self.output_fd = sys.stdout
         self.dm_password = dm_password
         self.ldapi = ldapi
+        self.autobind = autobind
 
         self.fqdn = socket.gethostname()
         self.admin_conn = None
@@ -77,12 +83,44 @@ class Service(object):
         self.dercert = None
 
     def ldap_connect(self):
-        if self.ldapi:
-            if not self.realm:
-                raise RuntimeError('realm must be set to use ldapi connection')
-            self.admin_conn = self.__get_conn(None, None, ldapi=True, 
realm=self.realm)
-        else:
-            self.admin_conn = self.__get_conn(self.fqdn, self.dm_password)
+        # If DM password is provided, we use it
+        # If autobind was requested, attempt autobind when root and ldapi
+        # If autobind was disabled or not succeeded, go with GSSAPI
+        # LDAPI can be used with either autobind or GSSAPI
+        # LDAPI requires realm to be set
+        try:
+            if self.ldapi:
+                if not self.realm:
+                    raise errors.NotFound("realm is missing for %s" % (self))
+                conn = ipaldap.IPAdmin(ldapi=self.ldapi, realm=self.realm)
+            else:
+                conn = ipaldap.IPAdmin(self.fqdn, port=389)
+            if self.dm_password:
+                conn.do_simple_bind(bindpw=self.dm_password)
+            elif self.autobind in [AUTO, ENABLED]:
+                if os.getegid() == 0 and self.ldapi:
+                    try:
+                        # autobind
+                        pw_name = pwd.getpwuid(os.geteuid()).pw_name
+                        conn.do_external_bind(pw_name)
+                    except errors.NotFound, e:
+                        if self.autobind == AUTO:
+                            # Fall back
+                            conn.do_sasl_gssapi_bind()
+                        else:
+                            # autobind was required and failed, raise
+                            # exception that it failed
+                            raise e
+                else:
+                    conn.do_sasl_gssapi_bind()
+            else:
+                conn.do_sasl_gssapi_bind()
+        except Exception, e:
+            root_logger.debug("Could not connect to the Directory Server on 
%s: %s" % (self.fqdn, str(e)))
+            raise e
+
+        self.admin_conn = conn
+
 
     def ldap_disconnect(self):
         self.admin_conn.unbind()
@@ -93,7 +131,6 @@ class Service(object):
         pw_name = None
         fd = None
         path = ipautil.SHARE_DIR + ldif
-        hostname = installutils.get_fqdn()
         nologlist=[]
 
         if sub_dict is not None:
@@ -107,15 +144,25 @@ class Service(object):
             if sub_dict.has_key('RANDOM_PASSWORD'):
                 nologlist.append(sub_dict['RANDOM_PASSWORD'])
 
+        args = ["/usr/bin/ldapmodify", "-v", "-f", path]
+
+        # As we always connect to the local host,
+        # use URI of admin connection
+        if not self.admin_conn:
+            self.ldap_connect()
+        args += ["-H", self.admin_conn._uri]
+
+        auth_parms = []
         if self.dm_password:
             [pw_fd, pw_name] = tempfile.mkstemp()
             os.write(pw_fd, self.dm_password)
             os.close(pw_fd)
             auth_parms = ["-x", "-D", "cn=Directory Manager", "-y", pw_name]
         else:
-            auth_parms = ["-Y", "GSSAPI"]
+            # always try GSSAPI auth when not using DM password or not being 
root
+            if os.getegid() != 0:
+                auth_parms = ["-Y", "GSSAPI"]
 
-        args = ["/usr/bin/ldapmodify", "-h", hostname, "-v", "-f", path]
         args += auth_parms
 
         try:
@@ -181,8 +228,19 @@ class Service(object):
         This server cert should be in DER format.
         """
 
-        if not self.admin_conn:
-            self.ldap_connect()
+        # add_cert_to_service() is relatively rare operation
+        # we actually call it twice during ipa-server-install, for different
+        # instances: ds and cs. Unfortunately, it may happen that admin
+        # connection was created well before add_cert_to_service() is called
+        # If there are other operations in between, it will become stale and
+        # since we are using SimpleLDAPObject, not ReconnectLDAPObject, the
+        # action will fail. Thus, explicitly disconnect and connect again.
+        # Using ReconnectLDAPObject instead of SimpleLDAPObject was considered
+        # but consequences for other parts of the framework are largely
+        # unknown.
+        if self.admin_conn:
+            self.ldap_disconnect()
+        self.ldap_connect()
 
         dn = "krbprincipalname=%s,cn=services,cn=accounts,%s" % 
(self.principal, self.suffix)
         mod = [(ldap.MOD_ADD, 'userCertificate', self.dercert)]
@@ -268,33 +326,6 @@ class Service(object):
 
         self.steps = []
 
-    def __get_conn(self, fqdn, dm_password, ldapi=False, realm=None):
-        # If we are passed a password we'll use it as the DM password
-        # otherwise we'll do a GSSAPI bind.
-        try:
-#            conn = ipaldap.IPAdmin(fqdn, port=636, cacert=CACERT)
-            if ldapi:
-                conn = ipaldap.IPAdmin(ldapi=ldapi, realm=realm)
-            else:
-                conn = ipaldap.IPAdmin(fqdn, port=389)
-            if dm_password:
-                conn.do_simple_bind(bindpw=dm_password)
-            elif os.getegid() == 0 and self.ldapi:
-                try:
-                    # autobind
-                    pw_name = pwd.getpwuid(os.geteuid()).pw_name
-                    conn.do_external_bind(pw_name)
-                except errors.NotFound:
-                    # Fall back
-                    conn.do_sasl_gssapi_bind()
-            else:
-                conn.do_sasl_gssapi_bind()
-        except Exception, e:
-            root_logger.debug("Could not connect to the Directory Server on 
%s: %s" % (fqdn, str(e)))
-            raise e
-
-        return conn
-
     def ldap_enable(self, name, fqdn, dm_password, ldap_suffix):
         self.disable()
         if not self.admin_conn:
@@ -318,11 +349,14 @@ class Service(object):
             raise e
 
 class SimpleServiceInstance(Service):
-    def create_instance(self, gensvc_name=None, fqdn=None, dm_password=None, 
ldap_suffix=None):
+    def create_instance(self, gensvc_name=None, fqdn=None, dm_password=None, 
ldap_suffix=None, realm=None):
         self.gensvc_name = gensvc_name
         self.fqdn = fqdn
         self.dm_password = dm_password
         self.suffix = ldap_suffix
+        self.realm = realm
+        if not realm:
+            self.ldapi = False
 
         self.step("starting %s " % self.service_name, self.__start)
         self.step("configuring %s to start on boot" % self.service_name, 
self.__enable)
-- 
1.7.11.2

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to