summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2005-02-24 21:45:44 +0000
committerNoriko Hosoi <nhosoi@redhat.com>2005-02-24 21:45:44 +0000
commit370d483a51167d5b9e7cf936a03f3bb42cae5cd4 (patch)
treed7a8ac1a13f94f82b349da141ba3b2f8fd606b15
parent537c8cb011005a99df7b26a9490dedb33c7b42db (diff)
downloadds-370d483a51167d5b9e7cf936a03f3bb42cae5cd4.tar.gz
ds-370d483a51167d5b9e7cf936a03f3bb42cae5cd4.tar.xz
ds-370d483a51167d5b9e7cf936a03f3bb42cae5cd4.zip
[bugzilla 149539] Use Cyrus SASL instead of our custom one
CYRUS_SASL is undef'ed both in saslbind.c and sasl_io.c, which should be defined once Cyrus sasl library is pushed to /s/b/c.
-rw-r--r--ldap/servers/slapd/sasl_io.c462
-rw-r--r--ldap/servers/slapd/saslbind.c347
2 files changed, 437 insertions, 372 deletions
diff --git a/ldap/servers/slapd/sasl_io.c b/ldap/servers/slapd/sasl_io.c
index 7345be35..bf250658 100644
--- a/ldap/servers/slapd/sasl_io.c
+++ b/ldap/servers/slapd/sasl_io.c
@@ -3,6 +3,8 @@
* All rights reserved.
* END COPYRIGHT BLOCK **/
+#undef CYRUS_SASL
+
#include "slap.h"
#include "slapi-plugin.h"
#include "fe.h"
@@ -26,173 +28,191 @@
*/
struct _sasl_io_private {
- struct lextiof_socket_private *real_handle;
- struct lber_x_ext_io_fns *real_iofns;
- char *decrypted_buffer;
- size_t decrypted_buffer_size;
- size_t decrypted_buffer_count;
- size_t decrypted_buffer_offset;
- char *encrypted_buffer;
- size_t encrypted_buffer_size;
- size_t encrypted_buffer_count;
- size_t encrypted_buffer_offset;
- Connection *conn;
+ struct lextiof_socket_private *real_handle;
+ struct lber_x_ext_io_fns *real_iofns;
+ char *decrypted_buffer;
+ size_t decrypted_buffer_size;
+ size_t decrypted_buffer_count;
+ size_t decrypted_buffer_offset;
+ char *encrypted_buffer;
+ size_t encrypted_buffer_size;
+ size_t encrypted_buffer_count;
+ size_t encrypted_buffer_offset;
+ Connection *conn;
};
int
sasl_io_enable(Connection *c)
{
- int ret = 0;
+ int ret = 0;
- LDAPDebug( LDAP_DEBUG_CONNS,
- "sasl_io_enable for connection %d\n", c->c_connid, 0, 0 );
- /* Flag that we should enable SASL I/O for the next read operation on this connection */
- c->c_enable_sasl_io = 1;
-
- return ret;
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "sasl_io_enable for connection %d\n", c->c_connid, 0, 0 );
+ /* Flag that we should enable SASL I/O for the next read operation on this connection */
+ c->c_enable_sasl_io = 1;
+
+ return ret;
}
static void
sasl_io_init_buffers(sasl_io_private *sp)
{
- sp->decrypted_buffer = slapi_ch_malloc(SASL_IO_BUFFER_SIZE);
- sp->decrypted_buffer_size = SASL_IO_BUFFER_SIZE;
- sp->encrypted_buffer = slapi_ch_malloc(SASL_IO_BUFFER_SIZE);
- sp->encrypted_buffer_size = SASL_IO_BUFFER_SIZE;
+ sp->decrypted_buffer = slapi_ch_malloc(SASL_IO_BUFFER_SIZE);
+ sp->decrypted_buffer_size = SASL_IO_BUFFER_SIZE;
+ sp->encrypted_buffer = slapi_ch_malloc(SASL_IO_BUFFER_SIZE);
+ sp->encrypted_buffer_size = SASL_IO_BUFFER_SIZE;
}
/* This function should be called under the connection mutex */
int
sasl_io_setup(Connection *c)
{
- int ret = 0;
- struct lber_x_ext_io_fns *func_pointers = NULL;
- sasl_io_private *sp = (sasl_io_private*) slapi_ch_calloc(1, sizeof(sasl_io_private));
+ int ret = 0;
+ struct lber_x_ext_io_fns *func_pointers = NULL;
+ sasl_io_private *sp = (sasl_io_private*) slapi_ch_calloc(1, sizeof(sasl_io_private));
- LDAPDebug( LDAP_DEBUG_CONNS,
- "sasl_io_setup for connection %d\n", c->c_connid, 0, 0 );
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "sasl_io_setup for connection %d\n", c->c_connid, 0, 0 );
/* Get the current functions and store them for later */
- ber_sockbuf_get_option( c->c_sb, LBER_SOCKBUF_OPT_EXT_IO_FNS, &func_pointers);
+ ber_sockbuf_get_option( c->c_sb, LBER_SOCKBUF_OPT_EXT_IO_FNS, &func_pointers);
sp->real_iofns = func_pointers;
func_pointers = NULL;
- /* Set up the private structure */
- sp->real_handle = (struct lextiof_socket_private*) c->c_prfd;
- sp->conn = c;
- /* Store the private structure in the connection */
- c->c_sasl_io_private = sp;
- /* Insert the sasl i/o functions into the ber layer */
- func_pointers = (struct lber_x_ext_io_fns *) slapi_ch_malloc(LBER_X_EXTIO_FNS_SIZE);
- func_pointers->lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
- func_pointers->lbextiofn_read = sasl_read_function;
- func_pointers->lbextiofn_write = sasl_write_function;
- func_pointers->lbextiofn_writev = NULL;
- func_pointers->lbextiofn_socket_arg = (struct lextiof_socket_private *) sp;
- ber_sockbuf_set_option( c->c_sb, LBER_SOCKBUF_OPT_EXT_IO_FNS, func_pointers);
- /* Setup the data buffers for the fast read path */
- sasl_io_init_buffers(sp);
- /* Reset the enable flag, so we don't process it again */
- c->c_enable_sasl_io = 0;
- /* Mark the connection as having SASL I/O */
- c->c_sasl_io = 1;
- return ret;
+ /* Set up the private structure */
+ sp->real_handle = (struct lextiof_socket_private*) c->c_prfd;
+ sp->conn = c;
+ /* Store the private structure in the connection */
+ c->c_sasl_io_private = sp;
+ /* Insert the sasl i/o functions into the ber layer */
+ func_pointers = (struct lber_x_ext_io_fns *) slapi_ch_malloc(LBER_X_EXTIO_FNS_SIZE);
+ func_pointers->lbextiofn_size = LBER_X_EXTIO_FNS_SIZE;
+ func_pointers->lbextiofn_read = sasl_read_function;
+ func_pointers->lbextiofn_write = sasl_write_function;
+ func_pointers->lbextiofn_writev = NULL;
+ func_pointers->lbextiofn_socket_arg = (struct lextiof_socket_private *) sp;
+ ber_sockbuf_set_option( c->c_sb, LBER_SOCKBUF_OPT_EXT_IO_FNS, func_pointers);
+ /* Setup the data buffers for the fast read path */
+ sasl_io_init_buffers(sp);
+ /* Reset the enable flag, so we don't process it again */
+ c->c_enable_sasl_io = 0;
+ /* Mark the connection as having SASL I/O */
+ c->c_sasl_io = 1;
+ return ret;
}
int
sasl_io_cleanup(Connection *c)
{
- int ret = 0;
- sasl_io_private *sp = c->c_sasl_io_private;
- if (sp) {
- LDAPDebug( LDAP_DEBUG_CONNS,
- "sasl_io_cleanup for connection %d\n", c->c_connid, 0, 0 );
- /* Free the buffers */
- slapi_ch_free((void**)&(sp->encrypted_buffer));
- slapi_ch_free((void**)&(sp->decrypted_buffer));
- /* Put the I/O functions back how they were */
- ber_sockbuf_set_option( c->c_sb, LBER_SOCKBUF_OPT_EXT_IO_FNS, sp->real_iofns);
- slapi_ch_free((void**)&sp);
- c->c_sasl_io_private = NULL;
- c->c_enable_sasl_io = 0;
- c->c_sasl_io = 0;
- }
- return ret;
+ int ret = 0;
+ sasl_io_private *sp = c->c_sasl_io_private;
+ if (sp) {
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "sasl_io_cleanup for connection %d\n", c->c_connid, 0, 0 );
+ /* Free the buffers */
+ slapi_ch_free((void**)&(sp->encrypted_buffer));
+ slapi_ch_free((void**)&(sp->decrypted_buffer));
+ /* Put the I/O functions back how they were */
+ ber_sockbuf_set_option( c->c_sb, LBER_SOCKBUF_OPT_EXT_IO_FNS, sp->real_iofns);
+ slapi_ch_free((void**)&sp);
+ c->c_sasl_io_private = NULL;
+ c->c_enable_sasl_io = 0;
+ c->c_sasl_io = 0;
+ }
+ return ret;
}
static void sasl_io_resize_encrypted_buffer(sasl_io_private *sp, size_t requested_size)
{
- if (requested_size > sp->encrypted_buffer_size) {
- sp->encrypted_buffer = slapi_ch_realloc(sp->encrypted_buffer, requested_size);
- sp->encrypted_buffer_size = requested_size;
- }
+ if (requested_size > sp->encrypted_buffer_size) {
+ sp->encrypted_buffer = slapi_ch_realloc(sp->encrypted_buffer, requested_size);
+ sp->encrypted_buffer_size = requested_size;
+ }
}
static void sasl_io_resize_decrypted_buffer(sasl_io_private *sp, size_t requested_size)
{
- if (requested_size > sp->decrypted_buffer_size) {
- sp->decrypted_buffer = slapi_ch_realloc(sp->decrypted_buffer, requested_size);
- sp->decrypted_buffer_size = requested_size;
- }
+ if (requested_size > sp->decrypted_buffer_size) {
+ sp->decrypted_buffer = slapi_ch_realloc(sp->decrypted_buffer, requested_size);
+ sp->decrypted_buffer_size = requested_size;
+ }
}
static int
sasl_io_reading_packet(sasl_io_private *sp)
{
- return (sp->encrypted_buffer_count > 0);
+ return (sp->encrypted_buffer_count > 0);
}
static int
sasl_io_finished_packet(sasl_io_private *sp)
{
- return (sp->encrypted_buffer_count && (sp->encrypted_buffer_offset == sp->encrypted_buffer_count) );
+ return (sp->encrypted_buffer_count && (sp->encrypted_buffer_offset == sp->encrypted_buffer_count) );
}
static int
sasl_io_start_packet(Connection *c, PRInt32 *err)
{
- int ret = 0;
- unsigned char buffer[4];
- size_t packet_length = 0;
-
- ret = PR_Recv(c->c_prfd,buffer,sizeof(buffer),0,PR_INTERVAL_NO_WAIT);
- if (ret < 0) {
- *err = PR_GetError();
- return -1;
- }
- if (ret != 0 && ret < sizeof(buffer)) {
- LDAPDebug( LDAP_DEBUG_ANY,
- "failed to read sasl packet length on connection %d\n", c->c_connid, 0, 0 );
- return -1;
-
- }
- if (ret == sizeof(buffer)) {
- /* Decode the length (could use ntohl here ??) */
- packet_length = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
- LDAPDebug( LDAP_DEBUG_CONNS,
- "read sasl packet length %ld on connection %d\n", packet_length, c->c_connid, 0 );
- sasl_io_resize_encrypted_buffer(c->c_sasl_io_private, packet_length);
- c->c_sasl_io_private->encrypted_buffer_count = packet_length;
- c->c_sasl_io_private->encrypted_buffer_offset = 0;
- }
- return 0;
+ int ret = 0;
+ unsigned char buffer[4];
+ size_t packet_length = 0;
+
+ ret = PR_Recv(c->c_prfd,buffer,sizeof(buffer),0,PR_INTERVAL_NO_WAIT);
+ if (ret < 0) {
+ *err = PR_GetError();
+ return -1;
+ }
+ if (ret != 0 && ret < sizeof(buffer)) {
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "failed to read sasl packet length on connection %d\n", c->c_connid, 0, 0 );
+ return -1;
+
+ }
+#ifdef CYRUS_SASL
+ if (ret == sizeof(buffer)) {
+ /* Decode the length (could use ntohl here ??) */
+ packet_length = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
+ /* add length itself (for Cyrus SASL library) */
+ packet_length += 4;
+
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "read sasl packet length %ld on connection %d\n", packet_length, c->c_connid, 0 );
+ sasl_io_resize_encrypted_buffer(c->c_sasl_io_private, packet_length);
+ /* Cyrus SASL implementation expects to have the length at the first
+ 4 bytes */
+ memcpy(c->c_sasl_io_private->encrypted_buffer, buffer, 4);
+ c->c_sasl_io_private->encrypted_buffer_count = packet_length;
+ c->c_sasl_io_private->encrypted_buffer_offset = 4;
+ }
+#else
+ if (ret == sizeof(buffer)) {
+ /* Decode the length (could use ntohl here ??) */
+ packet_length = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3];
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "read sasl packet length %ld on connection %d\n", packet_length, c->c_connid, 0 );
+ sasl_io_resize_encrypted_buffer(c->c_sasl_io_private, packet_length);
+ c->c_sasl_io_private->encrypted_buffer_count = packet_length;
+ c->c_sasl_io_private->encrypted_buffer_offset = 0;
+ }
+#endif
+ return 0;
}
static int
sasl_io_read_packet(Connection *c, PRInt32 *err)
{
- size_t ret = 0;
- sasl_io_private *sp = c->c_sasl_io_private;
- size_t bytes_remaining_to_read = sp->encrypted_buffer_count - sp->encrypted_buffer_offset;
+ size_t ret = 0;
+ sasl_io_private *sp = c->c_sasl_io_private;
+ size_t bytes_remaining_to_read = sp->encrypted_buffer_count - sp->encrypted_buffer_offset;
- ret = PR_Recv(c->c_prfd,sp->encrypted_buffer + sp->encrypted_buffer_offset,bytes_remaining_to_read,0,PR_INTERVAL_NO_WAIT);
- if (ret < 0) {
- *err = PR_GetError();
- return -1;
- }
- if (ret > 0) {
- sp->encrypted_buffer_offset += ret;
- }
- return ret;
+ ret = PR_Recv(c->c_prfd,sp->encrypted_buffer + sp->encrypted_buffer_offset,bytes_remaining_to_read,0,PR_INTERVAL_NO_WAIT);
+ if (ret < 0) {
+ *err = PR_GetError();
+ return -1;
+ }
+ if (ret > 0) {
+ sp->encrypted_buffer_offset += ret;
+ }
+ return ret;
}
/* Special recv function for the server connection code */
@@ -204,131 +224,131 @@ sasl_io_read_packet(Connection *c, PRInt32 *err)
int
sasl_recv_connection(Connection *c, char *buffer, size_t count,PRInt32 *err)
{
- int ret = 0;
- size_t bytes_in_buffer = 0;
- sasl_io_private *sp = c->c_sasl_io_private;
+ int ret = 0;
+ size_t bytes_in_buffer = 0;
+ sasl_io_private *sp = c->c_sasl_io_private;
- *err = 0;
- LDAPDebug( LDAP_DEBUG_CONNS,
- "sasl_recv_connection for connection %d\n", c->c_connid, 0, 0 );
- /* Do we have decrypted data buffered from 'before' ? */
- bytes_in_buffer = sp->decrypted_buffer_count - sp->decrypted_buffer_offset;
- if (0 == bytes_in_buffer) {
- /* If there wasn't buffered decrypted data, we need to get some... */
- if (!sasl_io_reading_packet(sp)) {
- /* First read the packet length and so on */
- ret = sasl_io_start_packet(c, err);
- if (0 != ret) {
- /* Most likely the i/o timed out */
- return ret;
- }
- }
- /* We now have the packet length
- * we now must read more data off the wire until we have the complete packet
- */
- ret = sasl_io_read_packet(c,err);
- if (0 == ret || -1 == ret) {
- return ret;
- }
- /* Are we there yet ? */
- if (sasl_io_finished_packet(sp)) {
- const char *output_buffer = NULL;
- unsigned int output_length = 0;
- LDAPDebug( LDAP_DEBUG_CONNS,
- "sasl_recv_connection finished reading packet for connection %d\n", c->c_connid, 0, 0 );
- /* Now decode it */
- ret = sasl_decode(c->c_sasl_conn,sp->encrypted_buffer,sp->encrypted_buffer_count,&output_buffer,&output_length);
- if (SASL_OK == ret) {
- LDAPDebug( LDAP_DEBUG_CONNS,
- "sasl_recv_connection decoded packet length %d for connection %d\n", output_length, c->c_connid, 0 );
- if (output_length) {
- sasl_io_resize_decrypted_buffer(sp,output_length);
- memcpy(sp->decrypted_buffer,output_buffer,output_length);
- sp->decrypted_buffer_count = output_length;
- sp->decrypted_buffer_offset = 0;
- sp->encrypted_buffer_offset = 0;
- sp->encrypted_buffer_count = 0;
- }
- } else {
- LDAPDebug( LDAP_DEBUG_ANY,
- "sasl_recv_connection failed to decode packet for connection %d\n", c->c_connid, 0, 0 );
- }
- }
- }
- /* Finally, return data from the buffer to the caller */
- {
- size_t bytes_to_return = sp->decrypted_buffer_count - sp->decrypted_buffer_offset;
- if (bytes_to_return > count) {
- bytes_to_return = count;
- }
- memcpy(buffer, sp->decrypted_buffer, bytes_to_return);
- if (bytes_in_buffer == bytes_to_return) {
- sp->decrypted_buffer_offset = 0;
- sp->decrypted_buffer_count = 0;
- } else {
- sp->decrypted_buffer_offset += bytes_to_return;
- }
- ret = bytes_to_return;
- }
- return ret;
+ *err = 0;
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "sasl_recv_connection for connection %d\n", c->c_connid, 0, 0 );
+ /* Do we have decrypted data buffered from 'before' ? */
+ bytes_in_buffer = sp->decrypted_buffer_count - sp->decrypted_buffer_offset;
+ if (0 == bytes_in_buffer) {
+ /* If there wasn't buffered decrypted data, we need to get some... */
+ if (!sasl_io_reading_packet(sp)) {
+ /* First read the packet length and so on */
+ ret = sasl_io_start_packet(c, err);
+ if (0 != ret) {
+ /* Most likely the i/o timed out */
+ return ret;
+ }
+ }
+ /* We now have the packet length
+ * we now must read more data off the wire until we have the complete packet
+ */
+ ret = sasl_io_read_packet(c,err);
+ if (0 == ret || -1 == ret) {
+ return ret;
+ }
+ /* Are we there yet ? */
+ if (sasl_io_finished_packet(sp)) {
+ const char *output_buffer = NULL;
+ unsigned int output_length = 0;
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "sasl_recv_connection finished reading packet for connection %d\n", c->c_connid, 0, 0 );
+ /* Now decode it */
+ ret = sasl_decode(c->c_sasl_conn,sp->encrypted_buffer,sp->encrypted_buffer_count,&output_buffer,&output_length);
+ if (SASL_OK == ret) {
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "sasl_recv_connection decoded packet length %d for connection %d\n", output_length, c->c_connid, 0 );
+ if (output_length) {
+ sasl_io_resize_decrypted_buffer(sp,output_length);
+ memcpy(sp->decrypted_buffer,output_buffer,output_length);
+ sp->decrypted_buffer_count = output_length;
+ sp->decrypted_buffer_offset = 0;
+ sp->encrypted_buffer_offset = 0;
+ sp->encrypted_buffer_count = 0;
+ }
+ } else {
+ LDAPDebug( LDAP_DEBUG_ANY,
+ "sasl_recv_connection failed to decode packet for connection %d\n", c->c_connid, 0, 0 );
+ }
+ }
+ }
+ /* Finally, return data from the buffer to the caller */
+ {
+ size_t bytes_to_return = sp->decrypted_buffer_count - sp->decrypted_buffer_offset;
+ if (bytes_to_return > count) {
+ bytes_to_return = count;
+ }
+ memcpy(buffer, sp->decrypted_buffer, bytes_to_return);
+ if (bytes_in_buffer == bytes_to_return) {
+ sp->decrypted_buffer_offset = 0;
+ sp->decrypted_buffer_count = 0;
+ } else {
+ sp->decrypted_buffer_offset += bytes_to_return;
+ }
+ ret = bytes_to_return;
+ }
+ return ret;
}
int
sasl_read_function(int ignore, void *buffer, int count, struct lextiof_socket_private *handle )
{
- int ret = 0;
- sasl_io_private *sp = (sasl_io_private*) handle;
+ int ret = 0;
+ sasl_io_private *sp = (sasl_io_private*) handle;
- /* First we look to see if we have buffered data that we can return to the caller */
- if ( (NULL == sp->decrypted_buffer) || ((sp->decrypted_buffer_count - sp->decrypted_buffer_offset) <= 0) ) {
- /* If we didn't have buffered data, we need to perform I/O and decrypt */
- PRUint32 buffer_length = 0;
- /* Read the packet length */
- ret = read_function(0, &buffer_length, sizeof(buffer_length), sp->real_handle);
- if (ret) {
- }
- /* Read the payload */
- ret = read_function(0, sp->encrypted_buffer, buffer_length, sp->real_handle);
- if (ret) {
- }
- /* Now we can call sasl to decrypt */
- /* ret = sasl_decode(sp->conn->c_sasl_conn,sp->encrypted_buffer, buffer_length, sp->decrypted_buffer, &sp->decrypted_buffer_count ); */
- }
- /* If things went well, copy the payload for the caller */
- if ( 0 == ret ) {
-/* size_t real_count = 0;
+ /* First we look to see if we have buffered data that we can return to the caller */
+ if ( (NULL == sp->decrypted_buffer) || ((sp->decrypted_buffer_count - sp->decrypted_buffer_offset) <= 0) ) {
+ /* If we didn't have buffered data, we need to perform I/O and decrypt */
+ PRUint32 buffer_length = 0;
+ /* Read the packet length */
+ ret = read_function(0, &buffer_length, sizeof(buffer_length), sp->real_handle);
+ if (ret) {
+ }
+ /* Read the payload */
+ ret = read_function(0, sp->encrypted_buffer, buffer_length, sp->real_handle);
+ if (ret) {
+ }
+ /* Now we can call sasl to decrypt */
+ /* ret = sasl_decode(sp->conn->c_sasl_conn,sp->encrypted_buffer, buffer_length, sp->decrypted_buffer, &sp->decrypted_buffer_count ); */
+ }
+ /* If things went well, copy the payload for the caller */
+ if ( 0 == ret ) {
+/* size_t real_count = 0;
- if (count >= (sp->buffer_count - sp->buffer_offset) ) {
- real_count = count;
- } else {
- real_count = (sp->buffer_count - sp->buffer_offset);
- }
- memcpy(buffer, sp->buffer, real_count);
- sp->buffer_offset += real_count; */
- }
-
- return ret;
+ if (count >= (sp->buffer_count - sp->buffer_offset) ) {
+ real_count = count;
+ } else {
+ real_count = (sp->buffer_count - sp->buffer_offset);
+ }
+ memcpy(buffer, sp->buffer, real_count);
+ sp->buffer_offset += real_count; */
+ }
+
+ return ret;
}
int
sasl_write_function(int ignore, const void *buffer, int count, struct lextiof_socket_private *handle)
{
- int ret = 0;
- sasl_io_private *sp = (sasl_io_private*) handle;
- const char *crypt_buffer = NULL;
- unsigned crypt_buffer_size = 0;
+ int ret = 0;
+ sasl_io_private *sp = (sasl_io_private*) handle;
+ const char *crypt_buffer = NULL;
+ unsigned crypt_buffer_size = 0;
- LDAPDebug( LDAP_DEBUG_CONNS,
- "sasl_write_function writing %d bytes\n", count, 0, 0 );
- /* Get SASL to encrypt the buffer */
- ret = sasl_encode(sp->conn->c_sasl_conn, buffer, count, &crypt_buffer, &crypt_buffer_size);
- LDAPDebug( LDAP_DEBUG_CONNS,
- "sasl_write_function encoded as %d bytes\n", crypt_buffer_size, 0, 0 );
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "sasl_write_function writing %d bytes\n", count, 0, 0 );
+ /* Get SASL to encrypt the buffer */
+ ret = sasl_encode(sp->conn->c_sasl_conn, buffer, count, &crypt_buffer, &crypt_buffer_size);
+ LDAPDebug( LDAP_DEBUG_CONNS,
+ "sasl_write_function encoded as %d bytes\n", crypt_buffer_size, 0, 0 );
ret = write_function(0, crypt_buffer, crypt_buffer_size, sp->real_handle);
if (ret) {
- }
-
- return ret;
+ }
+
+ return ret;
}
-
+
diff --git a/ldap/servers/slapd/saslbind.c b/ldap/servers/slapd/saslbind.c
index b7a2464e..3e86fece 100644
--- a/ldap/servers/slapd/saslbind.c
+++ b/ldap/servers/slapd/saslbind.c
@@ -4,11 +4,15 @@
* All rights reserved.
* END COPYRIGHT BLOCK **/
+#undef CYRUS_SASL
+
#include <slap.h>
#include <fe.h>
#include <sasl.h>
#include <saslplug.h>
+#ifndef CYRUS_SASL
#include <saslmod.h>
+#endif
#ifndef _WIN32
#include <unistd.h>
#endif
@@ -82,9 +86,9 @@ static int ids_sasl_getopt(
} else if (strcasecmp(option, "has_plain_passwords") == 0) {
*result = "yes";
} else if (strcasecmp(option, "LOG_LEVEL") == 0) {
- if (LDAPDebugLevelIsSet(LDAP_DEBUG_TRACE)) {
- *result = "6"; /* SASL_LOG_TRACE */
- }
+ if (LDAPDebugLevelIsSet(LDAP_DEBUG_TRACE)) {
+ *result = "6"; /* SASL_LOG_TRACE */
+ }
}
if (*result) *len = strlen(*result);
@@ -100,8 +104,8 @@ static int ids_sasl_log(
{
switch (level) {
case SASL_LOG_ERR: /* log unusual errors (default) */
- slapi_log_error(SLAPI_LOG_FATAL, "sasl", "%s", message);
- break;
+ slapi_log_error(SLAPI_LOG_FATAL, "sasl", "%s", message);
+ break;
case SASL_LOG_FAIL: /* log all authentication failures */
case SASL_LOG_WARN: /* log non-fatal warnings */
@@ -109,7 +113,7 @@ static int ids_sasl_log(
case SASL_LOG_DEBUG: /* more verbose than LOG_NOTE */
case SASL_LOG_TRACE: /* traces of internal protocols */
case SASL_LOG_PASS: /* traces of internal protocols, including
- * passwords */
+ * passwords */
LDAPDebug(LDAP_DEBUG_ANY, "sasl(%d): %s", level, message, 0);
break;
@@ -129,22 +133,22 @@ static int ids_sasl_proxy_policy(
struct propctx *propctx
)
{
- int retVal = SASL_OK;
+ int retVal = SASL_OK;
/* do not permit sasl proxy authorization */
- /* if the auth_identity is null or empty string, allow the sasl request to go thru */
- if ( (auth_identity != NULL ) && ( strlen(auth_identity) > 0 ) ) {
- Slapi_DN authId , reqUser;
- slapi_sdn_init_dn_byref(&authId,auth_identity);
- slapi_sdn_init_dn_byref(&reqUser,requested_user);
- if (slapi_sdn_compare((const Slapi_DN *)&reqUser,(const Slapi_DN *) &authId) != 0) {
- LDAPDebug(LDAP_DEBUG_TRACE,
+ /* if the auth_identity is null or empty string, allow the sasl request to go thru */
+ if ( (auth_identity != NULL ) && ( strlen(auth_identity) > 0 ) ) {
+ Slapi_DN authId , reqUser;
+ slapi_sdn_init_dn_byref(&authId,auth_identity);
+ slapi_sdn_init_dn_byref(&reqUser,requested_user);
+ if (slapi_sdn_compare((const Slapi_DN *)&reqUser,(const Slapi_DN *) &authId) != 0) {
+ LDAPDebug(LDAP_DEBUG_TRACE,
"sasl proxy auth not permitted authid=%s user=%s\n",
auth_identity, requested_user, 0);
- retVal = SASL_NOAUTHZ;
- }
- slapi_sdn_done(&authId);
- slapi_sdn_done(&reqUser);
- }
+ retVal = SASL_NOAUTHZ;
+ }
+ slapi_sdn_done(&authId);
+ slapi_sdn_done(&reqUser);
+ }
return retVal;
}
@@ -221,9 +225,9 @@ static Slapi_Entry *ids_sasl_user_to_entry(
char **attrs = NULL;
char *userattr = "uid", *realmattr = NULL, *ufilter = NULL;
void *node;
- int regexmatch = 0;
- char *regex_ldap_search_base = NULL;
- char *regex_ldap_search_filter = NULL;
+ int regexmatch = 0;
+ char *regex_ldap_search_base = NULL;
+ char *regex_ldap_search_filter = NULL;
/* TODO: userattr & realmattr should be configurable */
@@ -237,79 +241,79 @@ static Slapi_Entry *ids_sasl_user_to_entry(
ctrls, attrs, attrsonly,
&entry, &found);
} else {
- int offset = 0;
- if (strncasecmp(user,"u:",2) == 0 )
- offset = 2;
+ int offset = 0;
+ if (strncasecmp(user,"u:",2) == 0 )
+ offset = 2;
/* TODO: quote the filter values */
- /* New regex-based identity mapping : we call it here before the old code.
- * If there's a match, we skip the old way, otherwise we plow ahead for backwards compatibility reasons
- */
+ /* New regex-based identity mapping : we call it here before the old code.
+ * If there's a match, we skip the old way, otherwise we plow ahead for backwards compatibility reasons
+ */
- regexmatch = sasl_map_domap((char*)user, (char*)user_realm, &regex_ldap_search_base, &regex_ldap_search_filter);
- if (regexmatch) {
+ regexmatch = sasl_map_domap((char*)user, (char*)user_realm, &regex_ldap_search_base, &regex_ldap_search_filter);
+ if (regexmatch) {
- ids_sasl_user_search(regex_ldap_search_base, scope, regex_ldap_search_filter,
+ ids_sasl_user_search(regex_ldap_search_base, scope, regex_ldap_search_filter,
ctrls, attrs, attrsonly,
&entry, &found);
- /* Free the filter etc */
- slapi_ch_free((void**)&regex_ldap_search_base);
- slapi_ch_free((void**)&regex_ldap_search_filter);
- } else {
-
- /* Ensure no buffer overflow. */
- /* We don't know what the upper limits on username and
- * realm lengths are. There don't seem to be any defined
- * in the relevant standards. We may find in the future
- * that a 1K buffer is insufficient for some mechanism,
- * but it seems unlikely given that the values are exposed
- * to the end user.
- */
- ulen = strlen(user+offset);
- fsize += strlen(userattr) + ulen;
- if (realmattr && user_realm) {
- rlen = strlen(user_realm);
- fsize += strlen(realmattr) + rlen;
- }
- if (ufilter) fsize += strlen(ufilter);
- fsize += 100; /* includes a good safety margin */
- if (fsize > 1024) {
- LDAPDebug(LDAP_DEBUG_ANY, "sasl user name and/or realm too long"
- " (ulen=%u, rlen=%u)\n", ulen, rlen, 0);
- return NULL;
- }
-
- /* now we can safely write the filter */
- sprintf(fptr, "(&(%s=%s)", userattr, user+offset);
- fptr += strlen(fptr);
- if (realmattr && user_realm) {
- sprintf(fptr, "(%s=%s)", realmattr, user_realm);
- fptr += strlen(fptr);
- }
- if (ufilter) {
- if (*ufilter == '(') {
- sprintf(fptr, "%s", ufilter);
+ /* Free the filter etc */
+ slapi_ch_free((void**)&regex_ldap_search_base);
+ slapi_ch_free((void**)&regex_ldap_search_filter);
} else {
- sprintf(fptr, "(%s)", ufilter);
+
+ /* Ensure no buffer overflow. */
+ /* We don't know what the upper limits on username and
+ * realm lengths are. There don't seem to be any defined
+ * in the relevant standards. We may find in the future
+ * that a 1K buffer is insufficient for some mechanism,
+ * but it seems unlikely given that the values are exposed
+ * to the end user.
+ */
+ ulen = strlen(user+offset);
+ fsize += strlen(userattr) + ulen;
+ if (realmattr && user_realm) {
+ rlen = strlen(user_realm);
+ fsize += strlen(realmattr) + rlen;
}
+ if (ufilter) fsize += strlen(ufilter);
+ fsize += 100; /* includes a good safety margin */
+ if (fsize > 1024) {
+ LDAPDebug(LDAP_DEBUG_ANY, "sasl user name and/or realm too long"
+ " (ulen=%u, rlen=%u)\n", ulen, rlen, 0);
+ return NULL;
+ }
+
+ /* now we can safely write the filter */
+ sprintf(fptr, "(&(%s=%s)", userattr, user+offset);
fptr += strlen(fptr);
+ if (realmattr && user_realm) {
+ sprintf(fptr, "(%s=%s)", realmattr, user_realm);
+ fptr += strlen(fptr);
+ }
+ if (ufilter) {
+ if (*ufilter == '(') {
+ sprintf(fptr, "%s", ufilter);
+ } else {
+ sprintf(fptr, "(%s)", ufilter);
+ }
+ fptr += strlen(fptr);
+ }
+ sprintf(fptr, ")");
+
+ /* iterate through the naming contexts */
+ for (sdn = slapi_get_first_suffix(&node, 0); sdn != NULL;
+ sdn = slapi_get_next_suffix(&node, 0)) {
+
+ ids_sasl_user_search((char*)slapi_sdn_get_dn(sdn), scope, filter,
+ ctrls, attrs, attrsonly,
+ &entry, &found);
+ }
}
- sprintf(fptr, ")");
-
- /* iterate through the naming contexts */
- for (sdn = slapi_get_first_suffix(&node, 0); sdn != NULL;
- sdn = slapi_get_next_suffix(&node, 0)) {
-
- ids_sasl_user_search((char*)slapi_sdn_get_dn(sdn), scope, filter,
- ctrls, attrs, attrsonly,
- &entry, &found);
- }
- }
}
if (found == 1) {
- LDAPDebug(LDAP_DEBUG_TRACE, "sasl user search found this entry: dn:%s, matching filter=%s\n", entry->e_sdn.dn, filter, 0);
+ LDAPDebug(LDAP_DEBUG_TRACE, "sasl user search found this entry: dn:%s, matching filter=%s\n", entry->e_sdn.dn, filter, 0);
return entry;
}
@@ -339,10 +343,14 @@ static int ids_sasl_canon_user(
sasl_conn_t *conn,
void *context,
const char *userbuf, unsigned ulen,
+#ifndef CYRUS_SASL
const char *authidbuf, unsigned alen,
+#endif
unsigned flags, const char *user_realm,
- char *out_user, unsigned out_umax, unsigned *out_ulen,
- char *out_authid, unsigned out_amax, unsigned *out_alen
+ char *out_user, unsigned out_umax, unsigned *out_ulen
+#ifndef CYRUS_SASL
+ ,char *out_authid, unsigned out_amax, unsigned *out_alen
+#endif
)
{
struct propctx *propctx = sasl_auxprop_getctx(conn);
@@ -350,20 +358,29 @@ static int ids_sasl_canon_user(
Slapi_DN *sdn = NULL;
char *pw = NULL;
char *user = NULL;
+#ifndef CYRUS_SASL
char *authid = NULL;
+#endif
const char *dn;
int isroot = 0;
- char *clear = NULL;
+ char *clear = NULL;
+ int returnvalue = SASL_FAIL;
user = buf2str(userbuf, ulen);
if (user == NULL) {
goto fail;
}
+#ifdef CYRUS_SASL
+ LDAPDebug(LDAP_DEBUG_TRACE,
+ "ids_sasl_canon_user(user=%s, realm=%s)\n",
+ user, user_realm ? user_realm : "", 0);
+#else
authid = buf2str(authidbuf, alen);
LDAPDebug(LDAP_DEBUG_TRACE,
"ids_sasl_canon_user(user=%s, authzid=%s, realm=%s)\n",
user, authid, user_realm ? user_realm : "");
+#endif
if (strncasecmp(user, "dn:", 3) == 0) {
sdn = slapi_sdn_new();
@@ -379,6 +396,11 @@ static int ids_sasl_canon_user(
/* map the sasl username into an entry */
entry = ids_sasl_user_to_entry(conn, context, user, user_realm);
if (entry == NULL) {
+#ifdef CYRUS_SASL
+ /* Specific return value is supposed to be set instead of
+ an generic error (SASL_FAIL) for Cyrus SASL */
+ returnvalue = SASL_NOAUTHZ;
+#endif
goto fail;
}
dn = slapi_entry_get_ndn(entry);
@@ -392,29 +414,34 @@ static int ids_sasl_canon_user(
clear = pw;
if (clear) {
- if (prop_set(propctx, "userpassword", clear, -1) != 0) {
- /* Failure is benign here because some mechanisms don't support this property */
- /*LDAPDebug(LDAP_DEBUG_TRACE, "prop_set(userpassword) failed\n", 0, 0, 0);
- goto fail */ ;
- }
+ if (prop_set(propctx, "userpassword", clear, -1) != 0) {
+ /* Failure is benign here because some mechanisms don't support this property */
+ /*LDAPDebug(LDAP_DEBUG_TRACE, "prop_set(userpassword) failed\n", 0, 0, 0);
+ goto fail */ ;
+ }
}
/* TODO: canonicalize */
strcpy(out_user, dn);
- if (authid )
- {
- int offset = 0;
- /* The authid can start with dn:. In such case remove it */
- if (strncasecmp(authid,"dn:",3) == 0 )
- offset = 3;
- strcpy(out_authid, authid+offset);
- }
+#ifdef CYRUS_SASL
+ /* the length of out_user needs to be set for Cyrus SASL */
+ *out_ulen = strlen(out_user);
+#else
+ if (authid )
+ {
+ int offset = 0;
+ /* The authid can start with dn:. In such case remove it */
+ if (strncasecmp(authid,"dn:",3) == 0 )
+ offset = 3;
+ strcpy(out_authid, authid+offset);
+ }
*out_ulen = -1;
*out_alen = -1;
+ slapi_ch_free((void**)&authid);
+#endif
slapi_entry_free(entry);
slapi_ch_free((void**)&user);
- slapi_ch_free((void**)&authid);
slapi_ch_free((void**)&pw);
slapi_sdn_free(&sdn);
@@ -423,30 +450,46 @@ static int ids_sasl_canon_user(
fail:
slapi_entry_free(entry);
slapi_ch_free((void**)&user);
+#ifndef CYRUS_SASL
slapi_ch_free((void**)&authid);
+#endif
slapi_ch_free((void**)&pw);
slapi_sdn_free(&sdn);
- return SASL_FAIL;
+ return returnvalue;
}
static sasl_callback_t ids_sasl_callbacks[5] =
{
- SASL_CB_GETOPT,
- (IFP) ids_sasl_getopt,
- NULL,
- SASL_CB_LOG,
- (IFP) ids_sasl_log,
- NULL,
- SASL_CB_PROXY_POLICY,
- (IFP) ids_sasl_proxy_policy,
- NULL,
- SASL_CB_SERVER_CANON_USER,
- (IFP) ids_sasl_canon_user,
- NULL,
- SASL_CB_LIST_END,
- (IFP) NULL,
- NULL
+ {
+ SASL_CB_GETOPT,
+ (IFP) ids_sasl_getopt,
+ NULL
+ },
+ {
+ SASL_CB_LOG,
+ (IFP) ids_sasl_log,
+ NULL
+ },
+ {
+ SASL_CB_PROXY_POLICY,
+ (IFP) ids_sasl_proxy_policy,
+ NULL
+ },
+ {
+#ifdef CYRUS_SASL
+ SASL_CB_CANON_USER,
+#else
+ SASL_CB_SERVER_CANON_USER,
+#endif
+ (IFP) ids_sasl_canon_user,
+ NULL
+ },
+ {
+ SASL_CB_LIST_END,
+ (IFP) NULL,
+ NULL
+ }
};
static const char *dn_propnames[] = { "dn", 0 };
@@ -466,7 +509,7 @@ int ids_sasl_init(void)
serverfqdn = get_localhost_DNS();
- LDAPDebug(LDAP_DEBUG_TRACE, "sasl service fqdn is: %s\n",
+ LDAPDebug(LDAP_DEBUG_TRACE, "sasl service fqdn is: %s\n",
serverfqdn, 0, 0);
result = sasl_server_init(ids_sasl_callbacks, "iDS");
@@ -477,12 +520,13 @@ int ids_sasl_init(void)
return result;
}
+#ifndef CYRUS_SASL
result = sasl_server_add_plugin("USERDB", sasl_userdb_init);
if (result != SASL_OK) {
LDAPDebug(LDAP_DEBUG_TRACE, "failed to add LDAP sasl plugin\n",
0, 0, 0);
- return result;
+ return result;
}
#if defined(BUILD_GSSAPI)
@@ -493,6 +537,7 @@ int ids_sasl_init(void)
0, 0, 0);
}
#endif
+#endif
LDAPDebug( LDAP_DEBUG_TRACE, "<= ids_sasl_init\n", 0, 0, 0 );
@@ -611,9 +656,9 @@ ids_sasl_mech_supported(Slapi_PBlock *pb, sasl_conn_t *sasl_conn, const char *me
/* sasl_listmech is not thread-safe, so we lock here */
PR_Lock(pb->pb_conn->c_mutex);
sasl_result = sasl_listmech(sasl_conn,
- NULL, /* username */
- "", ",", "",
- &str, NULL, NULL);
+ NULL, /* username */
+ "", ",", "",
+ &str, NULL, NULL);
PR_Unlock(pb->pb_conn->c_mutex);
if (sasl_result != SASL_OK) {
return 0;
@@ -758,17 +803,17 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
isroot = slapi_dn_isroot(dn);
if (!isroot )
- {
- /* check if the account is locked */
- bind_target_entry = get_entry(pb, dn);
- if ( bind_target_entry == NULL )
- {
- break;
- }
- if ( check_account_lock(pb, bind_target_entry, pwresponse_requested) == 1) {
- slapi_entry_free(bind_target_entry);
- break;
- }
+ {
+ /* check if the account is locked */
+ bind_target_entry = get_entry(pb, dn);
+ if ( bind_target_entry == NULL )
+ {
+ break;
+ }
+ if ( check_account_lock(pb, bind_target_entry, pwresponse_requested) == 1) {
+ slapi_entry_free(bind_target_entry);
+ break;
+ }
}
/* see if we negotiated a security layer */
@@ -781,16 +826,16 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
"sasl encryption not supported over ssl",
0, NULL);
if ( bind_target_entry != NULL )
- slapi_entry_free(bind_target_entry);
+ slapi_entry_free(bind_target_entry);
break;
} else {
- /* Enable SASL I/O on the connection now */
- /* Note that this doesn't go into effect until the next _read_ operation is done */
- if (0 != sasl_io_enable(pb->pb_conn) ) {
- send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
+ /* Enable SASL I/O on the connection now */
+ /* Note that this doesn't go into effect until the next _read_ operation is done */
+ if (0 != sasl_io_enable(pb->pb_conn) ) {
+ send_ldap_result(pb, LDAP_OPERATIONS_ERROR, NULL,
"failed to enable sasl i/o",
- 0, NULL);
- }
+ 0, NULL);
+ }
}
}
@@ -825,14 +870,14 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
/* check password expiry */
if (!isroot) {
- int pwrc;
-
- pwrc = need_new_pw (pb, &t, bind_target_entry, pwresponse_requested);
- if ( bind_target_entry != NULL ) {
- slapi_entry_free(bind_target_entry);
- bind_target_entry = NULL;
- }
-
+ int pwrc;
+
+ pwrc = need_new_pw(pb, &t, bind_target_entry, pwresponse_requested);
+ if ( bind_target_entry != NULL ) {
+ slapi_entry_free(bind_target_entry);
+ bind_target_entry = NULL;
+ }
+
switch (pwrc) {
case 1:
slapi_add_pwd_control(pb, LDAP_CONTROL_PWEXPIRED, 0);
@@ -895,13 +940,13 @@ void ids_sasl_check_bind(Slapi_PBlock *pb)
break;
}
- out:
- if (referral)
- slapi_entry_free(referral);
- if (be)
- slapi_be_Unlock(be);
+ out:
+ if (referral)
+ slapi_entry_free(referral);
+ if (be)
+ slapi_be_Unlock(be);
- LDAPDebug( LDAP_DEBUG_TRACE, "=> ids_sasl_check_bind\n", 0, 0, 0 );
+ LDAPDebug( LDAP_DEBUG_TRACE, "=> ids_sasl_check_bind\n", 0, 0, 0 );
return;
}