merge the formfield patch from ooo-build
[ooovba.git] / extensions / source / config / ldap / ldapaccess.cxx
blob41c5e4f822bdd73aeadb0b86b339e84275ad2254
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ldapaccess.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_extensions.hxx"
34 #include "ldapaccess.hxx"
36 #include "ldapuserprof.hxx"
37 #include <rtl/ustrbuf.hxx>
38 #include <rtl/strbuf.hxx>
41 namespace extensions { namespace config { namespace ldap {
43 oslModule LdapConnection::s_Ldap_Module = NULL;
44 t_ldap_unbind_s LdapConnection::s_p_unbind_s = NULL;
45 t_ldap_simple_bind_s LdapConnection::s_p_simple_bind_s = NULL;
46 t_ldap_set_option LdapConnection::s_p_set_option = NULL;
47 t_ldap_err2string LdapConnection::s_p_err2string = NULL;
48 t_ldap_init LdapConnection::s_p_init = NULL;
49 t_ldap_msgfree LdapConnection::s_p_msgfree = NULL;
50 t_ldap_get_dn LdapConnection::s_p_get_dn = NULL;
51 t_ldap_first_entry LdapConnection::s_p_first_entry = NULL;
52 t_ldap_search_s LdapConnection::s_p_search_s = NULL;
53 t_ldap_value_free LdapConnection::s_p_value_free = NULL;
54 t_ldap_get_values LdapConnection::s_p_get_values = NULL;
55 t_ldap_memfree LdapConnection::s_p_memfree = NULL;
56 //------------------------------------------------------------------------------
57 typedef int LdapErrCode;
58 //------------------------------------------------------------------------------
59 struct LdapMessageHolder
61 LdapMessageHolder() : msg(0) {}
62 ~LdapMessageHolder()
64 if (msg)
65 (*LdapConnection::s_p_msgfree)(msg);
68 LDAPMessage * msg;
70 private:
71 LdapMessageHolder(LdapMessageHolder const&);
72 void operator=(LdapMessageHolder const&);
74 //------------------------------------------------------------------------------
75 LdapConnection::~LdapConnection()
77 if (isValid()) disconnect();
79 //------------------------------------------------------------------------------
81 void LdapConnection::disconnect()
83 if (mConnection != NULL)
85 (*s_p_unbind_s)(mConnection) ;
86 mConnection = NULL;
89 //------------------------------------------------------------------------------
91 static void checkLdapReturnCode(const sal_Char *aOperation,
92 LdapErrCode aRetCode,
93 LDAP * /*aConnection*/)
95 if (aRetCode == LDAP_SUCCESS) { return ; }
97 static const sal_Char *kNoSpecificMessage = "No additional information" ;
98 rtl::OUStringBuffer message ;
100 if (aOperation != NULL)
102 message.appendAscii(aOperation).appendAscii(": ") ;
104 message.appendAscii((*LdapConnection::s_p_err2string)(aRetCode)).appendAscii(" (") ;
105 sal_Char *stub = NULL ;
107 #ifndef LDAP_OPT_SIZELIMIT // for use with OpenLDAP
108 (*s_p_get_lderrno)(aConnection, NULL, &stub) ;
109 #endif
110 if (stub != NULL)
112 message.appendAscii(stub) ;
113 // It would seem the message returned is actually
114 // not a copy of a string but rather some static
115 // string itself. At any rate freeing it seems to
116 // cause some undue problems at least on Windows.
117 // This call is thus disabled for the moment.
118 //(*s_p_memfree)(stub) ;
120 else { message.appendAscii(kNoSpecificMessage) ; }
121 message.appendAscii(")") ;
122 throw ldap::LdapGenericException(message.makeStringAndClear(),
123 NULL, aRetCode) ;
125 //------------------------------------------------------------------------------
126 void LdapConnection::connectSimple(const LdapDefinition& aDefinition)
127 throw (ldap::LdapConnectionException, ldap::LdapGenericException)
129 OSL_ENSURE(!isValid(), "Recoonecting an LDAP connection that is already established");
130 if (isValid()) disconnect();
132 mLdapDefinition = aDefinition;
133 connectSimple();
135 //------------------------------------------------------------------------------
136 void LdapConnection::connectSimple()
137 throw (ldap::LdapConnectionException, ldap::LdapGenericException)
139 if (!isValid())
141 // Connect to the server
142 initConnection() ;
143 // Set Protocol V3
144 int version = LDAP_VERSION3;
145 (*s_p_set_option)(mConnection,
146 LDAP_OPT_PROTOCOL_VERSION,
147 &version);
149 #ifdef LDAP_X_OPT_CONNECT_TIMEOUT // OpenLDAP doesn't support this and the func
150 /* timeout is specified in milliseconds -> 4 seconds*/
151 int timeout = 4000;
152 (*s_p_set_option)( mConnection,
153 LDAP_X_OPT_CONNECT_TIMEOUT,
154 &timeout );
155 #endif
157 // Do the bind
158 LdapErrCode retCode = (*s_p_simple_bind_s)(mConnection,
159 mLdapDefinition.mAnonUser ,
160 mLdapDefinition.mAnonCredentials) ;
162 checkLdapReturnCode("SimpleBind", retCode, mConnection) ;
165 //------------------------------------------------------------------------------
166 void LdapConnection::initConnection()
167 throw (ldap::LdapConnectionException)
169 if (mLdapDefinition.mServer.getLength() == 0)
171 rtl::OUStringBuffer message ;
173 message.appendAscii("Cannot initialise connection to LDAP: No server specified.") ;
174 throw ldap::LdapConnectionException(message.makeStringAndClear(), NULL) ;
177 if (mLdapDefinition.mPort == 0) mLdapDefinition.mPort = LDAP_PORT;
179 mConnection = (*s_p_init)(mLdapDefinition.mServer,
180 mLdapDefinition.mPort) ;
181 if (mConnection == NULL)
183 rtl::OUStringBuffer message ;
185 message.appendAscii("Cannot initialise connection to LDAP server ") ;
186 message.appendAscii(mLdapDefinition.mServer) ;
187 message.appendAscii(":") ;
188 message.append(mLdapDefinition.mPort) ;
189 throw ldap::LdapConnectionException(message.makeStringAndClear(),
190 NULL) ;
193 //------------------------------------------------------------------------------
194 void LdapConnection::getUserProfile(const rtl::OUString& aUser,
195 const LdapUserProfileMap& aUserProfileMap,
196 LdapUserProfile& aUserProfile)
197 throw (lang::IllegalArgumentException,
198 ldap::LdapConnectionException, ldap::LdapGenericException)
200 if (!isValid()) { connectSimple(); }
202 rtl::OString aUserDn =findUserDn( rtl::OUStringToOString(aUser, RTL_TEXTENCODING_ASCII_US));
204 LdapMessageHolder result;
205 LdapErrCode retCode = (*s_p_search_s)(mConnection,
206 aUserDn,
207 LDAP_SCOPE_BASE,
208 "(objectclass=*)",
209 const_cast<sal_Char **>(aUserProfileMap.getLdapAttributes()),
210 0, // Attributes + values
211 &result.msg) ;
213 checkLdapReturnCode("getUserProfile", retCode,mConnection) ;
216 aUserProfileMap.ldapToUserProfile(mConnection,
217 result.msg,
218 aUserProfile) ;
221 //------------------------------------------------------------------------------
222 rtl::OString LdapConnection::findUserDn(const rtl::OString& aUser)
223 throw (lang::IllegalArgumentException,
224 ldap::LdapConnectionException, ldap::LdapGenericException)
226 if (!isValid()) { connectSimple(); }
228 if (aUser.getLength() == 0)
230 throw lang::IllegalArgumentException(
231 rtl::OUString(RTL_CONSTASCII_USTRINGPARAM
232 ("LdapConnection::findUserDn -User id is empty")),
233 NULL, 0) ;
238 rtl::OStringBuffer filter( "(&(objectclass=" );
240 filter.append( mLdapDefinition.mUserObjectClass ).append(")(") ;
241 filter.append( mLdapDefinition.mUserUniqueAttr ).append("=").append(aUser).append("))") ;
243 LdapMessageHolder result;
244 sal_Char * attributes [2];
245 attributes[0]= const_cast<sal_Char *>(LDAP_NO_ATTRS);
246 attributes[1]= NULL;
247 LdapErrCode retCode = (*s_p_search_s)(mConnection,
248 mLdapDefinition.mBaseDN,
249 LDAP_SCOPE_SUBTREE,
250 filter.makeStringAndClear(), attributes, 0, &result.msg) ;
252 checkLdapReturnCode("FindUserDn", retCode,mConnection) ;
253 rtl::OString userDn ;
254 LDAPMessage *entry = (*s_p_first_entry)(mConnection, result.msg) ;
256 if (entry != NULL)
258 sal_Char *charsDn = (*s_p_get_dn)(mConnection, entry) ;
260 userDn = charsDn ;
261 (*s_p_memfree)(charsDn) ;
263 else
265 OSL_ENSURE( false, "LdapConnection::findUserDn-could not get DN for User ");
268 return userDn ;
270 //------------------------------------------------------------------------------
271 rtl::OString LdapConnection::getSingleAttribute(
272 const rtl::OString& aDn,
273 const rtl::OString& aAttribute)
274 throw (ldap::LdapConnectionException, ldap::LdapGenericException)
276 if (!isValid()) { connectSimple(); }
277 const sal_Char *attributes [2] ;
278 rtl::OString value ;
280 attributes [0] = aAttribute ;
281 attributes [1] = 0 ;
282 LdapMessageHolder result ;
283 LdapErrCode retCode = (*s_p_search_s)(mConnection,
284 aDn,
285 LDAP_SCOPE_BASE,
286 "(objectclass=*)",
287 const_cast<sal_Char **>(attributes),
288 0, // Attributes + values
289 &result.msg) ;
291 if (retCode == LDAP_NO_SUCH_OBJECT)
293 return value ;
295 checkLdapReturnCode("GetSingleAttribute", retCode, mConnection) ;
296 LDAPMessage *entry = (*s_p_first_entry)(mConnection, result.msg) ;
298 if (entry != NULL)
300 sal_Char **values = (*s_p_get_values)(mConnection, entry,
301 aAttribute) ;
303 if (values != NULL)
305 if (*values != NULL) { value = *values ; }
306 (*s_p_value_free)(values) ;
309 return value ;
312 extern "C" { static void SAL_CALL thisModule() {} }
313 void LdapConnection::loadModule()
315 if ( !s_Ldap_Module )
317 #if defined(WIN) || defined(WNT)
318 # define LIBLDAP "nsldap32v50.dll"
319 #else
320 # ifdef WITH_OPENLDAP
321 # define xstr(s) str(s)
322 # define str(s) #s
323 # define LIBLDAP "libldap-" xstr(LDAP_VENDOR_VERSION_MAJOR) "." xstr(LDAP_VENDOR_VERSION_MINOR) ".so." xstr(LDAP_VENDOR_VERSION_MAJOR)
324 # else
325 # define LIBLDAP "libldap50.so"
326 # endif
327 #endif
328 const ::rtl::OUString sModuleName(RTL_CONSTASCII_USTRINGPARAM(LIBLDAP));
330 // load the dbtools library
331 s_Ldap_Module = osl_loadModuleRelative(&thisModule, sModuleName.pData, 0);
332 if ( s_Ldap_Module != NULL )
334 s_p_unbind_s = (t_ldap_unbind_s)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_unbind_s").pData));
335 s_p_simple_bind_s = (t_ldap_simple_bind_s)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_simple_bind_s").pData));
336 s_p_set_option = (t_ldap_set_option)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_set_option").pData));
337 s_p_err2string = (t_ldap_err2string)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_err2string").pData));
338 s_p_init = (t_ldap_init)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_init").pData));
339 s_p_msgfree = (t_ldap_msgfree)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_msgfree").pData));
340 s_p_get_dn = (t_ldap_get_dn)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_get_dn").pData));
341 s_p_first_entry = (t_ldap_first_entry)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_first_entry").pData));
342 s_p_search_s = (t_ldap_search_s)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_search_s").pData));
343 s_p_value_free = (t_ldap_value_free)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_value_free").pData));
344 s_p_get_values = (t_ldap_get_values)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_get_values").pData));
345 s_p_memfree = (t_ldap_memfree)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_memfree").pData));
350 //------------------------------------------------------------------------------
351 } } } // extensions.config.ldap