1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 2001-2002 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 /* 10*0Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public 11*0Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file 12*0Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of 13*0Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/ 14*0Sstevel@tonic-gate * 15*0Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS 16*0Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 17*0Sstevel@tonic-gate * implied. See the License for the specific language governing 18*0Sstevel@tonic-gate * rights and limitations under the License. 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released 21*0Sstevel@tonic-gate * March 31, 1998. 22*0Sstevel@tonic-gate * 23*0Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape 24*0Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 25*0Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All 26*0Sstevel@tonic-gate * Rights Reserved. 27*0Sstevel@tonic-gate * 28*0Sstevel@tonic-gate * Contributor(s): 29*0Sstevel@tonic-gate */ 30*0Sstevel@tonic-gate /* 31*0Sstevel@tonic-gate * Copyright (c) 1993, 1994 Regents of the University of Michigan. 32*0Sstevel@tonic-gate * All rights reserved. 33*0Sstevel@tonic-gate * 34*0Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted 35*0Sstevel@tonic-gate * provided that this notice is preserved and that due credit is given 36*0Sstevel@tonic-gate * to the University of Michigan at Ann Arbor. The name of the University 37*0Sstevel@tonic-gate * may not be used to endorse or promote products derived from this 38*0Sstevel@tonic-gate * software without specific prior written permission. This software 39*0Sstevel@tonic-gate * is provided ``as is'' without express or implied warranty. 40*0Sstevel@tonic-gate */ 41*0Sstevel@tonic-gate /* 42*0Sstevel@tonic-gate * disptmpl.c: display template library routines for LDAP clients 43*0Sstevel@tonic-gate */ 44*0Sstevel@tonic-gate 45*0Sstevel@tonic-gate #include "ldap-int.h" 46*0Sstevel@tonic-gate #include "disptmpl.h" 47*0Sstevel@tonic-gate 48*0Sstevel@tonic-gate static void free_disptmpl( struct ldap_disptmpl *tmpl ); 49*0Sstevel@tonic-gate static int read_next_tmpl( char **bufp, long *blenp, 50*0Sstevel@tonic-gate struct ldap_disptmpl **tmplp, int dtversion ); 51*0Sstevel@tonic-gate 52*0Sstevel@tonic-gate static char *tmploptions[] = { 53*0Sstevel@tonic-gate "addable", "modrdn", 54*0Sstevel@tonic-gate "altview", 55*0Sstevel@tonic-gate NULL 56*0Sstevel@tonic-gate }; 57*0Sstevel@tonic-gate 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate static unsigned long tmploptvals[] = { 60*0Sstevel@tonic-gate LDAP_DTMPL_OPT_ADDABLE, LDAP_DTMPL_OPT_ALLOWMODRDN, 61*0Sstevel@tonic-gate LDAP_DTMPL_OPT_ALTVIEW, 62*0Sstevel@tonic-gate }; 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate 65*0Sstevel@tonic-gate static char *itemtypes[] = { 66*0Sstevel@tonic-gate "cis", "mls", "dn", 67*0Sstevel@tonic-gate "bool", "jpeg", "jpegbtn", 68*0Sstevel@tonic-gate "fax", "faxbtn", "audiobtn", 69*0Sstevel@tonic-gate "time", "date", "url", 70*0Sstevel@tonic-gate "searchact", "linkact", "adddnact", 71*0Sstevel@tonic-gate "addact", "verifyact", "mail", 72*0Sstevel@tonic-gate NULL 73*0Sstevel@tonic-gate }; 74*0Sstevel@tonic-gate 75*0Sstevel@tonic-gate static unsigned long itemsynids[] = { 76*0Sstevel@tonic-gate LDAP_SYN_CASEIGNORESTR, LDAP_SYN_MULTILINESTR, LDAP_SYN_DN, 77*0Sstevel@tonic-gate LDAP_SYN_BOOLEAN, LDAP_SYN_JPEGIMAGE, LDAP_SYN_JPEGBUTTON, 78*0Sstevel@tonic-gate LDAP_SYN_FAXIMAGE, LDAP_SYN_FAXBUTTON, LDAP_SYN_AUDIOBUTTON, 79*0Sstevel@tonic-gate LDAP_SYN_TIME, LDAP_SYN_DATE, LDAP_SYN_LABELEDURL, 80*0Sstevel@tonic-gate LDAP_SYN_SEARCHACTION, LDAP_SYN_LINKACTION, LDAP_SYN_ADDDNACTION, 81*0Sstevel@tonic-gate LDAP_SYN_ADDDNACTION, LDAP_SYN_VERIFYDNACTION,LDAP_SYN_RFC822ADDR, 82*0Sstevel@tonic-gate }; 83*0Sstevel@tonic-gate 84*0Sstevel@tonic-gate 85*0Sstevel@tonic-gate static char *itemoptions[] = { 86*0Sstevel@tonic-gate "ro", "sort", 87*0Sstevel@tonic-gate "1val", "hide", 88*0Sstevel@tonic-gate "required", "hideiffalse", 89*0Sstevel@tonic-gate NULL 90*0Sstevel@tonic-gate }; 91*0Sstevel@tonic-gate 92*0Sstevel@tonic-gate 93*0Sstevel@tonic-gate static unsigned long itemoptvals[] = { 94*0Sstevel@tonic-gate LDAP_DITEM_OPT_READONLY, LDAP_DITEM_OPT_SORTVALUES, 95*0Sstevel@tonic-gate LDAP_DITEM_OPT_SINGLEVALUED, LDAP_DITEM_OPT_HIDEIFEMPTY, 96*0Sstevel@tonic-gate LDAP_DITEM_OPT_VALUEREQUIRED, LDAP_DITEM_OPT_HIDEIFFALSE, 97*0Sstevel@tonic-gate }; 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate 100*0Sstevel@tonic-gate #define ADDEF_CONSTANT "constant" 101*0Sstevel@tonic-gate #define ADDEF_ADDERSDN "addersdn" 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate 104*0Sstevel@tonic-gate int 105*0Sstevel@tonic-gate LDAP_CALL 106*0Sstevel@tonic-gate ldap_init_templates( char *file, struct ldap_disptmpl **tmpllistp ) 107*0Sstevel@tonic-gate { 108*0Sstevel@tonic-gate FILE *fp; 109*0Sstevel@tonic-gate char *buf; 110*0Sstevel@tonic-gate long rlen, len; 111*0Sstevel@tonic-gate int rc, eof; 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate *tmpllistp = NULLDISPTMPL; 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate if (( fp = fopen( file, "r" )) == NULL ) { 116*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_FILE ); 117*0Sstevel@tonic-gate } 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate if ( fseek( fp, 0L, SEEK_END ) != 0 ) { /* move to end to get len */ 120*0Sstevel@tonic-gate fclose( fp ); 121*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_FILE ); 122*0Sstevel@tonic-gate } 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate len = ftell( fp ); 125*0Sstevel@tonic-gate 126*0Sstevel@tonic-gate if ( fseek( fp, 0L, SEEK_SET ) != 0 ) { /* back to start of file */ 127*0Sstevel@tonic-gate fclose( fp ); 128*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_FILE ); 129*0Sstevel@tonic-gate } 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate if (( buf = NSLDAPI_MALLOC( (size_t)len )) == NULL ) { 132*0Sstevel@tonic-gate fclose( fp ); 133*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 134*0Sstevel@tonic-gate } 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate rlen = fread( buf, 1, (size_t)len, fp ); 137*0Sstevel@tonic-gate eof = feof( fp ); 138*0Sstevel@tonic-gate fclose( fp ); 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate if ( rlen != len && !eof ) { /* error: didn't get the whole file */ 141*0Sstevel@tonic-gate NSLDAPI_FREE( buf ); 142*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_FILE ); 143*0Sstevel@tonic-gate } 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate rc = ldap_init_templates_buf( buf, rlen, tmpllistp ); 146*0Sstevel@tonic-gate NSLDAPI_FREE( buf ); 147*0Sstevel@tonic-gate 148*0Sstevel@tonic-gate return( rc ); 149*0Sstevel@tonic-gate } 150*0Sstevel@tonic-gate 151*0Sstevel@tonic-gate 152*0Sstevel@tonic-gate int 153*0Sstevel@tonic-gate LDAP_CALL 154*0Sstevel@tonic-gate ldap_init_templates_buf( char *buf, long buflen, 155*0Sstevel@tonic-gate struct ldap_disptmpl **tmpllistp ) 156*0Sstevel@tonic-gate { 157*0Sstevel@tonic-gate int rc = 0, version; 158*0Sstevel@tonic-gate char **toks; 159*0Sstevel@tonic-gate struct ldap_disptmpl *prevtmpl, *tmpl; 160*0Sstevel@tonic-gate 161*0Sstevel@tonic-gate *tmpllistp = prevtmpl = NULLDISPTMPL; 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate if ( ldap_next_line_tokens( &buf, &buflen, &toks ) != 2 || 164*0Sstevel@tonic-gate strcasecmp( toks[ 0 ], "version" ) != 0 ) { 165*0Sstevel@tonic-gate ldap_free_strarray( toks ); 166*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 167*0Sstevel@tonic-gate } 168*0Sstevel@tonic-gate version = atoi( toks[ 1 ] ); 169*0Sstevel@tonic-gate ldap_free_strarray( toks ); 170*0Sstevel@tonic-gate if ( version != LDAP_TEMPLATE_VERSION ) { 171*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_VERSION ); 172*0Sstevel@tonic-gate } 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate while ( buflen > 0 && ( rc = read_next_tmpl( &buf, &buflen, &tmpl, 175*0Sstevel@tonic-gate version )) == 0 && tmpl != NULLDISPTMPL ) { 176*0Sstevel@tonic-gate if ( prevtmpl == NULLDISPTMPL ) { 177*0Sstevel@tonic-gate *tmpllistp = tmpl; 178*0Sstevel@tonic-gate } else { 179*0Sstevel@tonic-gate prevtmpl->dt_next = tmpl; 180*0Sstevel@tonic-gate } 181*0Sstevel@tonic-gate prevtmpl = tmpl; 182*0Sstevel@tonic-gate } 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate if ( rc != 0 ) { 185*0Sstevel@tonic-gate ldap_free_templates( *tmpllistp ); 186*0Sstevel@tonic-gate } 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate return( rc ); 189*0Sstevel@tonic-gate } 190*0Sstevel@tonic-gate 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate void 194*0Sstevel@tonic-gate LDAP_CALL 195*0Sstevel@tonic-gate ldap_free_templates( struct ldap_disptmpl *tmpllist ) 196*0Sstevel@tonic-gate { 197*0Sstevel@tonic-gate struct ldap_disptmpl *tp, *nexttp; 198*0Sstevel@tonic-gate 199*0Sstevel@tonic-gate if ( tmpllist != NULL ) { 200*0Sstevel@tonic-gate for ( tp = tmpllist; tp != NULL; tp = nexttp ) { 201*0Sstevel@tonic-gate nexttp = tp->dt_next; 202*0Sstevel@tonic-gate free_disptmpl( tp ); 203*0Sstevel@tonic-gate } 204*0Sstevel@tonic-gate } 205*0Sstevel@tonic-gate } 206*0Sstevel@tonic-gate 207*0Sstevel@tonic-gate 208*0Sstevel@tonic-gate static void 209*0Sstevel@tonic-gate free_disptmpl( struct ldap_disptmpl *tmpl ) 210*0Sstevel@tonic-gate { 211*0Sstevel@tonic-gate if ( tmpl != NULL ) { 212*0Sstevel@tonic-gate if ( tmpl->dt_name != NULL ) { 213*0Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_name ); 214*0Sstevel@tonic-gate } 215*0Sstevel@tonic-gate 216*0Sstevel@tonic-gate if ( tmpl->dt_pluralname != NULL ) { 217*0Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_pluralname ); 218*0Sstevel@tonic-gate } 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate if ( tmpl->dt_iconname != NULL ) { 221*0Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_iconname ); 222*0Sstevel@tonic-gate } 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate if ( tmpl->dt_authattrname != NULL ) { 225*0Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_authattrname ); 226*0Sstevel@tonic-gate } 227*0Sstevel@tonic-gate 228*0Sstevel@tonic-gate if ( tmpl->dt_defrdnattrname != NULL ) { 229*0Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_defrdnattrname ); 230*0Sstevel@tonic-gate } 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate if ( tmpl->dt_defaddlocation != NULL ) { 233*0Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_defaddlocation ); 234*0Sstevel@tonic-gate } 235*0Sstevel@tonic-gate 236*0Sstevel@tonic-gate if ( tmpl->dt_oclist != NULL ) { 237*0Sstevel@tonic-gate struct ldap_oclist *ocp, *nextocp; 238*0Sstevel@tonic-gate 239*0Sstevel@tonic-gate for ( ocp = tmpl->dt_oclist; ocp != NULL; ocp = nextocp ) { 240*0Sstevel@tonic-gate nextocp = ocp->oc_next; 241*0Sstevel@tonic-gate ldap_free_strarray( ocp->oc_objclasses ); 242*0Sstevel@tonic-gate NSLDAPI_FREE( ocp ); 243*0Sstevel@tonic-gate } 244*0Sstevel@tonic-gate } 245*0Sstevel@tonic-gate 246*0Sstevel@tonic-gate if ( tmpl->dt_adddeflist != NULL ) { 247*0Sstevel@tonic-gate struct ldap_adddeflist *adp, *nextadp; 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate for ( adp = tmpl->dt_adddeflist; adp != NULL; adp = nextadp ) { 250*0Sstevel@tonic-gate nextadp = adp->ad_next; 251*0Sstevel@tonic-gate if( adp->ad_attrname != NULL ) { 252*0Sstevel@tonic-gate NSLDAPI_FREE( adp->ad_attrname ); 253*0Sstevel@tonic-gate } 254*0Sstevel@tonic-gate if( adp->ad_value != NULL ) { 255*0Sstevel@tonic-gate NSLDAPI_FREE( adp->ad_value ); 256*0Sstevel@tonic-gate } 257*0Sstevel@tonic-gate NSLDAPI_FREE( adp ); 258*0Sstevel@tonic-gate } 259*0Sstevel@tonic-gate } 260*0Sstevel@tonic-gate 261*0Sstevel@tonic-gate if ( tmpl->dt_items != NULL ) { 262*0Sstevel@tonic-gate struct ldap_tmplitem *rowp, *nextrowp, *colp, *nextcolp; 263*0Sstevel@tonic-gate 264*0Sstevel@tonic-gate for ( rowp = tmpl->dt_items; rowp != NULL; rowp = nextrowp ) { 265*0Sstevel@tonic-gate nextrowp = rowp->ti_next_in_col; 266*0Sstevel@tonic-gate for ( colp = rowp; colp != NULL; colp = nextcolp ) { 267*0Sstevel@tonic-gate nextcolp = colp->ti_next_in_row; 268*0Sstevel@tonic-gate if ( colp->ti_attrname != NULL ) { 269*0Sstevel@tonic-gate NSLDAPI_FREE( colp->ti_attrname ); 270*0Sstevel@tonic-gate } 271*0Sstevel@tonic-gate if ( colp->ti_label != NULL ) { 272*0Sstevel@tonic-gate NSLDAPI_FREE( colp->ti_label ); 273*0Sstevel@tonic-gate } 274*0Sstevel@tonic-gate if ( colp->ti_args != NULL ) { 275*0Sstevel@tonic-gate ldap_free_strarray( colp->ti_args ); 276*0Sstevel@tonic-gate } 277*0Sstevel@tonic-gate NSLDAPI_FREE( colp ); 278*0Sstevel@tonic-gate } 279*0Sstevel@tonic-gate } 280*0Sstevel@tonic-gate } 281*0Sstevel@tonic-gate 282*0Sstevel@tonic-gate NSLDAPI_FREE( tmpl ); 283*0Sstevel@tonic-gate } 284*0Sstevel@tonic-gate } 285*0Sstevel@tonic-gate 286*0Sstevel@tonic-gate 287*0Sstevel@tonic-gate struct ldap_disptmpl * 288*0Sstevel@tonic-gate LDAP_CALL 289*0Sstevel@tonic-gate ldap_first_disptmpl( struct ldap_disptmpl *tmpllist ) 290*0Sstevel@tonic-gate { 291*0Sstevel@tonic-gate return( tmpllist ); 292*0Sstevel@tonic-gate } 293*0Sstevel@tonic-gate 294*0Sstevel@tonic-gate 295*0Sstevel@tonic-gate struct ldap_disptmpl * 296*0Sstevel@tonic-gate LDAP_CALL 297*0Sstevel@tonic-gate ldap_next_disptmpl( struct ldap_disptmpl *tmpllist, 298*0Sstevel@tonic-gate struct ldap_disptmpl *tmpl ) 299*0Sstevel@tonic-gate { 300*0Sstevel@tonic-gate return( tmpl == NULLDISPTMPL ? tmpl : tmpl->dt_next ); 301*0Sstevel@tonic-gate } 302*0Sstevel@tonic-gate 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate struct ldap_disptmpl * 305*0Sstevel@tonic-gate LDAP_CALL 306*0Sstevel@tonic-gate ldap_name2template( char *name, struct ldap_disptmpl *tmpllist ) 307*0Sstevel@tonic-gate { 308*0Sstevel@tonic-gate struct ldap_disptmpl *dtp; 309*0Sstevel@tonic-gate 310*0Sstevel@tonic-gate for ( dtp = ldap_first_disptmpl( tmpllist ); dtp != NULLDISPTMPL; 311*0Sstevel@tonic-gate dtp = ldap_next_disptmpl( tmpllist, dtp )) { 312*0Sstevel@tonic-gate if ( strcasecmp( name, dtp->dt_name ) == 0 ) { 313*0Sstevel@tonic-gate return( dtp ); 314*0Sstevel@tonic-gate } 315*0Sstevel@tonic-gate } 316*0Sstevel@tonic-gate 317*0Sstevel@tonic-gate return( NULLDISPTMPL ); 318*0Sstevel@tonic-gate } 319*0Sstevel@tonic-gate 320*0Sstevel@tonic-gate 321*0Sstevel@tonic-gate struct ldap_disptmpl * 322*0Sstevel@tonic-gate LDAP_CALL 323*0Sstevel@tonic-gate ldap_oc2template( char **oclist, struct ldap_disptmpl *tmpllist ) 324*0Sstevel@tonic-gate { 325*0Sstevel@tonic-gate struct ldap_disptmpl *dtp; 326*0Sstevel@tonic-gate struct ldap_oclist *oclp; 327*0Sstevel@tonic-gate int i, j, needcnt, matchcnt; 328*0Sstevel@tonic-gate 329*0Sstevel@tonic-gate if ( tmpllist == NULL || oclist == NULL || oclist[ 0 ] == NULL ) { 330*0Sstevel@tonic-gate return( NULLDISPTMPL ); 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate 333*0Sstevel@tonic-gate for ( dtp = ldap_first_disptmpl( tmpllist ); dtp != NULLDISPTMPL; 334*0Sstevel@tonic-gate dtp = ldap_next_disptmpl( tmpllist, dtp )) { 335*0Sstevel@tonic-gate for ( oclp = dtp->dt_oclist; oclp != NULLOCLIST; 336*0Sstevel@tonic-gate oclp = oclp->oc_next ) { 337*0Sstevel@tonic-gate needcnt = matchcnt = 0; 338*0Sstevel@tonic-gate for ( i = 0; oclp->oc_objclasses[ i ] != NULL; ++i ) { 339*0Sstevel@tonic-gate for ( j = 0; oclist[ j ] != NULL; ++j ) { 340*0Sstevel@tonic-gate if ( strcasecmp( oclist[ j ], oclp->oc_objclasses[ i ] ) 341*0Sstevel@tonic-gate == 0 ) { 342*0Sstevel@tonic-gate ++matchcnt; 343*0Sstevel@tonic-gate } 344*0Sstevel@tonic-gate } 345*0Sstevel@tonic-gate ++needcnt; 346*0Sstevel@tonic-gate } 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate if ( matchcnt == needcnt ) { 349*0Sstevel@tonic-gate return( dtp ); 350*0Sstevel@tonic-gate } 351*0Sstevel@tonic-gate } 352*0Sstevel@tonic-gate } 353*0Sstevel@tonic-gate 354*0Sstevel@tonic-gate return( NULLDISPTMPL ); 355*0Sstevel@tonic-gate } 356*0Sstevel@tonic-gate 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate struct ldap_tmplitem * 359*0Sstevel@tonic-gate LDAP_CALL 360*0Sstevel@tonic-gate ldap_first_tmplrow( struct ldap_disptmpl *tmpl ) 361*0Sstevel@tonic-gate { 362*0Sstevel@tonic-gate return( tmpl->dt_items ); 363*0Sstevel@tonic-gate } 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate 366*0Sstevel@tonic-gate struct ldap_tmplitem * 367*0Sstevel@tonic-gate LDAP_CALL 368*0Sstevel@tonic-gate ldap_next_tmplrow( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row ) 369*0Sstevel@tonic-gate { 370*0Sstevel@tonic-gate return( row == NULLTMPLITEM ? row : row->ti_next_in_col ); 371*0Sstevel@tonic-gate } 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate 374*0Sstevel@tonic-gate struct ldap_tmplitem * 375*0Sstevel@tonic-gate LDAP_CALL 376*0Sstevel@tonic-gate ldap_first_tmplcol( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row ) 377*0Sstevel@tonic-gate { 378*0Sstevel@tonic-gate return( row ); 379*0Sstevel@tonic-gate } 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate 382*0Sstevel@tonic-gate struct ldap_tmplitem * 383*0Sstevel@tonic-gate LDAP_CALL 384*0Sstevel@tonic-gate ldap_next_tmplcol( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row, 385*0Sstevel@tonic-gate struct ldap_tmplitem *col ) 386*0Sstevel@tonic-gate { 387*0Sstevel@tonic-gate return( col == NULLTMPLITEM ? col : col->ti_next_in_row ); 388*0Sstevel@tonic-gate } 389*0Sstevel@tonic-gate 390*0Sstevel@tonic-gate 391*0Sstevel@tonic-gate char ** 392*0Sstevel@tonic-gate LDAP_CALL 393*0Sstevel@tonic-gate ldap_tmplattrs( struct ldap_disptmpl *tmpl, char **includeattrs, 394*0Sstevel@tonic-gate int exclude, unsigned long syntaxmask ) 395*0Sstevel@tonic-gate { 396*0Sstevel@tonic-gate /* 397*0Sstevel@tonic-gate * this routine should filter out duplicate attributes... 398*0Sstevel@tonic-gate */ 399*0Sstevel@tonic-gate struct ldap_tmplitem *tirowp, *ticolp; 400*0Sstevel@tonic-gate int i, attrcnt, memerr; 401*0Sstevel@tonic-gate char **attrs; 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gate attrcnt = 0; 404*0Sstevel@tonic-gate memerr = 0; 405*0Sstevel@tonic-gate 406*0Sstevel@tonic-gate if (( attrs = (char **)NSLDAPI_MALLOC( sizeof( char * ))) == NULL ) { 407*0Sstevel@tonic-gate return( NULL ); 408*0Sstevel@tonic-gate } 409*0Sstevel@tonic-gate 410*0Sstevel@tonic-gate if ( includeattrs != NULL ) { 411*0Sstevel@tonic-gate for ( i = 0; !memerr && includeattrs[ i ] != NULL; ++i ) { 412*0Sstevel@tonic-gate if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 ) * 413*0Sstevel@tonic-gate sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] = 414*0Sstevel@tonic-gate nsldapi_strdup( includeattrs[ i ] )) == NULL ) { 415*0Sstevel@tonic-gate memerr = 1; 416*0Sstevel@tonic-gate } else { 417*0Sstevel@tonic-gate attrs[ attrcnt ] = NULL; 418*0Sstevel@tonic-gate } 419*0Sstevel@tonic-gate } 420*0Sstevel@tonic-gate } 421*0Sstevel@tonic-gate 422*0Sstevel@tonic-gate for ( tirowp = ldap_first_tmplrow( tmpl ); 423*0Sstevel@tonic-gate !memerr && tirowp != NULLTMPLITEM; 424*0Sstevel@tonic-gate tirowp = ldap_next_tmplrow( tmpl, tirowp )) { 425*0Sstevel@tonic-gate for ( ticolp = ldap_first_tmplcol( tmpl, tirowp ); 426*0Sstevel@tonic-gate ticolp != NULLTMPLITEM; 427*0Sstevel@tonic-gate ticolp = ldap_next_tmplcol( tmpl, tirowp, ticolp )) { 428*0Sstevel@tonic-gate 429*0Sstevel@tonic-gate if ( syntaxmask != 0 ) { 430*0Sstevel@tonic-gate if (( exclude && 431*0Sstevel@tonic-gate ( syntaxmask & ticolp->ti_syntaxid ) != 0 ) || 432*0Sstevel@tonic-gate ( !exclude && 433*0Sstevel@tonic-gate ( syntaxmask & ticolp->ti_syntaxid ) == 0 )) { 434*0Sstevel@tonic-gate continue; 435*0Sstevel@tonic-gate } 436*0Sstevel@tonic-gate } 437*0Sstevel@tonic-gate 438*0Sstevel@tonic-gate if ( ticolp->ti_attrname != NULL ) { 439*0Sstevel@tonic-gate if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 ) 440*0Sstevel@tonic-gate * sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] = 441*0Sstevel@tonic-gate nsldapi_strdup( ticolp->ti_attrname )) == NULL ) { 442*0Sstevel@tonic-gate memerr = 1; 443*0Sstevel@tonic-gate } else { 444*0Sstevel@tonic-gate attrs[ attrcnt ] = NULL; 445*0Sstevel@tonic-gate } 446*0Sstevel@tonic-gate } 447*0Sstevel@tonic-gate } 448*0Sstevel@tonic-gate } 449*0Sstevel@tonic-gate 450*0Sstevel@tonic-gate if ( memerr || attrcnt == 0 ) { 451*0Sstevel@tonic-gate for ( i = 0; i < attrcnt; ++i ) { 452*0Sstevel@tonic-gate if ( attrs[ i ] != NULL ) { 453*0Sstevel@tonic-gate NSLDAPI_FREE( attrs[ i ] ); 454*0Sstevel@tonic-gate } 455*0Sstevel@tonic-gate } 456*0Sstevel@tonic-gate 457*0Sstevel@tonic-gate NSLDAPI_FREE( (char *)attrs ); 458*0Sstevel@tonic-gate return( NULL ); 459*0Sstevel@tonic-gate } 460*0Sstevel@tonic-gate 461*0Sstevel@tonic-gate return( attrs ); 462*0Sstevel@tonic-gate } 463*0Sstevel@tonic-gate 464*0Sstevel@tonic-gate 465*0Sstevel@tonic-gate static int 466*0Sstevel@tonic-gate read_next_tmpl( char **bufp, long *blenp, struct ldap_disptmpl **tmplp, 467*0Sstevel@tonic-gate int dtversion ) 468*0Sstevel@tonic-gate { 469*0Sstevel@tonic-gate int i, j, tokcnt, samerow, adsource; 470*0Sstevel@tonic-gate char **toks, *itemopts; 471*0Sstevel@tonic-gate struct ldap_disptmpl *tmpl = NULL; 472*0Sstevel@tonic-gate struct ldap_oclist *ocp = NULL, *prevocp = NULL; 473*0Sstevel@tonic-gate struct ldap_adddeflist *adp = NULL, *prevadp = NULL; 474*0Sstevel@tonic-gate struct ldap_tmplitem *rowp = NULL, *ip = NULL, *previp = NULL; 475*0Sstevel@tonic-gate 476*0Sstevel@tonic-gate /* 477*0Sstevel@tonic-gate * template name comes first 478*0Sstevel@tonic-gate */ 479*0Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 480*0Sstevel@tonic-gate ldap_free_strarray( toks ); 481*0Sstevel@tonic-gate return( tokcnt == 0 ? 0 : LDAP_TMPL_ERR_SYNTAX ); 482*0Sstevel@tonic-gate } 483*0Sstevel@tonic-gate 484*0Sstevel@tonic-gate if (( tmpl = (struct ldap_disptmpl *)NSLDAPI_CALLOC( 1, 485*0Sstevel@tonic-gate sizeof( struct ldap_disptmpl ))) == NULL ) { 486*0Sstevel@tonic-gate ldap_free_strarray( toks ); 487*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 488*0Sstevel@tonic-gate } 489*0Sstevel@tonic-gate tmpl->dt_name = toks[ 0 ]; 490*0Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 491*0Sstevel@tonic-gate 492*0Sstevel@tonic-gate /* 493*0Sstevel@tonic-gate * template plural name comes next 494*0Sstevel@tonic-gate */ 495*0Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 496*0Sstevel@tonic-gate ldap_free_strarray( toks ); 497*0Sstevel@tonic-gate free_disptmpl( tmpl ); 498*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 499*0Sstevel@tonic-gate } 500*0Sstevel@tonic-gate tmpl->dt_pluralname = toks[ 0 ]; 501*0Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 502*0Sstevel@tonic-gate 503*0Sstevel@tonic-gate /* 504*0Sstevel@tonic-gate * template icon name is next 505*0Sstevel@tonic-gate */ 506*0Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 507*0Sstevel@tonic-gate ldap_free_strarray( toks ); 508*0Sstevel@tonic-gate free_disptmpl( tmpl ); 509*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 510*0Sstevel@tonic-gate } 511*0Sstevel@tonic-gate tmpl->dt_iconname = toks[ 0 ]; 512*0Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 513*0Sstevel@tonic-gate 514*0Sstevel@tonic-gate /* 515*0Sstevel@tonic-gate * template options come next 516*0Sstevel@tonic-gate */ 517*0Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) < 1 ) { 518*0Sstevel@tonic-gate ldap_free_strarray( toks ); 519*0Sstevel@tonic-gate free_disptmpl( tmpl ); 520*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 521*0Sstevel@tonic-gate } 522*0Sstevel@tonic-gate for ( i = 0; toks[ i ] != NULL; ++i ) { 523*0Sstevel@tonic-gate for ( j = 0; tmploptions[ j ] != NULL; ++j ) { 524*0Sstevel@tonic-gate if ( strcasecmp( toks[ i ], tmploptions[ j ] ) == 0 ) { 525*0Sstevel@tonic-gate tmpl->dt_options |= tmploptvals[ j ]; 526*0Sstevel@tonic-gate } 527*0Sstevel@tonic-gate } 528*0Sstevel@tonic-gate } 529*0Sstevel@tonic-gate ldap_free_strarray( toks ); 530*0Sstevel@tonic-gate 531*0Sstevel@tonic-gate /* 532*0Sstevel@tonic-gate * object class list is next 533*0Sstevel@tonic-gate */ 534*0Sstevel@tonic-gate while (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) > 0 ) { 535*0Sstevel@tonic-gate if (( ocp = (struct ldap_oclist *)NSLDAPI_CALLOC( 1, 536*0Sstevel@tonic-gate sizeof( struct ldap_oclist ))) == NULL ) { 537*0Sstevel@tonic-gate ldap_free_strarray( toks ); 538*0Sstevel@tonic-gate free_disptmpl( tmpl ); 539*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 540*0Sstevel@tonic-gate } 541*0Sstevel@tonic-gate ocp->oc_objclasses = toks; 542*0Sstevel@tonic-gate if ( tmpl->dt_oclist == NULL ) { 543*0Sstevel@tonic-gate tmpl->dt_oclist = ocp; 544*0Sstevel@tonic-gate } else { 545*0Sstevel@tonic-gate prevocp->oc_next = ocp; 546*0Sstevel@tonic-gate } 547*0Sstevel@tonic-gate prevocp = ocp; 548*0Sstevel@tonic-gate } 549*0Sstevel@tonic-gate if ( tokcnt < 0 ) { 550*0Sstevel@tonic-gate free_disptmpl( tmpl ); 551*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 552*0Sstevel@tonic-gate } 553*0Sstevel@tonic-gate 554*0Sstevel@tonic-gate /* 555*0Sstevel@tonic-gate * read name of attribute to authenticate as 556*0Sstevel@tonic-gate */ 557*0Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 558*0Sstevel@tonic-gate ldap_free_strarray( toks ); 559*0Sstevel@tonic-gate free_disptmpl( tmpl ); 560*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 561*0Sstevel@tonic-gate } 562*0Sstevel@tonic-gate if ( toks[ 0 ][ 0 ] != '\0' ) { 563*0Sstevel@tonic-gate tmpl->dt_authattrname = toks[ 0 ]; 564*0Sstevel@tonic-gate } else { 565*0Sstevel@tonic-gate NSLDAPI_FREE( toks[ 0 ] ); 566*0Sstevel@tonic-gate } 567*0Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 568*0Sstevel@tonic-gate 569*0Sstevel@tonic-gate /* 570*0Sstevel@tonic-gate * read default attribute to use for RDN 571*0Sstevel@tonic-gate */ 572*0Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 573*0Sstevel@tonic-gate ldap_free_strarray( toks ); 574*0Sstevel@tonic-gate free_disptmpl( tmpl ); 575*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 576*0Sstevel@tonic-gate } 577*0Sstevel@tonic-gate tmpl->dt_defrdnattrname = toks[ 0 ]; 578*0Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 579*0Sstevel@tonic-gate 580*0Sstevel@tonic-gate /* 581*0Sstevel@tonic-gate * read default location for new entries 582*0Sstevel@tonic-gate */ 583*0Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 584*0Sstevel@tonic-gate ldap_free_strarray( toks ); 585*0Sstevel@tonic-gate free_disptmpl( tmpl ); 586*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 587*0Sstevel@tonic-gate } 588*0Sstevel@tonic-gate if ( toks[ 0 ][ 0 ] != '\0' ) { 589*0Sstevel@tonic-gate tmpl->dt_defaddlocation = toks[ 0 ]; 590*0Sstevel@tonic-gate } else { 591*0Sstevel@tonic-gate NSLDAPI_FREE( toks[ 0 ] ); 592*0Sstevel@tonic-gate } 593*0Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 594*0Sstevel@tonic-gate 595*0Sstevel@tonic-gate /* 596*0Sstevel@tonic-gate * read list of rules used to define default values for new entries 597*0Sstevel@tonic-gate */ 598*0Sstevel@tonic-gate while (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) > 0 ) { 599*0Sstevel@tonic-gate if ( strcasecmp( ADDEF_CONSTANT, toks[ 0 ] ) == 0 ) { 600*0Sstevel@tonic-gate adsource = LDAP_ADSRC_CONSTANTVALUE; 601*0Sstevel@tonic-gate } else if ( strcasecmp( ADDEF_ADDERSDN, toks[ 0 ] ) == 0 ) { 602*0Sstevel@tonic-gate adsource = LDAP_ADSRC_ADDERSDN; 603*0Sstevel@tonic-gate } else { 604*0Sstevel@tonic-gate adsource = 0; 605*0Sstevel@tonic-gate } 606*0Sstevel@tonic-gate if ( adsource == 0 || tokcnt < 2 || 607*0Sstevel@tonic-gate ( adsource == LDAP_ADSRC_CONSTANTVALUE && tokcnt != 3 ) || 608*0Sstevel@tonic-gate ( adsource == LDAP_ADSRC_ADDERSDN && tokcnt != 2 )) { 609*0Sstevel@tonic-gate ldap_free_strarray( toks ); 610*0Sstevel@tonic-gate free_disptmpl( tmpl ); 611*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 612*0Sstevel@tonic-gate } 613*0Sstevel@tonic-gate 614*0Sstevel@tonic-gate if (( adp = (struct ldap_adddeflist *)NSLDAPI_CALLOC( 1, 615*0Sstevel@tonic-gate sizeof( struct ldap_adddeflist ))) == NULL ) { 616*0Sstevel@tonic-gate ldap_free_strarray( toks ); 617*0Sstevel@tonic-gate free_disptmpl( tmpl ); 618*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 619*0Sstevel@tonic-gate } 620*0Sstevel@tonic-gate adp->ad_source = adsource; 621*0Sstevel@tonic-gate adp->ad_attrname = toks[ 1 ]; 622*0Sstevel@tonic-gate if ( adsource == LDAP_ADSRC_CONSTANTVALUE ) { 623*0Sstevel@tonic-gate adp->ad_value = toks[ 2 ]; 624*0Sstevel@tonic-gate } 625*0Sstevel@tonic-gate NSLDAPI_FREE( toks[ 0 ] ); 626*0Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 627*0Sstevel@tonic-gate 628*0Sstevel@tonic-gate if ( tmpl->dt_adddeflist == NULL ) { 629*0Sstevel@tonic-gate tmpl->dt_adddeflist = adp; 630*0Sstevel@tonic-gate } else { 631*0Sstevel@tonic-gate prevadp->ad_next = adp; 632*0Sstevel@tonic-gate } 633*0Sstevel@tonic-gate prevadp = adp; 634*0Sstevel@tonic-gate } 635*0Sstevel@tonic-gate 636*0Sstevel@tonic-gate /* 637*0Sstevel@tonic-gate * item list is next 638*0Sstevel@tonic-gate */ 639*0Sstevel@tonic-gate samerow = 0; 640*0Sstevel@tonic-gate while (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) > 0 ) { 641*0Sstevel@tonic-gate if ( strcasecmp( toks[ 0 ], "item" ) == 0 ) { 642*0Sstevel@tonic-gate if ( tokcnt < 4 ) { 643*0Sstevel@tonic-gate ldap_free_strarray( toks ); 644*0Sstevel@tonic-gate free_disptmpl( tmpl ); 645*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 646*0Sstevel@tonic-gate } 647*0Sstevel@tonic-gate 648*0Sstevel@tonic-gate if (( ip = (struct ldap_tmplitem *)NSLDAPI_CALLOC( 1, 649*0Sstevel@tonic-gate sizeof( struct ldap_tmplitem ))) == NULL ) { 650*0Sstevel@tonic-gate ldap_free_strarray( toks ); 651*0Sstevel@tonic-gate free_disptmpl( tmpl ); 652*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 653*0Sstevel@tonic-gate } 654*0Sstevel@tonic-gate 655*0Sstevel@tonic-gate /* 656*0Sstevel@tonic-gate * find syntaxid from config file string 657*0Sstevel@tonic-gate */ 658*0Sstevel@tonic-gate while (( itemopts = strrchr( toks[ 1 ], ',' )) != NULL ) { 659*0Sstevel@tonic-gate *itemopts++ = '\0'; 660*0Sstevel@tonic-gate for ( i = 0; itemoptions[ i ] != NULL; ++i ) { 661*0Sstevel@tonic-gate if ( strcasecmp( itemopts, itemoptions[ i ] ) == 0 ) { 662*0Sstevel@tonic-gate break; 663*0Sstevel@tonic-gate } 664*0Sstevel@tonic-gate } 665*0Sstevel@tonic-gate if ( itemoptions[ i ] == NULL ) { 666*0Sstevel@tonic-gate ldap_free_strarray( toks ); 667*0Sstevel@tonic-gate free_disptmpl( tmpl ); 668*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 669*0Sstevel@tonic-gate } 670*0Sstevel@tonic-gate ip->ti_options |= itemoptvals[ i ]; 671*0Sstevel@tonic-gate } 672*0Sstevel@tonic-gate 673*0Sstevel@tonic-gate for ( i = 0; itemtypes[ i ] != NULL; ++i ) { 674*0Sstevel@tonic-gate if ( strcasecmp( toks[ 1 ], itemtypes[ i ] ) == 0 ) { 675*0Sstevel@tonic-gate break; 676*0Sstevel@tonic-gate } 677*0Sstevel@tonic-gate } 678*0Sstevel@tonic-gate if ( itemtypes[ i ] == NULL ) { 679*0Sstevel@tonic-gate ldap_free_strarray( toks ); 680*0Sstevel@tonic-gate free_disptmpl( tmpl ); 681*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 682*0Sstevel@tonic-gate } 683*0Sstevel@tonic-gate 684*0Sstevel@tonic-gate NSLDAPI_FREE( toks[ 0 ] ); 685*0Sstevel@tonic-gate NSLDAPI_FREE( toks[ 1 ] ); 686*0Sstevel@tonic-gate ip->ti_syntaxid = itemsynids[ i ]; 687*0Sstevel@tonic-gate ip->ti_label = toks[ 2 ]; 688*0Sstevel@tonic-gate if ( toks[ 3 ][ 0 ] == '\0' ) { 689*0Sstevel@tonic-gate ip->ti_attrname = NULL; 690*0Sstevel@tonic-gate NSLDAPI_FREE( toks[ 3 ] ); 691*0Sstevel@tonic-gate } else { 692*0Sstevel@tonic-gate ip->ti_attrname = toks[ 3 ]; 693*0Sstevel@tonic-gate } 694*0Sstevel@tonic-gate if ( toks[ 4 ] != NULL ) { /* extra args. */ 695*0Sstevel@tonic-gate for ( i = 0; toks[ i + 4 ] != NULL; ++i ) { 696*0Sstevel@tonic-gate ; 697*0Sstevel@tonic-gate } 698*0Sstevel@tonic-gate if (( ip->ti_args = (char **)NSLDAPI_CALLOC( i + 1, 699*0Sstevel@tonic-gate sizeof( char * ))) == NULL ) { 700*0Sstevel@tonic-gate free_disptmpl( tmpl ); 701*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 702*0Sstevel@tonic-gate } 703*0Sstevel@tonic-gate for ( i = 0; toks[ i + 4 ] != NULL; ++i ) { 704*0Sstevel@tonic-gate ip->ti_args[ i ] = toks[ i + 4 ]; 705*0Sstevel@tonic-gate } 706*0Sstevel@tonic-gate } 707*0Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 708*0Sstevel@tonic-gate 709*0Sstevel@tonic-gate if ( tmpl->dt_items == NULL ) { 710*0Sstevel@tonic-gate tmpl->dt_items = rowp = ip; 711*0Sstevel@tonic-gate } else if ( samerow ) { 712*0Sstevel@tonic-gate previp->ti_next_in_row = ip; 713*0Sstevel@tonic-gate } else { 714*0Sstevel@tonic-gate rowp->ti_next_in_col = ip; 715*0Sstevel@tonic-gate rowp = ip; 716*0Sstevel@tonic-gate } 717*0Sstevel@tonic-gate previp = ip; 718*0Sstevel@tonic-gate samerow = 0; 719*0Sstevel@tonic-gate } else if ( strcasecmp( toks[ 0 ], "samerow" ) == 0 ) { 720*0Sstevel@tonic-gate ldap_free_strarray( toks ); 721*0Sstevel@tonic-gate samerow = 1; 722*0Sstevel@tonic-gate } else { 723*0Sstevel@tonic-gate ldap_free_strarray( toks ); 724*0Sstevel@tonic-gate free_disptmpl( tmpl ); 725*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 726*0Sstevel@tonic-gate } 727*0Sstevel@tonic-gate } 728*0Sstevel@tonic-gate if ( tokcnt < 0 ) { 729*0Sstevel@tonic-gate free_disptmpl( tmpl ); 730*0Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 731*0Sstevel@tonic-gate } 732*0Sstevel@tonic-gate 733*0Sstevel@tonic-gate *tmplp = tmpl; 734*0Sstevel@tonic-gate return( 0 ); 735*0Sstevel@tonic-gate } 736*0Sstevel@tonic-gate 737*0Sstevel@tonic-gate 738*0Sstevel@tonic-gate struct tmplerror { 739*0Sstevel@tonic-gate int e_code; 740*0Sstevel@tonic-gate char *e_reason; 741*0Sstevel@tonic-gate }; 742*0Sstevel@tonic-gate 743*0Sstevel@tonic-gate #ifdef SUN 744*0Sstevel@tonic-gate static struct tmplerror ldap_tmplerrlist[] = { 745*0Sstevel@tonic-gate { LDAP_TMPL_ERR_VERSION, 0}, 746*0Sstevel@tonic-gate { LDAP_TMPL_ERR_MEM, 0}, 747*0Sstevel@tonic-gate { LDAP_TMPL_ERR_SYNTAX, 0}, 748*0Sstevel@tonic-gate { LDAP_TMPL_ERR_FILE, 0}, 749*0Sstevel@tonic-gate { -1, 0 } 750*0Sstevel@tonic-gate }; 751*0Sstevel@tonic-gate #else 752*0Sstevel@tonic-gate static struct tmplerror ldap_tmplerrlist[] = { 753*0Sstevel@tonic-gate { LDAP_TMPL_ERR_VERSION, "Bad template version" }, 754*0Sstevel@tonic-gate { LDAP_TMPL_ERR_MEM, "Out of memory" }, 755*0Sstevel@tonic-gate { LDAP_TMPL_ERR_SYNTAX, "Bad template syntax" }, 756*0Sstevel@tonic-gate { LDAP_TMPL_ERR_FILE, "File error reading template" }, 757*0Sstevel@tonic-gate { -1, 0 } 758*0Sstevel@tonic-gate }; 759*0Sstevel@tonic-gate #endif 760*0Sstevel@tonic-gate 761*0Sstevel@tonic-gate char * 762*0Sstevel@tonic-gate LDAP_CALL 763*0Sstevel@tonic-gate ldap_tmplerr2string( int err ) 764*0Sstevel@tonic-gate { 765*0Sstevel@tonic-gate static int init_flag = 0; 766*0Sstevel@tonic-gate int i; 767*0Sstevel@tonic-gate 768*0Sstevel@tonic-gate /* Multiple threads should be ok since they assign same strings */ 769*0Sstevel@tonic-gate if (init_flag == 0) { 770*0Sstevel@tonic-gate ldap_tmplerrlist[0].e_reason = 771*0Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "Bad template version"); 772*0Sstevel@tonic-gate ldap_tmplerrlist[1].e_reason = 773*0Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "Out of memory"); 774*0Sstevel@tonic-gate ldap_tmplerrlist[2].e_reason = 775*0Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "Bad template syntax"); 776*0Sstevel@tonic-gate ldap_tmplerrlist[3].e_reason = 777*0Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "File error reading template"); 778*0Sstevel@tonic-gate init_flag = 1; 779*0Sstevel@tonic-gate } 780*0Sstevel@tonic-gate 781*0Sstevel@tonic-gate for ( i = 0; ldap_tmplerrlist[i].e_code != -1; i++ ) { 782*0Sstevel@tonic-gate if ( err == ldap_tmplerrlist[i].e_code ) 783*0Sstevel@tonic-gate return( ldap_tmplerrlist[i].e_reason ); 784*0Sstevel@tonic-gate } 785*0Sstevel@tonic-gate 786*0Sstevel@tonic-gate return(dgettext(TEXT_DOMAIN, "Unknown error") ); 787*0Sstevel@tonic-gate } 788