10Sstevel@tonic-gate /* 2*1914Scasper * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 50Sstevel@tonic-gate 60Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 70Sstevel@tonic-gate 80Sstevel@tonic-gate 90Sstevel@tonic-gate /* 100Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public 110Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file 120Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of 130Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/ 140Sstevel@tonic-gate * 150Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS 160Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 170Sstevel@tonic-gate * implied. See the License for the specific language governing 180Sstevel@tonic-gate * rights and limitations under the License. 190Sstevel@tonic-gate * 200Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released 210Sstevel@tonic-gate * March 31, 1998. 220Sstevel@tonic-gate * 230Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape 240Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 250Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All 260Sstevel@tonic-gate * Rights Reserved. 270Sstevel@tonic-gate * 280Sstevel@tonic-gate * Contributor(s): 290Sstevel@tonic-gate */ 300Sstevel@tonic-gate /* 310Sstevel@tonic-gate * Copyright (c) 1993, 1994 Regents of the University of Michigan. 320Sstevel@tonic-gate * All rights reserved. 330Sstevel@tonic-gate * 340Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted 350Sstevel@tonic-gate * provided that this notice is preserved and that due credit is given 360Sstevel@tonic-gate * to the University of Michigan at Ann Arbor. The name of the University 370Sstevel@tonic-gate * may not be used to endorse or promote products derived from this 380Sstevel@tonic-gate * software without specific prior written permission. This software 390Sstevel@tonic-gate * is provided ``as is'' without express or implied warranty. 400Sstevel@tonic-gate */ 410Sstevel@tonic-gate /* 420Sstevel@tonic-gate * disptmpl.c: display template library routines for LDAP clients 430Sstevel@tonic-gate */ 440Sstevel@tonic-gate 450Sstevel@tonic-gate #include "ldap-int.h" 460Sstevel@tonic-gate #include "disptmpl.h" 470Sstevel@tonic-gate 480Sstevel@tonic-gate static void free_disptmpl( struct ldap_disptmpl *tmpl ); 490Sstevel@tonic-gate static int read_next_tmpl( char **bufp, long *blenp, 500Sstevel@tonic-gate struct ldap_disptmpl **tmplp, int dtversion ); 510Sstevel@tonic-gate 520Sstevel@tonic-gate static char *tmploptions[] = { 530Sstevel@tonic-gate "addable", "modrdn", 540Sstevel@tonic-gate "altview", 550Sstevel@tonic-gate NULL 560Sstevel@tonic-gate }; 570Sstevel@tonic-gate 580Sstevel@tonic-gate 590Sstevel@tonic-gate static unsigned long tmploptvals[] = { 600Sstevel@tonic-gate LDAP_DTMPL_OPT_ADDABLE, LDAP_DTMPL_OPT_ALLOWMODRDN, 610Sstevel@tonic-gate LDAP_DTMPL_OPT_ALTVIEW, 620Sstevel@tonic-gate }; 630Sstevel@tonic-gate 640Sstevel@tonic-gate 650Sstevel@tonic-gate static char *itemtypes[] = { 660Sstevel@tonic-gate "cis", "mls", "dn", 670Sstevel@tonic-gate "bool", "jpeg", "jpegbtn", 680Sstevel@tonic-gate "fax", "faxbtn", "audiobtn", 690Sstevel@tonic-gate "time", "date", "url", 700Sstevel@tonic-gate "searchact", "linkact", "adddnact", 710Sstevel@tonic-gate "addact", "verifyact", "mail", 720Sstevel@tonic-gate NULL 730Sstevel@tonic-gate }; 740Sstevel@tonic-gate 750Sstevel@tonic-gate static unsigned long itemsynids[] = { 760Sstevel@tonic-gate LDAP_SYN_CASEIGNORESTR, LDAP_SYN_MULTILINESTR, LDAP_SYN_DN, 770Sstevel@tonic-gate LDAP_SYN_BOOLEAN, LDAP_SYN_JPEGIMAGE, LDAP_SYN_JPEGBUTTON, 780Sstevel@tonic-gate LDAP_SYN_FAXIMAGE, LDAP_SYN_FAXBUTTON, LDAP_SYN_AUDIOBUTTON, 790Sstevel@tonic-gate LDAP_SYN_TIME, LDAP_SYN_DATE, LDAP_SYN_LABELEDURL, 800Sstevel@tonic-gate LDAP_SYN_SEARCHACTION, LDAP_SYN_LINKACTION, LDAP_SYN_ADDDNACTION, 810Sstevel@tonic-gate LDAP_SYN_ADDDNACTION, LDAP_SYN_VERIFYDNACTION,LDAP_SYN_RFC822ADDR, 820Sstevel@tonic-gate }; 830Sstevel@tonic-gate 840Sstevel@tonic-gate 850Sstevel@tonic-gate static char *itemoptions[] = { 860Sstevel@tonic-gate "ro", "sort", 870Sstevel@tonic-gate "1val", "hide", 880Sstevel@tonic-gate "required", "hideiffalse", 890Sstevel@tonic-gate NULL 900Sstevel@tonic-gate }; 910Sstevel@tonic-gate 920Sstevel@tonic-gate 930Sstevel@tonic-gate static unsigned long itemoptvals[] = { 940Sstevel@tonic-gate LDAP_DITEM_OPT_READONLY, LDAP_DITEM_OPT_SORTVALUES, 950Sstevel@tonic-gate LDAP_DITEM_OPT_SINGLEVALUED, LDAP_DITEM_OPT_HIDEIFEMPTY, 960Sstevel@tonic-gate LDAP_DITEM_OPT_VALUEREQUIRED, LDAP_DITEM_OPT_HIDEIFFALSE, 970Sstevel@tonic-gate }; 980Sstevel@tonic-gate 990Sstevel@tonic-gate 1000Sstevel@tonic-gate #define ADDEF_CONSTANT "constant" 1010Sstevel@tonic-gate #define ADDEF_ADDERSDN "addersdn" 1020Sstevel@tonic-gate 1030Sstevel@tonic-gate 1040Sstevel@tonic-gate int 1050Sstevel@tonic-gate LDAP_CALL 1060Sstevel@tonic-gate ldap_init_templates( char *file, struct ldap_disptmpl **tmpllistp ) 1070Sstevel@tonic-gate { 1080Sstevel@tonic-gate FILE *fp; 1090Sstevel@tonic-gate char *buf; 1100Sstevel@tonic-gate long rlen, len; 1110Sstevel@tonic-gate int rc, eof; 1120Sstevel@tonic-gate 1130Sstevel@tonic-gate *tmpllistp = NULLDISPTMPL; 1140Sstevel@tonic-gate 115*1914Scasper if (( fp = fopen( file, "rF" )) == NULL ) { 1160Sstevel@tonic-gate return( LDAP_TMPL_ERR_FILE ); 1170Sstevel@tonic-gate } 1180Sstevel@tonic-gate 1190Sstevel@tonic-gate if ( fseek( fp, 0L, SEEK_END ) != 0 ) { /* move to end to get len */ 1200Sstevel@tonic-gate fclose( fp ); 1210Sstevel@tonic-gate return( LDAP_TMPL_ERR_FILE ); 1220Sstevel@tonic-gate } 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate len = ftell( fp ); 1250Sstevel@tonic-gate 1260Sstevel@tonic-gate if ( fseek( fp, 0L, SEEK_SET ) != 0 ) { /* back to start of file */ 1270Sstevel@tonic-gate fclose( fp ); 1280Sstevel@tonic-gate return( LDAP_TMPL_ERR_FILE ); 1290Sstevel@tonic-gate } 1300Sstevel@tonic-gate 1310Sstevel@tonic-gate if (( buf = NSLDAPI_MALLOC( (size_t)len )) == NULL ) { 1320Sstevel@tonic-gate fclose( fp ); 1330Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 1340Sstevel@tonic-gate } 1350Sstevel@tonic-gate 1360Sstevel@tonic-gate rlen = fread( buf, 1, (size_t)len, fp ); 1370Sstevel@tonic-gate eof = feof( fp ); 1380Sstevel@tonic-gate fclose( fp ); 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate if ( rlen != len && !eof ) { /* error: didn't get the whole file */ 1410Sstevel@tonic-gate NSLDAPI_FREE( buf ); 1420Sstevel@tonic-gate return( LDAP_TMPL_ERR_FILE ); 1430Sstevel@tonic-gate } 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate rc = ldap_init_templates_buf( buf, rlen, tmpllistp ); 1460Sstevel@tonic-gate NSLDAPI_FREE( buf ); 1470Sstevel@tonic-gate 1480Sstevel@tonic-gate return( rc ); 1490Sstevel@tonic-gate } 1500Sstevel@tonic-gate 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate int 1530Sstevel@tonic-gate LDAP_CALL 1540Sstevel@tonic-gate ldap_init_templates_buf( char *buf, long buflen, 1550Sstevel@tonic-gate struct ldap_disptmpl **tmpllistp ) 1560Sstevel@tonic-gate { 1570Sstevel@tonic-gate int rc = 0, version; 1580Sstevel@tonic-gate char **toks; 1590Sstevel@tonic-gate struct ldap_disptmpl *prevtmpl, *tmpl; 1600Sstevel@tonic-gate 1610Sstevel@tonic-gate *tmpllistp = prevtmpl = NULLDISPTMPL; 1620Sstevel@tonic-gate 1630Sstevel@tonic-gate if ( ldap_next_line_tokens( &buf, &buflen, &toks ) != 2 || 1640Sstevel@tonic-gate strcasecmp( toks[ 0 ], "version" ) != 0 ) { 1650Sstevel@tonic-gate ldap_free_strarray( toks ); 1660Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 1670Sstevel@tonic-gate } 1680Sstevel@tonic-gate version = atoi( toks[ 1 ] ); 1690Sstevel@tonic-gate ldap_free_strarray( toks ); 1700Sstevel@tonic-gate if ( version != LDAP_TEMPLATE_VERSION ) { 1710Sstevel@tonic-gate return( LDAP_TMPL_ERR_VERSION ); 1720Sstevel@tonic-gate } 1730Sstevel@tonic-gate 1740Sstevel@tonic-gate while ( buflen > 0 && ( rc = read_next_tmpl( &buf, &buflen, &tmpl, 1750Sstevel@tonic-gate version )) == 0 && tmpl != NULLDISPTMPL ) { 1760Sstevel@tonic-gate if ( prevtmpl == NULLDISPTMPL ) { 1770Sstevel@tonic-gate *tmpllistp = tmpl; 1780Sstevel@tonic-gate } else { 1790Sstevel@tonic-gate prevtmpl->dt_next = tmpl; 1800Sstevel@tonic-gate } 1810Sstevel@tonic-gate prevtmpl = tmpl; 1820Sstevel@tonic-gate } 1830Sstevel@tonic-gate 1840Sstevel@tonic-gate if ( rc != 0 ) { 1850Sstevel@tonic-gate ldap_free_templates( *tmpllistp ); 1860Sstevel@tonic-gate } 1870Sstevel@tonic-gate 1880Sstevel@tonic-gate return( rc ); 1890Sstevel@tonic-gate } 1900Sstevel@tonic-gate 1910Sstevel@tonic-gate 1920Sstevel@tonic-gate 1930Sstevel@tonic-gate void 1940Sstevel@tonic-gate LDAP_CALL 1950Sstevel@tonic-gate ldap_free_templates( struct ldap_disptmpl *tmpllist ) 1960Sstevel@tonic-gate { 1970Sstevel@tonic-gate struct ldap_disptmpl *tp, *nexttp; 1980Sstevel@tonic-gate 1990Sstevel@tonic-gate if ( tmpllist != NULL ) { 2000Sstevel@tonic-gate for ( tp = tmpllist; tp != NULL; tp = nexttp ) { 2010Sstevel@tonic-gate nexttp = tp->dt_next; 2020Sstevel@tonic-gate free_disptmpl( tp ); 2030Sstevel@tonic-gate } 2040Sstevel@tonic-gate } 2050Sstevel@tonic-gate } 2060Sstevel@tonic-gate 2070Sstevel@tonic-gate 2080Sstevel@tonic-gate static void 2090Sstevel@tonic-gate free_disptmpl( struct ldap_disptmpl *tmpl ) 2100Sstevel@tonic-gate { 2110Sstevel@tonic-gate if ( tmpl != NULL ) { 2120Sstevel@tonic-gate if ( tmpl->dt_name != NULL ) { 2130Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_name ); 2140Sstevel@tonic-gate } 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate if ( tmpl->dt_pluralname != NULL ) { 2170Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_pluralname ); 2180Sstevel@tonic-gate } 2190Sstevel@tonic-gate 2200Sstevel@tonic-gate if ( tmpl->dt_iconname != NULL ) { 2210Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_iconname ); 2220Sstevel@tonic-gate } 2230Sstevel@tonic-gate 2240Sstevel@tonic-gate if ( tmpl->dt_authattrname != NULL ) { 2250Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_authattrname ); 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate 2280Sstevel@tonic-gate if ( tmpl->dt_defrdnattrname != NULL ) { 2290Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_defrdnattrname ); 2300Sstevel@tonic-gate } 2310Sstevel@tonic-gate 2320Sstevel@tonic-gate if ( tmpl->dt_defaddlocation != NULL ) { 2330Sstevel@tonic-gate NSLDAPI_FREE( tmpl->dt_defaddlocation ); 2340Sstevel@tonic-gate } 2350Sstevel@tonic-gate 2360Sstevel@tonic-gate if ( tmpl->dt_oclist != NULL ) { 2370Sstevel@tonic-gate struct ldap_oclist *ocp, *nextocp; 2380Sstevel@tonic-gate 2390Sstevel@tonic-gate for ( ocp = tmpl->dt_oclist; ocp != NULL; ocp = nextocp ) { 2400Sstevel@tonic-gate nextocp = ocp->oc_next; 2410Sstevel@tonic-gate ldap_free_strarray( ocp->oc_objclasses ); 2420Sstevel@tonic-gate NSLDAPI_FREE( ocp ); 2430Sstevel@tonic-gate } 2440Sstevel@tonic-gate } 2450Sstevel@tonic-gate 2460Sstevel@tonic-gate if ( tmpl->dt_adddeflist != NULL ) { 2470Sstevel@tonic-gate struct ldap_adddeflist *adp, *nextadp; 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate for ( adp = tmpl->dt_adddeflist; adp != NULL; adp = nextadp ) { 2500Sstevel@tonic-gate nextadp = adp->ad_next; 2510Sstevel@tonic-gate if( adp->ad_attrname != NULL ) { 2520Sstevel@tonic-gate NSLDAPI_FREE( adp->ad_attrname ); 2530Sstevel@tonic-gate } 2540Sstevel@tonic-gate if( adp->ad_value != NULL ) { 2550Sstevel@tonic-gate NSLDAPI_FREE( adp->ad_value ); 2560Sstevel@tonic-gate } 2570Sstevel@tonic-gate NSLDAPI_FREE( adp ); 2580Sstevel@tonic-gate } 2590Sstevel@tonic-gate } 2600Sstevel@tonic-gate 2610Sstevel@tonic-gate if ( tmpl->dt_items != NULL ) { 2620Sstevel@tonic-gate struct ldap_tmplitem *rowp, *nextrowp, *colp, *nextcolp; 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate for ( rowp = tmpl->dt_items; rowp != NULL; rowp = nextrowp ) { 2650Sstevel@tonic-gate nextrowp = rowp->ti_next_in_col; 2660Sstevel@tonic-gate for ( colp = rowp; colp != NULL; colp = nextcolp ) { 2670Sstevel@tonic-gate nextcolp = colp->ti_next_in_row; 2680Sstevel@tonic-gate if ( colp->ti_attrname != NULL ) { 2690Sstevel@tonic-gate NSLDAPI_FREE( colp->ti_attrname ); 2700Sstevel@tonic-gate } 2710Sstevel@tonic-gate if ( colp->ti_label != NULL ) { 2720Sstevel@tonic-gate NSLDAPI_FREE( colp->ti_label ); 2730Sstevel@tonic-gate } 2740Sstevel@tonic-gate if ( colp->ti_args != NULL ) { 2750Sstevel@tonic-gate ldap_free_strarray( colp->ti_args ); 2760Sstevel@tonic-gate } 2770Sstevel@tonic-gate NSLDAPI_FREE( colp ); 2780Sstevel@tonic-gate } 2790Sstevel@tonic-gate } 2800Sstevel@tonic-gate } 2810Sstevel@tonic-gate 2820Sstevel@tonic-gate NSLDAPI_FREE( tmpl ); 2830Sstevel@tonic-gate } 2840Sstevel@tonic-gate } 2850Sstevel@tonic-gate 2860Sstevel@tonic-gate 2870Sstevel@tonic-gate struct ldap_disptmpl * 2880Sstevel@tonic-gate LDAP_CALL 2890Sstevel@tonic-gate ldap_first_disptmpl( struct ldap_disptmpl *tmpllist ) 2900Sstevel@tonic-gate { 2910Sstevel@tonic-gate return( tmpllist ); 2920Sstevel@tonic-gate } 2930Sstevel@tonic-gate 2940Sstevel@tonic-gate 2950Sstevel@tonic-gate struct ldap_disptmpl * 2960Sstevel@tonic-gate LDAP_CALL 2970Sstevel@tonic-gate ldap_next_disptmpl( struct ldap_disptmpl *tmpllist, 2980Sstevel@tonic-gate struct ldap_disptmpl *tmpl ) 2990Sstevel@tonic-gate { 3000Sstevel@tonic-gate return( tmpl == NULLDISPTMPL ? tmpl : tmpl->dt_next ); 3010Sstevel@tonic-gate } 3020Sstevel@tonic-gate 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate struct ldap_disptmpl * 3050Sstevel@tonic-gate LDAP_CALL 3060Sstevel@tonic-gate ldap_name2template( char *name, struct ldap_disptmpl *tmpllist ) 3070Sstevel@tonic-gate { 3080Sstevel@tonic-gate struct ldap_disptmpl *dtp; 3090Sstevel@tonic-gate 3100Sstevel@tonic-gate for ( dtp = ldap_first_disptmpl( tmpllist ); dtp != NULLDISPTMPL; 3110Sstevel@tonic-gate dtp = ldap_next_disptmpl( tmpllist, dtp )) { 3120Sstevel@tonic-gate if ( strcasecmp( name, dtp->dt_name ) == 0 ) { 3130Sstevel@tonic-gate return( dtp ); 3140Sstevel@tonic-gate } 3150Sstevel@tonic-gate } 3160Sstevel@tonic-gate 3170Sstevel@tonic-gate return( NULLDISPTMPL ); 3180Sstevel@tonic-gate } 3190Sstevel@tonic-gate 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate struct ldap_disptmpl * 3220Sstevel@tonic-gate LDAP_CALL 3230Sstevel@tonic-gate ldap_oc2template( char **oclist, struct ldap_disptmpl *tmpllist ) 3240Sstevel@tonic-gate { 3250Sstevel@tonic-gate struct ldap_disptmpl *dtp; 3260Sstevel@tonic-gate struct ldap_oclist *oclp; 3270Sstevel@tonic-gate int i, j, needcnt, matchcnt; 3280Sstevel@tonic-gate 3290Sstevel@tonic-gate if ( tmpllist == NULL || oclist == NULL || oclist[ 0 ] == NULL ) { 3300Sstevel@tonic-gate return( NULLDISPTMPL ); 3310Sstevel@tonic-gate } 3320Sstevel@tonic-gate 3330Sstevel@tonic-gate for ( dtp = ldap_first_disptmpl( tmpllist ); dtp != NULLDISPTMPL; 3340Sstevel@tonic-gate dtp = ldap_next_disptmpl( tmpllist, dtp )) { 3350Sstevel@tonic-gate for ( oclp = dtp->dt_oclist; oclp != NULLOCLIST; 3360Sstevel@tonic-gate oclp = oclp->oc_next ) { 3370Sstevel@tonic-gate needcnt = matchcnt = 0; 3380Sstevel@tonic-gate for ( i = 0; oclp->oc_objclasses[ i ] != NULL; ++i ) { 3390Sstevel@tonic-gate for ( j = 0; oclist[ j ] != NULL; ++j ) { 3400Sstevel@tonic-gate if ( strcasecmp( oclist[ j ], oclp->oc_objclasses[ i ] ) 3410Sstevel@tonic-gate == 0 ) { 3420Sstevel@tonic-gate ++matchcnt; 3430Sstevel@tonic-gate } 3440Sstevel@tonic-gate } 3450Sstevel@tonic-gate ++needcnt; 3460Sstevel@tonic-gate } 3470Sstevel@tonic-gate 3480Sstevel@tonic-gate if ( matchcnt == needcnt ) { 3490Sstevel@tonic-gate return( dtp ); 3500Sstevel@tonic-gate } 3510Sstevel@tonic-gate } 3520Sstevel@tonic-gate } 3530Sstevel@tonic-gate 3540Sstevel@tonic-gate return( NULLDISPTMPL ); 3550Sstevel@tonic-gate } 3560Sstevel@tonic-gate 3570Sstevel@tonic-gate 3580Sstevel@tonic-gate struct ldap_tmplitem * 3590Sstevel@tonic-gate LDAP_CALL 3600Sstevel@tonic-gate ldap_first_tmplrow( struct ldap_disptmpl *tmpl ) 3610Sstevel@tonic-gate { 3620Sstevel@tonic-gate return( tmpl->dt_items ); 3630Sstevel@tonic-gate } 3640Sstevel@tonic-gate 3650Sstevel@tonic-gate 3660Sstevel@tonic-gate struct ldap_tmplitem * 3670Sstevel@tonic-gate LDAP_CALL 3680Sstevel@tonic-gate ldap_next_tmplrow( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row ) 3690Sstevel@tonic-gate { 3700Sstevel@tonic-gate return( row == NULLTMPLITEM ? row : row->ti_next_in_col ); 3710Sstevel@tonic-gate } 3720Sstevel@tonic-gate 3730Sstevel@tonic-gate 3740Sstevel@tonic-gate struct ldap_tmplitem * 3750Sstevel@tonic-gate LDAP_CALL 3760Sstevel@tonic-gate ldap_first_tmplcol( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row ) 3770Sstevel@tonic-gate { 3780Sstevel@tonic-gate return( row ); 3790Sstevel@tonic-gate } 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate 3820Sstevel@tonic-gate struct ldap_tmplitem * 3830Sstevel@tonic-gate LDAP_CALL 3840Sstevel@tonic-gate ldap_next_tmplcol( struct ldap_disptmpl *tmpl, struct ldap_tmplitem *row, 3850Sstevel@tonic-gate struct ldap_tmplitem *col ) 3860Sstevel@tonic-gate { 3870Sstevel@tonic-gate return( col == NULLTMPLITEM ? col : col->ti_next_in_row ); 3880Sstevel@tonic-gate } 3890Sstevel@tonic-gate 3900Sstevel@tonic-gate 3910Sstevel@tonic-gate char ** 3920Sstevel@tonic-gate LDAP_CALL 3930Sstevel@tonic-gate ldap_tmplattrs( struct ldap_disptmpl *tmpl, char **includeattrs, 3940Sstevel@tonic-gate int exclude, unsigned long syntaxmask ) 3950Sstevel@tonic-gate { 3960Sstevel@tonic-gate /* 3970Sstevel@tonic-gate * this routine should filter out duplicate attributes... 3980Sstevel@tonic-gate */ 3990Sstevel@tonic-gate struct ldap_tmplitem *tirowp, *ticolp; 4000Sstevel@tonic-gate int i, attrcnt, memerr; 4010Sstevel@tonic-gate char **attrs; 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate attrcnt = 0; 4040Sstevel@tonic-gate memerr = 0; 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate if (( attrs = (char **)NSLDAPI_MALLOC( sizeof( char * ))) == NULL ) { 4070Sstevel@tonic-gate return( NULL ); 4080Sstevel@tonic-gate } 4090Sstevel@tonic-gate 4100Sstevel@tonic-gate if ( includeattrs != NULL ) { 4110Sstevel@tonic-gate for ( i = 0; !memerr && includeattrs[ i ] != NULL; ++i ) { 4120Sstevel@tonic-gate if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 ) * 4130Sstevel@tonic-gate sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] = 4140Sstevel@tonic-gate nsldapi_strdup( includeattrs[ i ] )) == NULL ) { 4150Sstevel@tonic-gate memerr = 1; 4160Sstevel@tonic-gate } else { 4170Sstevel@tonic-gate attrs[ attrcnt ] = NULL; 4180Sstevel@tonic-gate } 4190Sstevel@tonic-gate } 4200Sstevel@tonic-gate } 4210Sstevel@tonic-gate 4220Sstevel@tonic-gate for ( tirowp = ldap_first_tmplrow( tmpl ); 4230Sstevel@tonic-gate !memerr && tirowp != NULLTMPLITEM; 4240Sstevel@tonic-gate tirowp = ldap_next_tmplrow( tmpl, tirowp )) { 4250Sstevel@tonic-gate for ( ticolp = ldap_first_tmplcol( tmpl, tirowp ); 4260Sstevel@tonic-gate ticolp != NULLTMPLITEM; 4270Sstevel@tonic-gate ticolp = ldap_next_tmplcol( tmpl, tirowp, ticolp )) { 4280Sstevel@tonic-gate 4290Sstevel@tonic-gate if ( syntaxmask != 0 ) { 4300Sstevel@tonic-gate if (( exclude && 4310Sstevel@tonic-gate ( syntaxmask & ticolp->ti_syntaxid ) != 0 ) || 4320Sstevel@tonic-gate ( !exclude && 4330Sstevel@tonic-gate ( syntaxmask & ticolp->ti_syntaxid ) == 0 )) { 4340Sstevel@tonic-gate continue; 4350Sstevel@tonic-gate } 4360Sstevel@tonic-gate } 4370Sstevel@tonic-gate 4380Sstevel@tonic-gate if ( ticolp->ti_attrname != NULL ) { 4390Sstevel@tonic-gate if (( attrs = (char **)NSLDAPI_REALLOC( attrs, ( attrcnt + 2 ) 4400Sstevel@tonic-gate * sizeof( char * ))) == NULL || ( attrs[ attrcnt++ ] = 4410Sstevel@tonic-gate nsldapi_strdup( ticolp->ti_attrname )) == NULL ) { 4420Sstevel@tonic-gate memerr = 1; 4430Sstevel@tonic-gate } else { 4440Sstevel@tonic-gate attrs[ attrcnt ] = NULL; 4450Sstevel@tonic-gate } 4460Sstevel@tonic-gate } 4470Sstevel@tonic-gate } 4480Sstevel@tonic-gate } 4490Sstevel@tonic-gate 4500Sstevel@tonic-gate if ( memerr || attrcnt == 0 ) { 4510Sstevel@tonic-gate for ( i = 0; i < attrcnt; ++i ) { 4520Sstevel@tonic-gate if ( attrs[ i ] != NULL ) { 4530Sstevel@tonic-gate NSLDAPI_FREE( attrs[ i ] ); 4540Sstevel@tonic-gate } 4550Sstevel@tonic-gate } 4560Sstevel@tonic-gate 4570Sstevel@tonic-gate NSLDAPI_FREE( (char *)attrs ); 4580Sstevel@tonic-gate return( NULL ); 4590Sstevel@tonic-gate } 4600Sstevel@tonic-gate 4610Sstevel@tonic-gate return( attrs ); 4620Sstevel@tonic-gate } 4630Sstevel@tonic-gate 4640Sstevel@tonic-gate 4650Sstevel@tonic-gate static int 4660Sstevel@tonic-gate read_next_tmpl( char **bufp, long *blenp, struct ldap_disptmpl **tmplp, 4670Sstevel@tonic-gate int dtversion ) 4680Sstevel@tonic-gate { 4690Sstevel@tonic-gate int i, j, tokcnt, samerow, adsource; 4700Sstevel@tonic-gate char **toks, *itemopts; 4710Sstevel@tonic-gate struct ldap_disptmpl *tmpl = NULL; 4720Sstevel@tonic-gate struct ldap_oclist *ocp = NULL, *prevocp = NULL; 4730Sstevel@tonic-gate struct ldap_adddeflist *adp = NULL, *prevadp = NULL; 4740Sstevel@tonic-gate struct ldap_tmplitem *rowp = NULL, *ip = NULL, *previp = NULL; 4750Sstevel@tonic-gate 4760Sstevel@tonic-gate /* 4770Sstevel@tonic-gate * template name comes first 4780Sstevel@tonic-gate */ 4790Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 4800Sstevel@tonic-gate ldap_free_strarray( toks ); 4810Sstevel@tonic-gate return( tokcnt == 0 ? 0 : LDAP_TMPL_ERR_SYNTAX ); 4820Sstevel@tonic-gate } 4830Sstevel@tonic-gate 4840Sstevel@tonic-gate if (( tmpl = (struct ldap_disptmpl *)NSLDAPI_CALLOC( 1, 4850Sstevel@tonic-gate sizeof( struct ldap_disptmpl ))) == NULL ) { 4860Sstevel@tonic-gate ldap_free_strarray( toks ); 4870Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 4880Sstevel@tonic-gate } 4890Sstevel@tonic-gate tmpl->dt_name = toks[ 0 ]; 4900Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 4910Sstevel@tonic-gate 4920Sstevel@tonic-gate /* 4930Sstevel@tonic-gate * template plural name comes next 4940Sstevel@tonic-gate */ 4950Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 4960Sstevel@tonic-gate ldap_free_strarray( toks ); 4970Sstevel@tonic-gate free_disptmpl( tmpl ); 4980Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 4990Sstevel@tonic-gate } 5000Sstevel@tonic-gate tmpl->dt_pluralname = toks[ 0 ]; 5010Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 5020Sstevel@tonic-gate 5030Sstevel@tonic-gate /* 5040Sstevel@tonic-gate * template icon name is next 5050Sstevel@tonic-gate */ 5060Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 5070Sstevel@tonic-gate ldap_free_strarray( toks ); 5080Sstevel@tonic-gate free_disptmpl( tmpl ); 5090Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 5100Sstevel@tonic-gate } 5110Sstevel@tonic-gate tmpl->dt_iconname = toks[ 0 ]; 5120Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 5130Sstevel@tonic-gate 5140Sstevel@tonic-gate /* 5150Sstevel@tonic-gate * template options come next 5160Sstevel@tonic-gate */ 5170Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) < 1 ) { 5180Sstevel@tonic-gate ldap_free_strarray( toks ); 5190Sstevel@tonic-gate free_disptmpl( tmpl ); 5200Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 5210Sstevel@tonic-gate } 5220Sstevel@tonic-gate for ( i = 0; toks[ i ] != NULL; ++i ) { 5230Sstevel@tonic-gate for ( j = 0; tmploptions[ j ] != NULL; ++j ) { 5240Sstevel@tonic-gate if ( strcasecmp( toks[ i ], tmploptions[ j ] ) == 0 ) { 5250Sstevel@tonic-gate tmpl->dt_options |= tmploptvals[ j ]; 5260Sstevel@tonic-gate } 5270Sstevel@tonic-gate } 5280Sstevel@tonic-gate } 5290Sstevel@tonic-gate ldap_free_strarray( toks ); 5300Sstevel@tonic-gate 5310Sstevel@tonic-gate /* 5320Sstevel@tonic-gate * object class list is next 5330Sstevel@tonic-gate */ 5340Sstevel@tonic-gate while (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) > 0 ) { 5350Sstevel@tonic-gate if (( ocp = (struct ldap_oclist *)NSLDAPI_CALLOC( 1, 5360Sstevel@tonic-gate sizeof( struct ldap_oclist ))) == NULL ) { 5370Sstevel@tonic-gate ldap_free_strarray( toks ); 5380Sstevel@tonic-gate free_disptmpl( tmpl ); 5390Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 5400Sstevel@tonic-gate } 5410Sstevel@tonic-gate ocp->oc_objclasses = toks; 5420Sstevel@tonic-gate if ( tmpl->dt_oclist == NULL ) { 5430Sstevel@tonic-gate tmpl->dt_oclist = ocp; 5440Sstevel@tonic-gate } else { 5450Sstevel@tonic-gate prevocp->oc_next = ocp; 5460Sstevel@tonic-gate } 5470Sstevel@tonic-gate prevocp = ocp; 5480Sstevel@tonic-gate } 5490Sstevel@tonic-gate if ( tokcnt < 0 ) { 5500Sstevel@tonic-gate free_disptmpl( tmpl ); 5510Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 5520Sstevel@tonic-gate } 5530Sstevel@tonic-gate 5540Sstevel@tonic-gate /* 5550Sstevel@tonic-gate * read name of attribute to authenticate as 5560Sstevel@tonic-gate */ 5570Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 5580Sstevel@tonic-gate ldap_free_strarray( toks ); 5590Sstevel@tonic-gate free_disptmpl( tmpl ); 5600Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 5610Sstevel@tonic-gate } 5620Sstevel@tonic-gate if ( toks[ 0 ][ 0 ] != '\0' ) { 5630Sstevel@tonic-gate tmpl->dt_authattrname = toks[ 0 ]; 5640Sstevel@tonic-gate } else { 5650Sstevel@tonic-gate NSLDAPI_FREE( toks[ 0 ] ); 5660Sstevel@tonic-gate } 5670Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 5680Sstevel@tonic-gate 5690Sstevel@tonic-gate /* 5700Sstevel@tonic-gate * read default attribute to use for RDN 5710Sstevel@tonic-gate */ 5720Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 5730Sstevel@tonic-gate ldap_free_strarray( toks ); 5740Sstevel@tonic-gate free_disptmpl( tmpl ); 5750Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 5760Sstevel@tonic-gate } 5770Sstevel@tonic-gate tmpl->dt_defrdnattrname = toks[ 0 ]; 5780Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 5790Sstevel@tonic-gate 5800Sstevel@tonic-gate /* 5810Sstevel@tonic-gate * read default location for new entries 5820Sstevel@tonic-gate */ 5830Sstevel@tonic-gate if (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) != 1 ) { 5840Sstevel@tonic-gate ldap_free_strarray( toks ); 5850Sstevel@tonic-gate free_disptmpl( tmpl ); 5860Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 5870Sstevel@tonic-gate } 5880Sstevel@tonic-gate if ( toks[ 0 ][ 0 ] != '\0' ) { 5890Sstevel@tonic-gate tmpl->dt_defaddlocation = toks[ 0 ]; 5900Sstevel@tonic-gate } else { 5910Sstevel@tonic-gate NSLDAPI_FREE( toks[ 0 ] ); 5920Sstevel@tonic-gate } 5930Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 5940Sstevel@tonic-gate 5950Sstevel@tonic-gate /* 5960Sstevel@tonic-gate * read list of rules used to define default values for new entries 5970Sstevel@tonic-gate */ 5980Sstevel@tonic-gate while (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) > 0 ) { 5990Sstevel@tonic-gate if ( strcasecmp( ADDEF_CONSTANT, toks[ 0 ] ) == 0 ) { 6000Sstevel@tonic-gate adsource = LDAP_ADSRC_CONSTANTVALUE; 6010Sstevel@tonic-gate } else if ( strcasecmp( ADDEF_ADDERSDN, toks[ 0 ] ) == 0 ) { 6020Sstevel@tonic-gate adsource = LDAP_ADSRC_ADDERSDN; 6030Sstevel@tonic-gate } else { 6040Sstevel@tonic-gate adsource = 0; 6050Sstevel@tonic-gate } 6060Sstevel@tonic-gate if ( adsource == 0 || tokcnt < 2 || 6070Sstevel@tonic-gate ( adsource == LDAP_ADSRC_CONSTANTVALUE && tokcnt != 3 ) || 6080Sstevel@tonic-gate ( adsource == LDAP_ADSRC_ADDERSDN && tokcnt != 2 )) { 6090Sstevel@tonic-gate ldap_free_strarray( toks ); 6100Sstevel@tonic-gate free_disptmpl( tmpl ); 6110Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 6120Sstevel@tonic-gate } 6130Sstevel@tonic-gate 6140Sstevel@tonic-gate if (( adp = (struct ldap_adddeflist *)NSLDAPI_CALLOC( 1, 6150Sstevel@tonic-gate sizeof( struct ldap_adddeflist ))) == NULL ) { 6160Sstevel@tonic-gate ldap_free_strarray( toks ); 6170Sstevel@tonic-gate free_disptmpl( tmpl ); 6180Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 6190Sstevel@tonic-gate } 6200Sstevel@tonic-gate adp->ad_source = adsource; 6210Sstevel@tonic-gate adp->ad_attrname = toks[ 1 ]; 6220Sstevel@tonic-gate if ( adsource == LDAP_ADSRC_CONSTANTVALUE ) { 6230Sstevel@tonic-gate adp->ad_value = toks[ 2 ]; 6240Sstevel@tonic-gate } 6250Sstevel@tonic-gate NSLDAPI_FREE( toks[ 0 ] ); 6260Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 6270Sstevel@tonic-gate 6280Sstevel@tonic-gate if ( tmpl->dt_adddeflist == NULL ) { 6290Sstevel@tonic-gate tmpl->dt_adddeflist = adp; 6300Sstevel@tonic-gate } else { 6310Sstevel@tonic-gate prevadp->ad_next = adp; 6320Sstevel@tonic-gate } 6330Sstevel@tonic-gate prevadp = adp; 6340Sstevel@tonic-gate } 6350Sstevel@tonic-gate 6360Sstevel@tonic-gate /* 6370Sstevel@tonic-gate * item list is next 6380Sstevel@tonic-gate */ 6390Sstevel@tonic-gate samerow = 0; 6400Sstevel@tonic-gate while (( tokcnt = ldap_next_line_tokens( bufp, blenp, &toks )) > 0 ) { 6410Sstevel@tonic-gate if ( strcasecmp( toks[ 0 ], "item" ) == 0 ) { 6420Sstevel@tonic-gate if ( tokcnt < 4 ) { 6430Sstevel@tonic-gate ldap_free_strarray( toks ); 6440Sstevel@tonic-gate free_disptmpl( tmpl ); 6450Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 6460Sstevel@tonic-gate } 6470Sstevel@tonic-gate 6480Sstevel@tonic-gate if (( ip = (struct ldap_tmplitem *)NSLDAPI_CALLOC( 1, 6490Sstevel@tonic-gate sizeof( struct ldap_tmplitem ))) == NULL ) { 6500Sstevel@tonic-gate ldap_free_strarray( toks ); 6510Sstevel@tonic-gate free_disptmpl( tmpl ); 6520Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 6530Sstevel@tonic-gate } 6540Sstevel@tonic-gate 6550Sstevel@tonic-gate /* 6560Sstevel@tonic-gate * find syntaxid from config file string 6570Sstevel@tonic-gate */ 6580Sstevel@tonic-gate while (( itemopts = strrchr( toks[ 1 ], ',' )) != NULL ) { 6590Sstevel@tonic-gate *itemopts++ = '\0'; 6600Sstevel@tonic-gate for ( i = 0; itemoptions[ i ] != NULL; ++i ) { 6610Sstevel@tonic-gate if ( strcasecmp( itemopts, itemoptions[ i ] ) == 0 ) { 6620Sstevel@tonic-gate break; 6630Sstevel@tonic-gate } 6640Sstevel@tonic-gate } 6650Sstevel@tonic-gate if ( itemoptions[ i ] == NULL ) { 6660Sstevel@tonic-gate ldap_free_strarray( toks ); 6670Sstevel@tonic-gate free_disptmpl( tmpl ); 6680Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 6690Sstevel@tonic-gate } 6700Sstevel@tonic-gate ip->ti_options |= itemoptvals[ i ]; 6710Sstevel@tonic-gate } 6720Sstevel@tonic-gate 6730Sstevel@tonic-gate for ( i = 0; itemtypes[ i ] != NULL; ++i ) { 6740Sstevel@tonic-gate if ( strcasecmp( toks[ 1 ], itemtypes[ i ] ) == 0 ) { 6750Sstevel@tonic-gate break; 6760Sstevel@tonic-gate } 6770Sstevel@tonic-gate } 6780Sstevel@tonic-gate if ( itemtypes[ i ] == NULL ) { 6790Sstevel@tonic-gate ldap_free_strarray( toks ); 6800Sstevel@tonic-gate free_disptmpl( tmpl ); 6810Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 6820Sstevel@tonic-gate } 6830Sstevel@tonic-gate 6840Sstevel@tonic-gate NSLDAPI_FREE( toks[ 0 ] ); 6850Sstevel@tonic-gate NSLDAPI_FREE( toks[ 1 ] ); 6860Sstevel@tonic-gate ip->ti_syntaxid = itemsynids[ i ]; 6870Sstevel@tonic-gate ip->ti_label = toks[ 2 ]; 6880Sstevel@tonic-gate if ( toks[ 3 ][ 0 ] == '\0' ) { 6890Sstevel@tonic-gate ip->ti_attrname = NULL; 6900Sstevel@tonic-gate NSLDAPI_FREE( toks[ 3 ] ); 6910Sstevel@tonic-gate } else { 6920Sstevel@tonic-gate ip->ti_attrname = toks[ 3 ]; 6930Sstevel@tonic-gate } 6940Sstevel@tonic-gate if ( toks[ 4 ] != NULL ) { /* extra args. */ 6950Sstevel@tonic-gate for ( i = 0; toks[ i + 4 ] != NULL; ++i ) { 6960Sstevel@tonic-gate ; 6970Sstevel@tonic-gate } 6980Sstevel@tonic-gate if (( ip->ti_args = (char **)NSLDAPI_CALLOC( i + 1, 6990Sstevel@tonic-gate sizeof( char * ))) == NULL ) { 7000Sstevel@tonic-gate free_disptmpl( tmpl ); 7010Sstevel@tonic-gate return( LDAP_TMPL_ERR_MEM ); 7020Sstevel@tonic-gate } 7030Sstevel@tonic-gate for ( i = 0; toks[ i + 4 ] != NULL; ++i ) { 7040Sstevel@tonic-gate ip->ti_args[ i ] = toks[ i + 4 ]; 7050Sstevel@tonic-gate } 7060Sstevel@tonic-gate } 7070Sstevel@tonic-gate NSLDAPI_FREE( (char *)toks ); 7080Sstevel@tonic-gate 7090Sstevel@tonic-gate if ( tmpl->dt_items == NULL ) { 7100Sstevel@tonic-gate tmpl->dt_items = rowp = ip; 7110Sstevel@tonic-gate } else if ( samerow ) { 7120Sstevel@tonic-gate previp->ti_next_in_row = ip; 7130Sstevel@tonic-gate } else { 7140Sstevel@tonic-gate rowp->ti_next_in_col = ip; 7150Sstevel@tonic-gate rowp = ip; 7160Sstevel@tonic-gate } 7170Sstevel@tonic-gate previp = ip; 7180Sstevel@tonic-gate samerow = 0; 7190Sstevel@tonic-gate } else if ( strcasecmp( toks[ 0 ], "samerow" ) == 0 ) { 7200Sstevel@tonic-gate ldap_free_strarray( toks ); 7210Sstevel@tonic-gate samerow = 1; 7220Sstevel@tonic-gate } else { 7230Sstevel@tonic-gate ldap_free_strarray( toks ); 7240Sstevel@tonic-gate free_disptmpl( tmpl ); 7250Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 7260Sstevel@tonic-gate } 7270Sstevel@tonic-gate } 7280Sstevel@tonic-gate if ( tokcnt < 0 ) { 7290Sstevel@tonic-gate free_disptmpl( tmpl ); 7300Sstevel@tonic-gate return( LDAP_TMPL_ERR_SYNTAX ); 7310Sstevel@tonic-gate } 7320Sstevel@tonic-gate 7330Sstevel@tonic-gate *tmplp = tmpl; 7340Sstevel@tonic-gate return( 0 ); 7350Sstevel@tonic-gate } 7360Sstevel@tonic-gate 7370Sstevel@tonic-gate 7380Sstevel@tonic-gate struct tmplerror { 7390Sstevel@tonic-gate int e_code; 7400Sstevel@tonic-gate char *e_reason; 7410Sstevel@tonic-gate }; 7420Sstevel@tonic-gate 7430Sstevel@tonic-gate #ifdef SUN 7440Sstevel@tonic-gate static struct tmplerror ldap_tmplerrlist[] = { 7450Sstevel@tonic-gate { LDAP_TMPL_ERR_VERSION, 0}, 7460Sstevel@tonic-gate { LDAP_TMPL_ERR_MEM, 0}, 7470Sstevel@tonic-gate { LDAP_TMPL_ERR_SYNTAX, 0}, 7480Sstevel@tonic-gate { LDAP_TMPL_ERR_FILE, 0}, 7490Sstevel@tonic-gate { -1, 0 } 7500Sstevel@tonic-gate }; 7510Sstevel@tonic-gate #else 7520Sstevel@tonic-gate static struct tmplerror ldap_tmplerrlist[] = { 7530Sstevel@tonic-gate { LDAP_TMPL_ERR_VERSION, "Bad template version" }, 7540Sstevel@tonic-gate { LDAP_TMPL_ERR_MEM, "Out of memory" }, 7550Sstevel@tonic-gate { LDAP_TMPL_ERR_SYNTAX, "Bad template syntax" }, 7560Sstevel@tonic-gate { LDAP_TMPL_ERR_FILE, "File error reading template" }, 7570Sstevel@tonic-gate { -1, 0 } 7580Sstevel@tonic-gate }; 7590Sstevel@tonic-gate #endif 7600Sstevel@tonic-gate 7610Sstevel@tonic-gate char * 7620Sstevel@tonic-gate LDAP_CALL 7630Sstevel@tonic-gate ldap_tmplerr2string( int err ) 7640Sstevel@tonic-gate { 7650Sstevel@tonic-gate static int init_flag = 0; 7660Sstevel@tonic-gate int i; 7670Sstevel@tonic-gate 7680Sstevel@tonic-gate /* Multiple threads should be ok since they assign same strings */ 7690Sstevel@tonic-gate if (init_flag == 0) { 7700Sstevel@tonic-gate ldap_tmplerrlist[0].e_reason = 7710Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "Bad template version"); 7720Sstevel@tonic-gate ldap_tmplerrlist[1].e_reason = 7730Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "Out of memory"); 7740Sstevel@tonic-gate ldap_tmplerrlist[2].e_reason = 7750Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "Bad template syntax"); 7760Sstevel@tonic-gate ldap_tmplerrlist[3].e_reason = 7770Sstevel@tonic-gate dgettext(TEXT_DOMAIN, "File error reading template"); 7780Sstevel@tonic-gate init_flag = 1; 7790Sstevel@tonic-gate } 7800Sstevel@tonic-gate 7810Sstevel@tonic-gate for ( i = 0; ldap_tmplerrlist[i].e_code != -1; i++ ) { 7820Sstevel@tonic-gate if ( err == ldap_tmplerrlist[i].e_code ) 7830Sstevel@tonic-gate return( ldap_tmplerrlist[i].e_reason ); 7840Sstevel@tonic-gate } 7850Sstevel@tonic-gate 7860Sstevel@tonic-gate return(dgettext(TEXT_DOMAIN, "Unknown error") ); 7870Sstevel@tonic-gate } 788