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 <stdarg.h> 24 #include "windef.h" 25 #include "winbase.h" 26 #include "winldap.h" 27 #include "wine/debug.h" 28 29 WINE_DEFAULT_DEBUG_CHANNEL(wldap32); 30 31 #ifndef LBER_ERROR 32 # define LBER_ERROR (~0U) 33 #endif 34 35 /*********************************************************************** 36 * ber_alloc_t (WLDAP32.@) 37 * 38 * Allocate a berelement structure. 39 * 40 * PARAMS 41 * options [I] Must be LBER_USE_DER. 42 * 43 * RETURNS 44 * Success: Pointer to an allocated berelement structure. 45 * Failure: NULL 46 * 47 * NOTES 48 * Free the berelement structure with ber_free. 49 */ 50 BerElement * CDECL WLDAP32_ber_alloc_t( INT options ) 51 { 52 #ifdef HAVE_LDAP 53 return ber_alloc_t( options ); 54 #else 55 return NULL; 56 #endif 57 } 58 59 60 /*********************************************************************** 61 * ber_bvdup (WLDAP32.@) 62 * 63 * Copy a berval structure. 64 * 65 * PARAMS 66 * berval [I] Pointer to the berval structure to be copied. 67 * 68 * RETURNS 69 * Success: Pointer to a copy of the berval structure. 70 * Failure: NULL 71 * 72 * NOTES 73 * Free the copy with ber_bvfree. 74 */ 75 BERVAL * CDECL WLDAP32_ber_bvdup( BERVAL *berval ) 76 { 77 #ifdef HAVE_LDAP 78 return ber_bvdup( berval ); 79 #else 80 return NULL; 81 #endif 82 } 83 84 85 /*********************************************************************** 86 * ber_bvecfree (WLDAP32.@) 87 * 88 * Free an array of berval structures. 89 * 90 * PARAMS 91 * berval [I] Pointer to an array of berval structures. 92 * 93 * RETURNS 94 * Nothing. 95 * 96 * NOTES 97 * Use this function only to free an array of berval structures 98 * returned by a call to ber_scanf with a 'V' in the format string. 99 */ 100 void CDECL WLDAP32_ber_bvecfree( PBERVAL *berval ) 101 { 102 #ifdef HAVE_LDAP 103 ber_bvecfree( berval ); 104 #endif 105 } 106 107 108 /*********************************************************************** 109 * ber_bvfree (WLDAP32.@) 110 * 111 * Free a berval structure. 112 * 113 * PARAMS 114 * berval [I] Pointer to a berval structure. 115 * 116 * RETURNS 117 * Nothing. 118 * 119 * NOTES 120 * Use this function only to free berval structures allocated by 121 * an LDAP API. 122 */ 123 void CDECL WLDAP32_ber_bvfree( BERVAL *berval ) 124 { 125 #ifdef HAVE_LDAP 126 ber_bvfree( berval ); 127 #endif 128 } 129 130 131 /*********************************************************************** 132 * ber_first_element (WLDAP32.@) 133 * 134 * Return the tag of the first element in a set or sequence. 135 * 136 * PARAMS 137 * berelement [I] Pointer to a berelement structure. 138 * len [O] Receives the length of the first element. 139 * opaque [O] Receives a pointer to a cookie. 140 * 141 * RETURNS 142 * Success: Tag of the first element. 143 * Failure: LBER_DEFAULT (no more data). 144 * 145 * NOTES 146 * len and cookie should be passed to ber_next_element. 147 */ 148 ULONG CDECL WLDAP32_ber_first_element( BerElement *berelement, ULONG *len, CHAR **opaque ) 149 { 150 #ifdef HAVE_LDAP 151 return ber_first_element( berelement, len, opaque ); 152 #else 153 return LBER_ERROR; 154 #endif 155 } 156 157 158 /*********************************************************************** 159 * ber_flatten (WLDAP32.@) 160 * 161 * Flatten a berelement structure into a berval structure. 162 * 163 * PARAMS 164 * berelement [I] Pointer to a berelement structure. 165 * berval [O] Pointer to a berval structure. 166 * 167 * RETURNS 168 * Success: 0 169 * Failure: LBER_ERROR 170 * 171 * NOTES 172 * Free the berval structure with ber_bvfree. 173 */ 174 INT CDECL WLDAP32_ber_flatten( BerElement *berelement, PBERVAL *berval ) 175 { 176 #ifdef HAVE_LDAP 177 return ber_flatten( berelement, berval ); 178 #else 179 return LBER_ERROR; 180 #endif 181 } 182 183 184 /*********************************************************************** 185 * ber_free (WLDAP32.@) 186 * 187 * Free a berelement structure. 188 * 189 * PARAMS 190 * berelement [I] Pointer to the berelement structure to be freed. 191 * buf [I] Flag. 192 * 193 * RETURNS 194 * Nothing. 195 * 196 * NOTES 197 * Set buf to 0 if the berelement was allocated with ldap_first_attribute 198 * or ldap_next_attribute, otherwise set it to 1. 199 */ 200 void CDECL WLDAP32_ber_free( BerElement *berelement, INT buf ) 201 { 202 #ifdef HAVE_LDAP 203 ber_free( berelement, buf ); 204 #endif 205 } 206 207 208 /*********************************************************************** 209 * ber_init (WLDAP32.@) 210 * 211 * Initialise a berelement structure from a berval structure. 212 * 213 * PARAMS 214 * berval [I] Pointer to a berval structure. 215 * 216 * RETURNS 217 * Success: Pointer to a berelement structure. 218 * Failure: NULL 219 * 220 * NOTES 221 * Call ber_free to free the returned berelement structure. 222 */ 223 BerElement * CDECL WLDAP32_ber_init( BERVAL *berval ) 224 { 225 #ifdef HAVE_LDAP 226 return ber_init( berval ); 227 #else 228 return NULL; 229 #endif 230 } 231 232 233 /*********************************************************************** 234 * ber_next_element (WLDAP32.@) 235 * 236 * Return the tag of the next element in a set or sequence. 237 * 238 * PARAMS 239 * berelement [I] Pointer to a berelement structure. 240 * len [I/O] Receives the length of the next element. 241 * opaque [I/O] Pointer to a cookie. 242 * 243 * RETURNS 244 * Success: Tag of the next element. 245 * Failure: LBER_DEFAULT (no more data). 246 * 247 * NOTES 248 * len and cookie are initialized by ber_first_element and should 249 * be passed on in subsequent calls to ber_next_element. 250 */ 251 ULONG CDECL WLDAP32_ber_next_element( BerElement *berelement, ULONG *len, CHAR *opaque ) 252 { 253 #ifdef HAVE_LDAP 254 return ber_next_element( berelement, len, opaque ); 255 #else 256 return LBER_ERROR; 257 #endif 258 } 259 260 261 /*********************************************************************** 262 * ber_peek_tag (WLDAP32.@) 263 * 264 * Return the tag of the next element. 265 * 266 * PARAMS 267 * berelement [I] Pointer to a berelement structure. 268 * len [O] Receives the length of the next element. 269 * 270 * RETURNS 271 * Success: Tag of the next element. 272 * Failure: LBER_DEFAULT (no more data). 273 */ 274 ULONG CDECL WLDAP32_ber_peek_tag( BerElement *berelement, ULONG *len ) 275 { 276 #ifdef HAVE_LDAP 277 return ber_peek_tag( berelement, len ); 278 #else 279 return LBER_ERROR; 280 #endif 281 } 282 283 284 /*********************************************************************** 285 * ber_skip_tag (WLDAP32.@) 286 * 287 * Skip the current tag and return the tag of the next element. 288 * 289 * PARAMS 290 * berelement [I] Pointer to a berelement structure. 291 * len [O] Receives the length of the skipped element. 292 * 293 * RETURNS 294 * Success: Tag of the next element. 295 * Failure: LBER_DEFAULT (no more data). 296 */ 297 ULONG CDECL WLDAP32_ber_skip_tag( BerElement *berelement, ULONG *len ) 298 { 299 #ifdef HAVE_LDAP 300 return ber_skip_tag( berelement, len ); 301 #else 302 return LBER_ERROR; 303 #endif 304 } 305 306 307 /*********************************************************************** 308 * ber_printf (WLDAP32.@) 309 * 310 * Encode a berelement structure. 311 * 312 * PARAMS 313 * berelement [I/O] Pointer to a berelement structure. 314 * fmt [I] Format string. 315 * ... [I] Values to encode. 316 * 317 * RETURNS 318 * Success: Non-negative number. 319 * Failure: LBER_ERROR 320 * 321 * NOTES 322 * berelement must have been allocated with ber_alloc_t. This function 323 * can be called multiple times to append data. 324 */ 325 INT WINAPIV WLDAP32_ber_printf( BerElement *berelement, PCHAR fmt, ... ) 326 { 327 #ifdef HAVE_LDAP 328 __ms_va_list list; 329 int ret = 0; 330 char new_fmt[2]; 331 332 new_fmt[1] = 0; 333 __ms_va_start( list, fmt ); 334 while (*fmt) 335 { 336 new_fmt[0] = *fmt++; 337 switch(new_fmt[0]) 338 { 339 case 'b': 340 case 'e': 341 case 'i': 342 { 343 int i = va_arg( list, int ); 344 ret = ber_printf( berelement, new_fmt, i ); 345 break; 346 } 347 case 'o': 348 case 's': 349 { 350 char *str = va_arg( list, char * ); 351 ret = ber_printf( berelement, new_fmt, str ); 352 break; 353 } 354 case 't': 355 { 356 unsigned int tag = va_arg( list, unsigned int ); 357 ret = ber_printf( berelement, new_fmt, tag ); 358 break; 359 } 360 case 'v': 361 { 362 char **array = va_arg( list, char ** ); 363 ret = ber_printf( berelement, new_fmt, array ); 364 break; 365 } 366 case 'V': 367 { 368 struct berval **array = va_arg( list, struct berval ** ); 369 ret = ber_printf( berelement, new_fmt, array ); 370 break; 371 } 372 case 'X': 373 { 374 char *str = va_arg( list, char * ); 375 int len = va_arg( list, int ); 376 new_fmt[0] = 'B'; /* 'X' is deprecated */ 377 ret = ber_printf( berelement, new_fmt, str, len ); 378 break; 379 } 380 case 'n': 381 case '{': 382 case '}': 383 case '[': 384 case ']': 385 ret = ber_printf( berelement, new_fmt ); 386 break; 387 default: 388 FIXME( "Unknown format '%c'\n", new_fmt[0] ); 389 ret = -1; 390 break; 391 } 392 if (ret == -1) break; 393 } 394 __ms_va_end( list ); 395 return ret; 396 #else 397 return LBER_ERROR; 398 #endif 399 } 400 401 402 /*********************************************************************** 403 * ber_scanf (WLDAP32.@) 404 * 405 * Decode a berelement structure. 406 * 407 * PARAMS 408 * berelement [I/O] Pointer to a berelement structure. 409 * fmt [I] Format string. 410 * ... [I] Pointers to values to be decoded. 411 * 412 * RETURNS 413 * Success: Non-negative number. 414 * Failure: LBER_ERROR 415 * 416 * NOTES 417 * berelement must have been allocated with ber_init. This function 418 * can be called multiple times to decode data. 419 */ 420 INT WINAPIV WLDAP32_ber_scanf( BerElement *berelement, PCHAR fmt, ... ) 421 { 422 #ifdef HAVE_LDAP 423 __ms_va_list list; 424 int ret = 0; 425 char new_fmt[2]; 426 427 new_fmt[1] = 0; 428 __ms_va_start( list, fmt ); 429 while (*fmt) 430 { 431 new_fmt[0] = *fmt++; 432 switch(new_fmt[0]) 433 { 434 case 'a': 435 { 436 char **ptr = va_arg( list, char ** ); 437 ret = ber_scanf( berelement, new_fmt, ptr ); 438 break; 439 } 440 case 'b': 441 case 'e': 442 case 'i': 443 { 444 int *i = va_arg( list, int * ); 445 ret = ber_scanf( berelement, new_fmt, i ); 446 break; 447 } 448 case 't': 449 { 450 unsigned int *tag = va_arg( list, unsigned int * ); 451 ret = ber_scanf( berelement, new_fmt, tag ); 452 break; 453 } 454 case 'v': 455 { 456 char ***array = va_arg( list, char *** ); 457 ret = ber_scanf( berelement, new_fmt, array ); 458 break; 459 } 460 case 'B': 461 { 462 char **str = va_arg( list, char ** ); 463 int *len = va_arg( list, int * ); 464 ret = ber_scanf( berelement, new_fmt, str, len ); 465 break; 466 } 467 case 'O': 468 { 469 struct berval **ptr = va_arg( list, struct berval ** ); 470 ret = ber_scanf( berelement, new_fmt, ptr ); 471 break; 472 } 473 case 'V': 474 { 475 struct berval ***array = va_arg( list, struct berval *** ); 476 ret = ber_scanf( berelement, new_fmt, array ); 477 break; 478 } 479 case 'n': 480 case 'x': 481 case '{': 482 case '}': 483 case '[': 484 case ']': 485 ret = ber_scanf( berelement, new_fmt ); 486 break; 487 default: 488 FIXME( "Unknown format '%c'\n", new_fmt[0] ); 489 ret = -1; 490 break; 491 } 492 if (ret == -1) break; 493 } 494 __ms_va_end( list ); 495 return ret; 496 #else 497 return LBER_ERROR; 498 #endif 499 } 500