Home | History | Annotate | Line # | Download | only in libldap
      1 /*	$NetBSD: getvalues.c,v 1.4 2025/09/05 21:16:21 christos Exp $	*/
      2 
      3 /* $OpenLDAP$ */
      4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      5  *
      6  * Copyright 1998-2024 The OpenLDAP Foundation.
      7  * All rights reserved.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted only as authorized by the OpenLDAP
     11  * Public License.
     12  *
     13  * A copy of this license is available in the file LICENSE in the
     14  * top-level directory of the distribution or, alternatively, at
     15  * <http://www.OpenLDAP.org/license.html>.
     16  */
     17 /* Portions Copyright (c) 1990 Regents of the University of Michigan.
     18  * All rights reserved.
     19  */
     20 
     21 #include <sys/cdefs.h>
     22 __RCSID("$NetBSD: getvalues.c,v 1.4 2025/09/05 21:16:21 christos Exp $");
     23 
     24 #include "portable.h"
     25 
     26 #include <stdio.h>
     27 
     28 #include <ac/stdlib.h>
     29 
     30 #include <ac/ctype.h>
     31 #include <ac/socket.h>
     32 #include <ac/string.h>
     33 #include <ac/time.h>
     34 
     35 #include "ldap-int.h"
     36 
     37 char **
     38 ldap_get_values( LDAP *ld, LDAPMessage *entry, LDAP_CONST char *target )
     39 {
     40 	BerElement	ber;
     41 	char		*attr;
     42 	int		found = 0;
     43 	char		**vals;
     44 
     45 	assert( ld != NULL );
     46 	assert( LDAP_VALID( ld ) );
     47 	assert( entry != NULL );
     48 	assert( target != NULL );
     49 
     50 	Debug0( LDAP_DEBUG_TRACE, "ldap_get_values\n" );
     51 
     52 	ber = *entry->lm_ber;
     53 
     54 	/* skip sequence, dn, sequence of, and snag the first attr */
     55 	if ( ber_scanf( &ber, "{x{{a" /*}}}*/, &attr ) == LBER_ERROR ) {
     56 		ld->ld_errno = LDAP_DECODING_ERROR;
     57 		return( NULL );
     58 	}
     59 
     60 	if ( strcasecmp( target, attr ) == 0 )
     61 		found = 1;
     62 
     63 	/* break out on success, return out on error */
     64 	while ( ! found ) {
     65 		LDAP_FREE(attr);
     66 		attr = NULL;
     67 
     68 		if ( ber_scanf( &ber, /*{*/ "x}{a" /*}*/, &attr ) == LBER_ERROR ) {
     69 			ld->ld_errno = LDAP_DECODING_ERROR;
     70 			return( NULL );
     71 		}
     72 
     73 		if ( strcasecmp( target, attr ) == 0 )
     74 			break;
     75 
     76 	}
     77 
     78 	LDAP_FREE(attr);
     79 	attr = NULL;
     80 
     81 	/*
     82 	 * if we get this far, we've found the attribute and are sitting
     83 	 * just before the set of values.
     84 	 */
     85 
     86 	if ( ber_scanf( &ber, "[v]", &vals ) == LBER_ERROR ) {
     87 		ld->ld_errno = LDAP_DECODING_ERROR;
     88 		return( NULL );
     89 	}
     90 
     91 	return( vals );
     92 }
     93 
     94 struct berval **
     95 ldap_get_values_len( LDAP *ld, LDAPMessage *entry, LDAP_CONST char *target )
     96 {
     97 	BerElement	ber;
     98 	char		*attr;
     99 	int		found = 0;
    100 	struct berval	**vals;
    101 
    102 	assert( ld != NULL );
    103 	assert( LDAP_VALID( ld ) );
    104 	assert( entry != NULL );
    105 	assert( target != NULL );
    106 
    107 	Debug0( LDAP_DEBUG_TRACE, "ldap_get_values_len\n" );
    108 
    109 	ber = *entry->lm_ber;
    110 
    111 	/* skip sequence, dn, sequence of, and snag the first attr */
    112 	if ( ber_scanf( &ber, "{x{{a" /* }}} */, &attr ) == LBER_ERROR ) {
    113 		ld->ld_errno = LDAP_DECODING_ERROR;
    114 		return( NULL );
    115 	}
    116 
    117 	if ( strcasecmp( target, attr ) == 0 )
    118 		found = 1;
    119 
    120 	/* break out on success, return out on error */
    121 	while ( ! found ) {
    122 		LDAP_FREE( attr );
    123 		attr = NULL;
    124 
    125 		if ( ber_scanf( &ber, /*{*/ "x}{a" /*}*/, &attr ) == LBER_ERROR ) {
    126 			ld->ld_errno = LDAP_DECODING_ERROR;
    127 			return( NULL );
    128 		}
    129 
    130 		if ( strcasecmp( target, attr ) == 0 )
    131 			break;
    132 	}
    133 
    134 	LDAP_FREE( attr );
    135 	attr = NULL;
    136 
    137 	/*
    138 	 * if we get this far, we've found the attribute and are sitting
    139 	 * just before the set of values.
    140 	 */
    141 
    142 	if ( ber_scanf( &ber, "[V]", &vals ) == LBER_ERROR ) {
    143 		ld->ld_errno = LDAP_DECODING_ERROR;
    144 		return( NULL );
    145 	}
    146 
    147 	return( vals );
    148 }
    149 
    150 int
    151 ldap_count_values( char **vals )
    152 {
    153 	int	i;
    154 
    155 	if ( vals == NULL )
    156 		return( 0 );
    157 
    158 	for ( i = 0; vals[i] != NULL; i++ )
    159 		;	/* NULL */
    160 
    161 	return( i );
    162 }
    163 
    164 int
    165 ldap_count_values_len( struct berval **vals )
    166 {
    167 	return( ldap_count_values( (char **) vals ) );
    168 }
    169 
    170 void
    171 ldap_value_free( char **vals )
    172 {
    173 	LDAP_VFREE( vals );
    174 }
    175 
    176 void
    177 ldap_value_free_len( struct berval **vals )
    178 {
    179 	ber_bvecfree( vals );
    180 }
    181 
    182 char **
    183 ldap_value_dup( char *const *vals )
    184 {
    185 	char **new;
    186 	int i;
    187 
    188 	if( vals == NULL ) {
    189 		return NULL;
    190 	}
    191 
    192 	for( i=0; vals[i]; i++ ) {
    193 		;   /* Count the number of values */
    194 	}
    195 
    196 	if( i == 0 ) {
    197 		return NULL;
    198 	}
    199 
    200 	new = LDAP_MALLOC( (i+1)*sizeof(char *) );  /* Alloc array of pointers */
    201 	if( new == NULL ) {
    202 		return NULL;
    203 	}
    204 
    205 	for( i=0; vals[i]; i++ ) {
    206 		new[i] = LDAP_STRDUP( vals[i] );   /* Dup each value */
    207 		if( new[i] == NULL ) {
    208 			LDAP_VFREE( new );
    209 			return NULL;
    210 		}
    211 	}
    212 	new[i] = NULL;
    213 
    214 	return new;
    215 }
    216 
    217