On 03/24/2014 03:27 PM, Jan Pazdziora wrote:
> On Mon, Mar 24, 2014 at 02:57:30PM +0100, Martin Kosek wrote:
>> On 03/24/2014 02:47 PM, Jan Pazdziora wrote:
>>> On Mon, Mar 03, 2014 at 08:24:41PM +0100, Tomas Babej wrote:
>>>> Hi,
>>>>
>>>> Makes ipa-client-install configure SSSD as the data provider
>>>> for the sudo service by default. This behaviour can be disabled
>>>> by using --no-sudo flag.
>>>>
>>>> https://fedorahosted.org/freeipa/ticket/3358
>>> Ack.
>>>
>>> Applied against ipa-client-3.0.0-37.el6.x86_64, tried without
>>> --no-sudo and sudo was added to sssd.conf's services list and sudoeers
>>> added to /etc/nsswitch.conf.
>>>
>>> Rerun with --uninstall and run again with the --no-sudo parameter,
>>> those settings were not longer there.
>>>
>> Did you also do the functional test?
> No. I do not want to get dragged into the discussion of having the
> correct sssd and sudo and glibc versions and SELinux and stuff. The
> ticket explicitly talk about setting configuration in config files,
> which the patch does.
>
>> To ack and push this ticket, following
>> scenario needs to work:
> Consumption of those configuration changes is really different story,
> isn't it?
>
>> 1) IPA clients enroll against IPA server without --no-sudo
>> 2) IPA client user logs in, types "sudo -l", gets all allowed commands
>> (prerequisite is of course to have sudo commands defined on the IPA server)
>> 3) IPA client reboots, IPA client user logs in, types "sudo -l", gets all
>> allowed commands
>>
>> For 2) to work, NIS domain name must be set, nsswitch and SSSD changes must 
>> be done
>>
>> For 3) to work, related systemd service preserving NIS domain name setting
>> needs to be enabled
> With the commit message only talking about configuring sssd, I assume
> the NIS domain name mentioned in the ticket will be done by some other
> patch.
>
> To me, the patch does what is advertised in the commit message, and is
> in line with what the ticket asks to be done.
>

Attached are rebased versions of the patches 113 and 167 (which was
marked as 157 in the thread previously by mistake).

There is a slight behaviour change in 167, if there is no sudoers line
in nsswitch.conf, we add both files and sss as sudoers sources.

I also developed CI test that covers the functionality of the IPA - sudo
integration feature, which is attached.

Please note that the last three tests are expected to fail until:

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

is fixed.

-- 
Tomas Babej
Associate Software Engineer | Red Hat | Identity Management
RHCE | Brno Site | IRC: tbabej | freeipa.org 

>From 0803c29840a79463fa838478bab65a061d779163 Mon Sep 17 00:00:00 2001
From: Tomas Babej <tomasba...@gmail.com>
Date: Thu, 21 Nov 2013 13:09:28 +0100
Subject: [PATCH] ipa-client-install: Configure sudo to use SSSD as data source

Makes ipa-client-install configure SSSD as the data provider
for the sudo service by default. This behaviour can be disabled
by using --no-sudo flag.

https://fedorahosted.org/freeipa/ticket/3358
---
 ipa-client/ipa-install/ipa-client-install | 58 ++++++++++++++++++++++++++++++-
 ipa-client/man/ipa-client-install.1       |  3 ++
 2 files changed, 60 insertions(+), 1 deletion(-)

diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 5fdd51520ba667f240239077a80e328877c99cd7..99fed2ab08195c7dfe4fb876ce225bac7868eb3b 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -137,6 +137,9 @@ def parse_options():
                       help="do not configure OpenSSH client")
     basic_group.add_option("--no-sshd", dest="conf_sshd", default=True, action="store_false",
                       help="do not configure OpenSSH server")
