Blame SOURCES/0042-Ticket-47379-DNA-plugin-failed-to-fetch-replication-.patch

ba46c7
From e5a913283852fd3f7074127076ef648c74fb8388 Mon Sep 17 00:00:00 2001
ba46c7
From: Mark Reynolds <mreynolds@redhat.com>
ba46c7
Date: Fri, 14 Jun 2013 11:05:46 -0400
ba46c7
Subject: [PATCH 42/44] Ticket 47379 - DNA plugin failed to fetch replication
ba46c7
 agreement
ba46c7
ba46c7
Bug Description:  When trying to get the next range of available values, if a shared config
ba46c7
                  server does not have a replication agreement that points to itself then
ba46c7
                  it can not obtain the bind credentials/info to successfully contact that
ba46c7
                  server when trying to get the next range.
ba46c7
ba46c7
Fix Description:  Extend the shared config server to allow for bind information, such as bind
ba46c7
                  method, and connection protocol.  For the bind DN and pw(for SIMPLE and DIGEST-MD5
ba46c7
                  bind methods), we store this in the plugin config entry.  As each bind pw needs to
ba46c7
                  use DES pw storage scheme, and this must be local to each server (not replicated
ba46c7
                  with the shared config server entry).
ba46c7
ba46c7
                  Fixed infinite loop in dna_fix_maxval() - we did not advance the server list if
ba46c7
                  there was a error.  Also improved config validation to make sure the shared config
ba46c7
                  entry is not within the scope & filter of the DNA config.
ba46c7
ba46c7
https://fedorahosted.org/389/ticket/47379
ba46c7
ba46c7
Reviewed by: richm & nkinder(Thanks!!)
ba46c7
(cherry picked from commit 3e2262e1c0410bdf4f9b9211aef13deb28f174d1)
ba46c7
(cherry picked from commit 5010f508203df08984500fdc3ac878611c0ac05b)
ba46c7
---
ba46c7
 ldap/schema/10dna-plugin.ldif  |  38 +++++-
ba46c7
 ldap/servers/plugins/dna/dna.c | 263 +++++++++++++++++++++++++++++++++++++----
ba46c7
 2 files changed, 278 insertions(+), 23 deletions(-)
ba46c7
ba46c7
diff --git a/ldap/schema/10dna-plugin.ldif b/ldap/schema/10dna-plugin.ldif
ba46c7
index c89c6b5..ac9b5f4 100644
ba46c7
--- a/ldap/schema/10dna-plugin.ldif
ba46c7
+++ b/ldap/schema/10dna-plugin.ldif
ba46c7
@@ -170,6 +170,38 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2130 NAME 'dnaRangeRequestTimeout'
ba46c7
 #
ba46c7
 ################################################################################
ba46c7
 #
ba46c7
+attributeTypes: ( 2.16.840.1.113730.3.1.2157 NAME 'dnaRemoteBindCred'
ba46c7
+  DESC 'Remote bind credentials'
ba46c7
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
ba46c7
+  SINGLE-VALUE
ba46c7
+  X-ORIGIN '389 Directory Server' )
ba46c7
+#
ba46c7
+################################################################################
ba46c7
+#
ba46c7
+attributeTypes: ( 2.16.840.1.113730.3.1.2158 NAME 'dnaRemoteBindDN'
ba46c7
+  DESC 'Remote bind DN'
ba46c7
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
ba46c7
+  SINGLE-VALUE
ba46c7
+  X-ORIGIN '389 Directory Server' )
ba46c7
+#
ba46c7
+################################################################################
ba46c7
+#
ba46c7
+attributeTypes: ( 2.16.840.1.113730.3.1.2159 NAME 'dnaRemoteConnProtocol'
ba46c7
+  DESC 'Connection protocol: LDAP, TLS, or SSL'
ba46c7
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
ba46c7
+  SINGLE-VALUE
ba46c7
+  X-ORIGIN '389 Directory Server' )
ba46c7
+#
ba46c7
+################################################################################
ba46c7
+#
ba46c7
+attributeTypes: ( 2.16.840.1.113730.3.1.2160 NAME 'dnaRemoteBindMethod'
ba46c7
+  DESC 'Remote bind method: SIMPLE, SSL, SASL/DIGEST-MD5, or SASL/GSSAPI'
ba46c7
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
ba46c7
+  SINGLE-VALUE
ba46c7
+  X-ORIGIN '389 Directory Server' )
ba46c7
+#
ba46c7
+################################################################################
ba46c7
+#
ba46c7
 objectClasses: ( 2.16.840.1.113730.3.2.324 NAME 'dnaPluginConfig'
ba46c7
   DESC 'DNA plugin configuration'
ba46c7
   SUP top
ba46c7
@@ -185,7 +217,9 @@ objectClasses: ( 2.16.840.1.113730.3.2.324 NAME 'dnaPluginConfig'
ba46c7
         dnaSharedCfgDN $
ba46c7
         dnaThreshold $
ba46c7
         dnaNextRange $
ba46c7
-        dnaRangeRequestTimeout $
ba46c7
+        dnaRangeRequestTimeout $        
ba46c7
+	dnaRemoteBindDN $
ba46c7
+        dnaRemoteBindCred $
ba46c7
         cn
ba46c7
  )
ba46c7
   X-ORIGIN '389 Directory Server' )
