On 01/21/2014 03:07 PM, Petr Viktorin wrote:
> On 01/16/2014 02:16 PM, Martin Kosek wrote:
>> [freeipa-mkosek-448-add-runas-option-to-run-function.patch]:
>>
>> Run function can now run the specified command as different user by
>> setting the EUID and EGID for executed process.
> 
> Please add the new argument to the docstring, otherwise ACK
> 
>> [freeipa-mkosek-449-switch-httpd-to-use-default-ccache.patch]:
>>
>> Stock httpd no longer uses systemd EnvironmentFile option which is
>> making FreeIPA's KRB5CCNAME setting ineffective. This can lead in hard
>> to debug problems during subsequent ipa-server-install's where HTTP
>> may use a stale CCACHE in the default kernel keyring CCACHE.
>>
>> Avoid forcing custom CCACHE and switch to system one, just make sure
>> that it is properly cleaned by kdestroy run as "apache" user during
>> FreeIPA server installation process.
>>
>> https://fedorahosted.org/freeipa/ticket/4084
> 
> This does not fix the issue for me.
> On a fresh f20 machine, I installed the server, uninstalled it, and installed
> again. The second installation failed with the ipa-client-install error
> described in the ticket.
> 

On your VM, I saw the method I use for running a command as different process
was indeed not effective. I had to change both effective and real UID/GID to
make the kdestroy function working.

I also added the missing docstrings in 448, both for runas as well as other
missing options.

Martin
From 3b6683c7a3da885350542157aae2afa0b3cdd37e Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Thu, 16 Jan 2014 14:10:42 +0100
Subject: [PATCH 1/2] Add runas option to run function

Run function can now run the specified command as different user by
setting the both real and effective UID and GID for executed process.

Add both the missing run function attribute doc strings as well as
a doc string for the runas attribute.
---
 ipapython/ipautil.py | 59 +++++++++++++++++++++++++++++++++-------------------
 1 file changed, 38 insertions(+), 21 deletions(-)

diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py
index a25dc358b9ddf9681925491ec1c4cd2de03d6b00..4ed32a6ad25daab2a606556cc0f532918abbfec1 100644
--- a/ipapython/ipautil.py
+++ b/ipapython/ipautil.py
@@ -42,6 +42,7 @@
 import netaddr
 import time
 import krbV
+import pwd
 from dns import resolver, rdatatype
 from dns.exception import DNSException
 
@@ -246,29 +247,35 @@ def shell_quote(string):
     return "'" + string.replace("'", "'\\''") + "'"
 
 def run(args, stdin=None, raiseonerr=True,
-        nolog=(), env=None, capture_output=True, skip_output=False, cwd=None):
+        nolog=(), env=None, capture_output=True, skip_output=False, cwd=None,
+        runas=None):
     """
     Execute a command and return stdin, stdout and the process return code.
 
-    args is a list of arguments for the command
-
-    stdin is used if you want to pass input to the command
-
-    raiseonerr raises an exception if the return code is not zero
-
-    nolog is a tuple of strings that shouldn't be logged, like passwords.
-    Each tuple consists of a string to be replaced by XXXXXXXX.
-
-    For example, the command ['/usr/bin/setpasswd', '--password', 'Secret123', 'someuser']
-
-    We don't want to log the password so nolog would be set to:
-    ('Secret123',)
-
-    The resulting log output would be:
-
-    /usr/bin/setpasswd --password XXXXXXXX someuser
-
-    If an value isn't found in the list it is silently ignored.
+    :param args: List of arguments for the command
+    :param stdin: Optional input to the command
+    :param: raiseonerr: If True, raises an exception if the return code is
+        not zero
+    :param nolog: Tuple of strings that shouldn't be logged, like passwords.
+        Each tuple consists of a string to be replaced by XXXXXXXX.
+
+        Example:
+        We have a command
+            ['/usr/bin/setpasswd', '--password', 'Secret123', 'someuser']
+        and we don't want to log the password so nolog would be set to:
+        ('Secret123',)
+        The resulting log output would be:
+
+        /usr/bin/setpasswd --password XXXXXXXX someuser
+
+        If an value isn't found in the list it is silently ignored.
+    :param env: Dictionary of environment variables passed to the command.
+        When None, current environment is copied
+    :param capture_output: Capture stderr and stdout
+    :param skip_output: Redirect the output to /dev/null and do not capture it
+    :param cwd: Current working directory
+    :param runas: Name of a user that the command shold be run as. The spawned
+        process will have both real and effective UID and GID set.
     """
     p_in = None
     p_out = None
