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