session FEATURE locking of the new server option structures
diff --git a/src/session_p.h b/src/session_p.h
index 1e89216..0a146b9 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -142,7 +142,7 @@
         pthread_mutex_t endpt_lock;
     } *endpts;
     uint16_t endpt_count;
-    /* WRITE - working with binds/endpoints, READ - modifying a specific bind/endpoint, holding that endpt_lock too */
+    /* WRITE - working with binds/endpoints, READ - reading/modifying a specific bind/endpoint, holding that endpt_lock too */
     pthread_rwlock_t endpt_array_lock;
 
     uint32_t new_session_id;
@@ -349,16 +349,11 @@
  */
 int nc_server_del_endpt(const char *name, NC_TRANSPORT_IMPL ti);
 
-/**
- * @brief Find an endpoint.
- *
- * Caller must hold endpt_array_lock for reading.
- *
- * @param[in] name Endpoint name.
- * @param[in] ti Endpoind transport.
- * @return Endpoint, NULL on error.
- */
-struct nc_endpt *nc_server_get_endpt(const char *name, NC_TRANSPORT_IMPL ti);
+/* TODO */
+struct nc_endpt *nc_server_endpt_lock(const char *name, NC_TRANSPORT_IMPL ti);
+
+/* TODO */
+void nc_server_endpt_unlock(struct nc_endpt *endpt);
 
 /* TODO */
 int nc_client_ch_add_bind_listen(const char *address, uint16_t port, NC_TRANSPORT_IMPL ti);
@@ -412,7 +407,7 @@
 int nc_ssh_pollin(struct nc_session *session, int *timeout);
 
 /* TODO */
-void nc_server_ssh_opts_clear(struct nc_server_ssh_opts *opts);
+void nc_server_ssh_clear_opts(struct nc_server_ssh_opts *opts);
 
 #endif /* ENABLE_SSH */
 
@@ -433,7 +428,7 @@
 int nc_accept_tls_session(struct nc_session *session, int sock, int timeout);
 
 /* TODO */
-void nc_server_tls_opts_clear(struct nc_server_tls_opts *opts);
+void nc_server_tls_clear_opts(struct nc_server_tls_opts *opts);
 
 #endif /* ENABLE_TLS */
 
diff --git a/src/session_server.c b/src/session_server.c
index d1d643f..568b5a8 100644
--- a/src/session_server.c
+++ b/src/session_server.c
@@ -39,21 +39,50 @@
 struct nc_server_opts server_opts = {
     .endpt_array_lock = PTHREAD_RWLOCK_INITIALIZER
 };
+
 extern struct nc_server_ssh_opts ssh_ch_opts;
+extern pthread_mutex_t ssh_ch_opts_lock;
+
 extern struct nc_server_tls_opts tls_ch_opts;
+extern pthread_mutex_t tls_ch_opts_lock;
 
 struct nc_endpt *
-nc_server_get_endpt(const char *name, NC_TRANSPORT_IMPL ti)
+nc_server_endpt_lock(const char *name, NC_TRANSPORT_IMPL ti)
 {
     uint16_t i;
+    struct nc_endpt *endpt = NULL;
+
+    /* READ LOCK */
+    pthread_rwlock_rdlock(&server_opts.endpt_array_lock);
 
     for (i = 0; i < server_opts.endpt_count; ++i) {
         if ((server_opts.binds[i].ti == ti) && !strcmp(server_opts.endpts[i].name, name)) {
-            return &server_opts.endpts[i];
+            endpt = &server_opts.endpts[i];
+            break;
         }
     }
 
-    return NULL;
+    if (!endpt) {
+        ERR("Endpoint \"%s\" was not found.", name);
+        /* READ UNLOCK */
+        pthread_rwlock_unlock(&server_opts.endpt_array_lock);
+        return NULL;
+    }
+
+    /* ENDPT LOCK */
+    pthread_mutex_lock(&endpt->endpt_lock);
+
+    return endpt;
+}
+
+void
+nc_server_endpt_unlock(struct nc_endpt *endpt)
+{
+    /* ENDPT UNLOCK */
+    pthread_mutex_unlock(&endpt->endpt_lock);
+
+    /* READ UNLOCK */
+    pthread_rwlock_rdlock(&server_opts.endpt_array_lock);
 }
 
 API void
