#if defined(LIBMEMCACHED_WITH_SASL_SUPPORT) && LIBMEMCACHED_WITH_SASL_SUPPORT
+#if defined(HAVE_LIBSASL) && HAVE_LIBSASL
#include <sasl/sasl.h>
+#endif
+
#include <pthread.h>
void memcached_set_sasl_callbacks(memcached_st *ptr,
return MEMCACHED_SUCCESS;
}
+extern "C" {
+
static void sasl_shutdown_function()
{
sasl_done();
}
-static int sasl_startup_state= SASL_OK;
+static volatile int sasl_startup_state= SASL_OK;
+pthread_mutex_t sasl_startup_state_LOCK= PTHREAD_MUTEX_INITIALIZER;
static pthread_once_t sasl_startup_once= PTHREAD_ONCE_INIT;
static void sasl_startup_function(void)
{
}
}
+} // extern "C"
+
memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *server)
{
if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
}
/* SANITY CHECK: SASL can only be used with the binary protocol */
- if (server->root->flags.binary_protocol == false)
+ if (memcached_is_binary(server->root) == false)
{
- return MEMCACHED_PROTOCOL_ERROR;
+ return memcached_set_error(*server, MEMCACHED_INVALID_ARGUMENTS, MEMCACHED_AT,
+ memcached_literal_param("memcached_sasl_authenticate_connection() is not supported via the ASCII protocol"));
}
/* Try to get the supported mech from the server. Servers without SASL
return memcached_set_errno(*server, pthread_error, MEMCACHED_AT);
}
+ (void)pthread_mutex_lock(&sasl_startup_state_LOCK);
if (sasl_startup_state != SASL_OK)
{
const char *sasl_error_msg= sasl_errstring(sasl_startup_state, NULL, NULL);
return memcached_set_error(*server, MEMCACHED_AUTH_PROBLEM, MEMCACHED_AT,
memcached_string_make_from_cstr(sasl_error_msg));
}
+ (void)pthread_mutex_unlock(&sasl_startup_state_LOCK);
sasl_conn_t *conn;
int ret;
do {
/* send the packet */
- struct libmemcached_io_vector_st vector[]=
+ libmemcached_io_vector_st vector[]=
{
- { sizeof(request.bytes), request.bytes },
- { keylen, chosenmech },
- { len, data }
+ { request.bytes, sizeof(request.bytes) },
+ { chosenmech, keylen },
+ { data, len }
};
- if (memcached_io_writev(server, vector, 3, true) == -1)
+ if (memcached_io_writev(server, vector, 3, true) == false)
{
rc= MEMCACHED_WRITE_FAILURE;
break;
memcached_destroy_sasl_auth_data(ptr);
- sasl_callback_t *callbacks= (sasl_callback_t*)libmemcached_calloc(ptr, 4, sizeof(sasl_callback_t));
+ sasl_callback_t *callbacks= libmemcached_xcalloc(ptr, 4, sasl_callback_t);
size_t password_length= strlen(password);
size_t username_length= strlen(username);
char *name= (char *)libmemcached_malloc(ptr, username_length +1);
* into the list, but if we don't know the ID we don't know how to handle
* the context...
*/
- size_t total= 0;
+ ptrdiff_t total= 0;
while (source->sasl.callbacks[total].id != SASL_CB_LIST_END)
{
++total;
}
- sasl_callback_t *callbacks= (sasl_callback_t*)libmemcached_calloc(clone, total +1, sizeof(sasl_callback_t));
+ sasl_callback_t *callbacks= libmemcached_xcalloc(clone, total +1, sasl_callback_t);
if (callbacks == NULL)
{
return MEMCACHED_MEMORY_ALLOCATION_FAILURE;
memcpy(callbacks, source->sasl.callbacks, (total + 1) * sizeof(sasl_callback_t));
/* Now update the context... */
- for (size_t x= 0; x < total; ++x)
+ for (ptrdiff_t x= 0; x < total; ++x)
{
if (callbacks[x].id == SASL_CB_USER || callbacks[x].id == SASL_CB_AUTHNAME)
{
if (callbacks[x].context == NULL)
{
/* Failed to allocate memory, clean up previously allocated memory */
- for (size_t y= 0; y < x; ++y)
+ for (ptrdiff_t y= 0; y < x; ++y)
{
libmemcached_free(clone, clone->sasl.callbacks[y].context);
}
if (n == NULL)
{
/* Failed to allocate memory, clean up previously allocated memory */
- for (size_t y= 0; y < x; ++y)
+ for (ptrdiff_t y= 0; y < x; ++y)
{
libmemcached_free(clone, clone->sasl.callbacks[y].context);
}