ba46c7
@@ -199,6 +233,8 @@ objectClasses: ( 2.16.840.1.113730.3.2.325 NAME 'dnaSharedConfig'
ba46c7
   MAY ( dnaHostname $
ba46c7
         dnaPortNum $
ba46c7
         dnaSecurePortNum $
ba46c7
+        dnaRemoteBindMethod $
ba46c7
+        dnaRemoteConnProtocol $
ba46c7
         dnaRemainingValues
ba46c7
  )
ba46c7
   X-ORIGIN '389 Directory Server' )
ba46c7
diff --git a/ldap/servers/plugins/dna/dna.c b/ldap/servers/plugins/dna/dna.c
ba46c7
index f3abb40..40522a6 100644
ba46c7
--- a/ldap/servers/plugins/dna/dna.c
ba46c7
+++ b/ldap/servers/plugins/dna/dna.c
ba46c7
@@ -87,18 +87,31 @@
ba46c7
 #define DNA_GENERATE        "dnaMagicRegen"
ba46c7
 #define DNA_FILTER          "dnaFilter"
ba46c7
 #define DNA_SCOPE           "dnaScope"
ba46c7
+#define DNA_REMOTE_BIND_DN  "dnaRemoteBindDN"
ba46c7
+#define DNA_REMOTE_BIND_PW  "dnaRemoteBindCred"
ba46c7
 
ba46c7
 /* since v2 */
ba46c7
 #define DNA_MAXVAL          "dnaMaxValue"
ba46c7
 #define DNA_SHARED_CFG_DN   "dnaSharedCfgDN"
ba46c7
 
ba46c7
 /* Shared Config */
ba46c7
-#define DNA_SHAREDCONFIG    "dnaSharedConfig"
ba46c7
-#define DNA_REMAINING       "dnaRemainingValues"
ba46c7
-#define DNA_THRESHOLD       "dnaThreshold"
ba46c7
-#define DNA_HOSTNAME        "dnaHostname"
ba46c7
-#define DNA_PORTNUM         "dnaPortNum"
ba46c7
-#define DNA_SECURE_PORTNUM  "dnaSecurePortNum"
ba46c7
+#define DNA_SHAREDCONFIG       "dnaSharedConfig"
ba46c7
+#define DNA_REMAINING          "dnaRemainingValues"
ba46c7
+#define DNA_THRESHOLD          "dnaThreshold"
ba46c7
+#define DNA_HOSTNAME           "dnaHostname"
ba46c7
+#define DNA_PORTNUM            "dnaPortNum"
ba46c7
+#define DNA_SECURE_PORTNUM     "dnaSecurePortNum"
ba46c7
+#define DNA_REMOTE_BIND_METHOD "dnaRemoteBindMethod"
ba46c7
+#define DNA_REMOTE_CONN_PROT   "dnaRemoteConnProtocol"
ba46c7
+
ba46c7
+/* Bind Methods & Protocols */
ba46c7
+#define DNA_METHOD_SIMPLE    "SIMPLE"
ba46c7
+#define DNA_METHOD_SSL       "SSL"
ba46c7
+#define DNA_METHOD_GSSAPI    "SASL/GSSAPI"
ba46c7
+#define DNA_METHOD_DIGESTMD5 "SASL/DIGEST-MD5"
ba46c7
+#define DNA_PROT_LDAP "LDAP"
ba46c7
+#define DNA_PROT_TLS  "TLS"
ba46c7
+#define DNA_PROT_SSL  "SSL"
ba46c7
 
