Skip to content

Commit

Permalink
Ticket 49814 - dscreate should set the port selinux labels
Browse files Browse the repository at this point in the history
Description:

dscreate was not setting the selinux labels on the ports, so if you specified
a non-standard port the instance would not start.  This fix sets/removes
selinux labels during instance creation and removal

Also moved ds_selinux_port_query & ds_selinux_enabled to the legacy tools
package as they are only used by setup-ds.pl

https://pagure.io/389-ds-base/issue/49814

Reviewed by: firstyear & mhonek (Thanks!!)
  • Loading branch information
mreynolds389 committed Oct 24, 2018
1 parent f901190 commit 3571bac
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 7 deletions.
6 changes: 3 additions & 3 deletions rpm/389-ds-base.spec.in
Expand Up @@ -55,7 +55,7 @@ Name: 389-ds-base
Version: __VERSION__
Release: __RELEASE__%{?dist}
License: GPLv3+
URL: http://www.port389.org/
URL: https://www.port389.org/
Group: System Environment/Daemons
# Is this still needed?
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
Expand Down Expand Up @@ -623,8 +623,6 @@ exit 0
# We have to seperate this from being a glob to ensure the caps are applied.
%caps(CAP_NET_BIND_SERVICE=pe) %{_sbindir}/ns-slapd
%{_mandir}/man8/ns-slapd.8.gz
%{_libexecdir}/%{pkgname}/ds_selinux_enabled
%{_libexecdir}/%{pkgname}/ds_selinux_port_query
%{_libexecdir}/%{pkgname}/ds_systemd_ask_password_acl
%{_sbindir}/bak2db
%{_mandir}/man8/bak2db.8.gz
Expand Down Expand Up @@ -794,6 +792,8 @@ exit 0
%{_sbindir}/verify-db.pl
%{_mandir}/man8/verify-db.pl.8.gz
%{_libdir}/%{pkgname}/perl
%{_libexecdir}/%{pkgname}/ds_selinux_enabled
%{_libexecdir}/%{pkgname}/ds_selinux_port_query
%endif

%files snmp
Expand Down
6 changes: 6 additions & 0 deletions src/lib389/lib389/instance/remove.py
Expand Up @@ -9,6 +9,7 @@
import os
import shutil
import subprocess
from lib389.utils import selinux_label_port


def remove_ds_instance(dirsrv):
Expand Down Expand Up @@ -76,6 +77,11 @@ def remove_ds_instance(dirsrv):
_log.debug("Removing the systemd symlink")
subprocess.check_call(["systemctl", "disable", "dirsrv@{}".format(dirsrv.serverid)])

# Remove selinux port label
selinux_label_port(dirsrv.port, remove_label=True)
if dirsrv.sslport is not None:
selinux_label_port(dirsrv.sslport, remove_label=True)

# Done!
_log.debug("Complete")

14 changes: 10 additions & 4 deletions src/lib389/lib389/instance/setup.py
Expand Up @@ -29,7 +29,8 @@
assert_c,
is_a_dn,
ensure_str,
socket_check_open,)
socket_check_open,
selinux_label_port)

ds_paths = Paths()

Expand Down Expand Up @@ -226,7 +227,7 @@ def create_from_cli(self):
'sysconf_dir': ds_paths.sysconf_dir,
'data_dir': ds_paths.data_dir,
'local_state_dir': ds_paths.local_state_dir,
'ldapi' : ds_paths.ldapi,
'ldapi': ds_paths.ldapi,
'lib_dir': ds_paths.lib_dir,
'run_dir': ds_paths.run_dir,
'tmp_dir': ds_paths.tmp_dir,
Expand Down Expand Up @@ -339,6 +340,8 @@ def create_from_cli(self):
# Port 636 is already taken, pick another port
port = get_port(slapd['secure_port'], "", secure=True)
slapd['secure_port'] = port
else:
slapd['secure_port'] = False

# Root DN
while 1:
Expand Down Expand Up @@ -548,8 +551,6 @@ def _prepare_ds(self, general, slapd, backends):
assert_c('cn' in be)
# Add an assertion that we don't double suffix or double CN here ...



def create_from_args(self, general, slapd, backends=[], extra=None):
"""
Actually does the setup. this is what you want to call as an api.
Expand Down Expand Up @@ -753,10 +754,15 @@ def _install_ds(self, general, slapd, backends):
csr = tlsdb.create_rsa_key_and_csr()
(ca, crt) = ssca.rsa_ca_sign_csr(csr)
tlsdb.import_rsa_crt(ca, crt)
if not self.containerised and general['selinux']:
# Set selinux port label
selinux_label_port(slapd['secure_port'])

## LAST CHANCE, FIX PERMISSIONS.
# Selinux fixups?
# Restorecon of paths?
if not self.containerised and general['selinux']:
selinux_label_port(slapd['port'])

# Start the server
# Make changes using the temp root
Expand Down
47 changes: 47 additions & 0 deletions src/lib389/lib389/utils.py
Expand Up @@ -34,6 +34,9 @@ def wait(self):
import filecmp
import six
import shlex
import selinux
import sepolicy
import subprocess
from socket import getfqdn
from ldapurl import LDAPUrl
from contextlib import closing
Expand Down Expand Up @@ -170,6 +173,50 @@ def wait(self):
#


def selinux_label_port(port, remove_label=False):
"""
Either set or remove an SELinux label(ldap_port_t) for a TCP port
:param port: The TCP port to be labelled
:type port: str
:param remove_label: Set True if the port label should be removed
:type remove_label: boolean
:raises: ValueError: Error message
"""

if not selinux.is_selinux_enabled():
return

label_set = False
label_ex = None

policies = [p for p in sepolicy.info(sepolicy.PORT)
if p['protocol'] == 'tcp'
if port in range(p['low'], p['high'] + 1)
if p['type'] not in ['unreserved_port_t', 'reserved_port_t', 'ephemeral_port_t']]

for policy in policies:
if "ldap_port_t" == policy['type']:
label_set = True # Port already has our label
break
else:
# Port belongs to someone else (bad)
raise ValueError("Port " + port + " was already labelled with: " + policy['type'])

if (remove_label and label_set) or (not remove_label and not label_set):
for i in range(3):
try:
subprocess.check_call(["semanage", "port",
"-d" if remove_label else "-a",
"-t", "ldap_port_t",
"-p", "tcp", str(port)])
return
except (OSError, subprocess.CalledProcessError) as e:
label_ex = e
time.sleep(3)
raise ValueError("Failed to mangle port label: " + str(label_ex))


def is_a_dn(dn, allow_anon=True):
"""Returns True if the given string is a DN, False otherwise."""
try:
Expand Down

0 comments on commit 3571bac

Please sign in to comment.