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 /*********************************************************************** 40 * ldap_close_extended_op (WLDAP32.@) 41 * 42 * Close an extended operation. 43 * 44 * PARAMS 45 * ld [I] Pointer to an LDAP context. 46 * msgid [I] Message ID of the operation to be closed. 47 * 48 * RETURNS 49 * Success: LDAP_SUCCESS 50 * Failure: An LDAP error code. 51 * 52 * NOTES 53 * Contrary to native, OpenLDAP does not require us to close 54 * extended operations, so this is a no-op. 55 */ 56 ULONG CDECL ldap_close_extended_op( WLDAP32_LDAP *ld, ULONG msgid ) 57 { 58 TRACE( "(%p, 0x%08x)\n", ld, msgid ); 59 60 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 61 return WLDAP32_LDAP_SUCCESS; 62 } 63 64 /*********************************************************************** 65 * ldap_extended_operationA (WLDAP32.@) 66 * 67 * See ldap_extended_operationW. 68 */ 69 ULONG CDECL ldap_extended_operationA( WLDAP32_LDAP *ld, PCHAR oid, struct WLDAP32_berval *data, 70 PLDAPControlA *serverctrls, PLDAPControlA *clientctrls, ULONG *message ) 71 { 72 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 73 #ifdef HAVE_LDAP 74 WCHAR *oidW = NULL; 75 LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL; 76 77 ret = WLDAP32_LDAP_NO_MEMORY; 78 79 TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_a(oid), data, serverctrls, 80 clientctrls, message ); 81 82 if (!ld || !message) return WLDAP32_LDAP_PARAM_ERROR; 83 84 if (oid) { 85 oidW = strAtoW( oid ); 86 if (!oidW) goto exit; 87 } 88 if (serverctrls) { 89 serverctrlsW = controlarrayAtoW( serverctrls ); 90 if (!serverctrlsW) goto exit; 91 } 92 if (clientctrls) { 93 clientctrlsW = controlarrayAtoW( clientctrls ); 94 if (!clientctrlsW) goto exit; 95 } 96 97 ret = ldap_extended_operationW( ld, oidW, data, serverctrlsW, clientctrlsW, message ); 98 99 exit: 100 strfreeW( oidW ); 101 controlarrayfreeW( serverctrlsW ); 102 controlarrayfreeW( clientctrlsW ); 103 104 #endif 105 return ret; 106 } 107 108 /*********************************************************************** 109 * ldap_extended_operationW (WLDAP32.@) 110 * 111 * Perform an extended operation (asynchronous mode). 112 * 113 * PARAMS 114 * ld [I] Pointer to an LDAP context. 115 * oid [I] OID of the extended operation. 116 * data [I] Data needed by the operation. 117 * serverctrls [I] Array of LDAP server controls. 118 * clientctrls [I] Array of LDAP client controls. 119 * message [O] Message ID of the extended operation. 120 * 121 * RETURNS 122 * Success: LDAP_SUCCESS 123 * Failure: An LDAP error code. 124 * 125 * NOTES 126 * The data parameter should be set to NULL if the operation 127 * requires no data. Call ldap_result with the message ID to 128 * get the result of the operation or ldap_abandon to cancel 129 * the operation. The serverctrls and clientctrls parameters 130 * are optional and should be set to NULL if not used. Call 131 * ldap_close_extended_op to close the operation. 132 */ 133 ULONG CDECL ldap_extended_operationW( WLDAP32_LDAP *ld, PWCHAR oid, struct WLDAP32_berval *data, 134 PLDAPControlW *serverctrls, PLDAPControlW *clientctrls, ULONG *message ) 135 { 136 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 137 #ifdef HAVE_LDAP 138 char *oidU = NULL; 139 LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL; 140 141 ret = WLDAP32_LDAP_NO_MEMORY; 142 143 TRACE( "(%p, %s, %p, %p, %p, %p)\n", ld, debugstr_w(oid), data, serverctrls, 144 clientctrls, message ); 145 146 if (!ld || !message) return WLDAP32_LDAP_PARAM_ERROR; 147 148 if (oid) { 149 oidU = strWtoU( oid ); 150 if (!oidU) goto exit; 151 } 152 if (serverctrls) { 153 serverctrlsU = controlarrayWtoU( serverctrls ); 154 if (!serverctrlsU) goto exit; 155 } 156 if (clientctrls) { 157 clientctrlsU = controlarrayWtoU( clientctrls ); 158 if (!clientctrlsU) goto exit; 159 } 160 161 ret = map_error( ldap_extended_operation( ld, oid ? oidU : "", (struct berval *)data, 162 serverctrlsU, clientctrlsU, (int *)message )); 163 164 exit: 165 strfreeU( oidU ); 166 controlarrayfreeU( serverctrlsU ); 167 controlarrayfreeU( clientctrlsU ); 168 169 #endif 170 return ret; 171 } 172 173 /*********************************************************************** 174 * ldap_extended_operation_sA (WLDAP32.@) 175 * 176 * See ldap_extended_operation_sW. 177 */ 178 ULONG CDECL ldap_extended_operation_sA( WLDAP32_LDAP *ld, PCHAR oid, struct WLDAP32_berval *data, 179 PLDAPControlA *serverctrls, PLDAPControlA *clientctrls, PCHAR *retoid, 180 struct WLDAP32_berval **retdata ) 181 { 182 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 183 #ifdef HAVE_LDAP 184 WCHAR *oidW = NULL, *retoidW = NULL; 185 LDAPControlW **serverctrlsW = NULL, **clientctrlsW = NULL; 186 187 ret = WLDAP32_LDAP_NO_MEMORY; 188 189 TRACE( "(%p, %s, %p, %p, %p, %p, %p)\n", ld, debugstr_a(oid), data, serverctrls, 190 clientctrls, retoid, retdata ); 191 192 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 193 194 if (oid) { 195 oidW = strAtoW( oid ); 196 if (!oidW) goto exit; 197 } 198 if (serverctrls) { 199 serverctrlsW = controlarrayAtoW( serverctrls ); 200 if (!serverctrlsW) goto exit; 201 } 202 if (clientctrls) { 203 clientctrlsW = controlarrayAtoW( clientctrls ); 204 if (!clientctrlsW) goto exit; 205 } 206 207 ret = ldap_extended_operation_sW( ld, oidW, data, serverctrlsW, clientctrlsW, 208 &retoidW, retdata ); 209 210 if (retoid && retoidW) { 211 *retoid = strWtoA( retoidW ); 212 if (!*retoid) ret = WLDAP32_LDAP_NO_MEMORY; 213 ldap_memfreeW( retoidW ); 214 } 215 216 exit: 217 strfreeW( oidW ); 218 controlarrayfreeW( serverctrlsW ); 219 controlarrayfreeW( clientctrlsW ); 220 221 #endif 222 return ret; 223 } 224 225 /*********************************************************************** 226 * ldap_extended_operation_sW (WLDAP32.@) 227 * 228 * Perform an extended operation (synchronous mode). 229 * 230 * PARAMS 231 * ld [I] Pointer to an LDAP context. 232 * oid [I] OID of the extended operation. 233 * data [I] Data needed by the operation. 234 * serverctrls [I] Array of LDAP server controls. 235 * clientctrls [I] Array of LDAP client controls. 236 * retoid [O] OID of the server response message. 237 * retdata [O] Data returned by the server. 238 * 239 * RETURNS 240 * Success: LDAP_SUCCESS 241 * Failure: An LDAP error code. 242 * 243 * NOTES 244 * The data parameter should be set to NULL if the operation 245 * requires no data. The serverctrls, clientctrls, retoid and 246 * and retdata parameters are also optional. Set to NULL if not 247 * used. Free retoid and retdata after use with ldap_memfree. 248 */ 249 ULONG CDECL ldap_extended_operation_sW( WLDAP32_LDAP *ld, PWCHAR oid, struct WLDAP32_berval *data, 250 PLDAPControlW *serverctrls, PLDAPControlW *clientctrls, PWCHAR *retoid, 251 struct WLDAP32_berval **retdata ) 252 { 253 ULONG ret = WLDAP32_LDAP_NOT_SUPPORTED; 254 #ifdef HAVE_LDAP 255 char *oidU = NULL, *retoidU = NULL; 256 LDAPControl **serverctrlsU = NULL, **clientctrlsU = NULL; 257 258 ret = WLDAP32_LDAP_NO_MEMORY; 259 260 TRACE( "(%p, %s, %p, %p, %p, %p, %p)\n", ld, debugstr_w(oid), data, serverctrls, 261 clientctrls, retoid, retdata ); 262 263 if (!ld) return WLDAP32_LDAP_PARAM_ERROR; 264 265 if (oid) { 266 oidU = strWtoU( oid ); 267 if (!oidU) goto exit; 268 } 269 if (serverctrls) { 270 serverctrlsU = controlarrayWtoU( serverctrls ); 271 if (!serverctrlsU) goto exit; 272 } 273 if (clientctrls) { 274 clientctrlsU = controlarrayWtoU( clientctrls ); 275 if (!clientctrlsU) goto exit; 276 } 277 278 ret = map_error( ldap_extended_operation_s( ld, oid ? oidU : "", (struct berval *)data, serverctrlsU, 279 clientctrlsU, &retoidU, (struct berval **)retdata )); 280 281 if (retoid && retoidU) { 282 *retoid = strUtoW( retoidU ); 283 if (!*retoid) ret = WLDAP32_LDAP_NO_MEMORY; 284 ldap_memfree( retoidU ); 285 } 286 287 exit: 288 strfreeU( oidU ); 289 controlarrayfreeU( serverctrlsU ); 290 controlarrayfreeU( clientctrlsU ); 291 292 #endif 293 return ret; 294 } 295