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 "winldap_private.h" 22 23 /*********************************************************************** 24 * ldap_parse_extended_resultA (WLDAP32.@) 25 * 26 * See ldap_parse_extended_resultW. 27 */ 28 ULONG CDECL ldap_parse_extended_resultA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *result, 29 PCHAR *oid, struct WLDAP32_berval **data, BOOLEAN free ) 30 { 31 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 32 #ifdef HAVE_LDAP 33 WCHAR *oidW = NULL; 34 35 TRACE( "(%p, %p, %p, %p, 0x%02x)\n", ld, result, oid, data, free ); 36 37 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 38 if (!result) return WLDAP32_LDAP_NO_RESULTS_RETURNED; 39 40 ret = ldap_parse_extended_resultW( ld, result, &oidW, data, free ); 41 42 if (oid) { 43 *oid = strWtoA( oidW ); 44 if (!*oid) ret = WLDAP32_LDAP_NO_MEMORY; 45 ldap_memfreeW( oidW ); 46 } 47 48 #endif 49 return ret; 50 } 51 52 /*********************************************************************** 53 * ldap_parse_extended_resultW (WLDAP32.@) 54 * 55 * Parse the result of an extended operation. 56 * 57 * PARAMS 58 * ld [I] Pointer to an LDAP context. 59 * result [I] Result message from an extended operation. 60 * oid [O] OID of the extended operation. 61 * data [O] Result data. 62 * free [I] Free the result message? 63 * 64 * RETURNS 65 * Success: LDAP_SUCCESS 66 * Failure: An LDAP error code. 67 * 68 * NOTES 69 * Free the OID and result data with ldap_memfree. Pass a nonzero 70 * value for 'free' or call ldap_msgfree to free the result message. 71 */ 72 ULONG CDECL ldap_parse_extended_resultW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *result, 73 PWCHAR *oid, struct WLDAP32_berval **data, BOOLEAN free ) 74 { 75 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 76 #ifdef HAVE_LDAP 77 char *oidU = NULL; 78 79 TRACE( "(%p, %p, %p, %p, 0x%02x)\n", ld, result, oid, data, free ); 80 81 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 82 if (!result) return WLDAP32_LDAP_NO_RESULTS_RETURNED; 83 84 ret = map_error( ldap_parse_extended_result( ld, result, &oidU, (struct berval **)data, free ) ); 85 86 if (oid) { 87 *oid = strUtoW( oidU ); 88 if (!*oid) ret = WLDAP32_LDAP_NO_MEMORY; 89 ldap_memfree( oidU ); 90 } 91 92 #endif 93 return ret; 94 } 95 96 /*********************************************************************** 97 * ldap_parse_referenceA (WLDAP32.@) 98 * 99 * See ldap_parse_referenceW. 100 */ 101 ULONG CDECL ldap_parse_referenceA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *message, 102 PCHAR **referrals ) 103 { 104 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 105 #ifdef HAVE_LDAP 106 WCHAR **referralsW = NULL; 107 108 TRACE( "(%p, %p, %p)\n", ld, message, referrals ); 109 110 if (!ld) return ~0u; 111 112 ret = ldap_parse_referenceW( ld, message, &referralsW ); 113 114 *referrals = strarrayWtoA( referralsW ); 115 ldap_value_freeW( referralsW ); 116 117 #endif 118 return ret; 119 } 120 121 /*********************************************************************** 122 * ldap_parse_referenceW (WLDAP32.@) 123 * 124 * Return any referrals from a result message. 125 * 126 * PARAMS 127 * ld [I] Pointer to an LDAP context. 128 * result [I] Result message. 129 * referrals [O] Array of referral URLs. 130 * 131 * RETURNS 132 * Success: LDAP_SUCCESS 133 * Failure: An LDAP error code. 134 * 135 * NOTES 136 * Free the referrals with ldap_value_free. 137 */ 138 ULONG CDECL ldap_parse_referenceW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *message, 139 PWCHAR **referrals ) 140 { 141 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 142 #ifdef HAVE_LDAP_PARSE_REFERENCE 143 char **referralsU = NULL; 144 145 TRACE( "(%p, %p, %p)\n", ld, message, referrals ); 146 147 if (!ld) return ~0u; 148 149 ret = map_error( ldap_parse_reference( ld, message, &referralsU, NULL, 0 )); 150 151 *referrals = strarrayUtoW( referralsU ); 152 ldap_memfree( referralsU ); 153 154 #endif 155 return ret; 156 } 157 158 /*********************************************************************** 159 * ldap_parse_resultA (WLDAP32.@) 160 * 161 * See ldap_parse_resultW. 162 */ 163 ULONG CDECL ldap_parse_resultA( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *result, 164 ULONG *retcode, PCHAR *matched, PCHAR *error, PCHAR **referrals, 165 PLDAPControlA **serverctrls, BOOLEAN free ) 166 { 167 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 168 #ifdef HAVE_LDAP 169 WCHAR *matchedW = NULL, *errorW = NULL, **referralsW = NULL; 170 LDAPControlW **serverctrlsW = NULL; 171 172 TRACE( "(%p, %p, %p, %p, %p, %p, %p, 0x%02x)\n", ld, result, retcode, 173 matched, error, referrals, serverctrls, free ); 174 175 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 176 177 ret = ldap_parse_resultW( ld, result, retcode, &matchedW, &errorW, 178 &referralsW, &serverctrlsW, free ); 179 180 if (matched) *matched = strWtoA( matchedW ); 181 if (error) *error = strWtoA( errorW ); 182 183 if (referrals) *referrals = strarrayWtoA( referralsW ); 184 if (serverctrls) *serverctrls = controlarrayWtoA( serverctrlsW ); 185 186 ldap_memfreeW( matchedW ); 187 ldap_memfreeW( errorW ); 188 ldap_value_freeW( referralsW ); 189 ldap_controls_freeW( serverctrlsW ); 190 191 #endif 192 return ret; 193 } 194 195 /*********************************************************************** 196 * ldap_parse_resultW (WLDAP32.@) 197 * 198 * Parse a result message. 199 * 200 * PARAMS 201 * ld [I] Pointer to an LDAP context. 202 * result [I] Result message. 203 * retcode [O] Return code for the server operation. 204 * matched [O] DNs matched in the operation. 205 * error [O] Error message for the operation. 206 * referrals [O] Referrals found in the result message. 207 * serverctrls [O] Controls used in the operation. 208 * free [I] Free the result message? 209 * 210 * RETURNS 211 * Success: LDAP_SUCCESS 212 * Failure: An LDAP error code. 213 * 214 * NOTES 215 * Free the DNs and error message with ldap_memfree. Free 216 * the referrals with ldap_value_free and the controls with 217 * ldap_controls_free. Pass a nonzero value for 'free' or call 218 * ldap_msgfree to free the result message. 219 */ 220 ULONG CDECL ldap_parse_resultW( WLDAP32_LDAP *ld, WLDAP32_LDAPMessage *result, 221 ULONG *retcode, PWCHAR *matched, PWCHAR *error, PWCHAR **referrals, 222 PLDAPControlW **serverctrls, BOOLEAN free ) 223 { 224 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 225 #ifdef HAVE_LDAP 226 char *matchedU = NULL, *errorU = NULL, **referralsU = NULL; 227 LDAPControl **serverctrlsU = NULL; 228 229 TRACE( "(%p, %p, %p, %p, %p, %p, %p, 0x%02x)\n", ld, result, retcode, 230 matched, error, referrals, serverctrls, free ); 231 232 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 233 234 ret = map_error( ldap_parse_result( ld, result, (int *)retcode, &matchedU, &errorU, 235 &referralsU, &serverctrlsU, free )); 236 237 if (matched) *matched = strUtoW( matchedU ); 238 if (error) *error = strUtoW( errorU ); 239 240 if (referrals) *referrals = strarrayUtoW( referralsU ); 241 if (serverctrls) *serverctrls = controlarrayUtoW( serverctrlsU ); 242 243 ldap_memfree( matchedU ); 244 ldap_memfree( errorU ); 245 strarrayfreeU( referralsU ); 246 ldap_controls_free( serverctrlsU ); 247 248 #endif 249 return ret; 250 } 251 252 /*********************************************************************** 253 * ldap_parse_sort_controlA (WLDAP32.@) 254 * 255 * See ldap_parse_sort_controlW. 256 */ 257 ULONG CDECL ldap_parse_sort_controlA( WLDAP32_LDAP *ld, PLDAPControlA *control, 258 ULONG *result, PCHAR *attr ) 259 { 260 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 261 #ifdef HAVE_LDAP 262 WCHAR *attrW = NULL; 263 LDAPControlW **controlW = NULL; 264 265 TRACE( "(%p, %p, %p, %p)\n", ld, control, result, attr ); 266 267 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 268 if (!control) return WLDAP32_LDAP_CONTROL_NOT_FOUND; 269 270 controlW = controlarrayAtoW( control ); 271 if (!controlW) return WLDAP32_LDAP_NO_MEMORY; 272 273 ret = ldap_parse_sort_controlW( ld, controlW, result, &attrW ); 274 275 *attr = strWtoA( attrW ); 276 controlarrayfreeW( controlW ); 277 278 #endif 279 return ret; 280 } 281 282 /*********************************************************************** 283 * ldap_parse_sort_controlW (WLDAP32.@) 284 * 285 * Parse a sort control. 286 * 287 * PARAMS 288 * ld [I] Pointer to an LDAP context. 289 * control [I] Control obtained from a result message. 290 * result [O] Result code. 291 * attr [O] Failing attribute. 292 * 293 * RETURNS 294 * Success: LDAP_SUCCESS 295 * Failure: An LDAP error code. 296 * 297 * NOTES 298 * If the function fails, free the failing attribute with ldap_memfree. 299 */ 300 ULONG CDECL ldap_parse_sort_controlW( WLDAP32_LDAP *ld, PLDAPControlW *control, 301 ULONG *result, PWCHAR *attr ) 302 { 303 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 304 #ifdef HAVE_LDAP 305 char *attrU = NULL; 306 LDAPControl **controlU = NULL; 307 #ifdef HAVE_LDAP_PARSE_SORT_CONTROL 308 unsigned long res; 309 #elif defined(HAVE_LDAP_PARSE_SORTRESPONSE_CONTROL) 310 ber_int_t res; 311 LDAPControl *sortcontrol = NULL; 312 unsigned int i; 313 #endif 314 315 TRACE( "(%p, %p, %p, %p)\n", ld, control, result, attr ); 316 317 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 318 if (!control) return WLDAP32_LDAP_CONTROL_NOT_FOUND; 319 320 controlU = controlarrayWtoU( control ); 321 if (!controlU) return WLDAP32_LDAP_NO_MEMORY; 322 323 #ifdef HAVE_LDAP_PARSE_SORT_CONTROL 324 if (!(ret = ldap_parse_sort_control( ld, controlU, &res, &attrU ))) 325 { 326 *result = res; 327 *attr = strUtoW( attrU ); 328 } 329 #elif defined(HAVE_LDAP_PARSE_SORTRESPONSE_CONTROL) 330 for (i = 0; controlU[i]; i++) 331 { 332 if (!strcmp( LDAP_SERVER_RESP_SORT_OID, controlU[i]->ldctl_oid )) 333 sortcontrol = controlU[i]; 334 } 335 if (!sortcontrol) 336 { 337 controlarrayfreeU( controlU ); 338 return WLDAP32_LDAP_CONTROL_NOT_FOUND; 339 } 340 if (!(ret = ldap_parse_sortresponse_control( ld, sortcontrol, &res, &attrU ))) 341 { 342 *result = res; 343 *attr = strUtoW( attrU ); 344 } 345 #endif 346 controlarrayfreeU( controlU ); 347 348 #endif 349 return map_error( ret ); 350 } 351 352 /*********************************************************************** 353 * ldap_parse_vlv_controlA (WLDAP32.@) 354 * 355 * See ldap_parse_vlv_controlW. 356 */ 357 INT CDECL ldap_parse_vlv_controlA( WLDAP32_LDAP *ld, PLDAPControlA *control, 358 PULONG targetpos, PULONG listcount, 359 struct WLDAP32_berval **context, PINT errcode ) 360 { 361 int ret = WLDAP32_LDAP_NOT_SUPPORTED; 362 #ifdef HAVE_LDAP 363 LDAPControlW **controlW = NULL; 364 365 TRACE( "(%p, %p, %p, %p, %p, %p)\n", ld, control, targetpos, 366 listcount, context, errcode ); 367 368 if (!ld) return ~0u; 369 370 if (control) { 371 controlW = controlarrayAtoW( control ); 372 if (!controlW) return WLDAP32_LDAP_NO_MEMORY; 373 } 374 375 ret = ldap_parse_vlv_controlW( ld, controlW, targetpos, listcount, 376 context, errcode ); 377 378 controlarrayfreeW( controlW ); 379 380 #endif 381 return ret; 382 } 383 384 /*********************************************************************** 385 * ldap_parse_vlv_controlW (WLDAP32.@) 386 * 387 * Parse a virtual list view control. 388 * 389 * PARAMS 390 * ld [I] Pointer to an LDAP context. 391 * control [I] Controls obtained from a result message. 392 * targetpos [O] Position of the target in the result list. 393 * listcount [O] Estimate of the number of results in the list. 394 * context [O] Server side context. 395 * errcode [O] Error code from the listview operation. 396 * 397 * RETURNS 398 * Success: LDAP_SUCCESS 399 * Failure: An LDAP error code. 400 * 401 * NOTES 402 * Free the server context with ber_bvfree. 403 */ 404 INT CDECL ldap_parse_vlv_controlW( WLDAP32_LDAP *ld, PLDAPControlW *control, 405 PULONG targetpos, PULONG listcount, 406 struct WLDAP32_berval **context, PINT errcode ) 407 { 408 int ret = WLDAP32_LDAP_NOT_SUPPORTED; 409 #ifdef HAVE_LDAP 410 LDAPControl **controlU = NULL; 411 #ifdef HAVE_LDAP_PARSE_VLV_CONTROL 412 unsigned long pos, count; 413 #elif defined(HAVE_LDAP_PARSE_VLVRESPONSE_CONTROL) 414 ber_int_t pos, count; 415 LDAPControl *vlvcontrol = NULL; 416 unsigned int i; 417 #endif 418 419 TRACE( "(%p, %p, %p, %p, %p, %p)\n", ld, control, targetpos, 420 listcount, context, errcode ); 421 422 if (!ld || !control) return ~0u; 423 424 controlU = controlarrayWtoU( control ); 425 if (!controlU) return WLDAP32_LDAP_NO_MEMORY; 426 427 #ifdef HAVE_LDAP_PARSE_VLV_CONTROL 428 if (!(ret = ldap_parse_vlv_control( ld, controlU, &pos, &count, 429 (struct berval **)context, errcode ))) 430 { 431 *targetpos = pos; 432 *listcount = count; 433 } 434 #elif defined(HAVE_LDAP_PARSE_VLVRESPONSE_CONTROL) 435 for (i = 0; controlU[i]; i++) 436 { 437 if (!strcmp( LDAP_CONTROL_VLVRESPONSE, controlU[i]->ldctl_oid )) 438 vlvcontrol = controlU[i]; 439 } 440 if (!vlvcontrol) 441 { 442 controlarrayfreeU( controlU ); 443 return WLDAP32_LDAP_CONTROL_NOT_FOUND; 444 } 445 if (!(ret = ldap_parse_vlvresponse_control( ld, vlvcontrol, &pos, &count, 446 (struct berval **)context, errcode ))) 447 { 448 *targetpos = pos; 449 *listcount = count; 450 } 451 #endif 452 controlarrayfreeU( controlU ); 453 454 #endif 455 return map_error( ret ); 456 } 457