ba46c7
 /* For transferred ranges */
ba46c7
 #define DNA_NEXT_RANGE            "dnaNextRange"
ba46c7
@@ -154,6 +167,8 @@ struct configEntry {
ba46c7
     PRUint64 threshold;
ba46c7
     char *shared_cfg_base;
ba46c7
     char *shared_cfg_dn;
ba46c7
+    char *remote_binddn;
ba46c7
+    char *remote_bindpw;
ba46c7
     PRUint64 timeout;
ba46c7
     /* This lock protects the 5 members below.  All
ba46c7
      * of the above members are safe to read as long
ba46c7
@@ -195,6 +210,12 @@ struct dnaServer {
ba46c7
     unsigned int port;
ba46c7
     unsigned int secureport;
ba46c7
     PRUint64 remaining;
ba46c7
+    /* Remote replica settings from config */
ba46c7
+    PRUint64 remote_defined;
ba46c7
+    char *remote_bind_method;
ba46c7
+    char *remote_conn_prot;
ba46c7
+    char *remote_binddn; /* contains pointer to main config binddn */
ba46c7
+    char *remote_bindpw; /* contains pointer to main config bindpw */
ba46c7
 };
ba46c7
 
ba46c7
 static char *dna_extend_exop_oid_list[] = {
ba46c7
@@ -220,8 +241,8 @@ static int dna_be_txn_preop_init(Slapi_PBlock *pb);
ba46c7
  * Local operation functions
ba46c7
  *
ba46c7
  */
ba46c7
-static int dna_load_plugin_config(int use_eventq);
ba46c7
-static int dna_parse_config_entry(Slapi_Entry * e, int apply);
ba46c7
+static int dna_load_plugin_config(Slapi_PBlock *pb, int use_eventq);
ba46c7
+static int dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply);
ba46c7
 static void dna_delete_config();
ba46c7
 static void dna_free_config_entry(struct configEntry ** entry);
ba46c7
 static int dna_load_host_port();
ba46c7
@@ -264,6 +285,8 @@ static void dna_list_remove_type(char **list, char *type);
ba46c7
 static int dna_is_multitype_range(struct configEntry *config_entry);
ba46c7
 static void dna_create_valcheck_filter(struct configEntry *config_entry, PRUint64 value, char **filter);
ba46c7
 static int dna_isrepl(Slapi_PBlock *pb);
ba46c7
+static int dna_get_remote_config_info( struct dnaServer *server, char **bind_dn, char **bind_passwd,
ba46c7
+                                       char **bind_method, int *is_ssl, int *port);
ba46c7
 
