]> git.sur5r.net Git - openldap/blob - servers/slapd/result.c
074b1c6b6d9ea26fee4d1d4768a5a9d270ec60dd
[openldap] / servers / slapd / result.c
1 /* result.c - routines to send ldap results, errors, and referrals */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/socket.h>
13 #include <ac/errno.h>
14 #include <ac/string.h>
15 #include <ac/ctype.h>
16 #include <ac/time.h>
17 #include <ac/unistd.h>
18
19 #include "slap.h"
20
21 static char *v2ref( BerVarray ref, const char *text )
22 {
23         size_t len = 0, i = 0;
24         char *v2;
25
26         if(ref == NULL) {
27                 if (text) {
28                         return ch_strdup(text);
29                 } else {
30                         return NULL;
31                 }
32         }
33         
34         if ( text != NULL ) {
35                 len = strlen( text );
36                 if (text[len-1] != '\n') {
37                     i = 1;
38                 }
39         }
40
41         v2 = ch_malloc( len+i+sizeof("Referral:") );
42         if( text != NULL ) {
43                 strcpy(v2, text);
44                 if( i ) {
45                         v2[len++] = '\n';
46                 }
47         }
48         strcpy( v2+len, "Referral:" );
49         len += sizeof("Referral:");
50
51         for( i=0; ref[i].bv_val != NULL; i++ ) {
52                 v2 = ch_realloc( v2, len + ref[i].bv_len + 1 );
53                 v2[len-1] = '\n';
54                 AC_MEMCPY(&v2[len], ref[i].bv_val, ref[i].bv_len );
55                 len += ref[i].bv_len;
56                 if (ref[i].bv_val[ref[i].bv_len-1] != '/') {
57                         ++len;
58                 }
59         }
60
61         v2[len-1] = '\0';
62         return v2;
63 }
64
65 static ber_tag_t req2res( ber_tag_t tag )
66 {
67         switch( tag ) {
68         case LDAP_REQ_ADD:
69         case LDAP_REQ_BIND:
70         case LDAP_REQ_COMPARE:
71         case LDAP_REQ_EXTENDED:
72         case LDAP_REQ_MODIFY:
73         case LDAP_REQ_MODRDN:
74                 tag++;
75                 break;
76
77         case LDAP_REQ_DELETE:
78                 tag = LDAP_RES_DELETE;
79                 break;
80
81         case LDAP_REQ_ABANDON:
82         case LDAP_REQ_UNBIND:
83                 tag = LBER_SEQUENCE;
84                 break;
85
86         case LDAP_REQ_SEARCH:
87                 tag = LDAP_RES_SEARCH_RESULT;
88                 break;
89
90         default:
91                 tag = LBER_SEQUENCE;
92         }
93
94         return tag;
95 }
96
97 static long send_ldap_ber(
98         Connection *conn,
99         BerElement *ber )
100 {
101         ber_len_t bytes;
102
103         ber_get_option( ber, LBER_OPT_BER_BYTES_TO_WRITE, &bytes );
104
105         /* write only one pdu at a time - wait til it's our turn */
106         ldap_pvt_thread_mutex_lock( &conn->c_write_mutex );
107
108         /* lock the connection */ 
109         ldap_pvt_thread_mutex_lock( &conn->c_mutex );
110
111         /* write the pdu */
112         while( 1 ) {
113                 int err;
114                 ber_socket_t    sd;
115
116                 if ( connection_state_closing( conn ) ) {
117                         ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
118                         ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
119
120                         return 0;
121                 }
122
123                 if ( ber_flush( conn->c_sb, ber, 0 ) == 0 ) {
124                         break;
125                 }
126
127                 err = errno;
128
129                 /*
130                  * we got an error.  if it's ewouldblock, we need to
131                  * wait on the socket being writable.  otherwise, figure
132                  * it's a hard error and return.
133                  */
134
135 #ifdef NEW_LOGGING
136                 LDAP_LOG( OPERATION, ERR, 
137                         "send_ldap_ber: conn %lu  ber_flush failed err=%d (%s)\n",
138                         conn ? conn->c_connid : 0, err, sock_errstr(err) );
139 #else
140                 Debug( LDAP_DEBUG_CONNS, "ber_flush failed errno=%d reason=\"%s\"\n",
141                     err, sock_errstr(err), 0 );
142 #endif
143
144                 if ( err != EWOULDBLOCK && err != EAGAIN ) {
145                         connection_closing( conn );
146
147                         ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
148                         ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
149
150                         return( -1 );
151                 }
152
153                 /* wait for socket to be write-ready */
154                 conn->c_writewaiter = 1;
155                 ber_sockbuf_ctrl( conn->c_sb, LBER_SB_OPT_GET_FD, &sd );
156                 slapd_set_write( sd, 1 );
157
158                 ldap_pvt_thread_cond_wait( &conn->c_write_cv, &conn->c_mutex );
159                 conn->c_writewaiter = 0;
160         }
161
162         ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
163         ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
164
165         return bytes;
166 }
167
168 static int
169 send_ldap_controls( BerElement *ber, LDAPControl **c )
170 {
171         int rc;
172         if( c == NULL ) return 0;
173
174         rc = ber_printf( ber, "t{"/*}*/, LDAP_TAG_CONTROLS );
175         if( rc == -1 ) return rc;
176
177         for( ; *c != NULL; c++) {
178                 rc = ber_printf( ber, "{s" /*}*/, (*c)->ldctl_oid );
179
180                 if( (*c)->ldctl_iscritical ) {
181                         rc = ber_printf( ber, "b",
182                                 (ber_int_t) (*c)->ldctl_iscritical ) ;
183                         if( rc == -1 ) return rc;
184                 }
185
186                 if( (*c)->ldctl_value.bv_val != NULL ) {
187                         rc = ber_printf( ber, "O", &((*c)->ldctl_value)); 
188                         if( rc == -1 ) return rc;
189                 }
190
191                 rc = ber_printf( ber, /*{*/"N}" );
192                 if( rc == -1 ) return rc;
193         }
194
195         rc = ber_printf( ber, /*{*/"N}" );
196
197         return rc;
198 }
199
200 static void
201 send_ldap_response(
202     Connection  *conn,
203     Operation   *op,
204         ber_tag_t       tag,
205         ber_int_t       msgid,
206     ber_int_t   err,
207     const char  *matched,
208     const char  *text,
209         BerVarray       ref,
210         const char      *resoid,
211         struct berval   *resdata,
212         struct berval   *sasldata,
213         LDAPControl **ctrls
214 )
215 {
216         char berbuf[256];
217         BerElement      *ber = (BerElement *)berbuf;
218         int             rc;
219         long    bytes;
220
221         if (op->o_callback && op->o_callback->sc_response) {
222                 op->o_callback->sc_response( conn, op, tag, msgid, err, matched,
223                         text, ref, resoid, resdata, sasldata, ctrls );
224                 return;
225         }
226                 
227         assert( ctrls == NULL ); /* ctrls not implemented */
228
229         ber_init_w_nullc( ber, LBER_USE_DER );
230
231 #ifdef NEW_LOGGING
232         LDAP_LOG( OPERATION, ENTRY, 
233                 "send_ldap_response:  msgid=%d tag=%lu err=%d\n",
234                 msgid, tag, err );
235 #else
236         Debug( LDAP_DEBUG_TRACE,
237                 "send_ldap_response: msgid=%d tag=%lu err=%d\n",
238                 msgid, tag, err );
239 #endif
240
241         if( ref ) {
242 #ifdef NEW_LOGGING
243                 LDAP_LOG( OPERATION, ARGS, 
244                         "send_ldap_response: conn %lu  ref=\"%s\"\n",
245                         conn ? conn->c_connid : 0, 
246                         ref[0].bv_val ? ref[0].bv_val : "NULL" , 0 );
247 #else
248                 Debug( LDAP_DEBUG_ARGS, "send_ldap_response: ref=\"%s\"\n",
249                         ref[0].bv_val ? ref[0].bv_val : "NULL",
250                         NULL, NULL );
251 #endif
252         }
253
254 #ifdef LDAP_CONNECTIONLESS
255         if (conn->c_is_udp) {
256             rc = ber_write(ber, (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
257             if (rc != sizeof(struct sockaddr)) {
258 #ifdef NEW_LOGGING
259                 LDAP_LOG( OPERATION, ERR, 
260                         "send_ldap_response: conn %lu  ber_write failed\n",
261                         conn ? conn->c_connid : 0 , 0, 0);
262 #else
263                 Debug( LDAP_DEBUG_ANY, "ber_write failed\n", 0, 0, 0 );
264 #endif
265                 ber_free_buf( ber );
266                 return;
267             }
268         }
269         if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
270             rc = ber_printf( ber, "{is{t{ess" /*"}}}"*/,
271                 msgid, "", tag, err,
272                 matched == NULL ? "" : matched,
273                 text == NULL ? "" : text );
274         } else
275 #endif
276         {
277             rc = ber_printf( ber, "{it{ess" /*"}}"*/,
278                 msgid, tag, err,
279                 matched == NULL ? "" : matched,
280                 text == NULL ? "" : text );
281         }
282
283         if( rc != -1 ) {
284                 if ( ref != NULL ) {
285                         assert( err == LDAP_REFERRAL );
286                         rc = ber_printf( ber, "t{W}",
287                                 LDAP_TAG_REFERRAL, ref );
288                 } else {
289                         assert( err != LDAP_REFERRAL );
290                 }
291         }
292
293         if( rc != -1 && sasldata != NULL ) {
294                 rc = ber_printf( ber, "tO",
295                         LDAP_TAG_SASL_RES_CREDS, sasldata );
296         }
297
298         if( rc != -1 && resoid != NULL ) {
299                 rc = ber_printf( ber, "ts",
300                         LDAP_TAG_EXOP_RES_OID, resoid );
301         }
302
303         if( rc != -1 && resdata != NULL ) {
304                 rc = ber_printf( ber, "tO",
305                         LDAP_TAG_EXOP_RES_VALUE, resdata );
306         }
307
308         if( rc != -1 ) {
309                 rc = ber_printf( ber, /*"{"*/ "N}" );
310         }
311
312         if( rc != -1 && ctrls != NULL ) {
313                 rc = send_ldap_controls( ber, ctrls );
314         }
315
316         if( rc != -1 ) {
317                 rc = ber_printf( ber, /*"{"*/ "N}" );
318         }
319
320 #ifdef LDAP_CONNECTIONLESS
321         if( conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1 ) {
322                 rc = ber_printf( ber, /*"{"*/ "N}" );
323         }
324 #endif
325
326         if ( rc == -1 ) {
327 #ifdef NEW_LOGGING
328                 LDAP_LOG( OPERATION, ERR, 
329                         "send_ldap_response: conn %lu  ber_printf failed\n",
330                         conn ? conn->c_connid : 0, 0, 0 );
331 #else
332                 Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
333 #endif
334
335                 ber_free_buf( ber );
336                 return;
337         }
338
339         /* send BER */
340         bytes = send_ldap_ber( conn, ber );
341         ber_free_buf( ber );
342
343         if ( bytes < 0 ) {
344 #ifdef NEW_LOGGING
345                 LDAP_LOG( OPERATION, ERR, 
346                         "send_ldap_response: conn %lu ber write failed\n",
347                         conn ? conn->c_connid : 0, 0, 0 );
348 #else
349                 Debug( LDAP_DEBUG_ANY,
350                         "send_ldap_response: ber write failed\n",
351                         0, 0, 0 );
352 #endif
353
354                 return;
355         }
356
357         ldap_pvt_thread_mutex_lock( &num_sent_mutex );
358         num_bytes_sent += bytes;
359         num_pdu_sent++;
360         ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
361         return;
362 }
363
364
365 void
366 send_ldap_disconnect(
367     Connection  *conn,
368     Operation   *op,
369     ber_int_t   err,
370     const char  *text
371 )
372 {
373         ber_tag_t tag;
374         ber_int_t msgid;
375         char *reqoid;
376
377 #define LDAP_UNSOLICITED_ERROR(e) \
378         (  (e) == LDAP_PROTOCOL_ERROR \
379         || (e) == LDAP_STRONG_AUTH_REQUIRED \
380         || (e) == LDAP_UNAVAILABLE )
381
382         assert( LDAP_UNSOLICITED_ERROR( err ) );
383
384 #ifdef NEW_LOGGING
385         LDAP_LOG( OPERATION, ENTRY, 
386                 "send_ldap_disconnect: conn %lu  %d:%s\n",
387                 conn ? conn->c_connid : 0, err, text ? text : "" );
388 #else
389         Debug( LDAP_DEBUG_TRACE,
390                 "send_ldap_disconnect %d:%s\n",
391                 err, text ? text : "", NULL );
392 #endif
393
394
395         if ( op->o_protocol < LDAP_VERSION3 ) {
396                 reqoid = NULL;
397                 tag = req2res( op->o_tag );
398                 msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
399
400         } else {
401                 reqoid = LDAP_NOTICE_DISCONNECT;
402                 tag = LDAP_RES_EXTENDED;
403                 msgid = 0;
404         }
405
406         send_ldap_response( conn, op, tag, msgid,
407                 err, NULL, text, NULL,
408                 reqoid, NULL, NULL, NULL );
409
410         Statslog( LDAP_DEBUG_STATS,
411             "conn=%lu op=%lu DISCONNECT tag=%lu err=%d text=%s\n",
412                 op->o_connid, op->o_opid, tag, err, text ? text : "" );
413 }
414
415 void
416 send_ldap_result(
417     Connection  *conn,
418     Operation   *op,
419     ber_int_t   err,
420     const char  *matched,
421     const char  *text,
422         BerVarray ref,
423         LDAPControl **ctrls
424 )
425 {
426         ber_tag_t tag;
427         ber_int_t msgid;
428         char *tmp = NULL;
429
430         assert( !LDAP_API_ERROR( err ) );
431
432 #ifdef NEW_LOGGING
433         LDAP_LOG( OPERATION, ENTRY, 
434                 "send_ldap_result : conn %lu      op=%lu p=%d\n",
435                 op->o_connid, op->o_opid, op->o_protocol );
436 #else
437         Debug( LDAP_DEBUG_TRACE,
438                 "send_ldap_result: conn=%lu op=%lu p=%d\n",
439                 op->o_connid, op->o_opid, op->o_protocol );
440 #endif
441
442 #ifdef NEW_LOGGING
443         LDAP_LOG( OPERATION, ARGS, 
444                 "send_ldap_result: err=%d matched=\"%s\" text=\"%s\"\n",
445                 err, matched ? matched : "", text ? text : "" );
446 #else
447         Debug( LDAP_DEBUG_ARGS,
448                 "send_ldap_result: err=%d matched=\"%s\" text=\"%s\"\n",
449                 err, matched ?  matched : "", text ? text : "" );
450 #endif
451
452
453         if( ref ) {
454 #ifdef NEW_LOGGING
455                 LDAP_LOG( OPERATION, ARGS, 
456                         "send_ldap_result: referral=\"%s\"\n",
457                         ref[0].bv_val ? ref[0].bv_val : "NULL", 0, 0 );
458 #else
459                 Debug( LDAP_DEBUG_ARGS,
460                         "send_ldap_result: referral=\"%s\"\n",
461                         ref[0].bv_val ? ref[0].bv_val : "NULL",
462                         NULL, NULL );
463 #endif
464         }
465
466         assert( err != LDAP_PARTIAL_RESULTS );
467
468         if ( err == LDAP_REFERRAL ) {
469                 if( ref == NULL ) {
470                         err = LDAP_NO_SUCH_OBJECT;
471                 } else if ( op->o_protocol < LDAP_VERSION3 ) {
472                         err = LDAP_PARTIAL_RESULTS;
473                 }
474         }
475
476         if ( op->o_protocol < LDAP_VERSION3 ) {
477                 tmp = v2ref( ref, text );
478                 text = tmp;
479                 ref = NULL;
480         }
481
482         tag = req2res( op->o_tag );
483         msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
484
485         send_ldap_response( conn, op, tag, msgid,
486                 err, matched, text, ref,
487                 NULL, NULL, NULL, ctrls );
488
489         Statslog( LDAP_DEBUG_STATS,
490             "conn=%lu op=%lu RESULT tag=%lu err=%d text=%s\n",
491                 op->o_connid, op->o_opid, tag, err, text ? text : "" );
492
493         if( tmp != NULL ) {
494                 ch_free(tmp);
495         }
496 }
497
498 void
499 send_ldap_sasl(
500     Connection  *conn,
501     Operation   *op,
502     ber_int_t   err,
503     const char  *matched,
504     const char  *text,
505         BerVarray ref,
506         LDAPControl **ctrls,
507         struct berval *cred
508 )
509 {
510         ber_tag_t tag;
511         ber_int_t msgid;
512
513 #ifdef NEW_LOGGING
514         LDAP_LOG( OPERATION, ENTRY, 
515                 "send_ldap_sasl: conn %lu err=%d len=%lu\n",
516                 op->o_connid, err, cred ? cred->bv_len : -1 );
517 #else
518         Debug( LDAP_DEBUG_TRACE, "send_ldap_sasl: err=%d len=%ld\n",
519                 err, cred ? (long) cred->bv_len : -1, NULL );
520 #endif
521
522
523         tag = req2res( op->o_tag );
524         msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
525
526         send_ldap_response( conn, op, tag, msgid,
527                 err, matched, text, ref,
528                 NULL, NULL, cred, ctrls  );
529 }
530
531 void
532 send_ldap_extended(
533     Connection  *conn,
534     Operation   *op,
535     ber_int_t   err,
536     const char  *matched,
537     const char  *text,
538     BerVarray   refs,
539     const char          *rspoid,
540         struct berval *rspdata,
541         LDAPControl **ctrls
542 )
543 {
544         ber_tag_t tag;
545         ber_int_t msgid;
546
547 #ifdef NEW_LOGGING
548         LDAP_LOG( OPERATION, ENTRY, 
549                 "send_ldap_extended: err=%d oid=%s len=%ld\n",
550                 err, rspoid ? rspoid : "",
551                 rspdata != NULL ? rspdata->bv_len : 0 );
552 #else
553         Debug( LDAP_DEBUG_TRACE,
554                 "send_ldap_extended err=%d oid=%s len=%ld\n",
555                 err,
556                 rspoid ? rspoid : "",
557                 rspdata != NULL ? rspdata->bv_len : 0 );
558 #endif
559
560
561         tag = req2res( op->o_tag );
562         msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
563
564         send_ldap_response( conn, op, tag, msgid,
565                 err, matched, text, refs,
566                 rspoid, rspdata, NULL, ctrls );
567 }
568
569
570 void
571 send_search_result(
572     Connection  *conn,
573     Operation   *op,
574     ber_int_t   err,
575     const char  *matched,
576         const char      *text,
577     BerVarray   refs,
578         LDAPControl **ctrls,
579     int         nentries
580 )
581 {
582         ber_tag_t tag;
583         ber_int_t msgid;
584         char *tmp = NULL;
585
586         assert( !LDAP_API_ERROR( err ) );
587
588         if (op->o_callback && op->o_callback->sc_sresult) {
589                 op->o_callback->sc_sresult(conn, op, err, matched, text, refs,
590                         ctrls, nentries);
591                 return;
592         }
593
594 #ifdef NEW_LOGGING
595         LDAP_LOG( OPERATION, ENTRY, 
596                 "send_search_result: err=%d matched=\"%s\" text=\"%s\"\n",
597                 err, matched ? matched : "", text ? text : "" );
598 #else
599         Debug( LDAP_DEBUG_TRACE,
600                 "send_search_result: err=%d matched=\"%s\" text=\"%s\"\n",
601                 err, matched ?  matched : "", text ? text : "" );
602 #endif
603
604
605         assert( err != LDAP_PARTIAL_RESULTS );
606
607         if( op->o_protocol < LDAP_VERSION3 ) {
608                 /* send references in search results */
609                 if( err == LDAP_REFERRAL ) {
610                         err = LDAP_PARTIAL_RESULTS;
611                 }
612
613                 tmp = v2ref( refs, text );
614                 text = tmp;
615                 refs = NULL;
616
617         } else {
618                 /* don't send references in search results */
619                 assert( refs == NULL );
620                 refs = NULL;
621
622                 if( err == LDAP_REFERRAL ) {
623                         err = LDAP_SUCCESS;
624                 }
625         }
626
627         tag = req2res( op->o_tag );
628         msgid = (tag != LBER_SEQUENCE) ? op->o_msgid : 0;
629
630         send_ldap_response( conn, op, tag, msgid,
631                 err, matched, text, refs,
632                 NULL, NULL, NULL, ctrls );
633
634         {
635         char nbuf[64];
636         snprintf( nbuf, sizeof nbuf, "%d nentries=%d", err, nentries );
637
638         Statslog( LDAP_DEBUG_STATS,
639             "conn=%lu op=%lu SEARCH RESULT tag=%lu err=%s text=%s\n",
640                 op->o_connid, op->o_opid, tag, nbuf, text ? text : "" );
641         }
642
643         if (tmp != NULL) {
644             ch_free(tmp);
645         }
646 }
647
648 int
649 send_search_entry(
650     Backend     *be,
651     Connection  *conn,
652     Operation   *op,
653     Entry       *e,
654     AttributeName       *attrs,
655     int         attrsonly,
656         LDAPControl **ctrls
657 )
658 {
659         char            berbuf[256];
660         BerElement      *ber = (BerElement *)berbuf;
661         Attribute       *a, *aa;
662         int             i, j, rc=-1, bytes;
663         char            *edn;
664         int             userattrs;
665         int             opattrs;
666         static AccessControlState acl_state_init = ACL_STATE_INIT;
667         AccessControlState acl_state;
668
669         AttributeDescription *ad_entry = slap_schema.si_ad_entry;
670
671         /* a_flags: array of flags telling if the i-th element will be
672          *          returned or filtered out
673          * e_flags: array of a_flags
674          */
675         char **e_flags = NULL;
676
677         if (op->o_callback && op->o_callback->sc_sendentry) {
678                 return op->o_callback->sc_sendentry( be, conn, op, e, attrs,
679                         attrsonly, ctrls );
680         }
681
682 #ifdef NEW_LOGGING
683         LDAP_LOG( OPERATION, ENTRY, 
684                 "send_search_entry: conn %lu    dn=\"%s\"%s\n",
685                 op->o_connid, e->e_dn, attrsonly ? " (attrsOnly)" : "" );
686 #else
687         Debug( LDAP_DEBUG_TRACE,
688                 "=> send_search_entry: dn=\"%s\"%s\n",
689                 e->e_dn, attrsonly ? " (attrsOnly)" : "", 0 );
690 #endif
691
692         if ( ! access_allowed( be, conn, op, e,
693                 ad_entry, NULL, ACL_READ, NULL ) )
694         {
695 #ifdef NEW_LOGGING
696                 LDAP_LOG( ACL, INFO, 
697                         "send_search_entry: conn %lu access to entry (%s) not allowed\n", 
698                         op->o_connid, e->e_dn, 0 );
699 #else
700                 Debug( LDAP_DEBUG_ACL,
701                         "send_search_entry: access to entry not allowed\n",
702                     0, 0, 0 );
703 #endif
704
705                 return( 1 );
706         }
707
708         edn = e->e_ndn;
709
710         ber_init_w_nullc( ber, LBER_USE_DER );
711
712 #ifdef LDAP_CONNECTIONLESS
713         if (conn->c_is_udp) {
714             rc = ber_write(ber, (char *)&op->o_peeraddr, sizeof(struct sockaddr), 0);
715             if (rc != sizeof(struct sockaddr)) {
716 #ifdef NEW_LOGGING
717                 LDAP_LOG( OPERATION, ERR, 
718                         "send_search_entry: conn %lu  ber_printf failed\n",
719                         conn ? conn->c_connid : 0, 0, 0 );
720 #else
721                 Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
722 #endif
723                 ber_free_buf( ber );
724                 return( 1 );
725             }
726         }
727         if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2) {
728             rc = ber_printf( ber, "{is{t{O{" /*}}}*/,
729                 op->o_msgid, "", LDAP_RES_SEARCH_ENTRY, &e->e_name );
730         } else
731 #endif /* LDAP_CONNECTIONLESS */
732         {
733             rc = ber_printf( ber, "{it{O{" /*}}}*/, op->o_msgid,
734                 LDAP_RES_SEARCH_ENTRY, &e->e_name );
735         }
736
737         if ( rc == -1 ) {
738 #ifdef NEW_LOGGING
739                 LDAP_LOG( OPERATION, ERR, 
740                         "send_search_entry: conn %lu  ber_printf failed\n", 
741                         op->o_connid, 0, 0 );
742 #else
743                 Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
744 #endif
745
746                 ber_free_buf( ber );
747                 send_ldap_result( conn, op, LDAP_OTHER,
748                     NULL, "encoding DN error", NULL, NULL );
749                 goto error_return;
750         }
751
752         /* check for special all user attributes ("*") type */
753         userattrs = ( attrs == NULL ) ? 1
754                 : an_find( attrs, &AllUser );
755
756         /* check for special all operational attributes ("+") type */
757         opattrs = ( attrs == NULL ) ? 0
758                 : an_find( attrs, &AllOper );
759
760         /* create an array of arrays of flags. Each flag corresponds
761          * to particular value of attribute and equals 1 if value matches
762          * to ValuesReturnFilter or 0 if not
763          */     
764         if ( op->vrFilter != NULL ) {
765                 int k = 0;
766                 char *a_flags;
767
768                 for ( a = e->e_attrs, i=0; a != NULL; a = a->a_next, i++ ) {
769                         for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) k++;
770                 }
771                 e_flags = ch_calloc ( 1, i * sizeof(char *) + k );
772                 a_flags = (char *)(e_flags + i);
773                 memset( a_flags, 0, k );
774                 for ( a = e->e_attrs, i=0; a != NULL; a = a->a_next, i++ ) {
775                         for ( j = 0; a->a_vals[j].bv_val != NULL; j++ );
776                         e_flags[i] = a_flags;
777                         a_flags += j;
778                 }
779
780                 rc = filter_matched_values(be, conn, op, e->e_attrs, &e_flags) ; 
781                 if ( rc == -1 ) {
782 #ifdef NEW_LOGGING
783                         LDAP_LOG( OPERATION, ERR, 
784                                 "send_search_entry: conn %lu matched values filtering failed\n",
785                                 conn ? conn->c_connid : 0, 0, 0 );
786 #else
787                 Debug( LDAP_DEBUG_ANY,
788                                 "matched values filtering failed\n", 0, 0, 0 );
789 #endif
790                         ber_free( ber, 1 );
791
792                         send_ldap_result( conn, op, LDAP_OTHER,
793                                 NULL, "matched values filtering error", 
794                                 NULL, NULL );
795                         goto error_return;
796                 }
797         }
798
799         for ( a = e->e_attrs, j = 0; a != NULL; a = a->a_next, j++ ) {
800                 AttributeDescription *desc = a->a_desc;
801
802                 if ( attrs == NULL ) {
803                         /* all attrs request, skip operational attributes */
804                         if( is_at_operational( desc->ad_type ) ) {
805                                 continue;
806                         }
807
808                 } else {
809                         /* specific attrs requested */
810                         if ( is_at_operational( desc->ad_type ) ) {
811                                 if( !opattrs && !ad_inlist( desc, attrs ) ) {
812                                         continue;
813                                 }
814
815                         } else {
816                                 if (!userattrs && !ad_inlist( desc, attrs ) ) {
817                                         continue;
818                                 }
819                         }
820                 }
821
822                 acl_state = acl_state_init;
823
824                 if ( ! access_allowed( be, conn, op, e, desc, NULL,
825                         ACL_READ, &acl_state ) )
826                 {
827 #ifdef NEW_LOGGING
828                         LDAP_LOG( ACL, INFO, 
829                                 "send_search_entry: conn %lu  access to attribute %s not "
830                                 "allowed\n", op->o_connid, desc->ad_cname.bv_val, 0 );
831 #else
832                         Debug( LDAP_DEBUG_ACL, "acl: "
833                                 "access to attribute %s not allowed\n",
834                             desc->ad_cname.bv_val, 0, 0 );
835 #endif
836                         continue;
837                 }
838
839                 if (( rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname )) == -1 ) {
840 #ifdef NEW_LOGGING
841                         LDAP_LOG( OPERATION, ERR, 
842                                 "send_search_entry: conn %lu  ber_printf failed\n", 
843                                 op->o_connid, 0, 0 );
844 #else
845                         Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
846 #endif
847
848                         ber_free_buf( ber );
849                         send_ldap_result( conn, op, LDAP_OTHER,
850                             NULL, "encoding description error", NULL, NULL );
851                         goto error_return;
852                 }
853
854                 if ( ! attrsonly ) {
855                         for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
856                                 if ( ! access_allowed( be, conn, op, e,
857                                         desc, &a->a_vals[i], ACL_READ, &acl_state ) )
858                                 {
859 #ifdef NEW_LOGGING
860                                         LDAP_LOG( ACL, INFO, 
861                                                 "send_search_entry: conn %lu "
862                                                 "access to attribute %s, value %d not allowed\n",
863                                                 op->o_connid, desc->ad_cname.bv_val, i );
864 #else
865                                         Debug( LDAP_DEBUG_ACL,
866                                                 "acl: access to attribute %s, "
867                                                 "value %d not allowed\n",
868                                                 desc->ad_cname.bv_val, i, 0 );
869 #endif
870
871                                         continue;
872                                 }
873
874                                 if ( op->vrFilter && e_flags[j][i] == 0 ){
875                                         continue;
876                                 }
877
878                                 if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) {
879 #ifdef NEW_LOGGING
880                                         LDAP_LOG( OPERATION, ERR, 
881                                                 "send_search_entry: conn %lu  "
882                                                 "ber_printf failed.\n", op->o_connid, 0, 0 );
883 #else
884                                         Debug( LDAP_DEBUG_ANY,
885                                             "ber_printf failed\n", 0, 0, 0 );
886 #endif
887
888                                         ber_free_buf( ber );
889                                         send_ldap_result( conn, op, LDAP_OTHER,
890                                                 NULL, "encoding values error",
891                                                 NULL, NULL );
892                                         goto error_return;
893                                 }
894                         }
895                 }
896
897                 if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
898 #ifdef NEW_LOGGING
899                         LDAP_LOG( OPERATION, ERR, 
900                                 "send_search_entry: conn %lu ber_printf failed\n", 
901                                 op->o_connid, 0, 0 );
902 #else
903                         Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
904 #endif
905
906                         ber_free_buf( ber );
907                         send_ldap_result( conn, op, LDAP_OTHER,
908                             NULL, "encode end error", NULL, NULL );
909                         goto error_return;
910                 }
911         }
912
913         /* eventually will loop through generated operational attributes */
914         /* only have subschemaSubentry implemented */
915         aa = backend_operational( be, conn, op, e, attrs, opattrs );
916
917         if ( aa != NULL && op->vrFilter != NULL ) {
918                 int k = 0;
919                 char *a_flags, **tmp;
920
921                 for ( a = aa, i=0; a != NULL; a = a->a_next, i++ ) {
922                         for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) k++;
923                 }
924                 /*
925                  * Reuse previous memory - we likely need less space
926                  * for operational attributes
927                  */
928                 tmp = ch_realloc ( e_flags, i * sizeof(char *) + k );
929                 if ( tmp == NULL ) {
930 #ifdef NEW_LOGGING
931                         LDAP_LOG( OPERATION, ERR, 
932                                 "send_search_entry: conn %lu "
933                                 "not enough memory "
934                                 "for matched values filtering\n", 
935                                 conn ? conn->c_connid : 0, 0, 0);
936 #else
937                         Debug( LDAP_DEBUG_ANY,
938                                 "send_search_entry: conn %lu "
939                                 "not enough memory "
940                                 "for matched values filtering\n",
941                                 conn ? conn->c_connid : 0, 0, 0 );
942 #endif
943                         ber_free( ber, 1 );
944
945                         send_ldap_result( conn, op, LDAP_NO_MEMORY,
946                                 NULL, NULL, NULL, NULL );
947                         goto error_return;
948                 }
949                 e_flags = tmp;
950                 a_flags = (char *)(e_flags + i);
951                 memset( a_flags, 0, k );
952                 for ( a = aa, i=0; a != NULL; a = a->a_next, i++ ) {
953                         for ( j = 0; a->a_vals[j].bv_val != NULL; j++ );
954                         e_flags[i] = a_flags;
955                         a_flags += j;
956                 }
957                 rc = filter_matched_values(be, conn, op, aa, &e_flags) ; 
958             
959                 if ( rc == -1 ) {
960 #ifdef NEW_LOGGING
961                         LDAP_LOG( OPERATION, ERR, 
962                                 "send_search_entry: conn %lu "
963                                 "matched values filtering failed\n", 
964                                 conn ? conn->c_connid : 0, 0, 0);
965 #else
966                         Debug( LDAP_DEBUG_ANY,
967                                 "matched values filtering failed\n", 0, 0, 0 );
968 #endif
969                         ber_free( ber, 1 );
970
971                         send_ldap_result( conn, op, LDAP_OTHER,
972                                 NULL, "matched values filtering error", 
973                                 NULL, NULL );
974                         goto error_return;
975                 }
976         }
977
978         for (a = aa, j=0; a != NULL; a = a->a_next, j++ ) {
979                 AttributeDescription *desc = a->a_desc;
980
981                 if ( attrs == NULL ) {
982                         /* all attrs request, skip operational attributes */
983                         if( is_at_operational( desc->ad_type ) ) {
984                                 continue;
985                         }
986
987                 } else {
988                         /* specific attrs requested */
989                         if( is_at_operational( desc->ad_type ) ) {
990                                 if( !opattrs && !ad_inlist( desc, attrs ) ) {
991                                         continue;
992                                 }
993                         } else {
994                                 if (!userattrs && !ad_inlist( desc, attrs ) )
995                                 {
996                                         continue;
997                                 }
998                         }
999                 }
1000
1001                 acl_state = acl_state_init;
1002
1003                 if ( ! access_allowed( be, conn, op, e, desc, NULL,
1004                         ACL_READ, &acl_state ) )
1005                 {
1006 #ifdef NEW_LOGGING
1007                         LDAP_LOG( ACL, INFO, 
1008                                 "send_search_entry: conn %lu "
1009                                 "access to attribute %s not allowed\n",
1010                                 op->o_connid, desc->ad_cname.bv_val, 0 );
1011 #else
1012                         Debug( LDAP_DEBUG_ACL, "acl: access to attribute %s "
1013                                         "not allowed\n",
1014                                         desc->ad_cname.bv_val, 0, 0 );
1015 #endif
1016
1017                         continue;
1018                 }
1019
1020                 rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname );
1021                 if ( rc == -1 ) {
1022 #ifdef NEW_LOGGING
1023                         LDAP_LOG( OPERATION, ERR, 
1024                                 "send_search_entry: conn %lu  "
1025                                 "ber_printf failed\n", op->o_connid, 0, 0 );
1026 #else
1027                         Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
1028 #endif
1029
1030                         ber_free_buf( ber );
1031                         send_ldap_result( conn, op, LDAP_OTHER,
1032                             NULL, "encoding description error", NULL, NULL );
1033
1034                         attrs_free( aa );
1035                         goto error_return;
1036                 }
1037
1038                 if ( ! attrsonly ) {
1039                         for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
1040                                 if ( ! access_allowed( be, conn, op, e,
1041                                         desc, &a->a_vals[i], ACL_READ, &acl_state ) )
1042                                 {
1043 #ifdef NEW_LOGGING
1044                                         LDAP_LOG( ACL, INFO, 
1045                                                 "send_search_entry: conn %lu "
1046                                                 "access to %s, value %d not allowed\n",
1047                                                 op->o_connid, desc->ad_cname.bv_val, i );
1048 #else
1049                                         Debug( LDAP_DEBUG_ACL,
1050                                                 "acl: access to attribute %s, "
1051                                                 "value %d not allowed\n",
1052                                                 desc->ad_cname.bv_val, i, 0 );
1053 #endif
1054
1055                                         continue;
1056                                 }
1057
1058                                 if ( op->vrFilter && e_flags[j][i] == 0 ){
1059                                         continue;
1060                                 }
1061
1062                                 if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) {
1063 #ifdef NEW_LOGGING
1064                                         LDAP_LOG( OPERATION, ERR, 
1065                                                 "send_search_entry: conn %lu  ber_printf failed\n", 
1066                                                 op->o_connid, 0, 0 );
1067 #else
1068                                         Debug( LDAP_DEBUG_ANY,
1069                                             "ber_printf failed\n", 0, 0, 0 );
1070 #endif
1071
1072                                         ber_free_buf( ber );
1073                                         send_ldap_result( conn, op, LDAP_OTHER,
1074                                                 NULL, "encoding values error", 
1075                                                 NULL, NULL );
1076
1077                                         attrs_free( aa );
1078                                         goto error_return;
1079                                 }
1080                         }
1081                 }
1082
1083                 if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
1084 #ifdef NEW_LOGGING
1085                         LDAP_LOG( OPERATION, ERR, 
1086                                 "send_search_entry: conn %lu  ber_printf failed\n",
1087                                 op->o_connid, 0, 0 );
1088 #else
1089                         Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
1090 #endif
1091
1092                         ber_free_buf( ber );
1093                         send_ldap_result( conn, op, LDAP_OTHER,
1094                             NULL, "encode end error", NULL, NULL );
1095
1096                         attrs_free( aa );
1097                         goto error_return;
1098                 }
1099         }
1100
1101         /* free e_flags */
1102         if ( e_flags ) {
1103                 free( e_flags );
1104                 e_flags = NULL;
1105         }
1106
1107         attrs_free( aa );
1108         rc = ber_printf( ber, /*{{*/ "}N}" );
1109
1110         if( rc != -1 && ctrls != NULL ) {
1111                 rc = send_ldap_controls( ber, ctrls );
1112         }
1113
1114         if( rc != -1 ) {
1115                 rc = ber_printf( ber, /*{*/ "N}" );
1116         }
1117
1118 #ifdef LDAP_CONNECTIONLESS
1119         if (conn->c_is_udp && op->o_protocol == LDAP_VERSION2 && rc != -1)
1120                 rc = ber_printf( ber, "}" );
1121 #endif
1122         if ( rc == -1 ) {
1123 #ifdef NEW_LOGGING
1124                 LDAP_LOG( OPERATION, ERR, 
1125                         "send_search_entry: conn %lu ber_printf failed\n", 
1126                         op->o_connid, 0, 0 );
1127 #else
1128                 Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
1129 #endif
1130
1131                 ber_free_buf( ber );
1132                 send_ldap_result( conn, op, LDAP_OTHER,
1133                         NULL, "encode entry end error", NULL, NULL );
1134                 return( 1 );
1135         }
1136
1137         bytes = send_ldap_ber( conn, ber );
1138         ber_free_buf( ber );
1139
1140         if ( bytes < 0 ) {
1141 #ifdef NEW_LOGGING
1142                 LDAP_LOG( OPERATION, ERR, 
1143                            "send_search_entry: conn %lu  ber write failed.\n", 
1144                            op->o_connid, 0, 0 );
1145 #else
1146                 Debug( LDAP_DEBUG_ANY,
1147                         "send_search_entry: ber write failed\n",
1148                         0, 0, 0 );
1149 #endif
1150
1151                 return -1;
1152         }
1153
1154         ldap_pvt_thread_mutex_lock( &num_sent_mutex );
1155         num_bytes_sent += bytes;
1156         num_entries_sent++;
1157         num_pdu_sent++;
1158         ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
1159
1160         Statslog( LDAP_DEBUG_STATS2, "conn=%lu op=%lu ENTRY dn=\"%s\"\n",
1161             conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
1162
1163 #ifdef NEW_LOGGING
1164         LDAP_LOG( OPERATION, ENTRY, 
1165                 "send_search_entry: conn %lu exit.\n", op->o_connid, 0, 0 );
1166 #else
1167         Debug( LDAP_DEBUG_TRACE, "<= send_search_entry\n", 0, 0, 0 );
1168 #endif
1169
1170         rc = 0;
1171
1172 error_return:;
1173         if ( e_flags ) free( e_flags );
1174         return( rc );
1175 }
1176
1177 int
1178 send_search_reference(
1179     Backend     *be,
1180     Connection  *conn,
1181     Operation   *op,
1182     Entry       *e,
1183         BerVarray refs,
1184         LDAPControl **ctrls,
1185     BerVarray *v2refs
1186 )
1187 {
1188         char            berbuf[256];
1189         BerElement      *ber = (BerElement *)berbuf;
1190         int rc;
1191         int bytes;
1192
1193         AttributeDescription *ad_ref = slap_schema.si_ad_ref;
1194         AttributeDescription *ad_entry = slap_schema.si_ad_entry;
1195
1196 #ifdef NEW_LOGGING
1197         LDAP_LOG( OPERATION, ENTRY, 
1198                 "send_search_reference: conn %lu  dn=\"%s\"\n", 
1199                 op->o_connid, e->e_dn, 0 );
1200 #else
1201         Debug( LDAP_DEBUG_TRACE,
1202                 "=> send_search_reference: dn=\"%s\"\n",
1203                 e->e_dn, 0, 0 );
1204 #endif
1205
1206
1207         if ( ! access_allowed( be, conn, op, e,
1208                 ad_entry, NULL, ACL_READ, NULL ) )
1209         {
1210 #ifdef NEW_LOGGING
1211                 LDAP_LOG( ACL, INFO, 
1212                         "send_search_reference: conn %lu        "
1213                         "access to entry %s not allowed\n", op->o_connid, e->e_dn, 0 );
1214 #else
1215                 Debug( LDAP_DEBUG_ACL,
1216                         "send_search_reference: access to entry not allowed\n",
1217                     0, 0, 0 );
1218 #endif
1219
1220                 return( 1 );
1221         }
1222
1223         if ( ! access_allowed( be, conn, op, e,
1224                 ad_ref, NULL, ACL_READ, NULL ) )
1225         {
1226 #ifdef NEW_LOGGING
1227                 LDAP_LOG( ACL, INFO, 
1228                         "send_search_reference: conn %lu access "
1229                         "to reference not allowed.\n", op->o_connid, 0, 0 );
1230 #else
1231                 Debug( LDAP_DEBUG_ACL,
1232                         "send_search_reference: access "
1233                         "to reference not allowed\n",
1234                     0, 0, 0 );
1235 #endif
1236
1237                 return( 1 );
1238         }
1239
1240         if( refs == NULL ) {
1241 #ifdef NEW_LOGGING
1242                 LDAP_LOG( OPERATION, ERR, 
1243                         "send_search_reference: conn %lu null ref in (%s).\n",
1244                         op->o_connid, e->e_dn, 0 );
1245 #else
1246                 Debug( LDAP_DEBUG_ANY,
1247                         "send_search_reference: null ref in (%s)\n", 
1248                         e->e_dn, 0, 0 );
1249 #endif
1250
1251                 return( 1 );
1252         }
1253
1254         if( op->o_protocol < LDAP_VERSION3 ) {
1255                 /* save the references for the result */
1256                 if( refs[0].bv_val != NULL ) {
1257                         value_add( v2refs, refs );
1258                 }
1259                 return 0;
1260         }
1261
1262         ber_init_w_nullc( ber, LBER_USE_DER );
1263
1264         rc = ber_printf( ber, "{it{W}" /*"}"*/ , op->o_msgid,
1265                 LDAP_RES_SEARCH_REFERENCE, refs );
1266
1267         if( rc != -1 && ctrls != NULL ) {
1268                 rc = send_ldap_controls( ber, ctrls );
1269         }
1270
1271         if( rc != -1 ) {
1272                 rc = ber_printf( ber, /*"{"*/ "N}", op->o_msgid,
1273                         LDAP_RES_SEARCH_REFERENCE, refs );
1274         }
1275
1276         if ( rc == -1 ) {
1277 #ifdef NEW_LOGGING
1278                 LDAP_LOG( OPERATION, ERR, 
1279                         "send_search_reference: conn %lu        "
1280                         "ber_printf failed.\n", op->o_connid, 0, 0 );
1281 #else
1282                 Debug( LDAP_DEBUG_ANY,
1283                         "send_search_reference: ber_printf failed\n", 0, 0, 0 );
1284 #endif
1285
1286                 ber_free_buf( ber );
1287                 send_ldap_result( conn, op, LDAP_OTHER,
1288                         NULL, "encode DN error", NULL, NULL );
1289                 return -1;
1290         }
1291
1292         bytes = send_ldap_ber( conn, ber );
1293         ber_free_buf( ber );
1294
1295         ldap_pvt_thread_mutex_lock( &num_sent_mutex );
1296         num_bytes_sent += bytes;
1297         num_refs_sent++;
1298         num_pdu_sent++;
1299         ldap_pvt_thread_mutex_unlock( &num_sent_mutex );
1300
1301         Statslog( LDAP_DEBUG_STATS2, "conn=%lu op=%lu REF dn=\"%s\"\n",
1302                 conn->c_connid, op->o_opid, e->e_dn, 0, 0 );
1303
1304 #ifdef NEW_LOGGING
1305         LDAP_LOG( OPERATION, ENTRY, 
1306                 "send_search_reference: conn %lu exit.\n", op->o_connid, 0, 0 );
1307 #else
1308         Debug( LDAP_DEBUG_TRACE, "<= send_search_reference\n", 0, 0, 0 );
1309 #endif
1310
1311         return 0;
1312 }
1313
1314
1315 int
1316 str2result(
1317     char        *s,
1318     int         *code,
1319     char        **matched,
1320     char        **info
1321 )
1322 {
1323         int     rc;
1324         char    *c;
1325
1326         *code = LDAP_SUCCESS;
1327         *matched = NULL;
1328         *info = NULL;
1329
1330         if ( strncasecmp( s, "RESULT", 6 ) != 0 ) {
1331 #ifdef NEW_LOGGING
1332                 LDAP_LOG( OPERATION, INFO, 
1333                         "str2result: (%s), expecting \"RESULT\"\n", s, 0, 0 );
1334 #else
1335                 Debug( LDAP_DEBUG_ANY, "str2result (%s) expecting \"RESULT\"\n",
1336                     s, 0, 0 );
1337 #endif
1338
1339                 return( -1 );
1340         }
1341
1342         rc = 0;
1343         while ( (s = strchr( s, '\n' )) != NULL ) {
1344                 *s++ = '\0';
1345                 if ( *s == '\0' ) {
1346                         break;
1347                 }
1348                 if ( (c = strchr( s, ':' )) != NULL ) {
1349                         c++;
1350                 }
1351
1352                 if ( strncasecmp( s, "code", 4 ) == 0 ) {
1353                         if ( c != NULL ) {
1354                                 *code = atoi( c );
1355                         }
1356                 } else if ( strncasecmp( s, "matched", 7 ) == 0 ) {
1357                         if ( c != NULL ) {
1358                                 *matched = c;
1359                         }
1360                 } else if ( strncasecmp( s, "info", 4 ) == 0 ) {
1361                         if ( c != NULL ) {
1362                                 *info = c;
1363                         }
1364                 } else {
1365 #ifdef NEW_LOGGING
1366                         LDAP_LOG( OPERATION, INFO, "str2result: (%s) unknown.\n", s, 0, 0 );
1367 #else
1368                         Debug( LDAP_DEBUG_ANY, "str2result (%s) unknown\n",
1369                             s, 0, 0 );
1370 #endif
1371
1372                         rc = -1;
1373                 }
1374         }
1375
1376         return( rc );
1377 }