1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate 7*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 8*7c478bd9Sstevel@tonic-gate 9*7c478bd9Sstevel@tonic-gate 10*7c478bd9Sstevel@tonic-gate /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- 11*7c478bd9Sstevel@tonic-gate * 12*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public License 13*7c478bd9Sstevel@tonic-gate * Version 1.0 (the "NPL"); you may not use this file except in 14*7c478bd9Sstevel@tonic-gate * compliance with the NPL. You may obtain a copy of the NPL at 15*7c478bd9Sstevel@tonic-gate * http://www.mozilla.org/NPL/ 16*7c478bd9Sstevel@tonic-gate * 17*7c478bd9Sstevel@tonic-gate * Software distributed under the NPL is distributed on an "AS IS" basis, 18*7c478bd9Sstevel@tonic-gate * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL 19*7c478bd9Sstevel@tonic-gate * for the specific language governing rights and limitations under the 20*7c478bd9Sstevel@tonic-gate * NPL. 21*7c478bd9Sstevel@tonic-gate * 22*7c478bd9Sstevel@tonic-gate * The Initial Developer of this code under the NPL is Netscape 23*7c478bd9Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 24*7c478bd9Sstevel@tonic-gate * Copyright (C) 1998 Netscape Communications Corporation. All Rights 25*7c478bd9Sstevel@tonic-gate * Reserved. 26*7c478bd9Sstevel@tonic-gate */ 27*7c478bd9Sstevel@tonic-gate 28*7c478bd9Sstevel@tonic-gate /* 29*7c478bd9Sstevel@tonic-gate * Copyright (c) 1990 Regents of the University of Michigan. 30*7c478bd9Sstevel@tonic-gate * All rights reserved. 31*7c478bd9Sstevel@tonic-gate * 32*7c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted 33*7c478bd9Sstevel@tonic-gate * provided that this notice is preserved and that due credit is given 34*7c478bd9Sstevel@tonic-gate * to the University of Michigan at Ann Arbor. The name of the University 35*7c478bd9Sstevel@tonic-gate * may not be used to endorse or promote products derived from this 36*7c478bd9Sstevel@tonic-gate * software without specific prior written permission. This software 37*7c478bd9Sstevel@tonic-gate * is provided ``as is'' without express or implied warranty. 38*7c478bd9Sstevel@tonic-gate */ 39*7c478bd9Sstevel@tonic-gate 40*7c478bd9Sstevel@tonic-gate /* decode.c - ber input decoding routines */ 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #include "lber-int.h" 43*7c478bd9Sstevel@tonic-gate LDAP_API(void) LDAP_CALL ber_svecfree( char **vals ); 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate /* 46*7c478bd9Sstevel@tonic-gate * Note: ber_get_tag() only uses the ber_end and ber_ptr elements of ber. 47*7c478bd9Sstevel@tonic-gate * If that changes, the ber_peek_tag() and/or ber_skip_tag() implementations 48*7c478bd9Sstevel@tonic-gate * will need to be changed. 49*7c478bd9Sstevel@tonic-gate */ 50*7c478bd9Sstevel@tonic-gate /* return the tag - LBER_DEFAULT returned means trouble */ 51*7c478bd9Sstevel@tonic-gate ber_tag_t 52*7c478bd9Sstevel@tonic-gate LDAP_CALL 53*7c478bd9Sstevel@tonic-gate ber_get_tag( BerElement *ber ) 54*7c478bd9Sstevel@tonic-gate { 55*7c478bd9Sstevel@tonic-gate unsigned char xbyte; 56*7c478bd9Sstevel@tonic-gate ber_tag_t tag; 57*7c478bd9Sstevel@tonic-gate char *tagp; 58*7c478bd9Sstevel@tonic-gate int i; 59*7c478bd9Sstevel@tonic-gate 60*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 ) 61*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate if ( (xbyte & LBER_BIG_TAG_MASK) != LBER_BIG_TAG_MASK ) 64*7c478bd9Sstevel@tonic-gate return( (ber_uint_t) xbyte ); 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate tagp = (char *) &tag; 67*7c478bd9Sstevel@tonic-gate tagp[0] = xbyte; 68*7c478bd9Sstevel@tonic-gate for ( i = 1; i < sizeof(ber_int_t); i++ ) { 69*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, (char *) &xbyte, 1 ) != 1 ) 70*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 71*7c478bd9Sstevel@tonic-gate 72*7c478bd9Sstevel@tonic-gate tagp[i] = xbyte; 73*7c478bd9Sstevel@tonic-gate 74*7c478bd9Sstevel@tonic-gate if ( ! (xbyte & LBER_MORE_TAG_MASK) ) 75*7c478bd9Sstevel@tonic-gate break; 76*7c478bd9Sstevel@tonic-gate } 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate /* tag too big! */ 79*7c478bd9Sstevel@tonic-gate if ( i == sizeof(ber_int_t) ) 80*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 81*7c478bd9Sstevel@tonic-gate 82*7c478bd9Sstevel@tonic-gate /* want leading, not trailing 0's */ 83*7c478bd9Sstevel@tonic-gate return( tag >> (sizeof(ber_int_t) - i - 1) ); 84*7c478bd9Sstevel@tonic-gate } 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate /* 87*7c478bd9Sstevel@tonic-gate * Note: ber_skip_tag() only uses the ber_end and ber_ptr elements of ber. 88*7c478bd9Sstevel@tonic-gate * If that changes, the implementation of ber_peek_tag() will need to 89*7c478bd9Sstevel@tonic-gate * be changed. 90*7c478bd9Sstevel@tonic-gate */ 91*7c478bd9Sstevel@tonic-gate ber_tag_t 92*7c478bd9Sstevel@tonic-gate LDAP_CALL 93*7c478bd9Sstevel@tonic-gate ber_skip_tag( BerElement *ber, ber_len_t *len ) 94*7c478bd9Sstevel@tonic-gate { 95*7c478bd9Sstevel@tonic-gate ber_tag_t tag; 96*7c478bd9Sstevel@tonic-gate unsigned char lc; 97*7c478bd9Sstevel@tonic-gate int noctets, diff; 98*7c478bd9Sstevel@tonic-gate ber_len_t netlen; 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate /* 101*7c478bd9Sstevel@tonic-gate * Any ber element looks like this: tag length contents. 102*7c478bd9Sstevel@tonic-gate * Assuming everything's ok, we return the tag byte (we 103*7c478bd9Sstevel@tonic-gate * can assume a single byte), and return the length in len. 104*7c478bd9Sstevel@tonic-gate * 105*7c478bd9Sstevel@tonic-gate * Assumptions: 106*7c478bd9Sstevel@tonic-gate * 1) definite lengths 107*7c478bd9Sstevel@tonic-gate * 2) primitive encodings used whenever possible 108*7c478bd9Sstevel@tonic-gate */ 109*7c478bd9Sstevel@tonic-gate 110*7c478bd9Sstevel@tonic-gate /* 111*7c478bd9Sstevel@tonic-gate * First, we read the tag. 112*7c478bd9Sstevel@tonic-gate */ 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate if ( (tag = ber_get_tag( ber )) == LBER_DEFAULT ) 115*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 116*7c478bd9Sstevel@tonic-gate 117*7c478bd9Sstevel@tonic-gate /* 118*7c478bd9Sstevel@tonic-gate * Next, read the length. The first byte contains the length of 119*7c478bd9Sstevel@tonic-gate * the length. If bit 8 is set, the length is the long form, 120*7c478bd9Sstevel@tonic-gate * otherwise it's the short form. We don't allow a length that's 121*7c478bd9Sstevel@tonic-gate * greater than what we can hold in an unsigned long. 122*7c478bd9Sstevel@tonic-gate */ 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate *len = netlen = 0; 125*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, (char *) &lc, 1 ) != 1 ) 126*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 127*7c478bd9Sstevel@tonic-gate if ( lc & 0x80 ) { 128*7c478bd9Sstevel@tonic-gate noctets = (lc & 0x7f); 129*7c478bd9Sstevel@tonic-gate if ( noctets > sizeof(ber_uint_t) ) 130*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 131*7c478bd9Sstevel@tonic-gate diff = sizeof(ber_int_t) - noctets; 132*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, (char *) &netlen + diff, noctets ) 133*7c478bd9Sstevel@tonic-gate != noctets ) 134*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 135*7c478bd9Sstevel@tonic-gate *len = LBER_NTOHL( netlen ); 136*7c478bd9Sstevel@tonic-gate } else { 137*7c478bd9Sstevel@tonic-gate *len = lc; 138*7c478bd9Sstevel@tonic-gate } 139*7c478bd9Sstevel@tonic-gate 140*7c478bd9Sstevel@tonic-gate return( tag ); 141*7c478bd9Sstevel@tonic-gate } 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate /* 145*7c478bd9Sstevel@tonic-gate * Note: Previously, we passed the "ber" parameter directly to ber_skip_tag(), 146*7c478bd9Sstevel@tonic-gate * saving and restoring the ber_ptr element only. We now take advantage 147*7c478bd9Sstevel@tonic-gate * of the fact that the only ber structure elements touched by ber_skip_tag() 148*7c478bd9Sstevel@tonic-gate * are ber_end and ber_ptr. If that changes, this code must change too. 149*7c478bd9Sstevel@tonic-gate */ 150*7c478bd9Sstevel@tonic-gate ber_tag_t 151*7c478bd9Sstevel@tonic-gate LDAP_CALL 152*7c478bd9Sstevel@tonic-gate ber_peek_tag( BerElement *ber, ber_len_t *len ) 153*7c478bd9Sstevel@tonic-gate { 154*7c478bd9Sstevel@tonic-gate BerElement bercopy; 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate bercopy.ber_end = ber->ber_end; 157*7c478bd9Sstevel@tonic-gate bercopy.ber_ptr = ber->ber_ptr; 158*7c478bd9Sstevel@tonic-gate return( ber_skip_tag( &bercopy, len )); 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate static int 162*7c478bd9Sstevel@tonic-gate ber_getnint( BerElement *ber, ber_int_t *num, ber_slen_t len ) 163*7c478bd9Sstevel@tonic-gate { 164*7c478bd9Sstevel@tonic-gate int i; 165*7c478bd9Sstevel@tonic-gate ber_int_t value; 166*7c478bd9Sstevel@tonic-gate unsigned char buffer[sizeof(ber_int_t)]; 167*7c478bd9Sstevel@tonic-gate /* 168*7c478bd9Sstevel@tonic-gate * The tag and length have already been stripped off. We should 169*7c478bd9Sstevel@tonic-gate * be sitting right before len bytes of 2's complement integer, 170*7c478bd9Sstevel@tonic-gate * ready to be read straight into an int. We may have to sign 171*7c478bd9Sstevel@tonic-gate * extend after we read it in. 172*7c478bd9Sstevel@tonic-gate */ 173*7c478bd9Sstevel@tonic-gate 174*7c478bd9Sstevel@tonic-gate if ( len > sizeof(ber_slen_t) ) 175*7c478bd9Sstevel@tonic-gate return( -1 ); 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate /* read into the low-order bytes of netnum */ 178*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, (char *) buffer, len ) != len ) 179*7c478bd9Sstevel@tonic-gate return( -1 ); 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate /* This sets the required sign extension */ 182*7c478bd9Sstevel@tonic-gate if ( len != 0) { 183*7c478bd9Sstevel@tonic-gate value = 0x80 & buffer[0] ? (LBER_FUNC_VALUE) : 0; 184*7c478bd9Sstevel@tonic-gate } else { 185*7c478bd9Sstevel@tonic-gate value = 0; 186*7c478bd9Sstevel@tonic-gate } 187*7c478bd9Sstevel@tonic-gate 188*7c478bd9Sstevel@tonic-gate for ( i = 0; i < len; i++ ) 189*7c478bd9Sstevel@tonic-gate value = (value << 8) | buffer[i]; 190*7c478bd9Sstevel@tonic-gate 191*7c478bd9Sstevel@tonic-gate *num = value; 192*7c478bd9Sstevel@tonic-gate 193*7c478bd9Sstevel@tonic-gate return( len ); 194*7c478bd9Sstevel@tonic-gate } 195*7c478bd9Sstevel@tonic-gate 196*7c478bd9Sstevel@tonic-gate ber_tag_t 197*7c478bd9Sstevel@tonic-gate LDAP_CALL 198*7c478bd9Sstevel@tonic-gate ber_get_int( BerElement *ber, ber_int_t *num ) 199*7c478bd9Sstevel@tonic-gate { 200*7c478bd9Sstevel@tonic-gate ber_tag_t tag; 201*7c478bd9Sstevel@tonic-gate ber_len_t len; 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) 204*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 205*7c478bd9Sstevel@tonic-gate 206*7c478bd9Sstevel@tonic-gate /* 207*7c478bd9Sstevel@tonic-gate * len is being demoted to a long here -- possible conversion error 208*7c478bd9Sstevel@tonic-gate */ 209*7c478bd9Sstevel@tonic-gate 210*7c478bd9Sstevel@tonic-gate if ( ber_getnint( ber, num, (int)len ) != (ber_slen_t)len ) 211*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 212*7c478bd9Sstevel@tonic-gate else 213*7c478bd9Sstevel@tonic-gate return( tag ); 214*7c478bd9Sstevel@tonic-gate } 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate ber_tag_t 217*7c478bd9Sstevel@tonic-gate LDAP_CALL 218*7c478bd9Sstevel@tonic-gate ber_get_stringb( BerElement *ber, char *buf, ber_len_t *len ) 219*7c478bd9Sstevel@tonic-gate { 220*7c478bd9Sstevel@tonic-gate ber_len_t datalen; 221*7c478bd9Sstevel@tonic-gate ber_tag_t tag; 222*7c478bd9Sstevel@tonic-gate #ifdef STR_TRANSLATION 223*7c478bd9Sstevel@tonic-gate char *transbuf; 224*7c478bd9Sstevel@tonic-gate #endif /* STR_TRANSLATION */ 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) 227*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 228*7c478bd9Sstevel@tonic-gate if ( datalen > (*len - 1) ) 229*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate /* 232*7c478bd9Sstevel@tonic-gate * datalen is being demoted to a long here -- possible conversion error 233*7c478bd9Sstevel@tonic-gate */ 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, buf, datalen ) != (ber_slen_t) datalen ) 236*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 237*7c478bd9Sstevel@tonic-gate 238*7c478bd9Sstevel@tonic-gate buf[datalen] = '\0'; 239*7c478bd9Sstevel@tonic-gate 240*7c478bd9Sstevel@tonic-gate #ifdef STR_TRANSLATION 241*7c478bd9Sstevel@tonic-gate if ( datalen > 0 && ( ber->ber_options & LBER_OPT_TRANSLATE_STRINGS ) 242*7c478bd9Sstevel@tonic-gate != 0 && ber->ber_decode_translate_proc != NULL ) { 243*7c478bd9Sstevel@tonic-gate transbuf = buf; 244*7c478bd9Sstevel@tonic-gate ++datalen; 245*7c478bd9Sstevel@tonic-gate if ( (*(ber->ber_decode_translate_proc))( &transbuf, &datalen, 246*7c478bd9Sstevel@tonic-gate 0 ) != 0 ) { 247*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 248*7c478bd9Sstevel@tonic-gate } 249*7c478bd9Sstevel@tonic-gate if ( datalen > *len ) { 250*7c478bd9Sstevel@tonic-gate NSLBERI_FREE( transbuf ); 251*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 252*7c478bd9Sstevel@tonic-gate } 253*7c478bd9Sstevel@tonic-gate SAFEMEMCPY( buf, transbuf, datalen ); 254*7c478bd9Sstevel@tonic-gate NSLBERI_FREE( transbuf ); 255*7c478bd9Sstevel@tonic-gate --datalen; 256*7c478bd9Sstevel@tonic-gate } 257*7c478bd9Sstevel@tonic-gate #endif /* STR_TRANSLATION */ 258*7c478bd9Sstevel@tonic-gate 259*7c478bd9Sstevel@tonic-gate *len = datalen; 260*7c478bd9Sstevel@tonic-gate return( tag ); 261*7c478bd9Sstevel@tonic-gate } 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate ber_tag_t 264*7c478bd9Sstevel@tonic-gate LDAP_CALL 265*7c478bd9Sstevel@tonic-gate ber_get_stringa( BerElement *ber, char **buf ) 266*7c478bd9Sstevel@tonic-gate { 267*7c478bd9Sstevel@tonic-gate ber_len_t datalen; 268*7c478bd9Sstevel@tonic-gate ber_tag_t tag; 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) 271*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 272*7c478bd9Sstevel@tonic-gate 273*7c478bd9Sstevel@tonic-gate if ( (*buf = (char *)NSLBERI_MALLOC( (size_t)datalen + 1 )) == NULL ) 274*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 275*7c478bd9Sstevel@tonic-gate 276*7c478bd9Sstevel@tonic-gate /* 277*7c478bd9Sstevel@tonic-gate * datalen is being demoted to a long here -- possible conversion error 278*7c478bd9Sstevel@tonic-gate */ 279*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, *buf, datalen ) != (ber_slen_t) datalen ) 280*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 281*7c478bd9Sstevel@tonic-gate (*buf)[datalen] = '\0'; 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate #ifdef STR_TRANSLATION 284*7c478bd9Sstevel@tonic-gate if ( datalen > 0 && ( ber->ber_options & LBER_OPT_TRANSLATE_STRINGS ) 285*7c478bd9Sstevel@tonic-gate != 0 && ber->ber_decode_translate_proc != NULL ) { 286*7c478bd9Sstevel@tonic-gate ++datalen; 287*7c478bd9Sstevel@tonic-gate if ( (*(ber->ber_decode_translate_proc))( buf, &datalen, 1 ) 288*7c478bd9Sstevel@tonic-gate != 0 ) { 289*7c478bd9Sstevel@tonic-gate NSLBERI_FREE( *buf ); 290*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 291*7c478bd9Sstevel@tonic-gate } 292*7c478bd9Sstevel@tonic-gate } 293*7c478bd9Sstevel@tonic-gate #endif /* STR_TRANSLATION */ 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate return( tag ); 296*7c478bd9Sstevel@tonic-gate } 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate ber_tag_t 299*7c478bd9Sstevel@tonic-gate LDAP_CALL 300*7c478bd9Sstevel@tonic-gate ber_get_stringal( BerElement *ber, struct berval **bv ) 301*7c478bd9Sstevel@tonic-gate { 302*7c478bd9Sstevel@tonic-gate ber_len_t len; 303*7c478bd9Sstevel@tonic-gate ber_tag_t tag; 304*7c478bd9Sstevel@tonic-gate 305*7c478bd9Sstevel@tonic-gate if ( (*bv = (struct berval *)NSLBERI_MALLOC( sizeof(struct berval) )) 306*7c478bd9Sstevel@tonic-gate == NULL ) { 307*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate 310*7c478bd9Sstevel@tonic-gate if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) { 311*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 312*7c478bd9Sstevel@tonic-gate } 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate if ( ((*bv)->bv_val = (char *)NSLBERI_MALLOC( (size_t)len + 1 )) 315*7c478bd9Sstevel@tonic-gate == NULL ) { 316*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate /* 320*7c478bd9Sstevel@tonic-gate * len is being demoted to a long here -- possible conversion error 321*7c478bd9Sstevel@tonic-gate */ 322*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, (*bv)->bv_val, len ) != (ber_slen_t) len ) 323*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 324*7c478bd9Sstevel@tonic-gate ((*bv)->bv_val)[len] = '\0'; 325*7c478bd9Sstevel@tonic-gate (*bv)->bv_len = len; 326*7c478bd9Sstevel@tonic-gate 327*7c478bd9Sstevel@tonic-gate #ifdef STR_TRANSLATION 328*7c478bd9Sstevel@tonic-gate if ( len > 0 && ( ber->ber_options & LBER_OPT_TRANSLATE_STRINGS ) != 0 329*7c478bd9Sstevel@tonic-gate && ber->ber_decode_translate_proc != NULL ) { 330*7c478bd9Sstevel@tonic-gate ++len; 331*7c478bd9Sstevel@tonic-gate if ( (*(ber->ber_decode_translate_proc))( &((*bv)->bv_val), 332*7c478bd9Sstevel@tonic-gate &len, 1 ) != 0 ) { 333*7c478bd9Sstevel@tonic-gate NSLBERI_FREE( (*bv)->bv_val ); 334*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 335*7c478bd9Sstevel@tonic-gate } 336*7c478bd9Sstevel@tonic-gate (*bv)->bv_len = len - 1; 337*7c478bd9Sstevel@tonic-gate } 338*7c478bd9Sstevel@tonic-gate #endif /* STR_TRANSLATION */ 339*7c478bd9Sstevel@tonic-gate 340*7c478bd9Sstevel@tonic-gate return( tag ); 341*7c478bd9Sstevel@tonic-gate } 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate ber_tag_t 344*7c478bd9Sstevel@tonic-gate LDAP_CALL 345*7c478bd9Sstevel@tonic-gate ber_get_bitstringa( BerElement *ber, char **buf, ber_len_t *blen ) 346*7c478bd9Sstevel@tonic-gate { 347*7c478bd9Sstevel@tonic-gate ber_len_t datalen; 348*7c478bd9Sstevel@tonic-gate ber_tag_t tag; 349*7c478bd9Sstevel@tonic-gate unsigned char unusedbits; 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate if ( (tag = ber_skip_tag( ber, &datalen )) == LBER_DEFAULT ) 352*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 353*7c478bd9Sstevel@tonic-gate --datalen; 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate if ( (*buf = (char *)NSLBERI_MALLOC( (size_t)datalen )) == NULL ) 356*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 357*7c478bd9Sstevel@tonic-gate 358*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, (char *)&unusedbits, 1 ) != 1 ) 359*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 360*7c478bd9Sstevel@tonic-gate 361*7c478bd9Sstevel@tonic-gate /* 362*7c478bd9Sstevel@tonic-gate * datalen is being demoted to a long here -- possible conversion error 363*7c478bd9Sstevel@tonic-gate */ 364*7c478bd9Sstevel@tonic-gate if ( ber_read( ber, *buf, datalen ) != (ber_slen_t) datalen ) 365*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 366*7c478bd9Sstevel@tonic-gate 367*7c478bd9Sstevel@tonic-gate *blen = datalen * 8 - unusedbits; 368*7c478bd9Sstevel@tonic-gate return( tag ); 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate ber_tag_t 372*7c478bd9Sstevel@tonic-gate LDAP_CALL 373*7c478bd9Sstevel@tonic-gate ber_get_null( BerElement *ber ) 374*7c478bd9Sstevel@tonic-gate { 375*7c478bd9Sstevel@tonic-gate ber_len_t len; 376*7c478bd9Sstevel@tonic-gate ber_tag_t tag; 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate if ( (tag = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) 379*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate if ( len != 0 ) 382*7c478bd9Sstevel@tonic-gate return( LBER_DEFAULT ); 383*7c478bd9Sstevel@tonic-gate 384*7c478bd9Sstevel@tonic-gate return( tag ); 385*7c478bd9Sstevel@tonic-gate } 386*7c478bd9Sstevel@tonic-gate 387*7c478bd9Sstevel@tonic-gate ber_tag_t 388*7c478bd9Sstevel@tonic-gate LDAP_CALL 389*7c478bd9Sstevel@tonic-gate ber_get_boolean( BerElement *ber, int *boolval ) 390*7c478bd9Sstevel@tonic-gate { 391*7c478bd9Sstevel@tonic-gate ber_int_t longbool; 392*7c478bd9Sstevel@tonic-gate int rc; 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate rc = ber_get_int( ber, &longbool ); 395*7c478bd9Sstevel@tonic-gate *boolval = longbool; 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate return( rc ); 398*7c478bd9Sstevel@tonic-gate } 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate ber_tag_t 401*7c478bd9Sstevel@tonic-gate LDAP_CALL 402*7c478bd9Sstevel@tonic-gate ber_first_element( BerElement *ber, ber_len_t *len, char **last ) 403*7c478bd9Sstevel@tonic-gate { 404*7c478bd9Sstevel@tonic-gate /* skip the sequence header, use the len to mark where to stop */ 405*7c478bd9Sstevel@tonic-gate if ( ber_skip_tag( ber, len ) == LBER_DEFAULT ) { 406*7c478bd9Sstevel@tonic-gate return( LBER_ERROR ); 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate *last = ber->ber_ptr + *len; 410*7c478bd9Sstevel@tonic-gate 411*7c478bd9Sstevel@tonic-gate if ( *last == ber->ber_ptr ) { 412*7c478bd9Sstevel@tonic-gate return( LBER_END_OF_SEQORSET ); 413*7c478bd9Sstevel@tonic-gate } 414*7c478bd9Sstevel@tonic-gate 415*7c478bd9Sstevel@tonic-gate return( ber_peek_tag( ber, len ) ); 416*7c478bd9Sstevel@tonic-gate } 417*7c478bd9Sstevel@tonic-gate 418*7c478bd9Sstevel@tonic-gate ber_tag_t 419*7c478bd9Sstevel@tonic-gate LDAP_CALL 420*7c478bd9Sstevel@tonic-gate ber_next_element( BerElement *ber, ber_len_t *len, char *last ) 421*7c478bd9Sstevel@tonic-gate { 422*7c478bd9Sstevel@tonic-gate if ( ber->ber_ptr == last ) { 423*7c478bd9Sstevel@tonic-gate return( LBER_END_OF_SEQORSET ); 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate return( ber_peek_tag( ber, len ) ); 427*7c478bd9Sstevel@tonic-gate } 428*7c478bd9Sstevel@tonic-gate 429*7c478bd9Sstevel@tonic-gate /* VARARGS */ 430*7c478bd9Sstevel@tonic-gate ber_tag_t 431*7c478bd9Sstevel@tonic-gate LDAP_C 432*7c478bd9Sstevel@tonic-gate ber_scanf( BerElement *ber, const char *fmt, ... ) 433*7c478bd9Sstevel@tonic-gate { 434*7c478bd9Sstevel@tonic-gate va_list ap; 435*7c478bd9Sstevel@tonic-gate char *last, *p; 436*7c478bd9Sstevel@tonic-gate char *s, **ss, ***sss; 437*7c478bd9Sstevel@tonic-gate struct berval ***bv, **bvp, *bval; 438*7c478bd9Sstevel@tonic-gate int *i, j; 439*7c478bd9Sstevel@tonic-gate ber_int_t *l, rc, tag; 440*7c478bd9Sstevel@tonic-gate ber_tag_t *t; 441*7c478bd9Sstevel@tonic-gate ber_len_t len; 442*7c478bd9Sstevel@tonic-gate size_t array_size; 443*7c478bd9Sstevel@tonic-gate 444*7c478bd9Sstevel@tonic-gate va_start( ap, fmt ); 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG 447*7c478bd9Sstevel@tonic-gate if ( lber_debug & 64 ) { 448*7c478bd9Sstevel@tonic-gate char msg[80]; 449*7c478bd9Sstevel@tonic-gate sprintf( msg, "ber_scanf fmt (%s) ber:\n", fmt ); 450*7c478bd9Sstevel@tonic-gate ber_err_print( msg ); 451*7c478bd9Sstevel@tonic-gate ber_dump( ber, 1 ); 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate #endif 454*7c478bd9Sstevel@tonic-gate 455*7c478bd9Sstevel@tonic-gate for ( rc = 0, p = (char *)fmt; *p && rc != LBER_DEFAULT; p++ ) { 456*7c478bd9Sstevel@tonic-gate switch ( *p ) { 457*7c478bd9Sstevel@tonic-gate case 'a': /* octet string - allocate storage as needed */ 458*7c478bd9Sstevel@tonic-gate ss = va_arg( ap, char ** ); 459*7c478bd9Sstevel@tonic-gate rc = ber_get_stringa( ber, ss ); 460*7c478bd9Sstevel@tonic-gate break; 461*7c478bd9Sstevel@tonic-gate 462*7c478bd9Sstevel@tonic-gate case 'b': /* boolean */ 463*7c478bd9Sstevel@tonic-gate i = va_arg( ap, int * ); 464*7c478bd9Sstevel@tonic-gate rc = ber_get_boolean( ber, i ); 465*7c478bd9Sstevel@tonic-gate break; 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate case 'e': /* enumerated */ 468*7c478bd9Sstevel@tonic-gate case 'i': /* int */ 469*7c478bd9Sstevel@tonic-gate l = va_arg( ap, ber_slen_t * ); 470*7c478bd9Sstevel@tonic-gate rc = ber_get_int( ber, l ); 471*7c478bd9Sstevel@tonic-gate break; 472*7c478bd9Sstevel@tonic-gate 473*7c478bd9Sstevel@tonic-gate case 'l': /* length of next item */ 474*7c478bd9Sstevel@tonic-gate l = va_arg( ap, ber_slen_t * ); 475*7c478bd9Sstevel@tonic-gate rc = ber_peek_tag( ber, (ber_len_t *)l ); 476*7c478bd9Sstevel@tonic-gate break; 477*7c478bd9Sstevel@tonic-gate 478*7c478bd9Sstevel@tonic-gate case 'n': /* null */ 479*7c478bd9Sstevel@tonic-gate rc = ber_get_null( ber ); 480*7c478bd9Sstevel@tonic-gate break; 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate case 's': /* octet string - in a buffer */ 483*7c478bd9Sstevel@tonic-gate s = va_arg( ap, char * ); 484*7c478bd9Sstevel@tonic-gate l = va_arg( ap, ber_slen_t * ); 485*7c478bd9Sstevel@tonic-gate rc = ber_get_stringb( ber, s, (ber_len_t *)l ); 486*7c478bd9Sstevel@tonic-gate break; 487*7c478bd9Sstevel@tonic-gate 488*7c478bd9Sstevel@tonic-gate case 'o': /* octet string in a supplied berval */ 489*7c478bd9Sstevel@tonic-gate bval = va_arg( ap, struct berval * ); 490*7c478bd9Sstevel@tonic-gate ber_peek_tag( ber, &bval->bv_len ); 491*7c478bd9Sstevel@tonic-gate rc = ber_get_stringa( ber, &bval->bv_val ); 492*7c478bd9Sstevel@tonic-gate break; 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate case 'O': /* octet string - allocate & include length */ 495*7c478bd9Sstevel@tonic-gate bvp = va_arg( ap, struct berval ** ); 496*7c478bd9Sstevel@tonic-gate rc = ber_get_stringal( ber, bvp ); 497*7c478bd9Sstevel@tonic-gate break; 498*7c478bd9Sstevel@tonic-gate 499*7c478bd9Sstevel@tonic-gate case 'B': /* bit string - allocate storage as needed */ 500*7c478bd9Sstevel@tonic-gate ss = va_arg( ap, char ** ); 501*7c478bd9Sstevel@tonic-gate l = va_arg( ap, ber_slen_t * ); /* for length, in bits */ 502*7c478bd9Sstevel@tonic-gate rc = ber_get_bitstringa( ber, ss, (ber_len_t *)l ); 503*7c478bd9Sstevel@tonic-gate break; 504*7c478bd9Sstevel@tonic-gate 505*7c478bd9Sstevel@tonic-gate case 't': /* tag of next item */ 506*7c478bd9Sstevel@tonic-gate t = va_arg( ap, ber_tag_t * ); 507*7c478bd9Sstevel@tonic-gate *t = rc = ber_peek_tag( ber, &len ); 508*7c478bd9Sstevel@tonic-gate break; 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate case 'T': /* skip tag of next item */ 511*7c478bd9Sstevel@tonic-gate t = va_arg( ap, ber_tag_t * ); 512*7c478bd9Sstevel@tonic-gate *t = rc = ber_skip_tag( ber, &len ); 513*7c478bd9Sstevel@tonic-gate break; 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate case 'v': /* sequence of strings */ 516*7c478bd9Sstevel@tonic-gate sss = va_arg( ap, char *** ); 517*7c478bd9Sstevel@tonic-gate *sss = NULL; 518*7c478bd9Sstevel@tonic-gate j = 0; 519*7c478bd9Sstevel@tonic-gate array_size = 0; 520*7c478bd9Sstevel@tonic-gate for ( tag = ber_first_element( ber, &len, &last ); 521*7c478bd9Sstevel@tonic-gate tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET 522*7c478bd9Sstevel@tonic-gate && rc != LBER_DEFAULT; 523*7c478bd9Sstevel@tonic-gate tag = ber_next_element( ber, &len, last ) ) { 524*7c478bd9Sstevel@tonic-gate if ( *sss == NULL ) { 525*7c478bd9Sstevel@tonic-gate /* Make room for at least 15 strings */ 526*7c478bd9Sstevel@tonic-gate *sss = (char **)NSLBERI_MALLOC(16 * sizeof(char *) ); 527*7c478bd9Sstevel@tonic-gate array_size = 16; 528*7c478bd9Sstevel@tonic-gate } else { 529*7c478bd9Sstevel@tonic-gate if ( (size_t)(j+2) > array_size) { 530*7c478bd9Sstevel@tonic-gate /* We'v overflowed our buffer */ 531*7c478bd9Sstevel@tonic-gate *sss = (char **)NSLBERI_REALLOC( *sss, (array_size * 2) * sizeof(char *) ); 532*7c478bd9Sstevel@tonic-gate array_size = array_size * 2; 533*7c478bd9Sstevel@tonic-gate } 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate rc = ber_get_stringa( ber, &((*sss)[j]) ); 536*7c478bd9Sstevel@tonic-gate j++; 537*7c478bd9Sstevel@tonic-gate } 538*7c478bd9Sstevel@tonic-gate if ( rc != LBER_DEFAULT && 539*7c478bd9Sstevel@tonic-gate tag != LBER_END_OF_SEQORSET ) { 540*7c478bd9Sstevel@tonic-gate rc = LBER_DEFAULT; 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate if ( j > 0 ) 543*7c478bd9Sstevel@tonic-gate (*sss)[j] = NULL; 544*7c478bd9Sstevel@tonic-gate break; 545*7c478bd9Sstevel@tonic-gate 546*7c478bd9Sstevel@tonic-gate case 'V': /* sequence of strings + lengths */ 547*7c478bd9Sstevel@tonic-gate bv = va_arg( ap, struct berval *** ); 548*7c478bd9Sstevel@tonic-gate *bv = NULL; 549*7c478bd9Sstevel@tonic-gate j = 0; 550*7c478bd9Sstevel@tonic-gate for ( tag = ber_first_element( ber, &len, &last ); 551*7c478bd9Sstevel@tonic-gate tag != LBER_DEFAULT && tag != LBER_END_OF_SEQORSET 552*7c478bd9Sstevel@tonic-gate && rc != LBER_DEFAULT; 553*7c478bd9Sstevel@tonic-gate tag = ber_next_element( ber, &len, last ) ) { 554*7c478bd9Sstevel@tonic-gate if ( *bv == NULL ) { 555*7c478bd9Sstevel@tonic-gate *bv = (struct berval **)NSLBERI_MALLOC( 556*7c478bd9Sstevel@tonic-gate 2 * sizeof(struct berval *) ); 557*7c478bd9Sstevel@tonic-gate } else { 558*7c478bd9Sstevel@tonic-gate *bv = (struct berval **)NSLBERI_REALLOC( 559*7c478bd9Sstevel@tonic-gate *bv, 560*7c478bd9Sstevel@tonic-gate (j + 2) * sizeof(struct berval *) ); 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate rc = ber_get_stringal( ber, &((*bv)[j]) ); 563*7c478bd9Sstevel@tonic-gate j++; 564*7c478bd9Sstevel@tonic-gate } 565*7c478bd9Sstevel@tonic-gate if ( rc != LBER_DEFAULT && 566*7c478bd9Sstevel@tonic-gate tag != LBER_END_OF_SEQORSET ) { 567*7c478bd9Sstevel@tonic-gate rc = LBER_DEFAULT; 568*7c478bd9Sstevel@tonic-gate } 569*7c478bd9Sstevel@tonic-gate if ( j > 0 ) 570*7c478bd9Sstevel@tonic-gate (*bv)[j] = NULL; 571*7c478bd9Sstevel@tonic-gate break; 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate case 'x': /* skip the next element - whatever it is */ 574*7c478bd9Sstevel@tonic-gate if ( (rc = ber_skip_tag( ber, &len )) == LBER_DEFAULT ) 575*7c478bd9Sstevel@tonic-gate break; 576*7c478bd9Sstevel@tonic-gate ber->ber_ptr += len; 577*7c478bd9Sstevel@tonic-gate break; 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate case '{': /* begin sequence */ 580*7c478bd9Sstevel@tonic-gate case '[': /* begin set */ 581*7c478bd9Sstevel@tonic-gate if ( *(p + 1) != 'v' && *(p + 1) != 'V' ) 582*7c478bd9Sstevel@tonic-gate rc = ber_skip_tag( ber, &len ); 583*7c478bd9Sstevel@tonic-gate break; 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate case '}': /* end sequence */ 586*7c478bd9Sstevel@tonic-gate case ']': /* end set */ 587*7c478bd9Sstevel@tonic-gate break; 588*7c478bd9Sstevel@tonic-gate 589*7c478bd9Sstevel@tonic-gate default: 590*7c478bd9Sstevel@tonic-gate { 591*7c478bd9Sstevel@tonic-gate char msg[80]; 592*7c478bd9Sstevel@tonic-gate sprintf( msg, "unknown fmt %c\n", *p ); 593*7c478bd9Sstevel@tonic-gate ber_err_print( msg ); 594*7c478bd9Sstevel@tonic-gate } 595*7c478bd9Sstevel@tonic-gate rc = LBER_DEFAULT; 596*7c478bd9Sstevel@tonic-gate break; 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate } 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate 601*7c478bd9Sstevel@tonic-gate va_end( ap ); 602*7c478bd9Sstevel@tonic-gate if (rc == LBER_DEFAULT) { 603*7c478bd9Sstevel@tonic-gate va_start( ap, fmt ); 604*7c478bd9Sstevel@tonic-gate for ( p--; fmt < p && *fmt; fmt++ ) { 605*7c478bd9Sstevel@tonic-gate switch ( *fmt ) { 606*7c478bd9Sstevel@tonic-gate case 'a': /* octet string - allocate storage as needed */ 607*7c478bd9Sstevel@tonic-gate ss = va_arg( ap, char ** ); 608*7c478bd9Sstevel@tonic-gate NSLBERI_FREE(*ss); 609*7c478bd9Sstevel@tonic-gate *ss = NULL; 610*7c478bd9Sstevel@tonic-gate break; 611*7c478bd9Sstevel@tonic-gate 612*7c478bd9Sstevel@tonic-gate case 'b': /* boolean */ 613*7c478bd9Sstevel@tonic-gate i = va_arg( ap, int * ); 614*7c478bd9Sstevel@tonic-gate break; 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate case 'e': /* enumerated */ 617*7c478bd9Sstevel@tonic-gate case 'i': /* int */ 618*7c478bd9Sstevel@tonic-gate l = va_arg( ap, ber_slen_t * ); 619*7c478bd9Sstevel@tonic-gate break; 620*7c478bd9Sstevel@tonic-gate 621*7c478bd9Sstevel@tonic-gate case 'l': /* length of next item */ 622*7c478bd9Sstevel@tonic-gate l = va_arg( ap, ber_slen_t * ); 623*7c478bd9Sstevel@tonic-gate break; 624*7c478bd9Sstevel@tonic-gate 625*7c478bd9Sstevel@tonic-gate case 'n': /* null */ 626*7c478bd9Sstevel@tonic-gate break; 627*7c478bd9Sstevel@tonic-gate 628*7c478bd9Sstevel@tonic-gate case 's': /* octet string - in a buffer */ 629*7c478bd9Sstevel@tonic-gate s = va_arg( ap, char * ); 630*7c478bd9Sstevel@tonic-gate l = va_arg( ap, ber_slen_t * ); 631*7c478bd9Sstevel@tonic-gate break; 632*7c478bd9Sstevel@tonic-gate 633*7c478bd9Sstevel@tonic-gate case 'o': /* octet string in a supplied berval */ 634*7c478bd9Sstevel@tonic-gate bval = va_arg( ap, struct berval * ); 635*7c478bd9Sstevel@tonic-gate if (bval->bv_val) NSLBERI_FREE(bval->bv_val); 636*7c478bd9Sstevel@tonic-gate memset(bval, 0, sizeof(struct berval)); 637*7c478bd9Sstevel@tonic-gate break; 638*7c478bd9Sstevel@tonic-gate 639*7c478bd9Sstevel@tonic-gate case 'O': /* octet string - allocate & include length */ 640*7c478bd9Sstevel@tonic-gate bvp = va_arg( ap, struct berval ** ); 641*7c478bd9Sstevel@tonic-gate ber_bvfree(*bvp); 642*7c478bd9Sstevel@tonic-gate bvp = NULL; 643*7c478bd9Sstevel@tonic-gate break; 644*7c478bd9Sstevel@tonic-gate 645*7c478bd9Sstevel@tonic-gate case 'B': /* bit string - allocate storage as needed */ 646*7c478bd9Sstevel@tonic-gate ss = va_arg( ap, char ** ); 647*7c478bd9Sstevel@tonic-gate l = va_arg( ap, ber_slen_t * ); /* for length, in bits */ 648*7c478bd9Sstevel@tonic-gate if (*ss) NSLBERI_FREE(*ss); 649*7c478bd9Sstevel@tonic-gate *ss = NULL; 650*7c478bd9Sstevel@tonic-gate break; 651*7c478bd9Sstevel@tonic-gate 652*7c478bd9Sstevel@tonic-gate case 't': /* tag of next item */ 653*7c478bd9Sstevel@tonic-gate t = va_arg( ap, ber_tag_t * ); 654*7c478bd9Sstevel@tonic-gate break; 655*7c478bd9Sstevel@tonic-gate case 'T': /* skip tag of next item */ 656*7c478bd9Sstevel@tonic-gate t = va_arg( ap, ber_tag_t * ); 657*7c478bd9Sstevel@tonic-gate break; 658*7c478bd9Sstevel@tonic-gate 659*7c478bd9Sstevel@tonic-gate case 'v': /* sequence of strings */ 660*7c478bd9Sstevel@tonic-gate sss = va_arg( ap, char *** ); 661*7c478bd9Sstevel@tonic-gate ber_svecfree(*sss); 662*7c478bd9Sstevel@tonic-gate *sss = NULL; 663*7c478bd9Sstevel@tonic-gate break; 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate case 'V': /* sequence of strings + lengths */ 666*7c478bd9Sstevel@tonic-gate bv = va_arg( ap, struct berval *** ); 667*7c478bd9Sstevel@tonic-gate ber_bvecfree(*bv); 668*7c478bd9Sstevel@tonic-gate *bv = NULL; 669*7c478bd9Sstevel@tonic-gate break; 670*7c478bd9Sstevel@tonic-gate 671*7c478bd9Sstevel@tonic-gate case 'x': /* skip the next element - whatever it is */ 672*7c478bd9Sstevel@tonic-gate break; 673*7c478bd9Sstevel@tonic-gate 674*7c478bd9Sstevel@tonic-gate case '{': /* begin sequence */ 675*7c478bd9Sstevel@tonic-gate case '[': /* begin set */ 676*7c478bd9Sstevel@tonic-gate break; 677*7c478bd9Sstevel@tonic-gate 678*7c478bd9Sstevel@tonic-gate case '}': /* end sequence */ 679*7c478bd9Sstevel@tonic-gate case ']': /* end set */ 680*7c478bd9Sstevel@tonic-gate break; 681*7c478bd9Sstevel@tonic-gate 682*7c478bd9Sstevel@tonic-gate default: 683*7c478bd9Sstevel@tonic-gate break; 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate } /* for */ 686*7c478bd9Sstevel@tonic-gate va_end( ap ); 687*7c478bd9Sstevel@tonic-gate } /* if */ 688*7c478bd9Sstevel@tonic-gate 689*7c478bd9Sstevel@tonic-gate 690*7c478bd9Sstevel@tonic-gate return( rc ); 691*7c478bd9Sstevel@tonic-gate } 692*7c478bd9Sstevel@tonic-gate 693*7c478bd9Sstevel@tonic-gate void 694*7c478bd9Sstevel@tonic-gate LDAP_CALL 695*7c478bd9Sstevel@tonic-gate ber_bvfree( struct berval *bv ) 696*7c478bd9Sstevel@tonic-gate { 697*7c478bd9Sstevel@tonic-gate if ( bv != NULL ) { 698*7c478bd9Sstevel@tonic-gate if ( bv->bv_val != NULL ) { 699*7c478bd9Sstevel@tonic-gate NSLBERI_FREE( bv->bv_val ); 700*7c478bd9Sstevel@tonic-gate } 701*7c478bd9Sstevel@tonic-gate NSLBERI_FREE( (char *) bv ); 702*7c478bd9Sstevel@tonic-gate } 703*7c478bd9Sstevel@tonic-gate } 704*7c478bd9Sstevel@tonic-gate 705*7c478bd9Sstevel@tonic-gate void 706*7c478bd9Sstevel@tonic-gate LDAP_CALL 707*7c478bd9Sstevel@tonic-gate ber_bvecfree( struct berval **bv ) 708*7c478bd9Sstevel@tonic-gate { 709*7c478bd9Sstevel@tonic-gate int i; 710*7c478bd9Sstevel@tonic-gate 711*7c478bd9Sstevel@tonic-gate if ( bv != NULL ) { 712*7c478bd9Sstevel@tonic-gate for ( i = 0; bv[i] != NULL; i++ ) { 713*7c478bd9Sstevel@tonic-gate ber_bvfree( bv[i] ); 714*7c478bd9Sstevel@tonic-gate } 715*7c478bd9Sstevel@tonic-gate NSLBERI_FREE( (char *) bv ); 716*7c478bd9Sstevel@tonic-gate } 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate 719*7c478bd9Sstevel@tonic-gate struct berval * 720*7c478bd9Sstevel@tonic-gate LDAP_CALL 721*7c478bd9Sstevel@tonic-gate ber_bvdup( const struct berval *bv ) 722*7c478bd9Sstevel@tonic-gate { 723*7c478bd9Sstevel@tonic-gate struct berval *new; 724*7c478bd9Sstevel@tonic-gate 725*7c478bd9Sstevel@tonic-gate if ( (new = (struct berval *)NSLBERI_MALLOC( sizeof(struct berval) )) 726*7c478bd9Sstevel@tonic-gate == NULL ) { 727*7c478bd9Sstevel@tonic-gate return( NULL ); 728*7c478bd9Sstevel@tonic-gate } 729*7c478bd9Sstevel@tonic-gate if ( bv->bv_val == NULL ) { 730*7c478bd9Sstevel@tonic-gate new->bv_val = NULL; 731*7c478bd9Sstevel@tonic-gate new->bv_len = 0; 732*7c478bd9Sstevel@tonic-gate } else { 733*7c478bd9Sstevel@tonic-gate if ( (new->bv_val = (char *)NSLBERI_MALLOC( bv->bv_len + 1 )) 734*7c478bd9Sstevel@tonic-gate == NULL ) { 735*7c478bd9Sstevel@tonic-gate return( NULL ); 736*7c478bd9Sstevel@tonic-gate } 737*7c478bd9Sstevel@tonic-gate SAFEMEMCPY( new->bv_val, bv->bv_val, (size_t) bv->bv_len ); 738*7c478bd9Sstevel@tonic-gate new->bv_val[bv->bv_len] = '\0'; 739*7c478bd9Sstevel@tonic-gate new->bv_len = bv->bv_len; 740*7c478bd9Sstevel@tonic-gate } 741*7c478bd9Sstevel@tonic-gate 742*7c478bd9Sstevel@tonic-gate return( new ); 743*7c478bd9Sstevel@tonic-gate } 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate void 746*7c478bd9Sstevel@tonic-gate LDAP_CALL 747*7c478bd9Sstevel@tonic-gate ber_svecfree( char **vals ) 748*7c478bd9Sstevel@tonic-gate { 749*7c478bd9Sstevel@tonic-gate int i; 750*7c478bd9Sstevel@tonic-gate 751*7c478bd9Sstevel@tonic-gate if ( vals == NULL ) 752*7c478bd9Sstevel@tonic-gate return; 753*7c478bd9Sstevel@tonic-gate for ( i = 0; vals[i] != NULL; i++ ) 754*7c478bd9Sstevel@tonic-gate NSLBERI_FREE( vals[i] ); 755*7c478bd9Sstevel@tonic-gate NSLBERI_FREE( (char *) vals ); 756*7c478bd9Sstevel@tonic-gate } 757*7c478bd9Sstevel@tonic-gate 758*7c478bd9Sstevel@tonic-gate #ifdef STR_TRANSLATION 759*7c478bd9Sstevel@tonic-gate void 760*7c478bd9Sstevel@tonic-gate LDAP_CALL 761*7c478bd9Sstevel@tonic-gate ber_set_string_translators( 762*7c478bd9Sstevel@tonic-gate BerElement *ber, 763*7c478bd9Sstevel@tonic-gate BERTranslateProc encode_proc, 764*7c478bd9Sstevel@tonic-gate BERTranslateProc decode_proc 765*7c478bd9Sstevel@tonic-gate ) 766*7c478bd9Sstevel@tonic-gate { 767*7c478bd9Sstevel@tonic-gate ber->ber_encode_translate_proc = encode_proc; 768*7c478bd9Sstevel@tonic-gate ber->ber_decode_translate_proc = decode_proc; 769*7c478bd9Sstevel@tonic-gate } 770*7c478bd9Sstevel@tonic-gate #endif /* STR_TRANSLATION */ 771