ba46c7
 /**
ba46c7
  *
ba46c7
@@ -572,7 +595,7 @@ dna_start(Slapi_PBlock * pb)
ba46c7
         slapi_ch_calloc(1, sizeof(struct configEntry));
ba46c7
     PR_INIT_CLIST(dna_global_config);
ba46c7
 
ba46c7
-    if (dna_load_plugin_config(1/* use eventq */) != DNA_SUCCESS) {
ba46c7
+    if (dna_load_plugin_config(pb, 1/* use eventq */) != DNA_SUCCESS) {
ba46c7
         slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
ba46c7
                         "dna_start: unable to load plug-in configuration\n");
ba46c7
         return DNA_FAILURE;
ba46c7
@@ -640,7 +663,7 @@ done:
ba46c7
  * ------ cn=etc etc
ba46c7
  */
ba46c7
 static int
ba46c7
-dna_load_plugin_config(int use_eventq)
ba46c7
+dna_load_plugin_config(Slapi_PBlock *pb, int use_eventq)
ba46c7
 {
ba46c7
     int status = DNA_SUCCESS;
ba46c7
     int result;
ba46c7
@@ -682,7 +705,7 @@ dna_load_plugin_config(int use_eventq)
ba46c7
         /* We don't care about the status here because we may have
ba46c7
          * some invalid config entries, but we just want to continue
ba46c7
          * looking for valid ones. */
ba46c7
-        dna_parse_config_entry(entries[i], 1);
ba46c7
+        dna_parse_config_entry(pb, entries[i], 1);
ba46c7
     }
ba46c7
     dna_unlock();
ba46c7
 
ba46c7
@@ -719,7 +742,7 @@ cleanup:
ba46c7
  * if it is invalid.
ba46c7
  */
ba46c7
 static int
ba46c7
-dna_parse_config_entry(Slapi_Entry * e, int apply)
ba46c7
+dna_parse_config_entry(Slapi_PBlock *pb, Slapi_Entry * e, int apply)
ba46c7
 {
ba46c7
     char *value;
ba46c7
     struct configEntry *entry = NULL;
ba46c7
@@ -885,6 +908,45 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
ba46c7
                     "----------> %s [%" NSPRIu64 "]\n", DNA_MAXVAL,
ba46c7
                     (long long unsigned int)entry->maxval);
ba46c7
 
ba46c7
+    /* get the global bind dn and password(if any) */
ba46c7
+    value = slapi_entry_attr_get_charptr(e, DNA_REMOTE_BIND_DN);
ba46c7
+    if (value) {
ba46c7
+        Slapi_DN *sdn = NULL;
ba46c7
+        char *normdn = NULL;
ba46c7
+
ba46c7
+        sdn = slapi_sdn_new_dn_passin(value);
ba46c7
+        if (!sdn) {
ba46c7
+            slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
ba46c7
+                    "dna_parse_config_entry: Unable to create "
ba46c7
+                    "slapi_dn from dnaRemoteBindDN (%s)\n", value);
ba46c7
+            ret = DNA_FAILURE;
ba46c7
+            slapi_ch_free_string(&value);
ba46c7
+            goto bail;
ba46c7
+        }
ba46c7
+        normdn = (char *)slapi_sdn_get_dn(sdn);
ba46c7
+        if (NULL == normdn) {
ba46c7
+            slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
ba46c7
+                "dna_parse_config_entry: failed to normalize dn: "
ba46c7
+                "%s\n", value);
ba46c7
+            ret = DNA_FAILURE;
ba46c7
+            slapi_sdn_free(&sdn);
ba46c7
+            goto bail;
ba46c7
+        }
ba46c7
+        entry->remote_binddn = slapi_ch_strdup(normdn);
ba46c7
+        slapi_sdn_free(&sdn);
ba46c7
+    }
ba46c7
+    /* now grab the password */
ba46c7
+    entry->remote_bindpw = slapi_entry_attr_get_charptr(e, DNA_REMOTE_BIND_PW);
ba46c7
+
ba46c7
+    /* validate that we have both a bind dn or password, or we have none */
ba46c7
+    if((entry->remote_bindpw != NULL && entry->remote_binddn == NULL) ||
ba46c7
+       (entry->remote_binddn != NULL && entry->remote_bindpw == NULL)){
ba46c7
+        slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
ba46c7
+                "dna_parse_config_entry: Invalid remote bind DN and password settings.\n");
ba46c7
+        ret = DNA_FAILURE;
ba46c7
+        goto bail;
ba46c7
+    }
ba46c7
+
ba46c7
     value = slapi_entry_attr_get_charptr(e, DNA_SHARED_CFG_DN);
ba46c7
     if (value) {
ba46c7
         Slapi_Entry *shared_e = NULL;
ba46c7
@@ -1060,6 +1122,21 @@ dna_parse_config_entry(Slapi_Entry * e, int apply)
ba46c7
         goto bail;
ba46c7
     }
