]> git.sur5r.net Git - openldap/blob - contrib/tweb/queries.c
fixed test on "" (empty) parent dn
[openldap] / contrib / tweb / queries.c
1 /*_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ 
2 *                                                                          *
3 * queries.c..                                                              *
4 *                                                                          *
5 * Function:..WorldWideWeb-X.500-Gateway - Server-Functions                 *
6 *            Based on web500gw.c 1.3 written by Frank Richter, TU Chemmniz *
7 *            which is based on go500gw by Tim Howes, University of         *
8 *            Michigan  - All rights reserved                               *
9 *                                                                          *
10 * Authors:...Dr. Kurt Spanier & Bernhard Winkler,                          *
11 *            Zentrum fuer Datenverarbeitung, Bereich Entwicklung           *
12 *            neuer Dienste, Universitaet Tuebingen, GERMANY                *
13 *                                                                          *
14 *                                       ZZZZZ  DDD    V   V                *
15 *            Creation date:                Z   D  D   V   V                *
16 *            August 16 1995               Z    D   D   V V                 *
17 *            Last modification:          Z     D  D    V V                 *
18 *            September 13 1999          ZZZZ   DDD      V                  *
19 *                                                                          *
20 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
21
22 /*
23  * $Id: queries.c,v 1.8 1999/09/13 13:47:47 zrnsk01 Exp $
24  *
25  */
26
27 #include "queries.h"
28
29
30 PUBLIC void do_queries( s, glob , ip_addr, ip_port, hp)
31 int            s;
32 GLOB_STRUCT   *glob;
33 char          *ip_addr;
34 unsigned int   ip_port;
35 struct hostent *hp;
36 {
37     char        buf[100*BUFSIZ], *query, *tail;
38     int        len;
39     FILE        *fp;
40     int        rc, tblsize;
41     struct timeval    timeout;
42     fd_set        readfds;
43     LDAP        *ld;
44     char tstring[100];
45
46 #if OL_LDAPV > 0
47         int ldap_opt;
48 #endif
49
50     /* get time for performance log */
51     gettimeofday(&timestore[2], NULL);
52
53     /*  open output-port to waiting client */
54     if ( (fp = fdopen( s, "a+")) == NULL ) {
55         perror( "fdopen" );
56         exit_tweb( 1 );
57     }
58
59     tblsize = getdtablesize();
60     timeout.tv_sec = glob->timeout;
61     timeout.tv_usec = 0;
62     FD_ZERO( &readfds );
63     FD_SET( fileno( fp ), &readfds );
64
65     time(&glob->nowtime);
66     time(&glob->expiretime);
67     if(glob->cache_expire) {
68         glob->expiretime += glob->cache_expire;
69         glob->caching =TRUE;
70     }
71     free(glob->nowtimestr);
72     free(glob->expiretimestr);
73
74     strftime(tstring, 99, GMT_FORMAT, gmtime(&glob->nowtime));
75     glob->nowtimestr = strdup(tstring);
76     strftime(tstring, 99, GMT_FORMAT2, gmtime(&glob->expiretime));
77     glob->expiretimestr = strdup(tstring);
78
79     /*  get client-query out from the system */
80     if((rc=select(tblsize,(fd_set *)&readfds,NULL,NULL,&timeout))<=0)
81         exit_tweb( 1 );
82
83     if ( fgets( buf, sizeof(buf), fp ) == NULL )
84         exit_tweb( 1 );
85
86     /* Analyse Web-Client-Type / proxy + log-message */
87     checkwwwclient(fp, ip_addr, ip_port, hp, glob);
88
89     len = strlen( buf );
90     if ( debug ) {
91         fprintf( stderr, "got %d bytes\n", len );
92
93 #if OL_LDAPV > 2
94         ber_bprint( buf, len );
95 #else
96         lber_bprint( buf, len );
97 #endif
98
99     }
100
101     /* strip of white spaces */
102     query = trim (buf, WSPACE);
103
104     rewind (fp);
105
106
107     /*  strip "HTTP" from the end of the request */
108     if ((tail = strstr(query, " HTTP")) != NULL || 
109             (tail = strstr(query, " http")) != NULL) {
110         http = 1;
111         *tail = '\0';
112     }
113
114     /*  recognize GET/HEAD */
115     if (!strncasecmp (query, "get", 3)) {
116
117         request = GET;
118         query += 3;
119
120     } else if (!strncasecmp (query, "head", 4)) {
121
122         request = HEAD;
123         query += 4;
124
125     } else {
126
127         /*  Error because of neither GET- nor HEAD-request */
128         do_error(fp, -2, NOT_IMPLEMENTED, glob);
129         /* fprintf(fp, "HTTP/1.0 501 %s<br>", glob->la[5]); */
130         rewind(fp);
131         exit_tweb( 1 );
132     }
133
134         /* strip off leading white space and '/' */
135     while ( isspace( *query ) || *query == '/') {
136         ++query;
137     }
138
139
140     /*  Now the real request is to be analized and served */
141
142     /* refuse robots if according robots.txt file exists */
143
144     if (!strcasecmp(query, "robots.txt")){
145         if (http == 1) PRINT_PLAIN_HEADER;
146         disp_file(glob, ROBOTS_TXT_FILE, fp);
147         exit_tweb(0);
148     }
149
150 #ifdef TUE_TEL
151     if( glob->ton_urls && *query == cTON) {
152         if(!glob->ton_urls->admin)
153             glob->allowed = 0;
154         if(glob->ton_urls->pass_oc) {
155             glob->max_person = 10000;
156             glob->no_browse = FALSE;
157         }
158     }
159 #endif
160
161     decide_access(glob);
162
163     /* get time for performance log */
164     gettimeofday(&timestore[3], NULL);
165
166     /* perform handling of pulldown/form retcodes
167                           -> gwswitch-redirect || pass */
168     if(*query == cPULLDOWN) {
169         if(strstr(query, "http")) {
170             /* redirection */
171             query += 4;
172             hex_decode(query);
173             PRINT_REDIRECT_HEADER;
174             PRINT_HTML_FOOTER;
175             exit_tweb(0);
176         } else {
177             /* pass */
178             query += 7;
179             hex_decode(query);
180         }
181     }
182
183     /* perform handling of buttons/form retcodes
184                           -> gwswitch-redirect || pass */
185     if(*query == cBUTTON) {
186         char *strptr;
187
188         query += 2;
189         strptr = strrchr( query, '=' );
190         *strptr = '\0';
191
192         if(strstr(query, "http")) {
193             /* redirection */
194             hex_decode(query);
195             PRINT_REDIRECT_HEADER;
196             PRINT_HTML_FOOTER;
197             exit_tweb(0);
198         } else {
199             /* pass */
200             hex_decode(query);
201         }
202     }
203
204
205     /*  1. requests that may be served without DSA */
206     switch (*query) {
207
208
209         /*  display Help-File */
210         case cHELP:
211             if (dosyslog)
212                 syslog (LOG_INFO, "working on query: %c (%s,%u) <%08d>",
213                                   cHELP, ip_addr, ip_port, glob->svc_cnt);
214             if (http == 1) PRINT_HTML_HEADER;
215             fprintf(fp, "<HTML><HEAD>");
216             disp_file(glob, glob->helpfile, fp);
217             PRINT_HTML_FOOTER;
218             rewind(fp);
219             exit_tweb( 0 );
220
221         /*  request error-explanation */
222         case cERROR:
223             if (dosyslog)
224                 syslog (LOG_INFO, "working on query: %c (%s,%u) <%08d>",
225                                   cERROR, ip_addr, ip_port, glob->svc_cnt);
226 /*            fprintf(fp, HTML_HEAD_TITLE, "Errors", glob->la[100]);
227 */
228             do_error( fp, 0 , 1, glob );
229             rewind(fp);
230             exit_tweb( 0 );
231
232         /*  RCC: remote configuration control */
233         case cCONFIG:
234             if (dosyslog)
235                 syslog (LOG_INFO, "working on query: %c (%s,%u) <%08d>",
236                                   cCONFIG, ip_addr, ip_port, glob->svc_cnt);
237             if (http == 1) PRINT_HTML_HEADER;
238             fprintf(fp, HTML_HEAD_TITLE, "Configuration", glob->la[100]);
239             output(fp, glob, TRUE);
240             langoutput(fp, glob, TRUE);
241             PRINT_HTML_FOOTER;
242             rewind(fp);
243             exit_tweb(0);
244
245         /* query access-statistic */
246         case cSTATS:
247             if (dosyslog)
248                 syslog (LOG_INFO, "working on query: %c (%s,%u) <%08d>",
249                                   cSTATS, ip_addr, ip_port, glob->svc_cnt);
250             if (http == 1) PRINT_HTML_HEADER;
251             fprintf(fp, HTML_HEAD_TITLE, "Statistics", glob->la[100]);
252             fprintf(fp,
253     "\n<strong>#############STATISTIC-DISPLAY#############</strong><br>\n" );
254             fprintf( fp, "\n%s\n\n<p>\n", version );
255             (void) put_hackStats (fp, 0);
256             PRINT_HTML_FOOTER;
257             rewind (fp);
258             exit_tweb (0);
259
260     /* NOT REACHED */
261     }
262
263     /* with ldap-referral use this host + port + use do_read */
264     /* query looks like this: Wldap://host:port/dn */
265     if ( *query == cREFERRAL ) {
266         char *host, *port, *dn = NULL;
267
268         glob->ldap_referral_mode = 1;
269         if ( ( host = strstr( query, "ldap://" ) ) ) {
270             host += 7;
271             if ( ( port = strchr( host, ':' ) ) ) {
272                 *port++ = '\0';
273                  if ( ( dn = strchr( port, '/' ) ) ) {
274                      *dn = '\0';
275                      glob->ldapd = strdup ( host );
276                      glob->ldapport = atoi ( port );
277                      *dn = cREAD;
278                      query = dn;
279                  }
280             }
281         }
282         if ( !dn )
283             exit_tweb( 1 );
284     }
285
286     /*  from here on there is needed a connection to the DSA */
287     if ( (ld = ldap_open( glob->ldapd, glob->ldapport )) == NULL ) {
288         if ( debug ) perror( "ldap_open" );
289         do_error( fp, LDAP_SERVER_DOWN, SERVER_ERROR, glob);
290         rewind(fp);
291         exit_tweb( 1 );
292     }
293
294     if(glob->caching_terms)
295         trade_cache(fp, ld, query, glob);
296
297     /* performance of STRICT-BASEDN (blind out accesses != BASEDN) */
298
299     if(glob->strict_basedn)
300         strict_basednf(fp, ld, query, glob);
301
302
303     /*  2. queries with binding of the owner */
304     switch (*query) {
305
306         /*  request of the modification-formulare */
307         case cGETMOD:
308             /*  log the request without password */
309             hex_decode(query);
310             if (dosyslog) {
311                 char qbuf[BUFSIZ], *qbufp;
312
313                 strcpy(qbuf, query);
314                 if( ( qbufp = strchr(qbuf, '?')) )
315                     *qbufp = '\0';
316                 syslog (LOG_INFO, "working on query: %s (%s,%u) <%08d>",
317                                   qbuf, ip_addr, ip_port, glob->svc_cnt);
318             }
319             rewind(fp);
320
321             /*  follow aliases while searching */
322 #if OL_LDAPV > 0
323
324                         ldap_opt = LDAP_DEREF_ALWAYS;
325             ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
326
327 #else
328             ld->ld_deref = LDAP_DEREF_ALWAYS;
329 #endif
330
331             if ( !searchaliases )
332 #if OL_LDAPV > 0
333
334                         ldap_opt = LDAP_DEREF_FINDING;
335             ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
336
337 #else
338                      ld->ld_deref = LDAP_DEREF_FINDING;
339 #endif
340     
341             /*  send WWW-Formulare with contence of the desired entry
342                 to the client */
343             do_form( ld, fp, ++query, glob);
344             ldap_unbind (ld);
345             close_ldap_connections(glob);
346             rewind(fp);
347             exit_tweb (0);
348
349         /*  return of the modification-formulare */
350         case cDOMOD:
351
352             /*  log the request in readable form without password if desired */
353             if (dosyslog) {
354
355                 char qbuf[100*BUFSIZ], *qbufp;
356
357                 strcpy(qbuf, query);
358                 if( ( qbufp = strchr (qbuf, '?')) )
359                     *qbufp = '\0';
360                 hex_decode(qbuf+1);
361                 syslog (LOG_INFO, "working on query: %s (%s,%u) <%08d>",
362                                   qbuf, ip_addr, ip_port, glob->svc_cnt);
363
364             }
365
366             /*  perform modification with the original request */
367             do_modify( ld, fp, ++query, glob);
368             ldap_unbind (ld);
369             close_ldap_connections(glob);
370             rewind(fp);
371             exit_tweb (0);
372
373     /* NOT REACHED */
374     }
375
376
377     /*  perform all the other requests */
378
379     /*  log the request in readable form first */
380     hex_decode(query);
381     if (dosyslog)
382         syslog (LOG_INFO, "working on query: %s (%s,%u) <%08d>",
383                *query ? trimright(query, WSPACE) : "BASEDN", ip_addr, ip_port,
384                                 glob->svc_cnt);
385
386     /*  accesses with resolvation of alias-entries */
387 #if OL_LDAPV > 0
388
389                         ldap_opt = LDAP_DEREF_ALWAYS;
390             ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
391
392 #else
393     ld->ld_deref = LDAP_DEREF_ALWAYS;
394 #endif
395
396     if ( !searchaliases )
397 #if OL_LDAPV > 0
398
399                         ldap_opt = LDAP_DEREF_FINDING;
400             ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
401
402 #else
403              ld->ld_deref = LDAP_DEREF_FINDING;
404 #endif
405     
406     /*  bind to DSA by order of the user as Web-DN
407         (DN1 or DN2 was decided at check4access) */
408
409 #if OL_LDAPV > 0
410
411     /*  a dummy call as long as socket connections are not settled
412      *  with OpenLDAP
413      */
414     if ( dosyslog )
415             syslog( LOG_INFO, "do_queries(): calling ldap_simple_bind_s()...\n" );
416
417 #endif
418
419     if ( (rc=ldap_simple_bind_s( ld, glob->webdn, glob->webpw ))
420                                                      != LDAP_SUCCESS ) {
421         if ( debug ) ldap_perror( ld, "ldap_simple_bind_s" );
422         do_error( fp, rc, SERVER_ERROR, glob);
423         rewind(fp);
424         exit_tweb( 1 );
425     }
426
427     /*  3. requests to the GW by order of the user */
428     switch ( *query++ ) {
429
430         /*  read entry */
431         case cREAD:
432             do_read( ld, fp, query, 0, glob );
433             break;
434
435         /*  display second page */
436         case cREADALL:
437             do_read( ld, fp, query, 1, glob);
438             break;
439
440         /*  search entries */
441         case cSEARCH:
442             do_search( ld, fp, query, glob );
443             break;
444
445         /*  list entries (browsing) */
446         case cLIST:
447             do_menu( ld, fp, query, "", glob );
448             break;
449
450 #ifdef TUE_TEL
451         /*  list entries (browsing TON instead of DN) */
452         case cTON:
453             if(glob->ton_urls)
454                 do_ton( ld, fp, query, glob );
455             break;
456 #endif
457
458         /*  request GIF-photo (Photo in X.500 as JPEG) */
459         case cGIF:
460             do_pict( ld, fp, query, 1, glob);
461             break;
462
463         /*  display JPEG-Photo */
464         case cJPEG:
465             do_pict( ld, fp, query, 2, glob);
466             break;
467
468         /*  display X.500-G3FAX-Photo */
469         case cG3FAX:
470             do_pict( ld, fp, query, 0, glob);
471             break;
472
473         /*  play Audio-attribute */
474         case cAUDIO:
475             do_audio( ld, fp, query, 0, glob);
476             break;
477
478         /*  eXtended query format */
479         case cEXTENDED:
480             do_xtend( ld, fp, query, 0, glob);
481             break;
482
483         /*  Default (empty query) is browsing of BASEDN */
484         default:
485             do_menu( ld, fp, glob->basedn->dn, "", glob );
486             break;
487     }
488
489     /*  Job done, terminate connection to the DSA and bye! */
490     ldap_unbind (ld);
491     close_ldap_connections(glob);
492     rewind(fp);
493     exit_tweb( 0 );
494     /* NOT REACHED */
495 }
496 /* end of function: do_queries */
497
498 PUBLIC void timeoutf(sig)
499 int sig;
500 {
501     /* fprintf(stderr, "timeout!"); */
502     exit_tweb(0);
503 }
504 /* end of function: timeoutf */
505
506
507 PRIVATE void strict_basednf(fp, ld, query, glob)
508 FILE *fp;
509 LDAP *ld;
510 char *query;
511 GLOB_STRUCT   *glob;
512 {
513     char dnbuf[BUFSIZ], basednbuf[BUFSIZ], *strptr;
514     LDAPMessage *res, *e;
515     int rc, flag = 0, i, j;
516     struct timeval timeout;
517     char *url = NULL, **uri, *urlnola = NULL;
518     pGW_SWITCH_LINE gw_ptr;
519     char  *url_tmp;
520     char **dnarray, **bdnarray;
521
522 #ifdef TUE_TEL
523     /* Patch for TONS */
524     if( glob->ton_urls && (*query == cTON))
525         return;
526 #endif
527
528     /* Patch for FORMs/PULLDOWNs (cPULLDOWN) */
529     if( glob->pull_down_menus && (*query == cPULLDOWN))
530         return;
531
532     /* Patch for FORMs/BUTTONs (cBUTTONs) */
533     if( glob->pull_down_menus && (*query == cBUTTON))
534         return;
535
536     if(*query)
537         strcpy(dnbuf, query+1);
538     else
539         strcpy(dnbuf, "\0");
540     hex_decode(dnbuf);
541     strcpy(basednbuf, glob->basedn->dn);
542
543     if( ( strptr = strchr(dnbuf, '?')) )
544         *strptr = '\0';
545
546     if( *query && !dn_issuffix( dn_normalize(dnbuf), dn_normalize(basednbuf))) {
547
548         dnarray = dn2charray(dnbuf);
549         bdnarray = glob->basedn->dnarray;
550
551         strcpy(dnbuf, "\0");
552         if (glob->gw_switch) {
553             for(gw_ptr = glob->gw_switch->list;
554                               !flag && gw_ptr; gw_ptr = gw_ptr->next) {
555                 if (!dn_cmp ("root", gw_ptr->dn)) {
556                     flag = 1;
557                     url = gw_ptr->url;
558                 }
559             }
560         }
561         if(!flag) {
562             fprintf(stderr, "Fehler:strict_basedn w/o root-switch!!!!\n");
563             exit_tweb(0);
564         }
565
566         for(j=0; bdnarray[j] && dnarray[j]; j++) {
567             char *dnbufb;
568
569             flag = 0;
570
571             dnbufb = strdup(dnbuf);
572             sprintf(dnbuf, "%s%s%s", dnarray[j], *dnbuf ? "," : "" , dnbufb);
573
574             if ( glob->gw_switch && glob->gw_switch->dynamic) {
575
576                 if ( (rc=ldap_simple_bind_s( ld, glob->webdn, glob->webpw ))
577                                                          != LDAP_SUCCESS ) {
578                     if ( debug ) ldap_perror( ld, "ldap_simple_bind_s" );
579                     do_error( fp, rc, SERVER_ERROR, glob);
580                     rewind(fp);
581                     exit_tweb( 1 );
582                 }
583
584                 timeout.tv_sec = glob->timeout;
585                 timeout.tv_usec = 0;
586
587                 if ( (rc = ldap_search_st( ld, dnbuf, LDAP_SCOPE_BASE, "objectClass=*",
588                     NULL, 0, &timeout, &res )) != LDAP_SUCCESS ) {
589 /*                    do_error(fp, rc, NOT_FOUND, glob);
590 */
591                     continue;
592                 }
593
594
595                 if ( (e = ldap_first_entry( ld, res )) == NULL ) {
596                     do_error(fp, -2, SERVER_ERROR, glob);
597                     return;
598                 }
599
600
601                 uri = ldap_get_values( ld, e, "labeledURI" );
602                 for(i=0; uri && uri[i] && *uri[i]; i++) {
603                     char *sp;
604
605                     if( ( sp = strchr(uri[i], ' ')) ) {
606                         *sp++ = '\0';
607                         if(strstr(sp, glob->gw_switch->lagws)) {
608                             flag = 1;
609                             url = uri[i];
610                             break;
611                         } else if(strstr(sp, GWS))
612                             urlnola = uri[i];
613                     }
614                 }
615             }
616             if(!flag && urlnola) {
617                 url = urlnola;
618                 flag = 1;
619             }
620             if (glob->gw_switch) {
621
622                 for(gw_ptr = glob->gw_switch->list;
623                                   !flag && gw_ptr; gw_ptr = gw_ptr->next) {
624                     if (!dn_cmp (dnbuf, gw_ptr->dn)) {
625                         flag = 1;
626                         url = gw_ptr->url;
627                     }
628                 }
629             }
630             if(strcmp(bdnarray[j], dnarray[j]))
631                 break;
632         }
633
634         if (http == 1) PRINT_HTML_HEADER;
635         fprintf( fp, HTML_HEAD_TITLE, "ACCESS DENIED", glob->la[100]);
636         disp_file(glob, glob->header, fp);
637         fprintf( fp, "%s\n", glob->la[96]);
638         url_tmp = strdup(url_complete(url, query, ""));
639         fprintf( fp, "<P><A HREF=\"%s\"><b>%s</b></A>\n",
640            url_tmp, url_tmp);
641         disp_file(glob, glob->footer, fp);
642         PRINT_HTML_FOOTER;
643         ldap_unbind (ld);
644         close_ldap_connections(glob);
645         exit_tweb(0);
646     }
647 }
648 /* end of function: strict_basednf */
649
650 PRIVATE void trade_cache(fp, ld, query, glob)
651 FILE *fp;
652 LDAP *ld;
653 char *query;
654 GLOB_STRUCT   *glob;
655 {
656     pCACHING_TERMS_LINE ca_ptr;
657     char dnbuf[BUFSIZ], rdn[BUFSIZ], *strptr;
658     char tstring[100];
659     int resflag;
660     int rc;
661     struct timeval timeout;
662     LDAPMessage *res, *e;
663     char **vals = NULL;
664
665     resflag = 0;
666     if(*query)
667         strcpy(dnbuf, query+1);
668     else
669         strcpy(dnbuf, glob->basedn->dn);
670     hex_decode(dnbuf);
671     if( ( strptr = strchr(dnbuf, '?')) )
672         *strptr = '\0';
673     strcpy(rdn, dnbuf);
674     if( ( strptr = strQuoteChr(rdn, ',')) )
675         *strptr = '\0';
676
677     for(ca_ptr = glob->caching_terms; ca_ptr; ca_ptr = ca_ptr->next) {
678         if((toupper(*query) == toupper(*ca_ptr->access_type)) ||
679             ( !*query && (toupper(*ca_ptr->access_type) == 'M'))) {
680             
681             if(ca_ptr->rdn_oc && (strstr(str_tolower(rdn), ca_ptr->pattern) ||
682                                  (*ca_ptr->pattern == '*'))) {
683                 time(&glob->expiretime);
684                 glob->expiretime += ca_ptr->time;
685                 free(glob->expiretimestr);
686                 strftime(tstring, 99, GMT_FORMAT2, gmtime(&glob->expiretime));
687                 glob->expiretimestr = strdup(tstring);
688                 glob->caching = TRUE;
689             }
690             if(!ca_ptr->rdn_oc) {
691                 if(!resflag) {
692
693                     if ( (rc=ldap_simple_bind_s( ld, glob->webdn, glob->webpw ))
694                                                          != LDAP_SUCCESS ) {
695                         if ( debug ) ldap_perror( ld, "ldap_simple_bind_s" );
696                             do_error( fp, rc, SERVER_ERROR, glob);
697                         rewind(fp);
698                         exit_tweb( 1 );
699                     }
700
701                     timeout.tv_sec = glob->timeout;
702                     timeout.tv_usec = 0;
703
704                     if ( (rc = ldap_search_st( ld, dnbuf, LDAP_SCOPE_BASE, "objectClass=*",
705                         NULL, 0, &timeout, &res )) != LDAP_SUCCESS ) {
706                         do_error(fp, rc, NOT_FOUND, glob);
707                         return;
708                     }
709
710
711                     if ( (e = ldap_first_entry( ld, res )) == NULL ) {
712                         do_error(fp, -2, SERVER_ERROR, glob);
713                         return;
714                     }
715
716
717                     vals = ldap_get_values( ld, e, "objectClass" );
718                     resflag = 1;
719                 }
720                 if(charray_inlist( vals, ca_ptr->pattern )) {
721                     time(&glob->expiretime);
722                     glob->expiretime += ca_ptr->time;
723                     free(glob->expiretimestr);
724                     strftime(tstring, 99, GMT_FORMAT2, gmtime(&glob->expiretime));
725                     glob->expiretimestr = strdup(tstring);
726                     glob->caching = TRUE;
727                 }
728             }
729
730         }
731     }
732
733 }
734 /* end of function: trade_cache */