wldap32: Fix some potential infinite loops because of an unsigned loop counter.
[wine] / dlls / wldap32 / value.c
1 /*
2  * WLDAP32 - LDAP support for Wine
3  *
4  * Copyright 2005 Hans Leidekker
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 #include "config.h"
22
23 #include "wine/port.h"
24 #include "wine/debug.h"
25
26 #include <stdarg.h>
27
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winnls.h"
31
32 #ifdef HAVE_LDAP_H
33 #include <ldap.h>
34 #else
35 #define LDAP_SUCCESS        0x00
36 #define LDAP_NOT_SUPPORTED  0x5c
37 #endif
38
39 #include "winldap_private.h"
40 #include "wldap32.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(wldap32);
43
44 /***********************************************************************
45  *      ldap_count_values_len     (WLDAP32.@)
46  *
47  * Count the number of values in an array of berval structures.
48  *
49  * PARAMS
50  *  vals  [I] Pointer to an array of berval structures.
51  *
52  * RETURNS
53  *  Success: The number of values counted.
54  *  Failure: 0
55  *
56  * NOTES
57  *  Call ldap_count_values_len with the result of a call to
58  *  ldap_get_values_len.
59  */
60 ULONG CDECL WLDAP32_ldap_count_values_len( struct WLDAP32_berval **vals )
61 {
62     ULONG ret = LDAP_NOT_SUPPORTED;
63 #ifdef HAVE_LDAP
64
65     TRACE( "(%p)\n", vals );
66     ret = ldap_count_values_len( (struct berval **)vals );
67
68 #endif
69     return ret;
70 }
71
72 /***********************************************************************
73  *      ldap_count_valuesA     (WLDAP32.@)
74  *
75  * See ldap_count_valuesW.
76  */
77 ULONG CDECL ldap_count_valuesA( PCHAR *vals )
78 {
79     ULONG ret = LDAP_NOT_SUPPORTED;
80 #ifdef HAVE_LDAP
81     WCHAR **valsW = NULL;
82
83     TRACE( "(%p)\n", vals );
84
85     if (!vals) return 0;
86
87     valsW = strarrayAtoW( vals );
88     if (!valsW) return WLDAP32_LDAP_NO_MEMORY;
89
90     ret = ldap_count_valuesW( valsW );
91     strarrayfreeW( valsW );
92
93 #endif
94     return ret;
95 }
96
97 /***********************************************************************
98  *      ldap_count_valuesW     (WLDAP32.@)
99  *
100  * Count the number of values in a string array.
101  *
102  * PARAMS
103  *  vals  [I] Pointer to an array of strings.
104  *
105  * RETURNS
106  *  Success: The number of values counted.
107  *  Failure: 0
108  *
109  * NOTES
110  *  Call ldap_count_valuesW with the result of a call to
111  *  ldap_get_valuesW.
112  */
113 ULONG CDECL ldap_count_valuesW( PWCHAR *vals )
114 {
115     ULONG ret = LDAP_NOT_SUPPORTED;
116 #ifdef HAVE_LDAP
117     WCHAR **p = vals;
118
119     TRACE( "(%p)\n", vals );
120
121     if (!vals) return 0;
122
123     ret = 0;
124     while (*p++) ret++;
125
126 #endif
127     return ret;
128 }
129
130 /***********************************************************************
131  *      ldap_get_valuesA     (WLDAP32.@)
132  *
133  * See ldap_get_valuesW.
134  */
135 PCHAR * CDECL ldap_get_valuesA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry, PCHAR attr )
136 {
137     PCHAR *ret = NULL;
138 #ifdef HAVE_LDAP
139     WCHAR *attrW = NULL, **retW;
140
141     TRACE( "(%p, %p, %s)\n", ld, entry, debugstr_a(attr) );
142
143     if (!ld || !entry || !attr) return NULL;
144
145     attrW = strAtoW( attr );
146     if (!attrW) return NULL;
147
148     retW = ldap_get_valuesW( ld, entry, attrW );
149
150     ret = strarrayWtoA( retW );
151     ldap_value_freeW( retW );
152     strfreeW( attrW );
153
154 #endif
155     return ret;
156 }
157
158 #ifdef HAVE_LDAP
159 static char *bv2str( struct berval *bv )
160 {
161     char *str = NULL;
162     unsigned int len = bv->bv_len;
163
164     str = HeapAlloc( GetProcessHeap(), 0, len + 1 );
165     if (str)
166     {
167         memcpy( str, bv->bv_val, len );
168         str[len] = '\0';
169     }
170     return str;
171 }
172
173 static char **bv2str_array( struct berval **bv )
174 {
175     unsigned int len = 0, i = 0;
176     struct berval **p = bv;
177     char **str;
178
179     while (*p)
180     {
181         len++;
182         p++;
183     }
184     str = HeapAlloc( GetProcessHeap(), 0, (len + 1) * sizeof(char *) );
185     if (!str) return NULL;
186
187     p = bv;
188     while (*p)
189     {
190         str[i] = bv2str( *p );
191         if (!str[i])
192         {
193             while (i > 0) HeapFree( GetProcessHeap(), 0, str[--i] );
194             HeapFree( GetProcessHeap(), 0, str );
195             return NULL;
196         } 
197         i++;
198         p++; 
199     }
200     str[i] = NULL;
201     return str;
202 }
203 #endif
204
205 /***********************************************************************
206  *      ldap_get_valuesW     (WLDAP32.@)
207  *
208  * Retrieve string values for a given attribute.
209  *
210  * PARAMS
211  *  ld     [I] Pointer to an LDAP context.
212  *  entry  [I] Entry to retrieve values from.
213  *  attr   [I] Attribute to retrieve values for.
214  *
215  * RETURNS
216  *  Success: Pointer to a character array holding the values.
217  *  Failure: NULL
218  *
219  * NOTES
220  *  Call ldap_get_valuesW with the result of a call to
221  *  ldap_first_entry or ldap_next_entry. Free the returned
222  *  array with a call to ldap_value_freeW.
223  */
224 PWCHAR * CDECL ldap_get_valuesW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *entry, PWCHAR attr )
225 {
226     PWCHAR *ret = NULL;
227 #ifdef HAVE_LDAP
228     char *attrU = NULL, **retU;
229     struct berval **bv;
230
231     TRACE( "(%p, %p, %s)\n", ld, entry, debugstr_w(attr) );
232
233     if (!ld || !entry || !attr) return NULL;
234
235     attrU = strWtoU( attr );
236     if (!attrU) return NULL;
237
238     bv = ldap_get_values_len( ld, entry, attrU );
239
240     retU = bv2str_array( bv );
241     ret = strarrayUtoW( retU );
242
243     ldap_value_free_len( bv );
244     strarrayfreeU( retU );
245     strfreeU( attrU );
246
247 #endif
248     return ret;
249 }
250
251 /***********************************************************************
252  *      ldap_get_values_lenA     (WLDAP32.@)
253  *
254  * See ldap_get_values_lenW.
255  */
256 struct WLDAP32_berval ** CDECL ldap_get_values_lenA( WLDAP32_LDAP *ld,
257     WLDAP32_LDAPMessage *message, PCHAR attr )
258 {
259 #ifdef HAVE_LDAP
260     WCHAR *attrW = NULL;
261     struct WLDAP32_berval **ret;
262
263     TRACE( "(%p, %p, %s)\n", ld, message, debugstr_a(attr) );
264
265     if (!ld || !message || !attr) return NULL;
266
267     attrW = strAtoW( attr );
268     if (!attrW) return NULL;
269
270     ret = ldap_get_values_lenW( ld, message, attrW );
271
272     strfreeW( attrW );
273     return ret;
274
275 #endif
276     return NULL;
277 }
278
279 /***********************************************************************
280  *      ldap_get_values_lenW     (WLDAP32.@)
281  *
282  * Retrieve binary values for a given attribute.
283  *
284  * PARAMS
285  *  ld      [I] Pointer to an LDAP context.
286  *  message [I] Entry to retrieve values from.
287  *  attr    [I] Attribute to retrieve values for.
288  *
289  * RETURNS
290  *  Success: Pointer to a berval array holding the values.
291  *  Failure: NULL
292  *
293  * NOTES
294  *  Call ldap_get_values_lenW with the result of a call to
295  *  ldap_first_entry or ldap_next_entry. Free the returned
296  *  array with a call to ldap_value_free_len.
297  */
298 struct WLDAP32_berval ** CDECL ldap_get_values_lenW( WLDAP32_LDAP *ld,
299     WLDAP32_LDAPMessage *message, PWCHAR attr )
300 {
301 #ifdef HAVE_LDAP
302     char *attrU = NULL;
303     struct berval **ret;
304
305     TRACE( "(%p, %p, %s)\n", ld, message, debugstr_w(attr) );
306
307     if (!ld || !message || !attr) return NULL;
308
309     attrU = strWtoU( attr );
310     if (!attrU) return NULL;
311
312     ret = ldap_get_values_len( ld, message, attrU );
313
314     strfreeU( attrU );
315     return (struct WLDAP32_berval **)ret;
316
317 #endif
318     return NULL;
319 }
320
321 /***********************************************************************
322  *      ldap_value_free_len     (WLDAP32.@)
323  *
324  * Free an array of berval structures.
325  *
326  * PARAMS
327  *  vals  [I] Array of berval structures.
328  *
329  * RETURNS
330  *  Success: LDAP_SUCCESS
331  *  Failure: An LDAP error code.
332  */
333 ULONG CDECL WLDAP32_ldap_value_free_len( struct WLDAP32_berval **vals )
334 {
335 #ifdef HAVE_LDAP
336
337     TRACE( "(%p)\n", vals );
338     ldap_value_free_len( (struct berval **)vals );
339
340 #endif
341     return LDAP_SUCCESS;
342 }
343
344 /***********************************************************************
345  *      ldap_value_freeA     (WLDAP32.@)
346  *
347  * See ldap_value_freeW.
348  */
349 ULONG CDECL ldap_value_freeA( PCHAR *vals )
350 {
351     TRACE( "(%p)\n", vals );
352
353     strarrayfreeA( vals );
354     return LDAP_SUCCESS;
355 }
356
357 /***********************************************************************
358  *      ldap_value_freeW     (WLDAP32.@)
359  *
360  * Free an array of string values.
361  *
362  * PARAMS
363  *  vals  [I] Array of string values.
364  *
365  * RETURNS
366  *  Success: LDAP_SUCCESS
367  *  Failure: An LDAP error code.
368  */
369 ULONG CDECL ldap_value_freeW( PWCHAR *vals )
370 {
371     TRACE( "(%p)\n", vals );
372
373     strarrayfreeW( vals );
374     return LDAP_SUCCESS;
375 }