Blame SOURCES/0027-Ticket-50393-maxlogsperdir-accepting-negative-values.patch

26521d
From 03695c416f7f8311afbded390f3c0ff3637a10d4 Mon Sep 17 00:00:00 2001
26521d
From: Mark Reynolds <mreynolds@redhat.com>
26521d
Date: Mon, 20 May 2019 11:38:05 -0400
26521d
Subject: [PATCH] Ticket 50393 - maxlogsperdir accepting negative values
26521d
26521d
Description:  Improve the log "digit" config setting validation
26521d
              for all settings.
26521d
26521d
https://pagure.io/389-ds-base/issue/50393
26521d
26521d
Reviewed by: tbordaz, firstyear, mhonek, and spichugi (Thanks!!!!)
26521d
26521d
(cherry picked from commit ca70d06fbb7a2c06c62f0ba5b192dba36f24b8e3)
26521d
---
26521d
 dirsrvtests/tests/suites/logging/__init__.py  |   3 +
26521d
 .../suites/logging/logging_config_test.py     |  86 +++++++++++
26521d
 ldap/servers/slapd/log.c                      | 143 +++++++++++++-----
26521d
 3 files changed, 192 insertions(+), 40 deletions(-)
26521d
 create mode 100644 dirsrvtests/tests/suites/logging/__init__.py
26521d
 create mode 100644 dirsrvtests/tests/suites/logging/logging_config_test.py
26521d
26521d
diff --git a/dirsrvtests/tests/suites/logging/__init__.py b/dirsrvtests/tests/suites/logging/__init__.py
26521d
new file mode 100644
26521d
index 000000000..7f812e357
26521d
--- /dev/null
26521d
+++ b/dirsrvtests/tests/suites/logging/__init__.py
26521d
@@ -0,0 +1,3 @@
26521d
+"""
26521d
+   :Requirement: 389-ds-base: Directory Server Logging Configurations
26521d
+"""
26521d
diff --git a/dirsrvtests/tests/suites/logging/logging_config_test.py b/dirsrvtests/tests/suites/logging/logging_config_test.py
26521d
new file mode 100644
26521d
index 000000000..4d8d68ab5
26521d
--- /dev/null
26521d
+++ b/dirsrvtests/tests/suites/logging/logging_config_test.py
26521d
@@ -0,0 +1,86 @@
26521d
+import logging
26521d
+import pytest
26521d
+import os
26521d
+import ldap
26521d
+from lib389._constants import *
26521d
+from lib389.topologies import topology_st as topo
26521d
+
26521d
+DEBUGGING = os.getenv("DEBUGGING", default=False)
26521d
+if DEBUGGING:
26521d
+    logging.getLogger(__name__).setLevel(logging.DEBUG)
26521d
+else:
26521d
+    logging.getLogger(__name__).setLevel(logging.INFO)
26521d
+log = logging.getLogger(__name__)
26521d
+
26521d
+big_value = "1111111111111111111111111111111111111111111"
26521d
+
26521d
+
26521d
+@pytest.mark.parametrize("attr, invalid_vals, valid_vals",
26521d
+                         [
26521d
+                             ("logexpirationtime", ["-2", "0"], ["1", "-1"]),
26521d
+                             ("maxlogsize", ["-2", "0"], ["100", "-1"]),
26521d
+                             ("logmaxdiskspace", ["-2", "0"], ["100", "-1"]),
26521d
+                             ("logminfreediskspace", ["-2", "0"], ["100", "-1"]),
26521d
+                             ("mode", ["888", "778", "77", "7777"], ["777", "000", "600"]),
26521d
+                             ("maxlogsperdir", ["-1", "0"], ["1", "20"]),
26521d
+                             ("logrotationsynchour", ["-1", "24"], ["0", "23"]),
26521d
+                             ("logrotationsyncmin", ["-1", "60"], ["0", "59"]),
26521d
+                             ("logrotationtime", ["-2", "0"], ["100", "-1"])
26521d
+                         ])
26521d
+def test_logging_digit_config(topo, attr, invalid_vals, valid_vals):
26521d
+    """Validate logging config settings
26521d
+
26521d
+    :id: a0ef30e5-538b-46fa-9762-01a4435a15e9
26521d
+    :setup: Standalone Instance
26521d
+    :steps:
26521d
+        1. Test log expiration time
26521d
+        2. Test log max size
26521d
+        3. Test log max disk space
26521d
+        4. Test log min disk space
26521d
+        5. Test log mode
26521d
+        6. Test log max number of logs
26521d
+        7. Test log rotation hour
26521d
+        8. Test log rotation minute
26521d
+        9. Test log rotation time
26521d
+    :expectedresults:
26521d
+        1. Success
26521d
+        2. Success
26521d
+        3. Success
26521d
+        4. Success
26521d
+        5. Success
26521d
+        6. Success
26521d
+        7. Success
26521d
+        8. Success
26521d
+        9. Success
26521d
+    """
26521d
+
26521d
+    accesslog_attr = "nsslapd-accesslog-{}".format(attr)
26521d
+    auditlog_attr = "nsslapd-auditlog-{}".format(attr)
26521d
+    auditfaillog_attr = "nsslapd-auditfaillog-{}".format(attr)
26521d
+    errorlog_attr = "nsslapd-errorlog-{}".format(attr)
26521d
+
26521d
+    # Test each log
26521d
+    for attr in [accesslog_attr, auditlog_attr, auditfaillog_attr, errorlog_attr]:
26521d
+        # Invalid values
26521d
+        for invalid_val in invalid_vals:
26521d
+            with pytest.raises(ldap.LDAPError):
26521d
+                topo.standalone.config.set(attr, invalid_val)
26521d
+
26521d
+        # Invalid high value
26521d
+        with pytest.raises(ldap.LDAPError):
26521d
+            topo.standalone.config.set(attr, big_value)
26521d
+
26521d
+        # Non digits
26521d
+        with pytest.raises(ldap.LDAPError):
26521d
+            topo.standalone.config.set(attr, "abc")
26521d
+
26521d
+        # Valid values
26521d
+        for valid_val in valid_vals:
26521d
+            topo.standalone.config.set(attr, valid_val)
26521d
+
26521d
+
26521d
+if __name__ == '__main__':
26521d
+    # Run isolated
26521d
+    # -s for DEBUG mode
26521d
+    CURRENT_FILE = os.path.realpath(__file__)
26521d
+    pytest.main(["-s", CURRENT_FILE])
26521d
diff --git a/ldap/servers/slapd/log.c b/ldap/servers/slapd/log.c
26521d
index 7dd71541b..2456abf1e 100644
26521d
--- a/ldap/servers/slapd/log.c
26521d
+++ b/ldap/servers/slapd/log.c
26521d
@@ -817,8 +817,9 @@ log_update_auditfaillogdir(char *pathname, int apply)
26521d
 int