ba46c7
 
ba46c7
+    /* Check if the shared config base matches the config scope and filter */
ba46c7
+    if (entry->scope && slapi_dn_issuffix(entry->shared_cfg_base, entry->scope)){
ba46c7
+        if (entry->slapi_filter) {
ba46c7
+            ret = slapi_vattr_filter_test(pb, e, entry->slapi_filter, 0);
ba46c7
+            if (LDAP_SUCCESS == ret) {
ba46c7
+                slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM, "dna_parse_config_entry: "
ba46c7
+                        "Error: shared config entry (%s) matches scope \"%s\", and filter \"%s\" "
ba46c7
+                        "of the DNA config entry (%s).\n", entry->shared_cfg_base,
ba46c7
+                        entry->scope, entry->filter, entry->dn);
ba46c7
+                ret = DNA_FAILURE;
ba46c7
+                goto bail;
ba46c7
+            }
ba46c7
+        }
ba46c7
+    }
ba46c7
+
ba46c7
     /**
ba46c7
      * Finally add the entry to the list.
ba46c7
      * We sort by scope dn length with longer
ba46c7
@@ -1143,6 +1220,8 @@ dna_free_config_entry(struct configEntry ** entry)
ba46c7
     slapi_ch_free_string(&e->scope);
ba46c7
     slapi_ch_free_string(&e->shared_cfg_base);
ba46c7
     slapi_ch_free_string(&e->shared_cfg_dn);
ba46c7
+    slapi_ch_free_string(&e->remote_binddn);
ba46c7
+    slapi_ch_free_string(&e->remote_bindpw);
ba46c7
 
ba46c7
     slapi_destroy_mutex(e->lock);
ba46c7
 
ba46c7
@@ -1173,13 +1252,14 @@ static void
ba46c7
 dna_free_shared_server(struct dnaServer **server)
ba46c7
 {
ba46c7
     struct dnaServer *s;
ba46c7
+
ba46c7
     if ((NULL == server) || (NULL == *server)) {
ba46c7
         return;
ba46c7
     }
ba46c7
-
ba46c7
     s = *server;
ba46c7
     slapi_ch_free_string(&s->host);
ba46c7
-
ba46c7
+    slapi_ch_free_string(&s->remote_bind_method);
ba46c7
+    slapi_ch_free_string(&s->remote_conn_prot);
ba46c7
     slapi_ch_free((void **)server);
ba46c7
 }
ba46c7
 
ba46c7
@@ -1383,6 +1463,7 @@ static int dna_fix_maxval(struct configEntry *config_entry,
ba46c7
                     if ((ret = dna_update_next_range(config_entry, lower, upper)) == 0) {
ba46c7
                         break;
ba46c7
                     }
ba46c7
+                    server = PR_NEXT_LINK(server);
ba46c7
                 }
ba46c7
             }
ba46c7
 
ba46c7
@@ -1459,7 +1540,7 @@ dna_get_shared_servers(struct configEntry *config_entry, PRCList **servers)
ba46c7
     int ret = LDAP_SUCCESS;
ba46c7
     Slapi_PBlock *pb = NULL;
ba46c7
     Slapi_Entry **entries = NULL;
ba46c7
-    char *attrs[5];
ba46c7
+    char *attrs[7];
ba46c7
 
ba46c7
     /* First do a search in the shared config area for this
ba46c7
      * range to find other servers who are managing this range. */
ba46c7
@@ -1467,7 +1548,9 @@ dna_get_shared_servers(struct configEntry *config_entry, PRCList **servers)
ba46c7
     attrs[1] = DNA_PORTNUM;
ba46c7
     attrs[2] = DNA_SECURE_PORTNUM;
ba46c7
     attrs[3] = DNA_REMAINING;
ba46c7
-    attrs[4] = NULL;
ba46c7
+    attrs[4] = DNA_REMOTE_BIND_METHOD;
ba46c7
+    attrs[5] = DNA_REMOTE_CONN_PROT;
ba46c7
+    attrs[6] = NULL;
ba46c7
 
ba46c7
     pb = slapi_pblock_new();
