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