Blame SOURCES/0035-Issue-51129-SSL-alert-The-value-of-sslVersionMax-TLS.patch

ea1d1b
From c510a50bbbb05099159817f8d9da0088c5a0a5c0 Mon Sep 17 00:00:00 2001
ea1d1b
From: Mark Reynolds <mreynolds@redhat.com>
ea1d1b
Date: Fri, 21 Aug 2020 12:44:18 -0400
ea1d1b
Subject: [PATCH] Issue 51129 - SSL alert: The value of sslVersionMax "TLS1.3"
ea1d1b
 is higher than the supported version
ea1d1b
ea1d1b
    Bug Description:  If you try and set the sslVersionMax higher than the
ea1d1b
                      default range, but within the supported range, you
ea1d1b
                      would still get an error and the server would reset
ea1d1b
                      the max to "default" max value.
ea1d1b
ea1d1b
    Fix Description:  Keep track of both the supported and default SSL ranges,
ea1d1b
                      and correctly use each range for value validation.  If
ea1d1b
                      the value is outside the supported range, then use default
ea1d1b
                      value, etc, but do not check the requested range against
ea1d1b
                      the default range.  We only use the default range if
ea1d1b
                      there is no specified min or max in the config, or if
ea1d1b
                      a invalid min or max value is set in the config.
ea1d1b
ea1d1b
                      Also, refactored the range variable names to be more
ea1d1b
                      accurate:
ea1d1b
ea1d1b
                         enabledNSSVersions -->  defaultNSSVersions
ea1d1b
                         emin, emax         -->  dmin, dmax
ea1d1b
ea1d1b
    relates: https://pagure.io/389-ds-base/issue/51129
ea1d1b
ea1d1b
    Reviewed by: firstyear(Thanks!)
ea1d1b
---
ea1d1b
 ldap/servers/slapd/ssl.c | 167 +++++++++++++++++++++------------------
ea1d1b
 1 file changed, 88 insertions(+), 79 deletions(-)
ea1d1b
ea1d1b
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
ea1d1b
index 71f91f761..1a860b71e 100644
ea1d1b
--- a/ldap/servers/slapd/ssl.c
ea1d1b
+++ b/ldap/servers/slapd/ssl.c
ea1d1b
@@ -48,12 +48,12 @@
ea1d1b
  *   sslVersionMax: max ssl version supported by NSS
ea1d1b
  ******************************************************************************/
ea1d1b
 
ea1d1b
-#define DEFVERSION "TLS1.0"
ea1d1b
-#define CURRENT_DEFAULT_SSL_VERSION SSL_LIBRARY_VERSION_TLS_1_0
ea1d1b
+#define DEFVERSION "TLS1.2"
ea1d1b
 
ea1d1b
 extern char *slapd_SSL3ciphers;
ea1d1b
 extern symbol_t supported_ciphers[];
ea1d1b
-static SSLVersionRange enabledNSSVersions;
ea1d1b
+static SSLVersionRange defaultNSSVersions;
ea1d1b
+static SSLVersionRange supportedNSSVersions;
ea1d1b
 static SSLVersionRange slapdNSSVersions;
ea1d1b
 
ea1d1b
 
ea1d1b
@@ -151,7 +151,7 @@ PRBool enableSSL2 = PR_FALSE;
ea1d1b
 PRBool enableSSL3 = PR_FALSE;
ea1d1b
 /*
ea1d1b
  * nsTLS1: on -- enable TLS1 by default.
ea1d1b
- * Corresonding to SSL_LIBRARY_VERSION_TLS_1_0 and greater.
ea1d1b
+ * Corresonding to SSL_LIBRARY_VERSION_TLS_1_2 and greater.
ea1d1b
  */
ea1d1b
 PRBool enableTLS1 = PR_TRUE;
ea1d1b
 