@@ -298,9 +305,19 @@ def run(args, stdin=None, raiseonerr=True,
     root_logger.debug('Starting external process')
     root_logger.debug('args=%s' % arg_string)
 
+    preexec_fn = None
+    if runas is not None:
+        pent = pwd.getpwnam(runas)
+        root_logger.debug('runas=%s (UID %d, GID %s)', runas,
+            pent.pw_uid, pent.pw_gid)
+
+        preexec_fn = lambda: (os.setregid(pent.pw_gid, pent.pw_gid),
+                              os.setreuid(pent.pw_uid, pent.pw_uid))
+
     try:
         p = subprocess.Popen(args, stdin=p_in, stdout=p_out, stderr=p_err,
-                             close_fds=True, env=env, cwd=cwd)
+                             close_fds=True, env=env, cwd=cwd,
+                             preexec_fn=preexec_fn)
         stdout,stderr = p.communicate(stdin)
         stdout,stderr = str(stdout), str(stderr)    # Make pylint happy
     except KeyboardInterrupt:
-- 
1.8.4.2

From 82a348928962e2753c51a27b85957b6912a98a52 Mon Sep 17 00:00:00 2001
From: Martin Kosek <mko...@redhat.com>
Date: Thu, 16 Jan 2014 14:12:29 +0100
Subject: [PATCH 2/2] Switch httpd to use default CCACHE

Stock httpd no longer uses systemd EnvironmentFile option which is
making FreeIPA's KRB5CCNAME setting ineffective. This can lead in hard
to debug problems during subsequent ipa-server-install's where HTTP
may use a stale CCACHE in the default kernel keyring CCACHE.

Avoid forcing custom CCACHE and switch to system one, just make sure
that it is properly cleaned by kdestroy run as "apache" user during
FreeIPA server installation process.

https://fedorahosted.org/freeipa/ticket/4084
---
 install/tools/ipa-upgradeconfig   |  7 ++++++-
 ipaserver/install/httpinstance.py | 22 +++-------------------
 2 files changed, 9 insertions(+), 20 deletions(-)

diff --git a/install/tools/ipa-upgradeconfig b/install/tools/ipa-upgradeconfig
index ed4852c0daea9b5b0efa907c325fbb138800995c..b281eb4eaf31a3d97cb4668cf7d38ab1f3e0f815 100644
--- a/install/tools/ipa-upgradeconfig
+++ b/install/tools/ipa-upgradeconfig
@@ -1043,10 +1043,15 @@ def main():
     update_dbmodules(api.env.realm)
     uninstall_ipa_kpasswd()
 
+    removed_sysconfig_file = '/etc/sysconfig/httpd'
+    if fstore.has_file(removed_sysconfig_file):
+        root_logger.info('Restoring %s as it is no longer required',
+            removed_sysconfig_file)
+        fstore.restore_file(removed_sysconfig_file)
+
     http = httpinstance.HTTPInstance(fstore)
     http.remove_httpd_ccache()
     http.configure_selinux_for_httpd()
-    http.configure_httpd_ccache()
     http.change_mod_nss_port_from_http()
 
     ds = dsinstance.DsInstance()
diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py
index e61a0c6d1526f29acb4647710e559a5bb32a58c0..12cb2e013ee4f6104f6c366882945c25b4ffc696 100644
--- a/ipaserver/install/httpinstance.py
+++ b/ipaserver/install/httpinstance.py
@@ -126,7 +126,6 @@ def create_instance(self, realm, fqdn, domain_name, dm_password=None,
         self.step("creating a keytab for httpd", self.__create_http_keytab)
         self.step("clean up any existing httpd ccache", self.remove_httpd_ccache)
         self.step("configuring SELinux for httpd", self.configure_selinux_for_httpd)
-        self.step("configure httpd ccache", self.configure_httpd_ccache)
         self.step("restarting httpd", self.__start)
         self.step("configuring httpd to start on boot", self.__enable)
 
@@ -217,24 +216,9 @@ def __create_http_keytab(self):
 
     def remove_httpd_ccache(self):
         # Clean up existing ccache
-        pent = pwd.getpwnam("apache")
-        installutils.remove_file('/tmp/krb5cc_%d' % pent.pw_uid)
-
-    def configure_httpd_ccache(self):
-        pent = pwd.getpwnam("apache")
-        ccache = '/tmp/krb5cc_%d' % pent.pw_uid
-        filepath = '/etc/sysconfig/httpd'
-        if not os.path.exists(filepath):
-            # file doesn't exist; create it with correct ownership & mode
-            open(filepath, 'a').close()
-            os.chmod(filepath,
-                stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH)
-            os.chown(filepath, 0, 0)
-
-        replacevars = {'KRB5CCNAME': ccache}
-        old_values = ipautil.backup_config_and_replace_variables(
-            self.fstore, filepath, replacevars=replacevars)
-        ipaservices.restore_context(filepath)
+        # Make sure that empty env is passed to avoid passing KRB5CCNAME from
+        # current env
+        ipautil.run(['kdestroy'], runas='apache', raiseonerr=False, env={})
 
     def __configure_http(self):
         target_fname = '/etc/httpd/conf.d/ipa.conf'
-- 
1.8.4.2

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

Reply via email to