Remove how use instance (keep API intact)
[m6w6/libmemcached] / libmemcached / sasl.cc
index f1de41eaec4fe30f86416da7714f625e169c0ba6..3d93b78686b880f7cc20b4376565191f5b783eab 100644 (file)
 
 #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,
@@ -62,7 +65,7 @@ sasl_callback_t *memcached_get_sasl_callbacks(memcached_st *ptr)
  * @param raddr remote address (out)
  * @return true on success false otherwise (errno contains more info)
  */
-static memcached_return_t resolve_names(memcached_server_st& server, char *laddr, size_t laddr_length, char *raddr, size_t raddr_length)
+static memcached_return_t resolve_names(memcached_instance_st& server, char *laddr, size_t laddr_length, char *raddr, size_t raddr_length)
 {
   char host[NI_MAXHOST];
   char port[NI_MAXSERV];
@@ -98,12 +101,15 @@ static memcached_return_t resolve_names(memcached_server_st& server, char *laddr
   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)
 {
@@ -115,7 +121,9 @@ static void sasl_startup_function(void)
   }
 }
 
-memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *server)
+} // extern "C"
+
+memcached_return_t memcached_sasl_authenticate_connection(memcached_instance_st *server)
 {
   if (LIBMEMCACHED_WITH_SASL_SUPPORT == 0)
   {
@@ -128,9 +136,10 @@ memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *s
   }
 
   /* 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
@@ -138,7 +147,9 @@ memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *s
    * as authenticated
  */
   protocol_binary_request_no_extras request= { };
-  request.message.header.request.magic= PROTOCOL_BINARY_REQ;
+
+  initialize_binary_request(ptr, request.message.header);
+
   request.message.header.request.opcode= PROTOCOL_BINARY_CMD_SASL_LIST_MECHS;
 
   if (memcached_io_write(server, request.bytes,
@@ -182,12 +193,14 @@ memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *s
     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;
@@ -222,14 +235,14 @@ memcached_return_t memcached_sasl_authenticate_connection(memcached_server_st *s
   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;
@@ -314,7 +327,7 @@ memcached_return_t memcached_set_sasl_auth_data(memcached_st *ptr,
 
   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);
@@ -416,7 +429,7 @@ memcached_return_t memcached_clone_sasl(memcached_st *clone, const  memcached_st
    * 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)
   {
@@ -434,7 +447,7 @@ memcached_return_t memcached_clone_sasl(memcached_st *clone, const  memcached_st
     ++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;
@@ -442,7 +455,7 @@ memcached_return_t memcached_clone_sasl(memcached_st *clone, const  memcached_st
   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)
     {
@@ -451,7 +464,7 @@ memcached_return_t memcached_clone_sasl(memcached_st *clone, const  memcached_st
       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);
         }
@@ -468,7 +481,7 @@ memcached_return_t memcached_clone_sasl(memcached_st *clone, const  memcached_st
       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);
         }