ea1d1b
@@ -934,15 +934,24 @@ slapd_nss_init(int init_ssl __attribute__((unused)), int config_available __attr
ea1d1b
     int create_certdb = 0;
ea1d1b
     PRUint32 nssFlags = 0;
ea1d1b
     char *certdir;
ea1d1b
-    char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
ea1d1b
-    /* Get the range of the supported SSL version */
ea1d1b
-    SSL_VersionRangeGetDefault(ssl_variant_stream, &enabledNSSVersions);
ea1d1b
+    char dmin[VERSION_STR_LENGTH], dmax[VERSION_STR_LENGTH];
ea1d1b
+    char smin[VERSION_STR_LENGTH], smax[VERSION_STR_LENGTH];
ea1d1b
 
ea1d1b
-    (void)slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin));
ea1d1b
-    (void)slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax));
ea1d1b
+    /* Get the range of the supported SSL version */
ea1d1b
+    SSL_VersionRangeGetSupported(ssl_variant_stream, &supportedNSSVersions);
ea1d1b
+    (void)slapi_getSSLVersion_str(supportedNSSVersions.min, smin, sizeof(smin));
ea1d1b
+    (void)slapi_getSSLVersion_str(supportedNSSVersions.max, smax, sizeof(smax));
ea1d1b
+
ea1d1b
+    /* Get the enabled default range */
ea1d1b
+    SSL_VersionRangeGetDefault(ssl_variant_stream, &defaultNSSVersions);
ea1d1b
+    (void)slapi_getSSLVersion_str(defaultNSSVersions.min, dmin, sizeof(dmin));
ea1d1b
+    (void)slapi_getSSLVersion_str(defaultNSSVersions.max, dmax, sizeof(dmax));
ea1d1b
     slapi_log_err(SLAPI_LOG_CONFIG, "Security Initialization",
ea1d1b
                   "slapd_nss_init - Supported range by NSS: min: %s, max: %s\n",
ea1d1b
-                  emin, emax);
ea1d1b
+                  smin, smax);
ea1d1b
+    slapi_log_err(SLAPI_LOG_CONFIG, "Security Initialization",
ea1d1b
+                  "slapd_nss_init - Enabled default range by NSS: min: %s, max: %s\n",
ea1d1b
+                  dmin, dmax);
ea1d1b
 
ea1d1b
     /* set in slapd_bootstrap_config,
ea1d1b
        thus certdir is available even if config_available is false */
ea1d1b
@@ -1262,21 +1271,21 @@ static int
ea1d1b
 set_NSS_version(char *val, PRUint16 *rval, int ismin)
ea1d1b
 {
ea1d1b
     char *vp;
ea1d1b
-    char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
ea1d1b
+    char dmin[VERSION_STR_LENGTH], dmax[VERSION_STR_LENGTH];
ea1d1b
 
ea1d1b
     if (NULL == rval) {
ea1d1b
         return 1;
ea1d1b
     }
ea1d1b
-    (void)slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin));
ea1d1b
-    (void)slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax));
ea1d1b
+    (void)slapi_getSSLVersion_str(defaultNSSVersions.min, dmin, sizeof(dmin));
ea1d1b
+    (void)slapi_getSSLVersion_str(defaultNSSVersions.max, dmax, sizeof(dmax));
ea1d1b
 