ba46c7
     if (NULL == pb) {
ba46c7
@@ -1515,9 +1598,16 @@ dna_get_shared_servers(struct configEntry *config_entry, PRCList **servers)
ba46c7
                 server->secureport = slapi_entry_attr_get_uint(entries[i], DNA_SECURE_PORTNUM);
ba46c7
                 server->remaining = slapi_entry_attr_get_ulonglong(entries[i],
ba46c7
                                                                    DNA_REMAINING);
ba46c7
+                server->remote_binddn = config_entry->remote_binddn;
ba46c7
+                server->remote_bindpw = config_entry->remote_bindpw;
ba46c7
+                server->remote_bind_method = slapi_entry_attr_get_charptr(entries[i],
ba46c7
+                                                                          DNA_REMOTE_BIND_METHOD);
ba46c7
+                server->remote_conn_prot = slapi_entry_attr_get_charptr(entries[i],
ba46c7
+                                                                        DNA_REMOTE_CONN_PROT);
ba46c7
 
ba46c7
                 /* validate the entry */
ba46c7
-                if (!server->host || server->port == 0 || server->remaining == 0) {
ba46c7
+                if (!server->host || (server->port == 0 && server->secureport == 0) || server->remaining == 0)
ba46c7
+                {
ba46c7
                     /* free and skip this one */
ba46c7
                     slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
ba46c7
                                     "dna_get_shared_servers: skipping invalid "
ba46c7
@@ -1525,6 +1615,40 @@ dna_get_shared_servers(struct configEntry *config_entry, PRCList **servers)
ba46c7
                     dna_free_shared_server(&server);
ba46c7
                     continue;
ba46c7
                 }
ba46c7
+                /* see if we defined a server manually */
ba46c7
+                if(server->remote_bind_method){
ba46c7
+                    char *reason;
ba46c7
+                    int err = 0;
ba46c7
+
ba46c7
+                    if(strcasecmp(server->remote_bind_method, DNA_METHOD_DIGESTMD5) == 0 ||
ba46c7
+                       strcasecmp(server->remote_bind_method, DNA_METHOD_SIMPLE) == 0){
ba46c7
+                        /* requires a DN and password */
ba46c7
+                        if(!server->remote_binddn || !server->remote_bindpw){
ba46c7
+                            reason = "missing bind DN and/or password.";
ba46c7
+                            err = 1;
ba46c7
+                        }
ba46c7
+                    }
ba46c7
+                    if(strcasecmp(server->remote_bind_method, DNA_METHOD_SSL) == 0){
ba46c7
+                        /* requires a bind DN */
ba46c7
+                        if(strcasecmp(server->remote_conn_prot, DNA_PROT_SSL) != 0 &&
ba46c7
+                           strcasecmp(server->remote_conn_prot, DNA_PROT_TLS) != 0 )
ba46c7
+                        {
ba46c7
+                            reason = "bind method (SSL) requires either SSL or TLS connection "
ba46c7
+                                     "protocol.";
ba46c7
+                            err = 1;
ba46c7
+                        }
ba46c7
+                    }
ba46c7
+                    if(err){
ba46c7
+                        slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
ba46c7
+                                        "dna_get_shared_servers: skipping invalid "
ba46c7
+                                        "shared config entry (%s). Reason: %s\n",
ba46c7
+                                        slapi_entry_get_dn(entries[i]), reason);
ba46c7
+                        dna_free_shared_server(&server);
ba46c7
+                        continue;
ba46c7
+                    }
ba46c7
+                    /* everything is ok */
ba46c7
+                    server->remote_defined = 1;
ba46c7
+                }
ba46c7
 
ba46c7
                 /* add a server entry to the list */
ba46c7
                 if (*servers == NULL) {
ba46c7
@@ -2513,7 +2637,8 @@ static int dna_get_replica_bind_creds(char *range_dn, struct dnaServer *server,
ba46c7
             slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
ba46c7
                             "dna_get_replica_bind_creds: Failed to fetch replica "
ba46c7
                             "bind credentials for range %s, server %s, port %u [error %d]\n",
ba46c7
-                            range_dn, server->host, server->port, ret);
ba46c7
+                            range_dn, server->host,
ba46c7
+                            server->port ? server->port : server->secureport, ret);
ba46c7
             goto bail;
ba46c7
         }
