/* result.c - routines to send ldap results, errors, and referrals */
-#define DISABLE_BRIDGE
#include "portable.h"
#include <stdio.h>
+
+#include <ac/errno.h>
+#include <ac/signal.h>
+#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <errno.h>
-#include <signal.h>
-#include "slap.h"
-
-#ifndef DECL_SYS_ERRLIST
-extern int sys_nerr;
-extern char *sys_errlist[];
-#endif
-
-extern int active_threads;
-extern pthread_mutex_t active_threads_mutex;
-extern pthread_mutex_t new_conn_mutex;
-extern pthread_t listener_tid;
-extern struct acl *acl_get_applicable();
-extern long num_entries_sent;
-extern long num_bytes_sent;
-extern pthread_mutex_t num_sent_mutex;
+#include <ac/unistd.h> /* get close() */
-void close_connection();
+#include "slap.h"
static void
send_ldap_result2(
)
{
BerElement *ber;
- int rc, sd;
+ int rc, tmp;
unsigned long tag, bytes;
+ if ( err == LDAP_PARTIAL_RESULTS && (text == NULL || *text == '\0') )
+ err = LDAP_NO_SUCH_OBJECT;
+
Debug( LDAP_DEBUG_TRACE, "send_ldap_result %d:%s:%s\n", err, matched ?
matched : "", text ? text : "" );
break;
}
-#ifdef COMPAT30
+
+#ifdef LDAP_COMPAT30
if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER ))
- == NULLBER ) {
+ == NULLBER )
#else
- if ( (ber = der_alloc()) == NULLBER ) {
+ if ( (ber = der_alloc()) == NULLBER )
#endif
+ {
Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
return;
}
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
if ( op->o_cldap ) {
rc = ber_printf( ber, "{is{t{ess}}}", op->o_msgid, "", tag,
err, matched ? matched : "", text ? text : "" );
} else
#endif
-#ifdef COMPAT30
+#ifdef LDAP_COMPAT30
if ( conn->c_version == 30 ) {
rc = ber_printf( ber, "{it{{ess}}}", op->o_msgid, tag, err,
matched ? matched : "", text ? text : "" );
}
/* write only one pdu at a time - wait til it's our turn */
- pthread_mutex_lock( &conn->c_pdumutex );
+ ldap_pvt_thread_mutex_lock( &conn->c_write_mutex );
+
+ /* lock the connection */
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
/* write the pdu */
bytes = ber->ber_ptr - ber->ber_buf;
- pthread_mutex_lock( &new_conn_mutex );
- while ( conn->c_connid == op->o_connid && ber_flush( &conn->c_sb, ber,
- 1 ) != 0 ) {
- pthread_mutex_unlock( &new_conn_mutex );
+
+ while ( ber_flush( &conn->c_sb, ber, 1 ) != 0 ) {
/*
* we got an error. if it's ewouldblock, we need to
* wait on the socket being writable. otherwise, figure
: "unknown", 0 );
if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
- close_connection( conn, op->o_connid, op->o_opid );
+ connection_closing( conn );
- pthread_mutex_unlock( &conn->c_pdumutex );
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
return;
}
/* wait for socket to be write-ready */
- pthread_mutex_lock( &active_threads_mutex );
- active_threads--;
conn->c_writewaiter = 1;
+ slapd_set_write( conn->c_sb.sb_sd, 1 );
-#ifdef linux
- pthread_kill( listener_tid, SIGSTKFLT );
-#else /* !linux */
- pthread_kill( listener_tid, SIGUSR1 );
-#endif /* !linux */
-
- pthread_cond_wait( &conn->c_wcv, &active_threads_mutex );
- pthread_mutex_unlock( &active_threads_mutex );
-
- pthread_yield();
- pthread_mutex_lock( &new_conn_mutex );
+ ldap_pvt_thread_cond_wait( &conn->c_write_cv, &conn->c_mutex );
+ conn->c_writewaiter = 0;
}
- pthread_mutex_unlock( &new_conn_mutex );
- pthread_mutex_unlock( &conn->c_pdumutex );
- pthread_mutex_lock( &num_sent_mutex );
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
+
+ ldap_pvt_thread_mutex_lock( &num_sent_mutex );
num_bytes_sent += bytes;
- pthread_mutex_unlock( &num_sent_mutex );
+ ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
Statslog( LDAP_DEBUG_STATS,
- "conn=%d op=%d RESULT err=%d tag=%d nentries=%d\n", conn->c_connid,
+ "conn=%d op=%d RESULT err=%d tag=%lu nentries=%d\n", conn->c_connid,
op->o_opid, err, tag, nentries );
return;
char *text
)
{
-#ifdef CLDAP
+#ifdef LDAP_CONNECTIONLESS
if ( op->o_cldap ) {
- SAFEMEMCPY( (char *)conn->c_sb.sb_useaddr, &op->o_clientaddr,
- sizeof( struct sockaddr ));
+ lber_pvt_sb_udp_set_dst( &conn->c_sb, &op->o_clientaddr );
Debug( LDAP_DEBUG_TRACE, "UDP response to %s port %d\n",
inet_ntoa(((struct sockaddr_in *)
- conn->c_sb.sb_useaddr)->sin_addr ),
- ((struct sockaddr_in *) conn->c_sb.sb_useaddr)->sin_port,
+ &op->o_clientaddr)->sin_addr ),
+ ((struct sockaddr_in *) &op->o_clientaddr)->sin_port,
0 );
}
#endif
{
BerElement *ber;
Attribute *a;
- int i, rc, bytes, sd;
+ int i, rc=-1, bytes;
struct acl *acl;
char *edn;
Debug( LDAP_DEBUG_TRACE, "=> send_search_entry (%s)\n", e->e_dn, 0, 0 );
- if ( ! access_allowed( be, conn, op, e, "entry", NULL, op->o_dn,
- ACL_READ ) ) {
+ if ( ! access_allowed( be, conn, op, e,
+ "entry", NULL, ACL_READ ) )
+ {
Debug( LDAP_DEBUG_ACL, "acl: access to entry not allowed\n",
0, 0, 0 );
return( 1 );
}
- edn = dn_normalize_case( strdup( e->e_dn ) );
+ edn = e->e_ndn;
-#ifdef COMPAT30
+#ifdef LDAP_COMPAT30
if ( (ber = ber_alloc_t( conn->c_version == 30 ? 0 : LBER_USE_DER ))
== NULLBER )
#else
Debug( LDAP_DEBUG_ANY, "ber_alloc failed\n", 0, 0, 0 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL,
"ber_alloc" );
- free(edn);
- return( 1 );
+ goto error_return;
}
-#ifdef COMPAT30
+#ifdef LDAP_COMPAT30
if ( conn->c_version == 30 ) {
rc = ber_printf( ber, "{it{{s{", op->o_msgid,
LDAP_RES_SEARCH_ENTRY, e->e_dn );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR, NULL,
"ber_printf dn" );
- free(edn);
- return( 1 );
+ goto error_return;
}
for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
a->a_type, 0, 0 );
acl = NULL;
} else {
- acl = acl_get_applicable( be, op, e, a->a_type, edn,
+ acl = acl_get_applicable( be, op, e, a->a_type,
MAXREMATCHES, matches );
}
- if ( ! acl_access_allowed( acl, be, conn, e, NULL, op, ACL_READ,
- edn, matches ) )
+ if ( ! acl_access_allowed( acl, be, conn, e,
+ NULL, op, ACL_READ, edn, matches ) )
{
continue;
}
- if ( ber_printf( ber, "{s[", a->a_type ) == -1 ) {
+ if (( rc = ber_printf( ber, "{s[", a->a_type )) == -1 ) {
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "ber_printf type" );
- free(edn);
- return( 1 );
+ goto error_return;
}
if ( ! attrsonly ) {
continue;
}
- if ( ber_printf( ber, "o",
+ if (( rc = ber_printf( ber, "o",
a->a_vals[i]->bv_val,
- a->a_vals[i]->bv_len ) == -1 )
+ a->a_vals[i]->bv_len )) == -1 )
{
Debug( LDAP_DEBUG_ANY,
"ber_printf failed\n", 0, 0, 0 );
send_ldap_result( conn, op,
LDAP_OPERATIONS_ERROR, NULL,
"ber_printf value" );
- free(edn);
- return( 1 );
+ goto error_return;
}
}
}
- if ( ber_printf( ber, "]}" ) == -1 ) {
+ if (( rc = ber_printf( ber, "]}" )) == -1 ) {
Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
ber_free( ber, 1 );
send_ldap_result( conn, op, LDAP_OPERATIONS_ERROR,
NULL, "ber_printf type end" );
- free(edn);
- return( 1 );
+ goto error_return;
}
}
- free(edn);
-
-#ifdef COMPAT30
+#ifdef LDAP_COMPAT30
if ( conn->c_version == 30 ) {
rc = ber_printf( ber, "}}}}" );
} else
return( 1 );
}
+ bytes = ber->ber_ptr - ber->ber_buf;
+
/* write only one pdu at a time - wait til it's our turn */
- pthread_mutex_lock( &conn->c_pdumutex );
+ ldap_pvt_thread_mutex_lock( &conn->c_write_mutex );
- bytes = ber->ber_ptr - ber->ber_buf;
- pthread_mutex_lock( &new_conn_mutex );
- while ( conn->c_connid == op->o_connid && ber_flush( &conn->c_sb, ber,
- 1 ) != 0 ) {
- pthread_mutex_unlock( &new_conn_mutex );
+ /* lock the connection */
+ ldap_pvt_thread_mutex_lock( &conn->c_mutex );
+
+ /* write the pdu */
+ while ( ber_flush( &conn->c_sb, ber, 1 ) != 0 ) {
/*
* we got an error. if it's ewouldblock, we need to
* wait on the socket being writable. otherwise, figure
: "unknown", 0 );
if ( errno != EWOULDBLOCK && errno != EAGAIN ) {
- close_connection( conn, op->o_connid, op->o_opid );
+ connection_closing( conn );
- pthread_mutex_unlock( &conn->c_pdumutex );
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
return( -1 );
}
/* wait for socket to be write-ready */
- pthread_mutex_lock( &active_threads_mutex );
- active_threads--;
conn->c_writewaiter = 1;
- pthread_kill( listener_tid, SIGUSR1 );
- pthread_cond_wait( &conn->c_wcv, &active_threads_mutex );
- pthread_mutex_unlock( &active_threads_mutex );
+ slapd_set_write( conn->c_sb.sb_sd, 1 );
- pthread_yield();
- pthread_mutex_lock( &new_conn_mutex );
+ ldap_pvt_thread_cond_wait( &conn->c_write_cv, &conn->c_mutex );
+ conn->c_writewaiter = 0;
}
- pthread_mutex_unlock( &new_conn_mutex );
- pthread_mutex_unlock( &conn->c_pdumutex );
- pthread_mutex_lock( &num_sent_mutex );
+ ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
+ ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
+
+ ldap_pvt_thread_mutex_lock( &num_sent_mutex );
num_bytes_sent += bytes;
num_entries_sent++;
- pthread_mutex_unlock( &num_sent_mutex );
-
- pthread_mutex_lock( &new_conn_mutex );
- if ( conn->c_connid == op->o_connid ) {
- rc = 0;
- Statslog( LDAP_DEBUG_STATS2, "conn=%d op=%d ENTRY dn=\"%s\"\n",
- conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
- } else {
- rc = -1;
- }
- pthread_mutex_unlock( &new_conn_mutex );
+ ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
+
+ Statslog( LDAP_DEBUG_STATS2, "conn=%d op=%d ENTRY dn=\"%s\"\n",
+ conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
Debug( LDAP_DEBUG_TRACE, "<= send_search_entry\n", 0, 0, 0 );
+ rc = 0;
+
+error_return:;
return( rc );
}
return( rc );
}
-
-/*
- * close_connection - close a connection. takes the connection to close,
- * the connid associated with the operation generating the close (so we
- * don't accidentally close a connection that's not ours), and the opid
- * of the operation generating the close (for logging purposes).
- */
-void
-close_connection( Connection *conn, int opconnid, int opid )
-{
- pthread_mutex_lock( &new_conn_mutex );
- if ( conn->c_sb.sb_sd != -1 && conn->c_connid == opconnid ) {
- Statslog( LDAP_DEBUG_STATS,
- "conn=%d op=%d fd=%d closed errno=%d\n", conn->c_connid,
- opid, conn->c_sb.sb_sd, errno, 0 );
- close( conn->c_sb.sb_sd );
- conn->c_sb.sb_sd = -1;
- conn->c_version = 0;
- }
- pthread_mutex_unlock( &new_conn_mutex );
-}