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 #include "wine/port.h" 23 24 #include <stdarg.h> 25 #ifdef HAVE_LDAP_H 26 #include <ldap.h> 27 #endif 28 29 #include "windef.h" 30 #include "winbase.h" 31 #include "winnls.h" 32 33 #include "winldap_private.h" 34 #include "wldap32.h" 35 #include "wine/debug.h" 36 37 WINE_DEFAULT_DEBUG_CHANNEL(wldap32); 38 39 #ifdef HAVE_LDAP 40 static LDAPMod *nullmods[] = { NULL }; 41 #endif 42 43 /*********************************************************************** 44 * ldap_modifyA (WLDAP32.@) 45 * 46 * See ldap_modifyW. 47 */ 48 ULONG CDECL ldap_modifyA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *mods[] ) 49 { 50 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 51 #ifdef HAVE_LDAP 52 WCHAR *dnW = NULL; 53 LDAPModW **modsW = NULL; 54 55 ret = WLDAP32_LDAP_NO_MEMORY; 56 57 TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), mods ); 58 59 if (!ld) return ~0u; 60 61 if (dn) { 62 dnW = strAtoW( dn ); 63 if (!dnW) goto exit; 64 } 65 if (mods) { 66 modsW = modarrayAtoW( mods ); 67 if (!modsW) goto exit; 68 } 69 70 ret = ldap_modifyW( ld, dnW, modsW ); 71 72 exit: 73 strfreeW( dnW ); 74 modarrayfreeW( modsW ); 75 76 #endif 77 return ret; 78 } 79 80 /*********************************************************************** 81 * ldap_modifyW (WLDAP32.@) 82 * 83 * Change an entry in a directory tree (asynchronous operation). 84 * 85 * PARAMS 86 * ld [I] Pointer to an LDAP context. 87 * dn [I] DN of the entry to change. 88 * mods [I] Pointer to an array of LDAPModW structures, each 89 * specifying an attribute and its values to change. 90 * 91 * RETURNS 92 * Success: Message ID of the modify operation. 93 * Failure: An LDAP error code. 94 * 95 * NOTES 96 * Call ldap_result with the message ID to get the result of 97 * the operation. Cancel the operation by calling ldap_abandon 98 * with the message ID. 99 */ 100 ULONG CDECL ldap_modifyW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[] ) 101 { 102 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 103 #ifdef HAVE_LDAP 104 char *dnU = NULL; 105 LDAPMod **modsU = NULL; 106 int msg; 107 108 ret = WLDAP32_LDAP_NO_MEMORY; 109 110 TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), mods ); 111 112 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 113 114 if (dn) { 115 dnU = strWtoU( dn ); 116 if (!dnU) goto exit; 117 } 118 if (mods) { 119 modsU = modarrayWtoU( mods ); 120 if (!modsU) goto exit; 121 } 122 123 ret = ldap_modify_ext( ld, dn ? dnU : "", mods ? modsU : nullmods, 124 NULL, NULL, &msg ); 125 126 if (ret == LDAP_SUCCESS) 127 ret = msg; 128 else 129 ret = ~0u; 130 131 exit: 132 strfreeU( dnU ); 133 modarrayfreeU( modsU ); 134 135 #endif 136 return ret; 137 } 138 139 /*********************************************************************** 140 * ldap_modify_extA (WLDAP32.@) 141 * 142 * See ldap_modify_extW. 143 */ 144 ULONG CDECL ldap_modify_extA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *mods[], 145 PLDAPControlA *serverctrls, PLDAPControlA *clientctrls, ULONG *message ) 146 { 147 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 148 #ifdef HAVE_LDAP 149 WCHAR *dnW = NULL; 150 LDAPModW **modsW = NULL; 151 LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL; 152 153 ret = WLDAP32_LDAP_NO_MEMORY; 154 155 TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_a(dn), mods, 156 serverctrls, clientctrls, message ); 157 158 if (!ld) return ~0u; 159 160 if (dn) { 161 dnW = strAtoW( dn ); 162 if (!dnW) goto exit; 163 } 164 if (mods) { 165 modsW = modarrayAtoW( mods ); 166 if (!modsW) goto exit; 167 } 168 if (serverctrls) { 169 serverctrlsW = controlarrayAtoW( serverctrls ); 170 if (!serverctrlsW) goto exit; 171 } 172 if (clientctrls) { 173 clientctrlsW = controlarrayAtoW( clientctrls ); 174 if (!clientctrlsW) goto exit; 175 } 176 177 ret = ldap_modify_extW( ld, dnW, modsW, serverctrlsW, clientctrlsW, message ); 178 179 exit: 180 strfreeW( dnW ); 181 modarrayfreeW( modsW ); 182 controlarrayfreeW( serverctrlsW ); 183 controlarrayfreeW( clientctrlsW ); 184 185 #endif 186 return ret; 187 } 188 189 /*********************************************************************** 190 * ldap_modify_extW (WLDAP32.@) 191 * 192 * Change an entry in a directory tree (asynchronous operation). 193 * 194 * PARAMS 195 * ld [I] Pointer to an LDAP context. 196 * dn [I] DN of the entry to change. 197 * mods [I] Pointer to an array of LDAPModW structures, each 198 * specifying an attribute and its values to change. 199 * serverctrls [I] Array of LDAP server controls. 200 * clientctrls [I] Array of LDAP client controls. 201 * message [O] Message ID of the modify operation. 202 * 203 * RETURNS 204 * Success: LDAP_SUCCESS 205 * Failure: An LDAP error code. 206 * 207 * NOTES 208 * Call ldap_result with the message ID to get the result of 209 * the operation. The serverctrls and clientctrls parameters are 210 * optional and should be set to NULL if not used. 211 */ 212 ULONG CDECL ldap_modify_extW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[], 213 PLDAPControlW *serverctrls, PLDAPControlW *clientctrls, ULONG *message ) 214 { 215 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 216 #ifdef HAVE_LDAP 217 char *dnU = NULL; 218 LDAPMod **modsU = NULL; 219 LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL; 220 int dummy; 221 222 ret = WLDAP32_LDAP_NO_MEMORY; 223 224 TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_w(dn), mods, 225 serverctrls, clientctrls, message ); 226 227 if (!ld) return ~0u; 228 229 if (dn) { 230 dnU = strWtoU( dn ); 231 if (!dnU) goto exit; 232 } 233 if (mods) { 234 modsU = modarrayWtoU( mods ); 235 if (!modsU) goto exit; 236 } 237 if (serverctrls) { 238 serverctrlsU = controlarrayWtoU( serverctrls ); 239 if (!serverctrlsU) goto exit; 240 } 241 if (clientctrls) { 242 clientctrlsU = controlarrayWtoU( clientctrls ); 243 if (!clientctrlsU) goto exit; 244 } 245 246 ret = map_error( ldap_modify_ext( ld, dn ? dnU : "", mods ? modsU : nullmods, serverctrlsU, 247 clientctrlsU, message ? (int *)message : &dummy )); 248 249 exit: 250 strfreeU( dnU ); 251 modarrayfreeU( modsU ); 252 controlarrayfreeU( serverctrlsU ); 253 controlarrayfreeU( clientctrlsU ); 254 255 #endif 256 return ret; 257 } 258 259 /*********************************************************************** 260 * ldap_modify_ext_sA (WLDAP32.@) 261 * 262 * See ldap_modify_ext_sW. 263 */ 264 ULONG CDECL ldap_modify_ext_sA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *mods[], 265 PLDAPControlA *serverctrls, PLDAPControlA *clientctrls ) 266 { 267 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 268 #ifdef HAVE_LDAP 269 WCHAR *dnW = NULL; 270 LDAPModW **modsW = NULL; 271 LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL; 272 273 ret = WLDAP32_LDAP_NO_MEMORY; 274 275 TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_a(dn), mods, 276 serverctrls, clientctrls ); 277 278 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 279 280 if (dn) { 281 dnW = strAtoW( dn ); 282 if (!dnW) goto exit; 283 } 284 if (mods) { 285 modsW = modarrayAtoW( mods ); 286 if (!modsW) goto exit; 287 } 288 if (serverctrls) { 289 serverctrlsW = controlarrayAtoW( serverctrls ); 290 if (!serverctrlsW) goto exit; 291 } 292 if (clientctrls) { 293 clientctrlsW = controlarrayAtoW( clientctrls ); 294 if (!clientctrlsW) goto exit; 295 } 296 297 ret = ldap_modify_ext_sW( ld, dnW, modsW, serverctrlsW, clientctrlsW ); 298 299 exit: 300 strfreeW( dnW ); 301 modarrayfreeW( modsW ); 302 controlarrayfreeW( serverctrlsW ); 303 controlarrayfreeW( clientctrlsW ); 304 305 #endif 306 return ret; 307 } 308 309 /*********************************************************************** 310 * ldap_modify_ext_sW (WLDAP32.@) 311 * 312 * Change an entry in a directory tree (synchronous operation). 313 * 314 * PARAMS 315 * ld [I] Pointer to an LDAP context. 316 * dn [I] DN of the entry to change. 317 * mods [I] Pointer to an array of LDAPModW structures, each 318 * specifying an attribute and its values to change. 319 * serverctrls [I] Array of LDAP server controls. 320 * clientctrls [I] Array of LDAP client controls. 321 * 322 * RETURNS 323 * Success: LDAP_SUCCESS 324 * Failure: An LDAP error code. 325 * 326 * NOTES 327 * The serverctrls and clientctrls parameters are optional and 328 * should be set to NULL if not used. 329 */ 330 ULONG CDECL ldap_modify_ext_sW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[], 331 PLDAPControlW *serverctrls, PLDAPControlW *clientctrls ) 332 { 333 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 334 #ifdef HAVE_LDAP 335 char *dnU = NULL; 336 LDAPMod **modsU = NULL; 337 LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL; 338 339 ret = WLDAP32_LDAP_NO_MEMORY; 340 341 TRACE( "(%p, %s, %p, %p, %p)\n", ld, debugstr_w(dn), mods, 342 serverctrls, clientctrls ); 343 344 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 345 346 if (dn) { 347 dnU = strWtoU( dn ); 348 if (!dnU) goto exit; 349 } 350 if (mods) { 351 modsU = modarrayWtoU( mods ); 352 if (!modsU) goto exit; 353 } 354 if (serverctrls) { 355 serverctrlsU = controlarrayWtoU( serverctrls ); 356 if (!serverctrlsU) goto exit; 357 } 358 if (clientctrls) { 359 clientctrlsU = controlarrayWtoU( clientctrls ); 360 if (!clientctrlsU) goto exit; 361 } 362 363 ret = map_error( ldap_modify_ext_s( ld, dn ? dnU : "", mods ? modsU : nullmods, 364 serverctrlsU, clientctrlsU )); 365 366 exit: 367 strfreeU( dnU ); 368 modarrayfreeU( modsU ); 369 controlarrayfreeU( serverctrlsU ); 370 controlarrayfreeU( clientctrlsU ); 371 372 #endif 373 return ret; 374 } 375 376 /*********************************************************************** 377 * ldap_modify_sA (WLDAP32.@) 378 * 379 * See ldap_modify_sW. 380 */ 381 ULONG CDECL ldap_modify_sA( WLDAP32_LDAP *ld, PCHAR dn, LDAPModA *mods[] ) 382 { 383 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 384 #ifdef HAVE_LDAP 385 WCHAR *dnW = NULL; 386 LDAPModW **modsW = NULL; 387 388 ret = WLDAP32_LDAP_NO_MEMORY; 389 390 TRACE( "(%p, %s, %p)\n", ld, debugstr_a(dn), mods ); 391 392 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 393 394 if (dn) { 395 dnW = strAtoW( dn ); 396 if (!dnW) goto exit; 397 } 398 if (mods) { 399 modsW = modarrayAtoW( mods ); 400 if (!modsW) goto exit; 401 } 402 403 ret = ldap_modify_sW( ld, dnW, modsW ); 404 405 exit: 406 strfreeW( dnW ); 407 modarrayfreeW( modsW ); 408 409 #endif 410 return ret; 411 } 412 413 /*********************************************************************** 414 * ldap_modify_sW (WLDAP32.@) 415 * 416 * Change an entry in a directory tree (synchronous operation). 417 * 418 * PARAMS 419 * ld [I] Pointer to an LDAP context. 420 * dn [I] DN of the entry to change. 421 * attrs [I] Pointer to an array of LDAPModW structures, each 422 * specifying an attribute and its values to change. 423 * 424 * RETURNS 425 * Success: LDAP_SUCCESS 426 * Failure: An LDAP error code. 427 */ 428 ULONG CDECL ldap_modify_sW( WLDAP32_LDAP *ld, PWCHAR dn, LDAPModW *mods[] ) 429 { 430 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 431 #ifdef HAVE_LDAP 432 char *dnU = NULL; 433 LDAPMod **modsU = NULL; 434 435 ret = WLDAP32_LDAP_NO_MEMORY; 436 437 TRACE( "(%p, %s, %p)\n", ld, debugstr_w(dn), mods ); 438 439 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 440 441 if (dn) { 442 dnU = strWtoU( dn ); 443 if (!dnU) goto exit; 444 } 445 if (mods) { 446 modsU = modarrayWtoU( mods ); 447 if (!modsU) goto exit; 448 } 449 450 ret = map_error( ldap_modify_ext_s( ld, dn ? dnU : "", mods ? modsU : nullmods, NULL, NULL )); 451 452 exit: 453 strfreeU( dnU ); 454 modarrayfreeU( modsU ); 455 456 #endif 457 return ret; 458 } 459