26521d
 log_set_mode(const char *attrname, char *value, int logtype, char *errorbuf, int apply)
26521d
 {
26521d
-    int v = 0;
26521d
+    int64_t v = 0;
26521d
     int retval = LDAP_SUCCESS;
26521d
+    char *endp = NULL;
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
 
26521d
     if (NULL == value) {
26521d
@@ -833,7 +834,18 @@ log_set_mode(const char *attrname, char *value, int logtype, char *errorbuf, int
26521d
         return LDAP_SUCCESS;
26521d
     }
26521d
 
26521d
-    v = strtol(value, NULL, 8);
26521d
+    errno = 0;
26521d
+    v = strtol(value, &endp, 8);
26521d
+    if (*endp != '\0' || errno == ERANGE ||
26521d
+        strlen(value) != 3 ||
26521d
+        v > 0777 /* octet of 777 511 */ ||
26521d
+        v < 0)
26521d
+    {
26521d
+        slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
26521d
+                "Invalid value \"%s\" for attribute (%s) (%ld), value must be three digits between 000 and 777",
26521d
+                value, attrname, v);
26521d
+        return LDAP_UNWILLING_TO_PERFORM;
26521d
+    }
26521d
 
26521d
     switch (logtype) {
26521d
     case SLAPD_ACCESS_LOG:
26521d
@@ -895,9 +907,9 @@ int
26521d
 log_set_numlogsperdir(const char *attrname, char *numlogs_str, int logtype, char *returntext, int apply)
26521d
 {
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
-
26521d
+    char *endp = NULL;
26521d
     int rv = LDAP_SUCCESS;
26521d
-    int numlogs;
26521d
+    int64_t numlogs;
26521d
 
26521d
     if (logtype != SLAPD_ACCESS_LOG &&
26521d
         logtype != SLAPD_ERROR_LOG &&
26521d
@@ -911,7 +923,14 @@ log_set_numlogsperdir(const char *attrname, char *numlogs_str, int logtype, char
26521d
         return rv;
26521d
     }
26521d
 
26521d
-    numlogs = atoi(numlogs_str);
26521d
+    errno = 0;
26521d
+    numlogs = strtol(numlogs_str, &endp, 10);
26521d
+    if (*endp != '\0' || errno == ERANGE || numlogs < 1) {
26521d
+        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
26521d
+                "Invalid value \"%s\" for attribute (%s), value must be between 1 and 2147483647",
26521d
+                numlogs_str, attrname);
26521d
+        return LDAP_UNWILLING_TO_PERFORM;
26521d
+    }
26521d
 
26521d
     if (numlogs >= 1) {
26521d
         switch (logtype) {
26521d
@@ -960,21 +979,25 @@ int
26521d
 log_set_logsize(const char *attrname, char *logsize_str, int logtype, char *returntext, int apply)
26521d
 {
26521d
     int rv = LDAP_SUCCESS;
26521d
-    PRInt64 max_logsize;    /* in bytes */
26521d
-    int logsize;            /* in megabytes */
26521d
+    int64_t max_logsize; /* in bytes */
26521d
+    int64_t logsize;     /* in megabytes */
26521d
+    char *endp = NULL;
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
 
26521d
     if (!apply || !logsize_str || !*logsize_str)
26521d
         return rv;
26521d
 
26521d
-    logsize = atoi(logsize_str);
26521d
+    errno = 0;
26521d
+    logsize = strtol(logsize_str, &endp, 10);
26521d
+    if (*endp != '\0' || errno == ERANGE || logsize < -1 || logsize == 0) {
26521d
+        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
26521d
+                "Invalid value \"%s\" for attribute (%s), value must be \"-1\" or greater than 0",
26521d
+                logsize_str, attrname);
26521d
+        return LDAP_UNWILLING_TO_PERFORM;
26521d
+    }
26521d
 
26521d
     /* convert it to bytes */
26521d
-    max_logsize = (PRInt64)logsize * LOG_MB_IN_BYTES;
26521d
-
26521d
-    if (max_logsize <= 0) {
26521d
-        max_logsize = -1;
26521d
-    }
26521d
+    max_logsize = logsize * LOG_MB_IN_BYTES;
26521d
 
26521d
     switch (logtype) {
26521d
     case SLAPD_ACCESS_LOG:
26521d
@@ -1101,8 +1124,9 @@ log_set_rotationsync_enabled(const char *attrname, char *value, int logtype, cha
26521d
 int
26521d
 log_set_rotationsynchour(const char *attrname, char *rhour_str, int logtype, char *returntext, int apply)
26521d
 {
26521d
-    int rhour = -1;
26521d
+    int64_t rhour = -1;
26521d
     int rv = LDAP_SUCCESS;
26521d
+    char *endp = NULL;
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
 
26521d
     if (logtype != SLAPD_ACCESS_LOG &&
26521d
@@ -1115,12 +1139,19 @@ log_set_rotationsynchour(const char *attrname, char *rhour_str, int logtype, cha
26521d
     }
26521d
 
26521d
     /* return if we aren't doing this for real */
26521d
-    if (!apply) {
26521d
+    if (!apply || !rhour_str || !*rhour_str) {
26521d
         return rv;
26521d
     }
26521d
 
26521d
-    if (rhour_str && *rhour_str != '\0')
26521d
-        rhour = atol(rhour_str);
26521d
+    errno = 0;
26521d
+    rhour = strtol(rhour_str, &endp, 10);
26521d
+    if (*endp != '\0' || errno == ERANGE || rhour < 0 || rhour > 23) {
26521d
+        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
26521d
+                "Invalid value \"%s\" for attribute (%s), value must be \"0\" thru \"23\"",
26521d
+                rhour_str, attrname);
26521d
+        return LDAP_UNWILLING_TO_PERFORM;
26521d
+    }
26521d
+
26521d
     if (rhour > 23)
26521d
         rhour = rhour % 24;
26521d
 
26521d
@@ -1161,8 +1192,9 @@ log_set_rotationsynchour(const char *attrname, char *rhour_str, int logtype, cha
26521d
 int
26521d
 log_set_rotationsyncmin(const char *attrname, char *rmin_str, int logtype, char *returntext, int apply)
26521d
 {
26521d
-    int rmin = -1;
26521d
+    int64_t rmin = -1;
26521d
     int rv = LDAP_SUCCESS;
26521d
+    char *endp = NULL;
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
 
26521d
     if (logtype != SLAPD_ACCESS_LOG &&
26521d
@@ -1175,14 +1207,18 @@ log_set_rotationsyncmin(const char *attrname, char *rmin_str, int logtype, char
26521d
     }
26521d
 
26521d
     /* return if we aren't doing this for real */
26521d
-    if (!apply) {
26521d
+    if (!apply || !rmin_str || !*rmin_str) {
26521d
         return rv;
26521d
     }
26521d
 
26521d
-    if (rmin_str && *rmin_str != '\0')
26521d
-        rmin = atol(rmin_str);
26521d
-    if (rmin > 59)
26521d
-        rmin = rmin % 60;
26521d
+    errno = 0;
26521d
+    rmin = strtol(rmin_str, &endp, 10);
26521d
+    if (*endp != '\0' || errno == ERANGE || rmin < 0 || rmin > 59) {
26521d
+        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
26521d
+                "Invalid value \"%s\" for attribute (%s), value must be between \"0\" and \"59\"",
26521d
+                rmin_str, attrname);
26521d
+        return LDAP_UNWILLING_TO_PERFORM;
26521d
+    }
26521d
 
26521d
     switch (logtype) {
26521d
     case SLAPD_ACCESS_LOG:
26521d
@@ -1229,8 +1265,9 @@ log_set_rotationtime(const char *attrname, char *rtime_str, int logtype, char *r
26521d
 {
26521d
 
26521d
     int runit = 0;
26521d
-    int value, rtime;
26521d
+    int64_t value, rtime;
26521d
     int rv = LDAP_SUCCESS;
26521d
+    char *endp = NULL;
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
 
26521d
     if (logtype != SLAPD_ACCESS_LOG &&
26521d
@@ -1247,7 +1284,14 @@ log_set_rotationtime(const char *attrname, char *rtime_str, int logtype, char *r
26521d
         return rv;
26521d
     }
26521d
 
26521d
-    rtime = atoi(rtime_str);
26521d
+    errno = 0;
26521d
+    rtime = strtol(rtime_str, &endp, 10);
26521d
+    if (*endp != '\0' || errno == ERANGE || rtime < -1 || rtime == 0) {
26521d
+        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
26521d
+                "Invalid value \"%s\" for attribute (%s), value must be \"-1\" or greater than \"0\"",
26521d
+                rtime_str, attrname);
26521d
+        return LDAP_UNWILLING_TO_PERFORM;
26521d
+    }
26521d
 
26521d
     if (0 == rtime) {
26521d
         rtime = -1; /* Value Range: -1 | 1 to PR_INT32_MAX */
26521d
@@ -1332,7 +1376,6 @@ log_set_rotationtimeunit(const char *attrname, char *runit, int logtype, char *e
26521d
     int origvalue = 0, value = 0;
26521d
     int runitType;
26521d
     int rv = 0;
26521d
-
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
 
26521d
     if (logtype != SLAPD_ACCESS_LOG &&
26521d
@@ -1448,10 +1491,10 @@ int
26521d
 log_set_maxdiskspace(const char *attrname, char *maxdiskspace_str, int logtype, char *errorbuf, int apply)
26521d
 {
26521d
     int rv = 0;
26521d
-    PRInt64 mlogsize = 0; /* in bytes */
26521d
-    PRInt64 maxdiskspace; /* in bytes */
26521d
-    int s_maxdiskspace;   /* in megabytes */
26521d
-
26521d
+    int64_t mlogsize = 0;   /* in bytes */
26521d
+    int64_t maxdiskspace;   /* in bytes */
26521d
+    int64_t s_maxdiskspace; /* in megabytes */
26521d
+    char *endp = NULL;
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
 
26521d
     if (logtype != SLAPD_ACCESS_LOG &&
26521d
@@ -1465,7 +1508,14 @@ log_set_maxdiskspace(const char *attrname, char *maxdiskspace_str, int logtype,
26521d
     if (!apply || !maxdiskspace_str || !*maxdiskspace_str)
26521d
         return rv;
26521d
 
26521d
-    s_maxdiskspace = atoi(maxdiskspace_str);
26521d
+    errno = 0;
26521d
+    s_maxdiskspace = strtol(maxdiskspace_str, &endp, 10);
26521d
+    if (*endp != '\0' || errno == ERANGE || s_maxdiskspace < -1 || s_maxdiskspace == 0) {
26521d
+        slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
26521d
+                "Invalid value \"%s\" for attribute (%s), value must be \"-1\" or greater than 0",
26521d
+                maxdiskspace_str, attrname);
26521d
+        return LDAP_UNWILLING_TO_PERFORM;
26521d
+    }
26521d
 
26521d
     /* Disk space are in MB  but store in bytes */
26521d
     switch (logtype) {
26521d
@@ -1538,9 +1588,9 @@ int
26521d
 log_set_mindiskspace(const char *attrname, char *minfreespace_str, int logtype, char *errorbuf, int apply)
26521d
 {
26521d
     int rv = LDAP_SUCCESS;
26521d
-    int minfreespace;      /* in megabytes */
26521d
-    PRInt64 minfreespaceB; /* in bytes */
26521d
-
26521d
+    int64_t minfreespace;  /* in megabytes */
26521d
+    int64_t minfreespaceB; /* in bytes */
26521d
+    char *endp = NULL;
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
 
26521d
     if (logtype != SLAPD_ACCESS_LOG &&
26521d
@@ -1556,11 +1606,18 @@ log_set_mindiskspace(const char *attrname, char *minfreespace_str, int logtype,
26521d
         return rv;
26521d
     }
26521d
 
26521d
-    minfreespace = atoi(minfreespace_str);
26521d
+    errno = 0;
26521d
+    minfreespace = strtol(minfreespace_str, &endp, 10);
26521d
+    if (*endp != '\0' || errno == ERANGE || minfreespace < -1 || minfreespace == 0) {
26521d
+        slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
26521d
+                "Invalid value \"%s\" for attribute (%s), value must be \"-1\" or greater than 0",
26521d
+                minfreespace_str, attrname);
26521d
+        return LDAP_UNWILLING_TO_PERFORM;
26521d
+    }
26521d
 
26521d
     /* Disk space are in MB  but store in bytes */
26521d
     if (minfreespace >= 1) {
26521d
-        minfreespaceB = (PRInt64)minfreespace * LOG_MB_IN_BYTES;
26521d
+        minfreespaceB = minfreespace * LOG_MB_IN_BYTES;
26521d
         switch (logtype) {
26521d
         case SLAPD_ACCESS_LOG:
26521d
             LOG_ACCESS_LOCK_WRITE();
26521d
@@ -1602,10 +1659,10 @@ log_set_mindiskspace(const char *attrname, char *minfreespace_str, int logtype,
26521d
 int
26521d
 log_set_expirationtime(const char *attrname, char *exptime_str, int logtype, char *errorbuf, int apply)
26521d
 {
26521d
-
26521d
-    int eunit, value, exptime;
26521d
+    int64_t eunit, value, exptime;
26521d
     int rsec = 0;
26521d
     int rv = 0;
26521d
+    char *endp = NULL;
26521d
     slapdFrontendConfig_t *fe_cfg = getFrontendConfig();
26521d
 
26521d
     if (logtype != SLAPD_ACCESS_LOG &&
26521d
@@ -1621,7 +1678,14 @@ log_set_expirationtime(const char *attrname, char *exptime_str, int logtype, cha
26521d
         return rv;
26521d
     }
26521d
 
26521d
-    exptime = atoi(exptime_str); /* <= 0: no exptime */
26521d
+    errno = 0;
26521d
+    exptime = strtol(exptime_str, &endp, 10);
26521d
+    if (*endp != '\0' || errno == ERANGE || exptime < -1 || exptime == 0) {
26521d
+        slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE,
26521d
+                "Invalid value \"%s\" for attribute (%s), value must be \"-1\" or greater than 0",
26521d
+                exptime_str, attrname);
26521d
+        return LDAP_UNWILLING_TO_PERFORM;
26521d
+    }
26521d
 
26521d
     switch (logtype) {
26521d
     case SLAPD_ACCESS_LOG:
26521d
@@ -1734,7 +1798,6 @@ log_set_expirationtimeunit(const char *attrname, char *expunit, int logtype, cha
26521d
     } else {
26521d
         slapi_create_errormsg(errorbuf, SLAPI_DSE_RETURNTEXT_SIZE, "%s: invalid time unit \"%s\"", attrname, expunit);
26521d
         rv = LDAP_OPERATIONS_ERROR;
26521d
-        ;
26521d
     }
26521d
 
26521d
     /* return if we aren't doing this for real */
26521d
-- 
26521d
2.17.2
26521d