ea1d1b
     if (!strncasecmp(val, SSLSTR, SSLLEN)) { /* ssl# NOT SUPPORTED */
ea1d1b
         if (ismin) {
ea1d1b
-            slapd_SSL_warn("SSL3 is no longer supported.  Using NSS default min value: %s\n", emin);
ea1d1b
-            (*rval) = enabledNSSVersions.min;
ea1d1b
+            slapd_SSL_warn("SSL3 is no longer supported.  Using NSS default min value: %s", dmin);
ea1d1b
+            (*rval) = defaultNSSVersions.min;
ea1d1b
         } else {
ea1d1b
-            slapd_SSL_warn("SSL3 is no longer supported.  Using NSS default max value: %s\n", emax);
ea1d1b
-            (*rval) = enabledNSSVersions.max;
ea1d1b
+            slapd_SSL_warn("SSL3 is no longer supported.  Using NSS default max value: %s", dmax);
ea1d1b
+            (*rval) = defaultNSSVersions.max;
ea1d1b
         }
ea1d1b
     } else if (!strncasecmp(val, TLSSTR, TLSLEN)) { /* tls# */
ea1d1b
         float tlsv;
ea1d1b
@@ -1284,122 +1293,122 @@ set_NSS_version(char *val, PRUint16 *rval, int ismin)
ea1d1b
         sscanf(vp, "%4f", &tlsv);
ea1d1b
         if (tlsv < 1.1f) { /* TLS1.0 */
ea1d1b
             if (ismin) {
ea1d1b
-                if (enabledNSSVersions.min > CURRENT_DEFAULT_SSL_VERSION) {
ea1d1b
+                if (supportedNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) {
ea1d1b
                     slapd_SSL_warn("The value of sslVersionMin "
ea1d1b
                                    "\"%s\" is lower than the supported version; "
ea1d1b
                                    "the default value \"%s\" is used.",
ea1d1b
-                                   val, emin);
ea1d1b
-                    (*rval) = enabledNSSVersions.min;
ea1d1b
+                                   val, dmin);
ea1d1b
+                    (*rval) = defaultNSSVersions.min;
ea1d1b
                 } else {
ea1d1b
-                    (*rval) = CURRENT_DEFAULT_SSL_VERSION;
ea1d1b
+                    (*rval) = SSL_LIBRARY_VERSION_TLS_1_0;
ea1d1b
                 }
ea1d1b
             } else {
ea1d1b
-                if (enabledNSSVersions.max < CURRENT_DEFAULT_SSL_VERSION) {
ea1d1b
+                if (supportedNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_0) {
ea1d1b
                     /* never happens */
ea1d1b
                     slapd_SSL_warn("The value of sslVersionMax "
ea1d1b
                                    "\"%s\" is higher than the supported version; "
ea1d1b
                                    "the default value \"%s\" is used.",
ea1d1b
-                                   val, emax);
ea1d1b
-                    (*rval) = enabledNSSVersions.max;
ea1d1b
+                                   val, dmax);
ea1d1b
+                    (*rval) = defaultNSSVersions.max;
ea1d1b
                 } else {
ea1d1b
-                    (*rval) = CURRENT_DEFAULT_SSL_VERSION;
ea1d1b
+                    (*rval) = SSL_LIBRARY_VERSION_TLS_1_0;
ea1d1b
                 }
ea1d1b
             }
ea1d1b
         } else if (tlsv < 1.2f) { /* TLS1.1 */
ea1d1b
             if (ismin) {
ea1d1b
-                if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_1) {
ea1d1b
+                if (supportedNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_1) {
ea1d1b
                     slapd_SSL_warn("The value of sslVersionMin "
ea1d1b
                                    "\"%s\" is lower than the supported version; "
ea1d1b
                                    "the default value \"%s\" is used.",
ea1d1b
-                                   val, emin);
ea1d1b
-                    (*rval) = enabledNSSVersions.min;
ea1d1b
+                                   val, dmin);
ea1d1b
+                    (*rval) = defaultNSSVersions.min;
ea1d1b
                 } else {
ea1d1b
                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_1;
ea1d1b
                 }
ea1d1b
             } else {
ea1d1b
-                if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) {
ea1d1b
+                if (supportedNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) {
ea1d1b
                     /* never happens */
ea1d1b
                     slapd_SSL_warn("The value of sslVersionMax "
ea1d1b
                                    "\"%s\" is higher than the supported version; "
ea1d1b
                                    "the default value \"%s\" is used.",
ea1d1b
-                                   val, emax);
ea1d1b
-                    (*rval) = enabledNSSVersions.max;
ea1d1b
+                                   val, dmax);
ea1d1b
+                    (*rval) = defaultNSSVersions.max;
ea1d1b
                 } else {
ea1d1b
                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_1;
ea1d1b
                 }
ea1d1b
             }
ea1d1b
         } else if (tlsv < 1.3f) { /* TLS1.2 */
ea1d1b
             if (ismin) {
ea1d1b
-                if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_2) {
ea1d1b
+                if (supportedNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_2) {
ea1d1b
                     slapd_SSL_warn("The value of sslVersionMin "
ea1d1b
                                    "\"%s\" is lower than the supported version; "
ea1d1b
                                    "the default value \"%s\" is used.",
ea1d1b
-                                   val, emin);
ea1d1b
-                    (*rval) = enabledNSSVersions.min;
ea1d1b
+                                   val, dmin);
ea1d1b
+                    (*rval) = defaultNSSVersions.min;
ea1d1b
                 } else {
ea1d1b
                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_2;
ea1d1b
                 }
ea1d1b
             } else {
ea1d1b
-                if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_2) {
ea1d1b
+                if (supportedNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_2) {
ea1d1b
                     /* never happens */
ea1d1b
                     slapd_SSL_warn("The value of sslVersionMax "
ea1d1b
                                    "\"%s\" is higher than the supported version; "
ea1d1b
                                    "the default value \"%s\" is used.",
ea1d1b
-                                   val, emax);
ea1d1b
-                    (*rval) = enabledNSSVersions.max;
ea1d1b
+                                   val, dmax);
ea1d1b
+                    (*rval) = defaultNSSVersions.max;
ea1d1b
                 } else {
ea1d1b
                     (*rval) = SSL_LIBRARY_VERSION_TLS_1_2;
ea1d1b
                 }
ea1d1b
             }
