Blame SOURCES/0005-Issue-51086-Improve-dscreate-instance-name-validatio.patch

d69b2b
From 9710c327b3034d7a9d112306961c9cec98083df5 Mon Sep 17 00:00:00 2001
d69b2b
From: Simon Pichugin <simon.pichugin@gmail.com>
d69b2b
Date: Mon, 18 May 2020 22:33:45 +0200
d69b2b
Subject: [PATCH 05/12] Issue 51086 - Improve dscreate instance name validation
d69b2b
d69b2b
Bug Description: When creating an instance using dscreate, it doesn't enforce
d69b2b
max name length. The ldapi socket name contains name of the instance. If it's
d69b2b
too long, we can hit limits, and the file name will be truncated. Also, it
d69b2b
doesn't sanitize the instance name, it's possible to create an instance with
d69b2b
non-ascii symbols in its name.
d69b2b
d69b2b
Fix Description: Add more checks to 'dscreate from-file' installation.
d69b2b
Add a limitation for nsslapd-ldapifilepath string lenght because it is
d69b2b
limited by sizeof((*ports_info.i_listenaddr)->local.path)) it is copied to.
d69b2b
d69b2b
https://pagure.io/389-ds-base/issue/51086
d69b2b
d69b2b
Reviewed by: firstyear, mreynolds (Thanks!)
d69b2b
---
d69b2b
 ldap/servers/slapd/libglobs.c       | 12 ++++++++++++
d69b2b
 src/cockpit/389-console/src/ds.jsx  |  8 ++++++--
d69b2b
 src/lib389/lib389/instance/setup.py |  9 +++++++++
d69b2b
 3 files changed, 27 insertions(+), 2 deletions(-)
d69b2b
d69b2b
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
d69b2b
index 0d3d9a924..fbf90d92d 100644
d69b2b
--- a/ldap/servers/slapd/libglobs.c
d69b2b
+++ b/ldap/servers/slapd/libglobs.c
d69b2b
@@ -2390,11 +2390,23 @@ config_set_ldapi_filename(const char *attrname, char *value, char *errorbuf, int
d69b2b
 {
d69b2b
     int retVal = LDAP_SUCCESS;
d69b2b
     slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
d69b2b
+    /*
d69b2b
+     * LDAPI file path length is limited by sizeof((*ports_info.i_listenaddr)->local.path))
d69b2b
+     * which is set in main.c inside of "#if defined(ENABLE_LDAPI)" block
d69b2b
+     * ports_info.i_listenaddr is sizeof(PRNetAddr) and our required sizes is 8 bytes less
d69b2b
+     */
d69b2b
+    size_t result_size = sizeof(PRNetAddr) - 8;
d69b2b
 
d69b2b
     if (config_value_is_null(attrname, value, errorbuf, 0)) {
d69b2b
         return LDAP_OPERATIONS_ERROR;
d69b2b
     }
d69b2b
 
d69b2b
+    if (strlen(value) >= result_size) {
d69b2b
+        slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: \"%s\" is invalid, its length must be less than %d",
d69b2b
+                              attrname, value, result_size);
d69b2b
+        return LDAP_OPERATIONS_ERROR;
d69b2b
+    }
d69b2b
+
d69b2b
     if (apply) {
d69b2b
         CFG_LOCK_WRITE(slapdFrontendConfig);
d69b2b
 
d69b2b
diff --git a/src/cockpit/389-console/src/ds.jsx b/src/cockpit/389-console/src/ds.jsx
d69b2b
index 90d9e5abd..53aa5cb79 100644
d69b2b
--- a/src/cockpit/389-console/src/ds.jsx
d69b2b
+++ b/src/cockpit/389-console/src/ds.jsx
d69b2b
@@ -793,10 +793,14 @@ class CreateInstanceModal extends React.Component {
d69b2b
             return;
d69b2b
         }
d69b2b
         newServerId = newServerId.replace(/^slapd-/i, ""); // strip "slapd-"
d69b2b
-        if (newServerId.length > 128) {
d69b2b
+        if (newServerId === "admin") {
d69b2b
+            addNotification("warning", "Instance Name 'admin' is reserved, please choose a different name");
d69b2b
+            return;
d69b2b
+        }
d69b2b
+        if (newServerId.length > 80) {
d69b2b
             addNotification(
d69b2b
                 "warning",
d69b2b
-                "Instance name is too long, it must not exceed 128 characters"
d69b2b
+                "Instance name is too long, it must not exceed 80 characters"
d69b2b
             );
d69b2b
             return;
d69b2b
         }
d69b2b
diff --git a/src/lib389/lib389/instance/setup.py b/src/lib389/lib389/instance/setup.py
d69b2b
index 803992275..f5fc5495d 100644
d69b2b
--- a/src/lib389/lib389/instance/setup.py
d69b2b
+++ b/src/lib389/lib389/instance/setup.py
d69b2b
@@ -567,6 +567,15 @@ class SetupDs(object):
d69b2b
 
d69b2b
         # We need to know the prefix before we can do the instance checks
d69b2b
         assert_c(slapd['instance_name'] is not None, "Configuration instance_name in section [slapd] not found")
d69b2b
+        assert_c(len(slapd['instance_name']) <= 80, "Server identifier should not be longer than 80 symbols")
d69b2b
+        assert_c(all(ord(c) < 128 for c in slapd['instance_name']), "Server identifier can not contain non ascii characters")
d69b2b
+        assert_c(' ' not in slapd['instance_name'], "Server identifier can not contain a space")
d69b2b
+        assert_c(slapd['instance_name'] != 'admin', "Server identifier \"admin\" is reserved, please choose a different identifier")
d69b2b
+
d69b2b
+        # Check that valid characters are used
d69b2b
+        safe = re.compile(r'^[#%:\w@_-]+$').search
d69b2b
+        assert_c(bool(safe(slapd['instance_name'])), "Server identifier has invalid characters, please choose a different value")
d69b2b
+
d69b2b
         # Check if the instance exists or not.
d69b2b
         # Should I move this import? I think this prevents some recursion
d69b2b
         from lib389 import DirSrv
d69b2b
-- 
d69b2b
2.26.2
d69b2b