+ if( (*c)->ldctl_value.bv_val != NULL ) {
+ rc = ber_printf( ber, "O", &((*c)->ldctl_value));
+ if( rc == -1 ) return rc;
+ }
+
+ rc = ber_printf( ber, /*{*/"N}" );
+ if( rc == -1 ) return rc;
+ }
+
+ rc = ber_printf( ber, /*{*/"N}" );
+
+ return rc;
+}
+
+static void
+send_ldap_response(
+ Connection *conn,
+ Operation *op,
+ ber_tag_t tag,
+ ber_int_t msgid,
+ ber_int_t err,
+ const char *matched,
+ const char *text,
+ BerVarray ref,
+ const char *resoid,
+ struct berval *resdata,
+ struct berval *sasldata,
+ LDAPControl **ctrls
+)
+{
+ char berbuf[256];
+ BerElement *ber = (BerElement *)berbuf;
+ int rc;
+ long bytes;
+
+ if (op->o_callback && op->o_callback->sc_response) {
+ op->o_callback->sc_response( conn, op, tag, msgid, err, matched,
+ text, ref, resoid, resdata, sasldata, ctrls );
+ return;
+ }
+
+ assert( ctrls == NULL ); /* ctrls not implemented */
+
+ ber_init_w_nullc( ber, LBER_USE_DER );
+
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ENTRY,
+ "send_ldap_response: msgid=%d tag=%lu err=%d\n",
+ msgid, tag, err );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "send_ldap_response: msgid=%d tag=%lu err=%d\n",
+ msgid, tag, err );
+#endif
+
+ if( ref ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ARGS,
+ "send_ldap_response: conn %lu ref=\"%s\"\n",
+ conn ? conn->c_connid : 0,
+ ref[0].bv_val ? ref[0].bv_val : "NULL" , 0 );
+#else
+ Debug( LDAP_DEBUG_ARGS, "send_ldap_response: ref=\"%s\"\n",
+ ref[0].bv_val ? ref[0].bv_val : "NULL",
+ NULL, NULL );
+#endif
+ }
+
+#ifdef LDAP_CONNECTIONLESS
+ if (conn->c_is_udp) {
+ rc = ber_write(ber, (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
+ if (rc != sizeof(struct sockaddr)) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ERR,
+ "send_ldap_response: conn %lu ber_write failed\n",
+ conn ? conn->c_connid : 0 , 0, 0);
+#else
+ Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
+#endif
+ ber_free_buf( ber );
+ return;
+ }
+ }
+ if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
+ rc = ber_printf( ber, "{is{t{ess" /*"}}}"*/,
+ msgid, "", tag, err,
+ matched == NULL ? "" : matched,
+ text == NULL ? "" : text );
+ } else
+#endif
+ {
+ rc = ber_printf( ber, "{it{ess" /*"}}"*/,
+ msgid, tag, err,
+ matched == NULL ? "" : matched,
+ text == NULL ? "" : text );
+ }
+
+ if( rc != -1 ) {
+ if ( ref != NULL ) {
+ assert( err == LDAP_REFERRAL );
+ rc = ber_printf( ber, "t{W}",
+ LDAP_TAG_REFERRAL, ref );
+ } else {
+ assert( err != LDAP_REFERRAL );
+ }
+ }
+
+ if( rc != -1 && sasldata != NULL ) {
+ rc = ber_printf( ber, "tO",
+ LDAP_TAG_SASL_RES_CREDS, sasldata );
+ }
+
+ if( rc != -1 && resoid != NULL ) {
+ rc = ber_printf( ber, "ts",
+ LDAP_TAG_EXOP_RES_OID, resoid );
+ }
+
+ if( rc != -1 && resdata != NULL ) {
+ rc = ber_printf( ber, "tO",
+ LDAP_TAG_EXOP_RES_VALUE, resdata );
+ }
+
+ if( rc != -1 ) {
+ rc = ber_printf( ber, /*"{"*/ "N}" );
+ }
+
+ if( rc != -1 && ctrls != NULL ) {
+ rc = send_ldap_controls( ber, ctrls );
+ }
+
+ if( rc != -1 ) {
+ rc = ber_printf( ber, /*"{"*/ "N}" );
+ }
+
+#ifdef LDAP_CONNECTIONLESS
+ if( conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1 ) {
+ rc = ber_printf( ber, /*"{"*/ "N}" );
+ }
+#endif
+
+ if ( rc == -1 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ERR,
+ "send_ldap_response: conn %lu ber_printf failed\n",
+ conn ? conn->c_connid : 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
+#endif
+
+ ber_free_buf( ber );
+ return;
+ }
+
+ /* send BER */
+ bytes = send_ldap_ber( conn, ber );
+ ber_free_buf( ber );
+
+ if ( bytes < 0 ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG( OPERATION, ERR,
+ "send_ldap_response: conn %lu ber write failed\n",
+ conn ? conn->c_connid : 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_ANY,
+ "send_ldap_response: ber write failed\n",
+ 0, 0, 0 );
+#endif
+
+ return;