]> git.sur5r.net Git - openldap/blob - contrib/tweb/x500.c
447060fbdef3b6a951164242d8400b9a8a774272
[openldap] / contrib / tweb / x500.c
1 /*_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
2 *                                                                          *
3 * x500.c.....                                                              *
4 *                                                                          *
5 * Function:..WorldWideWeb-X.500-Gateway - X.500-Access-Routines            *
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          ZZZZZ  DDD      V                  *
19 *                                                                          *
20 _/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_*/
21
22 /*
23  * $Id: x500.c,v 1.10 1999/09/13 13:47:48 zrnsk01 Exp $
24  *
25  */
26
27 #include "tgeneral.h"
28 #include "tglobal.h"
29 #include "x500.h"
30 #include "init_exp.h"
31 #include "support_exp.h"
32 #include "html_exp.h"
33
34 #ifdef TUE_TEL
35 #include "tueTel_exp.h"
36 #endif
37
38 #if defined( TUE_TEL ) || defined( AMBIXGW )
39 #include "resort_exp.h"
40 #endif
41
42
43 PRIVATE int compare(a,b)
44 DNLIST **a, **b;
45 {
46         return strcmp((*a)->string,(*b)->string);
47 }
48 /* end of function: compare */
49
50
51 PRIVATE char * pick_oc(oclist)
52 char **oclist;
53 {
54     int    i;
55
56     if ( oclist == NULL )
57         return( "unknown" );
58
59     for ( i = 0; oclist[i] != NULL; i++ ) {
60         if ( strcasecmp( oclist[i], "top" ) != 0 &&
61             strcasecmp( oclist[i], "quipuObject" ) != 0 &&
62             strcasecmp( oclist[i], "quipuNonLeafObject" ) != 0 )
63             return( str_tolower (oclist[i]) );
64     }
65
66     return( "unknown" );
67 }
68 /* end of function: pick_oc */
69
70
71 PUBLIC char * make_oc_to_string(oc)
72 char **oc;
73 {
74     static char oc_res[BUFSIZ];
75     int i;
76
77     if(!oc) return(NULL);
78
79     *oc_res = '|';
80     *(oc_res+1) = '\0';
81     for(i = 0; oc[i] && *oc[i]; i++) {
82         sprintf(oc_res, "%s%s|", oc_res, oc[i]);
83     }
84     return(str_tolower (oc_res));
85 }
86 /* end of function: make_oc_to_string */
87
88
89 PUBLIC void do_xtend(ld, fp, query, filter, glob)
90 LDAP *ld;
91 FILE *fp;
92 char *query;
93 char *filter;
94 GLOB_STRUCT *glob;
95 {
96     char *strptr, dn[BUFSIZ], command[BUFSIZ], extension[BUFSIZ];
97
98     strptr = strchr(query, '?');
99     *strptr++ = '\0';
100     strcpy(dn, query);
101     strcpy(command, strptr);
102     if( ( strptr = strchr(command, '#')) ) {
103         *strptr++ = '\0';
104         strcpy(extension, strptr);
105     }
106     
107     if(!strcasecmp(command, "MENU")){
108         glob->tables_marker = strdup(extension);
109         do_menu(ld, fp, dn, "", glob);
110     }
111     
112 #ifdef TUE_TEL
113     if(!strcasecmp(command, "PHONEBOOK")){
114         do_phonebook(ld, fp, strstr(dn, "ou=TELEFONBUCH") ? dn
115                              : NULL, extension, glob, 1);
116     }
117 #endif
118
119 }
120 /* end of function: do_xtend */
121
122 PUBLIC void do_menu(ld, fp, dn, filter, glob)
123 LDAP *ld;
124 FILE *fp;
125 char *dn;
126 char *filter;
127 GLOB_STRUCT *glob;
128 {
129     int             rc;
130     LDAPMessage     *pres;
131     struct timeval  timeout;
132     static char     *sattrs[] = { "objectClass", "labeledURI",
133                                      "aliasedObjectName", "mail",
134                                      "cn", "telephonenumber",
135 #ifdef TUE_TEL
136                                      "tat_ton", "tat_refphone",
137 #endif
138                                      0 };
139     static char **attrs = NULL;
140     int counter = 0;
141     pSEARCH_ONLY_LINE so_ptr;
142     char        la_url[BUFSIZ];
143     int count;
144     char           *ufn;
145
146 #if OL_LDAPV > 0
147         int         ldap_opt;
148 #endif
149
150     if(!attrs)
151         attrs = (char**) charray_dup(sattrs);
152
153     charray_merge(&attrs, glob->sort_attribs);
154
155     if(glob->raw_data)
156         charray_merge(&attrs, glob->raw_attrs);
157
158     for(so_ptr = glob->search_only; so_ptr; so_ptr = so_ptr->next) {
159         if (dn_cmp(dn, so_ptr->dn) == 0) {
160             break;
161         }
162     }
163
164     if(!so_ptr) {
165
166         timeout.tv_sec = glob->timeout;
167         timeout.tv_usec = 0;
168
169 #if OL_LDAPV > 0
170
171                 ldap_opt = LDAP_DEREF_FINDING;
172         ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
173
174 #else
175         ld->ld_deref = LDAP_DEREF_FINDING;
176 #endif
177
178         if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_ONELEVEL,
179             glob->menu_filter, attrs, 0, &timeout, &pres )) != LDAP_SUCCESS
180             && rc != LDAP_SIZELIMIT_EXCEEDED 
181                 && rc != LDAP_INSUFFICIENT_ACCESS ) {
182             do_error(fp, rc, NOT_FOUND, glob);
183             return;
184         }
185
186         if (rc == LDAP_SIZELIMIT_EXCEEDED) glob->persRestricted = TRUE;
187
188 #if OL_LDAPV > 0
189
190                 ldap_opt = LDAP_DEREF_ALWAYS;
191         ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
192
193 #else
194         ld->ld_deref = LDAP_DEREF_ALWAYS;
195 #endif
196
197         if ((count = (ldap_count_entries(ld, pres) )) < 1) {
198             ldap_msgfree (pres);
199             do_read (ld, fp, dn, 0, glob);
200             return;
201         }
202         items_displayed = count;
203     }
204
205     if (http == 1) {
206         PRINT_HTML_HEADER;
207     }
208     if (request == HEAD) {
209         fflush(fp);
210         exit_tweb (1);
211     }
212     fprintf( fp, HTML_HEAD_TITLE, ufn = friendly_dn(dn, glob), glob->la[100]);
213     if ( ufn ) free( ufn );
214
215     if (dn_cmp(dn, glob->basedn->dn) == 0)
216         disp_file(glob, glob->basedn->head, fp);
217     else if(so_ptr && so_ptr->head)
218         disp_file(glob, so_ptr->head, fp);
219     else
220         disp_file(glob, glob->header, fp);
221
222 #ifdef TUE_TEL
223     fprintf (fp, "\n<A NAME=\"phonebook=Telefonbuch\"></A>\n");
224     fprintf (fp, "\n<A NAME=\"phonebook\"></A>\n");
225 #endif
226
227     make_la_buttons("M", fp, ld, dn, la_url, glob );
228
229     make_header( fp, dn, 0, glob);
230
231     print_rdn(fp, dn, glob);
232
233     make_search_box(fp, ld, dn, glob);
234
235 #ifdef AMBIXGW
236     /* Button leading to cgi-script */
237     if( glob->form_button && !glob->selbsteintrag[0]){
238         char  **oc;
239         LDAPMessage    *res;
240         struct timeval    timeout;
241         static char    *attrs[] = { "objectClass", 0 };
242
243         timeout.tv_sec = glob->timeout;
244         timeout.tv_usec = 0;
245         if ( ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
246             attrs, 0, &timeout, &res ) != LDAP_SUCCESS ) {
247             exit_tweb( 1 );
248         }
249         oc = ldap_get_values( ld, ldap_first_entry( ld, res ), "objectClass" );
250
251         disp_form_button(0, oc, dn, ld, fp, glob);
252     }
253
254     /* check to see if selfinsert-buttons are appropriate here */
255     if(glob->selbsteintrag[0])
256         self_insert(ld,fp,dn,glob);
257 #endif
258
259 #ifdef TUE_TEL
260     /* Named link to skip header */
261     fprintf (fp, "\n<A NAME=\"pure-data\"></A>\n");
262 #endif
263
264     fprintf(fp, glob->la[101]);
265
266
267     if(!so_ptr) {
268
269         /*  DO_MENU  */
270         counter = sort_result( ld, pres, dn, glob);
271
272         /* get time for performance log */
273         gettimeofday(&timestore[4], NULL);
274
275         list_output(fp, glob);
276
277         if ( ldap_result2error( ld, pres, 1 ) == LDAP_SIZELIMIT_EXCEEDED
278             || glob->restricted )
279             do_sizelimit(fp, 1, glob);
280
281         if(glob->legal && !glob->legal_top)
282             fprintf (fp, "%s\n%s\n", glob->la[101],
283                             glob->is_proxy ? glob->la[104] : glob->la[65]);
284     }
285
286     if (dn_cmp(dn,glob->basedn->dn) == 0)
287         disp_file(glob, glob->basedn->foot, fp);
288     else if(so_ptr && so_ptr->foot)
289         disp_file(glob, so_ptr->foot, fp);
290     else
291         disp_file(glob, glob->footer, fp);
292
293     PRINT_HTML_FOOTER;
294 }
295 /* end of function: do_menu */
296
297
298 PRIVATE int make_scope(ld, dn, glob)
299 LDAP *ld;
300 char *dn;
301 GLOB_STRUCT *glob;
302 {
303     int        scope, idx;
304     char        **oc;
305     LDAPMessage    *res;
306     struct timeval    timeout;
307     static char    *attrs[] = { "objectClass", 0 };
308
309     if ( strcmp( dn, "" ) == 0 )
310         return( LDAP_SCOPE_ONELEVEL );
311
312     timeout.tv_sec = glob->timeout;
313     timeout.tv_usec = 0;
314     if ( ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
315         attrs, 0, &timeout, &res ) != LDAP_SUCCESS ) {
316         return( -1 );
317     }
318
319     oc = ldap_get_values( ld, ldap_first_entry( ld, res ), "objectClass" );
320
321     /* set scope according to configured object-classes */
322     scope = LDAP_SCOPE_ONELEVEL;
323     for(idx = 0; glob->subtree_search && glob->subtree_search[idx]; idx++)
324         if( charray_inlist( oc, glob->subtree_search[idx]))
325             scope = LDAP_SCOPE_SUBTREE;
326
327     ldap_value_free( oc );
328     ldap_msgfree( res );
329
330     return( scope );
331 }
332 /* end of function: make_scope */
333
334 PUBLIC int do_search(ld, fp, query, glob)
335 LDAP *ld;
336 FILE *fp;
337 char *query;
338 GLOB_STRUCT *glob;
339 {
340     int        scope;
341     char        *base, *filter, *strptr;
342     char        *filtertype;
343     int        count = 0, rc;
344     struct timeval    timeout;
345     LDAPFiltInfo    *fi;
346     LDAPMessage    *e, *res = NULL;
347     static char    *attrs[] = { "objectClass", "cn", "sn", "labeledURI", 
348                                  "aliasedObjectName", 0 };
349     int        counter = 0;
350     char               *ufn;
351     char title[BUFSIZ], title2[BUFSIZ];
352
353 #if OL_LDAPV > 0
354         int         ldap_opt;
355 #endif
356
357     glob->no_browse = FALSE;
358     
359 /* query string: base-DN?[OS]=filter 
360  *     search onelevel <--||--> search subtree 
361  */
362     if ( (filter = strchr( query, '?' )) == NULL ) {
363         explain_error( fp, glob->la[89], BAD_REQUEST, glob );
364         exit_tweb( 1 );
365     }
366     *filter++ = '\0';
367     if (*filter == '\0' || *(filter+1) != '=') {
368         explain_error( fp, glob->la[90], BAD_REQUEST, glob);
369         exit_tweb( 1 );
370     }
371     if( ( strptr = strchr(filter, '&')) )
372         *strptr = '\0';
373     if( ( strptr = strchr(filter, '*')) )
374         *strptr = '\0';
375     if (*filter == 'S') {
376         scope = LDAP_SCOPE_SUBTREE;
377     } else {
378         scope = LDAP_SCOPE_ONELEVEL;
379     }
380     filter += 2;
381     if (*filter == '\0') {
382         explain_error( fp, glob->la[92], BAD_REQUEST, glob);
383         exit_tweb( 1 );
384     }
385     /* deutsche Umlaute plaetten */
386     filter = flatten_chars(filter);
387
388     base = query;
389
390     filtertype = (scope == LDAP_SCOPE_ONELEVEL ? "web500gw onelevel" :
391         "web500gw subtree");
392
393 #if OL_LDAPV > 0
394
395                 ldap_opt = ( scope == LDAP_SCOPE_ONELEVEL ? LDAP_DEREF_FINDING :
396                                                  LDAP_DEREF_ALWAYS );
397         ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
398
399 #else
400     ld->ld_deref = (scope == LDAP_SCOPE_ONELEVEL ? LDAP_DEREF_FINDING :
401                                                   LDAP_DEREF_ALWAYS);
402 #endif
403
404     timeout.tv_sec = glob->timeout;
405     timeout.tv_usec = 0;
406
407     for (fi=ldap_getfirstfilter( filtd, filtertype, filter ); fi != NULL;
408         fi = ldap_getnextfilter( filtd ) ) {
409         if ( (rc = ldap_search_st( ld, base, scope, fi->lfi_filter,
410             attrs, 0, &timeout, &res )) != LDAP_SUCCESS
411             && rc != LDAP_SIZELIMIT_EXCEEDED ) {
412
413             if (dosyslog) {
414
415 #if OL_LDAPV > 0
416
417                 int ld_errno;
418
419                 ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ld_errno);
420                 syslog (LOG_INFO, "ldap_search_st(): %s",
421                     ldap_err2string ( ld_errno ));
422
423 #else
424                 syslog (LOG_INFO, "ldap_search_st(): %s",
425                     ldap_err2string (ld->ld_errno));
426 #endif
427
428             }
429
430             do_error(fp, rc, NOT_FOUND, glob);
431             return( 1 );
432         }
433
434         if ( res && (count = ldap_count_entries( ld, res )) != 0 ) {
435
436             break;
437         }
438
439     }
440     items_displayed = count;
441
442 #if OL_LDAPV > 0
443
444                 ldap_opt = LDAP_DEREF_ALWAYS;
445         ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
446
447 #else
448     ld->ld_deref = LDAP_DEREF_ALWAYS;
449 #endif
450
451     if ( count == 0 ) {
452
453         if (http == 1) {
454             fprintf(fp, "HTTP/1.0 404 %s \n", glob->la[6]); 
455                         fprintf(fp, "MIME-Version: 1.0\n");
456                         fprintf(fp, "Content-Type: text/html\n\n");
457         }
458
459         if (request == HEAD) {
460             fflush(fp);
461             exit_tweb (1);
462         }    
463
464         sprintf( title, "%s %s", filter, glob->la[36]);
465         fprintf( fp, HTML_HEAD_TITLE, title, glob->la[100]);
466
467         disp_file(glob, glob->header, fp);
468
469         fprintf( fp,
470  "<H2>%s</H2> %s <STRONG>%s</STRONG> in <STRONG>%s</STRONG></BODY></HTML>\n\n",
471                      glob->la[37], glob->la[38], filter, 
472                      (strlen(base) == 0) ? glob->la[77] : ldap_dn2ufn(base));
473                 fflush(fp);
474         return( 0 );
475     }
476     else if ( count == 1 ) {
477         e = ldap_first_entry( ld, res );
478         if ( e != NULL ) {
479             char *dn, **oc;
480             oc = ldap_get_values(ld, e, "objectClass");
481             dn = ldap_get_dn(ld, e);
482             if ( dn ) {
483
484                 /* GW-Switch if one search-result and dyn-URL by
485                    PRINT_REDIRECT_HEADER */
486         if ( glob->gw_switch->dynamic) {
487                     char **uri, query[10*BUFSIZ];
488                     int j;
489
490                     uri = ldap_get_values( ld, e, "labeledURI" );
491                     for(j=0; uri && uri[j] && *uri[j]; j++) {
492                         char *sp;
493
494                         if( ( sp = strchr(uri[j], ' ')) ) {
495                             *sp++ = '\0';
496                             if(strstr(sp, glob->gw_switch->lagws)) {
497                                 /*sprintf(query, "%s/M%s", uri[j], dn);*/
498                                 strcpy(query, uri[j]);
499                                 hex_decode(query);
500                                 PRINT_REDIRECT_HEADER;
501                                 PRINT_HTML_FOOTER;
502                                 exit_tweb(0);
503                             }
504                         }
505                     }
506                 }
507                 /* By default on one result: */
508                 do_menu(ld, fp, dn, "", glob);
509                 return (0);
510             }
511         }
512     }
513
514     if (http == 1)
515         PRINT_HTML_HEADER;
516     if (request == HEAD) {
517         fflush(fp);
518         exit_tweb (1); 
519         }
520
521     sprintf( title2, "%s %s", glob->la[39], filter);
522     fprintf( fp, HTML_HEAD_TITLE, title2, glob->la[100]);
523
524     disp_file(glob, glob->header, fp);
525
526     ufn = friendly_dn(base, glob);
527     fprintf( fp, "%s <STRONG>\"%s\"</STRONG> in <STRONG>\"%s\"</STRONG> ",
528                  glob->la[40], filter, ufn );
529     if ( ufn ) free( ufn );
530
531     if(!glob->noauth)
532         fprintf( fp, "(%d %s)<br>", count, 
533                          count == 1 ? glob->la[70] : glob->la[71]);
534
535       /*  DO_SEARCH  */
536       counter = sort_result( ld, res, base, glob);
537
538       /* get time for performance log */
539       gettimeofday(&timestore[4], NULL);
540
541      list_output(fp, glob);
542
543     if ( ldap_result2error( ld, res, 1 ) == LDAP_SIZELIMIT_EXCEEDED )
544         do_sizelimit(fp, 0, glob);
545
546     if(glob->legal && !glob->legal_top)
547         fprintf (fp, "%s\n%s\n", glob->la[101],
548                             glob->is_proxy ? glob->la[104] : glob->la[65]);
549     
550     disp_file(glob, glob->footer, fp);
551
552     PRINT_HTML_FOOTER;
553
554     return( 0 );
555
556 }
557 /* end of function: do_search */
558
559
560 PRIVATE pDISPLAY
561 find_dPtr( displayList, displayType )
562 pDISPLAY   displayList;
563 char      *displayType;
564 {
565     pDISPLAY  dis;
566
567     for ( dis = displayList; dis; dis = dis->next ) {
568
569         if ( !strcasecmp( dis->ocs, displayType )) return( dis );
570
571     }
572
573     return( NULL );
574
575 }  /*  find_dPtr  */
576
577
578 PUBLIC void do_read(ld, fp, dn, amore, glob)
579 LDAP *ld;
580 FILE *fp;
581 char *dn;
582 int amore;
583 GLOB_STRUCT *glob;
584 {
585     int        rc, j;
586     char        **val, **s;
587     char        *rdn;
588     LDAPMessage    *res, *e;
589     struct timeval    timeout;
590     int        classFound;
591     pDISPLAY    d_ptr = NULL;
592     pDISPLAY_LINE    dis_ptr = NULL;
593     SORT_LINE *s_ptr;
594     char            la_url[BUFSIZ];
595     char      *ufn;
596     char already_displayed[BUFSIZ];
597     int header_attr_mode = 0;
598
599 #if defined( TUE_TEL ) || defined( AMBIXGW )
600         char      *parentDN;
601 #endif
602
603
604     *already_displayed = ':';
605     *(already_displayed+1) = '\0';
606
607
608     timeout.tv_sec = glob->timeout;
609     timeout.tv_usec = 0;
610
611
612     if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
613         NULL, 0, &timeout, &res )) != LDAP_SUCCESS ) {
614         do_error(fp, rc, NOT_FOUND, glob);
615         return;
616     }
617
618
619     if ( (e = ldap_first_entry( ld, res )) == NULL ) {
620         do_error(fp, -2, SERVER_ERROR, glob);
621         return;
622     }
623
624     val = ldap_get_values( ld, e, "objectClass" );
625
626 #if defined( TUE_TEL ) || defined( AMBIXGW )
627     /* toc_derefalias: read entry, aliasedObjectName is referring to */
628     if(charray_inlist(val, "toc_derefalias")){
629         char **new_dn;
630
631         new_dn = ldap_get_values( ld, e, "aliasedObjectName" );
632         if(new_dn && new_dn[0]) {
633             do_read(ld, fp, new_dn[0], amore, glob);
634             return;
635         }
636     }
637
638     /*  before displaying check for dynamic changes of the sorting parms  */
639         parentDN = get_parentDN( dn );
640     dynamicResort( ld, glob, parentDN );
641 #endif
642
643         /* 
644          * check for objectClass via displayLists-Table which List
645          * of attributes we want to use.
646          */
647     classFound = -1;
648     for(s_ptr = glob->sort; s_ptr; s_ptr = s_ptr->next) {
649                 char   buf[BUFSIZ];
650
651         d_ptr = s_ptr->display_class_ptr;
652
653         for( j=0; val[j]; j++ ) {
654             sprintf( buf, "|%s|", str_tolower( val[j] ));
655
656             if ( strstr( s_ptr->object_class, buf )) {
657                  classFound = 1;
658                  break;
659             }
660         }
661         if (classFound == 1) break;
662     }
663
664 #if defined( TUE_TEL ) || defined( AMBIXGW )
665     dynamicDisplay( ld, glob, parentDN,
666                             s_ptr ? s_ptr->display_class : "default" );
667 #endif
668
669     if((classFound == -1) && (glob->default_display_type)) {
670         d_ptr = glob->default_display_type;
671         classFound = 1;
672     }
673
674     /* if we did not find a fitting objectClass, simply return */
675     if(classFound == -1) {
676
677         fprintf( fp, HTML_HEAD_TITLE, glob->la[22], glob->la[100]);
678         fprintf( fp, "\n%s</BODY></HTML>", glob->la[41]);
679         return;
680     }
681
682     /*  is the display description defined already  */
683     if ( !d_ptr && (( d_ptr = find_dPtr( glob->display,
684                                 s_ptr->display_class )) == NULL )) {
685
686         if ( dosyslog )
687             syslog( LOG_INFO,
688                     "do_read(%08d): couldn't find display type <%s> -- FATAL.",
689                     glob->svc_cnt, s_ptr->display_class );
690
691         fprintf( fp, HTML_HEAD_TITLE, glob->la[22], glob->la[100]);
692         fprintf( fp, "\n%s</BODY></HTML>", glob->la[41]);
693         return;
694
695     }
696
697     /*  now we can point to the final display screen  */
698     dis_ptr = ( amore ? d_ptr->second_page : d_ptr->first_page );
699
700     if (http == 1) PRINT_HTML_HEADER;
701     if (request == HEAD) {                
702         fflush(fp);
703         exit_tweb (1);
704     }
705
706     dn = ldap_get_dn( ld, e );
707
708         if ( strcmp( dn, "" ) != 0 ) {  /* Not the root */
709         s = ldap_explode_dn( dn, 1 );
710                 if ( s[1] == NULL )   /* toplevel */
711             rdn = ldap_friendly_name( glob->friendlyfile, s[0], &fm );
712         else 
713             rdn = s[0];
714     } else
715         rdn = glob->la[77];
716
717     fprintf( fp, HTML_HEAD_TITLE, ufn = friendly_dn( dn, glob ),
718                                     glob->la[100] );
719     if ( ufn ) free( ufn );
720
721     disp_file(glob, glob->header, fp);
722
723     if ( !glob->ldap_referral_mode ) {
724
725         make_la_buttons("R", fp, ld, dn, la_url, glob);
726         make_header( fp, dn, 0, glob );
727     } else {
728         fprintf( fp, glob->la[105]);
729     }
730     fprintf( fp, "<DL>");
731
732     fprintf( fp, glob->la[101]);
733
734     /* don't display rdn if first attribute is in header-mode */
735     if ( dis_ptr->ty == HEADER )
736         header_attr_mode = 1;
737     if( ( dis_ptr && !header_attr_mode ) || !dis_ptr ) {
738         if(glob->strip_pin && strstr(glob->strip_pin, d_ptr->ocs)) {
739             char rdnstriped[BUFSIZ];
740
741             strcpy( rdnstriped, rdn);
742             trimright (rdnstriped, " 1234567890");
743             fprintf( fp, "<H1>%s</H1>", rdnstriped );
744         } else
745             fprintf( fp, "<H1>%s</H1>", rdn);
746     }
747
748     if(glob->ind_attrs)
749         get_ref_attrs( ld, dn, e, glob );
750
751     /* get time for performance log */
752     items_displayed = 1;
753     gettimeofday(&timestore[4], NULL);
754
755     if ( header_attr_mode )
756         rdn = NULL;
757
758     for( ; dis_ptr; dis_ptr = dis_ptr->next) {
759
760         if(glob->ind_attrs){
761
762             int n, m, iatlabel=0, replace=0;
763             IND_ATTR_ARR *vnodes;
764
765 #ifdef TUE_TEL
766             int retcode = 0;
767
768             /* Function Mode */
769             retcode = displayTueRefPhone( ld, fp, dn, dis_ptr,
770                         e, rdn, glob, already_displayed );
771 #endif
772             if(strstr(already_displayed, dis_ptr->label)) {
773                 continue;
774             }
775
776             vnodes = glob->ind_attrs->valid_nodes;
777
778             for(n=0; vnodes && vnodes[n].key && *(vnodes[n].key) ;  n++) {
779
780                 if(!strcasecmp(vnodes[n].attr, dis_ptr->attribute)) {
781
782                     for(m=0; vnodes[n].e[m];  m++)
783                         print_attr( vnodes[n].ld, fp, dn,
784                                m==0 ? dis_ptr->label : "", dis_ptr->attribute,
785                                vnodes[n].e[m], dis_ptr->ty, rdn, glob);
786
787                     iatlabel = 1;
788                     if(vnodes[n].replace)
789                         replace=1;
790
791                 }
792
793             }
794             if( iatlabel && !replace)
795                 print_attr( ld, fp, dn, "",
796                    dis_ptr->attribute, e, dis_ptr->ty, rdn, glob);
797
798             if(!iatlabel)
799                 print_attr( ld, fp, dn, dis_ptr->label,
800                    dis_ptr->attribute, e, dis_ptr->ty, rdn, glob);
801
802         } else {
803             print_attr( ld, fp, dn, dis_ptr->label,
804                dis_ptr->attribute, e, dis_ptr->ty, rdn, glob);
805         }
806     }
807
808
809     if ( !amore && d_ptr && d_ptr->second_page ) {
810
811         fprintf( fp, "</DL><A HREF=\"/L%s\"><B>%s</B></A>\n",
812                      hex_encode(dn), glob->la[42]);
813
814
815     }
816     fprintf( fp, "</DL>\n");
817
818     if (strcasecmp(dn + strlen(dn) - strlen(glob->basedn->dn),
819             glob->basedn->dn) == 0) {
820
821         pMODIF  p_mod;
822         char   *aoc;
823         char  **oc;
824
825         aoc = make_oc_to_string(oc = ldap_get_values( ld, e, "objectClass" ));
826
827         if(!strlstcmp (aoc, glob->no_modify, '|')) {
828           for (p_mod = glob->modify; aoc && p_mod; p_mod = p_mod->next) {
829             if (strlstcmp (aoc, p_mod->ocs, '|')) {
830                 fprintf( fp, "%s<TT>%s</TT><P><FORM ACTION=\"F%s\">\n",
831                               glob->la[101], glob->la[43], hex_encode(dn));
832                 fprintf (fp, "%s <INPUT TYPE=\"password\" ",
833                               glob->la[44]);
834                 fprintf (fp, "NAME=\"userPassword\"><BR>%s  ",
835                               glob->la[45]);
836                 fprintf (fp, "<INPUT TYPE=\"submit\" VALUE=\"%s\">",
837                               glob->la[47]);
838                 fprintf (fp, " %s. </FORM>\n",
839                               glob->la[48]);
840                 break;
841             }
842           }
843         }
844
845         ldap_value_free( oc );
846
847     }
848
849     /* Button leading to cgi-script */
850     if( glob->form_button ){
851         char  **oc;
852
853         oc = ldap_get_values( ld, e, "objectClass" );
854         disp_form_button(1, oc, dn, ld, fp, glob);
855     }
856
857     disp_file(glob, glob->footer, fp);
858
859     PRINT_HTML_FOOTER;
860
861 }
862 /* end of function: do_read */
863
864 PRIVATE void disp_form_button(read_menu, oc, dn, ld, fp, glob)
865 int read_menu;
866 char  **oc;
867 char *dn;
868 LDAP *ld;
869 FILE *fp;
870 GLOB_STRUCT *glob;
871 {
872     pFORM_BUTTON fo_ptr;
873     char dn_used[BUFSIZ], button_label[BUFSIZ];
874
875 #ifdef AMBIXGW
876     char *who_val;
877     char  **selfInsertWho = NULL;
878     char  **studie = NULL;
879     int selfInsReadFlag = 0;
880 #endif
881
882     for(fo_ptr = glob->form_button; fo_ptr; fo_ptr = fo_ptr->next) {
883         if(read_menu != fo_ptr->read_menu ||
884                      ( !charray_inlist(oc, fo_ptr->object_class)
885                        && strncasecmp( "cn=", fo_ptr->object_class, 3 ) ) )
886             continue;
887         strcpy(dn_used, dn);
888         strcpy(button_label, fo_ptr->button_label);
889
890 #ifdef AMBIXGW
891         /* new-AMBIX cn=Selbst-Eintrag etc. support */
892         /* object-class field contains here cn=xyz e.g. cn=Selbst-Eintrag */
893         if ( !strncasecmp( "cn=", fo_ptr->object_class, 3 )) {
894             char dn_buf[BUFSIZ];
895             LDAPMessage    *res, *e;
896             struct timeval    timeout;
897             static char    *attrs[] = { "objectClass", "selfInsertWho",
898                                          "studie", 0 };
899
900             /* cn=Selbsteintrag nur einmal lesen */
901             if (!selfInsReadFlag ) {
902                 selfInsReadFlag = 1;
903
904                 timeout.tv_sec = glob->timeout;
905                 timeout.tv_usec = 0;
906
907                 sprintf(dn_buf, "%s,%s", fo_ptr->object_class, dn);
908                 if (ldap_search_st( ld, dn_buf, LDAP_SCOPE_BASE, "objectClass=*",
909                     attrs, 0, &timeout, &res ) != LDAP_SUCCESS )
910                         continue;
911                 if(( e = ldap_first_entry( ld, res )) == NULL )
912                         continue;
913
914                 selfInsertWho = ldap_get_values( ld, e, "selfInsertWho" );
915                 studie = ldap_get_values( ld, e, "studie" );
916             }
917
918             if ( (who_val = strchr(button_label, '|')))
919                 *who_val++ = '\0';
920
921             if ( !who_val )
922                 continue;
923
924             if ( !selfInsertWho || !selfInsertWho[0] )
925                         continue;
926
927             /* exception for all + studiedn != dn -> two buttons stud + ang */
928             if ( strcasecmp(selfInsertWho[0], who_val ) &&
929                  !(!strcasecmp(selfInsertWho[0], "all") && studie && studie[0] && dn_cmp(dn, studie[0]) && strcasecmp(who_val, "all")))
930                         continue;
931
932             /* filter for exception all-button */
933             if( studie && studie[0] && dn_cmp(dn, studie[0]) && !strcasecmp(selfInsertWho[0], "all") && !strcasecmp(who_val, "all") )
934                         continue;
935
936             if(!strcasecmp(who_val, "stud" ) && studie && studie[0]
937                && dn_cmp(dn, studie[0]))
938                 strcpy(dn_used, studie[0]);
939         }
940 #endif
941
942         fprintf (fp, "<FORM METHOD=%s ACTION=%s>\n", fo_ptr->method,
943                       fo_ptr->script_url);
944         fprintf (fp, "%s\n<INPUT type=hidden name=\"%s\" value=\"%s\">\n",
945                       fo_ptr->text, fo_ptr->dn_name, hex_encode(dn_used));
946         fprintf (fp, "<INPUT TYPE=\"submit\" name=\"%s\" value=\"%s\">\n",
947                       fo_ptr->form_name, button_label);
948         fprintf (fp, "</FORM>\n");
949     }
950 }
951 /* end of function: disp_form_button */
952
953
954 PUBLIC void do_form(ld, fp, query, glob)
955 LDAP *ld;
956 FILE *fp;
957 char *query;
958 GLOB_STRUCT *glob;
959 {
960         int             rc, count;
961         char            *dn = query, *pw;
962         char            *ufn;
963         char            *a;
964         LDAPMessage     *res, *e;
965         struct timeval  timeout;
966         pMODIFY_LINE mod_ptr;
967         char title[BUFSIZ];
968
969
970         if ( (pw = strchr( dn, '?' )) == NULL ) {
971                 fprintf( fp, "%s<br>", glob->la[49]);
972                 exit_tweb( 1 );
973         }
974         *pw++ = '\0';
975         if (strncmp(pw, "userPassword=", 13) == 0)
976                 pw += 13;
977         else {
978                 fprintf( fp, "%s %s!<br>", glob->la[50], pw);
979                 exit_tweb ( 1 );
980         }
981     if (strlen(pw) == 0) {
982         /* we need a password for simple auth */
983         do_error( fp, LDAP_INVALID_CREDENTIALS, FORBIDDEN, glob);
984         rewind(fp);
985         exit_tweb( 1 );
986     }
987         if ( (rc = ldap_simple_bind_s( ld, dn, pw )) != LDAP_SUCCESS ) {
988                 if ( debug ) ldap_perror( ld, "ldap_simple_bind_s" );
989                 do_error( fp, rc, FORBIDDEN, glob);
990                 return;
991         }
992         if (debug) fprintf(stderr, "BOUND as %s\n", dn);
993         timeout.tv_sec = glob->timeout;
994         timeout.tv_usec = 0;
995         if ( (rc = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
996             0, 0, &timeout, &res )) != LDAP_SUCCESS ) {
997                 do_error(fp, rc, NOT_FOUND, glob);
998                 return;
999         }
1000         if ( (e = ldap_first_entry( ld, res )) == NULL ) {
1001                 do_error(fp, -2, SERVER_ERROR, glob);
1002                 return;
1003         }
1004         dn = ldap_get_dn( ld, e );
1005         ufn = ldap_dn2ufn( dn );
1006         if (http == 1) {
1007         PRINT_HTML_HEADER;
1008         }
1009     sprintf( title, "%s %s", glob->la[51], ufn );
1010     fprintf( fp, HTML_HEAD_TITLE, title, glob->la[100] );
1011
1012     disp_file(glob, glob->header, fp);
1013
1014         fprintf( fp, "<FORM ACTION=\"Y%s\">\n<INPUT TYPE= \"radio\" ", hex_encode(dn));
1015         fprintf( fp, "NAME=\"oldPassword\" VALUE=\"%s\" CHECKED><TT>%s</TT>\n<H1>%s</H1><DL><br>", hex_encode(pw), glob->la[53], ufn );
1016         free( ufn );
1017     for(mod_ptr = glob->modify->modattr; mod_ptr; mod_ptr = mod_ptr->next){
1018         a = mod_ptr->attribute;
1019         count = mod_ptr->count;
1020                 if ( strcmp( a, "homepostaladdress" ) == 0
1021                     || strcmp( a, "postaladdress" ) == 0) 
1022             if (count == 0)
1023                             print_attr(ld,fp,dn,mod_ptr->label,a,e,MULTILINE,NULL, glob);
1024             else
1025                             form_attr(ld,fp,mod_ptr->label,a,e,1,count, glob);
1026                 else if (count == 0)
1027                     print_attr( ld, fp, dn, mod_ptr->label, a, e, DEFAULT, NULL, glob);
1028         else
1029                     form_attr( ld, fp, mod_ptr->label, a, e, 0, count, glob );
1030     }
1031         fprintf( fp, "</DL><InPut TYPE=\"reset\" VALUE=\"%s\"> ", glob->la[72]);
1032         fprintf( fp, "<InPut TYPE=\"submit\" VALUE=\"%s\">", glob->la[47]);
1033         fprintf( fp, "</FORM>");
1034
1035     disp_file(glob, glob->footer, fp);
1036
1037         PRINT_HTML_FOOTER;
1038     fflush(fp);
1039 }
1040 /* end of function: do_form */
1041
1042
1043 PUBLIC void do_modify(ld, fp, query, glob)
1044 LDAP    *ld;
1045 FILE *fp;
1046 char *query;
1047 GLOB_STRUCT *glob;
1048 {
1049     char *dn, *ufn, *pw, *what, *next, *val, *oldval, *cp;
1050     int     rc, changes = 0, delete_flag;
1051     static char    *value1[2], *value2[2];
1052     static LDAPMod mod1, mod2;
1053     static LDAPMod *mods[3] = { &mod1 , &mod2, NULL};
1054     char title[BUFSIZ];
1055
1056 /*  Patch: we can't run the modification of attributes in two distinct steps,
1057        since inheritage might copy a value into the entry after deletion
1058        of the old value
1059
1060     /KSp, 95/07/13
1061 */
1062
1063
1064     /* query: DN?oldPassword=oldpw&att1=oldval1=val1&att2=oldval2=val2&...
1065      * or:    DN?oldPassword=oldpw&att1%3Doldval1=val1&att2%3Doldval2=... 
1066      */
1067
1068     dn = query;
1069     rewind(fp);
1070
1071         if ( (what = strchr( dn, '?' )) == NULL ) {
1072                 explain_error( fp, glob->la[93], BAD_REQUEST, glob );
1073                 exit_tweb( 1 );
1074         }
1075         *what++ = '\0';
1076         hex_decode(dn);
1077         if (debug) fprintf(stderr, "What: %s\n", what);    
1078     /* At first there should be the old userPassword */
1079     if ( (pw = strstr( what, "oldPassword")) == NULL ) {
1080         explain_error( fp, glob->la[94], BAD_REQUEST, glob);
1081         exit_tweb ( 1 );
1082     }
1083         pw += 12;        /* strlen("oldPassword") + 1 */
1084     /* skip to the first real attribute */
1085     if ( (what = strchr(pw, '&'))  == NULL ) {
1086         explain_error( fp, glob->la[95], BAD_REQUEST, glob);
1087         exit_tweb( 1 );
1088     }
1089     *what++ = '\0';
1090     hex_qdecode(pw);
1091     if (debug) fprintf(stderr, 
1092          "\ndo_modify: DN = %s PW = #######  CONTENT =\n%s\n ", dn, what );
1093     if ( (rc = ldap_simple_bind_s( ld, dn, pw )) != LDAP_SUCCESS ) {
1094             if ( debug ) ldap_perror( ld, "ldap_simple_bind_s" );
1095             do_error( fp, rc, FORBIDDEN, glob);
1096             exit_tweb( 1 );
1097     }
1098     if (debug) fprintf(stderr, "BOUND as %s.\n", dn);
1099
1100     if (http == 1) {
1101         PRINT_HTML_HEADER;
1102     }
1103
1104     if (request == HEAD) {
1105         fflush(fp);
1106         exit_tweb (1);
1107     }
1108     ufn = ldap_dn2ufn( dn );
1109     sprintf( title, "%s %s", glob->la[8], ufn);
1110     fprintf(fp, HTML_HEAD_TITLE, title, glob->la[100]);
1111
1112     disp_file(glob, glob->header, fp);
1113
1114     fprintf(fp, "<H2>%s %s</H2>%s<DL>\n", glob->la[9],  ufn, glob->la[10]);
1115     free(ufn);
1116
1117         while (what) {
1118                 if ((next = strchr(what, '&')) != NULL) {
1119             *next++ = '\0';
1120         } else {    /* last in query */
1121             next = NULL;
1122         }
1123         if ((val = strrchr(what, '=')) == NULL) {
1124             /* new value */
1125             fprintf( fp, "<P>%s ", glob->la[54]);
1126                         fprintf( fp, "%s %s!<P>", glob->la[55], hex_qdecode(what));
1127             exit_tweb (1);
1128         }
1129         *val++ = '\0';
1130         hex_qdecode(what);
1131         hex_qdecode(val);
1132         if ((oldval = strchr(what, '=')) == NULL) {
1133             /* old value */
1134             fprintf( fp, "<P>%s ", glob->la[56]);
1135             fprintf( fp, "%s %s!<P>\n", glob->la[55], what);
1136             exit_tweb (1);
1137         }
1138         *oldval++ = '\0';
1139         if (strcmp(oldval, val) == 0 ) {    /* no changes */
1140             what = next;
1141             continue;
1142         }
1143         if ((strcasecmp(what, "homePostalAddress") == 0) ||
1144             (strcasecmp(what, "postalAddress") == 0)) {
1145             /* multiline */
1146             cp = oldval;
1147             while ((cp = strchr(cp, '\n')) != NULL) *cp = '$';
1148             cp = val;
1149             while ((cp = strchr(cp, '\n')) != NULL) *cp = '$';
1150                 }
1151         if (debug)
1152             fprintf(stderr, 
1153                              "what = %s, oldval = %s, val = %s\n", 
1154                              what, oldval, val);
1155
1156         /* there is something to do:
1157          * - delete the old value
1158          * - add the new value if not empty */
1159         mod1.mod_type = what;
1160         mod2.mod_type = what;
1161         value1[1] = NULL;
1162         value2[1] = NULL;
1163         mod1.mod_values = value1;
1164         mod2.mod_values = value2;
1165         mods[1] = NULL;
1166         delete_flag = FALSE;
1167
1168 /*  #############  */
1169
1170         if (strlen(oldval) > 0) {
1171
1172             if (strlen (val) > 0) {
1173
1174                 mod1.mod_op = LDAP_MOD_ADD;
1175                 value1[0] = val;
1176
1177 /*                mod2.mod_op = LDAP_MOD_DELETE;
1178                 value2[0] = oldval;
1179                 mods[1] = &mod2;
1180 */
1181                 if ((rc = ldap_modify_s(ld, dn, mods)) != LDAP_SUCCESS) {
1182
1183                     fprintf( fp, 
1184                     "%s <TT>%s</TT> %s <TT>%s</TT>!<P>\n<EM> %d: %s.</EM><p>\n",
1185                             glob->la[80], oldval, glob->la[81], what, 
1186                             rc, ldap_err2string(rc));
1187
1188                     what = next;
1189                     continue;
1190
1191                 }
1192
1193                 mod1.mod_op = LDAP_MOD_DELETE;
1194                 value1[0] = oldval;
1195
1196             } else {
1197
1198                 mod1.mod_op = LDAP_MOD_DELETE;
1199                 value1[0] = oldval;
1200                 delete_flag = TRUE;
1201
1202             }
1203
1204         } else  {
1205         
1206             mod1.mod_op = LDAP_MOD_ADD;
1207             value1[0] = val;
1208
1209         }
1210
1211         if (debug) 
1212               fprintf(stderr, "trying: %s = %s.\n", what, val);
1213
1214         if (((rc=ldap_modify_s(ld, dn, mods)) != LDAP_SUCCESS) &&
1215             (mod1.mod_op != LDAP_MOD_DELETE) && (rc != LDAP_NO_SUCH_ATTRIBUTE)){
1216
1217 if (dosyslog)
1218     syslog (LOG_INFO, "ERROR: ldap_modify_s: ADD\n");
1219             if ( debug ) 
1220                 ldap_perror( ld, "ldap_modify_s: ADD");
1221             fprintf( fp, 
1222                 "%s <TT>%s</TT> %s <TT>%s</TT><P>\n%s <EM> %d: %s.</EM><P>\n", 
1223                 glob->la[57], val, glob->la[58], what, glob->la[59], 
1224                 rc, ldap_err2string( rc ) );
1225             if (strlen(oldval) > 0 && rc != LDAP_INSUFFICIENT_ACCESS) {
1226                 /* try to reset to old value */
1227
1228                 mod1.mod_op = LDAP_MOD_ADD;
1229                 mods[1] = NULL;
1230
1231                 value1[0] = oldval;
1232                 if ((rc = ldap_modify_s(ld, dn, mods)) != LDAP_SUCCESS) {
1233                     fprintf( fp, 
1234                     "%s <TT>%s</TT> %s <TT>%s</TT>!<P>\n<EM> %d: %s.</EM><P>\n",
1235                                 glob->la[60], oldval, glob->la[61], what, 
1236                                 rc, ldap_err2string(rc));
1237
1238                     exit_tweb( 1 );
1239                 } else {
1240                     fprintf( fp, "%s <TT>%s</TT> %s <TT>%s</TT><P>\n", 
1241                                 glob->la[62], oldval, glob->la[61], what);
1242                 }
1243             }
1244             what = next;
1245             continue;
1246         }
1247
1248         if (debug) fprintf(stderr, "MOD: %s = %s.\n", what, val);
1249         changes++;
1250         fprintf(fp, "<DT><B>%s</B> <DD>%s <TT>(%s)</TT>\n",
1251             ldap_friendly_name(glob->friendlyfile, what, &fm), value1[0],
1252             delete_flag ? glob->la[74] : strlen(oldval) > 0 ? 
1253                                         glob->la[75] : glob->la[76]);
1254         what = next;
1255         }
1256     fprintf(fp, "</DL>%d %s%s%s!\n", changes, glob->la[15], 
1257                     changes != 1 ? glob->la[73] : "", 
1258                     changes > 0 ? glob->la[16] : "");
1259     if (changes > 0) {
1260         char  *dn2 = hex_encode(dn);
1261
1262         fprintf(fp, "<UL><LI><B><A HREF=\"/R%s\">%s</A>\n",
1263             dn2, glob->la[17]);
1264         fprintf(fp, "<LI><A HREF=\"/F%s?userPassword=%s\">%s</A></B></UL>\n", 
1265             dn2, pw, glob->la[19]);
1266
1267     }
1268
1269     disp_file(glob, glob->footer, fp);
1270
1271     PRINT_HTML_FOOTER;
1272     fflush(fp);
1273 }
1274 /* end of function: do_modify */
1275
1276 PRIVATE int no_show( rdn, glob)
1277 char *rdn;
1278 GLOB_STRUCT *glob;
1279 {
1280     if ( glob->no_show_rdn ) {
1281
1282         char rdn_cpy[BUFSIZ], *toc, no_sh[BUFSIZ];
1283
1284         strcpy(no_sh, glob->no_show_rdn);
1285         sprintf(rdn_cpy, "|%s|", rdn);
1286         toc = strtok(no_sh, " ");
1287         do {
1288             if(strstr(str_tolower((char *) rdn_cpy), str_tolower(toc)))
1289                 return(TRUE);
1290         } while( ( toc = strtok(NULL, " ")) );
1291
1292     }
1293
1294     return(FALSE);
1295 }
1296 /* end of function: no_show */
1297
1298
1299 PRIVATE int sort_result(ld, res, dn, glob)
1300 LDAP *ld;
1301 LDAPMessage *res;
1302 char *dn;
1303 GLOB_STRUCT *glob;
1304 {
1305     LDAPMessage    *e;
1306     char    *ufn;
1307     int counter = 0, baselen;
1308     int basecount;
1309     pSORT_LINE  s_ptr;
1310     pMY_LDAP_LIST lmptr;
1311     LFP getfirst = glob->prefer_ref_uris ? my_first_entry : ldap_first_entry,
1312         getnext  = glob->prefer_ref_uris ? my_next_entry : ldap_next_entry;
1313
1314     hex_decode (dn);
1315
1316     ufn = ldap_dn2ufn(dn);
1317     baselen = ufn ? strlen(ufn) : 0;
1318     basecount = ufn ? chrcnt(ufn, UFNSEP) : 0;
1319
1320 #if defined( TUE_TEL ) || defined( AMBIXGW )
1321     /*  before sorting check for dynamic changes of the sorting instructions  */
1322     dynamicResort( ld, glob, dn );
1323 #endif
1324
1325     for ( e = (*getfirst)(ld, res);     e != NULL && counter < glob->maxcount;
1326           e = (*getnext)(ld, e ) ) {
1327        sort_parse(ld, e, dn, ufn, baselen, basecount, counter, glob);
1328     }
1329     for(lmptr = mllroot; lmptr; lmptr = lmptr->next) {
1330         sort_parse(ld, lmptr->e, dn, ufn, baselen, basecount, counter, glob);
1331     }
1332     mllroot = NULL;
1333
1334     for(s_ptr = glob->sort; s_ptr; s_ptr = s_ptr->next) {
1335         if( s_ptr->dnLast )
1336             qsort(s_ptr->dnList, s_ptr->dnLast, sizeof(int), compare);
1337     }
1338     return counter;
1339 }
1340 /* end of function: sort_result */
1341
1342
1343 PRIVATE void list_output(fp, glob)
1344 FILE *fp;
1345 GLOB_STRUCT *glob;
1346 {
1347     int i, x;
1348     pSORT_LINE s_ptr;
1349
1350     if(glob->tables_marker)
1351         fprintf (fp, "</H3><TABLE WIDTH=\"100%%\">");
1352
1353     for (i = 0 ; i < MAX_OCS ; i++ ) {
1354         if(!glob->sorty[i]) continue;
1355         s_ptr = glob->sorty[i];
1356
1357         if(glob->tables_marker)
1358             fprintf( fp, "<TR><TH ALIGN=LEFT><BR>");
1359
1360         fprintf( fp, "<H3>%s", s_ptr->label);
1361
1362 #ifdef TUE_TEL
1363         if(glob->ton_urls && glob->ton_urls->department
1364                           && (strlen(s_ptr->label) >1) ) 
1365             fprintf( fp, " / %s", glob->ton_urls->department);
1366 #endif
1367
1368         if(s_ptr->restricted) {
1369             fprintf( fp, " %s", glob->la[33]);
1370             if (glob->legal && !glob->legal_top)
1371                 fprintf( fp, ", %s", glob->la[34]);
1372             fprintf (fp, ")");
1373         }
1374
1375         if(glob->tables_marker)
1376             fprintf (fp, "</H3></TH></TR>");
1377         else
1378             fprintf (fp, "</H3><MENU>\n");
1379
1380         for(x=0; x < s_ptr->dnLast; x++) {
1381             if(glob->strip_pin && strstr(glob->strip_pin, s_ptr->object_class)){
1382                 s_ptr->dnList[x]->href[strlen(s_ptr->dnList[x]->href) -5] = '\0';
1383                 trimright (s_ptr->dnList[x]->href, " 1234567890");
1384                 strcat(s_ptr->dnList[x]->href, "</A>\n");
1385             }
1386     
1387             if( glob->raw_data ) {
1388                 fprintf(fp,"%s",s_ptr->dnList[x]->raw);
1389                 free(s_ptr->dnList[x]->raw);
1390             } else {
1391                 fprintf(fp,"%s",s_ptr->dnList[x]->href);
1392                 free(s_ptr->dnList[x]->href);
1393             }
1394             free(s_ptr->dnList[x]->string);
1395         }
1396
1397         if(!glob->tables_marker)
1398             fprintf (fp, "</MENU>\n");
1399
1400         glob->sorty[i] = NULL;
1401     }
1402     if(glob->tables_marker)
1403         fprintf (fp, "</TABLE>\n");
1404 }
1405 /* end of function: list_output */
1406
1407 PRIVATE void make_la_buttons(sep, fp, ld, dn, la_url, glob)
1408 char *sep;
1409 FILE *fp;
1410 LDAP *ld;
1411 char *dn;
1412 char *la_url;
1413 GLOB_STRUCT *glob;
1414
1415 {
1416     int k;
1417
1418     /* Inform users from unknown */
1419     if(glob->unknown_host) fprintf( fp, glob->la[102]);
1420
1421     if(glob->legal && glob->legal_top)
1422         fprintf (fp, "%s\n%s\n",
1423                 glob->is_proxy ? glob->la[104] : glob->la[65], glob->la[101]);
1424
1425     /* if allowed -> allow-file-message */
1426     if(glob->allowed && glob->allow_msg)
1427         disp_file(glob, glob->allow_msg, fp);
1428
1429     if(glob->pull_down_menus) {
1430         make_la_buttons_pull_down(sep, fp, ld, dn, la_url, glob);
1431         return;
1432     }
1433
1434     fprintf( fp, "<B>");
1435     fprintf( fp, " [ <A HREF=\"/H\">%s</A> ] ",glob->la[29]);
1436     for(k=0; k<strlen(glob->olang); k++){
1437         if(glob->olang[k] == glob->lang[0]) continue;
1438         sprintf(la_url, "http://%s:%d/%s%s",
1439                     glob->hostname, glob->webport+glob->olang[k]-'0',
1440                     sep, hex_encode(dn));
1441         fprintf( fp, " [ <A HREF=\"%s\"> %s </A> ] ",
1442                     la_url, glob->language[glob->olang[k]-'0']);
1443     }
1444     fprintf( fp, "</B><p>");
1445 }
1446 /* end of function: make_la_buttons */
1447
1448 PRIVATE void make_la_buttons_pull_down(sep, fp, ld, dn, la_url, glob)
1449 char *sep;
1450 FILE *fp;
1451 LDAP *ld;
1452 char *dn;
1453 char *la_url;
1454 GLOB_STRUCT *glob;
1455
1456 {
1457     int k;
1458     TABLE_DISPLAY *tab_ptr;
1459
1460     fprintf( fp, "<FORM ACTION=\"/B\">\n");
1461     fprintf( fp, "<INPUT TYPE=SUBMIT NAME=H Value = \"%s\">\n",glob->la[29]);
1462
1463     fprintf( fp, "_\n");
1464
1465     for(k=0; k<strlen(glob->olang); k++){
1466         if(glob->olang[k] == glob->lang[0]) continue;
1467         sprintf(la_url, "http://%s:%d/%s%s",
1468                     glob->hostname, glob->webport+glob->olang[k]-'0',
1469                     sep, hex_encode(dn));
1470         fprintf( fp, "<INPUT TYPE=SUBMIT NAME=%s Value = \"%s\">\n", 
1471                       la_url, glob->language[glob->olang[k]-'0']);
1472     }
1473
1474     /* make tables button in order to have table-display requests */
1475     for(tab_ptr = glob->tables; tab_ptr; tab_ptr = tab_ptr->next) {
1476
1477         char **oc = NULL;
1478         struct timeval timeout;
1479         LDAPMessage *res;
1480         static char    *attrs[] = { "objectClass", 0 };
1481
1482         if( !((!tab_ptr->allow || glob->allowed) && !glob->tables_marker))
1483             continue;
1484
1485         /* Check objectclass for tables_oc */
1486         timeout.tv_sec = glob->timeout;
1487         timeout.tv_usec = 0;
1488         if ( ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*",
1489                               attrs, 0, &timeout, &res ) == LDAP_SUCCESS ){
1490             oc = ldap_get_values(ld, ldap_first_entry(ld, res), "objectClass");
1491         }
1492         if ( oc && charray_inlist( oc, tab_ptr->select_oc)) {
1493
1494             fprintf( fp, "_______\n");
1495             fprintf( fp, "<INPUT TYPE=SUBMIT NAME=X%s?%s#%s Value = \"%s\">\n",
1496                        hex_encode(dn),
1497 #ifdef TUE_TEL
1498                        strstr(tab_ptr->dn_extension, "persontable") ?
1499                        "MENU" : "PHONEBOOK",
1500 #else
1501                        "MENU",
1502 #endif
1503                        tab_ptr->dn_extension, tab_ptr->button_label);
1504         }
1505     }
1506
1507     fprintf( fp, "</FORM>\n");
1508 }
1509 /* end of function: make_la_buttons_pull_down */
1510
1511 PRIVATE void print_rdn(fp, dn, glob)
1512 FILE *fp;
1513 char *dn;
1514 GLOB_STRUCT *glob;
1515 {
1516     char        **s;
1517     char        *rdn = NULL;
1518
1519     if(glob->pull_down_menus) {
1520         print_rdn_pull_down(fp, dn, glob);
1521         return;
1522     }
1523
1524     s = ldap_explode_dn( dn, 1 );
1525     if ( strcmp( dn, "" ) != 0 ) {    /* Not the root */
1526         if ( s[1] == NULL ) {    /* toplevel */
1527             rdn = ldap_friendly_name( glob->friendlyfile, s[0], &fm );
1528         } else {
1529             rdn = s[0];
1530         }
1531         fprintf( fp,"%s <B><A HREF=\"/R%s\">%s</A></B>\n",glob->la[28],hex_encode(dn),rdn?rdn:s[0]);
1532     } else {            /* the root */
1533         fprintf( fp, "<B>%s</B>\n", glob->la[77]);
1534     }
1535     ldap_value_free( s );
1536 }
1537 /* end of function: print_rdn */
1538
1539 PRIVATE void print_rdn_pull_down(fp, dn, glob)
1540 FILE *fp;
1541 char *dn;
1542 GLOB_STRUCT *glob;
1543 {
1544     char        **s;
1545     char        *rdn = NULL;
1546
1547     fprintf( fp, "<FORM ACTION=\"/B\">\n");
1548
1549     s = ldap_explode_dn( dn, 1 );
1550     if ( strcmp( dn, "" ) != 0 ) {    /* Not the root */
1551         if ( s[1] == NULL ) {    /* toplevel */
1552             rdn = ldap_friendly_name( glob->friendlyfile, s[0], &fm );
1553         } else {
1554             rdn = s[0];
1555         }
1556         fprintf( fp,"%s <BIG><STRONG>%s</STRONG></BIG>  ",
1557                      glob->la[28], rdn?rdn:s[0]);
1558         fprintf( fp, "<INPUT TYPE=SUBMIT NAME=R%s Value = \"%s\">\n",
1559                        hex_encode(dn), glob->la[98]);
1560     } else {            /* the root */
1561         fprintf( fp, "<BIG><STRONG>%s</STRONG></BIG>\n", glob->la[77]);
1562     }
1563     ldap_value_free( s );
1564     fprintf( fp, "</FORM>\n");
1565 }
1566 /* end of function: print_rdn_pull_down */
1567
1568 PRIVATE void make_search_box(fp, ld, dn, glob)
1569 FILE *fp;
1570 LDAP *ld;
1571 char *dn;
1572 GLOB_STRUCT *glob;
1573 {
1574     int scope;
1575
1576     scope = make_scope(ld, dn, glob);    /* onelevel or subtree search ? */
1577     fprintf( fp, "<DL><DT><FORM ACTION=\"/S%s\">%s  <inPUT NAME=\"%s\"><INPUT TYPE=submit VALUE=%s><INPUT TYPE=reset VALUE=\"%s\">\n",
1578         hex_encode(dn),
1579         scope == LDAP_SCOPE_ONELEVEL ? glob->la[66] : glob->la[67],
1580         scope == LDAP_SCOPE_ONELEVEL ? "O" : "S",
1581         glob->la[68], glob->la[69]);
1582
1583     fprintf( fp, "</FORM></DL>\n");
1584 }
1585 /* end of function: make_search_box */
1586
1587 PRIVATE LDAPMessage *my_first_entry( ld, e )
1588 LDAP *ld;
1589 LDAPMessage *e;
1590 {
1591     return(ldap_list_eval(ld, e , ldap_first_entry));
1592 }
1593 /* end of function: my_first_entry */
1594
1595 PRIVATE LDAPMessage *my_next_entry(ld, e )
1596 LDAP *ld;
1597 LDAPMessage    *e;
1598 {
1599     return(ldap_list_eval(ld, e , ldap_next_entry));
1600 }
1601 /* end of function: my_next_entry */
1602
1603 PRIVATE LDAPMessage *ldap_list_eval(ld, e, funcp )
1604 LDAP *ld;
1605 LDAPMessage    *e;
1606 LFP funcp;
1607 {
1608
1609     char **value = NULL;
1610     pMY_LDAP_LIST *lmhandle; /* , lmptr; */
1611
1612     for(lmhandle = &mllroot; *lmhandle; lmhandle = &(*lmhandle)->next)
1613         ;
1614
1615     for( e =  (*funcp)( ld, e ) ;
1616          e && strstr(make_oc_to_string(value = ldap_get_values( ld, e, "objectClass" )),
1617                  "|alias|");     e = ldap_next_entry( ld, e )) {
1618         *lmhandle = (pMY_LDAP_LIST) ch_malloc(sizeof(MY_LDAP_LIST));
1619         (*lmhandle)->e = e;
1620         lmhandle = &(*lmhandle)->next;
1621         ldap_value_free(value);
1622         value = NULL;
1623
1624     }
1625     if (value) ldap_value_free(value);
1626
1627 /*    if(!e) {
1628         for(lmptr = mllroot; lmptr; lmptr = lmptr->next) {
1629             char **val;
1630
1631             val = ldap_get_values(ld, lmptr->e, "aliasedObjectName");
1632 if (dosyslog) syslog (LOG_INFO, "alias: %s", val[0]);
1633             ldap_value_free(val);
1634         }
1635         mllroot = NULL;
1636     }
1637 */
1638     return(e);
1639 }
1640 /* end of function: ldap_list_eval */
1641
1642 PRIVATE void sort_parse(ld, e, dn, ufn, baselen, basecount, counter, glob)
1643 LDAP *ld;
1644 LDAPMessage *e;
1645 char *dn;
1646 char *ufn;
1647 int baselen;
1648 int basecount;
1649 int counter;
1650 GLOB_STRUCT *glob;
1651 {
1652     char    **s, **oc;
1653     char    *dn2, *urldn = NULL, *rdn, *doc, *aoc;
1654     char    *ufn2, *sortstring = NULL, *cp;
1655     char   **sattr = NULL, href[20*BUFSIZ], *temp;
1656     int spaces = 0, iscountry;
1657     pGW_SWITCH_LINE gw_ptr;
1658     int flag, found_oc, i;
1659     pSORT_LINE *s_hndl;
1660     pSORT_LINE  s_ptr;
1661     char *url = NULL;
1662     char **uri = NULL, *urlnola, raw_string[BUFSIZ];
1663
1664 #if OL_LDAPV > 0
1665         int         ldap_opt;
1666 #endif
1667
1668     oc = ldap_get_values( ld, e, "objectClass" );
1669
1670     if(!(aoc = make_oc_to_string(oc))) return;
1671
1672
1673 #ifdef TUE_TEL
1674     /*** ton_urls ***/
1675     if(glob->ton_urls && glob->ton_urls->value && strstr(aoc, "|person|")) {
1676         char **tonvals;
1677         int k, matched;
1678
1679         matched=0;
1680         tonvals = ldap_get_values( ld, e, glob->ton_urls->attribute);
1681         if(!tonvals) return;
1682         for(k=0; tonvals[k]; k++) {
1683             if(strstr(tonvals[k], glob->ton_urls->value)
1684             && !(strchr(tonvals[k], '.')
1685                  && (strcspn(tonvals[k],".") > strlen(glob->ton_urls->value)))){
1686                 matched = 1;
1687             }
1688         }
1689         if(!matched) {
1690             return;
1691         }
1692     }
1693 #endif
1694
1695     /* Begin New Sort */
1696     found_oc = FALSE;
1697     i        = 0;
1698     for(s_hndl = &(glob->sort); *s_hndl; s_hndl = &(*s_hndl)->next) {
1699
1700         i++;
1701         if(strstr( aoc, (*s_hndl)->object_class )) {
1702
1703             if(strstr(aoc, "|person|") && glob->no_browse)
1704                 goto NEXTENTRY;
1705             found_oc = TRUE;
1706         }
1707         if(found_oc) break;
1708     }
1709
1710     if(!found_oc) {
1711         if(glob->show_defoc) {
1712             *s_hndl = s_ptr = (pSORT_LINE) ch_malloc(sizeof(SORT_LINE));
1713             s_ptr->object_class = strdup(pick_oc(oc));
1714             s_ptr->label = ldap_friendly_name(glob->friendlyfile, 
1715                                 s_ptr->object_class, &fm);
1716             s_ptr->priority = i;
1717
1718         } else return;
1719     }
1720
1721     s_ptr = *s_hndl;
1722     doc   = s_ptr->object_class;
1723
1724     dn2 = ldap_get_dn( ld, e );
1725     if(urldn) free(urldn);
1726     if(strstr(aoc, "|alias|")) {
1727
1728         char **val;
1729
1730         val = ldap_get_values(ld, e, "aliasedObjectName");
1731         urldn = strdup(hex_encode(val[0]));
1732         ldap_value_free(val);
1733
1734     } else
1735         urldn = strdup(hex_encode(dn2));
1736
1737     ufn2 = strdup (ldap_dn2ufn(dn2));
1738     s = ldap_explode_dn( dn2, 1 );
1739
1740     if(baselen)
1741         ufn2 = dnrcut(ufn2, UFNSEP, basecount);
1742
1743     /* Support raw data delivery */
1744     if(glob->raw_data) {
1745         char **rvals;
1746         int k, l;
1747
1748         sprintf(raw_string, "%s", ufn2);
1749         trimright (raw_string, " 1234567890");
1750
1751         for(l=0; glob->raw_attrs[l]; l++) {
1752             rvals = ldap_get_values( ld, e, glob->raw_attrs[l]);
1753             if(rvals[0])
1754                 sprintf(raw_string, "%s%% %s=", raw_string, glob->raw_attrs[l]);
1755             for(k=0; rvals[k]; k++) {
1756                 sprintf(raw_string, "%s%s%s",raw_string, 
1757                                              k>0 ? "&":"", rvals[k] );
1758             }
1759         }
1760         sprintf(raw_string, "%s|<br><br>", raw_string);
1761     }
1762
1763     iscountry = (strstr( doc, "country" ) != NULL);
1764     if ( iscountry ) {
1765         rdn = ldap_friendly_name( glob->friendlyfile, s[0], &fm );
1766         sortstring = ufn2 = ldap_friendly_name( glob->friendlyfile, 
1767                                                                 ufn2, &fm );
1768         sattr = NULL;
1769     } else
1770         rdn = s[0];
1771     if ( rdn == NULL )
1772         rdn = s[0];
1773     if (( strncasecmp( rdn, "{ASN}", 5 ) == 0 ) 
1774                  || no_show( rdn, glob)) {
1775         free( dn2 );
1776         ldap_value_free( s );
1777         ldap_value_free( oc );
1778             return;
1779     }
1780     if ( !iscountry ) {    /* not a country */
1781         sattr = ldap_get_values( ld, e, s_ptr->sort_attr);
1782         sortstring = strdup(dn2);
1783         if ( ( cp = strchr(sortstring,'=')) ) {
1784             sortstring = ++cp;
1785             /* DNs may have components in '"', ignored  when sorting */
1786             if ( *sortstring == '"' )
1787             sortstring++;
1788         }
1789         if ( sattr ) {
1790             cp = *sattr;
1791             while ( ( cp = strchr(cp,' ')) ) {
1792                 cp ++;
1793                 spaces ++;
1794             }
1795         }
1796         while ( spaces > 0 ) {
1797             if ( ( cp = strrchr(sortstring,' ')) ) {
1798                 *cp = '\0';
1799                 spaces --;
1800             }
1801         }
1802     }
1803
1804     ufn2 = trim(ufn2, "\"");
1805
1806     /* GW-SWITCH */
1807     flag = 0;
1808     urlnola = NULL;
1809
1810     if (glob->gw_switch && glob->gw_switch->dynamic) {
1811
1812         uri = ldap_get_values( ld, e, "labeledURI" );
1813
1814         /* PREFER-REF-URIS Code */
1815         if(strstr(aoc, "|alias|") && glob->prefer_ref_uris){
1816
1817             LDAPMessage *ures, *ue;
1818             struct timeval  timeout;
1819             char        **val;
1820
1821             timeout.tv_sec = glob->timeout;
1822             timeout.tv_usec = 0;
1823     
1824 #if OL_LDAPV > 0
1825
1826                 ldap_opt = LDAP_DEREF_ALWAYS;
1827         ldap_set_option( ld, LDAP_OPT_DEREF, &ldap_opt );
1828
1829 #else
1830             ld->ld_deref = LDAP_DEREF_ALWAYS;
1831 #endif
1832
1833             if ( (ldap_search_st( ld, dn2, LDAP_SCOPE_BASE, "objectClass=*",
1834                 NULL, 0, &timeout, &ures )) == LDAP_SUCCESS ) {
1835                 if ( (ue = ldap_first_entry( ld, ures ))) {
1836                     if( ( val = ldap_get_values( ld, ue, "labeledURI" )) ) {
1837                         if(uri) ldap_value_free(uri);
1838                         uri = val;
1839                             
1840                     }
1841                 }
1842             }
1843         }
1844
1845         for(i=0; uri && uri[i] && *uri[i]; i++) {
1846             char *sp;
1847
1848             if( ( sp = strchr(uri[i], ' ')) ) {
1849                 *sp++ = '\0';
1850                 if(strstr(sp, glob->gw_switch->lagws)) {
1851                     flag = 1;
1852                     url = uri[i];
1853                     break;
1854                 } else if(strstr(sp, GWS))
1855                     urlnola = uri[i];
1856             }
1857         }
1858     }
1859
1860     if(!flag && urlnola) {
1861         url = urlnola;
1862         flag = 1;
1863     }
1864
1865     if (glob->gw_switch) {
1866
1867         for(gw_ptr = glob->gw_switch->list; 
1868                           !flag && gw_ptr; gw_ptr = gw_ptr->next) {
1869             if (!dn_cmp (dn2, gw_ptr->dn)) {
1870                 flag = 1;
1871                 url = gw_ptr->url;
1872             }
1873         }
1874     }
1875
1876         if(flag == 1) {
1877             char  *url_tmp;
1878
1879             sprintf( href, "<LI><A HREF=\"%s\">%s</A>\n",
1880                         (url_tmp = url_complete(url, urldn, "M")),
1881                          glob->disp_sea_rdn ? rdn : ufn2);
1882
1883         }
1884
1885         if (flag==0) {
1886             char *strptr;
1887
1888             if(glob->strip_pin && strstr(glob->strip_pin, doc))
1889                 if ( ( strptr = strchr(ufn2, ',')) ) {
1890
1891                     *strptr++ = '\0';
1892                     trimright(ufn2, " 1234567890");
1893                     sprintf(ufn2, "%s,%s", ufn2, strptr);
1894
1895                 } else
1896                     trimright(ufn2, " 1234567890");
1897
1898             ufn2 = trim(ufn2, "\"");
1899
1900             /* TABLES DISPLAY CODE */
1901             if(glob->tables_marker){
1902
1903                 char disp_rule[BUFSIZ], *strptr, strbuf[BUFSIZ];
1904                 char tab_attr[BUFSIZ], percent[BUFSIZ];
1905                 char **aval;
1906                 int n;
1907
1908                 strcpy(disp_rule, glob->tables_marker);
1909                 strptr = strstr(disp_rule, "persontable");
1910
1911                 if(strptr){
1912                     strptr = strchr(strptr, ':') + 1;
1913                     strcpy(disp_rule, strptr);
1914                     strptr = strchr(disp_rule, '$');
1915                     if(strptr) *strptr = '\0';
1916                     strcat(disp_rule, "&");
1917
1918                     strcpy( href, "<TR>\n");
1919
1920                     while(*disp_rule){
1921                         strcpy(strbuf, disp_rule);
1922                         strptr=strchr(disp_rule, '&');
1923                         strcpy(disp_rule, strptr+1);
1924
1925                         strptr=strchr(strbuf, '&');
1926                         *strptr++ = '\0';
1927                         strcpy(tab_attr, strbuf);
1928                         strptr = strchr(tab_attr, ',');
1929                         *strptr++ = '\0';
1930                         strcpy(percent, strptr);
1931
1932                         sprintf( href, "%s <TD WIDTH=\"%s%%\" VALIGN=TOP %s>",
1933                                  href, percent,
1934                                  !strcasecmp(tab_attr, "telephonenumber") ?
1935                                  "ALIGN=RIGHT NOWRAP" : "ALIGN=LEFT");
1936
1937                         if(!strcasecmp(tab_attr, "rdn")){
1938                             trimright (ufn2, " 1234567890");
1939                             sprintf( href, "%s<A HREF=\"/M%s\">%s</A><BR>\n",
1940                                      href, urldn, ufn2);
1941
1942 #ifdef TUE_TEL
1943                         /* use tat_refphone & fallback to telephonenumber */
1944                         } else if(!strcasecmp(tab_attr, "phone")){
1945                             displayTueTelList( ld, e, href, glob );
1946
1947 #endif
1948                         } else if(!strncasecmp(tab_attr, "objectclass", 11)){
1949                             char objectclass[BUFSIZ], letter[BUFSIZ], *trptr;
1950                             char tab_attr_buf[BUFSIZ];
1951
1952                             *(letter+1) = *letter = '\0';
1953                             strcpy(tab_attr_buf, tab_attr);
1954                             trptr = tab_attr_buf;
1955                             while( ( trptr = strchr(trptr, '=')) )
1956                                 *trptr++ = ' ';
1957
1958                             sscanf(tab_attr_buf, "%*s%s%s",
1959                                               objectclass, letter);
1960                             if(!*letter) *letter = '*';
1961
1962                             if( ( aval =
1963                                     ldap_get_values( ld, e, "objectclass")) ) {
1964                                 if(charray_inlist(aval, objectclass))
1965                                     sprintf(href, "%s %s",
1966                                                       href, letter);
1967                             }
1968                         } else if( ( aval =
1969                                         ldap_get_values( ld, e, tab_attr )) ) {
1970                             for(n=0; aval[n]; n++){
1971                                 if(!strcasecmp(tab_attr, "mail"))
1972                                     sprintf(href,
1973                                             "%s<A HREF=\"mailto:%s\">%s</A><BR>",
1974                                             href, aval[n], aval[n]);
1975                                 else
1976                                     sprintf(href, "%s %s<BR>", href, aval[n]);
1977                             }
1978                         }
1979                         sprintf( href, "%s</TD>", href);
1980                     }
1981                     sprintf( href, "%s</TR>", href);
1982                 }
1983
1984             /* without tables */
1985             }else{
1986                 sprintf( href, "<LI><A HREF=\"%s%sM%s\">%s</A>\n",
1987
1988 #ifdef TUE_TEL
1989                          (glob->dit_config && !glob->dit_config->not_browse) ?
1990                                 dn2server(urldn, glob) : "",
1991 #else
1992                                 "",
1993 #endif
1994
1995                                 "/", urldn,
1996                                 glob->disp_sea_rdn ? rdn : ufn2);
1997             }
1998         }
1999
2000         if (*sortstring == '&') {
2001
2002             sortstring[0] = sortstring[1];
2003             sortstring[1] = 'e';
2004
2005         }
2006
2007         if( (strstr(aoc, "person") && (s_ptr->dnLast >= glob->max_person) )
2008            || ( s_ptr->dnLast >= glob->maxcount) ) {
2009             s_ptr->restricted = 1;
2010             return;
2011         }
2012
2013         if ( sattr ) 
2014             temp = (char *) ch_malloc(strlen(*sattr)+strlen(sortstring)+1);
2015         else 
2016             temp = (char *) ch_malloc(strlen(sortstring)+1);
2017         if ( sattr )
2018             strcat(temp, *sattr);
2019         strcat(temp,sortstring);
2020
2021         if(!s_ptr->dnList)
2022             s_ptr->dnList = (DNLIST **) ch_calloc(glob->maxcount+1,
2023                                                      sizeof(pDNLIST));
2024         if (!s_ptr->dnList[s_ptr->dnLast] )
2025                     s_ptr->dnList[s_ptr->dnLast] = (pDNLIST)
2026                                         ch_malloc(sizeof(DNLIST));
2027
2028         s_ptr->dnList[s_ptr->dnLast]->string = temp;
2029
2030         if(glob->raw_data) {
2031             s_ptr->dnList[s_ptr->dnLast]->raw = strdup(raw_string);
2032         }
2033
2034         s_ptr->dnList[s_ptr->dnLast++]->href = strdup(href);
2035         glob->sorty[s_ptr->priority] = s_ptr;
2036
2037         free( dn2 );
2038         ldap_value_free( s );
2039         ldap_value_free( oc );
2040         ldap_value_free( uri );
2041
2042         if(++counter >= glob->maxcount)
2043             glob->restricted = TRUE;
2044
2045 NEXTENTRY:
2046         ;
2047         return;
2048 }
2049 /* end of function: sort_parse */
2050
2051
2052 PUBLIC void close_ldap_connections(glob)
2053 GLOB_STRUCT *glob;
2054 {
2055     pLD_LIST ldlptr;
2056
2057     for(ldlptr = glob->ld_list; ldlptr; ldlptr = ldlptr->next)
2058         ldap_unbind(ldlptr->ld);
2059 }
2060 /* end of function: close_ldap_connections */
2061
2062 PUBLIC LDAP *get_ldap_connection( host, port, glob )
2063 char *host;
2064 int port;
2065 GLOB_STRUCT *glob;
2066 {
2067     pLD_LIST ldlptr, *ldlhdl;
2068     LDAP *ld = NULL;
2069     int rc;
2070
2071     for(ldlptr = glob->ld_list; ldlptr; ldlptr = ldlptr->next) {
2072         if ( !strcasecmp(ldlptr->host, host) && (ldlptr->port == port))
2073             ld = ldlptr->ld;
2074
2075     }
2076     if (!ld) {
2077
2078         if ( (ld = ldap_open( host, port )) == NULL )
2079             return(NULL);
2080         if ( (rc=ldap_simple_bind_s( ld, glob->webdn, glob->webpw ))
2081               != LDAP_SUCCESS )
2082             return(NULL);
2083         for(ldlhdl = &glob->ld_list; *ldlhdl; ldlhdl = &(*ldlhdl)->next)
2084             ;
2085         *ldlhdl = (pLD_LIST) ch_calloc(1, sizeof(LD_LIST));
2086         (*ldlhdl)->host = strdup(host);
2087         (*ldlhdl)->port = port;
2088         (*ldlhdl)->ld = ld;
2089     }
2090     return(ld);
2091 }
2092 /* end of function: get_ldap_connection */
2093
2094
2095 PRIVATE void get_ref_attrs( ld1, dn, e1, glob )
2096 LDAP *ld1;
2097 char *dn;
2098 LDAPMessage *e1;
2099 GLOB_STRUCT *glob;
2100 {
2101     pIND_ATTRS i_ptr;
2102     IND_ATTR_ARR *idx, **vnodes;
2103     int i, j, k, n;
2104     LDAP *ld;
2105     int rc;
2106     LDAPMessage *res, *e;
2107     struct timeval timeout;
2108     char **val, **val1;
2109     char ref_dn[BUFSIZ], ref_cnbuf[BUFSIZ], *ref_cn;
2110
2111
2112     for(i_ptr = glob->ind_attrs; i_ptr; i_ptr = i_ptr->next) {
2113
2114         /* Function-Mode */
2115         if (i_ptr->ia_arr && (i_ptr->ia_arr[0].replace == 2))
2116             continue;
2117
2118         if ( (val1 = ldap_get_values( ld1, e1, i_ptr->ref_attr )) == NULL )
2119             continue;
2120
2121         for(idx = i_ptr->ia_arr, i=0; idx[i].key; i++){
2122             /* idx[i].key idx[i].replace idx[i].attr idx[i].host idx[i].port
2123                idx[i].base -- i_ptr->ref_attr */
2124
2125             ld = get_ldap_connection( idx[i].host, idx[i].port, glob );
2126
2127             timeout.tv_sec = glob->timeout;
2128             timeout.tv_usec = 0;
2129
2130             for ( j = 0; val1[j] != NULL; j++ ) {
2131                 if(strncasecmp(val1[j], idx[i].key, strlen(idx[i].key)))
2132                     continue;
2133                 else {
2134                     strcpy(ref_cnbuf, val1[j]);
2135 /*                    ref_cn = ref_cnbuf + strlen(idx[i].key);
2136 */
2137                       ref_cn = ref_cnbuf;
2138                 }
2139
2140                 sprintf(ref_dn, "cn=%s,%s", ref_cn, idx[i].base);
2141                 if ( (rc = ldap_search_st( ld, ref_dn, LDAP_SCOPE_BASE, 
2142                   "objectClass=*", NULL, 0, &timeout, &res )) != LDAP_SUCCESS )
2143                     continue;
2144                 if ( (e = ldap_first_entry( ld, res )) == NULL )
2145                     return;
2146                 val = ldap_get_values( ld, e, idx[i].attr );
2147                 if(val[0] != NULL) {
2148                     if(!idx[i].e)
2149                         idx[i].e = ( LDAPMessage ** )
2150                             ch_malloc( 16 * sizeof(LDAPMessage *) );
2151                     for(n=0; idx[i].e[n];  n++)
2152                         ;
2153                     idx[i].e[n] = e;
2154                     idx[i].ld = ld;
2155                     vnodes = &glob->ind_attrs->valid_nodes;
2156                     if(!*vnodes)
2157                         *vnodes = (IND_ATTR_ARR *) 
2158                                    ch_malloc( 100 * sizeof(IND_ATTR_ARR *) );
2159                     for(k=0; (*vnodes)[k].key;  k++)
2160                         ;
2161                     if(j==0)
2162                         (*vnodes)[k] = idx[i];
2163                 }
2164             }
2165         }
2166     }
2167 }
2168 /* end of function: get_ref_attrs */