ea1d1b
         } else if (tlsv < 1.4f) { /* TLS1.3 */
ea1d1b
-                    if (ismin) {
ea1d1b
-                        if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_3) {
ea1d1b
-                            slapd_SSL_warn("The value of sslVersionMin "
ea1d1b
-                                           "\"%s\" is lower than the supported version; "
ea1d1b
-                                           "the default value \"%s\" is used.",
ea1d1b
-                                           val, emin);
ea1d1b
-                            (*rval) = enabledNSSVersions.min;
ea1d1b
-                        } else {
ea1d1b
-                            (*rval) = SSL_LIBRARY_VERSION_TLS_1_3;
ea1d1b
-                        }
ea1d1b
-                    } else {
ea1d1b
-                        if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) {
ea1d1b
-                            /* never happens */
ea1d1b
-                            slapd_SSL_warn("The value of sslVersionMax "
ea1d1b
-                                           "\"%s\" is higher than the supported version; "
ea1d1b
-                                           "the default value \"%s\" is used.",
ea1d1b
-                                           val, emax);
ea1d1b
-                            (*rval) = enabledNSSVersions.max;
ea1d1b
-                        } else {
ea1d1b
-                            (*rval) = SSL_LIBRARY_VERSION_TLS_1_3;
ea1d1b
-                        }
ea1d1b
-                    }
ea1d1b
+            if (ismin) {
ea1d1b
+                if (supportedNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_3) {
ea1d1b
+                    slapd_SSL_warn("The value of sslVersionMin "
ea1d1b
+                                   "\"%s\" is lower than the supported version; "
ea1d1b
+                                   "the default value \"%s\" is used.",
ea1d1b
+                                   val, dmin);
ea1d1b
+                    (*rval) = defaultNSSVersions.min;
ea1d1b
+                } else {
ea1d1b
+                    (*rval) = SSL_LIBRARY_VERSION_TLS_1_3;
ea1d1b
+                }
ea1d1b
+            } else {
ea1d1b
+                if (supportedNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_3) {
ea1d1b
+                    /* never happens */
ea1d1b
+                    slapd_SSL_warn("The value of sslVersionMax "
ea1d1b
+                                   "\"%s\" is higher than the supported version; "
ea1d1b
+                                   "the default value \"%s\" is used.",
ea1d1b
+                                   val, dmax);
ea1d1b
+                    (*rval) = defaultNSSVersions.max;
ea1d1b
+                } else {
ea1d1b
+                    (*rval) = SSL_LIBRARY_VERSION_TLS_1_3;
ea1d1b
+                }
ea1d1b
+            }
ea1d1b
         } else { /* Specified TLS is newer than supported */
ea1d1b
             if (ismin) {
ea1d1b
                 slapd_SSL_warn("The value of sslVersionMin "
ea1d1b
                                "\"%s\" is out of the range of the supported version; "
ea1d1b
                                "the default value \"%s\" is used.",
ea1d1b
-                               val, emin);
ea1d1b
-                (*rval) = enabledNSSVersions.min;
ea1d1b
+                               val, dmin);
ea1d1b
+                (*rval) = defaultNSSVersions.min;
ea1d1b
             } else {
ea1d1b
                 slapd_SSL_warn("The value of sslVersionMax "
ea1d1b
                                "\"%s\" is out of the range of the supported version; "
ea1d1b
                                "the default value \"%s\" is used.",
ea1d1b
-                               val, emax);
ea1d1b
-                (*rval) = enabledNSSVersions.max;
ea1d1b
+                               val, dmax);
ea1d1b
+                (*rval) = defaultNSSVersions.max;
ea1d1b
             }
ea1d1b
         }
ea1d1b
     } else {
ea1d1b
         if (ismin) {
ea1d1b
             slapd_SSL_warn("The value of sslVersionMin "
ea1d1b
                            "\"%s\" is invalid; the default value \"%s\" is used.",
ea1d1b
-                           val, emin);
ea1d1b
-            (*rval) = enabledNSSVersions.min;
ea1d1b
+                           val, dmin);
ea1d1b
+            (*rval) = defaultNSSVersions.min;
ea1d1b
         } else {
ea1d1b
             slapd_SSL_warn("The value of sslVersionMax "
ea1d1b
                            "\"%s\" is invalid; the default value \"%s\" is used.",
ea1d1b
-                           val, emax);
ea1d1b
-            (*rval) = enabledNSSVersions.max;
ea1d1b
+                           val, dmax);
ea1d1b
+            (*rval) = defaultNSSVersions.max;
ea1d1b
         }
ea1d1b
     }
ea1d1b
     return 0;
ea1d1b
@@ -1429,10 +1438,9 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
ea1d1b
     char *tmpDir;
ea1d1b
     Slapi_Entry *e = NULL;
ea1d1b
     PRBool fipsMode = PR_FALSE;
ea1d1b
-    PRUint16 NSSVersionMin = enabledNSSVersions.min;
ea1d1b
-    PRUint16 NSSVersionMax = enabledNSSVersions.max;
ea1d1b
+    PRUint16 NSSVersionMin = defaultNSSVersions.min;
ea1d1b
+    PRUint16 NSSVersionMax = defaultNSSVersions.max;
ea1d1b
     char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH];