+    basic_group.add_option("--no-sudo", dest="conf_sudo", default=True,
+                      action="store_false",
+                      help="do not configure SSSD as data source for sudo")
     basic_group.add_option("--no-dns-sshfp", dest="create_sshfp", default=True, action="store_false",
                       help="do not automatically create DNS SSHFP records")
     basic_group.add_option("--noac", dest="no_ac", default=False, action="store_true",
@@ -1141,6 +1144,59 @@ def configure_sssd_conf(fstore, cli_realm, cli_domain, cli_server, options, clie
 
         sssdconfig.activate_service('ssh')
 
+    if options.conf_sudo:
+        # Activate the service in the SSSD config
+        try:
+            sssdconfig.new_service('sudo')
+        except SSSDConfig.ServiceAlreadyExists:
+            pass
+        except SSSDConfig.ServiceNotRecognizedError:
+            root_logger.error("Unable to activate the SUDO service in "
+                              "SSSD config.")
+
+        sssdconfig.activate_service('sudo')
+
+        # Backup the nsswitch.conf, we're going to edit it now
+        NSSWITCH_CONF = '/etc/nsswitch.conf'
+        fstore.backup_file(NSSWITCH_CONF)
+
+        conf = ipaclient.ipachangeconf.IPAChangeConf("IPA Installer")
+        conf.setOptionAssignment(':')
+
+        # Determine if nsswitch already contains files for sudoers or not
+        sudoers_value = ' sss'
+
+        with open('/etc/nsswitch.conf', 'r') as f:
+            opts = conf.parse(f)
+            option_result = conf.findOpts(opts, 'option', 'sudoers')[1]
+
+            if not option_result:
+                # If there is no sudoers: directive in the nsswitch.conf
+                # present, set both files and sss, since sudo treats
+                # sudoers: files as default
+                sudoers_value = ' files sss'
+            elif 'sss' not in option_result['value']:
+                # If some explicit value is set in nsswitch.conf, we just append
+                # sss if not already there
+                sudoers_value = option_result['value'] + ' sss'
+            else:
+                # If sss is already set, do nothing
+                sudoers_value = option_result['value']
+
+        # Set sss as data source for sudoers
+        opts = [{'name':'sudoers',
+                 'type':'option',
+                 'action':'set',
+                 'value': sudoers_value
+                },
+                {'name':'empty',
+                 'type':'empty'
+                }]
+
+        conf.changeConf(NSSWITCH_CONF, opts)
+        root_logger.info("Configured %s" % NSSWITCH_CONF)
+
+
     domain.add_provider('ipa', 'id')
 
     #add discovery domain if client domain different from server domain
@@ -2265,7 +2321,7 @@ def install(options, env, fstore, statestore):
         # skip this step when run by ipa-server-install as it always configures
         # hostname if different from system hostname
         ipaservices.backup_and_replace_hostname(fstore, statestore, options.hostname)
-   
+
     if not options.on_master:
         # Attempt to sync time with IPA server.
         # We assume that NTP servers are discoverable through SRV records in the DNS
diff --git a/ipa-client/man/ipa-client-install.1 b/ipa-client/man/ipa-client-install.1
index 9d1ab75e4b20f3422e0e8dbd7728fcc281972362..42db4e4c327bee7f2f5512a53dc3c445c4ed5e29 100644
--- a/ipa-client/man/ipa-client-install.1
+++ b/ipa-client/man/ipa-client-install.1
@@ -140,6 +140,9 @@ Do not configure OpenSSH client.
 \fB\-\-no\-sshd\fR
 Do not configure OpenSSH server.
 .TP
+\fB\-\-no\-sudo\fR
+Do not configure SSSD as a data source for sudo.
+.TP
 \fB\-\-no\-dns\-sshfp\fR
 Do not automatically create DNS SSHFP records.
 .TP
-- 
1.8.5.3

>From 50b3271d8f05e3d1e55ae4b80a41949881fc72d2 Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Tue, 8 Apr 2014 13:14:13 +0200
Subject: [PATCH] ipatests: Add Sudo integration test

---
 ipatests/test_integration/tasks.py     |   2 +-
 ipatests/test_integration/test_sudo.py | 335 +++++++++++++++++++++++++++++++++
 2 files changed, 336 insertions(+), 1 deletion(-)
 create mode 100644 ipatests/test_integration/test_sudo.py

diff --git a/ipatests/test_integration/tasks.py b/ipatests/test_integration/tasks.py
index 2334e254e7ddd00beeb83d8a317b5db12c06a29e..a6c6f30d4c459de979f20aebd28276623ba2f700 100644
--- a/ipatests/test_integration/tasks.py
+++ b/ipatests/test_integration/tasks.py
@@ -430,7 +430,7 @@ def clear_sssd_cache(host):
         host.run_command(['/sbin/service', 'sssd', 'start'])
 
     # To avoid false negatives due to SSSD not responding yet
-    time.sleep(2)
+    time.sleep(10)
 
 
 def sync_time(host, server):
diff --git a/ipatests/test_integration/test_sudo.py b/ipatests/test_integration/test_sudo.py
new file mode 100644
index 0000000000000000000000000000000000000000..42c9b6b6a160e0449e734f176ff437c6e8f486fc
--- /dev/null
+++ b/ipatests/test_integration/test_sudo.py
@@ -0,0 +1,335 @@
+# Authors:
+#   Tomas Babej <tba...@redhat.com>
+#
+# Copyright (C) 2014  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/>.
+
+from ipatests.test_integration.base import IntegrationTest
+from ipatests.test_integration.tasks import clear_sssd_cache
+
+
+class TestSudo(IntegrationTest):
+    """
+    Test Sudo
+    http://www.freeipa.org/page/V4/Sudo_Integration#Test_Plan
+    """
+    num_clients = 1
+    topology = 'line'
+
+    @classmethod
+    def setup_class(cls):
+        super(TestSudo, cls).setup_class()
+
+        cls.client = cls.clients[0]
+
+        for i in range(1, 3):
+            # Add 1. and 2. testing user
+            cls.master.run_command(['ipa', 'user-add',
+                                     'testuser%d' % i,
+                                     '--first', 'Test',
+                                     '--last', 'User%d' % i])
+
+            # Add 1. and 2. testing groups
+            cls.master.run_command(['ipa', 'group-add',
+                                     'testgroup%d' % i,
+                                     '--desc', '"%d. testing group"' % i])
+
+            # Add respective members to each group
+            cls.master.run_command(['ipa', 'group-add-member',
+                                     'testgroup%d' % i,
+                                     '--users', 'testuser%d' % i])
+
+        # Add hostgroup containing the client
+        cls.master.run_command(['ipa', 'hostgroup-add',
+                                 'testhostgroup',
+                                 '--desc', '"Contains client"'])
+
+        # Add the client to the host group
+        cls.master.run_command(['ipa', 'hostgroup-add-member',
+                                 'testhostgroup',
+                                 '--hosts', cls.client.hostname])
+
+    def list_sudo_commands(self, user, raiseonerr=False, verbose=False):
+        clear_sssd_cache(self.client)
+        list_flag = '-ll' if verbose else '-l'
+        return self.client.run_command('su -c "sudo %s" %s' % (list_flag, user),
+                                       raiseonerr=raiseonerr)
+
+    def reset_rule_categories(self):
+        # Reset testrule to allow everything
+        self.master.run_command(['ipa', 'sudorule-mod',
+                                 'testrule',
+                                 '--usercat=all',
+                                 '--hostcat=all',
+                                 '--cmdcat=all',
+                                 '--runasusercat=all',
+                                 '--runasgroupcat=all'], raiseonerr=False)
+
+    def test_nisdomainname(self):
+        result = self.client.run_command('nisdomainname')
+        assert self.client.domain.name in result.stdout_text
+
+    def test_add_sudo_commands(self):
+        # Group: Readers
+        self.master.run_command(['ipa', 'sudocmd-add', '/usr/bin/cat'])
+        self.master.run_command(['ipa', 'sudocmd-add', '/usr/bin/tail'])
+
+        # No group
+        self.master.run_command(['ipa', 'sudocmd-add', '/usr/bin/yum'])
+
+    def test_add_sudo_command_groups(self):
+        self.master.run_command(['ipa', 'sudocmdgroup-add', 'readers',
+                                 '--desc', '"Applications that read"'])
+
+        self.master.run_command(['ipa', 'sudocmdgroup-add-member', 'readers',
+                                 '--sudocmds', '/usr/bin/cat'])
+
+        self.master.run_command(['ipa', 'sudocmdgroup-add-member', 'readers',
+                                 '--sudocmds', '/usr/bin/tail'])
+
+    def test_create_allow_all_rule(self):
+        # Create rule that allows everything
+        self.master.run_command(['ipa', 'sudorule-add',
+                                 'testrule',
+                                 '--usercat=all',
+                                 '--hostcat=all',
+                                 '--cmdcat=all',
+                                 '--runasusercat=all',
+                                 '--runasgroupcat=all'])
+
+        # Add !authenticate option
+        self.master.run_command(['ipa', 'sudorule-add-option',
+                                 'testrule',
+                                 '--sudooption', "!authenticate"])
+
+    def test_add_sudo_rule(self):
+        result1 = self.list_sudo_commands("testuser1")
+        assert "(ALL) NOPASSWD: ALL" in result1.stdout_text
+
+        result2 = self.list_sudo_commands("testuser2")
+        assert "(ALL) NOPASSWD: ALL" in result2.stdout_text
+
+    def test_sudo_rule_restricted_to_one_user_setup(self):
+        # Configure the rule to not apply to anybody
+        self.master.run_command(['ipa', 'sudorule-mod',
+                                 'testrule',
+                                 '--usercat='])
+
+        # Add the testuser1 to the rule
+        self.master.run_command(['ipa', 'sudorule-add-user',
+                                 'testrule',
+                                 '--users', 'testuser1'])
+
+    def test_sudo_rule_restricted_to_one_user(self):
+        result1 = self.list_sudo_commands("testuser1")
+        assert "(ALL) NOPASSWD: ALL" in result1.stdout_text
+
+        result2 = self.list_sudo_commands("testuser2", raiseonerr=False)
+        assert result2.returncode != 0
+
+    def test_sudo_rule_restricted_to_one_user_teardown(self):
+        # Remove the testuser1 from the rule
+        self.master.run_command(['ipa', 'sudorule-remove-user',
+                                 'testrule',
+                                 '--users', 'testuser1'])
+
+    def test_sudo_rule_restricted_to_one_group_setup(self):
+        # Add the testgroup2 to the rule
+        self.master.run_command(['ipa', 'sudorule-add-user',
+                                 'testrule',
+                                 '--groups', 'testgroup2'])
+
+    def test_sudo_rule_restricted_to_one_group(self):
+        result1 = self.list_sudo_commands("testuser1", raiseonerr=False)
+        assert result1.returncode != 0
+
+        result2 = self.list_sudo_commands("testuser2")
+        assert "(ALL) NOPASSWD: ALL" in result2.stdout_text
+
+    def test_sudo_rule_restricted_to_one_group_teardown(self):
+        # Remove the testgroup2 from the rule
+        self.master.run_command(['ipa', 'sudorule-remove-user',
+                                 'testrule',
+                                 '--groups', 'testgroup2'])
+
+    def test_sudo_rule_restricted_to_one_host_negative_setup(self):
+        # Reset testrule configuration
+        self.reset_rule_categories()
+
+        # Configure the rule to not apply anywhere
+        self.master.run_command(['ipa', 'sudorule-mod',
+                                 'testrule',
+                                 '--hostcat='])
+
+        # Add the master to the rule
+        self.master.run_command(['ipa', 'sudorule-add-host',
+                                 'testrule',
+                                 '--hosts', self.master.hostname])
+
+    def test_sudo_rule_restricted_to_one_host_negative(self):
+        result1 = self.list_sudo_commands("testuser1", raiseonerr=False)
+        assert result1.returncode != 0
+
+    def test_sudo_rule_restricted_to_one_host_negative_teardown(self):
+        # Remove the master from the rule
+        self.master.run_command(['ipa', 'sudorule-remove-host',
+                                 'testrule',
+                                 '--hosts', self.master.hostname])
+
+    def test_sudo_rule_restricted_to_one_host_setup(self):
+        # Configure the rulle to not apply anywhere
+        self.master.run_command(['ipa', 'sudorule-mod',
+                                 'testrule',
+                                 '--hostcat='], raiseonerr=False)
+
+        # Add the master to the rule
+        self.master.run_command(['ipa', 'sudorule-add-host',
+                                 'testrule',
+                                 '--hosts', self.client.hostname])
+
+    def test_sudo_rule_restricted_to_one_host(self):
+        result1 = self.list_sudo_commands("testuser1", raiseonerr=False)
+        assert "(ALL) NOPASSWD: ALL" in result1.stdout_text
+
+    def test_sudo_rule_restricted_to_one_host_teardown(self):
+        # Remove the master from the rule
+        self.master.run_command(['ipa', 'sudorule-remove-host',
+                                 'testrule',
+                                 '--hosts', self.client.hostname])
+
+    def test_sudo_rule_restricted_to_one_hostgroup_setup(self):
+        # Add the testhostgroup to the rule
+        self.master.run_command(['ipa', 'sudorule-add-host',
+                                 'testrule',
+                                 '--hostgroups', 'testhostgroup'])
+
+    def test_sudo_rule_restricted_to_one_hostgroup(self):
+        result1 = self.list_sudo_commands("testuser1")
+        assert "(ALL) NOPASSWD: ALL" in result1.stdout_text
+
+    def test_sudo_rule_restricted_to_one_hostgroup_teardown(self):
+        # Remove the testhostgroup from the rule
+        self.master.run_command(['ipa', 'sudorule-remove-host',
+                                 'testrule',
+                                 '--hostgroups', 'testhostgroup'])
+
+    def test_sudo_rule_restricted_to_one_command_setup(self):
+        # Reset testrule configuration
+        self.reset_rule_categories()
+
+        # Configure the rule to not allow any command
+        self.master.run_command(['ipa', 'sudorule-mod',
+                                 'testrule',
+                                 '--cmdcat='])
+
+        # Add the yum command to the rule
+        self.master.run_command(['ipa', 'sudorule-add-allow-command',
+                                 'testrule',
+                                 '--sudocmds', '/usr/bin/yum'])
+
+    def test_sudo_rule_restricted_to_one_command(self):
+        result1 = self.list_sudo_commands("testuser1")
+        assert "(ALL) NOPASSWD: /usr/bin/yum" in result1.stdout_text
+
+    def test_sudo_rule_restricted_to_command_and_command_group_setup(self):
+        # Add the readers command group to the rule
+        self.master.run_command(['ipa', 'sudorule-add-allow-command',
+                                 'testrule',
+                                 '--sudocmdgroups', 'readers'])
+
+    def test_sudo_rule_restricted_to_command_and_command_group(self):
+        result1 = self.list_sudo_commands("testuser1")
+        assert "(ALL) NOPASSWD:" in result1.stdout_text
+        assert "/usr/bin/yum" in result1.stdout_text
+        assert "/usr/bin/tail" in result1.stdout_text
+        assert "/usr/bin/cat" in result1.stdout_text
+
+    def test_sudo_rule_restricted_to_command_and_command_group_teardown(self):
+        # Remove the yum command from the rule
+        self.master.run_command(['ipa', 'sudorule-remove-allow-command',
+                                 'testrule',
+                                 '--sudocmds', '/usr/bin/yum'])
+
+        # Remove the readers command group from the rule
+        self.master.run_command(['ipa', 'sudorule-remove-allow-command',
+                                 'testrule',
+                                 '--sudocmdgroups', 'readers'])
+
+    def test_sudo_rule_restricted_to_running_as_single_user_setup(self):
+        # Reset testrule configuration
+        self.reset_rule_categories()
+
+        # Configure the rule to not allow running commands as anybody
+        self.master.run_command(['ipa', 'sudorule-mod',
+                                 'testrule',
+                                 '--runasusercat='])
+
+        self.master.run_command(['ipa', 'sudorule-mod',
+                                 'testrule',
+                                 '--runasgroupcat='])
+
+        # Allow running commands as testuser2
+        self.master.run_command(['ipa', 'sudorule-add-runasuser',
+                                 'testrule',
+                                 '--users', 'testuser2'])
+
+    def test_sudo_rule_restricted_to_running_as_single_user(self):
+        result1 = self.list_sudo_commands("testuser1", verbose=True)
+        assert "RunAsUsers: testuser2" in result1.stdout_text
+        assert "RunAsGroups:" not in result1.stdout_text
+
+    def test_sudo_rule_restricted_to_running_as_single_user_teardown(self):
+        # Remove permission to run commands as testuser2
+        self.master.run_command(['ipa', 'sudorule-remove-runasuser',
+                                 'testrule',
+                                 '--users', 'testuser2'])
+
+    def test_sudo_rule_restricted_to_running_as_users_from_group_setup(self):
+        # Allow running commands as users from testgroup2
+        self.master.run_command(['ipa', 'sudorule-add-runasuser',
+                                 'testrule',
+                                 '--groups', 'testgroup2'])
+
+    def test_sudo_rule_restricted_to_running_as_users_from_group(self):
+        result1 = self.list_sudo_commands("testuser1", verbose=True)
+        assert "RunAsUsers: testuser2" in result1.stdout_text
+        assert "RunAsGroups:" not in result1.stdout_text
+
+    def test_sudo_rule_restricted_to_running_as_users_from_group_teardown(self):
+        # Remove permission to run commands as testuser2
+        self.master.run_command(['ipa', 'sudorule-remove-runasuser',
+                                 'testrule',
+                                 '--groups', 'testgroup2'])
+
+    def test_sudo_rule_restricted_to_running_as_single_group_setup(self):
+        # Allow running commands as testgroup2
+        self.master.run_command(['ipa', 'sudorule-add-runasgroup',
+                                 'testrule',
+                                 '--groups', 'testgroup2'])
+
+    def test_sudo_rule_restricted_to_running_as_single_group(self):
+        result1 = self.list_sudo_commands("testuser1", verbose=True)
+        assert "RunAsUsers:" not in result1.stdout_text
+        assert "RunAsGroups: testgroup2" in result1.stdout_text
+
+    def test_sudo_rule_restricted_to_running_as_single_group_teardown(self):
+        # Remove permission to run commands as testgroup2
+        self.master.run_command(['ipa', 'sudorule-remove-runasgroup',
+                                 'testrule',
+                                 '--groups', 'testgroup2'])
+
+        # Reset testrule configuration
+        self.reset_rule_categories()
-- 
1.8.5.3

>From 3b66934f1dd3167dc56ffa8b4a750a0912a89642 Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Wed, 25 Sep 2013 13:45:45 +0200
Subject: [PATCH] ipa-client: Set NIS domain name in the installer

Provides two new options for the ipa-client-install:
    --nisdomain: specifies the NIS domain name
    --no_nisdomain: flag to aviod setting the NIS domain name

In case no --nisdomain is specified and --no_nisdomain flag was
not set, the IPA domain is used.

Manual pages updated.

http://fedorahosted.org/freeipa/ticket/3202
---
 ipa-client/ipa-install/ipa-client-install | 65 +++++++++++++++++++++++++++++++
 ipa-client/man/ipa-client-install.1       |  6 +++
 ipapython/platform/base/__init__.py       |  3 +-
 ipapython/platform/fedora16/service.py    |  2 +
 4 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index 7cc0c33973fb9bd2113b33da7cb1d450b66a49dd..03679c10d09c64a284e3950a1808887ec52ae5ea 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -126,6 +126,11 @@ def parse_options():
     basic_group.add_option("", "--force-ntpd", dest="force_ntpd",
                       action="store_true", default=False,
                       help="Stop and disable any time&date synchronization services besides ntpd")
+    basic_group.add_option("--nisdomain", dest="nisdomain",
+                           help="NIS domain name")
+    basic_group.add_option("--no-nisdomain", action="store_true", default=False,
+                      help="do not configure NIS domain name",
+                      dest="no_nisdomain")
     basic_group.add_option("--ssh-trust-dns", dest="trust_sshfp", default=False, action="store_true",
                       help="configure OpenSSH client to trust DNS SSHFP records")
     basic_group.add_option("--no-ssh", dest="conf_ssh", default=True, action="store_false",
@@ -195,6 +200,9 @@ def parse_options():
     if options.firefox_dir and not options.configure_firefox:
         parser.error("--firefox-dir cannot be used without --configure-firefox option")
 
+    if options.no_nisdomain and options.nisdomain:
+        parser.error("--no-nisdomain cannot be used together with --nisdomain")
+
     return safe_opts, options
 
 def logging_setup(options):
@@ -595,6 +603,7 @@ def uninstall(options, env):
         fstore.restore_all_files()
 
     ipautil.restore_hostname(statestore)
+    unconfigure_nisdomain()
 
     nscd = ipaservices.knownservices.nscd
     nslcd = ipaservices.knownservices.nslcd
@@ -1351,6 +1360,59 @@ def configure_automount(options):
         root_logger.info(stdout)
 
 
+def configure_nisdomain(options, domain):
+    domain = options.nisdomain or domain
+    root_logger.info('Configuring %s as NIS domain.' % domain)
+
+    nis_domain_name = ''
+
+    # First backup the old NIS domain name
+    if os.path.exists('/usr/bin/nisdomainname'):
+        try:
+            nis_domain_name, _, _ = ipautil.run(['/usr/bin/nisdomainname'])
+        except CalledProcessError, e:
+            pass
+
+    statestore.backup_state('network', 'nisdomain', nis_domain_name)
+
+    # Backup the state of the domainname service
+    statestore.backup_state("domainname", "enabled",
+                            ipaservices.knownservices.domainname.is_enabled())
+
+    # Set the new NIS domain name
+    set_nisdomain(domain)
+
+    # Enable and start the domainname service
+    ipaservices.knownservices.domainname.enable()
+    ipaservices.knownservices.domainname.start()
+
+
+def unconfigure_nisdomain():
+    # Set the nisdomain permanent and current nisdomain configuration as it was
+    if statestore.has_state('network'):
+        old_nisdomain = statestore.restore_state('network','nisdomain') or ''
+
+        if old_nisdomain:
+            root_logger.info('Restoring %s as NIS domain.' % old_nisdomain)
+        else:
+            root_logger.info('Unconfiguring the NIS domain.')
+
+        set_nisdomain(old_nisdomain)
+
+    # Restore the configuration of the domainname service
+    enabled = statestore.restore_state('domainname', 'enabled')
+    if not enabled:
+        ipaservices.knownservices.domainname.disable()
+
+
+def set_nisdomain(nisdomain):
+    # Let authconfig setup the permanent configuration
+    auth_config = ipaservices.authconfig()
+    auth_config.add_parameter("nisdomain", nisdomain)
+    auth_config.add_option("update")
+    auth_config.execute()
+
+
 def resolve_ipaddress(server):
     """ Connect to the server's LDAP port in order to determine what ip
         address this machine uses as "public" ip (relative to the server).
@@ -2693,6 +2755,9 @@ def install(options, env, fstore, statestore):
     if options.configure_firefox:
         configure_firefox(options, statestore, cli_domain)
 
+    if not options.no_nisdomain:
+        configure_nisdomain(options=options, domain=cli_domain)
+
     root_logger.info('Client configuration complete.')
 
     return 0
diff --git a/ipa-client/man/ipa-client-install.1 b/ipa-client/man/ipa-client-install.1
index 51a276202ac28b630d928e70dd658fad929b8d2b..a7acf58e532d4d39abd6db0bd5c38a74a708ee3e 100644
--- a/ipa-client/man/ipa-client-install.1
+++ b/ipa-client/man/ipa-client-install.1
@@ -122,6 +122,12 @@ Do not configure or enable NTP.
 \fB\-\-force\-ntpd\fR
 Stop and disable any time&date synchronization services besides ntpd.
 .TP
+\fB\-\-nisdomain\fR=\fINIS_DOMAIN\fR
+Set the NIS domain name as specified. By default, this is set to the IPA domain name.
+.TP
+\fB\-\-no\-nisdomain\fR
+Do not configure NIS domain name.
+.TP
 \fB\-\-ssh\-trust\-dns\fR
 Configure OpenSSH client to trust DNS SSHFP records.
 .TP
diff --git a/ipapython/platform/base/__init__.py b/ipapython/platform/base/__init__.py
index c1b076b2cb0c4c365447377725e55966650ce116..f988c7127b0395f962faeb3fd16b853c4df62016 100644
--- a/ipapython/platform/base/__init__.py
+++ b/ipapython/platform/base/__init__.py
@@ -27,7 +27,8 @@ import os
 wellknownservices = ['certmonger', 'dirsrv', 'httpd', 'ipa', 'krb5kdc',
                      'messagebus', 'nslcd', 'nscd', 'ntpd', 'portmap',
                      'rpcbind', 'kadmin', 'sshd', 'autofs', 'rpcgssd',
-                     'rpcidmapd', 'pki_tomcatd', 'pki_cad', 'chronyd']
+                     'rpcidmapd', 'pki_tomcatd', 'pki_cad', 'chronyd',
+                     'domainname']
 
 # System may support more time&date services. FreeIPA supports ntpd only, other
 # services will be disabled during IPA installation
diff --git a/ipapython/platform/fedora16/service.py b/ipapython/platform/fedora16/service.py
index edf2d7ff824399171f59a72a9b8fb49b1c4b08df..41c241ae5c31df56544b5b2bebd71c5ef109dd6e 100644
--- a/ipapython/platform/fedora16/service.py
+++ b/ipapython/platform/fedora16/service.py
@@ -54,6 +54,8 @@ system_units['pki_cad'] = system_units['pki-cad']
 system_units['pki-tomcatd'] = 'pki-tomcatd@pki-tomcat.service'
 system_units['pki_tomcatd'] = system_units['pki-tomcatd']
 system_units['ipa-otpd'] = 'ipa-otpd.socket'
+# Service that sets domainname on Fedora is called fedora-domainname.service
+system_units['domainname'] = 'fedora-domainname.service'
 
 class Fedora16Service(systemd.SystemdService):
     def __init__(self, service_name):
-- 
1.8.5.3

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

Reply via email to