@@ -879,12 +908,12 @@
             switch (server_opts.binds[i].ti) {
 #ifdef ENABLE_SSH
             case NC_TI_LIBSSH:
-                nc_server_ssh_opts_clear(server_opts.endpts[i].ti_opts);
+                nc_server_ssh_clear_opts(server_opts.endpts[i].ti_opts);
                 break;
 #endif
 #ifdef ENABLE_TLS
             case NC_TI_OPENSSL:
-                nc_server_tls_opts_clear(server_opts.endpts[i].ti_opts);
+                nc_server_tls_clear_opts(server_opts.endpts[i].ti_opts);
                 break;
 #endif
             default:
@@ -915,12 +944,12 @@
                 switch (server_opts.binds[i].ti) {
 #ifdef ENABLE_SSH
                 case NC_TI_LIBSSH:
-                    nc_server_ssh_opts_clear(server_opts.endpts[i].ti_opts);
+                    nc_server_ssh_clear_opts(server_opts.endpts[i].ti_opts);
                     break;
 #endif
 #ifdef ENABLE_TLS
                 case NC_TI_OPENSSL:
-                    nc_server_tls_opts_clear(server_opts.endpts[i].ti_opts);
+                    nc_server_tls_clear_opts(server_opts.endpts[i].ti_opts);
                     break;
 #endif
                 default:
@@ -961,18 +990,21 @@
         return -1;
     }
 
-    /* WRITE LOCK */
-    pthread_rwlock_wrlock(&server_opts.endpt_array_lock);
+    /* READ LOCK */
+    pthread_rwlock_rdlock(&server_opts.endpt_array_lock);
 
     ret = nc_sock_accept_binds(server_opts.binds, server_opts.endpt_count, timeout, &host, &port, &idx);
 
     if (ret < 0) {
-        /* WRITE UNLOCK */
+        /* READ UNLOCK */
         pthread_rwlock_unlock(&server_opts.endpt_array_lock);
         return ret;
     }
     sock = ret;
 
+    /* ENDPT LOCK */
+    pthread_mutex_lock(&server_opts.endpts[idx].endpt_lock);
+
     *session = calloc(1, sizeof **session);
     if (!(*session)) {
         ERRMEM;
@@ -1020,7 +1052,10 @@
         goto fail;
     }
 
-    /* WRITE UNLOCK */
+    /* ENDPT UNLOCK */
+    pthread_mutex_lock(&server_opts.endpts[idx].endpt_lock);
+
+    /* READ UNLOCK */
     pthread_rwlock_unlock(&server_opts.endpt_array_lock);
 
     /* assign new SID atomically */
@@ -1041,6 +1076,8 @@
     return 1;
 
 fail:
+    /* ENDPT UNLOCK */
+    pthread_mutex_lock(&server_opts.endpts[idx].endpt_lock);
     /* WRITE UNLOCK */
     pthread_rwlock_unlock(&server_opts.endpt_array_lock);
 
@@ -1091,14 +1128,30 @@
 
     /* sock gets assigned to session or closed */
     if (ti == NC_TI_LIBSSH) {
+        /* OPTS LOCK */
+        pthread_mutex_lock(&ssh_ch_opts_lock);
+
         (*session)->ti_opts = &ssh_ch_opts;
         ret = nc_accept_ssh_session(*session, sock, timeout);
+        (*session)->ti_opts = NULL;
+
+        /* OPTS UNLOCK */
+        pthread_mutex_unlock(&ssh_ch_opts_lock);
+
         if (ret < 1) {
             goto fail;
         }
     } else if (ti == NC_TI_OPENSSL) {
+        /* OPTS LOCK */
+        pthread_mutex_lock(&tls_ch_opts_lock);
+
         (*session)->ti_opts = &tls_ch_opts;
         ret = nc_accept_tls_session(*session, sock, timeout);
+        (*session)->ti_opts = NULL;
+
+        /* OPTS UNLOCK */
+        pthread_mutex_unlock(&tls_ch_opts_lock);
+
         if (ret < 1) {
             goto fail;
         }
diff --git a/src/session_server.h b/src/session_server.h
index 14009c2..45cdcda 100644
--- a/src/session_server.h
+++ b/src/session_server.h
@@ -321,7 +321,7 @@
 /**
  * @brief Free all the various SSH server options (excluding Call Home).
  */
-void nc_server_ssh_opts_free(void);
+void nc_server_ssh_destroy_opts(void);
 
 /*
  * Call Home
@@ -401,7 +401,7 @@
 int nc_server_ssh_ch_del_authkey(const char *pubkey_path, const char *username);
 
 /* TODO */
-void nc_server_ssh_ch_opts_clear(void);
+void nc_server_ssh_ch_clear_opts(void);
 
 #endif /* ENABLE_SSH */
 
@@ -497,7 +497,7 @@
  * @brief Destroy and clean all the set certificates and private keys. CRLs and
  * CTN entries are not affected.
  */
-void nc_server_tls_endpt_destroy_certs(const char *endpt_name);
+void nc_server_tls_endpt_clear_certs(const char *endpt_name);
 
 /**
  * @brief Set Certificate Revocation List locations. There can only be one file
@@ -514,7 +514,7 @@
  * @brief Destroy and clean CRLs. Certificates, priavte keys, and CTN entries are
  * not affected.
  */
-void nc_server_tls_endpt_destroy_crls(const char *endpt_name);
+void nc_server_tls_endpt_clear_crls(const char *endpt_name);
 
 /**
  * @brief Add a Cert-to-name entry.
@@ -625,7 +625,7 @@
  * @brief Destroy and clean all the set Call Home certificates and private keys.
  * CRLs and CTN entries are not affected.
  */
-void nc_server_tls_ch_destroy_certs(void);
+void nc_server_tls_ch_clear_certs(void);
 
 /**
  * @brief Set Call Home Certificate Revocation List locations. There can only be
@@ -642,7 +642,7 @@
  * @brief Destroy and clean Call Home CRLs. Call Home certificates, private keys,
  * and CTN entries are not affected.
  */
-void nc_server_tls_ch_destroy_crls(void);
+void nc_server_tls_ch_clear_crls(void);
 
 /**
  * @brief Add a Call Home Cert-to-name entry.
@@ -667,7 +667,7 @@
 int nc_server_tls_ch_del_ctn(int64_t id, const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type, const char *name);
 
 /* TODO */
-void nc_server_tls_ch_opts_clear(void);
+void nc_server_tls_ch_clear_opts(void);
 
 #endif /* ENABLE_TLS */
 
diff --git a/src/session_server_ssh.c b/src/session_server_ssh.c
index 31838e3..bbe0b98 100644
--- a/src/session_server_ssh.c
+++ b/src/session_server_ssh.c
@@ -38,6 +38,7 @@
     .auth_attempts = 3,
     .auth_timeout = 10
 };
+pthread_mutex_t ssh_ch_opts_lock = PTHREAD_MUTEX_INITIALIZER;
 extern struct nc_server_opts server_opts;
 
 API int
@@ -84,21 +85,31 @@
 API int
 nc_server_ssh_endpt_set_hostkey(const char *endpt_name, const char *privkey_path)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_LIBSSH);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_LIBSSH);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_ssh_set_hostkey(privkey_path, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_ssh_set_hostkey(privkey_path, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_ssh_ch_set_hostkey(const char *privkey_path)
 {
-    return nc_server_ssh_set_hostkey(privkey_path, &ssh_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&ssh_ch_opts_lock);
+    ret = nc_server_ssh_set_hostkey(privkey_path, &ssh_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&ssh_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -128,21 +139,31 @@
 API int
 nc_server_ssh_endpt_set_banner(const char *endpt_name, const char *banner)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_LIBSSH);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_LIBSSH);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_ssh_set_banner(banner, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_ssh_set_banner(banner, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_ssh_ch_set_banner(const char *banner)
 {
-    return nc_server_ssh_set_banner(banner, &ssh_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&ssh_ch_opts_lock);
+    ret = nc_server_ssh_set_banner(banner, &ssh_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&ssh_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -161,21 +182,31 @@
 API int
 nc_server_ssh_endpt_set_auth_methods(const char *endpt_name, int auth_methods)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_LIBSSH);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_LIBSSH);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_ssh_set_auth_methods(auth_methods, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_ssh_set_auth_methods(auth_methods, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_ssh_ch_set_auth_methods(int auth_methods)
 {
-    return nc_server_ssh_set_auth_methods(auth_methods, &ssh_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&ssh_ch_opts_lock);
+    ret = nc_server_ssh_set_auth_methods(auth_methods, &ssh_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&ssh_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -193,21 +224,31 @@
 API int
 nc_server_ssh_endpt_set_auth_attempts(const char *endpt_name, uint16_t auth_attempts)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_LIBSSH);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_LIBSSH);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_ssh_set_auth_attempts(auth_attempts, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_ssh_set_auth_attempts(auth_attempts, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_ssh_set_ch_auth_attempts(uint16_t auth_attempts)
 {
-    return nc_server_ssh_set_auth_attempts(auth_attempts, &ssh_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&ssh_ch_opts_lock);
+    ret = nc_server_ssh_set_auth_attempts(auth_attempts, &ssh_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&ssh_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -225,21 +266,31 @@
 API int
 nc_server_ssh_endpt_set_auth_timeout(const char *endpt_name, uint16_t auth_timeout)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_LIBSSH);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_LIBSSH);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_ssh_set_auth_timeout(auth_timeout, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_ssh_set_auth_timeout(auth_timeout, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_ssh_ch_set_auth_timeout(uint16_t auth_timeout)
 {
-    return nc_server_ssh_set_auth_timeout(auth_timeout, &ssh_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&ssh_ch_opts_lock);
+    ret = nc_server_ssh_set_auth_timeout(auth_timeout, &ssh_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&ssh_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -264,21 +315,31 @@
 API int
 nc_server_ssh_endpt_add_authkey(const char *endpt_name, const char *pubkey_path, const char *username)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_LIBSSH);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_LIBSSH);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_ssh_add_authkey(pubkey_path, username, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_ssh_add_authkey(pubkey_path, username, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_ssh_ch_add_authkey(const char *pubkey_path, const char *username)
 {
-    return nc_server_ssh_add_authkey(pubkey_path, username, &ssh_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&ssh_ch_opts_lock);
+    ret = nc_server_ssh_add_authkey(pubkey_path, username, &ssh_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&ssh_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -322,25 +383,35 @@
 API int
 nc_server_ssh_endpt_del_authkey(const char *endpt_name, const char *pubkey_path, const char *username)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_LIBSSH);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_LIBSSH);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_ssh_del_authkey(pubkey_path, username, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_ssh_del_authkey(pubkey_path, username, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_ssh_ch_del_authkey(const char *pubkey_path, const char *username)
 {
-    return nc_server_ssh_del_authkey(pubkey_path, username, &ssh_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&ssh_ch_opts_lock);
+    ret = nc_server_ssh_del_authkey(pubkey_path, username, &ssh_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&ssh_ch_opts_lock);
+
+    return ret;
 }
 
 void
-nc_server_ssh_opts_clear(struct nc_server_ssh_opts *opts)
+nc_server_ssh_clear_opts(struct nc_server_ssh_opts *opts)
 {
     if (opts->sshbind) {
         ssh_bind_free(opts->sshbind);
@@ -351,9 +422,13 @@
 }
 
 API void
-nc_server_ssh_ch_opts_clear(void)
+nc_server_ssh_ch_clear_opts(void)
 {
-    nc_server_ssh_opts_clear(&ssh_ch_opts);
+    /* OPTS LOCK */
+    pthread_mutex_lock(&ssh_ch_opts_lock);
+    nc_server_ssh_clear_opts(&ssh_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&ssh_ch_opts_lock);
 }
 
 static char *
diff --git a/src/session_server_tls.c b/src/session_server_tls.c
index d40fcaa..6a045c9 100644
--- a/src/session_server_tls.c
+++ b/src/session_server_tls.c
@@ -34,6 +34,7 @@
 #include "session_server.h"
 
 struct nc_server_tls_opts tls_ch_opts;
+pthread_mutex_t tls_ch_opts_lock = PTHREAD_MUTEX_INITIALIZER;
 extern struct nc_server_opts server_opts;
 
 static pthread_key_t verify_key;
@@ -701,21 +702,31 @@
 API int
 nc_server_tls_endpt_set_cert(const char *endpt_name, const char *cert)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_set_cert(cert, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_set_cert(cert, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_set_cert(const char *cert)
 {
-    return nc_server_tls_set_cert(cert, &tls_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_set_cert(cert, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -749,21 +760,31 @@
 API int
 nc_server_tls_set_endpt_cert_path(const char *endpt_name, const char *cert_path)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_set_cert_path(cert_path, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_set_cert_path(cert_path, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_set_cert_path(const char *cert_path)
 {
-    return nc_server_tls_set_cert_path(cert_path, &tls_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_set_cert_path(cert_path, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -802,21 +823,31 @@
 API int
 nc_server_tls_endpt_set_key(const char *endpt_name, const char *privkey, int is_rsa)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_set_key(privkey, is_rsa, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_set_key(privkey, is_rsa, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_set_key(const char *privkey, int is_rsa)
 {
-    return nc_server_tls_set_key(privkey, is_rsa, &tls_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_set_key(privkey, is_rsa, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -850,21 +881,31 @@
 API int
 nc_server_tls_endpt_set_key_path(const char *endpt_name, const char *privkey_path)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_set_key_path(privkey_path, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_set_key_path(privkey_path, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_set_key_path(const char *privkey_path)
 {
-    return nc_server_tls_set_key_path(privkey_path, &tls_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_set_key_path(privkey_path, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -910,21 +951,31 @@
 API int
 nc_server_tls_endpt_add_trusted_cert(const char *endpt_name, const char *cert)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_add_trusted_cert(cert, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_add_trusted_cert(cert, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_add_trusted_cert(const char *cert)
 {
-    return nc_server_tls_add_trusted_cert(cert, &tls_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_add_trusted_cert(cert, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -972,21 +1023,31 @@
 API int
 nc_server_tls_endpt_add_trusted_cert_path(const char *endpt_name, const char *cert_path)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_add_trusted_cert_path(cert_path, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_add_trusted_cert_path(cert_path, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_add_trusted_cert_path(const char *cert_path)
 {
-    return nc_server_tls_add_trusted_cert_path(cert_path, &tls_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_add_trusted_cert_path(cert_path, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -1050,25 +1111,35 @@
 API int
 nc_server_tls_endpt_set_trusted_cacert_locations(const char *endpt_name, const char *cacert_file_path, const char *cacert_dir_path)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_set_trusted_cacert_locations(cacert_file_path, cacert_dir_path, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_set_trusted_cacert_locations(cacert_file_path, cacert_dir_path, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_set_trusted_cacert_locations(const char *cacert_file_path, const char *cacert_dir_path)
 {
-    return nc_server_tls_set_trusted_cacert_locations(cacert_file_path, cacert_dir_path, &tls_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_set_trusted_cacert_locations(cacert_file_path, cacert_dir_path, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 static void
-nc_server_tls_destroy_certs(struct nc_server_tls_opts *opts)
+nc_server_tls_clear_certs(struct nc_server_tls_opts *opts)
 {
     if (!opts->tls_ctx) {
         return;
@@ -1079,23 +1150,26 @@
 }
 
 API void
-nc_server_tls_endpt_destroy_certs(const char *endpt_name)
+nc_server_tls_endpt_clear_certs(const char *endpt_name)
 {
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return;
     }
-
-    nc_server_tls_destroy_certs(endpt->ti_opts);
+    nc_server_tls_clear_certs(endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 }
 
 API void
-nc_server_tls_ch_destroy_certs(void)
+nc_server_tls_ch_clear_certs(void)
 {
-    nc_server_tls_destroy_certs(&tls_ch_opts);
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    nc_server_tls_clear_certs(&tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
 }
 
 static int
@@ -1147,25 +1221,35 @@
 API int
 nc_server_tls_endpt_set_crl_locations(const char *endpt_name, const char *crl_file_path, const char *crl_dir_path)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_set_crl_locations(crl_file_path, crl_dir_path, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_set_crl_locations(crl_file_path, crl_dir_path, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_set_crl_locations(const char *crl_file_path, const char *crl_dir_path)
 {
-    return nc_server_tls_set_crl_locations(crl_file_path, crl_dir_path, &tls_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_set_crl_locations(crl_file_path, crl_dir_path, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 static void
-nc_server_tls_destroy_crls(struct nc_server_tls_opts *opts)
+nc_server_tls_clear_crls(struct nc_server_tls_opts *opts)
 {
     if (!opts->crl_store) {
         return;
@@ -1176,23 +1260,26 @@
 }
 
 API void
-nc_server_tls_endpt_destroy_crls(const char *endpt_name)
+nc_server_tls_endpt_clear_crls(const char *endpt_name)
 {
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return;
     }
-
-    nc_server_tls_destroy_crls(endpt->ti_opts);
+    nc_server_tls_clear_crls(endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 }
 
 API void
-nc_server_tls_ch_destroy_crls(void)
+nc_server_tls_ch_clear_crls(void)
 {
-    nc_server_tls_destroy_crls(&tls_ch_opts);
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    nc_server_tls_clear_crls(&tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
 }
 
 static int
@@ -1236,21 +1323,31 @@
 API int
 nc_server_tls_endpt_add_ctn(const char *endpt_name, uint32_t id, const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type, const char *name)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_add_ctn(id, fingerprint, map_type, name, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_add_ctn(id, fingerprint, map_type, name, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_add_ctn(uint32_t id, const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type, const char *name)
 {
-    return nc_server_tls_add_ctn(id, fingerprint, map_type, name, &tls_ch_opts);
+    int ret;
+
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_add_ctn(id, fingerprint, map_type, name, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 static int
@@ -1311,37 +1408,51 @@
 API int
 nc_server_tls_endpt_del_ctn(const char *endpt_name, int64_t id, const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type, const char *name)
 {
+    int ret;
     struct nc_endpt *endpt;
 
-    endpt = nc_server_get_endpt(endpt_name, NC_TI_OPENSSL);
+    endpt = nc_server_endpt_lock(endpt_name, NC_TI_OPENSSL);
     if (!endpt) {
-        ERR("Endpoint \"%s\" was not found.", endpt_name);
         return -1;
     }
+    ret = nc_server_tls_del_ctn(id, fingerprint, map_type, name, endpt->ti_opts);
+    nc_server_endpt_unlock(endpt);
 
-    return nc_server_tls_del_ctn(id, fingerprint, map_type, name, endpt->ti_opts);
+    return ret;
 }
 
 API int
 nc_server_tls_ch_del_ctn(int64_t id, const char *fingerprint, NC_TLS_CTN_MAPTYPE map_type, const char *name)
 {
-    return nc_server_tls_del_ctn(id, fingerprint, map_type, name, &tls_ch_opts);
-}
+    int ret;
 
-API void
-nc_server_tls_ch_opts_clear(void)
-{
-    nc_server_tls_opts_clear(&tls_ch_opts);
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    ret = nc_server_tls_del_ctn(id, fingerprint, map_type, name, &tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+
+    return ret;
 }
 
 void
-nc_server_tls_opts_clear(struct nc_server_tls_opts *opts)
+nc_server_tls_clear_opts(struct nc_server_tls_opts *opts)
 {
-    nc_server_tls_destroy_certs(opts);
-    nc_server_tls_destroy_crls(opts);
+    nc_server_tls_clear_certs(opts);
+    nc_server_tls_clear_crls(opts);
     nc_server_tls_del_ctn(-1, NULL, 0, NULL, opts);
 }
 
+API void
+nc_server_tls_ch_clear_opts(void)
+{
+    /* OPTS LOCK */
+    pthread_mutex_lock(&tls_ch_opts_lock);
+    nc_server_tls_clear_opts(&tls_ch_opts);
+    /* OPTS UNLOCK */
+    pthread_mutex_unlock(&tls_ch_opts_lock);
+}
+
 static void
 nc_tls_make_verify_key(void)
 {