ba46c7
 
ba46c7
@@ -2521,10 +2646,18 @@ static int dna_get_replica_bind_creds(char *range_dn, struct dnaServer *server,
ba46c7
                          &entries);
ba46c7
 
ba46c7
         if (NULL == entries || NULL == entries[0]) {
ba46c7
-            slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
ba46c7
+            if(server->remote_defined){
ba46c7
+                /*
ba46c7
+                 * Ok there are no replication agreements for this shared server, but we
ba46c7
+                 * do have custom defined authentication settings we can use.
ba46c7
+                 */
ba46c7
+                ret = dna_get_remote_config_info(server, bind_dn, bind_passwd, bind_method, is_ssl, port);
ba46c7
+                goto bail;
ba46c7
+            }
ba46c7
+            slapi_log_error(SLAPI_LOG_PLUGIN, DNA_PLUGIN_SUBSYSTEM,
ba46c7
                             "dna_get_replica_bind_creds: Failed to fetch replication "
ba46c7
                             "agreement for range %s, server %s, port %u\n", range_dn,
ba46c7
-                            server->host, server->port);
ba46c7
+                            server->host, server->port ? server->port : server->secureport);
ba46c7
             ret = LDAP_OPERATIONS_ERROR;
ba46c7
             goto bail;
ba46c7
         }
ba46c7
@@ -2603,6 +2736,92 @@ bail:
ba46c7
     return ret;
ba46c7
 }
ba46c7
 
