1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*0Sstevel@tonic-gate * Use is subject to license terms. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate /* 9*0Sstevel@tonic-gate * tmplout.c: display template library output routines for LDAP clients 10*0Sstevel@tonic-gate * 12 April 1994 by Mark C Smith 11*0Sstevel@tonic-gate */ 12*0Sstevel@tonic-gate 13*0Sstevel@tonic-gate #include <stdio.h> 14*0Sstevel@tonic-gate #include <string.h> 15*0Sstevel@tonic-gate #include <ctype.h> 16*0Sstevel@tonic-gate #include <time.h> 17*0Sstevel@tonic-gate #include <tzfile.h> 18*0Sstevel@tonic-gate #include <stdlib.h> 19*0Sstevel@tonic-gate #ifdef MACOS 20*0Sstevel@tonic-gate #include "macos.h" 21*0Sstevel@tonic-gate #else /* MACOS */ 22*0Sstevel@tonic-gate #ifdef DOS 23*0Sstevel@tonic-gate #include <malloc.h> 24*0Sstevel@tonic-gate #include "msdos.h" 25*0Sstevel@tonic-gate #else /* DOS */ 26*0Sstevel@tonic-gate #include <sys/time.h> 27*0Sstevel@tonic-gate #include <sys/types.h> 28*0Sstevel@tonic-gate #include <sys/file.h> 29*0Sstevel@tonic-gate #endif /* DOS */ 30*0Sstevel@tonic-gate #endif /* MACOS */ 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #ifdef VMS 33*0Sstevel@tonic-gate #include <sys/socket.h> 34*0Sstevel@tonic-gate #endif /* VMS */ 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate #include "lber.h" 37*0Sstevel@tonic-gate #include "ldap.h" 38*0Sstevel@tonic-gate #include "ldap-private.h" 39*0Sstevel@tonic-gate #include "ldap-int.h" 40*0Sstevel@tonic-gate #ifdef SUN 41*0Sstevel@tonic-gate /* 42*0Sstevel@tonic-gate * to include definition of FILTERFILE and or TEMPLATEFILE 43*0Sstevel@tonic-gate */ 44*0Sstevel@tonic-gate #include "ldapconfig.h" 45*0Sstevel@tonic-gate #endif 46*0Sstevel@tonic-gate 47*0Sstevel@tonic-gate #ifdef NEEDPROTOS 48*0Sstevel@tonic-gate static int do_entry2text( LDAP *ld, char *buf, char *base, LDAPMessage *entry, 49*0Sstevel@tonic-gate struct ldap_disptmpl *tmpl, char **defattrs, char ***defvals, 50*0Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, int rdncount, 51*0Sstevel@tonic-gate unsigned int opts, char *urlprefix ); 52*0Sstevel@tonic-gate static int do_entry2text_search( LDAP *ld, char *dn, char *base, 53*0Sstevel@tonic-gate LDAPMessage *entry, struct ldap_disptmpl *tmpllist, char **defattrs, 54*0Sstevel@tonic-gate char ***defvals, writeptype writeproc, void *writeparm, char *eol, 55*0Sstevel@tonic-gate int rdncount, unsigned int opts, char *urlprefix ); 56*0Sstevel@tonic-gate static int do_vals2text( LDAP *ld, char *buf, char **vals, char *label, 57*0Sstevel@tonic-gate int labelwidth, unsigned int syntaxid, writeptype writeproc, 58*0Sstevel@tonic-gate void *writeparm, char *eol, int rdncount, char *urlprefix ); 59*0Sstevel@tonic-gate static int max_label_len( struct ldap_disptmpl *tmpl ); 60*0Sstevel@tonic-gate static int output_label( char *buf, char *label, int width, 61*0Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, int html ); 62*0Sstevel@tonic-gate static int output_dn( char *buf, char *dn, int width, int rdncount, 63*0Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, char *urlprefix ); 64*0Sstevel@tonic-gate static void strcat_escaped( char *s1, char *s2 ); 65*0Sstevel@tonic-gate static char *time2text( char *ldtimestr, int dateonly ); 66*0Sstevel@tonic-gate static time_t gtime( struct tm *tm ); 67*0Sstevel@tonic-gate static int searchaction( LDAP *ld, char *buf, char *base, LDAPMessage *entry, 68*0Sstevel@tonic-gate char *dn, struct ldap_tmplitem *tip, int labelwidth, int rdncount, 69*0Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, char *urlprefix ); 70*0Sstevel@tonic-gate #else /* NEEDPROTOS */ 71*0Sstevel@tonic-gate static int do_entry2text(); 72*0Sstevel@tonic-gate static int do_entry2text_search(); 73*0Sstevel@tonic-gate static int do_vals2text(); 74*0Sstevel@tonic-gate static int max_label_len(); 75*0Sstevel@tonic-gate static int output_label(); 76*0Sstevel@tonic-gate static int output_dn(); 77*0Sstevel@tonic-gate static void strcat_escaped(); 78*0Sstevel@tonic-gate static char *time2text(); 79*0Sstevel@tonic-gate static time_t gtime(); 80*0Sstevel@tonic-gate static int searchaction(); 81*0Sstevel@tonic-gate #endif /* NEEDPROTOS */ 82*0Sstevel@tonic-gate 83*0Sstevel@tonic-gate #define DEF_LABEL_WIDTH 15 84*0Sstevel@tonic-gate #define SEARCH_TIMEOUT_SECS 120 85*0Sstevel@tonic-gate #define OCATTRNAME "objectClass" 86*0Sstevel@tonic-gate 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate #define NONFATAL_LDAP_ERR( err ) ( err == LDAP_SUCCESS || \ 89*0Sstevel@tonic-gate err == LDAP_TIMELIMIT_EXCEEDED || err == LDAP_SIZELIMIT_EXCEEDED ) 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate #define DEF_LDAP_URL_PREFIX "ldap:///" 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate 94*0Sstevel@tonic-gate int 95*0Sstevel@tonic-gate ldap_entry2text( 96*0Sstevel@tonic-gate LDAP *ld, 97*0Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 98*0Sstevel@tonic-gate LDAPMessage *entry, 99*0Sstevel@tonic-gate struct ldap_disptmpl *tmpl, 100*0Sstevel@tonic-gate char **defattrs, 101*0Sstevel@tonic-gate char ***defvals, 102*0Sstevel@tonic-gate writeptype writeproc, 103*0Sstevel@tonic-gate void *writeparm, 104*0Sstevel@tonic-gate char *eol, 105*0Sstevel@tonic-gate int rdncount, 106*0Sstevel@tonic-gate unsigned int opts 107*0Sstevel@tonic-gate ) 108*0Sstevel@tonic-gate { 109*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 110*0Sstevel@tonic-gate int rv; 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate LOCK_LDAP(ld); 113*0Sstevel@tonic-gate #endif 114*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 253, "ldap_entry2text\n"), 0, 0, 0 ); 115*0Sstevel@tonic-gate 116*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 117*0Sstevel@tonic-gate rv = do_entry2text( ld, buf, NULL, entry, tmpl, defattrs, defvals, 118*0Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, opts, NULL ); 119*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 120*0Sstevel@tonic-gate return( rv ); 121*0Sstevel@tonic-gate #else 122*0Sstevel@tonic-gate return( do_entry2text( ld, buf, NULL, entry, tmpl, defattrs, defvals, 123*0Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, opts, NULL )); 124*0Sstevel@tonic-gate #endif 125*0Sstevel@tonic-gate } 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate 129*0Sstevel@tonic-gate int 130*0Sstevel@tonic-gate ldap_entry2html( 131*0Sstevel@tonic-gate LDAP *ld, 132*0Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 133*0Sstevel@tonic-gate LDAPMessage *entry, 134*0Sstevel@tonic-gate struct ldap_disptmpl *tmpl, 135*0Sstevel@tonic-gate char **defattrs, 136*0Sstevel@tonic-gate char ***defvals, 137*0Sstevel@tonic-gate writeptype writeproc, 138*0Sstevel@tonic-gate void *writeparm, 139*0Sstevel@tonic-gate char *eol, 140*0Sstevel@tonic-gate int rdncount, 141*0Sstevel@tonic-gate unsigned int opts, 142*0Sstevel@tonic-gate char *base, 143*0Sstevel@tonic-gate char *urlprefix 144*0Sstevel@tonic-gate ) 145*0Sstevel@tonic-gate { 146*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 147*0Sstevel@tonic-gate int rv; 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate LOCK_LDAP(ld); 150*0Sstevel@tonic-gate #endif 151*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 254, "ldap_entry2html\n"), 0, 0, 0 ); 152*0Sstevel@tonic-gate 153*0Sstevel@tonic-gate if ( urlprefix == NULL ) { 154*0Sstevel@tonic-gate urlprefix = DEF_LDAP_URL_PREFIX; 155*0Sstevel@tonic-gate } 156*0Sstevel@tonic-gate 157*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 158*0Sstevel@tonic-gate rv = do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals, 159*0Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, opts, urlprefix ); 160*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 161*0Sstevel@tonic-gate return( rv ); 162*0Sstevel@tonic-gate #else 163*0Sstevel@tonic-gate return( do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals, 164*0Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, opts, urlprefix )); 165*0Sstevel@tonic-gate #endif 166*0Sstevel@tonic-gate } 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate 169*0Sstevel@tonic-gate static int 170*0Sstevel@tonic-gate do_entry2text( 171*0Sstevel@tonic-gate LDAP *ld, 172*0Sstevel@tonic-gate char *buf, /* NULL for use-internal */ 173*0Sstevel@tonic-gate char *base, /* used for search actions */ 174*0Sstevel@tonic-gate LDAPMessage *entry, 175*0Sstevel@tonic-gate struct ldap_disptmpl *tmpl, 176*0Sstevel@tonic-gate char **defattrs, 177*0Sstevel@tonic-gate char ***defvals, 178*0Sstevel@tonic-gate writeptype writeproc, 179*0Sstevel@tonic-gate void *writeparm, 180*0Sstevel@tonic-gate char *eol, 181*0Sstevel@tonic-gate int rdncount, 182*0Sstevel@tonic-gate unsigned int opts, 183*0Sstevel@tonic-gate char *urlprefix /* if non-NULL, do HTML */ 184*0Sstevel@tonic-gate ) 185*0Sstevel@tonic-gate { 186*0Sstevel@tonic-gate int i, err, html, show, labelwidth; 187*0Sstevel@tonic-gate int freebuf, freevals; 188*0Sstevel@tonic-gate char *dn, **vals; 189*0Sstevel@tonic-gate struct ldap_tmplitem *rowp, *colp; 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate if (( dn = ldap_get_dn( ld, entry )) == NULL ) { 192*0Sstevel@tonic-gate return( ld->ld_errno ); 193*0Sstevel@tonic-gate } 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate if ( buf == NULL ) { 196*0Sstevel@tonic-gate if (( buf = malloc( LDAP_DTMPL_BUFSIZ )) == NULL ) { 197*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 198*0Sstevel@tonic-gate free( dn ); 199*0Sstevel@tonic-gate return( ld->ld_errno ); 200*0Sstevel@tonic-gate } 201*0Sstevel@tonic-gate freebuf = 1; 202*0Sstevel@tonic-gate } else { 203*0Sstevel@tonic-gate freebuf = 0; 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate 206*0Sstevel@tonic-gate html = ( urlprefix != NULL ); 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate if ( html ) { 209*0Sstevel@tonic-gate /* 210*0Sstevel@tonic-gate * add HTML intro. and title 211*0Sstevel@tonic-gate */ 212*0Sstevel@tonic-gate if (!(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) { 213*0Sstevel@tonic-gate sprintf( buf, "<HTML>%s<HEAD>%s<TITLE>%s%s - ", eol, eol, eol, 214*0Sstevel@tonic-gate ( tmpl == NULL ) ? "Entry" : tmpl->dt_name ); 215*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 216*0Sstevel@tonic-gate output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL ); 217*0Sstevel@tonic-gate sprintf( buf, "%s</TITLE>%s</HEAD>%s<BODY>%s<H3>%s - ", eol, eol, 218*0Sstevel@tonic-gate eol, eol, ( tmpl == NULL ) ? "Entry" : tmpl->dt_name ); 219*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 220*0Sstevel@tonic-gate output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL ); 221*0Sstevel@tonic-gate sprintf( buf, "</H3>%s", eol ); 222*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 223*0Sstevel@tonic-gate } 224*0Sstevel@tonic-gate 225*0Sstevel@tonic-gate if (( opts & LDAP_DISP_OPT_NONLEAF ) != 0 && 226*0Sstevel@tonic-gate ( vals = ldap_explode_dn( dn, 0 )) != NULL ) { 227*0Sstevel@tonic-gate char *untagged; 228*0Sstevel@tonic-gate 229*0Sstevel@tonic-gate /* 230*0Sstevel@tonic-gate * add "Move Up" link 231*0Sstevel@tonic-gate */ 232*0Sstevel@tonic-gate sprintf( buf, "<A HREF=\"%s", urlprefix ); 233*0Sstevel@tonic-gate for ( i = 1; vals[ i ] != NULL; ++i ) { 234*0Sstevel@tonic-gate if ( i > 1 ) { 235*0Sstevel@tonic-gate strcat_escaped( buf, ", " ); 236*0Sstevel@tonic-gate } 237*0Sstevel@tonic-gate strcat_escaped( buf, vals[ i ] ); 238*0Sstevel@tonic-gate } 239*0Sstevel@tonic-gate if ( vals[ 1 ] != NULL ) { 240*0Sstevel@tonic-gate untagged = strchr( vals[ 1 ], '=' ); 241*0Sstevel@tonic-gate } else { 242*0Sstevel@tonic-gate untagged = "=The World"; 243*0Sstevel@tonic-gate } 244*0Sstevel@tonic-gate sprintf( buf + strlen( buf ), 245*0Sstevel@tonic-gate "%s\">Move Up To <EM>%s</EM></A>%s<BR>", 246*0Sstevel@tonic-gate ( vals[ 1 ] == NULL ) ? "??one" : "", 247*0Sstevel@tonic-gate ( untagged != NULL ) ? untagged + 1 : vals[ 1 ], eol, eol ); 248*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate /* 251*0Sstevel@tonic-gate * add "Browse" link 252*0Sstevel@tonic-gate */ 253*0Sstevel@tonic-gate untagged = strchr( vals[ 0 ], '=' ); 254*0Sstevel@tonic-gate sprintf( buf, "<A HREF=\"%s", urlprefix ); 255*0Sstevel@tonic-gate strcat_escaped( buf, dn ); 256*0Sstevel@tonic-gate sprintf( buf + strlen( buf ), "??one?(!(objectClass=dsa))\">Browse Below <EM>%s</EM></A>%s%s", 257*0Sstevel@tonic-gate ( untagged != NULL ) ? untagged + 1 : vals[ 0 ], eol, eol ); 258*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 259*0Sstevel@tonic-gate 260*0Sstevel@tonic-gate ldap_value_free( vals ); 261*0Sstevel@tonic-gate } 262*0Sstevel@tonic-gate 263*0Sstevel@tonic-gate (*writeproc)( writeparm, "<HR>", 4 ); /* horizontal rule */ 264*0Sstevel@tonic-gate } else { 265*0Sstevel@tonic-gate (*writeproc)( writeparm, "\"", 1 ); 266*0Sstevel@tonic-gate output_dn( buf, dn, 0, rdncount, writeproc, writeparm, "", NULL ); 267*0Sstevel@tonic-gate sprintf( buf, "\"%s", eol ); 268*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 269*0Sstevel@tonic-gate } 270*0Sstevel@tonic-gate 271*0Sstevel@tonic-gate if ( tmpl != NULL && ( opts & LDAP_DISP_OPT_AUTOLABELWIDTH ) != 0 ) { 272*0Sstevel@tonic-gate labelwidth = max_label_len( tmpl ) + 3; 273*0Sstevel@tonic-gate } else { 274*0Sstevel@tonic-gate labelwidth = DEF_LABEL_WIDTH;; 275*0Sstevel@tonic-gate } 276*0Sstevel@tonic-gate 277*0Sstevel@tonic-gate err = LDAP_SUCCESS; 278*0Sstevel@tonic-gate 279*0Sstevel@tonic-gate if ( tmpl == NULL ) { 280*0Sstevel@tonic-gate BerElement *ber; 281*0Sstevel@tonic-gate char *attr; 282*0Sstevel@tonic-gate 283*0Sstevel@tonic-gate ber = NULL; 284*0Sstevel@tonic-gate for ( attr = ldap_first_attribute( ld, entry, &ber ); 285*0Sstevel@tonic-gate NONFATAL_LDAP_ERR( err ) && attr != NULL; 286*0Sstevel@tonic-gate attr = ldap_next_attribute( ld, entry, ber )) { 287*0Sstevel@tonic-gate if (( vals = ldap_get_values( ld, entry, attr )) == NULL ) { 288*0Sstevel@tonic-gate freevals = 0; 289*0Sstevel@tonic-gate if ( defattrs != NULL ) { 290*0Sstevel@tonic-gate for ( i = 0; defattrs[ i ] != NULL; ++i ) { 291*0Sstevel@tonic-gate if ( strcasecmp( attr, defattrs[ i ] ) == 0 ) { 292*0Sstevel@tonic-gate break; 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate } 295*0Sstevel@tonic-gate if ( defattrs[ i ] != NULL ) { 296*0Sstevel@tonic-gate vals = defvals[ i ]; 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate } 299*0Sstevel@tonic-gate } else { 300*0Sstevel@tonic-gate freevals = 1; 301*0Sstevel@tonic-gate } 302*0Sstevel@tonic-gate 303*0Sstevel@tonic-gate if ( islower( *attr )) { /* cosmetic -- upcase attr. name */ 304*0Sstevel@tonic-gate *attr = toupper( *attr ); 305*0Sstevel@tonic-gate } 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate err = do_vals2text( ld, buf, vals, attr, labelwidth, 308*0Sstevel@tonic-gate LDAP_SYN_CASEIGNORESTR, writeproc, writeparm, eol, 309*0Sstevel@tonic-gate rdncount, urlprefix ); 310*0Sstevel@tonic-gate if ( freevals ) { 311*0Sstevel@tonic-gate ldap_value_free( vals ); 312*0Sstevel@tonic-gate } 313*0Sstevel@tonic-gate } 314*0Sstevel@tonic-gate } else { 315*0Sstevel@tonic-gate for ( rowp = ldap_first_tmplrow( tmpl ); 316*0Sstevel@tonic-gate NONFATAL_LDAP_ERR( err ) && rowp != NULLTMPLITEM; 317*0Sstevel@tonic-gate rowp = ldap_next_tmplrow( tmpl, rowp )) { 318*0Sstevel@tonic-gate for ( colp = ldap_first_tmplcol( tmpl, rowp ); colp != NULLTMPLITEM; 319*0Sstevel@tonic-gate colp = ldap_next_tmplcol( tmpl, rowp, colp )) { 320*0Sstevel@tonic-gate vals = NULL; 321*0Sstevel@tonic-gate if ( colp->ti_attrname == NULL || ( vals = ldap_get_values( ld, 322*0Sstevel@tonic-gate entry, colp->ti_attrname )) == NULL ) { 323*0Sstevel@tonic-gate freevals = 0; 324*0Sstevel@tonic-gate if ( !LDAP_IS_TMPLITEM_OPTION_SET( colp, 325*0Sstevel@tonic-gate LDAP_DITEM_OPT_HIDEIFEMPTY ) && defattrs != NULL 326*0Sstevel@tonic-gate && colp->ti_attrname != NULL ) { 327*0Sstevel@tonic-gate for ( i = 0; defattrs[ i ] != NULL; ++i ) { 328*0Sstevel@tonic-gate if ( strcasecmp( colp->ti_attrname, defattrs[ i ] ) 329*0Sstevel@tonic-gate == 0 ) { 330*0Sstevel@tonic-gate break; 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate } 333*0Sstevel@tonic-gate if ( defattrs[ i ] != NULL ) { 334*0Sstevel@tonic-gate vals = defvals[ i ]; 335*0Sstevel@tonic-gate } 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate } else { 338*0Sstevel@tonic-gate freevals = 1; 339*0Sstevel@tonic-gate if ( LDAP_IS_TMPLITEM_OPTION_SET( colp, 340*0Sstevel@tonic-gate LDAP_DITEM_OPT_SORTVALUES ) && vals[ 0 ] != NULL 341*0Sstevel@tonic-gate && vals[ 1 ] != NULL ) { 342*0Sstevel@tonic-gate ldap_sort_values( ld, vals, ldap_sort_strcasecmp ); 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate } 345*0Sstevel@tonic-gate 346*0Sstevel@tonic-gate /* 347*0Sstevel@tonic-gate * don't bother even calling do_vals2text() if no values 348*0Sstevel@tonic-gate * or boolean with value false and "hide if false" option set 349*0Sstevel@tonic-gate */ 350*0Sstevel@tonic-gate show = ( vals != NULL && vals[ 0 ] != NULL ); 351*0Sstevel@tonic-gate if ( show && LDAP_GET_SYN_TYPE( colp->ti_syntaxid ) 352*0Sstevel@tonic-gate == LDAP_SYN_TYPE_BOOLEAN && LDAP_IS_TMPLITEM_OPTION_SET( 353*0Sstevel@tonic-gate colp, LDAP_DITEM_OPT_HIDEIFFALSE ) && 354*0Sstevel@tonic-gate toupper( vals[ 0 ][ 0 ] ) != 'T' ) { 355*0Sstevel@tonic-gate show = 0; 356*0Sstevel@tonic-gate } 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate if ( colp->ti_syntaxid == LDAP_SYN_SEARCHACTION ) { 359*0Sstevel@tonic-gate if (( opts & LDAP_DISP_OPT_DOSEARCHACTIONS ) != 0 ) { 360*0Sstevel@tonic-gate if ( colp->ti_attrname == NULL || ( show && 361*0Sstevel@tonic-gate toupper( vals[ 0 ][ 0 ] ) == 'T' )) { 362*0Sstevel@tonic-gate err = searchaction( ld, buf, base, entry, dn, colp, 363*0Sstevel@tonic-gate labelwidth, rdncount, writeproc, 364*0Sstevel@tonic-gate writeparm, eol, urlprefix ); 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate } 367*0Sstevel@tonic-gate show = 0; 368*0Sstevel@tonic-gate } 369*0Sstevel@tonic-gate 370*0Sstevel@tonic-gate if ( show ) { 371*0Sstevel@tonic-gate err = do_vals2text( ld, buf, vals, colp->ti_label, 372*0Sstevel@tonic-gate labelwidth, colp->ti_syntaxid, writeproc, writeparm, 373*0Sstevel@tonic-gate eol, rdncount, urlprefix ); 374*0Sstevel@tonic-gate } 375*0Sstevel@tonic-gate 376*0Sstevel@tonic-gate if ( freevals ) { 377*0Sstevel@tonic-gate ldap_value_free( vals ); 378*0Sstevel@tonic-gate } 379*0Sstevel@tonic-gate } 380*0Sstevel@tonic-gate } 381*0Sstevel@tonic-gate } 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate if ( html && !(( opts & LDAP_DISP_OPT_HTMLBODYONLY ) != 0 )) { 384*0Sstevel@tonic-gate sprintf( buf, "</BODY>%s</HTML>%s", eol, eol ); 385*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 386*0Sstevel@tonic-gate } 387*0Sstevel@tonic-gate 388*0Sstevel@tonic-gate free( dn ); 389*0Sstevel@tonic-gate if ( freebuf ) { 390*0Sstevel@tonic-gate free( buf ); 391*0Sstevel@tonic-gate } 392*0Sstevel@tonic-gate 393*0Sstevel@tonic-gate return( err ); 394*0Sstevel@tonic-gate } 395*0Sstevel@tonic-gate 396*0Sstevel@tonic-gate 397*0Sstevel@tonic-gate int 398*0Sstevel@tonic-gate ldap_entry2text_search( 399*0Sstevel@tonic-gate LDAP *ld, 400*0Sstevel@tonic-gate char *dn, /* if NULL, use entry */ 401*0Sstevel@tonic-gate char *base, /* if NULL, no search actions */ 402*0Sstevel@tonic-gate LDAPMessage *entry, /* if NULL, use dn */ 403*0Sstevel@tonic-gate struct ldap_disptmpl* tmpllist, /* if NULL, load default file */ 404*0Sstevel@tonic-gate char **defattrs, 405*0Sstevel@tonic-gate char ***defvals, 406*0Sstevel@tonic-gate writeptype writeproc, 407*0Sstevel@tonic-gate void *writeparm, 408*0Sstevel@tonic-gate char *eol, 409*0Sstevel@tonic-gate int rdncount, /* if 0, display full DN */ 410*0Sstevel@tonic-gate unsigned int opts 411*0Sstevel@tonic-gate ) 412*0Sstevel@tonic-gate { 413*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 414*0Sstevel@tonic-gate int rv; 415*0Sstevel@tonic-gate 416*0Sstevel@tonic-gate LOCK_LDAP(ld); 417*0Sstevel@tonic-gate #endif 418*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 255, "ldap_entry2text_search\n"), 0, 0, 0 ); 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 421*0Sstevel@tonic-gate rv = do_entry2text_search( ld, dn, base, entry, tmpllist, defattrs, 422*0Sstevel@tonic-gate defvals, writeproc, writeparm, eol, rdncount, opts, NULL ); 423*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 424*0Sstevel@tonic-gate return( rv ); 425*0Sstevel@tonic-gate #else 426*0Sstevel@tonic-gate return( do_entry2text_search( ld, dn, base, entry, tmpllist, defattrs, 427*0Sstevel@tonic-gate defvals, writeproc, writeparm, eol, rdncount, opts, NULL )); 428*0Sstevel@tonic-gate #endif 429*0Sstevel@tonic-gate } 430*0Sstevel@tonic-gate 431*0Sstevel@tonic-gate 432*0Sstevel@tonic-gate 433*0Sstevel@tonic-gate int 434*0Sstevel@tonic-gate ldap_entry2html_search( 435*0Sstevel@tonic-gate LDAP *ld, 436*0Sstevel@tonic-gate char *dn, /* if NULL, use entry */ 437*0Sstevel@tonic-gate char *base, /* if NULL, no search actions */ 438*0Sstevel@tonic-gate LDAPMessage *entry, /* if NULL, use dn */ 439*0Sstevel@tonic-gate struct ldap_disptmpl* tmpllist, /* if NULL, load default file */ 440*0Sstevel@tonic-gate char **defattrs, 441*0Sstevel@tonic-gate char ***defvals, 442*0Sstevel@tonic-gate writeptype writeproc, 443*0Sstevel@tonic-gate void *writeparm, 444*0Sstevel@tonic-gate char *eol, 445*0Sstevel@tonic-gate int rdncount, /* if 0, display full DN */ 446*0Sstevel@tonic-gate unsigned int opts, 447*0Sstevel@tonic-gate char *urlprefix 448*0Sstevel@tonic-gate ) 449*0Sstevel@tonic-gate { 450*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 451*0Sstevel@tonic-gate int rv; 452*0Sstevel@tonic-gate 453*0Sstevel@tonic-gate LOCK_LDAP(ld); 454*0Sstevel@tonic-gate #endif 455*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 256, "ldap_entry2html_search\n"), 0, 0, 0 ); 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 458*0Sstevel@tonic-gate rv = do_entry2text_search( ld, dn, base, entry, tmpllist, defattrs, 459*0Sstevel@tonic-gate defvals, writeproc, writeparm, eol, rdncount, opts, urlprefix ); 460*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 461*0Sstevel@tonic-gate return( rv ); 462*0Sstevel@tonic-gate #else 463*0Sstevel@tonic-gate return( do_entry2text_search( ld, dn, base, entry, tmpllist, defattrs, 464*0Sstevel@tonic-gate defvals, writeproc, writeparm, eol, rdncount, opts, urlprefix )); 465*0Sstevel@tonic-gate #endif 466*0Sstevel@tonic-gate } 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate 469*0Sstevel@tonic-gate static int 470*0Sstevel@tonic-gate do_entry2text_search( 471*0Sstevel@tonic-gate LDAP *ld, 472*0Sstevel@tonic-gate char *dn, /* if NULL, use entry */ 473*0Sstevel@tonic-gate char *base, /* if NULL, no search actions */ 474*0Sstevel@tonic-gate LDAPMessage *entry, /* if NULL, use dn */ 475*0Sstevel@tonic-gate struct ldap_disptmpl* tmpllist, /* if NULL, load default file */ 476*0Sstevel@tonic-gate char **defattrs, 477*0Sstevel@tonic-gate char ***defvals, 478*0Sstevel@tonic-gate writeptype writeproc, 479*0Sstevel@tonic-gate void *writeparm, 480*0Sstevel@tonic-gate char *eol, 481*0Sstevel@tonic-gate int rdncount, /* if 0, display full DN */ 482*0Sstevel@tonic-gate unsigned int opts, 483*0Sstevel@tonic-gate char *urlprefix 484*0Sstevel@tonic-gate ) 485*0Sstevel@tonic-gate { 486*0Sstevel@tonic-gate int err, freedn, freetmpls, html; 487*0Sstevel@tonic-gate char *buf, **fetchattrs, **vals; 488*0Sstevel@tonic-gate LDAPMessage *ldmp; 489*0Sstevel@tonic-gate struct ldap_disptmpl *tmpl; 490*0Sstevel@tonic-gate struct timeval timeout; 491*0Sstevel@tonic-gate 492*0Sstevel@tonic-gate if ( dn == NULL && entry == NULLMSG ) { 493*0Sstevel@tonic-gate ld->ld_errno = LDAP_PARAM_ERROR; 494*0Sstevel@tonic-gate return( ld->ld_errno ); 495*0Sstevel@tonic-gate } 496*0Sstevel@tonic-gate 497*0Sstevel@tonic-gate html = ( urlprefix != NULL ); 498*0Sstevel@tonic-gate 499*0Sstevel@tonic-gate timeout.tv_sec = SEARCH_TIMEOUT_SECS; 500*0Sstevel@tonic-gate timeout.tv_usec = 0; 501*0Sstevel@tonic-gate 502*0Sstevel@tonic-gate if (( buf = malloc( LDAP_DTMPL_BUFSIZ )) == NULL ) { 503*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 504*0Sstevel@tonic-gate return( ld->ld_errno ); 505*0Sstevel@tonic-gate } 506*0Sstevel@tonic-gate 507*0Sstevel@tonic-gate freedn = freetmpls = 0; 508*0Sstevel@tonic-gate tmpl = NULL; 509*0Sstevel@tonic-gate 510*0Sstevel@tonic-gate if ( tmpllist == NULL ) { 511*0Sstevel@tonic-gate if (( err = ldap_init_templates( TEMPLATEFILE, &tmpllist )) != 0 ) { 512*0Sstevel@tonic-gate sprintf( buf, "%sUnable to read template file %s (error %d)%s%s", 513*0Sstevel@tonic-gate html ? "<!-- " : "", TEMPLATEFILE, err, 514*0Sstevel@tonic-gate html ? "-->" : "", eol ); 515*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 516*0Sstevel@tonic-gate } 517*0Sstevel@tonic-gate freetmpls = 1; 518*0Sstevel@tonic-gate } 519*0Sstevel@tonic-gate 520*0Sstevel@tonic-gate if ( dn == NULL ) { 521*0Sstevel@tonic-gate if (( dn = ldap_get_dn( ld, entry )) == NULL ) { 522*0Sstevel@tonic-gate free( buf ); 523*0Sstevel@tonic-gate if ( freetmpls ) { 524*0Sstevel@tonic-gate ldap_free_templates( tmpllist ); 525*0Sstevel@tonic-gate } 526*0Sstevel@tonic-gate return( ld->ld_errno ); 527*0Sstevel@tonic-gate } 528*0Sstevel@tonic-gate freedn = 1; 529*0Sstevel@tonic-gate } 530*0Sstevel@tonic-gate 531*0Sstevel@tonic-gate 532*0Sstevel@tonic-gate if ( tmpllist != NULL ) { 533*0Sstevel@tonic-gate ldmp = NULLMSG; 534*0Sstevel@tonic-gate 535*0Sstevel@tonic-gate if ( entry == NULL ) { 536*0Sstevel@tonic-gate char *ocattrs[2]; 537*0Sstevel@tonic-gate 538*0Sstevel@tonic-gate ocattrs[0] = OCATTRNAME; 539*0Sstevel@tonic-gate ocattrs[1] = NULL; 540*0Sstevel@tonic-gate #ifdef CLDAP 541*0Sstevel@tonic-gate if ( LDAP_IS_CLDAP( ld )) 542*0Sstevel@tonic-gate err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, 543*0Sstevel@tonic-gate "objectClass=*", ocattrs, 0, &ldmp, NULL ); 544*0Sstevel@tonic-gate else 545*0Sstevel@tonic-gate #endif /* CLDAP */ 546*0Sstevel@tonic-gate err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, 547*0Sstevel@tonic-gate "objectClass=*", ocattrs, 0, &timeout, &ldmp ); 548*0Sstevel@tonic-gate 549*0Sstevel@tonic-gate if ( err == LDAP_SUCCESS ) { 550*0Sstevel@tonic-gate entry = ldap_first_entry( ld, ldmp ); 551*0Sstevel@tonic-gate } 552*0Sstevel@tonic-gate } 553*0Sstevel@tonic-gate 554*0Sstevel@tonic-gate if ( entry != NULL ) { 555*0Sstevel@tonic-gate vals = ldap_get_values( ld, entry, OCATTRNAME ); 556*0Sstevel@tonic-gate tmpl = ldap_oc2template( vals, tmpllist ); 557*0Sstevel@tonic-gate if ( vals != NULL ) { 558*0Sstevel@tonic-gate ldap_value_free( vals ); 559*0Sstevel@tonic-gate } 560*0Sstevel@tonic-gate } 561*0Sstevel@tonic-gate if ( ldmp != NULL ) { 562*0Sstevel@tonic-gate ldap_msgfree( ldmp ); 563*0Sstevel@tonic-gate } 564*0Sstevel@tonic-gate } 565*0Sstevel@tonic-gate 566*0Sstevel@tonic-gate entry = NULL; 567*0Sstevel@tonic-gate 568*0Sstevel@tonic-gate if ( tmpl == NULL ) { 569*0Sstevel@tonic-gate fetchattrs = NULL; 570*0Sstevel@tonic-gate } else { 571*0Sstevel@tonic-gate fetchattrs = ldap_tmplattrs( tmpl, NULL, 1, LDAP_SYN_OPT_DEFER ); 572*0Sstevel@tonic-gate } 573*0Sstevel@tonic-gate 574*0Sstevel@tonic-gate #ifdef CLDAP 575*0Sstevel@tonic-gate if ( LDAP_IS_CLDAP( ld )) 576*0Sstevel@tonic-gate err = cldap_search_s( ld, dn, LDAP_SCOPE_BASE, "objectClass=*", 577*0Sstevel@tonic-gate fetchattrs, 0, &ldmp, NULL ); 578*0Sstevel@tonic-gate else 579*0Sstevel@tonic-gate #endif /* CLDAP */ 580*0Sstevel@tonic-gate err = ldap_search_st( ld, dn, LDAP_SCOPE_BASE, "objectClass=*", 581*0Sstevel@tonic-gate fetchattrs, 0, &timeout, &ldmp ); 582*0Sstevel@tonic-gate 583*0Sstevel@tonic-gate if ( freedn ) { 584*0Sstevel@tonic-gate free( dn ); 585*0Sstevel@tonic-gate } 586*0Sstevel@tonic-gate if ( fetchattrs != NULL ) { 587*0Sstevel@tonic-gate ldap_value_free( fetchattrs ); 588*0Sstevel@tonic-gate } 589*0Sstevel@tonic-gate 590*0Sstevel@tonic-gate if ( err != LDAP_SUCCESS || 591*0Sstevel@tonic-gate ( entry = ldap_first_entry( ld, ldmp )) == NULL ) { 592*0Sstevel@tonic-gate if ( freetmpls ) { 593*0Sstevel@tonic-gate ldap_free_templates( tmpllist ); 594*0Sstevel@tonic-gate } 595*0Sstevel@tonic-gate free( buf ); 596*0Sstevel@tonic-gate return( ld->ld_errno ); 597*0Sstevel@tonic-gate } 598*0Sstevel@tonic-gate 599*0Sstevel@tonic-gate err = do_entry2text( ld, buf, base, entry, tmpl, defattrs, defvals, 600*0Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, opts, urlprefix ); 601*0Sstevel@tonic-gate 602*0Sstevel@tonic-gate free( buf ); 603*0Sstevel@tonic-gate if ( freetmpls ) { 604*0Sstevel@tonic-gate ldap_free_templates( tmpllist ); 605*0Sstevel@tonic-gate } 606*0Sstevel@tonic-gate ldap_msgfree( ldmp ); 607*0Sstevel@tonic-gate return( err ); 608*0Sstevel@tonic-gate } 609*0Sstevel@tonic-gate 610*0Sstevel@tonic-gate 611*0Sstevel@tonic-gate int 612*0Sstevel@tonic-gate ldap_vals2text( 613*0Sstevel@tonic-gate LDAP *ld, 614*0Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 615*0Sstevel@tonic-gate char **vals, 616*0Sstevel@tonic-gate char *label, 617*0Sstevel@tonic-gate int labelwidth, /* 0 means use default */ 618*0Sstevel@tonic-gate unsigned int syntaxid, 619*0Sstevel@tonic-gate writeptype writeproc, 620*0Sstevel@tonic-gate void *writeparm, 621*0Sstevel@tonic-gate char *eol, 622*0Sstevel@tonic-gate int rdncount 623*0Sstevel@tonic-gate ) 624*0Sstevel@tonic-gate { 625*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 626*0Sstevel@tonic-gate int rv; 627*0Sstevel@tonic-gate 628*0Sstevel@tonic-gate LOCK_LDAP(ld); 629*0Sstevel@tonic-gate #endif 630*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 257, "ldap_vals2text\n"), 0, 0, 0 ); 631*0Sstevel@tonic-gate 632*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 633*0Sstevel@tonic-gate rv = do_vals2text( ld, buf, vals, label, labelwidth, syntaxid, 634*0Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, NULL ); 635*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 636*0Sstevel@tonic-gate return( rv ); 637*0Sstevel@tonic-gate #else 638*0Sstevel@tonic-gate return( do_vals2text( ld, buf, vals, label, labelwidth, syntaxid, 639*0Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, NULL )); 640*0Sstevel@tonic-gate #endif 641*0Sstevel@tonic-gate } 642*0Sstevel@tonic-gate 643*0Sstevel@tonic-gate 644*0Sstevel@tonic-gate int 645*0Sstevel@tonic-gate ldap_vals2html( 646*0Sstevel@tonic-gate LDAP *ld, 647*0Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 648*0Sstevel@tonic-gate char **vals, 649*0Sstevel@tonic-gate char *label, 650*0Sstevel@tonic-gate int labelwidth, /* 0 means use default */ 651*0Sstevel@tonic-gate unsigned int syntaxid, 652*0Sstevel@tonic-gate writeptype writeproc, 653*0Sstevel@tonic-gate void *writeparm, 654*0Sstevel@tonic-gate char *eol, 655*0Sstevel@tonic-gate int rdncount, 656*0Sstevel@tonic-gate char *urlprefix 657*0Sstevel@tonic-gate ) 658*0Sstevel@tonic-gate { 659*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 660*0Sstevel@tonic-gate int rv; 661*0Sstevel@tonic-gate 662*0Sstevel@tonic-gate LOCK_LDAP(ld); 663*0Sstevel@tonic-gate #endif 664*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 258, "ldap_vals2html\n"), 0, 0, 0 ); 665*0Sstevel@tonic-gate 666*0Sstevel@tonic-gate if ( urlprefix == NULL ) { 667*0Sstevel@tonic-gate urlprefix = DEF_LDAP_URL_PREFIX; 668*0Sstevel@tonic-gate } 669*0Sstevel@tonic-gate 670*0Sstevel@tonic-gate #if defined( SUN ) && defined( _REENTRANT ) 671*0Sstevel@tonic-gate rv = do_vals2text( ld, buf, vals, label, labelwidth, syntaxid, 672*0Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, urlprefix ); 673*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 674*0Sstevel@tonic-gate return( rv ); 675*0Sstevel@tonic-gate #else 676*0Sstevel@tonic-gate return( do_vals2text( ld, buf, vals, label, labelwidth, syntaxid, 677*0Sstevel@tonic-gate writeproc, writeparm, eol, rdncount, urlprefix )); 678*0Sstevel@tonic-gate #endif 679*0Sstevel@tonic-gate } 680*0Sstevel@tonic-gate 681*0Sstevel@tonic-gate 682*0Sstevel@tonic-gate static int 683*0Sstevel@tonic-gate do_vals2text( 684*0Sstevel@tonic-gate LDAP *ld, 685*0Sstevel@tonic-gate char *buf, /* NULL for "use internal" */ 686*0Sstevel@tonic-gate char **vals, 687*0Sstevel@tonic-gate char *label, 688*0Sstevel@tonic-gate int labelwidth, /* 0 means use default */ 689*0Sstevel@tonic-gate unsigned int syntaxid, 690*0Sstevel@tonic-gate writeptype writeproc, 691*0Sstevel@tonic-gate void *writeparm, 692*0Sstevel@tonic-gate char *eol, 693*0Sstevel@tonic-gate int rdncount, 694*0Sstevel@tonic-gate char *urlprefix 695*0Sstevel@tonic-gate ) 696*0Sstevel@tonic-gate { 697*0Sstevel@tonic-gate int i, html, writeoutval, freebuf, notascii; 698*0Sstevel@tonic-gate char *p, *s, *outval; 699*0Sstevel@tonic-gate 700*0Sstevel@tonic-gate 701*0Sstevel@tonic-gate if ( vals == NULL ) { 702*0Sstevel@tonic-gate return( LDAP_SUCCESS ); 703*0Sstevel@tonic-gate } 704*0Sstevel@tonic-gate 705*0Sstevel@tonic-gate html = ( urlprefix != NULL ); 706*0Sstevel@tonic-gate 707*0Sstevel@tonic-gate switch( LDAP_GET_SYN_TYPE( syntaxid )) { 708*0Sstevel@tonic-gate case LDAP_SYN_TYPE_TEXT: 709*0Sstevel@tonic-gate case LDAP_SYN_TYPE_BOOLEAN: 710*0Sstevel@tonic-gate break; /* we only bother with these two types... */ 711*0Sstevel@tonic-gate default: 712*0Sstevel@tonic-gate return( LDAP_SUCCESS ); 713*0Sstevel@tonic-gate } 714*0Sstevel@tonic-gate 715*0Sstevel@tonic-gate if ( labelwidth == 0 || labelwidth < 0 ) { 716*0Sstevel@tonic-gate labelwidth = DEF_LABEL_WIDTH; 717*0Sstevel@tonic-gate } 718*0Sstevel@tonic-gate 719*0Sstevel@tonic-gate if ( buf == NULL ) { 720*0Sstevel@tonic-gate if (( buf = malloc( LDAP_DTMPL_BUFSIZ )) == NULL ) { 721*0Sstevel@tonic-gate ld->ld_errno = LDAP_NO_MEMORY; 722*0Sstevel@tonic-gate return( ld->ld_errno ); 723*0Sstevel@tonic-gate } 724*0Sstevel@tonic-gate freebuf = 1; 725*0Sstevel@tonic-gate } else { 726*0Sstevel@tonic-gate freebuf = 0; 727*0Sstevel@tonic-gate } 728*0Sstevel@tonic-gate 729*0Sstevel@tonic-gate output_label( buf, label, labelwidth, writeproc, writeparm, eol, html ); 730*0Sstevel@tonic-gate 731*0Sstevel@tonic-gate for ( i = 0; vals[ i ] != NULL; ++i ) { 732*0Sstevel@tonic-gate for ( p = vals[ i ]; *p != '\0'; ++p ) { 733*0Sstevel@tonic-gate if ( !isascii( *p )) { 734*0Sstevel@tonic-gate break; 735*0Sstevel@tonic-gate } 736*0Sstevel@tonic-gate } 737*0Sstevel@tonic-gate notascii = ( *p != '\0' ); 738*0Sstevel@tonic-gate outval = notascii ? "(unable to display non-ASCII text value)" 739*0Sstevel@tonic-gate : vals[ i ]; 740*0Sstevel@tonic-gate 741*0Sstevel@tonic-gate writeoutval = 0; /* if non-zero, write outval after switch */ 742*0Sstevel@tonic-gate 743*0Sstevel@tonic-gate switch( syntaxid ) { 744*0Sstevel@tonic-gate case LDAP_SYN_CASEIGNORESTR: 745*0Sstevel@tonic-gate ++writeoutval; 746*0Sstevel@tonic-gate break; 747*0Sstevel@tonic-gate 748*0Sstevel@tonic-gate case LDAP_SYN_RFC822ADDR: 749*0Sstevel@tonic-gate if ( html ) { 750*0Sstevel@tonic-gate strcpy( buf, "<DD><A HREF=\"mailto:" ); 751*0Sstevel@tonic-gate strcat_escaped( buf, outval ); 752*0Sstevel@tonic-gate sprintf( buf + strlen( buf ), "\">%s</A><BR>%s", outval, eol ); 753*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 754*0Sstevel@tonic-gate } else { 755*0Sstevel@tonic-gate ++writeoutval; 756*0Sstevel@tonic-gate } 757*0Sstevel@tonic-gate break; 758*0Sstevel@tonic-gate 759*0Sstevel@tonic-gate case LDAP_SYN_DN: /* for now */ 760*0Sstevel@tonic-gate output_dn( buf, outval, labelwidth, rdncount, writeproc, 761*0Sstevel@tonic-gate writeparm, eol, urlprefix ); 762*0Sstevel@tonic-gate break; 763*0Sstevel@tonic-gate 764*0Sstevel@tonic-gate case LDAP_SYN_MULTILINESTR: 765*0Sstevel@tonic-gate if ( i > 0 && !html ) { 766*0Sstevel@tonic-gate output_label( buf, label, labelwidth, writeproc, 767*0Sstevel@tonic-gate writeparm, eol, html ); 768*0Sstevel@tonic-gate } 769*0Sstevel@tonic-gate 770*0Sstevel@tonic-gate p = s = outval; 771*0Sstevel@tonic-gate while (( s = strchr( s, '$' )) != NULL ) { 772*0Sstevel@tonic-gate *s++ = '\0'; 773*0Sstevel@tonic-gate while ( isspace( *s )) { 774*0Sstevel@tonic-gate ++s; 775*0Sstevel@tonic-gate } 776*0Sstevel@tonic-gate if ( html ) { 777*0Sstevel@tonic-gate sprintf( buf, "<DD>%s<BR>%s", p, eol ); 778*0Sstevel@tonic-gate } else { 779*0Sstevel@tonic-gate sprintf( buf, "%-*s%s%s", labelwidth, " ", p, eol ); 780*0Sstevel@tonic-gate } 781*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 782*0Sstevel@tonic-gate p = s; 783*0Sstevel@tonic-gate } 784*0Sstevel@tonic-gate outval = p; 785*0Sstevel@tonic-gate ++writeoutval; 786*0Sstevel@tonic-gate break; 787*0Sstevel@tonic-gate 788*0Sstevel@tonic-gate case LDAP_SYN_BOOLEAN: 789*0Sstevel@tonic-gate outval = toupper( outval[ 0 ] ) == 'T' ? "TRUE" : "FALSE"; 790*0Sstevel@tonic-gate ++writeoutval; 791*0Sstevel@tonic-gate break; 792*0Sstevel@tonic-gate 793*0Sstevel@tonic-gate case LDAP_SYN_TIME: 794*0Sstevel@tonic-gate case LDAP_SYN_DATE: 795*0Sstevel@tonic-gate outval = time2text( outval, syntaxid == LDAP_SYN_DATE ); 796*0Sstevel@tonic-gate ++writeoutval; 797*0Sstevel@tonic-gate break; 798*0Sstevel@tonic-gate 799*0Sstevel@tonic-gate case LDAP_SYN_LABELEDURL: 800*0Sstevel@tonic-gate if ( !notascii && ( p = strchr( outval, '$' )) != NULL ) { 801*0Sstevel@tonic-gate *p++ = '\0'; 802*0Sstevel@tonic-gate while ( isspace( *p )) { 803*0Sstevel@tonic-gate ++p; 804*0Sstevel@tonic-gate } 805*0Sstevel@tonic-gate s = outval; 806*0Sstevel@tonic-gate } else if ( !notascii && ( s = strchr( outval, ' ' )) != NULL ) { 807*0Sstevel@tonic-gate *s++ = '\0'; 808*0Sstevel@tonic-gate while ( isspace( *s )) { 809*0Sstevel@tonic-gate ++s; 810*0Sstevel@tonic-gate } 811*0Sstevel@tonic-gate p = outval; 812*0Sstevel@tonic-gate } else { 813*0Sstevel@tonic-gate s = "URL"; 814*0Sstevel@tonic-gate p = outval; 815*0Sstevel@tonic-gate } 816*0Sstevel@tonic-gate 817*0Sstevel@tonic-gate /* 818*0Sstevel@tonic-gate * at this point `s' points to the label & `p' to the URL 819*0Sstevel@tonic-gate */ 820*0Sstevel@tonic-gate if ( html ) { 821*0Sstevel@tonic-gate sprintf( buf, "<DD><A HREF=\"%s\">%s</A><BR>%s", p, s, eol ); 822*0Sstevel@tonic-gate } else { 823*0Sstevel@tonic-gate sprintf( buf, "%-*s%s%s%-*s%s%s", labelwidth, " ", 824*0Sstevel@tonic-gate s, eol, labelwidth + 2, " ",p , eol ); 825*0Sstevel@tonic-gate } 826*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 827*0Sstevel@tonic-gate break; 828*0Sstevel@tonic-gate 829*0Sstevel@tonic-gate default: 830*0Sstevel@tonic-gate sprintf( buf, " Can't display item type %ld%s", 831*0Sstevel@tonic-gate syntaxid, eol ); 832*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 833*0Sstevel@tonic-gate } 834*0Sstevel@tonic-gate 835*0Sstevel@tonic-gate if ( writeoutval ) { 836*0Sstevel@tonic-gate if ( html ) { 837*0Sstevel@tonic-gate sprintf( buf, "<DD>%s<BR>%s", outval, eol ); 838*0Sstevel@tonic-gate } else { 839*0Sstevel@tonic-gate sprintf( buf, "%-*s%s%s", labelwidth, " ", outval, eol ); 840*0Sstevel@tonic-gate } 841*0Sstevel@tonic-gate (*writeproc)( writeparm, buf, strlen( buf )); 842*0Sstevel@tonic-gate } 843*0Sstevel@tonic-gate } 844*0Sstevel@tonic-gate 845*0Sstevel@tonic-gate if ( freebuf ) { 846*0Sstevel@tonic-gate free( buf ); 847*0Sstevel@tonic-gate } 848*0Sstevel@tonic-gate 849*0Sstevel@tonic-gate return( LDAP_SUCCESS ); 850*0Sstevel@tonic-gate } 851*0Sstevel@tonic-gate 852*0Sstevel@tonic-gate 853*0Sstevel@tonic-gate static int 854*0Sstevel@tonic-gate max_label_len( struct ldap_disptmpl *tmpl ) 855*0Sstevel@tonic-gate { 856*0Sstevel@tonic-gate struct ldap_tmplitem *rowp, *colp; 857*0Sstevel@tonic-gate int len, maxlen; 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate maxlen = 0; 860*0Sstevel@tonic-gate 861*0Sstevel@tonic-gate for ( rowp = ldap_first_tmplrow( tmpl ); rowp != NULLTMPLITEM; 862*0Sstevel@tonic-gate rowp = ldap_next_tmplrow( tmpl, rowp )) { 863*0Sstevel@tonic-gate for ( colp = ldap_first_tmplcol( tmpl, rowp ); colp != NULLTMPLITEM; 864*0Sstevel@tonic-gate colp = ldap_next_tmplcol( tmpl, rowp, colp )) { 865*0Sstevel@tonic-gate if (( len = strlen( colp->ti_label )) > maxlen ) { 866*0Sstevel@tonic-gate maxlen = len; 867*0Sstevel@tonic-gate } 868*0Sstevel@tonic-gate } 869*0Sstevel@tonic-gate } 870*0Sstevel@tonic-gate 871*0Sstevel@tonic-gate return( maxlen ); 872*0Sstevel@tonic-gate } 873*0Sstevel@tonic-gate 874*0Sstevel@tonic-gate 875*0Sstevel@tonic-gate static int 876*0Sstevel@tonic-gate output_label( char *buf, char *label, int width, writeptype writeproc, 877*0Sstevel@tonic-gate void *writeparm, char *eol, int html ) 878*0Sstevel@tonic-gate { 879*0Sstevel@tonic-gate char *p; 880*0Sstevel@tonic-gate 881*0Sstevel@tonic-gate if ( html ) { 882*0Sstevel@tonic-gate sprintf( buf, "<DT><B>%s</B>", label ); 883*0Sstevel@tonic-gate } else { 884*0Sstevel@tonic-gate sprintf( buf, " %s:", label ); 885*0Sstevel@tonic-gate p = buf + strlen( buf ); 886*0Sstevel@tonic-gate 887*0Sstevel@tonic-gate while ( p - buf < width ) { 888*0Sstevel@tonic-gate *p++ = ' '; 889*0Sstevel@tonic-gate } 890*0Sstevel@tonic-gate 891*0Sstevel@tonic-gate *p = '\0'; 892*0Sstevel@tonic-gate strcat( buf, eol ); 893*0Sstevel@tonic-gate } 894*0Sstevel@tonic-gate 895*0Sstevel@tonic-gate return ((*writeproc)( writeparm, buf, strlen( buf ))); 896*0Sstevel@tonic-gate } 897*0Sstevel@tonic-gate 898*0Sstevel@tonic-gate 899*0Sstevel@tonic-gate static int 900*0Sstevel@tonic-gate output_dn( char *buf, char *dn, int width, int rdncount, 901*0Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, char *urlprefix ) 902*0Sstevel@tonic-gate { 903*0Sstevel@tonic-gate char **dnrdns; 904*0Sstevel@tonic-gate int i; 905*0Sstevel@tonic-gate 906*0Sstevel@tonic-gate if (( dnrdns = ldap_explode_dn( dn, 1 )) == NULL ) { 907*0Sstevel@tonic-gate return( -1 ); 908*0Sstevel@tonic-gate } 909*0Sstevel@tonic-gate 910*0Sstevel@tonic-gate if ( urlprefix != NULL ) { 911*0Sstevel@tonic-gate sprintf( buf, "<DD><A HREF=\"%s", urlprefix ); 912*0Sstevel@tonic-gate strcat_escaped( buf, dn ); 913*0Sstevel@tonic-gate strcat( buf, "\">" ); 914*0Sstevel@tonic-gate } else if ( width > 0 ) { 915*0Sstevel@tonic-gate sprintf( buf, "%-*s", width, " " ); 916*0Sstevel@tonic-gate } else { 917*0Sstevel@tonic-gate *buf = '\0'; 918*0Sstevel@tonic-gate } 919*0Sstevel@tonic-gate 920*0Sstevel@tonic-gate for ( i = 0; dnrdns[ i ] != NULL && ( rdncount == 0 || i < rdncount ); 921*0Sstevel@tonic-gate ++i ) { 922*0Sstevel@tonic-gate if ( i > 0 ) { 923*0Sstevel@tonic-gate strcat( buf, ", " ); 924*0Sstevel@tonic-gate } 925*0Sstevel@tonic-gate strcat( buf, dnrdns[ i ] ); 926*0Sstevel@tonic-gate } 927*0Sstevel@tonic-gate 928*0Sstevel@tonic-gate if ( urlprefix != NULL ) { 929*0Sstevel@tonic-gate strcat( buf, "</A><BR>" ); 930*0Sstevel@tonic-gate } 931*0Sstevel@tonic-gate 932*0Sstevel@tonic-gate ldap_value_free( dnrdns ); 933*0Sstevel@tonic-gate 934*0Sstevel@tonic-gate strcat( buf, eol ); 935*0Sstevel@tonic-gate 936*0Sstevel@tonic-gate return ((*writeproc)( writeparm, buf, strlen( buf ))); 937*0Sstevel@tonic-gate } 938*0Sstevel@tonic-gate 939*0Sstevel@tonic-gate 940*0Sstevel@tonic-gate 941*0Sstevel@tonic-gate #define HREF_CHAR_ACCEPTABLE( c ) (( c >= '-' && c <= '9' ) || \ 942*0Sstevel@tonic-gate ( c >= '@' && c <= 'Z' ) || \ 943*0Sstevel@tonic-gate ( c == '_' ) || \ 944*0Sstevel@tonic-gate ( c >= 'a' && c <= 'z' )) 945*0Sstevel@tonic-gate 946*0Sstevel@tonic-gate static void 947*0Sstevel@tonic-gate strcat_escaped( char *s1, char *s2 ) 948*0Sstevel@tonic-gate { 949*0Sstevel@tonic-gate char *p, *q; 950*0Sstevel@tonic-gate char *hexdig = "0123456789ABCDEF"; 951*0Sstevel@tonic-gate 952*0Sstevel@tonic-gate p = s1 + strlen( s1 ); 953*0Sstevel@tonic-gate for ( q = s2; *q != '\0'; ++q ) { 954*0Sstevel@tonic-gate if ( HREF_CHAR_ACCEPTABLE( *q )) { 955*0Sstevel@tonic-gate *p++ = *q; 956*0Sstevel@tonic-gate } else { 957*0Sstevel@tonic-gate *p++ = '%'; 958*0Sstevel@tonic-gate *p++ = hexdig[ *q >> 4 ]; 959*0Sstevel@tonic-gate *p++ = hexdig[ *q & 0x0F ]; 960*0Sstevel@tonic-gate } 961*0Sstevel@tonic-gate } 962*0Sstevel@tonic-gate 963*0Sstevel@tonic-gate *p = '\0'; 964*0Sstevel@tonic-gate } 965*0Sstevel@tonic-gate 966*0Sstevel@tonic-gate 967*0Sstevel@tonic-gate #define GET2BYTENUM( p ) (( *p - '0' ) * 10 + ( *(p+1) - '0' )) 968*0Sstevel@tonic-gate 969*0Sstevel@tonic-gate static char * 970*0Sstevel@tonic-gate time2text( char *ldtimestr, int dateonly ) 971*0Sstevel@tonic-gate { 972*0Sstevel@tonic-gate struct tm t; 973*0Sstevel@tonic-gate char *p, zone, *fmterr = "badly formatted time"; 974*0Sstevel@tonic-gate time_t gmttime; 975*0Sstevel@tonic-gate int century; 976*0Sstevel@tonic-gate static char timestr[128]; 977*0Sstevel@tonic-gate 978*0Sstevel@tonic-gate memset( (char *)&t, 0, sizeof( struct tm )); 979*0Sstevel@tonic-gate if ( (int) strlen( ldtimestr ) < 13 ) { 980*0Sstevel@tonic-gate return( fmterr ); 981*0Sstevel@tonic-gate } 982*0Sstevel@tonic-gate 983*0Sstevel@tonic-gate for ( p = ldtimestr; p - ldtimestr < 12; ++p ) { 984*0Sstevel@tonic-gate if ( !isdigit( *p )) { 985*0Sstevel@tonic-gate return( fmterr ); 986*0Sstevel@tonic-gate } 987*0Sstevel@tonic-gate } 988*0Sstevel@tonic-gate 989*0Sstevel@tonic-gate p = ldtimestr; 990*0Sstevel@tonic-gate century = GET2BYTENUM( p ) * 100; p += 2; 991*0Sstevel@tonic-gate century += GET2BYTENUM( p ); p += 2; 992*0Sstevel@tonic-gate /* tm_year is the offset of number of years from TM_YEAR_BASE */ 993*0Sstevel@tonic-gate t.tm_year = century - TM_YEAR_BASE; 994*0Sstevel@tonic-gate t.tm_mon = GET2BYTENUM( p ) - 1; p += 2; 995*0Sstevel@tonic-gate t.tm_mday = GET2BYTENUM( p ); p += 2; 996*0Sstevel@tonic-gate t.tm_hour = GET2BYTENUM( p ); p += 2; 997*0Sstevel@tonic-gate t.tm_min = GET2BYTENUM( p ); p += 2; 998*0Sstevel@tonic-gate t.tm_sec = GET2BYTENUM( p ); p += 2; 999*0Sstevel@tonic-gate 1000*0Sstevel@tonic-gate /*strftime will return for e.g. Thu Aug 19 2001 */ 1001*0Sstevel@tonic-gate if (strftime(timestr, sizeof(timestr), "%a %b %d %Y", &t) == 0) { 1002*0Sstevel@tonic-gate return( fmterr ); 1003*0Sstevel@tonic-gate } 1004*0Sstevel@tonic-gate if (dateonly) { 1005*0Sstevel@tonic-gate strcpy(timestr + 11, timestr + 20); 1006*0Sstevel@tonic-gate } 1007*0Sstevel@tonic-gate return( timestr ); 1008*0Sstevel@tonic-gate } 1009*0Sstevel@tonic-gate 1010*0Sstevel@tonic-gate 1011*0Sstevel@tonic-gate 1012*0Sstevel@tonic-gate /* gtime.c - inverse gmtime */ 1013*0Sstevel@tonic-gate 1014*0Sstevel@tonic-gate #if !defined( MACOS ) && !defined( _WIN32 ) && !defined( DOS ) 1015*0Sstevel@tonic-gate #include <sys/time.h> 1016*0Sstevel@tonic-gate #endif /* !MACOS */ 1017*0Sstevel@tonic-gate 1018*0Sstevel@tonic-gate /* gtime(): the inverse of localtime(). 1019*0Sstevel@tonic-gate This routine was supplied by Mike Accetta at CMU many years ago. 1020*0Sstevel@tonic-gate */ 1021*0Sstevel@tonic-gate 1022*0Sstevel@tonic-gate static int dmsize[] = { 1023*0Sstevel@tonic-gate 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 1024*0Sstevel@tonic-gate }; 1025*0Sstevel@tonic-gate 1026*0Sstevel@tonic-gate #define dysize(y) \ 1027*0Sstevel@tonic-gate (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366))) 1028*0Sstevel@tonic-gate 1029*0Sstevel@tonic-gate #define YEAR(y) ((y) >= 100 ? (y) : (y) + 1900) 1030*0Sstevel@tonic-gate 1031*0Sstevel@tonic-gate /* */ 1032*0Sstevel@tonic-gate 1033*0Sstevel@tonic-gate static time_t gtime ( struct tm *tm ) 1034*0Sstevel@tonic-gate { 1035*0Sstevel@tonic-gate register int i, 1036*0Sstevel@tonic-gate sec, 1037*0Sstevel@tonic-gate mins, 1038*0Sstevel@tonic-gate hour, 1039*0Sstevel@tonic-gate mday, 1040*0Sstevel@tonic-gate mon, 1041*0Sstevel@tonic-gate year; 1042*0Sstevel@tonic-gate register time_t result; 1043*0Sstevel@tonic-gate 1044*0Sstevel@tonic-gate if ((sec = tm -> tm_sec) < 0 || sec > 59 1045*0Sstevel@tonic-gate || (mins = tm -> tm_min) < 0 || mins > 59 1046*0Sstevel@tonic-gate || (hour = tm -> tm_hour) < 0 || hour > 24 1047*0Sstevel@tonic-gate || (mday = tm -> tm_mday) < 1 || mday > 31 1048*0Sstevel@tonic-gate || (mon = tm -> tm_mon + 1) < 1 || mon > 12) 1049*0Sstevel@tonic-gate return ((time_t) -1); 1050*0Sstevel@tonic-gate if (hour == 24) { 1051*0Sstevel@tonic-gate hour = 0; 1052*0Sstevel@tonic-gate mday++; 1053*0Sstevel@tonic-gate } 1054*0Sstevel@tonic-gate year = YEAR (tm -> tm_year); 1055*0Sstevel@tonic-gate 1056*0Sstevel@tonic-gate result = 0L; 1057*0Sstevel@tonic-gate for (i = 1970; i < year; i++) 1058*0Sstevel@tonic-gate result += dysize (i); 1059*0Sstevel@tonic-gate if (dysize (year) == 366 && mon >= 3) 1060*0Sstevel@tonic-gate result++; 1061*0Sstevel@tonic-gate while (--mon) 1062*0Sstevel@tonic-gate result += dmsize[mon - 1]; 1063*0Sstevel@tonic-gate result += mday - 1; 1064*0Sstevel@tonic-gate result = 24 * result + hour; 1065*0Sstevel@tonic-gate result = 60 * result + mins; 1066*0Sstevel@tonic-gate result = 60 * result + sec; 1067*0Sstevel@tonic-gate 1068*0Sstevel@tonic-gate return result; 1069*0Sstevel@tonic-gate } 1070*0Sstevel@tonic-gate 1071*0Sstevel@tonic-gate static int 1072*0Sstevel@tonic-gate searchaction( LDAP *ld, char *buf, char *base, LDAPMessage *entry, char *dn, 1073*0Sstevel@tonic-gate struct ldap_tmplitem *tip, int labelwidth, int rdncount, 1074*0Sstevel@tonic-gate writeptype writeproc, void *writeparm, char *eol, char *urlprefix ) 1075*0Sstevel@tonic-gate { 1076*0Sstevel@tonic-gate int err, lderr, i, count, html; 1077*0Sstevel@tonic-gate char **vals, **members; 1078*0Sstevel@tonic-gate char *value, *filtpattern, *attr, *selectname; 1079*0Sstevel@tonic-gate char *retattrs[2], filter[ 256 ]; 1080*0Sstevel@tonic-gate LDAPMessage *ldmp; 1081*0Sstevel@tonic-gate struct timeval timeout; 1082*0Sstevel@tonic-gate 1083*0Sstevel@tonic-gate html = ( urlprefix != NULL ); 1084*0Sstevel@tonic-gate 1085*0Sstevel@tonic-gate for ( i = 0; tip->ti_args != NULL && tip->ti_args[ i ] != NULL; ++i ) { 1086*0Sstevel@tonic-gate ; 1087*0Sstevel@tonic-gate } 1088*0Sstevel@tonic-gate if ( i < 3 ) { 1089*0Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 1090*0Sstevel@tonic-gate } 1091*0Sstevel@tonic-gate attr = tip->ti_args[ 0 ]; 1092*0Sstevel@tonic-gate filtpattern = tip->ti_args[ 1 ]; 1093*0Sstevel@tonic-gate retattrs[ 0 ] = tip->ti_args[ 2 ]; 1094*0Sstevel@tonic-gate retattrs[ 1 ] = NULL; 1095*0Sstevel@tonic-gate selectname = tip->ti_args[ 3 ]; 1096*0Sstevel@tonic-gate 1097*0Sstevel@tonic-gate vals = NULL; 1098*0Sstevel@tonic-gate if ( attr == NULL ) { 1099*0Sstevel@tonic-gate value = NULL; 1100*0Sstevel@tonic-gate } else if ( strcasecmp( attr, "-dnb" ) == 0 ) { 1101*0Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 1102*0Sstevel@tonic-gate } else if ( strcasecmp( attr, "-dnt" ) == 0 ) { 1103*0Sstevel@tonic-gate value = dn; 1104*0Sstevel@tonic-gate } else if (( vals = ldap_get_values( ld, entry, attr )) != NULL ) { 1105*0Sstevel@tonic-gate value = vals[ 0 ]; 1106*0Sstevel@tonic-gate } else { 1107*0Sstevel@tonic-gate value = NULL; 1108*0Sstevel@tonic-gate } 1109*0Sstevel@tonic-gate 1110*0Sstevel@tonic-gate ldap_build_filter( filter, sizeof( filter ), filtpattern, NULL, NULL, NULL, 1111*0Sstevel@tonic-gate value, NULL ); 1112*0Sstevel@tonic-gate 1113*0Sstevel@tonic-gate if ( html ) { 1114*0Sstevel@tonic-gate /* 1115*0Sstevel@tonic-gate * if we are generating HTML, we add an HREF link that embodies this 1116*0Sstevel@tonic-gate * search action as an LDAP URL, instead of actually doing the search 1117*0Sstevel@tonic-gate * now. 1118*0Sstevel@tonic-gate */ 1119*0Sstevel@tonic-gate sprintf( buf, "<DT><A HREF=\"%s", urlprefix ); 1120*0Sstevel@tonic-gate if ( base != NULL ) { 1121*0Sstevel@tonic-gate strcat_escaped( buf, base ); 1122*0Sstevel@tonic-gate } 1123*0Sstevel@tonic-gate strcat( buf, "??sub?" ); 1124*0Sstevel@tonic-gate strcat_escaped( buf, filter ); 1125*0Sstevel@tonic-gate sprintf( buf + strlen( buf ), "\"><B>%s</B></A><DD><BR>%s", 1126*0Sstevel@tonic-gate tip->ti_label, eol ); 1127*0Sstevel@tonic-gate if ((*writeproc)( writeparm, buf, strlen( buf )) < 0 ) { 1128*0Sstevel@tonic-gate return( LDAP_LOCAL_ERROR ); 1129*0Sstevel@tonic-gate } 1130*0Sstevel@tonic-gate return( LDAP_SUCCESS ); 1131*0Sstevel@tonic-gate } 1132*0Sstevel@tonic-gate 1133*0Sstevel@tonic-gate timeout.tv_sec = SEARCH_TIMEOUT_SECS; 1134*0Sstevel@tonic-gate timeout.tv_usec = 0; 1135*0Sstevel@tonic-gate 1136*0Sstevel@tonic-gate #ifdef CLDAP 1137*0Sstevel@tonic-gate if ( LDAP_IS_CLDAP( ld )) 1138*0Sstevel@tonic-gate lderr = cldap_search_s( ld, base, LDAP_SCOPE_SUBTREE, filter, retattrs, 1139*0Sstevel@tonic-gate 0, &ldmp, NULL ); 1140*0Sstevel@tonic-gate else 1141*0Sstevel@tonic-gate #endif /* CLDAP */ 1142*0Sstevel@tonic-gate lderr = ldap_search_st( ld, base, LDAP_SCOPE_SUBTREE, filter, retattrs, 1143*0Sstevel@tonic-gate 0, &timeout, &ldmp ); 1144*0Sstevel@tonic-gate 1145*0Sstevel@tonic-gate if ( lderr == LDAP_SUCCESS || NONFATAL_LDAP_ERR( lderr )) { 1146*0Sstevel@tonic-gate if (( count = ldap_count_entries( ld, ldmp )) > 0 ) { 1147*0Sstevel@tonic-gate if (( members = (char **)malloc( (count + 1) * sizeof(char *))) 1148*0Sstevel@tonic-gate == NULL ) { 1149*0Sstevel@tonic-gate err = LDAP_NO_MEMORY; 1150*0Sstevel@tonic-gate } else { 1151*0Sstevel@tonic-gate for ( i = 0, entry = ldap_first_entry( ld, ldmp ); 1152*0Sstevel@tonic-gate entry != NULL; 1153*0Sstevel@tonic-gate entry = ldap_next_entry( ld, entry ), ++i ) { 1154*0Sstevel@tonic-gate members[ i ] = ldap_get_dn( ld, entry ); 1155*0Sstevel@tonic-gate } 1156*0Sstevel@tonic-gate members[ i ] = NULL; 1157*0Sstevel@tonic-gate 1158*0Sstevel@tonic-gate ldap_sort_values( ld, members, ldap_sort_strcasecmp ); 1159*0Sstevel@tonic-gate 1160*0Sstevel@tonic-gate err = do_vals2text( ld, NULL, members, tip->ti_label, 1161*0Sstevel@tonic-gate html ? -1 : 0, LDAP_SYN_DN, writeproc, writeparm, 1162*0Sstevel@tonic-gate eol, rdncount, urlprefix ); 1163*0Sstevel@tonic-gate 1164*0Sstevel@tonic-gate ldap_value_free( members ); 1165*0Sstevel@tonic-gate } 1166*0Sstevel@tonic-gate } 1167*0Sstevel@tonic-gate ldap_msgfree( ldmp ); 1168*0Sstevel@tonic-gate } 1169*0Sstevel@tonic-gate 1170*0Sstevel@tonic-gate 1171*0Sstevel@tonic-gate if ( vals != NULL ) { 1172*0Sstevel@tonic-gate ldap_value_free( vals ); 1173*0Sstevel@tonic-gate } 1174*0Sstevel@tonic-gate 1175*0Sstevel@tonic-gate return(( err == LDAP_SUCCESS ) ? lderr : err ); 1176*0Sstevel@tonic-gate } 1177