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