ea1d1b
-    char newmax[VERSION_STR_LENGTH];
ea1d1b
     int allowweakcipher = CIPHER_SET_DEFAULTWEAKCIPHER;
ea1d1b
     int_fast16_t renegotiation = (int_fast16_t)SSL_RENEGOTIATE_REQUIRES_XTN;
ea1d1b
 
ea1d1b
@@ -1780,7 +1788,11 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
ea1d1b
         }
ea1d1b
         val = slapi_entry_attr_get_ref(e, "sslVersionMin");
ea1d1b
         if (val) {
ea1d1b
+            /* Use the user defined minimum */
ea1d1b
             (void)set_NSS_version((char *)val, &NSSVersionMin, 1);
ea1d1b
+        } else {
ea1d1b
+            /* Force our default minimum */
ea1d1b
+            (void)set_NSS_version(DEFVERSION, &NSSVersionMin, 1);
ea1d1b
         }
ea1d1b
         val = slapi_entry_attr_get_ref(e, "sslVersionMax");
ea1d1b
         if (val) {
ea1d1b
@@ -1789,12 +1801,9 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
ea1d1b
         if (NSSVersionMin > NSSVersionMax) {
ea1d1b
             (void)slapi_getSSLVersion_str(NSSVersionMin, mymin, sizeof(mymin));
ea1d1b
             (void)slapi_getSSLVersion_str(NSSVersionMax, mymax, sizeof(mymax));
ea1d1b
-            slapd_SSL_warn("The min value of NSS version range \"%s\" is greater than the max value \"%s\".",
ea1d1b
+            slapd_SSL_warn("The min value of NSS version range \"%s\" is greater than the max value \"%s\".  Adjusting the max to match the miniumum.",
ea1d1b
                            mymin, mymax);
ea1d1b
-            (void)slapi_getSSLVersion_str(enabledNSSVersions.max, newmax, sizeof(newmax));
ea1d1b
-            slapd_SSL_warn("Reset the max \"%s\" to supported max \"%s\".",
ea1d1b
-                           mymax, newmax);
ea1d1b
-            NSSVersionMax = enabledNSSVersions.max;
ea1d1b
+            NSSVersionMax = NSSVersionMin;
ea1d1b
         }
ea1d1b
     }
ea1d1b
 
ea1d1b
@@ -1810,7 +1819,7 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
ea1d1b
     if (sslStatus != SECSuccess) {
ea1d1b
         errorCode = PR_GetError();
ea1d1b
         slapd_SSL_error("Security Initialization - "
ea1d1b
-                "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)\n",
ea1d1b
+                "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)",
ea1d1b
                 mymin, mymax, errorCode, slapd_pr_strerror(errorCode));
ea1d1b
     }
ea1d1b
     /*
ea1d1b
@@ -1840,13 +1849,13 @@ slapd_ssl_init2(PRFileDesc **fd, int startTLS)
ea1d1b
             (void)slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin));
ea1d1b
             (void)slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax));
ea1d1b
             slapd_SSL_error("Security Initialization - "
ea1d1b
-                    "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)\n",
ea1d1b
+                    "slapd_ssl_init2 - Failed to set SSL range: min: %s, max: %s - error %d (%s)",
ea1d1b
                     mymin, mymax, errorCode, slapd_pr_strerror(errorCode));
ea1d1b
         }
ea1d1b
     } else {
ea1d1b
         errorCode = PR_GetError();
ea1d1b
         slapd_SSL_error("Security Initialization - ",
ea1d1b
-                "slapd_ssl_init2 - Failed to get SSL range from socket - error %d (%s)\n",
ea1d1b
+                "slapd_ssl_init2 - Failed to get SSL range from socket - error %d (%s)",
ea1d1b
                 errorCode, slapd_pr_strerror(errorCode));
ea1d1b
     }
ea1d1b
 
ea1d1b
@@ -2173,7 +2182,7 @@ slapd_SSL_client_auth(LDAP *ld)
ea1d1b
         }
ea1d1b
     } else {
ea1d1b
         if (token == NULL) {
ea1d1b
-            slapd_SSL_warn("slapd_SSL_client_auth - certificate token was not found\n");
ea1d1b
+            slapd_SSL_warn("slapd_SSL_client_auth - certificate token was not found");
ea1d1b
         }
ea1d1b
         rc = -1;
ea1d1b
     }
ea1d1b
-- 
ea1d1b
2.26.2
ea1d1b