ba46c7
+static int
ba46c7
+dna_get_remote_config_info( struct dnaServer *server, char **bind_dn, char **bind_passwd,
ba46c7
+                            char **bind_method, int *is_ssl, int *port)
ba46c7
+{
ba46c7
+    int rc = 0;
ba46c7
+
ba46c7
+    /* populate the bind info */
ba46c7
+    slapi_ch_free_string(bind_dn);
ba46c7
+    slapi_ch_free_string(bind_method);
ba46c7
+    *bind_dn = slapi_ch_strdup(server->remote_binddn);
ba46c7
+    *bind_method = slapi_ch_strdup(server->remote_bind_method);
ba46c7
+    /* fix up the bind method */
ba46c7
+    if ((NULL == *bind_method) || (strcasecmp(*bind_method, DNA_METHOD_SIMPLE) == 0)) {
ba46c7
+        slapi_ch_free_string(bind_method);
ba46c7
+        *bind_method = slapi_ch_strdup(LDAP_SASL_SIMPLE);
ba46c7
+    } else if (strcasecmp(*bind_method, "SSLCLIENTAUTH") == 0) {
ba46c7
+        slapi_ch_free_string(bind_method);
ba46c7
+        *bind_method = slapi_ch_strdup(LDAP_SASL_EXTERNAL);
ba46c7
+    } else if (strcasecmp(*bind_method, DNA_METHOD_GSSAPI) == 0) {
ba46c7
+        slapi_ch_free_string(bind_method);
ba46c7
+        *bind_method = slapi_ch_strdup("GSSAPI");
ba46c7
+    } else if (strcasecmp(*bind_method, DNA_METHOD_DIGESTMD5) == 0) {
ba46c7
+        slapi_ch_free_string(bind_method);
ba46c7
+        *bind_method = slapi_ch_strdup("DIGEST-MD5");
ba46c7
+    } else { /* some other weird value */
ba46c7
+        ; /* just use it directly */
ba46c7
+    }
ba46c7
+
ba46c7
+    if(server->remote_conn_prot && strcasecmp(server->remote_conn_prot, DNA_PROT_SSL) == 0){
ba46c7
+        *is_ssl = 1;
ba46c7
+    } else if(server->remote_conn_prot && strcasecmp(server->remote_conn_prot, DNA_PROT_TLS) == 0){
ba46c7
+        *is_ssl = 2;
ba46c7
+    } else {
ba46c7
+        *is_ssl = 0;
ba46c7
+    }
ba46c7
+    if(*is_ssl == 1){ /* SSL(covers TLS over ssl) */
ba46c7
+        if (server->secureport){
ba46c7
+            *port = server->secureport;
ba46c7
+        } else {
ba46c7
+            slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
ba46c7
+                    "dna_get_remote_config_info: Using SSL protocol, but the secure "
ba46c7
+                    "port is not defined.\n");
ba46c7
+            return -1;
ba46c7
+        }
ba46c7
+    } else { /* LDAP/TLS(non secure port) */
ba46c7
+        if(server->port){
ba46c7
+            *port = server->port;
ba46c7
+        } else {
ba46c7
+            slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
ba46c7
+                    "dna_get_remote_config_info: Using %s protocol, but the non-secure "
ba46c7
+                    "port is not defined.\n", server->remote_conn_prot);
ba46c7
+            return -1;
ba46c7
+        }
ba46c7
+    }
ba46c7
+
ba46c7
+    /* Decode the password */
ba46c7
+    if (server->remote_bindpw) {
ba46c7
+        char *bind_cred = slapi_ch_strdup(server->remote_bindpw);
ba46c7
+        int pw_ret = 0;
ba46c7
+
ba46c7
+        slapi_ch_free_string(bind_passwd);
ba46c7
+        pw_ret = pw_rever_decode(bind_cred, bind_passwd, DNA_REPL_CREDS);
ba46c7
+
ba46c7
+        if (pw_ret == -1) {
ba46c7
+            slapi_log_error(SLAPI_LOG_FATAL, DNA_PLUGIN_SUBSYSTEM,
ba46c7
+                    "dna_get_remote_config_info: Failed to decode "
ba46c7
+                    "replica bind credentials for server %s, "
ba46c7
+                    "port %u\n", server->host,
ba46c7
+                    server->port ? server->port : server->secureport);
ba46c7
+            rc = -1;
ba46c7
+        } else if (pw_ret != 0) {
ba46c7
+            /*
ba46c7
+             * The password was already in clear text, so pw_rever_decode
ba46c7
+             * simply set bind_passwd to bind_cred.  Set bind_cred to NULL
ba46c7
+             * to prevent a double free.  The memory is now owned by
ba46c7
+             * bind_passwd, which is the callers responsibility to free.
ba46c7
+             */
ba46c7
+            bind_cred = NULL;
ba46c7
+        }
ba46c7
+        slapi_ch_free_string(&bind_cred);
ba46c7
+    }
ba46c7
+
ba46c7
+    return rc;
ba46c7
+}
ba46c7
+
ba46c7
+
ba46c7
 /*
ba46c7
  * dna_list_contains_type()
ba46c7
  *
ba46c7
@@ -3339,7 +3558,7 @@ dna_pre_op(Slapi_PBlock * pb, int modtype)
ba46c7
          * here at the pre-op stage.  Applying the config
ba46c7
          * needs to be done at the post-op stage. */
ba46c7
 
ba46c7
-        if (dna_parse_config_entry(test_e, 0) != DNA_SUCCESS) {
ba46c7
+        if (dna_parse_config_entry(pb, test_e, 0) != DNA_SUCCESS) {
ba46c7
             /* Refuse the operation if config parsing failed. */
ba46c7
             ret = LDAP_UNWILLING_TO_PERFORM;
ba46c7
             if (LDAP_CHANGETYPE_ADD == modtype) {
ba46c7
@@ -3711,7 +3930,7 @@ static int dna_config_check_post_op(Slapi_PBlock * pb)
ba46c7
     if (!slapi_op_internal(pb)) { /* If internal, no need to check. */
ba46c7
         if ((dn = dna_get_dn(pb))) {
ba46c7
             if (dna_dn_is_config(dn)) {
ba46c7
-                dna_load_plugin_config(0);
ba46c7
+                dna_load_plugin_config(pb, 0);
ba46c7
             }
ba46c7
         }
ba46c7
     }
ba46c7
-- 
ba46c7
1.8.1.4
ba46c7