Branch '389-ds-base-1.3.2' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/auth.c | 115 +++++++++++++++++++------------------
ldap/servers/slapd/slapi-private.h | 19 ++++++
2 files changed, 80 insertions(+), 54 deletions(-)
New commits:
commit 712d8eb77a32bde75e63a5d3beb27e62d1e2258c
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Jan 7 11:35:32 2015 -0800
Ticket #47945 - Add SSL/TLS version info to the access log
Description: Added the currently used SSL library version info per
connection to the access log.
Sample output:
SSL
[..] conn=3 fd=64 slot=64 SSL connection from ::1 to ::1
[..] conn=3 TLS1.2 128-bit AES-GCM
startTLS
[..] conn=4 op=0 EXT oid="1.3.6.1.4.1.1466.20037" name="startTLS"
[..] conn=4 op=0 RESULT err=0 tag=120 nentries=0 etime=0
[..] conn=4 TLS1.2 128-bit AES-GCM
To convert the SSL version number to string (e.g., SSL_LIBRARY_VERSION_
TLS_1_2 --> "TLS1.2"), instead of maintaining a mapping table, this
patch calculates the number and generates the version string.
Back-ported commit a2e0de3aa90f04593427628afeb7fe090dac93fb
https://fedorahosted.org/389/ticket/47945
(cherry picked from commit d62b281480c4c17438a6541c150bdb1e80abf14f)
(cherry picked from commit 0680446be988316e26715a2c3dbeb3163f7f6e85)
diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c
index 5b7dc31..6031b90 100644
--- a/ldap/servers/slapd/auth.c
+++ b/ldap/servers/slapd/auth.c
@@ -433,6 +433,7 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
SSLChannelInfo channelInfo;
SSLCipherSuiteInfo cipherInfo;
char* subject = NULL;
+ char sslversion[64];
if ( (slapd_ssl_getChannelInfo (prfd, &channelInfo, sizeof(channelInfo))) != SECSuccess ) {
PRErrorCode errorCode = PR_GetError();
@@ -465,59 +466,63 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
}
}
+ (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion));
if (config_get_SSLclientAuth() == SLAPD_SSLCLIENTAUTH_OFF ) {
- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL %i-bit %s\n",
- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL" );
+ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL" );
goto done;
- }
+ }
if (clientCert == NULL) {
- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL %i-bit %s\n",
- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL" );
+ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL" );
} else {
- subject = subject_of (clientCert);
- if (!subject) {
- slapi_log_access( LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL %i-bit %s; missing subject\n",
- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL");
- goto done;
- }
- {
- char* issuer = issuer_of (clientCert);
- char sbuf[ BUFSIZ ], ibuf[ BUFSIZ ];
- slapi_log_access( LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL %i-bit %s; client %s; issuer %s\n",
- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL",
- subject ? escape_string( subject, sbuf ) : "NULL",
- issuer ? escape_string( issuer, ibuf ) : "NULL");
- if (issuer) free (issuer);
- }
- slapi_dn_normalize (subject);
- {
- LDAPMessage* chain = NULL;
- char *basedn = config_get_basedn();
- int err;
-
- err = ldapu_cert_to_ldap_entry
- (clientCert, internal_ld, basedn?basedn:""/*baseDN*/, &chain);
- if (err == LDAPU_SUCCESS && chain) {
- LDAPMessage* entry = slapu_first_entry (internal_ld, chain);
- if (entry) {
- /* clientDN is duplicated in slapu_get_dn */
- clientDN = slapu_get_dn (internal_ld, entry);
- } else {
-
- extraErrorMsg = "no entry";
- LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %s\n",
- extraErrorMsg, 0, 0);
- }
- } else {
- extraErrorMsg = ldapu_err2string(err);
- LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %i (%s)%s\n",
- err, extraErrorMsg, chain ? "" : " NULL");
- }
- slapi_ch_free_string(&basedn);
- slapu_msgfree (internal_ld, chain);
- }
+ subject = subject_of (clientCert);
+ if (!subject) {
+ slapi_log_access( LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " %s %i-bit %s; missing subject\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL");
+ goto done;
+ }
+ {
+ char* issuer = issuer_of (clientCert);
+ char sbuf[ BUFSIZ ], ibuf[ BUFSIZ ];
+ slapi_log_access( LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " %s %i-bit %s; client %s; issuer %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL",
+ subject ? escape_string( subject, sbuf ) : "NULL",
+ issuer ? escape_string( issuer, ibuf ) : "NULL");
+ if (issuer) free (issuer);
+ }
+ slapi_dn_normalize (subject);
+ {
+ LDAPMessage* chain = NULL;
+ char *basedn = config_get_basedn();
+ int err;
+
+ err = ldapu_cert_to_ldap_entry
+ (clientCert, internal_ld, basedn?basedn:""/*baseDN*/, &chain);
+ if (err == LDAPU_SUCCESS && chain) {
+ LDAPMessage* entry = slapu_first_entry (internal_ld, chain);
+ if (entry) {
+ /* clientDN is duplicated in slapu_get_dn */
+ clientDN = slapu_get_dn (internal_ld, entry);
+ } else {
+ extraErrorMsg = "no entry";
+ LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %s\n",
+ extraErrorMsg, 0, 0);
+ }
+ } else {
+ extraErrorMsg = ldapu_err2string(err);
+ LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %i (%s)%s\n",
+ err, extraErrorMsg, chain ? "" : " NULL");
+ }
+ slapi_ch_free_string(&basedn);
+ slapu_msgfree (internal_ld, chain);
+ }
}
if (clientDN != NULL) {
@@ -525,14 +530,16 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
sdn = slapi_sdn_new_dn_passin(clientDN);
clientDN = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
slapi_sdn_free(&sdn);
- slapi_log_access (LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL client bound as %s\n",
- (long long unsigned int)conn->c_connid, clientDN);
+ slapi_log_access (LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " %s client bound as %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, clientDN);
} else if (clientCert != NULL) {
slapi_log_access (LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL failed to map client "
+ "conn=%" NSPRIu64 " %s failed to map client "
"certificate to LDAP DN (%s)\n",
- (long long unsigned int)conn->c_connid, extraErrorMsg );
+ (long long unsigned int)conn->c_connid,
+ sslversion, extraErrorMsg);
}
/*
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index f2b4fe8..588c284 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -1326,6 +1326,25 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods);
/* add.c */
void add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e);
+/* ssl.c */
+/*
+ * If non NULL buf and positive bufsize is given,
+ * the memory is used to store the version string.
+ * Otherwise, the memory for the string is allocated.
+ * The latter case, caller is responsible to free it.
+ */
+/* vnum is supposed to be in one of the following:
+ * nss3/sslproto.h
+ * #define SSL_LIBRARY_VERSION_2 0x0002
+ * #define SSL_LIBRARY_VERSION_3_0 0x0300
+ * #define SSL_LIBRARY_VERSION_TLS_1_0 0x0301
+ * #define SSL_LIBRARY_VERSION_TLS_1_1 0x0302
+ * #define SSL_LIBRARY_VERSION_TLS_1_2 0x0303
+ * #define SSL_LIBRARY_VERSION_TLS_1_3 0x0304
+ * ...
+ */
+char *slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t bufsize);
+
#ifdef __cplusplus
}
#endif
9 years, 2 months
Branch '389-ds-base-1.3.1' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/auth.c | 115 +++++++++++++++++++------------------
ldap/servers/slapd/slapi-private.h | 19 ++++++
2 files changed, 80 insertions(+), 54 deletions(-)
New commits:
commit 0680446be988316e26715a2c3dbeb3163f7f6e85
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Jan 7 11:35:32 2015 -0800
Ticket #47945 - Add SSL/TLS version info to the access log
Description: Added the currently used SSL library version info per
connection to the access log.
Sample output:
SSL
[..] conn=3 fd=64 slot=64 SSL connection from ::1 to ::1
[..] conn=3 TLS1.2 128-bit AES-GCM
startTLS
[..] conn=4 op=0 EXT oid="1.3.6.1.4.1.1466.20037" name="startTLS"
[..] conn=4 op=0 RESULT err=0 tag=120 nentries=0 etime=0
[..] conn=4 TLS1.2 128-bit AES-GCM
To convert the SSL version number to string (e.g., SSL_LIBRARY_VERSION_
TLS_1_2 --> "TLS1.2"), instead of maintaining a mapping table, this
patch calculates the number and generates the version string.
Back-ported commit a2e0de3aa90f04593427628afeb7fe090dac93fb
https://fedorahosted.org/389/ticket/47945
(cherry picked from commit d62b281480c4c17438a6541c150bdb1e80abf14f)
diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c
index 3a72f79..2b4d173 100644
--- a/ldap/servers/slapd/auth.c
+++ b/ldap/servers/slapd/auth.c
@@ -433,6 +433,7 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
SSLChannelInfo channelInfo;
SSLCipherSuiteInfo cipherInfo;
char* subject = NULL;
+ char sslversion[64];
if ( (slapd_ssl_getChannelInfo (prfd, &channelInfo, sizeof(channelInfo))) != SECSuccess ) {
PRErrorCode errorCode = PR_GetError();
@@ -465,59 +466,63 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
}
}
+ (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion));
if (config_get_SSLclientAuth() == SLAPD_SSLCLIENTAUTH_OFF ) {
- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL %i-bit %s\n",
- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL" );
+ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL" );
goto done;
- }
+ }
if (clientCert == NULL) {
- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL %i-bit %s\n",
- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL" );
+ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL" );
} else {
- subject = subject_of (clientCert);
- if (!subject) {
- slapi_log_access( LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL %i-bit %s; missing subject\n",
- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL");
- goto done;
- }
- {
- char* issuer = issuer_of (clientCert);
- char sbuf[ BUFSIZ ], ibuf[ BUFSIZ ];
- slapi_log_access( LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL %i-bit %s; client %s; issuer %s\n",
- (long long unsigned int)conn->c_connid, keySize, cipher ? cipher : "NULL",
- subject ? escape_string( subject, sbuf ) : "NULL",
- issuer ? escape_string( issuer, ibuf ) : "NULL");
- if (issuer) free (issuer);
- }
- slapi_dn_normalize (subject);
- {
- LDAPMessage* chain = NULL;
- char *basedn = config_get_basedn();
- int err;
-
- err = ldapu_cert_to_ldap_entry
- (clientCert, internal_ld, basedn?basedn:""/*baseDN*/, &chain);
- if (err == LDAPU_SUCCESS && chain) {
- LDAPMessage* entry = slapu_first_entry (internal_ld, chain);
- if (entry) {
- /* clientDN is duplicated in slapu_get_dn */
- clientDN = slapu_get_dn (internal_ld, entry);
- } else {
-
- extraErrorMsg = "no entry";
- LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %s\n",
- extraErrorMsg, 0, 0);
- }
- } else {
- extraErrorMsg = ldapu_err2string(err);
- LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %i (%s)%s\n",
- err, extraErrorMsg, chain ? "" : " NULL");
- }
- slapi_ch_free_string(&basedn);
- slapu_msgfree (internal_ld, chain);
- }
+ subject = subject_of (clientCert);
+ if (!subject) {
+ slapi_log_access( LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " %s %i-bit %s; missing subject\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL");
+ goto done;
+ }
+ {
+ char* issuer = issuer_of (clientCert);
+ char sbuf[ BUFSIZ ], ibuf[ BUFSIZ ];
+ slapi_log_access( LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " %s %i-bit %s; client %s; issuer %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL",
+ subject ? escape_string( subject, sbuf ) : "NULL",
+ issuer ? escape_string( issuer, ibuf ) : "NULL");
+ if (issuer) free (issuer);
+ }
+ slapi_dn_normalize (subject);
+ {
+ LDAPMessage* chain = NULL;
+ char *basedn = config_get_basedn();
+ int err;
+
+ err = ldapu_cert_to_ldap_entry
+ (clientCert, internal_ld, basedn?basedn:""/*baseDN*/, &chain);
+ if (err == LDAPU_SUCCESS && chain) {
+ LDAPMessage* entry = slapu_first_entry (internal_ld, chain);
+ if (entry) {
+ /* clientDN is duplicated in slapu_get_dn */
+ clientDN = slapu_get_dn (internal_ld, entry);
+ } else {
+ extraErrorMsg = "no entry";
+ LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %s\n",
+ extraErrorMsg, 0, 0);
+ }
+ } else {
+ extraErrorMsg = ldapu_err2string(err);
+ LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %i (%s)%s\n",
+ err, extraErrorMsg, chain ? "" : " NULL");
+ }
+ slapi_ch_free_string(&basedn);
+ slapu_msgfree (internal_ld, chain);
+ }
}
if (clientDN != NULL) {
@@ -525,14 +530,16 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
sdn = slapi_sdn_new_dn_passin(clientDN);
clientDN = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
slapi_sdn_free(&sdn);
- slapi_log_access (LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL client bound as %s\n",
- (long long unsigned int)conn->c_connid, clientDN);
+ slapi_log_access (LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " %s client bound as %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, clientDN);
} else if (clientCert != NULL) {
slapi_log_access (LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL failed to map client "
+ "conn=%" NSPRIu64 " %s failed to map client "
"certificate to LDAP DN (%s)\n",
- (long long unsigned int)conn->c_connid, extraErrorMsg );
+ (long long unsigned int)conn->c_connid,
+ sslversion, extraErrorMsg);
}
/*
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 3712e65..914b85a 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -1323,6 +1323,25 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods);
/* add.c */
void add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e);
+/* ssl.c */
+/*
+ * If non NULL buf and positive bufsize is given,
+ * the memory is used to store the version string.
+ * Otherwise, the memory for the string is allocated.
+ * The latter case, caller is responsible to free it.
+ */
+/* vnum is supposed to be in one of the following:
+ * nss3/sslproto.h
+ * #define SSL_LIBRARY_VERSION_2 0x0002
+ * #define SSL_LIBRARY_VERSION_3_0 0x0300
+ * #define SSL_LIBRARY_VERSION_TLS_1_0 0x0301
+ * #define SSL_LIBRARY_VERSION_TLS_1_1 0x0302
+ * #define SSL_LIBRARY_VERSION_TLS_1_2 0x0303
+ * #define SSL_LIBRARY_VERSION_TLS_1_3 0x0304
+ * ...
+ */
+char *slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t bufsize);
+
#ifdef __cplusplus
}
#endif
9 years, 2 months
Branch '389-ds-base-1.3.2' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/fedse.c | 3
ldap/servers/slapd/ssl.c | 150 ++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 136 insertions(+), 17 deletions(-)
New commits:
commit f7ae1e80d871b64ffbe0f18e9999855ea73bb253
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Jan 6 16:23:35 2015 -0800
Ticket #47928 - Disable SSL v3, by default [389-ds-base-1.2.11 only]
Description:
[fedse.c]
By default, nsSSL3 is set to off and nsTLS1 is on in cn=encryption,cn=config.
[ssl.c]
Back-ported SSLVersionRange from the master branch, but no new range
parameter support in the config. If nsSSL3 is explicitely set to
on, SSL_LIBRARY_VERSION_3_0 is set to the minimum ssl version.
Otherwise, SSL_LIBRARY_VERSION_TLS_1_0 becomes the minimum version.
The max available version is set to the maximum ssl version.
On this version, there is no way to disable TLS1.0 and enable TLS1.1
and newer. If nsTLS1 is on, all TLS1.X are enabled.
Note: This patch covers Ticket #605 - support TLS 1.1, as well.
https://fedorahosted.org/389/ticket/47928
(cherry picked from commit 17fc03cf1101135b99234f17efd3eb746626be1a)
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index 0b537bb..c23e124 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -108,7 +108,8 @@ static const char *internal_entries[] =
"nsSSLSessionTimeout:0\n"
"nsSSLClientAuth:allowed\n"
"nsSSL2:off\n"
- "nsSSL3:off\n",
+ "nsSSL3:off\n"
+ "nsTLS1:on\n",
"dn:cn=monitor\n"
"objectclass:top\n"
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index bbadf93..23fa620 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -79,6 +79,24 @@
#define MAXPATHLEN 1024
#endif
+#if NSS_VMAJOR * 100 + NSS_VMINOR >= 315
+/* TLS1.2 is defined in RFC5246. */
+#define NSS_TLS12 1
+#elif NSS_VMAJOR * 100 + NSS_VMINOR >= 314
+/* TLS1.1 is defined in RFC4346. */
+#define NSS_TLS11 1
+#else
+#define NSS_TLS10 1
+#endif
+
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+static SSLVersionRange enabledNSSVersions;
+static SSLVersionRange slapdNSSVersions;
+#endif
+
+/* E.g., "SSL3", "TLS1.2", "Unknown SSL version: 0x0" */
+#define VERSION_STR_LENGTH 64
+
extern char* slapd_SSL3ciphers;
extern symbol_t supported_ciphers[];
@@ -165,6 +183,12 @@ static cipherstruct _conf_ciphers[] = {
/*{"TLS","tls_dhe_dss_1024_des_sha", TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA}, */
{"TLS","tls_dhe_dss_1024_rc4_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
{"TLS","tls_dhe_dss_rc4_128_sha", TLS_DHE_DSS_WITH_RC4_128_SHA},
+#if defined(NSS_TLS12)
+ /* New in NSS 3.15 */
+ {"tls_rsa_aes_128_gcm_sha", "TLS_RSA_WITH_AES_128_GCM_SHA256"},
+ {"tls_dhe_rsa_aes_128_gcm_sha", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"},
+ {"tls_dhe_dss_aes_128_gcm_sha", NULL}, /* not available */
+#endif
{NULL, NULL, 0}
};
@@ -524,6 +548,54 @@ warn_if_no_key_file(const char *dir, int no_log)
return ret;
}
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+/*
+ * If non NULL buf and positive bufsize is given,
+ * the memory is used to store the version string.
+ * Otherwise, the memory for the string is allocated.
+ * The latter case, caller is responsible to free it.
+ */
+char *
+slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t bufsize)
+{
+ char *vstr = buf;
+ if (vnum >= SSL_LIBRARY_VERSION_3_0) {
+ if (vnum == SSL_LIBRARY_VERSION_3_0) { /* SSL3 */
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, "SSL3");
+ } else {
+ vstr = slapi_ch_smprintf("SSL3");
+ }
+ } else { /* TLS v X.Y */
+ const char *TLSFMT = "TLS%d.%d";
+ int minor_offset = 0; /* e.g. 0x0401 -> TLS v 2.1, not 2.0 */
+
+ if ((vnum & SSL_LIBRARY_VERSION_3_0) == SSL_LIBRARY_VERSION_3_0) {
+ minor_offset = 1; /* e.g. 0x0301 -> TLS v 1.0, not 1.1 */
+ }
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset);
+ } else {
+ vstr = slapi_ch_smprintf(TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset);
+ }
+ }
+ } else if (vnum == SSL_LIBRARY_VERSION_2) { /* SSL2 */
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, "SSL2");
+ } else {
+ vstr = slapi_ch_smprintf("SSL2");
+ }
+ } else {
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, "Unknown SSL version: 0x%x", vnum);
+ } else {
+ vstr = slapi_ch_smprintf("Unknown SSL version: 0x%x", vnum);
+ }
+ }
+ return vstr;
+}
+#endif
+
/*
* slapd_nss_init() is always called from main(), even if we do not
* plan to listen on a secure port. If config_available is 0, the
@@ -548,6 +620,17 @@ slapd_nss_init(int init_ssl, int config_available)
char *certdb_file_name = NULL;
char *keydb_file_name = NULL;
char *secmoddb_file_name = NULL;
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+ char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
+ /* Get the range of the supported SSL version */
+ SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions);
+
+ (void) slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin));
+ (void) slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax));
+ slapi_log_error(SLAPI_LOG_CONFIG, "SSL Initialization",
+ "supported range by NSS: min: %s, max: %s\n",
+ emin, emax);
+#endif
/* set in slapd_bootstrap_config,
thus certdir is available even if config_available is false */
@@ -879,9 +962,13 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
char* tmpDir;
Slapi_Entry *e = NULL;
PRBool enableSSL2 = PR_FALSE;
- PRBool enableSSL3 = PR_TRUE;
+ PRBool enableSSL3 = PR_FALSE;
PRBool enableTLS1 = PR_TRUE;
PRBool fipsMode = PR_FALSE;
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+ PRUint16 NSSVersionMin = SSL_LIBRARY_VERSION_TLS_1_0;
+ PRUint16 NSSVersionMax = enabledNSSVersions.max;
+#endif
/* turn off the PKCS11 pin interactive mode */
#ifndef _WIN32
@@ -1226,23 +1313,54 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
}
slapi_ch_free_string( &val );
}
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
- if (sslStatus != SECSuccess) {
- errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
- enableSSL3 ? "enable" : "disable",
- errorCode, slapd_pr_strerror(errorCode));
- }
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+ if (NSSVersionMin > 0) {
+ char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH];
+ /* Use new NSS API SSL_VersionRangeSet (NSS3.14 or newer) */
+ if (enableTLS1) {
+ NSSVersionMin = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ if (enableSSL3) {
+ NSSVersionMin = SSL_LIBRARY_VERSION_3_0;
+ }
+ slapdNSSVersions.min = NSSVersionMin;
+ slapdNSSVersions.max = NSSVersionMax;
+ (void) slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin));
+ (void) slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax));
+ slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization",
+ "Configured SSL version range: min: %s, max: %s\n",
+ mymin, mymax);
+ sslStatus = SSL_VersionRangeSet(pr_sock, &slapdNSSVersions);
+ if (sslStatus == SECSuccess) {
+ /* Set the restricted value to the cn=encryption entry */
+ } else {
+ slapd_SSL_error("SSL Initialization 2: "
+ "Failed to set SSL range: min: %s, max: %s\n",
+ mymin, mymax);
+ }
+ } else {
+#endif
+ /* deprecated code */
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
+ if (sslStatus != SECSuccess) {
+ errorCode = PR_GetError();
+ slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
+ "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+ enableSSL3 ? "enable" : "disable",
+ errorCode, slapd_pr_strerror(errorCode));
+ }
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
- if (sslStatus != SECSuccess) {
- errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
- enableTLS1 ? "enable" : "disable",
- errorCode, slapd_pr_strerror(errorCode));
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
+ if (sslStatus != SECSuccess) {
+ errorCode = PR_GetError();
+ slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
+ "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+ enableTLS1 ? "enable" : "disable",
+ errorCode, slapd_pr_strerror(errorCode));
+ }
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
}
+#endif
freeConfigEntry( &e );
if(( slapd_SSLclientAuth = config_get_SSLclientAuth()) != SLAPD_SSLCLIENTAUTH_OFF ) {
9 years, 2 months
Branch '389-ds-base-1.3.1' - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/fedse.c | 3
ldap/servers/slapd/ssl.c | 150 ++++++++++++++++++++++++++++++++++++++++-----
2 files changed, 136 insertions(+), 17 deletions(-)
New commits:
commit d4d34b245905886742f18d63da83c4edddf973ea
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Jan 6 16:23:35 2015 -0800
Ticket #47928 - Disable SSL v3, by default [389-ds-base-1.2.11 only]
Description:
[fedse.c]
By default, nsSSL3 is set to off and nsTLS1 is on in cn=encryption,cn=config.
[ssl.c]
Back-ported SSLVersionRange from the master branch, but no new range
parameter support in the config. If nsSSL3 is explicitely set to
on, SSL_LIBRARY_VERSION_3_0 is set to the minimum ssl version.
Otherwise, SSL_LIBRARY_VERSION_TLS_1_0 becomes the minimum version.
The max available version is set to the maximum ssl version.
On this version, there is no way to disable TLS1.0 and enable TLS1.1
and newer. If nsTLS1 is on, all TLS1.X are enabled.
Note: This patch covers Ticket #605 - support TLS 1.1, as well.
https://fedorahosted.org/389/ticket/47928
(cherry picked from commit 17fc03cf1101135b99234f17efd3eb746626be1a)
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index 5434c75..c1ba9ca 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -107,7 +107,8 @@ static const char *internal_entries[] =
"nsSSLSessionTimeout:0\n"
"nsSSLClientAuth:allowed\n"
"nsSSL2:off\n"
- "nsSSL3:off\n",
+ "nsSSL3:off\n"
+ "nsTLS1:on\n",
"dn:cn=monitor\n"
"objectclass:top\n"
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index bbadf93..23fa620 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -79,6 +79,24 @@
#define MAXPATHLEN 1024
#endif
+#if NSS_VMAJOR * 100 + NSS_VMINOR >= 315
+/* TLS1.2 is defined in RFC5246. */
+#define NSS_TLS12 1
+#elif NSS_VMAJOR * 100 + NSS_VMINOR >= 314
+/* TLS1.1 is defined in RFC4346. */
+#define NSS_TLS11 1
+#else
+#define NSS_TLS10 1
+#endif
+
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+static SSLVersionRange enabledNSSVersions;
+static SSLVersionRange slapdNSSVersions;
+#endif
+
+/* E.g., "SSL3", "TLS1.2", "Unknown SSL version: 0x0" */
+#define VERSION_STR_LENGTH 64
+
extern char* slapd_SSL3ciphers;
extern symbol_t supported_ciphers[];
@@ -165,6 +183,12 @@ static cipherstruct _conf_ciphers[] = {
/*{"TLS","tls_dhe_dss_1024_des_sha", TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA}, */
{"TLS","tls_dhe_dss_1024_rc4_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
{"TLS","tls_dhe_dss_rc4_128_sha", TLS_DHE_DSS_WITH_RC4_128_SHA},
+#if defined(NSS_TLS12)
+ /* New in NSS 3.15 */
+ {"tls_rsa_aes_128_gcm_sha", "TLS_RSA_WITH_AES_128_GCM_SHA256"},
+ {"tls_dhe_rsa_aes_128_gcm_sha", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"},
+ {"tls_dhe_dss_aes_128_gcm_sha", NULL}, /* not available */
+#endif
{NULL, NULL, 0}
};
@@ -524,6 +548,54 @@ warn_if_no_key_file(const char *dir, int no_log)
return ret;
}
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+/*
+ * If non NULL buf and positive bufsize is given,
+ * the memory is used to store the version string.
+ * Otherwise, the memory for the string is allocated.
+ * The latter case, caller is responsible to free it.
+ */
+char *
+slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t bufsize)
+{
+ char *vstr = buf;
+ if (vnum >= SSL_LIBRARY_VERSION_3_0) {
+ if (vnum == SSL_LIBRARY_VERSION_3_0) { /* SSL3 */
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, "SSL3");
+ } else {
+ vstr = slapi_ch_smprintf("SSL3");
+ }
+ } else { /* TLS v X.Y */
+ const char *TLSFMT = "TLS%d.%d";
+ int minor_offset = 0; /* e.g. 0x0401 -> TLS v 2.1, not 2.0 */
+
+ if ((vnum & SSL_LIBRARY_VERSION_3_0) == SSL_LIBRARY_VERSION_3_0) {
+ minor_offset = 1; /* e.g. 0x0301 -> TLS v 1.0, not 1.1 */
+ }
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset);
+ } else {
+ vstr = slapi_ch_smprintf(TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset);
+ }
+ }
+ } else if (vnum == SSL_LIBRARY_VERSION_2) { /* SSL2 */
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, "SSL2");
+ } else {
+ vstr = slapi_ch_smprintf("SSL2");
+ }
+ } else {
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, "Unknown SSL version: 0x%x", vnum);
+ } else {
+ vstr = slapi_ch_smprintf("Unknown SSL version: 0x%x", vnum);
+ }
+ }
+ return vstr;
+}
+#endif
+
/*
* slapd_nss_init() is always called from main(), even if we do not
* plan to listen on a secure port. If config_available is 0, the
@@ -548,6 +620,17 @@ slapd_nss_init(int init_ssl, int config_available)
char *certdb_file_name = NULL;
char *keydb_file_name = NULL;
char *secmoddb_file_name = NULL;
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+ char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
+ /* Get the range of the supported SSL version */
+ SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions);
+
+ (void) slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin));
+ (void) slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax));
+ slapi_log_error(SLAPI_LOG_CONFIG, "SSL Initialization",
+ "supported range by NSS: min: %s, max: %s\n",
+ emin, emax);
+#endif
/* set in slapd_bootstrap_config,
thus certdir is available even if config_available is false */
@@ -879,9 +962,13 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
char* tmpDir;
Slapi_Entry *e = NULL;
PRBool enableSSL2 = PR_FALSE;
- PRBool enableSSL3 = PR_TRUE;
+ PRBool enableSSL3 = PR_FALSE;
PRBool enableTLS1 = PR_TRUE;
PRBool fipsMode = PR_FALSE;
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+ PRUint16 NSSVersionMin = SSL_LIBRARY_VERSION_TLS_1_0;
+ PRUint16 NSSVersionMax = enabledNSSVersions.max;
+#endif
/* turn off the PKCS11 pin interactive mode */
#ifndef _WIN32
@@ -1226,23 +1313,54 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
}
slapi_ch_free_string( &val );
}
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
- if (sslStatus != SECSuccess) {
- errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
- enableSSL3 ? "enable" : "disable",
- errorCode, slapd_pr_strerror(errorCode));
- }
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+ if (NSSVersionMin > 0) {
+ char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH];
+ /* Use new NSS API SSL_VersionRangeSet (NSS3.14 or newer) */
+ if (enableTLS1) {
+ NSSVersionMin = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ if (enableSSL3) {
+ NSSVersionMin = SSL_LIBRARY_VERSION_3_0;
+ }
+ slapdNSSVersions.min = NSSVersionMin;
+ slapdNSSVersions.max = NSSVersionMax;
+ (void) slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin));
+ (void) slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax));
+ slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization",
+ "Configured SSL version range: min: %s, max: %s\n",
+ mymin, mymax);
+ sslStatus = SSL_VersionRangeSet(pr_sock, &slapdNSSVersions);
+ if (sslStatus == SECSuccess) {
+ /* Set the restricted value to the cn=encryption entry */
+ } else {
+ slapd_SSL_error("SSL Initialization 2: "
+ "Failed to set SSL range: min: %s, max: %s\n",
+ mymin, mymax);
+ }
+ } else {
+#endif
+ /* deprecated code */
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
+ if (sslStatus != SECSuccess) {
+ errorCode = PR_GetError();
+ slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
+ "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+ enableSSL3 ? "enable" : "disable",
+ errorCode, slapd_pr_strerror(errorCode));
+ }
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
- if (sslStatus != SECSuccess) {
- errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
- enableTLS1 ? "enable" : "disable",
- errorCode, slapd_pr_strerror(errorCode));
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
+ if (sslStatus != SECSuccess) {
+ errorCode = PR_GetError();
+ slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
+ "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+ enableTLS1 ? "enable" : "disable",
+ errorCode, slapd_pr_strerror(errorCode));
+ }
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
}
+#endif
freeConfigEntry( &e );
if(( slapd_SSLclientAuth = config_get_SSLclientAuth()) != SLAPD_SSLCLIENTAUTH_OFF ) {
9 years, 2 months
Branch '389-ds-base-1.2.11' - 3 commits - ldap/servers
by Noriko Hosoi
ldap/servers/slapd/auth.c | 115 +++++++++++-----------
ldap/servers/slapd/fedse.c | 17 ++-
ldap/servers/slapd/slapi-private.h | 19 +++
ldap/servers/slapd/ssl.c | 192 +++++++++++++++++++++++++++++++++----
4 files changed, 270 insertions(+), 73 deletions(-)
New commits:
commit 8550aaf90870e75b78bb6f393f9fd4aedb68d612
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Jan 7 12:58:32 2015 -0800
Ticket #47880 - provide enabled ciphers as search result
Description: Implemented getEnabledCiphers, with which
ldapsearch -b "cn=encryption,cn=config" nsSSLEnabledCiphers
returns enabled cipher list. Example of returned enabled cipher
dn: cn=encryption,cn=config
nsSSLEnabledCiphers: TLS_RSA_WITH_RC4_128_MD5::RC4::MD5::128
nsSSLEnabledCiphers: SSL_CK_DES_192_EDE3_CBC_WITH_MD5::3DES::MD5::192
Back-ported commit c675243e018a89291760161998944c04ea04b12f
https://fedorahosted.org/389/ticket/47880
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index f8c95ce..6a8b6e6 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -75,6 +75,7 @@
#endif /* _WIN32 */
extern char ** getSupportedCiphers();
+extern char ** getEnabledCiphers();
/* Note: These DNs are no need to be normalized */
static const char *internal_entries[] =
@@ -1693,11 +1694,12 @@ search_encryption( Slapi_PBlock *pb, Slapi_Entry *entry, Slapi_Entry *entryAfter
struct berval *vals[2];
struct berval val;
char ** cipherList = getSupportedCiphers(); /*Get the string array of supported ciphers here */
+ char ** enabledCipherList = getEnabledCiphers(); /*Get the string array of enabled ciphers here */
vals[0] = &val;
vals[1] = NULL;
attrlist_delete ( &entry->e_attrs, "nsSSLSupportedCiphers");
- while (*cipherList) /* iterarate thru each of them and add to the attr value */
+ while (cipherList && *cipherList) /* iterarate thru each of them and add to the attr value */
{
char *cipher = *cipherList;
val.bv_val = (char* ) cipher;
@@ -1706,6 +1708,16 @@ search_encryption( Slapi_PBlock *pb, Slapi_Entry *entry, Slapi_Entry *entryAfter
cipherList++;
}
+ attrlist_delete ( &entry->e_attrs, "nsSSLEnabledCiphers");
+ while (enabledCipherList && *enabledCipherList) /* iterarate thru each of them and add to the attr value */
+ {
+ char *cipher = *enabledCipherList;
+ val.bv_val = (char* ) cipher;
+ val.bv_len = strlen ( val.bv_val );
+ attrlist_merge ( &entry->e_attrs, "nsSSLEnabledCiphers", vals);
+ enabledCipherList++;
+ }
+
return SLAPI_DSE_CALLBACK_OK;
}
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index 23fa620..c30ebd6 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -128,6 +128,7 @@ static char * configDN = "cn=encryption,cn=config";
static char **cipher_names = NULL;
+static char **enabled_cipher_names = NULL;
typedef struct {
char *version;
char *name;
@@ -220,7 +221,8 @@ slapd_SSL_warn(char *fmt, ...)
va_end(args);
}
-char ** getSupportedCiphers()
+char **
+getSupportedCiphers()
{
SSLCipherSuiteInfo info;
char *sep = "::";
@@ -242,6 +244,44 @@ char ** getSupportedCiphers()
return cipher_names;
}
+char **
+getEnabledCiphers()
+{
+ SSLCipherSuiteInfo info;
+ char *sep = "::";
+ int number_of_ciphers = 0;
+ int x;
+ int idx = 0;
+ PRBool enabled;
+
+ /* We have to wait until the SSL initialization is done. */
+ if (!slapd_ssl_listener_is_initialized()) {
+ return NULL;
+ }
+ if ((enabled_cipher_names == NULL)) {
+ for (x = 0; _conf_ciphers[x].name; x++) {
+ SSL_CipherPrefGetDefault(_conf_ciphers[x].num, &enabled);
+ if (enabled) {
+ number_of_ciphers++;
+ }
+ }
+ enabled_cipher_names = (char **)slapi_ch_calloc((number_of_ciphers + 1), sizeof(char *));
+ for (x = 0; _conf_ciphers[x].name; x++) {
+ SSL_CipherPrefGetDefault(_conf_ciphers[x].num, &enabled);
+ if (enabled) {
+ SSL_GetCipherSuiteInfo((PRUint16)_conf_ciphers[x].num,&info,sizeof(info));
+ enabled_cipher_names[idx++] = PR_smprintf("%s%s%s%s%s%s%d",
+ _conf_ciphers[x].name,sep,
+ info.symCipherName,sep,
+ info.macAlgorithmName,sep,
+ info.symKeyBits);
+ }
+ }
+ }
+
+ return enabled_cipher_names;
+}
+
static PRBool
cipher_check_fips(int idx, char ***suplist, char ***unsuplist)
{
commit d62b281480c4c17438a6541c150bdb1e80abf14f
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Jan 7 11:35:32 2015 -0800
Ticket #47945 - Add SSL/TLS version info to the access log
Description: Added the currently used SSL library version info per
connection to the access log.
Sample output:
SSL
[..] conn=3 fd=64 slot=64 SSL connection from ::1 to ::1
[..] conn=3 TLS1.2 128-bit AES-GCM
startTLS
[..] conn=4 op=0 EXT oid="1.3.6.1.4.1.1466.20037" name="startTLS"
[..] conn=4 op=0 RESULT err=0 tag=120 nentries=0 etime=0
[..] conn=4 TLS1.2 128-bit AES-GCM
To convert the SSL version number to string (e.g., SSL_LIBRARY_VERSION_
TLS_1_2 --> "TLS1.2"), instead of maintaining a mapping table, this
patch calculates the number and generates the version string.
Back-ported commit a2e0de3aa90f04593427628afeb7fe090dac93fb
https://fedorahosted.org/389/ticket/47945
diff --git a/ldap/servers/slapd/auth.c b/ldap/servers/slapd/auth.c
index 4976406..73f6c0e 100644
--- a/ldap/servers/slapd/auth.c
+++ b/ldap/servers/slapd/auth.c
@@ -433,6 +433,7 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
SSLChannelInfo channelInfo;
SSLCipherSuiteInfo cipherInfo;
char* subject = NULL;
+ char sslversion[64];
if ( (slapd_ssl_getChannelInfo (prfd, &channelInfo, sizeof(channelInfo))) != SECSuccess ) {
PRErrorCode errorCode = PR_GetError();
@@ -465,59 +466,63 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
}
}
+ (void) slapi_getSSLVersion_str(channelInfo.protocolVersion, sslversion, sizeof(sslversion));
if (config_get_SSLclientAuth() == SLAPD_SSLCLIENTAUTH_OFF ) {
- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL %i-bit %s\n",
- conn->c_connid, keySize, cipher ? cipher : "NULL" );
+ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL" );
goto done;
- }
+ }
if (clientCert == NULL) {
- slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " SSL %i-bit %s\n",
- conn->c_connid, keySize, cipher ? cipher : "NULL" );
+ slapi_log_access (LDAP_DEBUG_STATS, "conn=%" NSPRIu64 " %s %i-bit %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL" );
} else {
- subject = subject_of (clientCert);
- if (!subject) {
- slapi_log_access( LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL %i-bit %s; missing subject\n",
- conn->c_connid, keySize, cipher ? cipher : "NULL");
- goto done;
- }
- {
- char* issuer = issuer_of (clientCert);
- char sbuf[ BUFSIZ ], ibuf[ BUFSIZ ];
- slapi_log_access( LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL %i-bit %s; client %s; issuer %s\n",
- conn->c_connid, keySize, cipher ? cipher : "NULL",
- subject ? escape_string( subject, sbuf ) : "NULL",
- issuer ? escape_string( issuer, ibuf ) : "NULL");
- if (issuer) free (issuer);
- }
- slapi_dn_normalize (subject);
- {
- LDAPMessage* chain = NULL;
- char *basedn = config_get_basedn();
- int err;
-
- err = ldapu_cert_to_ldap_entry
- (clientCert, internal_ld, basedn?basedn:""/*baseDN*/, &chain);
- if (err == LDAPU_SUCCESS && chain) {
- LDAPMessage* entry = slapu_first_entry (internal_ld, chain);
- if (entry) {
- /* clientDN is duplicated in slapu_get_dn */
- clientDN = slapu_get_dn (internal_ld, entry);
- } else {
-
- extraErrorMsg = "no entry";
- LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %s\n",
- extraErrorMsg, 0, 0);
- }
- } else {
- extraErrorMsg = ldapu_err2string(err);
- LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %i (%s)%s\n",
- err, extraErrorMsg, chain ? "" : " NULL");
- }
- slapi_ch_free_string(&basedn);
- slapu_msgfree (internal_ld, chain);
- }
+ subject = subject_of (clientCert);
+ if (!subject) {
+ slapi_log_access( LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " %s %i-bit %s; missing subject\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL");
+ goto done;
+ }
+ {
+ char* issuer = issuer_of (clientCert);
+ char sbuf[ BUFSIZ ], ibuf[ BUFSIZ ];
+ slapi_log_access( LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " %s %i-bit %s; client %s; issuer %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, keySize, cipher ? cipher : "NULL",
+ subject ? escape_string( subject, sbuf ) : "NULL",
+ issuer ? escape_string( issuer, ibuf ) : "NULL");
+ if (issuer) free (issuer);
+ }
+ slapi_dn_normalize (subject);
+ {
+ LDAPMessage* chain = NULL;
+ char *basedn = config_get_basedn();
+ int err;
+
+ err = ldapu_cert_to_ldap_entry
+ (clientCert, internal_ld, basedn?basedn:""/*baseDN*/, &chain);
+ if (err == LDAPU_SUCCESS && chain) {
+ LDAPMessage* entry = slapu_first_entry (internal_ld, chain);
+ if (entry) {
+ /* clientDN is duplicated in slapu_get_dn */
+ clientDN = slapu_get_dn (internal_ld, entry);
+ } else {
+ extraErrorMsg = "no entry";
+ LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %s\n",
+ extraErrorMsg, 0, 0);
+ }
+ } else {
+ extraErrorMsg = ldapu_err2string(err);
+ LDAPDebug (LDAP_DEBUG_TRACE, "<= ldapu_cert_to_ldap_entry() %i (%s)%s\n",
+ err, extraErrorMsg, chain ? "" : " NULL");
+ }
+ slapi_ch_free_string(&basedn);
+ slapu_msgfree (internal_ld, chain);
+ }
}
if (clientDN != NULL) {
@@ -525,14 +530,16 @@ handle_handshake_done (PRFileDesc *prfd, void* clientData)
sdn = slapi_sdn_new_dn_passin(clientDN);
clientDN = slapi_ch_strdup(slapi_sdn_get_dn(sdn));
slapi_sdn_free(&sdn);
- slapi_log_access (LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL client bound as %s\n",
- conn->c_connid, clientDN);
+ slapi_log_access (LDAP_DEBUG_STATS,
+ "conn=%" NSPRIu64 " %s client bound as %s\n",
+ (long long unsigned int)conn->c_connid,
+ sslversion, clientDN);
} else if (clientCert != NULL) {
slapi_log_access (LDAP_DEBUG_STATS,
- "conn=%" NSPRIu64 " SSL failed to map client "
+ "conn=%" NSPRIu64 " %s failed to map client "
"certificate to LDAP DN (%s)\n",
- conn->c_connid, extraErrorMsg );
+ (long long unsigned int)conn->c_connid,
+ sslversion, extraErrorMsg);
}
/*
diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h
index 8507f47..18f0e94 100644
--- a/ldap/servers/slapd/slapi-private.h
+++ b/ldap/servers/slapd/slapi-private.h
@@ -1278,6 +1278,25 @@ void modify_update_last_modified_attr(Slapi_PBlock *pb, Slapi_Mods *smods);
/* add.c */
void add_internal_modifiersname(Slapi_PBlock *pb, Slapi_Entry *e);
+/* ssl.c */
+/*
+ * If non NULL buf and positive bufsize is given,
+ * the memory is used to store the version string.
+ * Otherwise, the memory for the string is allocated.
+ * The latter case, caller is responsible to free it.
+ */
+/* vnum is supposed to be in one of the following:
+ * nss3/sslproto.h
+ * #define SSL_LIBRARY_VERSION_2 0x0002
+ * #define SSL_LIBRARY_VERSION_3_0 0x0300
+ * #define SSL_LIBRARY_VERSION_TLS_1_0 0x0301
+ * #define SSL_LIBRARY_VERSION_TLS_1_1 0x0302
+ * #define SSL_LIBRARY_VERSION_TLS_1_2 0x0303
+ * #define SSL_LIBRARY_VERSION_TLS_1_3 0x0304
+ * ...
+ */
+char *slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t bufsize);
+
#ifdef __cplusplus
}
#endif
commit 17fc03cf1101135b99234f17efd3eb746626be1a
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Jan 6 16:23:35 2015 -0800
Ticket #47928 - Disable SSL v3, by default [389-ds-base-1.2.11 only]
Description:
[fedse.c]
By default, nsSSL3 is set to off and nsTLS1 is on in cn=encryption,cn=config.
[ssl.c]
Back-ported SSLVersionRange from the master branch, but no new range
parameter support in the config. If nsSSL3 is explicitely set to
on, SSL_LIBRARY_VERSION_3_0 is set to the minimum ssl version.
Otherwise, SSL_LIBRARY_VERSION_TLS_1_0 becomes the minimum version.
The max available version is set to the maximum ssl version.
On this version, there is no way to disable TLS1.0 and enable TLS1.1
and newer. If nsTLS1 is on, all TLS1.X are enabled.
Note: This patch covers Ticket #605 - support TLS 1.1, as well.
https://fedorahosted.org/389/ticket/47928
diff --git a/ldap/servers/slapd/fedse.c b/ldap/servers/slapd/fedse.c
index dbfba16..f8c95ce 100644
--- a/ldap/servers/slapd/fedse.c
+++ b/ldap/servers/slapd/fedse.c
@@ -107,7 +107,8 @@ static const char *internal_entries[] =
"nsSSLSessionTimeout:0\n"
"nsSSLClientAuth:allowed\n"
"nsSSL2:off\n"
- "nsSSL3:off\n",
+ "nsSSL3:off\n"
+ "nsTLS1:on\n",
"dn:cn=monitor\n"
"objectclass:top\n"
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index bbadf93..23fa620 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -79,6 +79,24 @@
#define MAXPATHLEN 1024
#endif
+#if NSS_VMAJOR * 100 + NSS_VMINOR >= 315
+/* TLS1.2 is defined in RFC5246. */
+#define NSS_TLS12 1
+#elif NSS_VMAJOR * 100 + NSS_VMINOR >= 314
+/* TLS1.1 is defined in RFC4346. */
+#define NSS_TLS11 1
+#else
+#define NSS_TLS10 1
+#endif
+
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+static SSLVersionRange enabledNSSVersions;
+static SSLVersionRange slapdNSSVersions;
+#endif
+
+/* E.g., "SSL3", "TLS1.2", "Unknown SSL version: 0x0" */
+#define VERSION_STR_LENGTH 64
+
extern char* slapd_SSL3ciphers;
extern symbol_t supported_ciphers[];
@@ -165,6 +183,12 @@ static cipherstruct _conf_ciphers[] = {
/*{"TLS","tls_dhe_dss_1024_des_sha", TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA}, */
{"TLS","tls_dhe_dss_1024_rc4_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA},
{"TLS","tls_dhe_dss_rc4_128_sha", TLS_DHE_DSS_WITH_RC4_128_SHA},
+#if defined(NSS_TLS12)
+ /* New in NSS 3.15 */
+ {"tls_rsa_aes_128_gcm_sha", "TLS_RSA_WITH_AES_128_GCM_SHA256"},
+ {"tls_dhe_rsa_aes_128_gcm_sha", "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"},
+ {"tls_dhe_dss_aes_128_gcm_sha", NULL}, /* not available */
+#endif
{NULL, NULL, 0}
};
@@ -524,6 +548,54 @@ warn_if_no_key_file(const char *dir, int no_log)
return ret;
}
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+/*
+ * If non NULL buf and positive bufsize is given,
+ * the memory is used to store the version string.
+ * Otherwise, the memory for the string is allocated.
+ * The latter case, caller is responsible to free it.
+ */
+char *
+slapi_getSSLVersion_str(PRUint16 vnum, char *buf, size_t bufsize)
+{
+ char *vstr = buf;
+ if (vnum >= SSL_LIBRARY_VERSION_3_0) {
+ if (vnum == SSL_LIBRARY_VERSION_3_0) { /* SSL3 */
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, "SSL3");
+ } else {
+ vstr = slapi_ch_smprintf("SSL3");
+ }
+ } else { /* TLS v X.Y */
+ const char *TLSFMT = "TLS%d.%d";
+ int minor_offset = 0; /* e.g. 0x0401 -> TLS v 2.1, not 2.0 */
+
+ if ((vnum & SSL_LIBRARY_VERSION_3_0) == SSL_LIBRARY_VERSION_3_0) {
+ minor_offset = 1; /* e.g. 0x0301 -> TLS v 1.0, not 1.1 */
+ }
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset);
+ } else {
+ vstr = slapi_ch_smprintf(TLSFMT, (vnum >> 8) - 2, (vnum & 0xff) - minor_offset);
+ }
+ }
+ } else if (vnum == SSL_LIBRARY_VERSION_2) { /* SSL2 */
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, "SSL2");
+ } else {
+ vstr = slapi_ch_smprintf("SSL2");
+ }
+ } else {
+ if (buf && bufsize) {
+ PR_snprintf(buf, bufsize, "Unknown SSL version: 0x%x", vnum);
+ } else {
+ vstr = slapi_ch_smprintf("Unknown SSL version: 0x%x", vnum);
+ }
+ }
+ return vstr;
+}
+#endif
+
/*
* slapd_nss_init() is always called from main(), even if we do not
* plan to listen on a secure port. If config_available is 0, the
@@ -548,6 +620,17 @@ slapd_nss_init(int init_ssl, int config_available)
char *certdb_file_name = NULL;
char *keydb_file_name = NULL;
char *secmoddb_file_name = NULL;
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+ char emin[VERSION_STR_LENGTH], emax[VERSION_STR_LENGTH];
+ /* Get the range of the supported SSL version */
+ SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions);
+
+ (void) slapi_getSSLVersion_str(enabledNSSVersions.min, emin, sizeof(emin));
+ (void) slapi_getSSLVersion_str(enabledNSSVersions.max, emax, sizeof(emax));
+ slapi_log_error(SLAPI_LOG_CONFIG, "SSL Initialization",
+ "supported range by NSS: min: %s, max: %s\n",
+ emin, emax);
+#endif
/* set in slapd_bootstrap_config,
thus certdir is available even if config_available is false */
@@ -879,9 +962,13 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
char* tmpDir;
Slapi_Entry *e = NULL;
PRBool enableSSL2 = PR_FALSE;
- PRBool enableSSL3 = PR_TRUE;
+ PRBool enableSSL3 = PR_FALSE;
PRBool enableTLS1 = PR_TRUE;
PRBool fipsMode = PR_FALSE;
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+ PRUint16 NSSVersionMin = SSL_LIBRARY_VERSION_TLS_1_0;
+ PRUint16 NSSVersionMax = enabledNSSVersions.max;
+#endif
/* turn off the PKCS11 pin interactive mode */
#ifndef _WIN32
@@ -1226,23 +1313,54 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
}
slapi_ch_free_string( &val );
}
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
- if (sslStatus != SECSuccess) {
- errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
- enableSSL3 ? "enable" : "disable",
- errorCode, slapd_pr_strerror(errorCode));
- }
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
+ if (NSSVersionMin > 0) {
+ char mymin[VERSION_STR_LENGTH], mymax[VERSION_STR_LENGTH];
+ /* Use new NSS API SSL_VersionRangeSet (NSS3.14 or newer) */
+ if (enableTLS1) {
+ NSSVersionMin = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ if (enableSSL3) {
+ NSSVersionMin = SSL_LIBRARY_VERSION_3_0;
+ }
+ slapdNSSVersions.min = NSSVersionMin;
+ slapdNSSVersions.max = NSSVersionMax;
+ (void) slapi_getSSLVersion_str(slapdNSSVersions.min, mymin, sizeof(mymin));
+ (void) slapi_getSSLVersion_str(slapdNSSVersions.max, mymax, sizeof(mymax));
+ slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization",
+ "Configured SSL version range: min: %s, max: %s\n",
+ mymin, mymax);
+ sslStatus = SSL_VersionRangeSet(pr_sock, &slapdNSSVersions);
+ if (sslStatus == SECSuccess) {
+ /* Set the restricted value to the cn=encryption entry */
+ } else {
+ slapd_SSL_error("SSL Initialization 2: "
+ "Failed to set SSL range: min: %s, max: %s\n",
+ mymin, mymax);
+ }
+ } else {
+#endif
+ /* deprecated code */
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3, enableSSL3);
+ if (sslStatus != SECSuccess) {
+ errorCode = PR_GetError();
+ slapd_SSL_warn("Security Initialization: Failed to %s SSLv3 "
+ "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+ enableSSL3 ? "enable" : "disable",
+ errorCode, slapd_pr_strerror(errorCode));
+ }
- sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
- if (sslStatus != SECSuccess) {
- errorCode = PR_GetError();
- slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
- "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
- enableTLS1 ? "enable" : "disable",
- errorCode, slapd_pr_strerror(errorCode));
+ sslStatus = SSL_OptionSet(pr_sock, SSL_ENABLE_TLS, enableTLS1);
+ if (sslStatus != SECSuccess) {
+ errorCode = PR_GetError();
+ slapd_SSL_warn("Security Initialization: Failed to %s TLSv1 "
+ "on the imported socket (" SLAPI_COMPONENT_NAME_NSPR " error %d - %s)",
+ enableTLS1 ? "enable" : "disable",
+ errorCode, slapd_pr_strerror(errorCode));
+ }
+#if !defined(NSS_TLS10) /* NSS_TLS11 or newer */
}
+#endif
freeConfigEntry( &e );
if(( slapd_SSLclientAuth = config_get_SSLclientAuth()) != SLAPD_SSLCLIENTAUTH_OFF ) {
9 years, 2 months
Branch '389-ds-base-1.2.11' - ldap/admin
by Mark Reynolds
ldap/admin/src/logconv.pl | 69 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 53 insertions(+), 16 deletions(-)
New commits:
commit 099d1ce8c8e230bc41e5d77cb042c65b99f60d60
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Dec 5 15:42:45 2014 -0500
Ticket 47949 - logconv.pl -- support parsing/showing/reporting different protocol versions
Description: Update script to report on the secure protocol versions that are now available
in the access log.
Also, revised the connection section output, cleaned up the SASL bind report,
and handled issue with log(s) that only span 1 second(0 elapsed time)
https://fedorahosted.org/389/ticket/47949
Reviewed by: nhosoi & rmeggins(Thanks!!)
(cherry picked from commit 7aeeb7c968a03f4a75c8338ffbd7cbbaa73e102d)
(cherry picked from commit 8b7ae6d930927171c7976fe9093f2f765714c8ac)
diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl
index cd45a8b..11dc335 100755
--- a/ldap/admin/src/logconv.pl
+++ b/ldap/admin/src/logconv.pl
@@ -67,7 +67,7 @@ if ($#ARGV < 0){;
my $file_count = 0;
my $arg_count = 0;
-my $logversion = "8.0";
+my $logversion = "8.1";
my $sizeCount = "20";
my $startFlag = 0;
my $startTime = 0;
@@ -258,7 +258,14 @@ my $startTLSCount = 0;
my $ldapiCount = 0;
my $autobindCount = 0;
my $limit = 25000; # number of lines processed to trigger output
-
+my $searchStat;
+my $modStat;
+my $addStat;
+my $deleteStat;
+my $modrdnStat;
+my $compareStat;
+my $bindCountStat;
+my %cipher = ();
my @removefiles = ();
my @conncodes = qw(A1 B1 B4 T1 T2 B2 B3 R1 P1 P2 U1);
@@ -623,27 +630,45 @@ if($reportStats ne ""){
print "Restarts: $serverRestartCount\n";
print "Total Connections: $connectionCount\n";
-print " - StartTLS Connections: $startTLSCount\n";
-print " - LDAPS Connections: $sslCount\n";
+print " - LDAP Connections: " . ($connectionCount - $sslCount - $ldapiCount) . "\n";
print " - LDAPI Connections: $ldapiCount\n";
+print " - LDAPS Connections: $sslCount\n";
+print " - StartTLS Extended Ops: $startTLSCount\n";
+if(%cipher){
+ print " Secure Protocol Versions:\n";
+ foreach my $key (sort { $b cmp $a } keys %cipher) {
+ print " - $key - $cipher{$key}\n";
+ }
+ print "\n";
+}
+
print "Peak Concurrent Connections: $maxsimConnection\n";
print "Total Operations: $allOps\n";
print "Total Results: $allResults\n";
my ($perf, $tmp);
if ($allOps ne "0"){
- print sprintf "Overall Performance: %.1f%%\n\n" , ($perf = ($tmp = ($allResults / $allOps)*100) > 100 ? 100.0 : $tmp) ;
- }
-else {
- print "Overall Performance: No Operations to evaluate\n\n";
+ print sprintf "Overall Performance: %.1f%%\n\n" , ($perf = ($tmp = ($allResults / $allOps)*100) > 100 ? 100.0 : $tmp) ;
+} else {
+ print "Overall Performance: No Operations to evaluate\n\n";
}
-my $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n",($srchCount / $totalTimeInSecs), $srchCount / ($totalTimeInSecs/60);
-my $modStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modCount / $totalTimeInSecs, $modCount/($totalTimeInSecs/60);
-my $addStat = sprintf "(%.2f/sec) (%.2f/min)\n",$addCount/$totalTimeInSecs, $addCount/($totalTimeInSecs/60);
-my $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n",$delCount/$totalTimeInSecs, $delCount/($totalTimeInSecs/60);
-my $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modrdnCount/$totalTimeInSecs, $modrdnCount/($totalTimeInSecs/60);
-my $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n",$cmpCount/$totalTimeInSecs, $cmpCount/($totalTimeInSecs/60);
-my $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n",$bindCount/$totalTimeInSecs, $bindCount/($totalTimeInSecs/60);
+if ($totalTimeInSecs == 0){
+ $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $modStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $addStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+} else {
+ $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n",($srchCount / $totalTimeInSecs), $srchCount / ($totalTimeInSecs/60);
+ $modStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modCount / $totalTimeInSecs, $modCount/($totalTimeInSecs/60);
+ $addStat = sprintf "(%.2f/sec) (%.2f/min)\n",$addCount/$totalTimeInSecs, $addCount/($totalTimeInSecs/60);
+ $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n",$delCount/$totalTimeInSecs, $delCount/($totalTimeInSecs/60);
+ $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modrdnCount/$totalTimeInSecs, $modrdnCount/($totalTimeInSecs/60);
+ $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n",$cmpCount/$totalTimeInSecs, $cmpCount/($totalTimeInSecs/60);
+ $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n",$bindCount/$totalTimeInSecs, $bindCount/($totalTimeInSecs/60);
+}
format STDOUT =
Searches: @<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@@ -844,7 +869,7 @@ print " - SASL Binds: $saslBindCount\n";
if ($saslBindCount > 0){
my $saslmech = $hashes->{saslmech};
foreach my $saslb ( sort {$saslmech->{$b} <=> $saslmech->{$a} } (keys %{$saslmech}) ){
- printf " %-4s %-12s\n",$saslmech->{$saslb}, $saslb;
+ printf " %-4s - %s\n",$saslb, $saslmech->{$saslb};
}
}
@@ -1776,6 +1801,18 @@ sub parseLineNormal
handleRestart();
}
if (m/ SSL connection from/){$sslCount++; if($reportStats){ inc_stats('sslconns',$s_stats,$m_stats); }}
+ # Gather TLS and SSL version info
+ if ($_ =~ /conn= *([0-9A-Z]+) TLS *(.*)/){
+ $cipher{"TLS" . $2}++;
+ }
+ if ($_ =~ /conn= *([0-9A-Z]+) SSL *(.*)/){
+ my $sslversion = $2;
+ if(/SSL /){
+ $cipher{"SSL " . $sslversion}++;
+ } else {
+ $cipher{"SSL" . $sslversion}++;
+ }
+ }
if (m/ connection from local to /){$ldapiCount++;}
if($_ =~ /AUTOBIND dn=\"(.*)\"/){
$autobindCount++;
9 years, 2 months
Branch '389-ds-base-1.3.1' - ldap/admin
by Mark Reynolds
ldap/admin/src/logconv.pl | 69 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 53 insertions(+), 16 deletions(-)
New commits:
commit d1b5c7a63d12d1700db83ca5db95d2d2e6da87cd
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Dec 5 15:42:45 2014 -0500
Ticket 47949 - logconv.pl -- support parsing/showing/reporting different protocol versions
Description: Update script to report on the secure protocol versions that are now available
in the access log.
Also, revised the connection section output, cleaned up the SASL bind report,
and handled issue with log(s) that only span 1 second(0 elapsed time)
https://fedorahosted.org/389/ticket/47949
Reviewed by: nhosoi & rmeggins(Thanks!!)
(cherry picked from commit 7aeeb7c968a03f4a75c8338ffbd7cbbaa73e102d)
(cherry picked from commit 8b7ae6d930927171c7976fe9093f2f765714c8ac)
diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl
index cd45a8b..11dc335 100755
--- a/ldap/admin/src/logconv.pl
+++ b/ldap/admin/src/logconv.pl
@@ -67,7 +67,7 @@ if ($#ARGV < 0){;
my $file_count = 0;
my $arg_count = 0;
-my $logversion = "8.0";
+my $logversion = "8.1";
my $sizeCount = "20";
my $startFlag = 0;
my $startTime = 0;
@@ -258,7 +258,14 @@ my $startTLSCount = 0;
my $ldapiCount = 0;
my $autobindCount = 0;
my $limit = 25000; # number of lines processed to trigger output
-
+my $searchStat;
+my $modStat;
+my $addStat;
+my $deleteStat;
+my $modrdnStat;
+my $compareStat;
+my $bindCountStat;
+my %cipher = ();
my @removefiles = ();
my @conncodes = qw(A1 B1 B4 T1 T2 B2 B3 R1 P1 P2 U1);
@@ -623,27 +630,45 @@ if($reportStats ne ""){
print "Restarts: $serverRestartCount\n";
print "Total Connections: $connectionCount\n";
-print " - StartTLS Connections: $startTLSCount\n";
-print " - LDAPS Connections: $sslCount\n";
+print " - LDAP Connections: " . ($connectionCount - $sslCount - $ldapiCount) . "\n";
print " - LDAPI Connections: $ldapiCount\n";
+print " - LDAPS Connections: $sslCount\n";
+print " - StartTLS Extended Ops: $startTLSCount\n";
+if(%cipher){
+ print " Secure Protocol Versions:\n";
+ foreach my $key (sort { $b cmp $a } keys %cipher) {
+ print " - $key - $cipher{$key}\n";
+ }
+ print "\n";
+}
+
print "Peak Concurrent Connections: $maxsimConnection\n";
print "Total Operations: $allOps\n";
print "Total Results: $allResults\n";
my ($perf, $tmp);
if ($allOps ne "0"){
- print sprintf "Overall Performance: %.1f%%\n\n" , ($perf = ($tmp = ($allResults / $allOps)*100) > 100 ? 100.0 : $tmp) ;
- }
-else {
- print "Overall Performance: No Operations to evaluate\n\n";
+ print sprintf "Overall Performance: %.1f%%\n\n" , ($perf = ($tmp = ($allResults / $allOps)*100) > 100 ? 100.0 : $tmp) ;
+} else {
+ print "Overall Performance: No Operations to evaluate\n\n";
}
-my $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n",($srchCount / $totalTimeInSecs), $srchCount / ($totalTimeInSecs/60);
-my $modStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modCount / $totalTimeInSecs, $modCount/($totalTimeInSecs/60);
-my $addStat = sprintf "(%.2f/sec) (%.2f/min)\n",$addCount/$totalTimeInSecs, $addCount/($totalTimeInSecs/60);
-my $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n",$delCount/$totalTimeInSecs, $delCount/($totalTimeInSecs/60);
-my $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modrdnCount/$totalTimeInSecs, $modrdnCount/($totalTimeInSecs/60);
-my $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n",$cmpCount/$totalTimeInSecs, $cmpCount/($totalTimeInSecs/60);
-my $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n",$bindCount/$totalTimeInSecs, $bindCount/($totalTimeInSecs/60);
+if ($totalTimeInSecs == 0){
+ $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $modStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $addStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+} else {
+ $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n",($srchCount / $totalTimeInSecs), $srchCount / ($totalTimeInSecs/60);
+ $modStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modCount / $totalTimeInSecs, $modCount/($totalTimeInSecs/60);
+ $addStat = sprintf "(%.2f/sec) (%.2f/min)\n",$addCount/$totalTimeInSecs, $addCount/($totalTimeInSecs/60);
+ $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n",$delCount/$totalTimeInSecs, $delCount/($totalTimeInSecs/60);
+ $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modrdnCount/$totalTimeInSecs, $modrdnCount/($totalTimeInSecs/60);
+ $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n",$cmpCount/$totalTimeInSecs, $cmpCount/($totalTimeInSecs/60);
+ $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n",$bindCount/$totalTimeInSecs, $bindCount/($totalTimeInSecs/60);
+}
format STDOUT =
Searches: @<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@@ -844,7 +869,7 @@ print " - SASL Binds: $saslBindCount\n";
if ($saslBindCount > 0){
my $saslmech = $hashes->{saslmech};
foreach my $saslb ( sort {$saslmech->{$b} <=> $saslmech->{$a} } (keys %{$saslmech}) ){
- printf " %-4s %-12s\n",$saslmech->{$saslb}, $saslb;
+ printf " %-4s - %s\n",$saslb, $saslmech->{$saslb};
}
}
@@ -1776,6 +1801,18 @@ sub parseLineNormal
handleRestart();
}
if (m/ SSL connection from/){$sslCount++; if($reportStats){ inc_stats('sslconns',$s_stats,$m_stats); }}
+ # Gather TLS and SSL version info
+ if ($_ =~ /conn= *([0-9A-Z]+) TLS *(.*)/){
+ $cipher{"TLS" . $2}++;
+ }
+ if ($_ =~ /conn= *([0-9A-Z]+) SSL *(.*)/){
+ my $sslversion = $2;
+ if(/SSL /){
+ $cipher{"SSL " . $sslversion}++;
+ } else {
+ $cipher{"SSL" . $sslversion}++;
+ }
+ }
if (m/ connection from local to /){$ldapiCount++;}
if($_ =~ /AUTOBIND dn=\"(.*)\"/){
$autobindCount++;
9 years, 2 months
Branch '389-ds-base-1.3.2' - ldap/admin
by Mark Reynolds
ldap/admin/src/logconv.pl | 69 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 53 insertions(+), 16 deletions(-)
New commits:
commit a31bd5c2d65a715dc3e03586e86dad665c44e06a
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Dec 5 15:42:45 2014 -0500
Ticket 47949 - logconv.pl -- support parsing/showing/reporting different protocol versions
Description: Update script to report on the secure protocol versions that are now available
in the access log.
Also, revised the connection section output, cleaned up the SASL bind report,
and handled issue with log(s) that only span 1 second(0 elapsed time)
https://fedorahosted.org/389/ticket/47949
Reviewed by: nhosoi & rmeggins(Thanks!!)
(cherry picked from commit 7aeeb7c968a03f4a75c8338ffbd7cbbaa73e102d)
(cherry picked from commit 8b7ae6d930927171c7976fe9093f2f765714c8ac)
diff --git a/ldap/admin/src/logconv.pl b/ldap/admin/src/logconv.pl
index cd45a8b..11dc335 100755
--- a/ldap/admin/src/logconv.pl
+++ b/ldap/admin/src/logconv.pl
@@ -67,7 +67,7 @@ if ($#ARGV < 0){;
my $file_count = 0;
my $arg_count = 0;
-my $logversion = "8.0";
+my $logversion = "8.1";
my $sizeCount = "20";
my $startFlag = 0;
my $startTime = 0;
@@ -258,7 +258,14 @@ my $startTLSCount = 0;
my $ldapiCount = 0;
my $autobindCount = 0;
my $limit = 25000; # number of lines processed to trigger output
-
+my $searchStat;
+my $modStat;
+my $addStat;
+my $deleteStat;
+my $modrdnStat;
+my $compareStat;
+my $bindCountStat;
+my %cipher = ();
my @removefiles = ();
my @conncodes = qw(A1 B1 B4 T1 T2 B2 B3 R1 P1 P2 U1);
@@ -623,27 +630,45 @@ if($reportStats ne ""){
print "Restarts: $serverRestartCount\n";
print "Total Connections: $connectionCount\n";
-print " - StartTLS Connections: $startTLSCount\n";
-print " - LDAPS Connections: $sslCount\n";
+print " - LDAP Connections: " . ($connectionCount - $sslCount - $ldapiCount) . "\n";
print " - LDAPI Connections: $ldapiCount\n";
+print " - LDAPS Connections: $sslCount\n";
+print " - StartTLS Extended Ops: $startTLSCount\n";
+if(%cipher){
+ print " Secure Protocol Versions:\n";
+ foreach my $key (sort { $b cmp $a } keys %cipher) {
+ print " - $key - $cipher{$key}\n";
+ }
+ print "\n";
+}
+
print "Peak Concurrent Connections: $maxsimConnection\n";
print "Total Operations: $allOps\n";
print "Total Results: $allResults\n";
my ($perf, $tmp);
if ($allOps ne "0"){
- print sprintf "Overall Performance: %.1f%%\n\n" , ($perf = ($tmp = ($allResults / $allOps)*100) > 100 ? 100.0 : $tmp) ;
- }
-else {
- print "Overall Performance: No Operations to evaluate\n\n";
+ print sprintf "Overall Performance: %.1f%%\n\n" , ($perf = ($tmp = ($allResults / $allOps)*100) > 100 ? 100.0 : $tmp) ;
+} else {
+ print "Overall Performance: No Operations to evaluate\n\n";
}
-my $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n",($srchCount / $totalTimeInSecs), $srchCount / ($totalTimeInSecs/60);
-my $modStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modCount / $totalTimeInSecs, $modCount/($totalTimeInSecs/60);
-my $addStat = sprintf "(%.2f/sec) (%.2f/min)\n",$addCount/$totalTimeInSecs, $addCount/($totalTimeInSecs/60);
-my $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n",$delCount/$totalTimeInSecs, $delCount/($totalTimeInSecs/60);
-my $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modrdnCount/$totalTimeInSecs, $modrdnCount/($totalTimeInSecs/60);
-my $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n",$cmpCount/$totalTimeInSecs, $cmpCount/($totalTimeInSecs/60);
-my $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n",$bindCount/$totalTimeInSecs, $bindCount/($totalTimeInSecs/60);
+if ($totalTimeInSecs == 0){
+ $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $modStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $addStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+ $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n","0", "0";
+} else {
+ $searchStat = sprintf "(%.2f/sec) (%.2f/min)\n",($srchCount / $totalTimeInSecs), $srchCount / ($totalTimeInSecs/60);
+ $modStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modCount / $totalTimeInSecs, $modCount/($totalTimeInSecs/60);
+ $addStat = sprintf "(%.2f/sec) (%.2f/min)\n",$addCount/$totalTimeInSecs, $addCount/($totalTimeInSecs/60);
+ $deleteStat = sprintf "(%.2f/sec) (%.2f/min)\n",$delCount/$totalTimeInSecs, $delCount/($totalTimeInSecs/60);
+ $modrdnStat = sprintf "(%.2f/sec) (%.2f/min)\n",$modrdnCount/$totalTimeInSecs, $modrdnCount/($totalTimeInSecs/60);
+ $compareStat = sprintf "(%.2f/sec) (%.2f/min)\n",$cmpCount/$totalTimeInSecs, $cmpCount/($totalTimeInSecs/60);
+ $bindCountStat = sprintf "(%.2f/sec) (%.2f/min)\n",$bindCount/$totalTimeInSecs, $bindCount/($totalTimeInSecs/60);
+}
format STDOUT =
Searches: @<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
@@ -844,7 +869,7 @@ print " - SASL Binds: $saslBindCount\n";
if ($saslBindCount > 0){
my $saslmech = $hashes->{saslmech};
foreach my $saslb ( sort {$saslmech->{$b} <=> $saslmech->{$a} } (keys %{$saslmech}) ){
- printf " %-4s %-12s\n",$saslmech->{$saslb}, $saslb;
+ printf " %-4s - %s\n",$saslb, $saslmech->{$saslb};
}
}
@@ -1776,6 +1801,18 @@ sub parseLineNormal
handleRestart();
}
if (m/ SSL connection from/){$sslCount++; if($reportStats){ inc_stats('sslconns',$s_stats,$m_stats); }}
+ # Gather TLS and SSL version info
+ if ($_ =~ /conn= *([0-9A-Z]+) TLS *(.*)/){
+ $cipher{"TLS" . $2}++;
+ }
+ if ($_ =~ /conn= *([0-9A-Z]+) SSL *(.*)/){
+ my $sslversion = $2;
+ if(/SSL /){
+ $cipher{"SSL " . $sslversion}++;
+ } else {
+ $cipher{"SSL" . $sslversion}++;
+ }
+ }
if (m/ connection from local to /){$ldapiCount++;}
if($_ =~ /AUTOBIND dn=\"(.*)\"/){
$autobindCount++;
9 years, 2 months
Branch '389-ds-base-1.2.11' - dirsrvtests/tickets ldap/servers
by Mark Reynolds
dirsrvtests/tickets/ticket47981_test.py | 345 ++++++++++++++++++++++++++++++++
ldap/servers/plugins/cos/cos_cache.c | 34 +--
2 files changed, 359 insertions(+), 20 deletions(-)
New commits:
commit c1ba7eb8c41c44bd7689bfc2526a2aa7fff47284
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed Jan 7 08:59:06 2015 -0500
Ticket 47981 - COS cache doesn't properly mark vattr cache as
invalid when there are multiple suffixes
Bug Description: When rebuilding the COS cache, we check each suffix for COS entries.
If the last suffix checked does not contain any COS entries, then the
virtual attribute cache is incorrectly not invalidated. This allows
for already cached entries to hold onto the old COS attributes/values.
Fix Description: Only set the vattr_cacheable flag if a suffix contains COS entries, not
if it does not - by default the flag is not set.
https://fedorahosted.org/389/ticket/47981
Reviewed by: nhosoi(Thanks!)
(cherry picked from commit 42e2df3858a4e14706d57b5c907d1d3768f4d970)
diff --git a/dirsrvtests/tickets/ticket47981_test.py b/dirsrvtests/tickets/ticket47981_test.py
new file mode 100644
index 0000000..2a16ce6
--- /dev/null
+++ b/dirsrvtests/tickets/ticket47981_test.py
@@ -0,0 +1,345 @@
+import os
+import sys
+import time
+import ldap
+import ldap.sasl
+import logging
+import socket
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+installation_prefix = None
+
+BRANCH = 'ou=people,' + DEFAULT_SUFFIX
+USER_DN = 'uid=user1,%s' % (BRANCH)
+BRANCH_CONTAINER = 'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
+BRANCH_COS_DEF = 'cn=nsPwPolicy_CoS,ou=people,dc=example,dc=com'
+BRANCH_PWP = 'cn=cn\\3DnsPwPolicyEntry\\2Cou\\3DPeople\\2Cdc\\3Dexample\\2Cdc\\3Dcom,' + \
+ 'cn=nsPwPolicyContainer,ou=People,dc=example,dc=com'
+BRANCH_COS_TMPL = 'cn=cn\\3DnsPwTemplateEntry\\2Cou\\3DPeople\\2Cdc\\3Dexample\\2Cdc\\3Dcom,' + \
+ 'cn=nsPwPolicyContainer,ou=People,dc=example,dc=com'
+SECOND_SUFFIX = 'o=netscaperoot'
+BE_NAME = 'netscaperoot'
+
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ '''
+ This fixture is used to standalone topology for the 'module'.
+ At the beginning, It may exists a standalone instance.
+ It may also exists a backup for the standalone instance.
+
+ Principle:
+ If standalone instance exists:
+ restart it
+ If backup of standalone exists:
+ create/rebind to standalone
+
+ restore standalone instance from backup
+ else:
+ Cleanup everything
+ remove instance
+ remove backup
+ Create instance
+ Create backup
+ '''
+ global installation_prefix
+
+ if installation_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation_prefix
+
+ standalone = DirSrv(verbose=False)
+
+ # Args for the standalone instance
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+
+ # Get the status of the backups
+ backup_standalone = standalone.checkBackupFS()
+
+ # Get the status of the instance and restart it if it exists
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ # assuming the instance is already stopped, just wait 5 sec max
+ standalone.stop(timeout=5)
+ standalone.start(timeout=10)
+
+ if backup_standalone:
+ # The backup exist, assuming it is correct
+ # we just re-init the instance with it
+ if not instance_standalone:
+ standalone.create()
+ # Used to retrieve configuration information (dbdir, confdir...)
+ standalone.open()
+
+ # restore standalone instance from backup
+ standalone.stop(timeout=10)
+ standalone.restoreFS(backup_standalone)
+ standalone.start(timeout=10)
+
+ else:
+ # We should be here only in two conditions
+ # - This is the first time a test involve standalone instance
+ # - Something weird happened (instance/backup destroyed)
+ # so we discard everything and recreate all
+
+ # Remove the backup. So even if we have a specific backup file
+ # (e.g backup_standalone) we clear backup that an instance may have created
+ if backup_standalone:
+ standalone.clearBackupFS()
+
+ # Remove the instance
+ if instance_standalone:
+ standalone.delete()
+
+ # Create the instance
+ standalone.create()
+
+ # Used to retrieve configuration information (dbdir, confdir...)
+ standalone.open()
+
+ # Time to create the backups
+ standalone.stop(timeout=10)
+ standalone.backupfile = standalone.backupFS()
+ standalone.start(timeout=10)
+
+ # clear the tmp directory
+ standalone.clearTmpDir(__file__)
+
+ #
+ # Here we have standalone instance up and running
+ # Either coming from a backup recovery
+ # or from a fresh (re)init
+ # Time to return the topology
+ return TopologyStandalone(standalone)
+
+
+def addSubtreePwPolicy(inst):
+ #
+ # Add subtree policy to the people branch
+ #
+ try:
+ inst.add_s(Entry((BRANCH_CONTAINER, {
+ 'objectclass': 'top nsContainer'.split(),
+ 'cn': 'nsPwPolicyContainer'
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add subtree container for ou=people: error ' + e.message['desc'])
+ assert False
+
+ # Add the password policy subentry
+ try:
+ inst.add_s(Entry((BRANCH_PWP, {
+ 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
+ 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
+ 'passwordMustChange': 'off',
+ 'passwordExp': 'off',
+ 'passwordHistory': 'off',
+ 'passwordMinAge': '0',
+ 'passwordChange': 'off',
+ 'passwordStorageScheme': 'ssha'
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add passwordpolicy: error ' + e.message['desc'])
+ assert False
+
+ # Add the COS template
+ try:
+ inst.add_s(Entry((BRANCH_COS_TMPL, {
+ 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
+ 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
+ 'cosPriority': '1',
+ 'cn': 'cn=nsPwTemplateEntry,ou=people,dc=example,dc=com',
+ 'pwdpolicysubentry': BRANCH_PWP
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add COS template: error ' + e.message['desc'])
+ assert False
+
+ # Add the COS definition
+ try:
+ inst.add_s(Entry((BRANCH_COS_DEF, {
+ 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
+ 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
+ 'costemplatedn': BRANCH_COS_TMPL,
+ 'cosAttribute': 'pwdpolicysubentry default operational-default'
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add COS def: error ' + e.message['desc'])
+ assert False
+ time.sleep(0.5)
+
+
+def delSubtreePwPolicy(inst):
+ try:
+ inst.delete_s(BRANCH_COS_DEF)
+ except ldap.LDAPError, e:
+ log.error('Failed to delete COS def: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH_COS_TMPL)
+ except ldap.LDAPError, e:
+ log.error('Failed to delete COS template: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH_PWP)
+ except ldap.LDAPError, e:
+ log.error('Failed to delete COS password policy: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH_CONTAINER)
+ except ldap.LDAPError, e:
+ log.error('Failed to delete COS container: error ' + e.message['desc'])
+ assert False
+ time.sleep(0.5)
+
+
+def test_ticket47981(topology):
+ """
+ If there are multiple suffixes, and the last suffix checked does not contain any COS entries,
+ while other suffixes do, then the vattr cache is not invalidated as it should be. Then any
+ cached entries will still contain the old COS attributes/values.
+ """
+
+ log.info('Testing Ticket 47981 - Test that COS def changes are correctly reflected in affected users')
+
+ #
+ # Create a second backend that does not have any COS entries
+ #
+ log.info('Adding second suffix that will not contain any COS entries...\n')
+
+ topology.standalone.backend.create(SECOND_SUFFIX, {BACKEND_NAME: BE_NAME})
+ topology.standalone.mappingtree.create(SECOND_SUFFIX, bename=BE_NAME)
+ try:
+ topology.standalone.add_s(Entry((SECOND_SUFFIX, {
+ 'objectclass': 'top organization'.split(),
+ 'o': BE_NAME})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('Failed to create suffix entry: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Add People branch, it might already exist
+ #
+ log.info('Add our test entries to the default suffix, and proceed with the test...')
+
+ try:
+ topology.standalone.add_s(Entry((BRANCH, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'level4'
+ })))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('Failed to add ou=people: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Add a user to the branch
+ #
+ try:
+ topology.standalone.add_s(Entry((USER_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Enable password policy and add the subtree policy
+ #
+ try:
+ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on')])
+ except ldap.LDAPError, e:
+ log.error('Failed to set pwpolicy-local: error ' + e.message['desc'])
+ assert False
+
+ addSubtreePwPolicy(topology.standalone)
+
+ #
+ # Now check the user has its expected passwordPolicy subentry
+ #
+ try:
+ entries = topology.standalone.search_s(USER_DN,
+ ldap.SCOPE_BASE,
+ '(objectclass=top)',
+ ['pwdpolicysubentry', 'dn'])
+ if not entries[0].hasAttr('pwdpolicysubentry'):
+ log.fatal('User does not have expected pwdpolicysubentry!')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('Unable to search for entry %s: error %s' % (USER_DN, e.message['desc']))
+ assert False
+
+ #
+ # Delete the password policy and make sure it is removed from the same user
+ #
+ delSubtreePwPolicy(topology.standalone)
+ try:
+ entries = topology.standalone.search_s(USER_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
+ if entries[0].hasAttr('pwdpolicysubentry'):
+ log.fatal('User unexpectedly does have the pwdpolicysubentry!')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('Unable to search for entry %s: error %s' % (USER_DN, e.message['desc']))
+ assert False
+
+ #
+ # Add the subtree policvy back and see if the user now has it
+ #
+ addSubtreePwPolicy(topology.standalone)
+ try:
+ entries = topology.standalone.search_s(USER_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
+ if not entries[0].hasAttr('pwdpolicysubentry'):
+ log.fatal('User does not have expected pwdpolicysubentry!')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('Unable to search for entry %s: error %s' % (USER_DN, e.message['desc']))
+ assert False
+
+ # If we got here the test passed
+ log.info('Test PASSED')
+
+
+def test_ticket47981_final(topology):
+ topology.standalone.stop(timeout=10)
+
+
+def run_isolated():
+ '''
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+ To run isolated without py.test, you need to
+ - edit this file and comment '@pytest.fixture' line before 'topology' function.
+ - set the installation prefix
+ - run this program
+ '''
+ global installation_prefix
+ installation_prefix = None
+
+ topo = topology(True)
+ test_ticket47981(topo)
+
+if __name__ == '__main__':
+ run_isolated()
\ No newline at end of file
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
index 76cc8fd..f41c3de 100644
--- a/ldap/servers/plugins/cos/cos_cache.c
+++ b/ldap/servers/plugins/cos/cos_cache.c
@@ -300,7 +300,7 @@ static int cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAt
/* cosDefinitions manipulation */
static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_cacheable);
-static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs, int *vattr_cacheable);
+static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs);
static int cos_cache_add_defn(cosDefinitions **pDefs, cosAttrValue **dn, int cosType, cosAttrValue **tree, cosAttrValue **tmpDn, cosAttrValue **spec, cosAttrValue **pAttrs, cosAttrValue **pOverrides, cosAttrValue **pOperational, cosAttrValue **pCosMerge, cosAttrValue **pCosOpDefault);
static int cos_cache_entry_is_cos_related( Slapi_Entry *e);
@@ -659,9 +659,9 @@ static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_ca
LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_cache_build_definition_list\n",0,0,0);
/*
- the class of service definitions may be anywhere in the DIT,
- so our first task is to find them.
- */
+ * The class of service definitions may be anywhere in the DIT,
+ * so our first task is to find them.
+ */
attrs[0] = "namingcontexts";
attrs[1] = 0;
@@ -669,9 +669,9 @@ static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_ca
LDAPDebug( LDAP_DEBUG_PLUGIN, "cos: Building class of service cache after status change.\n",0,0,0);
/*
- * XXXrbyrne: this looks really ineficient--should be using
+ * XXXrbyrne: this looks really inefficient--should be using
* slapi_get_next_suffix(), rather than searching for namingcontexts.
- */
+ */
pSuffixSearch = slapi_search_internal("",LDAP_SCOPE_BASE,"(objectclass=*)",NULL,attrs,0);
if(pSuffixSearch)
@@ -711,19 +711,21 @@ static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_ca
{
/* here's a suffix, lets search it... */
if(suffixVals[valIndex]->bv_val)
- if(!cos_cache_add_dn_defs(suffixVals[valIndex]->bv_val ,pDefs, vattr_cacheable))
+ {
+ if(!cos_cache_add_dn_defs(suffixVals[valIndex]->bv_val ,pDefs))
+ {
+ *vattr_cacheable = -1;
cos_def_available = 1;
-
+ break;
+ }
+ }
valIndex++;
}
-
-
ber_bvecfree( suffixVals );
suffixVals = NULL;
}
}
}
-
} while(!slapi_entry_next_attr(pSuffixList[suffixIndex], suffixAttr, &suffixAttr));
}
suffixIndex++;
@@ -749,7 +751,6 @@ next:
slapi_pblock_destroy(pSuffixSearch);
}
-
LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_cache_build_definition_list\n",0,0,0);
return ret;
}
@@ -790,10 +791,6 @@ cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
char *norm_dn = NULL;
info=(struct dn_defs_info *)callback_data;
-
- /* assume cacheable */
- info->vattr_cacheable = -1;
-
cos_cache_add_attrval(&pDn, slapi_entry_get_dn(e));
if(slapi_entry_first_attr(e, &dnAttr)) {
goto bail;
@@ -1119,7 +1116,7 @@ bail:
#define DN_DEF_FILTER "(&(|(objectclass=cosSuperDefinition)(objectclass=cosDefinition))(objectclass=ldapsubentry))"
-static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs, int *vattr_cacheable)
+static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs)
{
Slapi_PBlock *pDnSearch = 0;
struct dn_defs_info info = {NULL, 0, 0};
@@ -1127,7 +1124,6 @@ static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs, int *vattr_ca
if (pDnSearch) {
info.ret=-1; /* assume no good defs */
info.pDefs=pDefs;
- info.vattr_cacheable = 0; /* assume not cacheable */
slapi_search_internal_set_pb(pDnSearch, dn, LDAP_SCOPE_SUBTREE,
DN_DEF_FILTER,NULL,0,
NULL,NULL,cos_get_plugin_identity(),0);
@@ -1139,8 +1135,6 @@ static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs, int *vattr_ca
slapi_pblock_destroy (pDnSearch);
}
- *vattr_cacheable = info.vattr_cacheable;
-
return info.ret;
}
9 years, 2 months
Branch '389-ds-base-1.3.1' - dirsrvtests/tickets ldap/servers
by Mark Reynolds
dirsrvtests/tickets/ticket47981_test.py | 345 ++++++++++++++++++++++++++++++++
ldap/servers/plugins/cos/cos_cache.c | 34 +--
2 files changed, 359 insertions(+), 20 deletions(-)
New commits:
commit c7c0e753d03349efc7f36654529a3be907d3187c
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Wed Jan 7 08:59:06 2015 -0500
Ticket 47981 - COS cache doesn't properly mark vattr cache as
invalid when there are multiple suffixes
Bug Description: When rebuilding the COS cache, we check each suffix for COS entries.
If the last suffix checked does not contain any COS entries, then the
virtual attribute cache is incorrectly not invalidated. This allows
for already cached entries to hold onto the old COS attributes/values.
Fix Description: Only set the vattr_cacheable flag if a suffix contains COS entries, not
if it does not - by default the flag is not set.
https://fedorahosted.org/389/ticket/47981
Reviewed by: nhosoi(Thanks!)
(cherry picked from commit 42e2df3858a4e14706d57b5c907d1d3768f4d970)
diff --git a/dirsrvtests/tickets/ticket47981_test.py b/dirsrvtests/tickets/ticket47981_test.py
new file mode 100644
index 0000000..2a16ce6
--- /dev/null
+++ b/dirsrvtests/tickets/ticket47981_test.py
@@ -0,0 +1,345 @@
+import os
+import sys
+import time
+import ldap
+import ldap.sasl
+import logging
+import socket
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from constants import *
+
+log = logging.getLogger(__name__)
+
+installation_prefix = None
+
+BRANCH = 'ou=people,' + DEFAULT_SUFFIX
+USER_DN = 'uid=user1,%s' % (BRANCH)
+BRANCH_CONTAINER = 'cn=nsPwPolicyContainer,ou=people,dc=example,dc=com'
+BRANCH_COS_DEF = 'cn=nsPwPolicy_CoS,ou=people,dc=example,dc=com'
+BRANCH_PWP = 'cn=cn\\3DnsPwPolicyEntry\\2Cou\\3DPeople\\2Cdc\\3Dexample\\2Cdc\\3Dcom,' + \
+ 'cn=nsPwPolicyContainer,ou=People,dc=example,dc=com'
+BRANCH_COS_TMPL = 'cn=cn\\3DnsPwTemplateEntry\\2Cou\\3DPeople\\2Cdc\\3Dexample\\2Cdc\\3Dcom,' + \
+ 'cn=nsPwPolicyContainer,ou=People,dc=example,dc=com'
+SECOND_SUFFIX = 'o=netscaperoot'
+BE_NAME = 'netscaperoot'
+
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ '''
+ This fixture is used to standalone topology for the 'module'.
+ At the beginning, It may exists a standalone instance.
+ It may also exists a backup for the standalone instance.
+
+ Principle:
+ If standalone instance exists:
+ restart it
+ If backup of standalone exists:
+ create/rebind to standalone
+
+ restore standalone instance from backup
+ else:
+ Cleanup everything
+ remove instance
+ remove backup
+ Create instance
+ Create backup
+ '''
+ global installation_prefix
+
+ if installation_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation_prefix
+
+ standalone = DirSrv(verbose=False)
+
+ # Args for the standalone instance
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+
+ # Get the status of the backups
+ backup_standalone = standalone.checkBackupFS()
+
+ # Get the status of the instance and restart it if it exists
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ # assuming the instance is already stopped, just wait 5 sec max
+ standalone.stop(timeout=5)
+ standalone.start(timeout=10)
+
+ if backup_standalone:
+ # The backup exist, assuming it is correct
+ # we just re-init the instance with it
+ if not instance_standalone:
+ standalone.create()
+ # Used to retrieve configuration information (dbdir, confdir...)
+ standalone.open()
+
+ # restore standalone instance from backup
+ standalone.stop(timeout=10)
+ standalone.restoreFS(backup_standalone)
+ standalone.start(timeout=10)
+
+ else:
+ # We should be here only in two conditions
+ # - This is the first time a test involve standalone instance
+ # - Something weird happened (instance/backup destroyed)
+ # so we discard everything and recreate all
+
+ # Remove the backup. So even if we have a specific backup file
+ # (e.g backup_standalone) we clear backup that an instance may have created
+ if backup_standalone:
+ standalone.clearBackupFS()
+
+ # Remove the instance
+ if instance_standalone:
+ standalone.delete()
+
+ # Create the instance
+ standalone.create()
+
+ # Used to retrieve configuration information (dbdir, confdir...)
+ standalone.open()
+
+ # Time to create the backups
+ standalone.stop(timeout=10)
+ standalone.backupfile = standalone.backupFS()
+ standalone.start(timeout=10)
+
+ # clear the tmp directory
+ standalone.clearTmpDir(__file__)
+
+ #
+ # Here we have standalone instance up and running
+ # Either coming from a backup recovery
+ # or from a fresh (re)init
+ # Time to return the topology
+ return TopologyStandalone(standalone)
+
+
+def addSubtreePwPolicy(inst):
+ #
+ # Add subtree policy to the people branch
+ #
+ try:
+ inst.add_s(Entry((BRANCH_CONTAINER, {
+ 'objectclass': 'top nsContainer'.split(),
+ 'cn': 'nsPwPolicyContainer'
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add subtree container for ou=people: error ' + e.message['desc'])
+ assert False
+
+ # Add the password policy subentry
+ try:
+ inst.add_s(Entry((BRANCH_PWP, {
+ 'objectclass': 'top ldapsubentry passwordpolicy'.split(),
+ 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
+ 'passwordMustChange': 'off',
+ 'passwordExp': 'off',
+ 'passwordHistory': 'off',
+ 'passwordMinAge': '0',
+ 'passwordChange': 'off',
+ 'passwordStorageScheme': 'ssha'
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add passwordpolicy: error ' + e.message['desc'])
+ assert False
+
+ # Add the COS template
+ try:
+ inst.add_s(Entry((BRANCH_COS_TMPL, {
+ 'objectclass': 'top ldapsubentry costemplate extensibleObject'.split(),
+ 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
+ 'cosPriority': '1',
+ 'cn': 'cn=nsPwTemplateEntry,ou=people,dc=example,dc=com',
+ 'pwdpolicysubentry': BRANCH_PWP
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add COS template: error ' + e.message['desc'])
+ assert False
+
+ # Add the COS definition
+ try:
+ inst.add_s(Entry((BRANCH_COS_DEF, {
+ 'objectclass': 'top ldapsubentry cosSuperDefinition cosPointerDefinition'.split(),
+ 'cn': 'cn=nsPwPolicyEntry,ou=people,dc=example,dc=com',
+ 'costemplatedn': BRANCH_COS_TMPL,
+ 'cosAttribute': 'pwdpolicysubentry default operational-default'
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add COS def: error ' + e.message['desc'])
+ assert False
+ time.sleep(0.5)
+
+
+def delSubtreePwPolicy(inst):
+ try:
+ inst.delete_s(BRANCH_COS_DEF)
+ except ldap.LDAPError, e:
+ log.error('Failed to delete COS def: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH_COS_TMPL)
+ except ldap.LDAPError, e:
+ log.error('Failed to delete COS template: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH_PWP)
+ except ldap.LDAPError, e:
+ log.error('Failed to delete COS password policy: error ' + e.message['desc'])
+ assert False
+
+ try:
+ inst.delete_s(BRANCH_CONTAINER)
+ except ldap.LDAPError, e:
+ log.error('Failed to delete COS container: error ' + e.message['desc'])
+ assert False
+ time.sleep(0.5)
+
+
+def test_ticket47981(topology):
+ """
+ If there are multiple suffixes, and the last suffix checked does not contain any COS entries,
+ while other suffixes do, then the vattr cache is not invalidated as it should be. Then any
+ cached entries will still contain the old COS attributes/values.
+ """
+
+ log.info('Testing Ticket 47981 - Test that COS def changes are correctly reflected in affected users')
+
+ #
+ # Create a second backend that does not have any COS entries
+ #
+ log.info('Adding second suffix that will not contain any COS entries...\n')
+
+ topology.standalone.backend.create(SECOND_SUFFIX, {BACKEND_NAME: BE_NAME})
+ topology.standalone.mappingtree.create(SECOND_SUFFIX, bename=BE_NAME)
+ try:
+ topology.standalone.add_s(Entry((SECOND_SUFFIX, {
+ 'objectclass': 'top organization'.split(),
+ 'o': BE_NAME})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('Failed to create suffix entry: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Add People branch, it might already exist
+ #
+ log.info('Add our test entries to the default suffix, and proceed with the test...')
+
+ try:
+ topology.standalone.add_s(Entry((BRANCH, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'level4'
+ })))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError, e:
+ log.error('Failed to add ou=people: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Add a user to the branch
+ #
+ try:
+ topology.standalone.add_s(Entry((USER_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'uid': 'user1'
+ })))
+ except ldap.LDAPError, e:
+ log.error('Failed to add user1: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Enable password policy and add the subtree policy
+ #
+ try:
+ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-pwpolicy-local', 'on')])
+ except ldap.LDAPError, e:
+ log.error('Failed to set pwpolicy-local: error ' + e.message['desc'])
+ assert False
+
+ addSubtreePwPolicy(topology.standalone)
+
+ #
+ # Now check the user has its expected passwordPolicy subentry
+ #
+ try:
+ entries = topology.standalone.search_s(USER_DN,
+ ldap.SCOPE_BASE,
+ '(objectclass=top)',
+ ['pwdpolicysubentry', 'dn'])
+ if not entries[0].hasAttr('pwdpolicysubentry'):
+ log.fatal('User does not have expected pwdpolicysubentry!')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('Unable to search for entry %s: error %s' % (USER_DN, e.message['desc']))
+ assert False
+
+ #
+ # Delete the password policy and make sure it is removed from the same user
+ #
+ delSubtreePwPolicy(topology.standalone)
+ try:
+ entries = topology.standalone.search_s(USER_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
+ if entries[0].hasAttr('pwdpolicysubentry'):
+ log.fatal('User unexpectedly does have the pwdpolicysubentry!')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('Unable to search for entry %s: error %s' % (USER_DN, e.message['desc']))
+ assert False
+
+ #
+ # Add the subtree policvy back and see if the user now has it
+ #
+ addSubtreePwPolicy(topology.standalone)
+ try:
+ entries = topology.standalone.search_s(USER_DN, ldap.SCOPE_BASE, '(objectclass=top)', ['pwdpolicysubentry'])
+ if not entries[0].hasAttr('pwdpolicysubentry'):
+ log.fatal('User does not have expected pwdpolicysubentry!')
+ assert False
+ except ldap.LDAPError, e:
+ log.fatal('Unable to search for entry %s: error %s' % (USER_DN, e.message['desc']))
+ assert False
+
+ # If we got here the test passed
+ log.info('Test PASSED')
+
+
+def test_ticket47981_final(topology):
+ topology.standalone.stop(timeout=10)
+
+
+def run_isolated():
+ '''
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+ To run isolated without py.test, you need to
+ - edit this file and comment '@pytest.fixture' line before 'topology' function.
+ - set the installation prefix
+ - run this program
+ '''
+ global installation_prefix
+ installation_prefix = None
+
+ topo = topology(True)
+ test_ticket47981(topo)
+
+if __name__ == '__main__':
+ run_isolated()
\ No newline at end of file
diff --git a/ldap/servers/plugins/cos/cos_cache.c b/ldap/servers/plugins/cos/cos_cache.c
index bc1132f..f98d1c8 100644
--- a/ldap/servers/plugins/cos/cos_cache.c
+++ b/ldap/servers/plugins/cos/cos_cache.c
@@ -260,7 +260,7 @@ static int cos_cache_add_tmpl(cosTemplates **pTemplates, cosAttrValue *dn, cosAt
/* cosDefinitions manipulation */
static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_cacheable);
-static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs, int *vattr_cacheable);
+static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs);
static int cos_cache_add_defn(cosDefinitions **pDefs, cosAttrValue **dn, int cosType, cosAttrValue **tree, cosAttrValue **tmpDn, cosAttrValue **spec, cosAttrValue **pAttrs, cosAttrValue **pOverrides, cosAttrValue **pOperational, cosAttrValue **pCosMerge, cosAttrValue **pCosOpDefault);
static int cos_cache_entry_is_cos_related( Slapi_Entry *e);
@@ -619,9 +619,9 @@ static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_ca
LDAPDebug( LDAP_DEBUG_TRACE, "--> cos_cache_build_definition_list\n",0,0,0);
/*
- the class of service definitions may be anywhere in the DIT,
- so our first task is to find them.
- */
+ * The class of service definitions may be anywhere in the DIT,
+ * so our first task is to find them.
+ */
attrs[0] = "namingcontexts";
attrs[1] = 0;
@@ -629,9 +629,9 @@ static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_ca
LDAPDebug( LDAP_DEBUG_PLUGIN, "cos: Building class of service cache after status change.\n",0,0,0);
/*
- * XXXrbyrne: this looks really ineficient--should be using
+ * XXXrbyrne: this looks really inefficient--should be using
* slapi_get_next_suffix(), rather than searching for namingcontexts.
- */
+ */
pSuffixSearch = slapi_search_internal("",LDAP_SCOPE_BASE,"(objectclass=*)",NULL,attrs,0);
if(pSuffixSearch)
@@ -671,19 +671,21 @@ static int cos_cache_build_definition_list(cosDefinitions **pDefs, int *vattr_ca
{
/* here's a suffix, lets search it... */
if(suffixVals[valIndex]->bv_val)
- if(!cos_cache_add_dn_defs(suffixVals[valIndex]->bv_val ,pDefs, vattr_cacheable))
+ {
+ if(!cos_cache_add_dn_defs(suffixVals[valIndex]->bv_val ,pDefs))
+ {
+ *vattr_cacheable = -1;
cos_def_available = 1;
-
+ break;
+ }
+ }
valIndex++;
}
-
-
ber_bvecfree( suffixVals );
suffixVals = NULL;
}
}
}
-
} while(!slapi_entry_next_attr(pSuffixList[suffixIndex], suffixAttr, &suffixAttr));
}
suffixIndex++;
@@ -709,7 +711,6 @@ next:
slapi_pblock_destroy(pSuffixSearch);
}
-
LDAPDebug( LDAP_DEBUG_TRACE, "<-- cos_cache_build_definition_list\n",0,0,0);
return ret;
}
@@ -750,10 +751,6 @@ cos_dn_defs_cb (Slapi_Entry* e, void *callback_data)
char *norm_dn = NULL;
info=(struct dn_defs_info *)callback_data;
-
- /* assume cacheable */
- info->vattr_cacheable = -1;
-
cos_cache_add_attrval(&pDn, slapi_entry_get_dn(e));
if(slapi_entry_first_attr(e, &dnAttr)) {
goto bail;
@@ -1076,7 +1073,7 @@ bail:
#define DN_DEF_FILTER "(&(|(objectclass=cosSuperDefinition)(objectclass=cosDefinition))(objectclass=ldapsubentry))"
-static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs, int *vattr_cacheable)
+static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs)
{
Slapi_PBlock *pDnSearch = 0;
struct dn_defs_info info = {NULL, 0, 0};
@@ -1084,7 +1081,6 @@ static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs, int *vattr_ca
if (pDnSearch) {
info.ret=-1; /* assume no good defs */
info.pDefs=pDefs;
- info.vattr_cacheable = 0; /* assume not cacheable */
slapi_search_internal_set_pb(pDnSearch, dn, LDAP_SCOPE_SUBTREE,
DN_DEF_FILTER,NULL,0,
NULL,NULL,cos_get_plugin_identity(),0);
@@ -1096,8 +1092,6 @@ static int cos_cache_add_dn_defs(char *dn, cosDefinitions **pDefs, int *vattr_ca
slapi_pblock_destroy (pDnSearch);
}
- *vattr_cacheable = info.vattr_cacheable;
-
return info.ret;
}
9 years, 2 months