xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/getvalues.c (revision 549b59ed3ccf0d36d3097190a0db27b770f3a839)
1 /*	$NetBSD: getvalues.c,v 1.3 2021/08/14 16:14:56 christos Exp $	*/
2 
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5  *
6  * Copyright 1998-2021 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.3 2021/08/14 16:14:56 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 **
ldap_get_values(LDAP * ld,LDAPMessage * entry,LDAP_CONST char * target)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 **
ldap_get_values_len(LDAP * ld,LDAPMessage * entry,LDAP_CONST char * target)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
ldap_count_values(char ** vals)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
ldap_count_values_len(struct berval ** vals)165 ldap_count_values_len( struct berval **vals )
166 {
167 	return( ldap_count_values( (char **) vals ) );
168 }
169 
170 void
ldap_value_free(char ** vals)171 ldap_value_free( char **vals )
172 {
173 	LDAP_VFREE( vals );
174 }
175 
176 void
ldap_value_free_len(struct berval ** vals)177 ldap_value_free_len( struct berval **vals )
178 {
179 	ber_bvecfree( vals );
180 }
181 
182 char **
ldap_value_dup(char * const * vals)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