summaryrefslogtreecommitdiffstats
path: root/ldap/servers
diff options
context:
space:
mode:
authorNoriko Hosoi <nhosoi@redhat.com>2006-08-31 23:26:25 +0000
committerNoriko Hosoi <nhosoi@redhat.com>2006-08-31 23:26:25 +0000
commita656383901931edb24e5c3e4943931b0acff0a9c (patch)
tree7532696f43f1a001c966ea90f615827c3547f29d /ldap/servers
parente5be59676dcf75e5cda532d54bdae6e215a0c489 (diff)
downloadds-a656383901931edb24e5c3e4943931b0acff0a9c.tar.gz
ds-a656383901931edb24e5c3e4943931b0acff0a9c.tar.xz
ds-a656383901931edb24e5c3e4943931b0acff0a9c.zip
[204566] Adjustment for new LDAP C SDK (ber_get_next_buffer_ext)
Changes: 1) When ber_get_next_buffer_ext fails, not just LBER_DEFAULT but LBER_OVERFLOW can be set to the ber tag. Thus, LBER_OVERFLOW is also checked in the error check now. 2) The too large length error used be checked as "errno == EMSGSIZE", which is replaced with "tag == LBER_OVERFLOW"
Diffstat (limited to 'ldap/servers')
-rw-r--r--ldap/servers/slapd/connection.c76
1 files changed, 47 insertions, 29 deletions
diff --git a/ldap/servers/slapd/connection.c b/ldap/servers/slapd/connection.c
index d3172e91..ec9b65cb 100644
--- a/ldap/servers/slapd/connection.c
+++ b/ldap/servers/slapd/connection.c
@@ -1037,35 +1037,37 @@ static int read_the_data(Connection *conn, int *process_op, int *defer_io, int *
/* We need to read the data into the BER buffer */
/* This can return a tag pr LBER_DEFAULT, indicating some error condition */
tag = ber_get_next_buffer_ext( Buffer, Bytes_Read, &ber_len, op->o_ber, &Bytes_Scanned, conn->c_sb );
- if(LBER_DEFAULT == tag)
+ if (LBER_DEFAULT == tag || LBER_OVERFLOW == tag)
{
- if (0 == Bytes_Scanned)
- {
- /* Means we encountered an error---eg the client sent us pure crap---
- a bunch of bytes which we took to be a tag, length, then we ran off the
- end of the buffer. The next time we get here, we'll be returned LBER_DEFAULT
- This means that everything we've seen up till now is useless because it wasn't
- an LDAP message.
- So, we toss it away ! */
- if (errno == EMSGSIZE) {
- log_ber_too_big_error(conn, ber_len, 0);
+ if (0 == Bytes_Scanned)
+ {
+ /* Means we encountered an error---eg the client sent us pure crap---
+ a bunch of bytes which we took to be a tag, length, then we ran off the
+ end of the buffer. The next time we get here, we'll be returned LBER_DEFAULT
+ This means that everything we've seen up till now is useless because it wasn't
+ an LDAP message.
+ So, we toss it away ! */
+ if (LBER_OVERFLOW == tag) {
+ slapi_log_error( SLAPI_LOG_FATAL, "connection",
+ "conn=%d fd=%d The length of BER Element was too long.\n",
+ conn->c_connid, conn->c_sd );
+ }
+ PR_Lock( conn->c_mutex );
+ connection_remove_operation( conn, op );
+ operation_free(&op, conn);
+ priv->c_current_op = NULL;
+ PR_Unlock( conn->c_mutex );
+ return -1; /* Abandon Connection */
}
+ }
+ if (is_ber_too_big(conn,ber_len))
+ {
PR_Lock( conn->c_mutex );
connection_remove_operation( conn, op );
operation_free(&op, conn);
priv->c_current_op = NULL;
PR_Unlock( conn->c_mutex );
- return -1; /* Abandon Connection */
- }
- }
- if (is_ber_too_big(conn,ber_len))
- {
- PR_Lock( conn->c_mutex );
- connection_remove_operation( conn, op );
- operation_free(&op, conn);
- priv->c_current_op = NULL;
- PR_Unlock( conn->c_mutex );
- return -1; /* Abandon Connection */
+ return -1; /* Abandon Connection */
}
/* We set the flag to indicate that we'er in the middle of an op */
@@ -1582,6 +1584,19 @@ void connection_make_new_pb(Slapi_PBlock **ppb, Connection *conn)
/*
* Utility function called by connection_read_operation(). This is a
* small wrapper on top of libldap's ber_get_next_buffer_ext().
+ *
+ * Return value:
+ * 0: Success
+ * case 1) If there was not enough data in the buffer to complete the
+ * message, go to the next cycle. In this case, bytes_scanned is set
+ * to a positive number and *tagp is set to LBER_DEFAULT.
+ * case 2) Complete. *tagp == (tag of the message) and bytes_scanned is
+ * set to a positive number.
+ * -1: Failure
+ * case 1) *tagp == LBER_OVERFLOW: the length is either bigger than
+ * ber_uint_t type or the value preset via
+ * LBER_SOCKBUF_OPT_MAX_INCOMING_SIZE option
+ * case 2) *tagp == LBER_DEFAULT: memory error or tag mismatch
*/
static int
get_next_from_buffer( void *buffer, size_t buffer_size, ber_len_t *lenp,
@@ -1594,16 +1609,20 @@ get_next_from_buffer( void *buffer, size_t buffer_size, ber_len_t *lenp,
*lenp = 0;
*tagp = ber_get_next_buffer_ext( buffer, buffer_size, lenp, ber,
&bytes_scanned, conn->c_sb );
- if (LBER_DEFAULT == *tagp && 0 == bytes_scanned) {
- if (errno == EMSGSIZE) {
- log_ber_too_big_error(conn, *lenp, 0);
+ if ((LBER_OVERFLOW == *tagp || LBER_DEFAULT == *tagp) && 0 == bytes_scanned)
+ {
+ if (LBER_OVERFLOW == *tagp)
+ {
err = SLAPD_DISCONNECT_BER_TOO_BIG;
- } else {
- syserr = errno;
}
+ else
+ {
+ err = SLAPD_DISCONNECT_BAD_BER_TAG;
+ }
+ syserr = errno;
/* Bad stuff happened, like the client sent us some junk */
LDAPDebug( LDAP_DEBUG_CONNS,
- "ber_get_next failed for connection %d\n", conn->c_connid, 0, 0 );
+ "ber_get_next failed for connection %d\n", conn->c_connid, 0, 0 );
/* reset private buffer */
conn->c_private->c_buffer_bytes = conn->c_private->c_buffer_offset = 0;
@@ -1697,7 +1716,6 @@ int connection_read_operation(Connection *conn, Operation *op, ber_tag_t *tag, i
/* We should never get here with data remaining in the buffer */
PR_ASSERT( !new_operation || 0 == (conn->c_private->c_buffer_bytes - conn->c_private->c_buffer_offset) );
/* We make a non-blocking read call */
- /* ret = PR_Recv(conn->c_prfd,conn->c_private->c_buffer,conn->c_private->c_buffer_size,0,PR_INTERVAL_NO_WAIT); */
ret = connection_read_ldap_data(conn,&err);
if (ret <= 0) {
if (0 == ret) {