ldap/schema ldap/servers
by Noriko Hosoi
ldap/schema/01core389.ldif | 4
ldap/servers/slapd/ssl.c | 407 ++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 385 insertions(+), 26 deletions(-)
New commits:
commit 88d4beccb9d9f7bb89f5e24c47828d7516ba7ca8
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Tue Dec 3 11:49:03 2013 -0800
Ticket #605 - support TLS 1.1
Description:
NSS 3.14 deprecates the current way to configure SSL versions:
SSL_OptionSet(pr_sock, SSL_ENABLE_SSL3|SSL_ENABLE_TLS, True|False)
Instead, it introduces new range APIs to provide more detailed SSL
version control by using SSL_VersionRangeSet(pr_sock, NSSVersions).
The NSSVersions has 2 fields "min" and "max", which take the minimum
and maximum SSL versions.
By default, slapd_ssl_init2 sets the default supported range by NSS,
which is min: SSL3 and max: TLS1.2. This patch adds 2 config params
sslVersionMin and sslVersionMax to cn=encryption,cn=config to provide
the ability to control the values.
Both takes: ssl3 or tls1.?. If the range is not supported by the
NSS or conflicts with the current params nsSSL3 and nsTLS1, it'd be
adjusted.
Reviewed by rmeggins(a)redhat.com (Thank you, Rich!)
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index b9baae7..7b27685 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -120,6 +120,8 @@ attributeTypes: ( nsKeyfile-oid NAME 'nsKeyfile' DESC 'Netscape defined attribut
attributeTypes: ( nsSSL2-oid NAME 'nsSSL2' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSL3-oid NAME 'nsSSL3' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsTLS1-oid NAME 'nsTLS1' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( sslVersionMin-oid NAME 'sslVersionMin' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
+attributeTypes: ( sslVersionMax-oid NAME 'sslVersionMax' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSLClientAuth-oid NAME 'nsSSLClientAuth' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSLSessionTimeout-oid NAME 'nsSSLSessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
attributeTypes: ( nsSSL3SessionTimeout-oid NAME 'nsSSL3SessionTimeout' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'Netscape' )
@@ -169,7 +171,7 @@ objectClasses: ( 2.16.840.1.113730.3.2.103 NAME 'nsDS5ReplicationAgreement' DESC
objectClasses: ( 2.16.840.1.113730.3.2.39 NAME 'nsslapdConfig' DESC 'Netscape defined objectclass' SUP top MAY ( cn ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.317 NAME 'nsSaslMapping' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSaslMapRegexString $ nsSaslMapBaseDNTemplate $ nsSaslMapFilterTemplate ) MAY ( nsSaslMapPriority ) X-ORIGIN 'Netscape Directory Server' )
objectClasses: ( 2.16.840.1.113730.3.2.43 NAME 'nsSNMP' DESC 'Netscape defined objectclass' SUP top MUST ( cn $ nsSNMPEnabled ) MAY ( nsSNMPOrganization $ nsSNMPLocation $ nsSNMPContact $ nsSNMPDescription $ nsSNMPName $ nsSNMPMasterHost $ nsSNMPMasterPort ) X-ORIGIN 'Netscape Directory Server' )
-objectClasses: ( nsEncryptionConfig-oid NAME 'nsEncryptionConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsCertfile $ nsKeyfile $ nsSSL2 $ nsSSL3 $ nsTLS1 $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $ nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers) X-ORIGIN 'Netscape' )
+objectClasses: ( nsEncryptionConfig-oid NAME 'nsEncryptionConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsCertfile $ nsKeyfile $ nsSSL2 $ nsSSL3 $ nsTLS1 $ sslVersionMin $ sslVersionMax $ nsSSLSessionTimeout $ nsSSL3SessionTimeout $ nsSSLClientAuth $ nsSSL2Ciphers $ nsSSL3Ciphers $ nsSSLSupportedCiphers) X-ORIGIN 'Netscape' )
objectClasses: ( nsEncryptionModule-oid NAME 'nsEncryptionModule' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( nsSSLToken $ nsSSLPersonalityssl $ nsSSLActivation ) X-ORIGIN 'Netscape' )
objectClasses: ( 2.16.840.1.113730.3.2.327 NAME 'rootDNPluginConfig' DESC 'Netscape defined objectclass' SUP top MUST ( cn ) MAY ( rootdn-open-time $ rootdn-close-time $ rootdn-days-allowed $ rootdn-allow-host $ rootdn-deny-host $ rootdn-allow-ip $ rootdn-deny-ip ) X-ORIGIN 'Netscape' )
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
index 61809aa..7b9bf2a 100644
--- a/ldap/servers/slapd/ssl.c
+++ b/ldap/servers/slapd/ssl.c
@@ -54,6 +54,7 @@
#include <io.h>
#endif
+#include <stdio.h>
#include <sys/param.h>
#include <ssl.h>
#include <nss.h>
@@ -81,6 +82,7 @@
extern char* slapd_SSL3ciphers;
extern symbol_t supported_ciphers[];
+static SSLVersionRange enabledNSSVersions;
/* dongle_file_name is set in slapd_nss_init when we set the path for the
key, cert, and secmod files - the dongle file must be in the same directory
@@ -141,10 +143,9 @@ static cipherstruct _conf_ciphers[] = {
{"TLS","rsa_rc4_56_sha", TLS_RSA_EXPORT1024_WITH_RC4_56_SHA}, /* ditto */
{"TLS","tls_rsa_export1024_with_des_cbc_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA},
{"TLS","rsa_des_56_sha", TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA}, /* ditto */
- {"SSL3","fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA},
- {"SSL3","fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA},
- {"SSL3","fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA},
-
+ {"SSL3","fortezza", SSL_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA}, /* deprecated */
+ {"SSL3","fortezza_rc4_128_sha", SSL_FORTEZZA_DMS_WITH_RC4_128_SHA}, /* deprecated */
+ {"SSL3","fortezza_null", SSL_FORTEZZA_DMS_WITH_NULL_SHA}, /* deprecated */
/*{"SSL3","dhe_dss_40_sha", SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA}, */
{"SSL3","dhe_dss_des_sha", SSL_DHE_DSS_WITH_DES_CBC_SHA},
@@ -165,6 +166,11 @@ 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},
+ /* New in NSS 3.14 */
+ {"TLS","tls_rsa_aes_128_gcm_sha", TLS_RSA_WITH_AES_128_GCM_SHA256},
+ {"TLS","tls_dhe_rsa_aes_128_gcm_sha", TLS_DHE_RSA_WITH_AES_128_GCM_SHA256},
+ {"TLS","tls_dhe_dss_aes_128_gcm_sha", TLS_DHE_DSS_WITH_AES_128_GCM_SHA256},
+
{NULL, NULL, 0}
};
@@ -517,6 +523,121 @@ warn_if_no_key_file(const char *dir, int no_log)
return ret;
}
+typedef struct _nss_version_list {
+ PRUint16 vnum;
+ char* vname;
+} NSSVersion_list;
+NSSVersion_list _NSSVersion_list[] =
+{
+ {SSL_LIBRARY_VERSION_2, "SSL2"},
+ {SSL_LIBRARY_VERSION_3_0, "SSL3"},
+ {SSL_LIBRARY_VERSION_TLS_1_0, "TLS1.0"},
+ {SSL_LIBRARY_VERSION_TLS_1_1, "TLS1.1"},
+ {SSL_LIBRARY_VERSION_TLS_1_2, "TLS1.2"},
+ {0, "unknown"}
+};
+
+static char *
+getNSSVersion_str(PRUint16 vnum)
+{
+ NSSVersion_list *nvlp = NULL;
+ char *vstr = "none";
+ if (vnum) {
+ for (nvlp = _NSSVersion_list; nvlp && nvlp->vnum; nvlp++) {
+ if (nvlp->vnum == vnum) {
+ vstr = nvlp->vname;
+ break;
+ }
+ }
+ }
+ return vstr;
+}
+
+/* restrict SSLVersionRange with the existing SSL config params (nsSSL3, nsTLS1) */
+static void
+restrict_SSLVersionRange(SSLVersionRange *sslversion, PRBool enableSSL3, PRBool enableTLS1)
+{
+ int rc = 0;
+ if (enableSSL3) {
+ if (enableTLS1) {
+ /* no restriction */
+ ;
+ } else {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_3_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Supported range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsTLS1. "
+ "Ignoring nsTLS1: off\n",
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
+ rc = 1;
+ } else if (sslversion->min > SSL_LIBRARY_VERSION_3_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Configured range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsTLS1. "
+ "Ignoring nsTLS1: off\n",
+ getNSSVersion_str(sslversion->min),
+ getNSSVersion_str(sslversion->max));
+ rc = 1;
+ } else if (sslversion->max < SSL_LIBRARY_VERSION_3_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Configured range: min: %s, max: %s; "
+ "but the SSL configuration of the server enabled nsSSL3. "
+ "Ignoring max: %s\n",
+ getNSSVersion_str(sslversion->min),
+ getNSSVersion_str(sslversion->max),
+ getNSSVersion_str(sslversion->max));
+ sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */
+ sslversion->max = SSL_LIBRARY_VERSION_3_0;
+ rc = 1;
+ } else {
+ sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */
+ sslversion->max = SSL_LIBRARY_VERSION_3_0;
+ }
+ }
+ } else {
+ if (enableTLS1) {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Supported range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsSSL3. ",
+ "Ignoring nsSSL3: off\n",
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
+ sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */
+ sslversion->max = SSL_LIBRARY_VERSION_3_0;
+ rc = 1;
+ } else if (sslversion->max < SSL_LIBRARY_VERSION_TLS_1_0) {
+ slapd_SSL_warn("Security Initialization: "
+ "Configured range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsSSL3. "
+ "Ignoring nsSSL3: off\n",
+ getNSSVersion_str(sslversion->min),
+ getNSSVersion_str(sslversion->max));
+ sslversion->min = SSL_LIBRARY_VERSION_3_0; /* don't enable SSL2 */
+ sslversion->max = SSL_LIBRARY_VERSION_3_0;
+ rc = 1;
+ } else if (sslversion->min < SSL_LIBRARY_VERSION_TLS_1_0) {
+ sslversion->min = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ } else {
+ slapd_SSL_warn("Security Initialization: "
+ "Supported range: min: %s, max: %s; "
+ "but the SSL configuration of the server disables nsSSL3 and nsTLS1. "
+ "Ignoring nsSSL3: off and nsTLS1: off\n",
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
+ rc = 1;
+ }
+ }
+ if (0 == rc) {
+ slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization",
+ "SSL version range: min: %s, max: %s\n",
+ getNSSVersion_str(sslversion->min),
+ getNSSVersion_str(sslversion->max));
+ }
+}
+
/*
* 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
@@ -541,6 +662,13 @@ slapd_nss_init(int init_ssl, int config_available)
char *certdb_file_name = NULL;
char *keydb_file_name = NULL;
char *secmoddb_file_name = NULL;
+ /* Get the range of the supported SSL version */
+ SSL_VersionRangeGetSupported(ssl_variant_stream, &enabledNSSVersions);
+
+ slapi_log_error(SLAPI_LOG_FATAL, "SSL Initialization",
+ "supported range: min: %s, max: %s\n",
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
/* set in slapd_bootstrap_config,
thus certdir is available even if config_available is false */
@@ -854,8 +982,196 @@ slapd_ssl_init() {
}
+/*
+ * val: sslVersionMin/Max value set in cn=encription,cn=config (INPUT)
+ * rval: Corresponding value to set SSLVersionRange (OUTPUT)
+ * ismin: True if val is sslVersionMin value
+ */
+#define SSLSTR "ssl"
+#define SSLLEN (sizeof(SSLSTR) - 1)
+#define TLSSTR "tls"
+#define TLSLEN (sizeof(TLSSTR) - 1)
+static int
+set_NSS_version(char *val, PRUint16 *rval, int ismin)
+{
+ char *vp, *endp;
+ int vnum;
-int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
+ if (NULL == rval) {
+ return 1;
+ }
+ if (!strncasecmp(val, SSLSTR, SSLLEN)) { /* ssl# */
+ vp = val + SSLLEN;
+ vnum = strtol(vp, &endp, 10);
+ if (2 == vnum) {
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_2) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_2;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_2) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_2;
+ }
+ }
+ } else if (3 == vnum) {
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_3_0) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_3_0;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_3_0) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_3_0;
+ }
+ }
+ } else {
+ if (ismin) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is invalid; the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is invalid; the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ }
+ }
+ } else if (!strncasecmp(val, TLSSTR, TLSLEN)) { /* tls# */
+ float tlsv;
+ vp = val + TLSLEN;
+ sscanf(vp, "%4f", &tlsv);
+ if (tlsv < 1.1) { /* TLS1.0 */
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_0) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_0) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_0;
+ }
+ }
+ } else if (tlsv < 1.2) { /* TLS1.1 */
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_1) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_1;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_1) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_1;
+ }
+ }
+ } else if (tlsv < 1.3) { /* TLS1.2 */
+ if (ismin) {
+ if (enabledNSSVersions.min > SSL_LIBRARY_VERSION_TLS_1_2) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is lower than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_2;
+ }
+ } else {
+ if (enabledNSSVersions.max < SSL_LIBRARY_VERSION_TLS_1_2) {
+ /* never happens */
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is higher than the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.max));
+ (*rval) = enabledNSSVersions.max;
+ } else {
+ (*rval) = SSL_LIBRARY_VERSION_TLS_1_2;
+ }
+ }
+ } else { /* TLS newer than 1.2 */
+ if (ismin) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is out of the range of the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is out of the range of the supported version; "
+ "the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.max;
+ }
+ }
+ } else {
+ if (ismin) {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMin "
+ "\"%s\" is invalid; the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.min;
+ } else {
+ slapd_SSL_warn("Security Initialization: The value of sslVersionMax "
+ "\"%s\" is invalid; the default value \"%s\" is used.\n",
+ val, getNSSVersion_str(enabledNSSVersions.min));
+ (*rval) = enabledNSSVersions.max;
+ }
+ }
+ return 0;
+}
+#undef SSLSTR
+#undef SSLLEN
+#undef TLSSTR
+#undef TLSLEN
+
+int
+slapd_ssl_init2(PRFileDesc **fd, int startTLS)
{
PRFileDesc *pr_sock, *sock = (*fd);
PRErrorCode errorCode;
@@ -875,13 +1191,15 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
PRBool enableSSL3 = PR_TRUE;
PRBool enableTLS1 = PR_TRUE;
PRBool fipsMode = PR_FALSE;
+ PRUint16 NSSVersionMin = enabledNSSVersions.min;
+ PRUint16 NSSVersionMax = enabledNSSVersions.max;
/* turn off the PKCS11 pin interactive mode */
#ifndef _WIN32
SVRCOREStdPinObj *StdPinObj;
if (svrcore_setup()) {
- return 1;
+ return 1;
}
StdPinObj = (SVRCOREStdPinObj *)SVRCORE_GetRegisteredPinObj();
@@ -1083,7 +1401,7 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
slapd_pk11_DestroyPrivateKey(key);
key = NULL;
}
- slapi_ch_free((void **) &personality);
+ slapi_ch_free((void **) &personality);
if (SECSuccess != rv) {
freeConfigEntry( &e );
continue;
@@ -1108,7 +1426,7 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
"slapd_ssl_init2", "tmp dir = %s\n", tmpDir);
rv = SSL_ConfigServerSessionIDCache(0, stimeout, stimeout, tmpDir);
- slapi_ch_free_string(&tmpDir);
+ slapi_ch_free_string(&tmpDir);
if (rv) {
errorCode = PR_GetError();
if (errorCode == ENOSPC) {
@@ -1172,7 +1490,7 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
default_val = "allowed";
break;
}
- val = default_val;
+ val = default_val;
}
if( config_set_SSLclientAuth( "nssslclientauth", val, errorbuf,
CONFIG_APPLY ) != LDAP_SUCCESS ) {
@@ -1184,7 +1502,7 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
val, errorbuf, errorCode, slapd_pr_strerror(errorCode));
}
if (val != default_val) {
- slapi_ch_free_string(&val);
+ slapi_ch_free_string(&val);
}
if ( e != NULL ) {
@@ -1218,23 +1536,62 @@ int slapd_ssl_init2(PRFileDesc **fd, int startTLS)
}
}
slapi_ch_free_string( &val );
+ val = slapi_entry_attr_get_charptr( e, "sslVersionMin" );
+ if ( val ) {
+ (void)set_NSS_version(val, &NSSVersionMin, 1);
+ }
+ slapi_ch_free_string( &val );
+ val = slapi_entry_attr_get_charptr( e, "sslVersionMax" );
+ if ( val ) {
+ (void)set_NSS_version(val, &NSSVersionMax, 0);
+ }
+ slapi_ch_free_string( &val );
+ if (NSSVersionMin > NSSVersionMax) {
+ slapd_SSL_warn("Security Initialization: The min value of NSS version range "
+ "\"%s\" is greater than the max value \"%s\"; "
+ "the default range \"%s\" - \"%s\" is used.\n",
+ getNSSVersion_str(NSSVersionMin),
+ getNSSVersion_str(NSSVersionMax),
+ getNSSVersion_str(enabledNSSVersions.min),
+ getNSSVersion_str(enabledNSSVersions.max));
+ NSSVersionMin = enabledNSSVersions.min;
+ NSSVersionMax = enabledNSSVersions.max;
+ }
}
- 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 (NSSVersionMin > 0) {
+ /* Use new NSS API SSL_VersionRangeSet (NSS3.14 or newer) */
+ SSLVersionRange myNSSVersions;
+ myNSSVersions.min = NSSVersionMin;
+ myNSSVersions.max = NSSVersionMax;
+ restrict_SSLVersionRange(&myNSSVersions, enableSSL3, enableTLS1);
+ SSL_VersionRangeSet(pr_sock, &myNSSVersions);
+ 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",
+ getNSSVersion_str(myNSSVersions.min),
+ getNSSVersion_str(myNSSVersions.max));
+ }
+ } else {
+ /* 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));
+ }
}
freeConfigEntry( &e );
10 years, 4 months
ldap/ldif ldap/servers
by Mark Reynolds
ldap/ldif/template-dse.ldif.in | 14
ldap/servers/plugins/referint/referint.c | 836 ++++++++++++++++++++++++-------
2 files changed, 672 insertions(+), 178 deletions(-)
New commits:
commit 9357bf1c46a1cbf38ae694109504ce8786a97590
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Dec 2 17:50:45 2013 -0500
Ticket 47603 - Allow RI plugin to use alternate config area
Description: RI plugin can now use an alternate config area. Also, the
pluginarg plugin configuration has been deprecated to use
unique config attributes instead:
old:
nsslapd-pluginarg0: 0
nsslapd-pluginarg1: /var/log/dirsrv/slapd-localhost/referint
nsslapd-pluginarg2: 0
nsslapd-pluginarg3: member
nsslapd-pluginarg4: uniquemember
new:
referint-update-delay: 0
referint-logfile: /var/log/dirsrv/slapd-localhost/referint
referint-logchanges: 0
referint-membership-attr: member
referint-membership-attr: uniquemember
The plugin still accepts the plugin arg configuration in the plugin
entry, but not in the new shared config entry.
Making config changes is dynamnic now, and does not require a server
restart.
Jenkins & Coverity tests: passed
https://fedorahosted.org/389/ticket/47603
Reviewed by: richm(Thanks!)
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in
index 9a52bc5..af176e9 100644
--- a/ldap/ldif/template-dse.ldif.in
+++ b/ldap/ldif/template-dse.ldif.in
@@ -606,13 +606,13 @@ nsslapd-plugininitfunc: referint_postop_init
nsslapd-plugintype: betxnpostoperation
nsslapd-pluginenabled: off
nsslapd-pluginprecedence: 40
-nsslapd-pluginArg0: 0
-nsslapd-pluginArg1: %log_dir%/referint
-nsslapd-pluginArg2: 0
-nsslapd-pluginArg3: member
-nsslapd-pluginArg4: uniquemember
-nsslapd-pluginArg5: owner
-nsslapd-pluginArg6: seeAlso
+referint-update-delay: 0
+referint-logfile: %log_dir%/referint
+referint-logchanges: 0
+referint-membership-attr: member
+referint-membership-attr: uniquemember
+referint-membership-attr: owner
+referint-membership-attr: seeAlso
nsslapd-plugin-depends-on-type: database
dn: cn=attribute uniqueness,cn=plugins,cn=config
diff --git a/ldap/servers/plugins/referint/referint.c b/ldap/servers/plugins/referint/referint.c
index 252ff16..013ffa3 100644
--- a/ldap/servers/plugins/referint/referint.c
+++ b/ldap/servers/plugins/referint/referint.c
@@ -65,9 +65,23 @@
#endif
#define REFERINT_PLUGIN_SUBSYSTEM "referint-plugin" /* used for logging */
+#define REFERINT_PREOP_DESC "referint preop plugin"
+#define REFERINT_ATTR_DELAY "referint-update-delay"
+#define REFERINT_ATTR_LOGCHANGES "referint-logchanges"
+#define REFERINT_ATTR_LOGFILE "referint-logfile"
+#define REFERINT_ATTR_MEMBERSHIP "referint-membership-attr"
#define MAX_LINE 2048
#define READ_BUFSIZE 4096
#define MY_EOF 0
+#define STARTUP 2
+
+typedef struct referint_config {
+ int delay;
+ char *logfile;
+ int logchanges;
+ char **attrs;
+} referint_config;
+Slapi_RWLock *config_rwlock = NULL;
/* function prototypes */
int referint_postop_init( Slapi_PBlock *pb );
@@ -75,11 +89,25 @@ int referint_postop_del( Slapi_PBlock *pb );
int referint_postop_modrdn( Slapi_PBlock *pb );
int referint_postop_start( Slapi_PBlock *pb);
int referint_postop_close( Slapi_PBlock *pb);
-int update_integrity(char **argv, Slapi_DN *sDN, char *newrDN, Slapi_DN *newsuperior, int logChanges);
+int update_integrity(Slapi_DN *sDN, char *newrDN, Slapi_DN *newsuperior, int logChanges);
int GetNextLine(char *dest, int size_dest, PRFileDesc *stream);
int my_fgetc(PRFileDesc *stream);
void referint_thread_func(void *arg);
void writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn, char *newrdn, Slapi_DN *newsuperior, Slapi_DN *requestorsdn);
+int load_config(Slapi_PBlock *pb, Slapi_Entry *config_entry, int apply);
+int referint_get_delay();
+int referint_get_logchanges();
+char *referint_get_logfile();
+char **referint_get_attrs();
+int referint_postop_modify(Slapi_PBlock *pb);
+int referint_validate_config(Slapi_PBlock *pb);
+static int referint_preop_init(Slapi_PBlock *pb);
+void referint_set_config_area(Slapi_DN *dn);
+Slapi_DN *referint_get_config_area();
+void referint_set_plugin_area(Slapi_DN *sdn);
+Slapi_DN *referint_get_plugin_area();
+int referint_sdn_config_cmp(Slapi_DN *sdn);
+void referint_get_config(int *delay, int *logchanges, char **logfile);
/* global thread control stuff */
static PRLock *referint_mutex = NULL;
@@ -88,14 +116,17 @@ static PRLock *keeprunning_mutex = NULL;
static PRCondVar *keeprunning_cv = NULL;
static int keeprunning = 0;
static int refint_started = 0;
+static referint_config *config = NULL;
+static Slapi_DN* _ConfigAreaDN = NULL;
+static Slapi_DN* _pluginDN = NULL;
static Slapi_PluginDesc pdesc = { "referint", VENDOR, DS_PACKAGE_VERSION, "referential integrity plugin" };
static int allow_repl = 0;
static Slapi_DN *plugin_EntryScope = NULL;
static Slapi_DN *plugin_ContainerScope = NULL;
static void* referint_plugin_identity = NULL;
-
static int use_txn = 0;
+static int premodfn = SLAPI_PLUGIN_PRE_MODIFY_FN;
#ifdef _WIN32
int *module_ldap_debug = 0;
@@ -131,6 +162,39 @@ referint_unlock()
}
}
+void
+referint_set_config_area(Slapi_DN *dn)
+{
+ slapi_rwlock_wrlock(config_rwlock);
+ slapi_sdn_free(&_ConfigAreaDN);
+ _ConfigAreaDN = slapi_sdn_dup(dn);
+ slapi_rwlock_unlock(config_rwlock);
+}
+
+/*
+ * No need to lock here, because this only called from referint_sdn_config_cmp()
+ * which does take the lock.
+ */
+Slapi_DN *
+referint_get_config_area()
+{
+ return _ConfigAreaDN;
+}
+
+/* no locking needed for the plugin DN because it is set at initialization */
+void
+referint_set_plugin_area(Slapi_DN *sdn)
+{
+ slapi_sdn_free(&_pluginDN);
+ _pluginDN = slapi_sdn_dup(sdn);
+}
+
+Slapi_DN *
+referint_get_plugin_area()
+{
+ return _pluginDN;
+}
+
int
referint_postop_init( Slapi_PBlock *pb )
{
@@ -138,6 +202,8 @@ referint_postop_init( Slapi_PBlock *pb )
char *plugin_type = NULL;
int delfn = SLAPI_PLUGIN_POST_DELETE_FN;
int mdnfn = SLAPI_PLUGIN_POST_MODRDN_FN;
+ int modfn = SLAPI_PLUGIN_POST_MODIFY_FN; /* for config changes */
+ char *preop_plugin_type = NULL;
/*
* Get plugin identity and stored it for later use.
@@ -146,6 +212,12 @@ referint_postop_init( Slapi_PBlock *pb )
slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &referint_plugin_identity);
PR_ASSERT (referint_plugin_identity);
+ if((config = (referint_config *)slapi_ch_calloc (1, sizeof (referint_config))) == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_postop_init failed to "
+ "allocate configuration\n" );
+ return ( -1 );
+ }
+
/* get the args */
if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) &&
plugin_entry &&
@@ -154,8 +226,13 @@ referint_postop_init( Slapi_PBlock *pb )
{
delfn = SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN;
mdnfn = SLAPI_PLUGIN_BE_TXN_POST_MODRDN_FN;
+ modfn = SLAPI_PLUGIN_BE_TXN_POST_MODIFY_FN;
+ preop_plugin_type = "betxnpreoperation";
+ premodfn = SLAPI_PLUGIN_BE_TXN_PRE_MODIFY_FN;
use_txn = 1;
}
+ slapi_ch_free_string(&plugin_type);
+
if(plugin_entry){
char *plugin_attr_value;
@@ -164,33 +241,37 @@ referint_postop_init( Slapi_PBlock *pb )
allow_repl = 1;
}
slapi_ch_free_string(&plugin_attr_value);
+
plugin_attr_value = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-pluginEntryScope");
if(plugin_attr_value) {
- if (slapi_dn_syntax_check(NULL, plugin_attr_value, 1) == 1) {
- slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "Error: Ignoring invalid DN used as plugin entry scope: [%s]\n",
- plugin_attr_value);
- } else {
- plugin_EntryScope = slapi_sdn_new_dn_byref(plugin_attr_value);
- }
- }
+ if (slapi_dn_syntax_check(NULL, plugin_attr_value, 1) == 1) {
+ slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "Error: Ignoring invalid DN used as plugin entry scope: [%s]\n",
+ plugin_attr_value);
+ } else {
+ plugin_EntryScope = slapi_sdn_new_dn_byref(plugin_attr_value);
+ }
+ }
+
plugin_attr_value = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-pluginContainerScope");
if(plugin_attr_value) {
- if (slapi_dn_syntax_check(NULL, plugin_attr_value, 1) == 1) {
- slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "Error: Ignoring invalid DN used as plugin container scope: [%s]\n",
- plugin_attr_value);
- } else {
- plugin_ContainerScope = slapi_sdn_new_dn_byref(plugin_attr_value);
- }
- }
+ if (slapi_dn_syntax_check(NULL, plugin_attr_value, 1) == 1) {
+ slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "Error: Ignoring invalid DN used as plugin container scope: [%s]\n",
+ plugin_attr_value);
+ } else {
+ plugin_ContainerScope = slapi_sdn_new_dn_byref(plugin_attr_value);
+ }
+ }
+
+ referint_set_plugin_area(slapi_entry_get_sdn(plugin_entry));
}
- slapi_ch_free_string(&plugin_type);
if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01 ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&pdesc ) != 0 ||
slapi_pblock_set( pb, delfn, (void *) referint_postop_del ) != 0 ||
slapi_pblock_set( pb, mdnfn, (void *) referint_postop_modrdn ) != 0 ||
+ slapi_pblock_set( pb, modfn, (void *) (void *)referint_postop_modify ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_START_FN, (void *) referint_postop_start ) != 0 ||
slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN, (void *) referint_postop_close ) != 0)
{
@@ -198,16 +279,321 @@ referint_postop_init( Slapi_PBlock *pb )
return( -1 );
}
+ /*
+ * Setup the preop plugin for config validation
+ */
+ if (slapi_register_plugin(preop_plugin_type, /* op type */
+ 1, /* Enabled */
+ "referint_preop_init", /* this function desc */
+ referint_preop_init, /* init func */
+ REFERINT_PREOP_DESC, /* plugin desc */
+ NULL, /* ? */
+ referint_plugin_identity /* access control */))
+ {
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_preop_init failed\n" );
+ return ( -1 );
+ }
+
return( 0 );
}
+/*
+ * referint-update-delay: 0
+ * referint-logfile: /var/log/dirsrv/slapd-localhost/referint
+ * referint-logchanges: 0
+ * referint-membership-attr: member
+ * referint-membership-attr: uniquemember
+ * referint-membership-attr: owner
+ * referint-membership-attr: seeAlso
+ *
+ *
+ * Need to lock this!
+ */
+int
+load_config(Slapi_PBlock *pb, Slapi_Entry *config_entry, int apply)
+{
+ referint_config *tmp_config = NULL;
+ char *value = NULL;
+ char **attrs = NULL;
+ char **argv = NULL;
+ int new_config_present = 0;
+ int argc = 0;
+ int rc = SLAPI_PLUGIN_SUCCESS;
+
+ slapi_rwlock_wrlock(config_rwlock);
+
+ if(config == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "load_config: config is NULL\n" );
+ rc = SLAPI_PLUGIN_FAILURE;
+ goto done;
+ }
+ if((tmp_config = (referint_config *)slapi_ch_calloc (1, sizeof (referint_config))) == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "load_config failed to "
+ "allocate configuration\n" );
+ rc = SLAPI_PLUGIN_FAILURE;
+ goto done;
+ } else {
+ /* set these to -1 for config validation */
+ tmp_config->delay = -1;
+ tmp_config->logchanges = -1;
+ }
+
+ if((value = slapi_entry_attr_get_charptr(config_entry, REFERINT_ATTR_DELAY))){
+ tmp_config->delay = atoi(value);
+ slapi_ch_free_string(&value);
+ new_config_present = 1;
+ }
+ if((value = slapi_entry_attr_get_charptr(config_entry, REFERINT_ATTR_LOGFILE))){
+ tmp_config->logfile = value;
+ new_config_present = 1;
+ }
+ if((value = slapi_entry_attr_get_charptr(config_entry, REFERINT_ATTR_LOGCHANGES))){
+ tmp_config->logchanges = atoi(value);
+ slapi_ch_free_string(&value);
+ new_config_present = 1;
+ }
+ if((attrs = slapi_entry_attr_get_charray(config_entry, REFERINT_ATTR_MEMBERSHIP))){
+ tmp_config->attrs = attrs;
+ new_config_present = 1;
+ }
+
+ if(new_config_present){
+ /* Verify we have everything we need */
+ if(tmp_config->delay == -1){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "Plugin configuration is missing %s\n",
+ REFERINT_ATTR_DELAY);
+ rc = SLAPI_PLUGIN_FAILURE;
+ } else if (!tmp_config->logfile){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "Plugin configuration is missing %s\n",
+ REFERINT_ATTR_LOGFILE);
+ rc = SLAPI_PLUGIN_FAILURE;
+ } else if (tmp_config->logchanges == -1){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "Plugin configuration is missing %s\n",
+ REFERINT_ATTR_LOGCHANGES);
+ rc = SLAPI_PLUGIN_FAILURE;
+ } else if (!tmp_config->attrs){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "Plugin configuration is missing %s\n",
+ REFERINT_ATTR_MEMBERSHIP);
+ rc = SLAPI_PLUGIN_FAILURE;
+ }
+ } else{
+ /*
+ * We are using the old plugin arg configuration, get the args
+ */
+ if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0) {
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_postop failed to get argc\n" );
+ rc = SLAPI_PLUGIN_FAILURE;
+ goto done;
+ }
+ if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0) {
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_postop failed to get argv\n" );
+ rc = SLAPI_PLUGIN_FAILURE;
+ goto done;
+ }
+ if(argv == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_postop_del, args are NULL\n" );
+ rc = SLAPI_PLUGIN_FAILURE;
+ goto done;
+ }
+ /*
+ * Load the args and set the config struct
+ */
+ if (argc >= 3) {
+ int i;
+
+ tmp_config->delay = atoi(argv[0]);
+ tmp_config->logfile = slapi_ch_strdup(argv[1]);
+ tmp_config->logchanges = atoi(argv[2]);
+ for(i = 3; argv[i] != NULL; i++){
+ slapi_ch_array_add(&tmp_config->attrs, slapi_ch_strdup(argv[i]));
+ }
+ } else {
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_postop insufficient arguments supplied\n" );
+ rc = SLAPI_PLUGIN_FAILURE;
+ goto done;
+ }
+ }
+
+done:
+ if(apply && rc == SLAPI_PLUGIN_SUCCESS){
+ slapi_ch_free_string(&config->logfile);
+ slapi_ch_array_free(config->attrs);
+ slapi_ch_free((void **)&config);
+ config = tmp_config;
+ } else if(tmp_config){
+ slapi_ch_free_string(&tmp_config->logfile);
+ slapi_ch_array_free(tmp_config->attrs);
+ slapi_ch_free((void **)&tmp_config);
+ }
+
+ slapi_rwlock_unlock(config_rwlock);
+
+ return rc;
+}
+
+int
+referint_postop_modify(Slapi_PBlock *pb)
+{
+ Slapi_Entry *entry = NULL, *e = NULL;
+ Slapi_Entry *config_e = NULL;
+ Slapi_DN *config_sdn = NULL;
+ Slapi_DN *sdn = NULL;
+ char *config_area = NULL;
+ int result = 0;
+ int rc = SLAPI_PLUGIN_SUCCESS;
+
+ /* check if we are updating the shared config entry */
+ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
+ slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &entry);
+
+ if (referint_sdn_config_cmp(sdn) == 0 && slapi_sdn_compare(sdn, referint_get_plugin_area()))
+ {
+ if( SLAPI_PLUGIN_FAILURE == load_config(pb, entry, 1)){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "Failed to update configuration.\n");
+ return SLAPI_PLUGIN_FAILURE;
+ }
+ } else if (slapi_sdn_compare(sdn, referint_get_plugin_area()) == 0){
+ /*
+ * Check if the plugin config area is set(verify it and load its config),
+ * otherwise reload the plugin entry config
+ */
+ if((config_area = slapi_entry_attr_get_charptr(entry, SLAPI_PLUGIN_SHARED_CONFIG_AREA))){
+ rc = slapi_dn_syntax_check(pb, config_area, 1);
+ if (rc) { /* syntax check failed */
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_postop_modify: "
+ "%s does not contain a valid DN (%s)\n",
+ SLAPI_PLUGIN_SHARED_CONFIG_AREA, config_area);
+ rc = LDAP_INVALID_DN_SYNTAX;
+ goto bail;
+ }
+ config_sdn = slapi_sdn_new_dn_byval(config_area);
+ result = slapi_search_internal_get_entry(config_sdn, NULL, &e, referint_plugin_identity);
+ if (LDAP_SUCCESS != result) {
+ if (result == LDAP_NO_SUCH_OBJECT) {
+ /* log an error and use the plugin entry for the config */
+ slapi_log_error(SLAPI_LOG_PLUGIN, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_postop_modify: Config entry \"%s\" does "
+ "not exist.\n", config_area);
+ rc = LDAP_OPERATIONS_ERROR;
+ goto bail;
+ }
+ } else {
+ if(e){
+ config_e = e;
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_postop_modify: Config entry \"%s\" was not located.\n", config_area);
+ rc = LDAP_OPERATIONS_ERROR;
+ goto bail;
+ }
+ }
+ } else {
+ config_e = entry;
+ }
+ if(load_config(pb, config_e, 1) != LDAP_SUCCESS){
+ rc = LDAP_UNWILLING_TO_PERFORM;
+ goto bail;
+ }
+ referint_set_config_area(slapi_entry_get_sdn(config_e));
+ }
+
+bail:
+ slapi_ch_free_string(&config_area);
+ slapi_sdn_free(&config_sdn);
+ slapi_entry_free(e);
+
+ return rc;
+}
+
+int
+referint_get_delay()
+{
+ int delay;
+
+ slapi_rwlock_rdlock(config_rwlock);
+ delay = config->delay;
+ slapi_rwlock_unlock(config_rwlock);
+
+ return delay;
+}
+
+int
+referint_get_logchanges()
+{
+ int log_changes;
+
+ slapi_rwlock_rdlock(config_rwlock);
+ log_changes = config->logchanges;
+ slapi_rwlock_unlock(config_rwlock);
+
+ return log_changes;
+}
+
+char *
+referint_get_logfile()
+{
+ char *log_file;
+
+ slapi_rwlock_rdlock(config_rwlock);
+ log_file = slapi_ch_strdup(config->logfile);
+ slapi_rwlock_unlock(config_rwlock);
+
+ return log_file;
+}
+
+void
+referint_get_config(int *delay, int *logchanges, char **logfile)
+{
+ slapi_rwlock_rdlock(config_rwlock);
+ if(delay){
+ *delay = config->delay;
+ }
+ if(logchanges){
+ *logchanges = config->logchanges;
+ }
+ if(logfile){
+ *logfile = slapi_ch_strdup(config->logfile);
+ }
+ slapi_rwlock_unlock(config_rwlock);
+}
+
+/*
+ * might need to find an alternate option instead of copying
+ */
+char **
+referint_get_attrs()
+{
+ char **attrs = NULL;
+
+ slapi_rwlock_rdlock(config_rwlock);
+ attrs = slapi_ch_array_dup(config->attrs);
+ slapi_rwlock_unlock(config_rwlock);
+
+ return attrs;
+}
+
+int
+referint_sdn_config_cmp(Slapi_DN *sdn)
+{
+ int rc = 0;
+
+ slapi_rwlock_rdlock(config_rwlock);
+ rc = slapi_sdn_compare(sdn, referint_get_config_area());
+ slapi_rwlock_unlock(config_rwlock);
+
+ return rc;
+}
int
referint_postop_del( Slapi_PBlock *pb )
{
Slapi_DN *sdn = NULL;
- char **argv;
- int argc;
+ char *logfile = NULL;
int delay;
int logChanges=0;
int isrepop = 0;
@@ -234,50 +620,26 @@ referint_postop_del( Slapi_PBlock *pb )
if(oprc != 0 || (isrepop && !allow_repl)){
return SLAPI_PLUGIN_SUCCESS;
}
- /* get the args */
- if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0) {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop failed to get argc\n" );
- return SLAPI_PLUGIN_FAILURE;
- }
- if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0) {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop failed to get argv\n" );
- return SLAPI_PLUGIN_FAILURE;
- }
- if(argv == NULL){
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop_del, args are NULL\n" );
- return SLAPI_PLUGIN_FAILURE;
- }
+ referint_get_config(&delay, &logChanges, NULL);
- if (argc >= 3) {
- /* argv[0] will be the delay */
- delay = atoi(argv[0]);
-
- /* argv[2] will be wether or not to log changes */
- logChanges = atoi(argv[2]);
-
- if(delay == -1){
- /* integrity updating is off */
- rc = SLAPI_PLUGIN_SUCCESS;
- } else if(delay == 0){ /* no delay */
- /* call function to update references to entry */
- if (plugin_EntryScope && slapi_sdn_issuffix(sdn, plugin_EntryScope)) {
- rc = update_integrity(argv, sdn, NULL, NULL, logChanges);
- }
- } else {
- /* write the entry to integrity log */
- writeintegritylog(pb, argv[1], sdn, NULL, NULL, NULL /* slapi_get_requestor_sdn(pb) */);
- rc = SLAPI_PLUGIN_SUCCESS;
+ if(delay == -1){
+ /* integrity updating is off */
+ rc = SLAPI_PLUGIN_SUCCESS;
+ } else if(delay == 0){ /* no delay */
+ /* call function to update references to entry */
+ if (plugin_EntryScope && slapi_sdn_issuffix(sdn, plugin_EntryScope)) {
+ rc = update_integrity(sdn, NULL, NULL, logChanges);
}
} else {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop insufficient arguments supplied\n" );
- return SLAPI_PLUGIN_FAILURE;
+ /* write the entry to integrity log */
+ logfile = referint_get_logfile();
+ writeintegritylog(pb, logfile, sdn, NULL, NULL, NULL /* slapi_get_requestor_sdn(pb) */);
+ rc = SLAPI_PLUGIN_SUCCESS;
}
+ slapi_ch_free_string(&logfile);
+
return( rc );
}
@@ -286,11 +648,10 @@ referint_postop_modrdn( Slapi_PBlock *pb )
{
Slapi_DN *sdn = NULL;
Slapi_DN *newsuperior;
+ char *logfile = NULL;
char *newrdn;
- char **argv;
int oprc;
int rc = SLAPI_PLUGIN_SUCCESS;
- int argc = 0;
int delay;
int logChanges=0;
int isrepop = 0;
@@ -312,61 +673,39 @@ referint_postop_modrdn( Slapi_PBlock *pb )
if(oprc != 0 || (isrepop && !allow_repl)){
return SLAPI_PLUGIN_SUCCESS;
}
- /* get the args */
- if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0) {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop failed to get argv\n" );
- return SLAPI_PLUGIN_FAILURE;
- }
- if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0) {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop failed to get argv\n" );
- return SLAPI_PLUGIN_FAILURE;
- }
- if(argv == NULL){
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop_modrdn, args are NULL\n" );
- return SLAPI_PLUGIN_FAILURE;
- }
- if (argc >= 3) {
- /* argv[0] will always be the delay */
- delay = atoi(argv[0]);
-
- /* argv[2] will be wether or not to log changes */
- logChanges = atoi(argv[2]);
- } else {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop_modrdn insufficient arguments supplied\n" );
- return SLAPI_PLUGIN_FAILURE;
- }
+ referint_get_config(&delay, &logChanges, NULL);
if(delay == -1){
/* integrity updating is off */
rc = SLAPI_PLUGIN_SUCCESS;
} else if(delay == 0){ /* no delay */
/* call function to update references to entry */
- if (!plugin_EntryScope) {
- /* no scope definde, default always process refint */
- rc = update_integrity(argv, sdn, newrdn, newsuperior, logChanges);
- } else {
- const char *newsuperiordn = slapi_sdn_get_dn(newsuperior);
- if ( (newsuperiordn == NULL && slapi_sdn_issuffix(sdn, plugin_EntryScope)) ||
- ( newsuperiordn && slapi_sdn_issuffix(newsuperior, plugin_EntryScope))) {
- /* it is a modrdn inside the scope or into the scope,
+ if (!plugin_EntryScope) {
+ /* no scope defined, default always process referint */
+ rc = update_integrity(sdn, newrdn, newsuperior, logChanges);
+ } else {
+ const char *newsuperiordn = slapi_sdn_get_dn(newsuperior);
+ if ( (newsuperiordn == NULL && slapi_sdn_issuffix(sdn, plugin_EntryScope)) ||
+ ( newsuperiordn && slapi_sdn_issuffix(newsuperior, plugin_EntryScope)))
+ {
+ /*
+ * It is a modrdn inside the scope or into the scope,
* process normal modrdn
*/
- rc = update_integrity(argv, sdn, newrdn, newsuperior, logChanges);
- } else if (slapi_sdn_issuffix(sdn, plugin_EntryScope)) {
- /* the entry is moved out of scope, treat as delete */
- rc = update_integrity(argv, sdn, NULL, NULL, logChanges);
+ rc = update_integrity(sdn, newrdn, newsuperior, logChanges);
+ } else if (slapi_sdn_issuffix(sdn, plugin_EntryScope)) {
+ /* the entry is moved out of scope, treat as delete */
+ rc = update_integrity(sdn, NULL, NULL, logChanges);
+ }
}
- }
} else {
/* write the entry to integrity log */
- writeintegritylog(pb, argv[1], sdn, newrdn, newsuperior, NULL /* slapi_get_requestor_sdn(pb) */);
+ logfile = referint_get_logfile();
+ writeintegritylog(pb, logfile, sdn, newrdn, newsuperior, NULL /* slapi_get_requestor_sdn(pb) */);
rc = SLAPI_PLUGIN_SUCCESS;
}
+ slapi_ch_free_string(&logfile);
return( rc );
}
@@ -741,7 +1080,7 @@ bail:
}
int
-update_integrity(char **argv, Slapi_DN *origSDN,
+update_integrity(Slapi_DN *origSDN,
char *newrDN, Slapi_DN *newsuperior,
int logChanges)
{
@@ -756,17 +1095,13 @@ update_integrity(char **argv, Slapi_DN *origSDN,
char *attrName = NULL;
char *filter = NULL;
char *attrs[2];
+ char **membership_attrs = NULL;
int search_result;
int nval = 0;
int i, j;
int rc = SLAPI_PLUGIN_SUCCESS;
- if ( argv == NULL ){
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop required config file arguments missing\n" );
- rc = SLAPI_PLUGIN_FAILURE;
- goto free_and_return;
- }
+ membership_attrs = referint_get_attrs();
/*
* For now, just putting attributes to keep integrity on in conf file,
* until resolve the other timing mode issue
@@ -786,16 +1121,16 @@ update_integrity(char **argv, Slapi_DN *origSDN,
Slapi_Backend *be = slapi_be_select(sdn);
search_base = slapi_sdn_get_dn( sdn );
- for(i = 3; argv[i] != NULL; i++){
+ for(i = 0; membership_attrs[i] != NULL; i++){
if(newrDN){
/* we need to check the children of the old dn, so use a wildcard */
- filter = slapi_filter_sprintf("(%s=*%s%s)", argv[i], ESC_NEXT_VAL, origDN);
+ filter = slapi_filter_sprintf("(%s=*%s%s)", membership_attrs[i], ESC_NEXT_VAL, origDN);
} else {
- filter = slapi_filter_sprintf("(%s=%s%s)", argv[i], ESC_NEXT_VAL, origDN);
+ filter = slapi_filter_sprintf("(%s=%s%s)", membership_attrs[i], ESC_NEXT_VAL, origDN);
}
if ( filter ) {
/* Need only the current attribute and its subtypes */
- attrs[0] = argv[i];
+ attrs[0] = membership_attrs[i];
attrs[1] = NULL;
/* Use new search API */
@@ -829,7 +1164,7 @@ update_integrity(char **argv, Slapi_DN *origSDN,
* in argv[i] having the necessary value - origDN
*/
slapi_attr_get_type(attr, &attrName);
- if (slapi_attr_type_cmp(argv[i], attrName,
+ if (slapi_attr_type_cmp(membership_attrs[i], attrName,
SLAPI_TYPE_CMP_SUBTYPE) == 0)
{
nval = 0;
@@ -891,6 +1226,7 @@ update_integrity(char **argv, Slapi_DN *origSDN,
free_and_return:
/* free filter and search_results_pb */
slapi_ch_free_string(&filter);
+ slapi_ch_array_free(membership_attrs);
slapi_pblock_destroy(mod_pb);
if (search_result_pb) {
@@ -903,61 +1239,102 @@ free_and_return:
int referint_postop_start( Slapi_PBlock *pb)
{
- char **argv;
- int argc = 0;
-
- /* get args */
- if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGC, &argc ) != 0 ) {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop failed to get argv\n" );
- return( -1 );
- }
- if ( slapi_pblock_get( pb, SLAPI_PLUGIN_ARGV, &argv ) != 0 ) {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop failed to get argv\n" );
- return( -1 );
- }
- if(argv == NULL){
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "args were null in referint_postop_start\n" );
- return( -1 );
+ Slapi_Entry *plugin_entry = NULL;
+ Slapi_Entry *config_e = NULL;
+ Slapi_PBlock *search_pb = NULL;
+ Slapi_Entry *e = NULL;
+ Slapi_DN *config_sdn = NULL;
+ char *config_area = NULL;
+ int result = 0;
+ int rc = 0;
+
+ if((config_rwlock = slapi_new_rwlock()) == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_postop_init failed to "
+ "create rwlock.\n" );
+ return ( -1 );
}
+
+ slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &plugin_entry );
+
+ /* Set the alternate config area if one is defined. */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_AREA, &config_area);
+ if (config_area)
+ {
+ rc = slapi_dn_syntax_check(pb, config_area, 1);
+ if (rc) { /* syntax check failed */
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_postop_start: "
+ "%s does not contain a valid DN (%s)\n",
+ SLAPI_PLUGIN_SHARED_CONFIG_AREA, config_area);
+ rc = LDAP_INVALID_DN_SYNTAX;
+ goto bail;
+ }
+ config_sdn = slapi_sdn_new_dn_byval(config_area);
+ result = slapi_search_internal_get_entry(config_sdn, NULL, &e, referint_plugin_identity);
+ if (LDAP_SUCCESS != result) {
+ if (result == LDAP_NO_SUCH_OBJECT) {
+ /* log an error and use the plugin entry for the config */
+ slapi_log_error(SLAPI_LOG_PLUGIN, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_postop_start: Config entry \"%s\" does "
+ "not exist.\n", config_area);
+ rc = -1;
+ goto bail;
+ }
+ } else {
+ if(e){
+ config_e = e;
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_postop_start: Config entry \"%s\" was not located.\n", config_area);
+ rc = -1;
+ goto bail;
+ }
+ }
+ } else {
+ config_e = plugin_entry;
+ }
+ if(load_config(pb, config_e, STARTUP) != LDAP_SUCCESS){
+ rc = -1;
+ goto bail;
+ }
+ referint_set_config_area(slapi_entry_get_sdn(config_e));
+
/*
* Only bother to start the thread if you are in delay mode.
* 0 = no delay,
* -1 = integrity off
*/
- if (argc >= 1) {
- if(atoi(argv[0]) > 0){
- /* initialize the cv and lock */
- if (!use_txn && (NULL == referint_mutex)) {
- referint_mutex = PR_NewLock();
- }
- keeprunning_mutex = PR_NewLock();
- keeprunning_cv = PR_NewCondVar(keeprunning_mutex);
- keeprunning =1;
-
- referint_tid = PR_CreateThread (PR_USER_THREAD,
- referint_thread_func,
- (void *)argv,
- PR_PRIORITY_NORMAL,
- PR_GLOBAL_THREAD,
- PR_UNJOINABLE_THREAD,
- SLAPD_DEFAULT_THREAD_STACKSIZE);
- if ( referint_tid == NULL ) {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop_start PR_CreateThread failed\n" );
- exit( 1 );
- }
+ if(referint_get_delay() > 0){
+ /* initialize the cv and lock */
+ if (!use_txn && (NULL == referint_mutex)) {
+ referint_mutex = PR_NewLock();
+ }
+ keeprunning_mutex = PR_NewLock();
+ keeprunning_cv = PR_NewCondVar(keeprunning_mutex);
+ keeprunning =1;
+
+ referint_tid = PR_CreateThread (PR_USER_THREAD,
+ referint_thread_func,
+ NULL,
+ PR_PRIORITY_NORMAL,
+ PR_GLOBAL_THREAD,
+ PR_UNJOINABLE_THREAD,
+ SLAPD_DEFAULT_THREAD_STACKSIZE);
+ if ( referint_tid == NULL ) {
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_postop_start PR_CreateThread failed\n" );
+ exit( 1 );
}
- } else {
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_postop_start insufficient arguments supplied\n" );
- return( -1 );
}
refint_started = 1;
- return(0);
+
+bail:
+ slapi_free_search_results_internal(search_pb);
+ slapi_pblock_destroy(search_pb);
+ slapi_sdn_free(&config_sdn);
+ slapi_entry_free(e);
+
+ return rc;
}
int referint_postop_close( Slapi_PBlock *pb)
@@ -972,6 +1349,8 @@ int referint_postop_close( Slapi_PBlock *pb)
PR_Unlock(keeprunning_mutex);
}
+ slapi_destroy_rwlock(config_rwlock);
+
refint_started = 0;
return(0);
}
@@ -980,8 +1359,7 @@ void
referint_thread_func(void *arg)
{
PRFileDesc *prfd = NULL;
- char **plugin_argv = (char **)arg;
- char *logfilename;
+ char *logfilename = NULL;
char thisline[MAX_LINE];
char delimiter[]="\t\n";
char *ptoken;
@@ -993,21 +1371,17 @@ referint_thread_func(void *arg)
int delay;
int no_changes;
- if(plugin_argv == NULL){
- slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
- "referint_thread_func not get args \n" );
- return;
- }
-
- delay = atoi(plugin_argv[0]);
- logfilename = plugin_argv[1];
- logChanges = atoi(plugin_argv[2]);
/*
* keep running this thread until plugin is signaled to close
*/
while(1){
+ /* refresh the config */
+ slapi_ch_free_string(&logfilename);
+ referint_get_config(&delay, &logChanges, &logfilename);
+
no_changes=1;
while(no_changes){
+
PR_Lock(keeprunning_mutex);
if(keeprunning == 0){
PR_Unlock(keeprunning_mutex);
@@ -1064,7 +1438,7 @@ referint_thread_func(void *arg)
}
}
- update_integrity(plugin_argv, sdn, tmprdn, tmpsuperior, logChanges);
+ update_integrity(sdn, tmprdn, tmpsuperior, logChanges);
slapi_sdn_free(&sdn);
slapi_ch_free_string(&tmprdn);
@@ -1098,6 +1472,7 @@ referint_thread_func(void *arg)
if (NULL != keeprunning_cv) {
PR_DestroyCondVar(keeprunning_cv);
}
+ slapi_ch_free_string(&logfilename);
}
int my_fgetc(PRFileDesc *stream)
@@ -1267,3 +1642,122 @@ writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn,
}
referint_unlock();
}
+
+static int
+referint_preop_init(Slapi_PBlock *pb)
+{
+ int status = 0;
+
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *) &pdesc) != 0 ||
+ slapi_pblock_set(pb, premodfn, (void *)referint_validate_config) != 0)
+ {
+ slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_preop_init: failed to register plugin\n");
+ status = -1;
+ }
+
+ return status;
+}
+
+/*
+ * This is our preop function to validate a config update, postop modify
+ * will apply the config change.
+ */
+int
+referint_validate_config(Slapi_PBlock *pb)
+{
+ Slapi_Entry *config_e = NULL, *e = NULL;
+ Slapi_Entry *pre_entry = NULL;
+ Slapi_DN *config_sdn = NULL;
+ Slapi_DN *sdn = NULL;
+ Slapi_Mods *smods = NULL;
+ LDAPMod **mods = NULL;
+ char *config_area = NULL;
+ int rc = SLAPI_PLUGIN_SUCCESS;
+
+ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &sdn);
+ slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &pre_entry);
+
+ if (referint_sdn_config_cmp(sdn) == 0 && slapi_sdn_compare(sdn, referint_get_plugin_area()) ){
+ /*
+ * This is the shared config entry. Apply the mods and set/validate
+ * the config
+ */
+ slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
+ smods = slapi_mods_new();
+ slapi_mods_init_byref(smods, mods);
+
+ /* Apply the mods to create the resulting entry. */
+ if (mods && (slapi_entry_apply_mods(pre_entry, mods) != LDAP_SUCCESS)) {
+ /* we don't care about this, the update is invalid and will be caught later */
+ goto bail;
+ }
+
+ if ( SLAPI_PLUGIN_FAILURE == load_config(pb, pre_entry, 0)) {
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_validate_config: "
+ "configuration validation failed.\n");
+ rc = LDAP_UNWILLING_TO_PERFORM;
+ }
+ } else if (slapi_sdn_compare(sdn, referint_get_plugin_area()) == 0){
+ /*
+ * Check if the plugin config area is set(verify it and load its config),
+ * otherwise reload the plugin entry config
+ */
+ slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
+ smods = slapi_mods_new();
+ slapi_mods_init_byref(smods, mods);
+
+ /* Apply the mods to create the resulting entry. */
+ if (mods && (slapi_entry_apply_mods(pre_entry, mods) != LDAP_SUCCESS)) {
+ /* we don't care about this, the update is invalid and will be caught later */
+ goto bail;
+ }
+
+ if((config_area = slapi_entry_attr_get_charptr(pre_entry, SLAPI_PLUGIN_SHARED_CONFIG_AREA))){
+ rc = slapi_dn_syntax_check(pb, config_area, 1);
+ if (rc) { /* syntax check failed */
+ slapi_log_error( SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM, "referint_validate_config: "
+ "%s does not contain a valid DN (%s)\n",
+ SLAPI_PLUGIN_SHARED_CONFIG_AREA, config_area);
+ rc = LDAP_INVALID_DN_SYNTAX;
+ goto bail;
+ }
+ config_sdn = slapi_sdn_new_dn_byval(config_area);
+ rc = slapi_search_internal_get_entry(config_sdn, NULL, &e, referint_plugin_identity);
+ if (LDAP_SUCCESS != rc) {
+ /* log an error and use the plugin entry for the config */
+ slapi_log_error(SLAPI_LOG_PLUGIN, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_validate_config: Config entry \"%s\" couild not be found, error %d\n",
+ config_area, rc);
+ rc = LDAP_OPERATIONS_ERROR;
+ goto bail;
+ } else {
+ if(e){
+ config_e = e;
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN, REFERINT_PLUGIN_SUBSYSTEM,
+ "referint_validate_config: Config entry \"%s\" was not located.\n", config_area);
+ rc = LDAP_OPERATIONS_ERROR;
+ goto bail;
+ }
+ }
+ } else {
+ config_e = pre_entry;
+ }
+ if(load_config(pb, config_e, 0) != LDAP_SUCCESS){
+ rc = LDAP_UNWILLING_TO_PERFORM;
+ goto bail;
+ }
+ referint_set_config_area(slapi_entry_get_sdn(config_e));
+ }
+
+bail:
+ slapi_entry_free(e);
+ slapi_sdn_free(&config_sdn);
+ slapi_ch_free_string(&config_area);
+ slapi_mods_free(&smods);
+
+ return rc;
+}
+
10 years, 4 months
Branch '389-ds-base-1.3.2' - rpm/add_patches.sh rpm.mk
by Nathan Kinder
rpm.mk | 16 +++++++++++++++
rpm/add_patches.sh | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+)
New commits:
commit b3b9c45481daed58cc30f4d30b422415d41a2fd0
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Wed Nov 27 05:23:50 2013 +0000
Ticket 47611 - Add script to build patched RPMs
This adds the ability to build patched RPMs, which can be useful
for using with scanning tools like Coverity. The script will
create the source tarball from HEAD of the current branch, but it
will also add patch files to the specfile if any are found in the
rpm directory in the source tree. The intended way of using this
is as follows:
git diff master workbranch > rpm/workbranch.patch
make -f rpm.mk patch_rpms
The patch files must end in .patch. Make targets are added for
patch_srpms and patch_rpms.
(cherry picked from commit 463f879b36f17aec25f78cef0dd54d27d9cbe3a4)
diff --git a/rpm.mk b/rpm.mk
index dfbadc6..fffc528 100644
--- a/rpm.mk
+++ b/rpm.mk
@@ -43,9 +43,25 @@ srpms: rpmroot srpmdistdir tarballs rpmbuildprep
cp $(RPMBUILD)/SRPMS/$(RPM_NAME_VERSION)-*.src.rpm dist/srpms/
rm -rf $(RPMBUILD)
+patch_srpms: rpmroot srpmdistdir tarballs rpmbuildprep
+ cp rpm/*.patch $(RPMBUILD)/SOURCES/
+ rpm/add_patches.sh rpm $(RPMBUILD)/SPECS/$(PACKAGE).spec
+ rpmbuild --define "_topdir $(RPMBUILD)" -bs $(RPMBUILD)/SPECS/$(PACKAGE).spec
+ cp $(RPMBUILD)/SRPMS/$(RPM_NAME_VERSION)-*.src.rpm dist/srpms/
+ rm -rf $(RPMBUILD)
+
rpms: rpmroot srpmdistdir rpmdistdir tarballs rpmbuildprep
rpmbuild --define "_topdir $(RPMBUILD)" -ba $(RPMBUILD)/SPECS/$(PACKAGE).spec
cp $(RPMBUILD)/RPMS/*/$(RPM_NAME_VERSION)-*.rpm dist/rpms/
cp $(RPMBUILD)/RPMS/*/$(PACKAGE)-*-$(RPM_VERSION)-*.rpm dist/rpms/
cp $(RPMBUILD)/SRPMS/$(RPM_NAME_VERSION)-*.src.rpm dist/srpms/
rm -rf $(RPMBUILD)
+
+patch_rpms: rpmroot srpmdistdir rpmdistdir tarballs rpmbuildprep
+ cp rpm/*.patch $(RPMBUILD)/SOURCES/
+ rpm/add_patches.sh rpm $(RPMBUILD)/SPECS/$(PACKAGE).spec
+ rpmbuild --define "_topdir $(RPMBUILD)" -ba $(RPMBUILD)/SPECS/$(PACKAGE).spec
+ cp $(RPMBUILD)/RPMS/*/$(RPM_NAME_VERSION)-*.rpm dist/rpms/
+ cp $(RPMBUILD)/RPMS/*/$(PACKAGE)-*-$(RPM_VERSION)-*.rpm dist/rpms/
+ cp $(RPMBUILD)/SRPMS/$(RPM_NAME_VERSION)-*.src.rpm dist/srpms/
+ rm -rf $(RPMBUILD)
diff --git a/rpm/add_patches.sh b/rpm/add_patches.sh
new file mode 100755
index 0000000..690d0b2
--- /dev/null
+++ b/rpm/add_patches.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+function usage()
+{
+ echo "Adds patches to a specfile"
+ echo ""
+ echo "$0 <patchdir> <specfile>"
+ echo ""
+ echo " patchdir - directory containing patches with"
+ echo " .patch extension."
+ echo " specfile - the specfile to patch."
+ exit 1
+}
+
+
+if [ $# -ne 2 ]; then
+ usage
+fi
+
+patchdir=$1
+specfile=$2
+
+# Validate our arguments.
+if [ ! -d $1 ]; then
+ echo "Patch directory $1 does not exist or is not a directory."
+ exit 1
+elif [ ! -f $2 ]; then
+ echo "Specfile $2 does not exist or is not a file."
+ exit 1
+fi
+
+# These keep track of our spec file substitutions.
+i=1
+prefix="Source0:"
+prepprefix="%setup"
+
+# Find all patches in the the patch directory.
+# to the spec file.
+patches=`ls ${patchdir}/*.patch 2>/dev/null`
+
+# If no patches exist, just exit.
+if [ -z "$patches" ]; then
+ echo "No patches found in $patchdir."
+ exit 0
+fi
+
+# Add the patches to the specfile.
+for p in $patches; do
+ p=`basename $p`
+ echo "Adding patch to spec file - $p"
+ sed -i -e "/${prefix}/a Patch${i}: ${p}" -e "/$prepprefix/a %patch${i} -p1" $specfile
+ prefix="Patch${i}:"
+ prepprefix="%patch${i}"
+ i=$(($i+1))
+done
10 years, 4 months
rpm/add_patches.sh rpm.mk
by Nathan Kinder
rpm.mk | 16 +++++++++++++++
rpm/add_patches.sh | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 71 insertions(+)
New commits:
commit 463f879b36f17aec25f78cef0dd54d27d9cbe3a4
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Wed Nov 27 05:23:50 2013 +0000
Ticket 47611 - Add script to build patched RPMs
This adds the ability to build patched RPMs, which can be useful
for using with scanning tools like Coverity. The script will
create the source tarball from HEAD of the current branch, but it
will also add patch files to the specfile if any are found in the
rpm directory in the source tree. The intended way of using this
is as follows:
git diff master workbranch > rpm/workbranch.patch
make -f rpm.mk patch_rpms
The patch files must end in .patch. Make targets are added for
patch_srpms and patch_rpms.
diff --git a/rpm.mk b/rpm.mk
index dfbadc6..fffc528 100644
--- a/rpm.mk
+++ b/rpm.mk
@@ -43,9 +43,25 @@ srpms: rpmroot srpmdistdir tarballs rpmbuildprep
cp $(RPMBUILD)/SRPMS/$(RPM_NAME_VERSION)-*.src.rpm dist/srpms/
rm -rf $(RPMBUILD)
+patch_srpms: rpmroot srpmdistdir tarballs rpmbuildprep
+ cp rpm/*.patch $(RPMBUILD)/SOURCES/
+ rpm/add_patches.sh rpm $(RPMBUILD)/SPECS/$(PACKAGE).spec
+ rpmbuild --define "_topdir $(RPMBUILD)" -bs $(RPMBUILD)/SPECS/$(PACKAGE).spec
+ cp $(RPMBUILD)/SRPMS/$(RPM_NAME_VERSION)-*.src.rpm dist/srpms/
+ rm -rf $(RPMBUILD)
+
rpms: rpmroot srpmdistdir rpmdistdir tarballs rpmbuildprep
rpmbuild --define "_topdir $(RPMBUILD)" -ba $(RPMBUILD)/SPECS/$(PACKAGE).spec
cp $(RPMBUILD)/RPMS/*/$(RPM_NAME_VERSION)-*.rpm dist/rpms/
cp $(RPMBUILD)/RPMS/*/$(PACKAGE)-*-$(RPM_VERSION)-*.rpm dist/rpms/
cp $(RPMBUILD)/SRPMS/$(RPM_NAME_VERSION)-*.src.rpm dist/srpms/
rm -rf $(RPMBUILD)
+
+patch_rpms: rpmroot srpmdistdir rpmdistdir tarballs rpmbuildprep
+ cp rpm/*.patch $(RPMBUILD)/SOURCES/
+ rpm/add_patches.sh rpm $(RPMBUILD)/SPECS/$(PACKAGE).spec
+ rpmbuild --define "_topdir $(RPMBUILD)" -ba $(RPMBUILD)/SPECS/$(PACKAGE).spec
+ cp $(RPMBUILD)/RPMS/*/$(RPM_NAME_VERSION)-*.rpm dist/rpms/
+ cp $(RPMBUILD)/RPMS/*/$(PACKAGE)-*-$(RPM_VERSION)-*.rpm dist/rpms/
+ cp $(RPMBUILD)/SRPMS/$(RPM_NAME_VERSION)-*.src.rpm dist/srpms/
+ rm -rf $(RPMBUILD)
diff --git a/rpm/add_patches.sh b/rpm/add_patches.sh
new file mode 100755
index 0000000..690d0b2
--- /dev/null
+++ b/rpm/add_patches.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+function usage()
+{
+ echo "Adds patches to a specfile"
+ echo ""
+ echo "$0 <patchdir> <specfile>"
+ echo ""
+ echo " patchdir - directory containing patches with"
+ echo " .patch extension."
+ echo " specfile - the specfile to patch."
+ exit 1
+}
+
+
+if [ $# -ne 2 ]; then
+ usage
+fi
+
+patchdir=$1
+specfile=$2
+
+# Validate our arguments.
+if [ ! -d $1 ]; then
+ echo "Patch directory $1 does not exist or is not a directory."
+ exit 1
+elif [ ! -f $2 ]; then
+ echo "Specfile $2 does not exist or is not a file."
+ exit 1
+fi
+
+# These keep track of our spec file substitutions.
+i=1
+prefix="Source0:"
+prepprefix="%setup"
+
+# Find all patches in the the patch directory.
+# to the spec file.
+patches=`ls ${patchdir}/*.patch 2>/dev/null`
+
+# If no patches exist, just exit.
+if [ -z "$patches" ]; then
+ echo "No patches found in $patchdir."
+ exit 0
+fi
+
+# Add the patches to the specfile.
+for p in $patches; do
+ p=`basename $p`
+ echo "Adding patch to spec file - $p"
+ sed -i -e "/${prefix}/a Patch${i}: ${p}" -e "/$prepprefix/a %patch${i} -p1" $specfile
+ prefix="Patch${i}:"
+ prepprefix="%patch${i}"
+ i=$(($i+1))
+done
10 years, 4 months
Branch '389-ds-base-1.3.1' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/libglobs.c | 60 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
New commits:
commit f00321f892545d59e07c1a944936153660640e47
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Dec 2 17:13:55 2013 -0500
Ticket 47614 - Possible to specify invalid SASL mechanism in nsslapd-allowed-sasl-mechanisms
Bug Description: Invalid values could be specified in the allowed sasl mechanisms configuration
attribute. These values are directly passed to the sasl library.
Fix Description: Follow RFR 4422, only allow upto 20 characters that are ASCII upper-case letters,
digits, hyphens, or underscores.
https://fedorahosted.org/389/ticket/47614
Reviewed by: richm(Thanks!)
(cherry picked from commit 7e8a5fc7183f7c08212bfb746ea8c5ceedee0132)
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index b925a2c..a763135 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -126,6 +126,7 @@ static int config_set_onoff( const char *attrname, char *value,
static int config_set_schemareplace ( const char *attrname, char *value,
char *errorbuf, int apply );
static void remove_commas(char *str);
+static int invalid_sasl_mech(char *str);
/* Keeping the initial values */
/* CONFIG_INT/CONFIG_LONG */
@@ -6768,6 +6769,13 @@ config_set_allowed_sasl_mechs(const char *attrname, char *value, char *errorbuf,
/* cyrus sasl doesn't like comma separated lists */
remove_commas(value);
+ if(invalid_sasl_mech(value)){
+ LDAPDebug(LDAP_DEBUG_ANY,"Invalid value/character for sasl mechanism (%s). Use ASCII "
+ "characters, upto 20 characters, that are upper-case letters, "
+ "digits, hyphens, or underscores\n", value, 0, 0);
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+
CFG_LOCK_WRITE(slapdFrontendConfig);
slapdFrontendConfig->allowed_sasl_mechs = slapi_ch_strdup(value);
CFG_UNLOCK_WRITE(slapdFrontendConfig);
@@ -7452,3 +7460,55 @@ remove_commas(char *str)
}
}
}
+
+/*
+ * Check the SASL mechanism values
+ *
+ * As per RFC 4422:
+ * SASL mechanisms are named by character strings, from 1 to 20
+ * characters in length, consisting of ASCII [ASCII] uppercase letters,
+ * digits, hyphens, and/or underscores.
+ */
+static int
+invalid_sasl_mech(char *str)
+{
+ char *mech = NULL, *token = NULL, *next = NULL;
+ int i;
+
+ if(str == NULL){
+ return 0;
+ }
+
+ /*
+ * Check the length for each mechanism
+ */
+ token = slapi_ch_strdup(str);
+ for (mech = ldap_utf8strtok_r(token, " ", &next); mech;
+ mech = ldap_utf8strtok_r(NULL, " ", &next))
+ {
+ if(strlen(mech) == 0 || strlen(mech) > 20){
+ /* invalid length */
+ slapi_ch_free_string(&token);
+ return 1;
+ }
+ }
+ slapi_ch_free_string(&token);
+
+ /*
+ * Check the individual characters
+ */
+ for (i = 0; str[i]; i++){
+ if ( ((int)str[i] < 48 || (int)str[i] > 57) && /* not a digit */
+ ((int)str[i] < 65 || (int)str[i] > 90) && /* not upper case */
+ (int)str[i] != 32 && /* not a space (between mechanisms) */
+ (int)str[i] != 45 && /* not a hyphen */
+ (int)str[i] != 95 ) /* not an underscore */
+ {
+ /* invalid character */
+ return 1;
+ }
+ }
+
+ /* Mechanism value is valid */
+ return 0;
+}
10 years, 4 months
Branch '389-ds-base-1.3.2' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/libglobs.c | 60 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
New commits:
commit 158795ab549bc2ffa5ddb316af94b4e0fe0b6bfb
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Dec 2 17:13:55 2013 -0500
Ticket 47614 - Possible to specify invalid SASL mechanism in nsslapd-allowed-sasl-mechanisms
Bug Description: Invalid values could be specified in the allowed sasl mechanisms configuration
attribute. These values are directly passed to the sasl library.
Fix Description: Follow RFR 4422, only allow upto 20 characters that are ASCII upper-case letters,
digits, hyphens, or underscores.
https://fedorahosted.org/389/ticket/47614
Reviewed by: richm(Thanks!)
(cherry picked from commit 7e8a5fc7183f7c08212bfb746ea8c5ceedee0132)
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index d640850..9b63fe0 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -126,6 +126,7 @@ static int config_set_onoff( const char *attrname, char *value,
static int config_set_schemareplace ( const char *attrname, char *value,
char *errorbuf, int apply );
static void remove_commas(char *str);
+static int invalid_sasl_mech(char *str);
/* Keeping the initial values */
/* CONFIG_INT/CONFIG_LONG */
@@ -6823,6 +6824,13 @@ config_set_allowed_sasl_mechs(const char *attrname, char *value, char *errorbuf,
/* cyrus sasl doesn't like comma separated lists */
remove_commas(value);
+ if(invalid_sasl_mech(value)){
+ LDAPDebug(LDAP_DEBUG_ANY,"Invalid value/character for sasl mechanism (%s). Use ASCII "
+ "characters, upto 20 characters, that are upper-case letters, "
+ "digits, hyphens, or underscores\n", value, 0, 0);
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+
CFG_LOCK_WRITE(slapdFrontendConfig);
slapdFrontendConfig->allowed_sasl_mechs = slapi_ch_strdup(value);
CFG_UNLOCK_WRITE(slapdFrontendConfig);
@@ -7594,3 +7602,55 @@ remove_commas(char *str)
}
}
}
+
+/*
+ * Check the SASL mechanism values
+ *
+ * As per RFC 4422:
+ * SASL mechanisms are named by character strings, from 1 to 20
+ * characters in length, consisting of ASCII [ASCII] uppercase letters,
+ * digits, hyphens, and/or underscores.
+ */
+static int
+invalid_sasl_mech(char *str)
+{
+ char *mech = NULL, *token = NULL, *next = NULL;
+ int i;
+
+ if(str == NULL){
+ return 0;
+ }
+
+ /*
+ * Check the length for each mechanism
+ */
+ token = slapi_ch_strdup(str);
+ for (mech = ldap_utf8strtok_r(token, " ", &next); mech;
+ mech = ldap_utf8strtok_r(NULL, " ", &next))
+ {
+ if(strlen(mech) == 0 || strlen(mech) > 20){
+ /* invalid length */
+ slapi_ch_free_string(&token);
+ return 1;
+ }
+ }
+ slapi_ch_free_string(&token);
+
+ /*
+ * Check the individual characters
+ */
+ for (i = 0; str[i]; i++){
+ if ( ((int)str[i] < 48 || (int)str[i] > 57) && /* not a digit */
+ ((int)str[i] < 65 || (int)str[i] > 90) && /* not upper case */
+ (int)str[i] != 32 && /* not a space (between mechanisms) */
+ (int)str[i] != 45 && /* not a hyphen */
+ (int)str[i] != 95 ) /* not an underscore */
+ {
+ /* invalid character */
+ return 1;
+ }
+ }
+
+ /* Mechanism value is valid */
+ return 0;
+}
10 years, 4 months
ldap/servers
by Mark Reynolds
ldap/servers/slapd/libglobs.c | 60 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
New commits:
commit 7e8a5fc7183f7c08212bfb746ea8c5ceedee0132
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Dec 2 17:13:55 2013 -0500
Ticket 47614 - Possible to specify invalid SASL mechanism in nsslapd-allowed-sasl-mechanisms
Bug Description: Invalid values could be specified in the allowed sasl mechanisms configuration
attribute. These values are directly passed to the sasl library.
Fix Description: Follow RFR 4422, only allow upto 20 characters that are ASCII upper-case letters,
digits, hyphens, or underscores.
https://fedorahosted.org/389/ticket/47614
Reviewed by: richm(Thanks!)
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 3afcb30..f269742 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -126,6 +126,7 @@ static int config_set_onoff( const char *attrname, char *value,
static int config_set_schemareplace ( const char *attrname, char *value,
char *errorbuf, int apply );
static void remove_commas(char *str);
+static int invalid_sasl_mech(char *str);
/* Keeping the initial values */
/* CONFIG_INT/CONFIG_LONG */
@@ -6824,6 +6825,13 @@ config_set_allowed_sasl_mechs(const char *attrname, char *value, char *errorbuf,
/* cyrus sasl doesn't like comma separated lists */
remove_commas(value);
+ if(invalid_sasl_mech(value)){
+ LDAPDebug(LDAP_DEBUG_ANY,"Invalid value/character for sasl mechanism (%s). Use ASCII "
+ "characters, upto 20 characters, that are upper-case letters, "
+ "digits, hyphens, or underscores\n", value, 0, 0);
+ return LDAP_UNWILLING_TO_PERFORM;
+ }
+
CFG_LOCK_WRITE(slapdFrontendConfig);
slapdFrontendConfig->allowed_sasl_mechs = slapi_ch_strdup(value);
CFG_UNLOCK_WRITE(slapdFrontendConfig);
@@ -7595,3 +7603,55 @@ remove_commas(char *str)
}
}
}
+
+/*
+ * Check the SASL mechanism values
+ *
+ * As per RFC 4422:
+ * SASL mechanisms are named by character strings, from 1 to 20
+ * characters in length, consisting of ASCII [ASCII] uppercase letters,
+ * digits, hyphens, and/or underscores.
+ */
+static int
+invalid_sasl_mech(char *str)
+{
+ char *mech = NULL, *token = NULL, *next = NULL;
+ int i;
+
+ if(str == NULL){
+ return 0;
+ }
+
+ /*
+ * Check the length for each mechanism
+ */
+ token = slapi_ch_strdup(str);
+ for (mech = ldap_utf8strtok_r(token, " ", &next); mech;
+ mech = ldap_utf8strtok_r(NULL, " ", &next))
+ {
+ if(strlen(mech) == 0 || strlen(mech) > 20){
+ /* invalid length */
+ slapi_ch_free_string(&token);
+ return 1;
+ }
+ }
+ slapi_ch_free_string(&token);
+
+ /*
+ * Check the individual characters
+ */
+ for (i = 0; str[i]; i++){
+ if ( ((int)str[i] < 48 || (int)str[i] > 57) && /* not a digit */
+ ((int)str[i] < 65 || (int)str[i] > 90) && /* not upper case */
+ (int)str[i] != 32 && /* not a space (between mechanisms) */
+ (int)str[i] != 45 && /* not a hyphen */
+ (int)str[i] != 95 ) /* not an underscore */
+ {
+ /* invalid character */
+ return 1;
+ }
+ }
+
+ /* Mechanism value is valid */
+ return 0;
+}
10 years, 4 months
ldap/servers
by Ludwig Krispenz
ldap/servers/plugins/referint/referint.c | 88 ++++++++++++++++++++++++++-----
1 file changed, 76 insertions(+), 12 deletions(-)
New commits:
commit 0cb6de1488cb5a09dd62b6279500306484fa1876
Author: Ludwig Krispenz <lkrispen(a)redhat.com>
Date: Tue Dec 3 10:11:02 2013 +0100
Ticket 47527 - Allow referential integrity suffixes to be configurable
Bug Description: Request to apply referential integrity operations
to specific subtrees only
Fix Description: The fix adds two configuration parameters to the
referential integrity plugins:
nsslapd-pluginContainerScope: <dn>
nsslapd-pluginEntryScope: <dn>
The logic implemented is:
Only entries in the nsslapd-pluginContainerScope will
be searched for references to be handled
Only for entries for which nsslapd-pluginEntryScope is
a suffix will be considered for referential integrity
processing. This results in a different bahaviour for
modrdn operations in some scenarios:
if an entry is renamed and the new superior is not
below nsslapd-pluginEntryScope then the reference to the
original dn is removed, like a delete.
For consistency also a modrdn, which moves an entry
into scope will be considered: if the old rdn is already
referenced in an entry inside the containerscope its reference
will be updated to the newdn
https://fedorahosted.org/389/ticket/47527
Reviewed by: Mark,Rich -Thanks
diff --git a/ldap/servers/plugins/referint/referint.c b/ldap/servers/plugins/referint/referint.c
index 3d5bba8..252ff16 100644
--- a/ldap/servers/plugins/referint/referint.c
+++ b/ldap/servers/plugins/referint/referint.c
@@ -91,6 +91,8 @@ static int refint_started = 0;
static Slapi_PluginDesc pdesc = { "referint", VENDOR, DS_PACKAGE_VERSION, "referential integrity plugin" };
static int allow_repl = 0;
+static Slapi_DN *plugin_EntryScope = NULL;
+static Slapi_DN *plugin_ContainerScope = NULL;
static void* referint_plugin_identity = NULL;
static int use_txn = 0;
@@ -155,13 +157,33 @@ referint_postop_init( Slapi_PBlock *pb )
use_txn = 1;
}
if(plugin_entry){
- char *allow_repl_updates;
+ char *plugin_attr_value;
- allow_repl_updates = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-pluginAllowReplUpdates");
- if(allow_repl_updates && strcasecmp(allow_repl_updates,"on")==0){
+ plugin_attr_value = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-pluginAllowReplUpdates");
+ if(plugin_attr_value && strcasecmp(plugin_attr_value,"on")==0){
allow_repl = 1;
}
- slapi_ch_free_string(&allow_repl_updates);
+ slapi_ch_free_string(&plugin_attr_value);
+ plugin_attr_value = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-pluginEntryScope");
+ if(plugin_attr_value) {
+ if (slapi_dn_syntax_check(NULL, plugin_attr_value, 1) == 1) {
+ slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "Error: Ignoring invalid DN used as plugin entry scope: [%s]\n",
+ plugin_attr_value);
+ } else {
+ plugin_EntryScope = slapi_sdn_new_dn_byref(plugin_attr_value);
+ }
+ }
+ plugin_attr_value = slapi_entry_attr_get_charptr(plugin_entry, "nsslapd-pluginContainerScope");
+ if(plugin_attr_value) {
+ if (slapi_dn_syntax_check(NULL, plugin_attr_value, 1) == 1) {
+ slapi_log_error(SLAPI_LOG_FATAL, REFERINT_PLUGIN_SUBSYSTEM,
+ "Error: Ignoring invalid DN used as plugin container scope: [%s]\n",
+ plugin_attr_value);
+ } else {
+ plugin_ContainerScope = slapi_sdn_new_dn_byref(plugin_attr_value);
+ }
+ }
}
slapi_ch_free_string(&plugin_type);
@@ -190,7 +212,7 @@ referint_postop_del( Slapi_PBlock *pb )
int logChanges=0;
int isrepop = 0;
int oprc;
- int rc;
+ int rc = SLAPI_PLUGIN_SUCCESS;
if (0 == refint_started) {
/* not initialized yet */
@@ -242,7 +264,9 @@ referint_postop_del( Slapi_PBlock *pb )
rc = SLAPI_PLUGIN_SUCCESS;
} else if(delay == 0){ /* no delay */
/* call function to update references to entry */
- rc = update_integrity(argv, sdn, NULL, NULL, logChanges);
+ if (plugin_EntryScope && slapi_sdn_issuffix(sdn, plugin_EntryScope)) {
+ rc = update_integrity(argv, sdn, NULL, NULL, logChanges);
+ }
} else {
/* write the entry to integrity log */
writeintegritylog(pb, argv[1], sdn, NULL, NULL, NULL /* slapi_get_requestor_sdn(pb) */);
@@ -265,7 +289,7 @@ referint_postop_modrdn( Slapi_PBlock *pb )
char *newrdn;
char **argv;
int oprc;
- int rc;
+ int rc = SLAPI_PLUGIN_SUCCESS;
int argc = 0;
int delay;
int logChanges=0;
@@ -322,7 +346,22 @@ referint_postop_modrdn( Slapi_PBlock *pb )
rc = SLAPI_PLUGIN_SUCCESS;
} else if(delay == 0){ /* no delay */
/* call function to update references to entry */
- rc = update_integrity(argv, sdn, newrdn, newsuperior, logChanges);
+ if (!plugin_EntryScope) {
+ /* no scope definde, default always process refint */
+ rc = update_integrity(argv, sdn, newrdn, newsuperior, logChanges);
+ } else {
+ const char *newsuperiordn = slapi_sdn_get_dn(newsuperior);
+ if ( (newsuperiordn == NULL && slapi_sdn_issuffix(sdn, plugin_EntryScope)) ||
+ ( newsuperiordn && slapi_sdn_issuffix(newsuperior, plugin_EntryScope))) {
+ /* it is a modrdn inside the scope or into the scope,
+ * process normal modrdn
+ */
+ rc = update_integrity(argv, sdn, newrdn, newsuperior, logChanges);
+ } else if (slapi_sdn_issuffix(sdn, plugin_EntryScope)) {
+ /* the entry is moved out of scope, treat as delete */
+ rc = update_integrity(argv, sdn, NULL, NULL, logChanges);
+ }
+ }
} else {
/* write the entry to integrity log */
writeintegritylog(pb, argv[1], sdn, newrdn, newsuperior, NULL /* slapi_get_requestor_sdn(pb) */);
@@ -734,9 +773,15 @@ update_integrity(char **argv, Slapi_DN *origSDN,
*/
search_result_pb = slapi_pblock_new();
- /* Search each namingContext in turn */
- for ( sdn = slapi_get_first_suffix( &node, 0 ); sdn != NULL;
- sdn = slapi_get_next_suffix( &node, 0 ))
+ /* Search each namingContext in turn
+ * or use the defined scope(s)
+ */
+ if (plugin_ContainerScope) {
+ sdn = plugin_ContainerScope;
+ } else {
+ sdn = slapi_get_first_suffix( &node, 0 );
+ }
+ while (sdn)
{
Slapi_Backend *be = slapi_be_select(sdn);
search_base = slapi_sdn_get_dn( sdn );
@@ -831,6 +876,14 @@ update_integrity(char **argv, Slapi_DN *origSDN,
}
slapi_free_search_results_internal(search_result_pb);
}
+ if (plugin_ContainerScope) {
+ /* at the moment only a single scope is supported
+ * so the loop ends after the first iteration
+ */
+ sdn = NULL;
+ } else {
+ sdn = slapi_get_next_suffix( &node, 0 );
+ }
}
/* if got here, then everything good rc = 0 */
rc = SLAPI_PLUGIN_SUCCESS;
@@ -1128,6 +1181,11 @@ writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn,
const char *newsuperiordn = NULL;
size_t reqdn_len = 0;
+ if (plugin_EntryScope &&
+ !(slapi_sdn_issuffix(sdn, plugin_EntryScope) ||
+ (newsuperior && slapi_sdn_issuffix(newsuperior, plugin_EntryScope)))) {
+ return;
+ }
/*
* Use this lock to protect file data when update integrity is occuring.
* If betxn is enabled, this mutex is ignored; transaction itself takes
@@ -1152,6 +1210,13 @@ writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn,
*/
len_to_write = slapi_sdn_get_ndn_len(sdn) + 5;
+ newsuperiordn = slapi_sdn_get_dn(newsuperior);
+ if (plugin_EntryScope && newsuperiordn &&
+ !slapi_sdn_issuffix(newsuperior, plugin_EntryScope)) {
+ /* this is a modrdn which moves the entry out of scope, handle like a delete */
+ newsuperiordn = NULL;
+ newrdn = NULL;
+ }
if(newrdn == NULL){
/* add the length of "NULL" */
len_to_write += 4;
@@ -1159,7 +1224,6 @@ writeintegritylog(Slapi_PBlock *pb, char *logfilename, Slapi_DN *sdn,
/* add the length of the newrdn */
len_to_write += strlen(newrdn);
}
- newsuperiordn = slapi_sdn_get_dn(newsuperior);
if(NULL == newsuperiordn)
{
/* add the length of "NULL" */
10 years, 4 months
dirsrvtests/tickets
by thierry bordaz
dirsrvtests/tickets/ticket47490_test.py | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
New commits:
commit fc65a9cb8b9f432e3e6b4280be8f34ceef65fd47
Author: Thierry bordaz (tbordaz) <tbordaz(a)redhat.com>
Date: Tue Dec 3 09:16:41 2013 +0100
Ticket 47586 - Need to rebind after a stop (fix to run direct python script)
Bug Description:
After a restart we need to rebind to the instance.
The fixture restore the instance from a backup
that means we need to rebind after the restore
Fix Description:
When creating the topology object, rebind the instance
https://fedorahosted.org/389/ticket/47586
Reviewed by: Rich Megginson (thanks Rich)
Platforms tested: F19
Flag Day: no
Doc impact: no
diff --git a/dirsrvtests/tickets/ticket47490_test.py b/dirsrvtests/tickets/ticket47490_test.py
index b6e591e..4fa8ffd 100644
--- a/dirsrvtests/tickets/ticket47490_test.py
+++ b/dirsrvtests/tickets/ticket47490_test.py
@@ -49,8 +49,8 @@ def _ds_rebind_instance(dirsrv):
class TopologyMasterConsumer(object):
def __init__(self, master, consumer):
- self.master = master
- self.consumer = consumer
+ self.master = _ds_rebind_instance(master)
+ self.consumer = _ds_rebind_instance(consumer)
def pattern_errorlog(file, log_pattern):
try:
10 years, 4 months
Branch '389-ds-base-1.3.1' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/libglobs.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
New commits:
commit f1461312fc9e221413b19d6babbdf5a886794d10
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Dec 2 15:08:15 2013 -0500
Ticket 47613 - Impossible to configure nsslapd-allowed-sasl-mechanisms
Bug Description: The design doc sasy you can use comma separated list of supported mechanisms,
but in fact this was not supported.
Fix Description: Allow comma separated lists.
https://fedorahosted.org/389/ticket/47613
Reviewed by: richm(Thanks!)
(cherry picked from commit 6200f6812682760cd2a54d6a3bcbb009a0dffe79)
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index f8c5b01..b925a2c 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -125,6 +125,7 @@ static int config_set_onoff( const char *attrname, char *value,
int *configvalue, char *errorbuf, int apply );
static int config_set_schemareplace ( const char *attrname, char *value,
char *errorbuf, int apply );
+static void remove_commas(char *str);
/* Keeping the initial values */
/* CONFIG_INT/CONFIG_LONG */
@@ -6764,6 +6765,9 @@ config_set_allowed_sasl_mechs(const char *attrname, char *value, char *errorbuf,
return LDAP_SUCCESS;
}
+ /* cyrus sasl doesn't like comma separated lists */
+ remove_commas(value);
+
CFG_LOCK_WRITE(slapdFrontendConfig);
slapdFrontendConfig->allowed_sasl_mechs = slapi_ch_strdup(value);
CFG_UNLOCK_WRITE(slapdFrontendConfig);
@@ -7434,3 +7438,17 @@ slapi_err2string(int result)
#endif
}
+/* replace commas with spaces */
+static void
+remove_commas(char *str)
+{
+ int i;
+
+ for (i = 0; str && str[i]; i++)
+ {
+ if (str[i] == ',')
+ {
+ str[i] = ' ';
+ }
+ }
+}
10 years, 4 months