#7907 ipa-replica-install due to permission error, leaves ipa server in unstable condition
Closed: fixed 4 years ago by rcritten. Opened 4 years ago by fcami.

On Fedora 30, the following issue was reported. However I was not able to reproduce it directly on a replica install (see below for an explanation).

During ipa-replica-install:

2019-04-09T18:46:05Z DEBUG   [5/28]: configuring certificate server instance
2019-04-09T18:46:05Z DEBUG Traceback (most recent call last):
  File "/usr/lib/python3.7/site-packages/ipaserver/install/service.py", line 605, in start_creation
    run_step(full_msg, method)
  File "/usr/lib/python3.7/site-packages/ipaserver/install/service.py", line 591, in run_step
    method()
  File "/usr/lib/python3.7/site-packages/ipaserver/install/cainstance.py", line 600, in __spawn_instance
    shutil.copy(cafile, paths.TMP_CA_P12)
  File "/usr/lib64/python3.7/shutil.py", line 245, in copy
    copyfile(src, dst, follow_symlinks=follow_symlinks)
  File "/usr/lib64/python3.7/shutil.py", line 121, in copyfile
    with open(dst, 'wb') as fdst:
PermissionError: [Errno 13] Permission denied: '/tmp/ca.p12'

2019-04-09T18:46:05Z DEBUG   [error] PermissionError: [Errno 13] Permission denied: '/tmp/ca.p12'
2019-04-09T18:46:05Z DEBUG Removing /root/.dogtag/pki-tomcat/ca
2019-04-09T18:46:05Z DEBUG   File "/usr/lib/python3.7/site-packages/ipapython/admintool.py", line 179, in execute
    return_value = self.run()
  File "/usr/lib/python3.7/site-packages/ipapython/install/cli.py", line 347, in run
    return cfgr.run()
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 360, in run
    return self.execute()
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 386, in execute
    for rval in self._executor():
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 431, in __runner
    exc_handler(exc_info)
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 460, in _handle_execute_exception
    self._handle_exception(exc_info)
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 450, in _handle_exception
    six.reraise(*exc_info)
  File "/usr/lib/python3.7/site-packages/six.py", line 693, in reraise
    raise value
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 421, in __runner
    step()
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 418, in <lambda>
    step = lambda: next(self.__gen)
  File "/usr/lib/python3.7/site-packages/ipapython/install/util.py", line 81, in run_generator_with_yield_from
    six.reraise(*exc_info)
  File "/usr/lib/python3.7/site-packages/six.py", line 693, in reraise
    raise value
  File "/usr/lib/python3.7/site-packages/ipapython/install/util.py", line 59, in run_generator_with_yield_from
    value = gen.send(prev_value)
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 655, in _configure
    next(executor)
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 431, in __runner
    exc_handler(exc_info)
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 460, in _handle_execute_exception
    self._handle_exception(exc_info)
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 518, in _handle_exception
    self.__parent._handle_exception(exc_info)
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 450, in _handle_exception
    six.reraise(*exc_info)
  File "/usr/lib/python3.7/site-packages/six.py", line 693, in reraise
    raise value
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 515, in _handle_exception
    super(ComponentBase, self)._handle_exception(exc_info)
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 450, in _handle_exception
    six.reraise(*exc_info)
  File "/usr/lib/python3.7/site-packages/six.py", line 693, in reraise
    raise value
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 421, in __runner
    step()
  File "/usr/lib/python3.7/site-packages/ipapython/install/core.py", line 418, in <lambda>
    step = lambda: next(self.__gen)
  File "/usr/lib/python3.7/site-packages/ipapython/install/util.py", line 81, in run_generator_with_yield_from
    six.reraise(*exc_info)
  File "/usr/lib/python3.7/site-packages/six.py", line 693, in reraise
    raise value
  File "/usr/lib/python3.7/site-packages/ipapython/install/util.py", line 59, in run_generator_with_yield_from
    value = gen.send(prev_value)
  File "/usr/lib/python3.7/site-packages/ipapython/install/common.py", line 65, in _install
    for unused in self._installer(self.parent):
  File "/usr/lib/python3.7/site-packages/ipaserver/install/server/__init__.py", line 583, in main
    replica_install(self)
  File "/usr/lib/python3.7/site-packages/ipaserver/install/server/replicainstall.py", line 400, in decorated
    func(installer)
  File "/usr/lib/python3.7/site-packages/ipaserver/install/server/replicainstall.py", line 1262, in install
    ca.install(False, config, options, custodia=custodia)
  File "/usr/lib/python3.7/site-packages/ipaserver/install/ca.py", line 239, in install
    install_step_0(standalone, replica_config, options, custodia=custodia)
  File "/usr/lib/python3.7/site-packages/ipaserver/install/ca.py", line 318, in install_step_0
    use_ldaps=standalone)
  File "/usr/lib/python3.7/site-packages/ipaserver/install/cainstance.py", line 484, in configure_instance
    self.start_creation(runtime=runtime)
  File "/usr/lib/python3.7/site-packages/ipaserver/install/service.py", line 605, in start_creation
    run_step(full_msg, method)
  File "/usr/lib/python3.7/site-packages/ipaserver/install/service.py", line 591, in run_step
    method()
  File "/usr/lib/python3.7/site-packages/ipaserver/install/cainstance.py", line 600, in __spawn_instance
    shutil.copy(cafile, paths.TMP_CA_P12)
  File "/usr/lib64/python3.7/shutil.py", line 245, in copy
    copyfile(src, dst, follow_symlinks=follow_symlinks)
  File "/usr/lib64/python3.7/shutil.py", line 121, in copyfile
    with open(dst, 'wb') as fdst:

The following in cainstance.py (and possibly elsewhere):

            cafile = self.pkcs12_info[0]
            shutil.copy(cafile, paths.TMP_CA_P12)

will break when fs.protected_regular=1 + /tmp/ca.p12 already exists and is owned by anybody but root:root.
This can happen on a system where a previous replica install failed, leaving that file in /tmp.

Proposal is to protect that shutil.copy call by checking if the target file exists, and if yes, chown it to root:root beforehand.


Metadata Update from @fcami:
- Custom field rhbz adjusted to https://bugzilla.redhat.com/show_bug.cgi?id=1698188

4 years ago

Reproducer:

# touch /tmp/ca.p12
# chown pkiuser:pkiuser /tmp/ca.p12
# ipa-replica-install ...

Configuring certificate server (pki-tomcatd). Estimated time: 3 minutes
  [1/28]: creating certificate server db
  [2/28]: setting up initial replication
Starting replication, please wait until this has completed.
Update in progress, 4 seconds elapsed
Update succeeded

  [3/28]: creating ACIs for admin
  [4/28]: creating installation admin user
  [5/28]: configuring certificate server instance
  [error] PermissionError: [Errno 13] Permission denied: '/tmp/ca.p12'
Your system may be partly configured.

It looks like /tmp/ca.p12 can be left over from a previously failed installation, leading to all subsequent installs to fail.

The shutil.copy() operation fails, because the function opens the file in truncating write mode. A better workaround would be to unlink the file first and ignore ENOENT.

The implementation has a bunch of code smells:

  • The file should not be chowned to pkiuser:pkiuser and later opened as root. That only works with DAC override capability. Instead the file should be owned by pkiuser:root and have permission 660. That way both the user and root still can modify the file.

  • The installer should not use hard-coded file names. It could simply use a temporary file and remove it afterwards.

@cheimes the file is not chowned first and opened as root later in this case.
A previous (failed) run of the install leaves this file in-place.
The second run finds it and chokes on it.
Agreed that having it pkiuser:root would be better, but I think unlink would work in all situations.

Metadata Update from @fcami:
- Custom field on_review adjusted to https://github.com/freeipa/freeipa/pull/3024

4 years ago

master:

  • d68fe6b ipaserver/install/cainstance.py: unlink before creating new file in /tmp

ipa-4-7:

  • eeeed84 ipaserver/install/cainstance.py: unlink before creating new file in /tmp

Metadata Update from @rcritten:
- Issue close_status updated to: fixed
- Issue status updated to: Closed (was: Open)

4 years ago

Login to comment on this ticket.

Metadata