10Sstevel@tonic-gate /*
20Sstevel@tonic-gate *
3*3857Sstevel * Portions Copyright 1998 Sun Microsystems, Inc. All rights reserved.
4*3857Sstevel * Use is subject to license terms.
50Sstevel@tonic-gate *
60Sstevel@tonic-gate */
70Sstevel@tonic-gate
80Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
90Sstevel@tonic-gate
100Sstevel@tonic-gate /*
110Sstevel@tonic-gate * Copyright (c) 1990 Regents of the University of Michigan.
120Sstevel@tonic-gate * All rights reserved.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * getvalues.c
150Sstevel@tonic-gate */
160Sstevel@tonic-gate
170Sstevel@tonic-gate #ifndef lint
180Sstevel@tonic-gate static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n";
190Sstevel@tonic-gate #endif
200Sstevel@tonic-gate
210Sstevel@tonic-gate #include <stdio.h>
220Sstevel@tonic-gate #include <ctype.h>
230Sstevel@tonic-gate #include <string.h>
240Sstevel@tonic-gate #include <stdlib.h> /* free() for Solaris */
250Sstevel@tonic-gate #ifdef MACOS
260Sstevel@tonic-gate #include <stdlib.h>
270Sstevel@tonic-gate #include "macos.h"
280Sstevel@tonic-gate #else /* MACOS */
290Sstevel@tonic-gate #if defined( DOS ) || defined( _WIN32 )
300Sstevel@tonic-gate #include <malloc.h>
310Sstevel@tonic-gate #include "msdos.h"
320Sstevel@tonic-gate #else /* DOS */
330Sstevel@tonic-gate #include <sys/types.h>
340Sstevel@tonic-gate #include <sys/socket.h>
350Sstevel@tonic-gate #endif /* DOS */
360Sstevel@tonic-gate #endif /* MACOS */
370Sstevel@tonic-gate
380Sstevel@tonic-gate #include "lber.h"
390Sstevel@tonic-gate #include "ldap.h"
400Sstevel@tonic-gate #include "ldap-private.h"
410Sstevel@tonic-gate #include "ldap-int.h"
420Sstevel@tonic-gate
430Sstevel@tonic-gate char **
ldap_get_values(LDAP * ld,LDAPMessage * entry,char * target)440Sstevel@tonic-gate ldap_get_values( LDAP *ld, LDAPMessage *entry, char *target )
450Sstevel@tonic-gate {
460Sstevel@tonic-gate BerElement ber;
470Sstevel@tonic-gate char attr[LDAP_MAX_ATTR_LEN];
480Sstevel@tonic-gate int found = 0;
490Sstevel@tonic-gate int len;
500Sstevel@tonic-gate char **vals;
510Sstevel@tonic-gate
520Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 184, "ldap_get_values\n"), 0, 0, 0 );
530Sstevel@tonic-gate
540Sstevel@tonic-gate ber = *entry->lm_ber;
550Sstevel@tonic-gate
560Sstevel@tonic-gate /* skip sequence, dn, sequence of, and snag the first attr */
570Sstevel@tonic-gate len = sizeof(attr);
580Sstevel@tonic-gate if ( ber_scanf( &ber, "{x{{s", attr, &len ) == LBER_ERROR ) {
590Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR;
600Sstevel@tonic-gate return( NULL );
610Sstevel@tonic-gate }
620Sstevel@tonic-gate
630Sstevel@tonic-gate if ( strcasecmp( target, attr ) == 0 )
640Sstevel@tonic-gate found = 1;
650Sstevel@tonic-gate
660Sstevel@tonic-gate /* break out on success, return out on error */
670Sstevel@tonic-gate while ( ! found ) {
680Sstevel@tonic-gate len = sizeof(attr);
690Sstevel@tonic-gate if ( ber_scanf( &ber, "x}{s", attr, &len ) == LBER_ERROR ) {
700Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR;
710Sstevel@tonic-gate return( NULL );
720Sstevel@tonic-gate }
730Sstevel@tonic-gate
740Sstevel@tonic-gate if ( strcasecmp( target, attr ) == 0 )
750Sstevel@tonic-gate break;
760Sstevel@tonic-gate }
770Sstevel@tonic-gate
780Sstevel@tonic-gate /*
790Sstevel@tonic-gate * if we get this far, we've found the attribute and are sitting
800Sstevel@tonic-gate * just before the set of values.
810Sstevel@tonic-gate */
820Sstevel@tonic-gate
830Sstevel@tonic-gate if ( ber_scanf( &ber, "[v]", &vals ) == LBER_ERROR ) {
840Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR;
850Sstevel@tonic-gate return( NULL );
860Sstevel@tonic-gate }
870Sstevel@tonic-gate
880Sstevel@tonic-gate return( vals );
890Sstevel@tonic-gate }
900Sstevel@tonic-gate
910Sstevel@tonic-gate struct berval **
ldap_get_values_len(LDAP * ld,LDAPMessage * entry,char * target)920Sstevel@tonic-gate ldap_get_values_len( LDAP *ld, LDAPMessage *entry, char *target )
930Sstevel@tonic-gate {
940Sstevel@tonic-gate BerElement ber;
950Sstevel@tonic-gate char attr[LDAP_MAX_ATTR_LEN];
960Sstevel@tonic-gate int found = 0;
970Sstevel@tonic-gate int len;
980Sstevel@tonic-gate struct berval **vals;
990Sstevel@tonic-gate
1000Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 185, "ldap_get_values_len\n"), 0, 0, 0 );
1010Sstevel@tonic-gate
1020Sstevel@tonic-gate ber = *entry->lm_ber;
1030Sstevel@tonic-gate
1040Sstevel@tonic-gate /* skip sequence, dn, sequence of, and snag the first attr */
1050Sstevel@tonic-gate len = sizeof(attr);
1060Sstevel@tonic-gate if ( ber_scanf( &ber, "{x{{s", attr, &len ) == LBER_ERROR ) {
1070Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR;
1080Sstevel@tonic-gate return( NULL );
1090Sstevel@tonic-gate }
1100Sstevel@tonic-gate
1110Sstevel@tonic-gate if ( strcasecmp( target, attr ) == 0 )
1120Sstevel@tonic-gate found = 1;
1130Sstevel@tonic-gate
1140Sstevel@tonic-gate /* break out on success, return out on error */
1150Sstevel@tonic-gate while ( ! found ) {
1160Sstevel@tonic-gate len = sizeof(attr);
1170Sstevel@tonic-gate if ( ber_scanf( &ber, "x}{s", attr, &len ) == LBER_ERROR ) {
1180Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR;
1190Sstevel@tonic-gate return( NULL );
1200Sstevel@tonic-gate }
1210Sstevel@tonic-gate
1220Sstevel@tonic-gate if ( strcasecmp( target, attr ) == 0 )
1230Sstevel@tonic-gate break;
1240Sstevel@tonic-gate }
1250Sstevel@tonic-gate
1260Sstevel@tonic-gate /*
1270Sstevel@tonic-gate * if we get this far, we've found the attribute and are sitting
1280Sstevel@tonic-gate * just before the set of values.
1290Sstevel@tonic-gate */
1300Sstevel@tonic-gate
1310Sstevel@tonic-gate if ( ber_scanf( &ber, "[V]", &vals ) == LBER_ERROR ) {
1320Sstevel@tonic-gate ld->ld_errno = LDAP_DECODING_ERROR;
1330Sstevel@tonic-gate return( NULL );
1340Sstevel@tonic-gate }
1350Sstevel@tonic-gate
1360Sstevel@tonic-gate return( vals );
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate
1390Sstevel@tonic-gate int
ldap_count_values(char ** vals)1400Sstevel@tonic-gate ldap_count_values( char **vals )
1410Sstevel@tonic-gate {
1420Sstevel@tonic-gate int i;
1430Sstevel@tonic-gate
1440Sstevel@tonic-gate if ( vals == NULL )
1450Sstevel@tonic-gate return( 0 );
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate for ( i = 0; vals[i] != NULL; i++ )
1480Sstevel@tonic-gate ; /* NULL */
1490Sstevel@tonic-gate
1500Sstevel@tonic-gate return( i );
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate int
ldap_count_values_len(struct berval ** vals)1540Sstevel@tonic-gate ldap_count_values_len( struct berval **vals )
1550Sstevel@tonic-gate {
1560Sstevel@tonic-gate return( ldap_count_values( (char **) vals ) );
1570Sstevel@tonic-gate }
1580Sstevel@tonic-gate
1590Sstevel@tonic-gate void
ldap_value_free(char ** vals)1600Sstevel@tonic-gate ldap_value_free( char **vals )
1610Sstevel@tonic-gate {
1620Sstevel@tonic-gate int i;
1630Sstevel@tonic-gate
1640Sstevel@tonic-gate if ( vals == NULL )
1650Sstevel@tonic-gate return;
1660Sstevel@tonic-gate for ( i = 0; vals[i] != NULL; i++ )
1670Sstevel@tonic-gate free( vals[i] );
1680Sstevel@tonic-gate free( (char *) vals );
1690Sstevel@tonic-gate }
1700Sstevel@tonic-gate
1710Sstevel@tonic-gate void
ldap_value_free_len(struct berval ** vals)1720Sstevel@tonic-gate ldap_value_free_len( struct berval **vals )
1730Sstevel@tonic-gate {
1740Sstevel@tonic-gate int i;
1750Sstevel@tonic-gate
1760Sstevel@tonic-gate if ( vals == NULL )
1770Sstevel@tonic-gate return;
1780Sstevel@tonic-gate for ( i = 0; vals[i] != NULL; i++ ) {
1790Sstevel@tonic-gate free( vals[i]->bv_val );
1800Sstevel@tonic-gate free( vals[i] );
1810Sstevel@tonic-gate }
1820Sstevel@tonic-gate free( (char *) vals );
1830Sstevel@tonic-gate }
184