diff options
Diffstat (limited to 'extensions/source/config/ldap')
-rw-r--r-- | extensions/source/config/ldap/componentdef.cxx | 80 | ||||
-rw-r--r-- | extensions/source/config/ldap/exports.dxp | 3 | ||||
-rw-r--r-- | extensions/source/config/ldap/ldapaccess.cxx | 319 | ||||
-rw-r--r-- | extensions/source/config/ldap/ldapaccess.hxx | 168 | ||||
-rw-r--r-- | extensions/source/config/ldap/ldapuserprofilebe.cxx | 280 | ||||
-rw-r--r-- | extensions/source/config/ldap/ldapuserprofilebe.hxx | 158 | ||||
-rw-r--r-- | extensions/source/config/ldap/makefile.mk | 97 | ||||
-rw-r--r-- | extensions/source/config/ldap/wrapldapinclude.hxx | 50 |
8 files changed, 1155 insertions, 0 deletions
diff --git a/extensions/source/config/ldap/componentdef.cxx b/extensions/source/config/ldap/componentdef.cxx new file mode 100644 index 000000000000..0fd917d2ff9e --- /dev/null +++ b/extensions/source/config/ldap/componentdef.cxx @@ -0,0 +1,80 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "ldapuserprofilebe.hxx" +#include <cppuhelper/implementationentry.hxx> + +using namespace extensions::config::ldap ; + +//============================================================================== + +static uno::Reference<uno::XInterface> SAL_CALL createLdapUserProfileBe( + const uno::Reference<uno::XComponentContext>& aContext) { + return * new LdapUserProfileBe(aContext) ; +} +//------------------------------------------------------------------------------ + +static const cppu::ImplementationEntry kImplementations_entries[] = +{ + { + createLdapUserProfileBe, + LdapUserProfileBe::getLdapUserProfileBeName, + LdapUserProfileBe::getLdapUserProfileBeServiceNames, + cppu::createSingleComponentFactory, + NULL, + 0 + }, + { NULL, NULL, NULL, NULL, NULL, 0 } +} ; +//------------------------------------------------------------------------------ + +extern "C" void SAL_CALL component_getImplementationEnvironment( + const sal_Char **aEnvTypeName, + uno_Environment** /*aEnvironment*/) { + *aEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME ; +} +//------------------------------------------------------------------------------ + +extern "C" sal_Bool SAL_CALL component_writeInfo(void *aServiceManager, + void *aRegistryKey) { + return cppu::component_writeInfoHelper( + aServiceManager, aRegistryKey, kImplementations_entries); +} +//------------------------------------------------------------------------------ + +extern "C" void *component_getFactory(const sal_Char *aImplementationName, + void *aServiceManager, + void *aRegistryKey) { + return cppu::component_getFactoryHelper(aImplementationName, + aServiceManager, + aRegistryKey, + kImplementations_entries) ; +} +//------------------------------------------------------------------------------ diff --git a/extensions/source/config/ldap/exports.dxp b/extensions/source/config/ldap/exports.dxp new file mode 100644 index 000000000000..9630d7e06768 --- /dev/null +++ b/extensions/source/config/ldap/exports.dxp @@ -0,0 +1,3 @@ +component_getImplementationEnvironment +component_writeInfo +component_getFactory diff --git a/extensions/source/config/ldap/ldapaccess.cxx b/extensions/source/config/ldap/ldapaccess.cxx new file mode 100644 index 000000000000..c518dc37e94c --- /dev/null +++ b/extensions/source/config/ldap/ldapaccess.cxx @@ -0,0 +1,319 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "ldapaccess.hxx" + +#include <rtl/ustrbuf.hxx> +#include <rtl/strbuf.hxx> + + +namespace extensions { namespace config { namespace ldap { + +oslModule LdapConnection::s_Ldap_Module = NULL; +t_ldap_unbind_s LdapConnection::s_p_unbind_s = NULL; +t_ldap_simple_bind_s LdapConnection::s_p_simple_bind_s = NULL; +t_ldap_set_option LdapConnection::s_p_set_option = NULL; +t_ldap_err2string LdapConnection::s_p_err2string = NULL; +t_ldap_init LdapConnection::s_p_init = NULL; +t_ldap_msgfree LdapConnection::s_p_msgfree = NULL; +t_ldap_get_dn LdapConnection::s_p_get_dn = NULL; +t_ldap_first_entry LdapConnection::s_p_first_entry = NULL; +t_ldap_first_attribute LdapConnection::s_p_first_attribute = NULL; +t_ldap_next_attribute LdapConnection::s_p_next_attribute = NULL; +t_ldap_search_s LdapConnection::s_p_search_s = NULL; +t_ldap_value_free LdapConnection::s_p_value_free = NULL; +t_ldap_get_values LdapConnection::s_p_get_values = NULL; +t_ldap_memfree LdapConnection::s_p_memfree = NULL; +//------------------------------------------------------------------------------ +typedef int LdapErrCode; +//------------------------------------------------------------------------------ +struct LdapMessageHolder +{ + LdapMessageHolder() : msg(0) {} + ~LdapMessageHolder() + { + if (msg) + (*LdapConnection::s_p_msgfree)(msg); + } + + LDAPMessage * msg; + +private: + LdapMessageHolder(LdapMessageHolder const&); + void operator=(LdapMessageHolder const&); +}; +//------------------------------------------------------------------------------ +LdapConnection::~LdapConnection() +{ + if (isValid()) disconnect(); +} +//------------------------------------------------------------------------------ + +void LdapConnection::disconnect() +{ + if (mConnection != NULL) + { + (*s_p_unbind_s)(mConnection) ; + mConnection = NULL; + } +} +//------------------------------------------------------------------------------ + +static void checkLdapReturnCode(const sal_Char *aOperation, + LdapErrCode aRetCode, + LDAP * /*aConnection*/) +{ + if (aRetCode == LDAP_SUCCESS) { return ; } + + static const sal_Char *kNoSpecificMessage = "No additional information" ; + rtl::OUStringBuffer message ; + + if (aOperation != NULL) + { + message.appendAscii(aOperation).appendAscii(": ") ; + } + message.appendAscii((*LdapConnection::s_p_err2string)(aRetCode)).appendAscii(" (") ; + sal_Char *stub = NULL ; + +#ifndef LDAP_OPT_SIZELIMIT // for use with OpenLDAP + (*s_p_get_lderrno)(aConnection, NULL, &stub) ; +#endif + if (stub != NULL) + { + message.appendAscii(stub) ; + // It would seem the message returned is actually + // not a copy of a string but rather some static + // string itself. At any rate freeing it seems to + // cause some undue problems at least on Windows. + // This call is thus disabled for the moment. + //(*s_p_memfree)(stub) ; + } + else { message.appendAscii(kNoSpecificMessage) ; } + message.appendAscii(")") ; + throw ldap::LdapGenericException(message.makeStringAndClear(), + NULL, aRetCode) ; +} +//------------------------------------------------------------------------------ +void LdapConnection::connectSimple(const LdapDefinition& aDefinition) + throw (ldap::LdapConnectionException, ldap::LdapGenericException) +{ + OSL_ENSURE(!isValid(), "Recoonecting an LDAP connection that is already established"); + if (isValid()) disconnect(); + + mLdapDefinition = aDefinition; + connectSimple(); +} +//------------------------------------------------------------------------------ +void LdapConnection::connectSimple() + throw (ldap::LdapConnectionException, ldap::LdapGenericException) +{ + if (!isValid()) + { + // Connect to the server + initConnection() ; + // Set Protocol V3 + int version = LDAP_VERSION3; + (*s_p_set_option)(mConnection, + LDAP_OPT_PROTOCOL_VERSION, + &version); + +#ifdef LDAP_X_OPT_CONNECT_TIMEOUT // OpenLDAP doesn't support this and the func + /* timeout is specified in milliseconds -> 4 seconds*/ + int timeout = 4000; + (*s_p_set_option)( mConnection, + LDAP_X_OPT_CONNECT_TIMEOUT, + &timeout ); +#endif + + // Do the bind + LdapErrCode retCode = (*s_p_simple_bind_s)(mConnection, + mLdapDefinition.mAnonUser , + mLdapDefinition.mAnonCredentials) ; + + checkLdapReturnCode("SimpleBind", retCode, mConnection) ; + } +} +//------------------------------------------------------------------------------ +void LdapConnection::initConnection() + throw (ldap::LdapConnectionException) +{ + if (mLdapDefinition.mServer.getLength() == 0) + { + rtl::OUStringBuffer message ; + + message.appendAscii("Cannot initialise connection to LDAP: No server specified.") ; + throw ldap::LdapConnectionException(message.makeStringAndClear(), NULL) ; + } + + if (mLdapDefinition.mPort == 0) mLdapDefinition.mPort = LDAP_PORT; + + mConnection = (*s_p_init)(mLdapDefinition.mServer, + mLdapDefinition.mPort) ; + if (mConnection == NULL) + { + rtl::OUStringBuffer message ; + + message.appendAscii("Cannot initialise connection to LDAP server ") ; + message.appendAscii(mLdapDefinition.mServer) ; + message.appendAscii(":") ; + message.append(mLdapDefinition.mPort) ; + throw ldap::LdapConnectionException(message.makeStringAndClear(), + NULL) ; + } +} +//------------------------------------------------------------------------------ + void LdapConnection::getUserProfile( + const rtl::OUString& aUser, LdapData * data) + throw (lang::IllegalArgumentException, + ldap::LdapConnectionException, ldap::LdapGenericException) +{ + OSL_ASSERT(data != 0); + if (!isValid()) { connectSimple(); } + + rtl::OString aUserDn =findUserDn( rtl::OUStringToOString(aUser, RTL_TEXTENCODING_ASCII_US)); + + LdapMessageHolder result; + LdapErrCode retCode = (*s_p_search_s)(mConnection, + aUserDn, + LDAP_SCOPE_BASE, + "(objectclass=*)", + 0, + 0, // Attributes + values + &result.msg) ; + + checkLdapReturnCode("getUserProfile", retCode,mConnection) ; + + void * ptr; + char * attr = (*s_p_first_attribute)(mConnection, result.msg, &ptr); + while (attr != 0) { + char ** values = (*s_p_get_values)(mConnection, result.msg, attr); + if (values != 0) { + data->insert( + LdapData::value_type( + rtl::OStringToOUString(attr, RTL_TEXTENCODING_ASCII_US), + rtl::OStringToOUString(*values, RTL_TEXTENCODING_UTF8))); + (*s_p_value_free)(values); + } + attr = (*s_p_next_attribute)(mConnection, result.msg, ptr); + } +} +//------------------------------------------------------------------------------ + rtl::OString LdapConnection::findUserDn(const rtl::OString& aUser) + throw (lang::IllegalArgumentException, + ldap::LdapConnectionException, ldap::LdapGenericException) +{ + if (!isValid()) { connectSimple(); } + + if (aUser.getLength() == 0) + { + throw lang::IllegalArgumentException( + rtl::OUString(RTL_CONSTASCII_USTRINGPARAM + ("LdapConnection::findUserDn -User id is empty")), + NULL, 0) ; + } + + + + rtl::OStringBuffer filter( "(&(objectclass=" ); + + filter.append( mLdapDefinition.mUserObjectClass ).append(")(") ; + filter.append( mLdapDefinition.mUserUniqueAttr ).append("=").append(aUser).append("))") ; + + LdapMessageHolder result; + sal_Char * attributes [2]; + attributes[0]= const_cast<sal_Char *>(LDAP_NO_ATTRS); + attributes[1]= NULL; + LdapErrCode retCode = (*s_p_search_s)(mConnection, + mLdapDefinition.mBaseDN, + LDAP_SCOPE_SUBTREE, + filter.makeStringAndClear(), attributes, 0, &result.msg) ; + + checkLdapReturnCode("FindUserDn", retCode,mConnection) ; + rtl::OString userDn ; + LDAPMessage *entry = (*s_p_first_entry)(mConnection, result.msg) ; + + if (entry != NULL) + { + sal_Char *charsDn = (*s_p_get_dn)(mConnection, entry) ; + + userDn = charsDn ; + (*s_p_memfree)(charsDn) ; + } + else + { + OSL_ENSURE( false, "LdapConnection::findUserDn-could not get DN for User "); + } + + return userDn ; +} + +extern "C" { static void SAL_CALL thisModule() {} } +void LdapConnection::loadModule() +{ + if ( !s_Ldap_Module ) + { +#if defined(WIN) || defined(WNT) +# define LIBLDAP "nsldap32v50.dll" +#else +# ifdef WITH_OPENLDAP +# define xstr(s) str(s) +# define str(s) #s +# define LIBLDAP "libldap-" xstr(LDAP_VENDOR_VERSION_MAJOR) "." xstr(LDAP_VENDOR_VERSION_MINOR) ".so." xstr(LDAP_VENDOR_VERSION_MAJOR) +# else +# define LIBLDAP "libldap50.so" +# endif +#endif + const ::rtl::OUString sModuleName(RTL_CONSTASCII_USTRINGPARAM(LIBLDAP)); + + // load the dbtools library + s_Ldap_Module = osl_loadModuleRelative(&thisModule, sModuleName.pData, 0); + if ( s_Ldap_Module != NULL ) + { + s_p_unbind_s = (t_ldap_unbind_s)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_unbind_s").pData)); + s_p_simple_bind_s = (t_ldap_simple_bind_s)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_simple_bind_s").pData)); + s_p_set_option = (t_ldap_set_option)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_set_option").pData)); + s_p_err2string = (t_ldap_err2string)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_err2string").pData)); + s_p_init = (t_ldap_init)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_init").pData)); + s_p_msgfree = (t_ldap_msgfree)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_msgfree").pData)); + s_p_get_dn = (t_ldap_get_dn)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_get_dn").pData)); + s_p_first_entry = (t_ldap_first_entry)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_first_entry").pData)); + s_p_first_attribute = (t_ldap_first_attribute)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_first_attribute").pData)); + s_p_next_attribute = (t_ldap_next_attribute)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_next_attribute").pData)); + s_p_search_s = (t_ldap_search_s)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_search_s").pData)); + s_p_value_free = (t_ldap_value_free)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_value_free").pData)); + s_p_get_values = (t_ldap_get_values)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_get_values").pData)); + s_p_memfree = (t_ldap_memfree)(osl_getFunctionSymbol(s_Ldap_Module, ::rtl::OUString::createFromAscii("ldap_memfree").pData)); + } + } +} + +//------------------------------------------------------------------------------ +} } } // extensions.config.ldap + diff --git a/extensions/source/config/ldap/ldapaccess.hxx b/extensions/source/config/ldap/ldapaccess.hxx new file mode 100644 index 000000000000..b2ea7970952e --- /dev/null +++ b/extensions/source/config/ldap/ldapaccess.hxx @@ -0,0 +1,168 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef EXTENSIONS_CONFIG_LDAP_LDAPACCESS_HXX_ +#define EXTENSIONS_CONFIG_LDAP_LDAPACCESS_HXX_ + +#include "sal/config.h" + +#include <map> + +#include "wrapldapinclude.hxx" +#include <com/sun/star/ldap/LdapGenericException.hpp> + +#include <com/sun/star/ldap/LdapConnectionException.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <osl/module.h> + +namespace extensions { namespace config { namespace ldap { + +namespace css = com::sun::star ; +namespace uno = css::uno ; +namespace lang = css::lang ; +namespace ldap = css::ldap ; +//------------------------------------------------------------------------------ +// LdapUserProfile classes +struct LdapUserProfile; +class LdapUserProfileMap; + +typedef LDAP_API(int) (LDAP_CALL *t_ldap_unbind_s)( LDAP *ld ); +typedef LDAP_API(int) (LDAP_CALL *t_ldap_simple_bind_s)( LDAP *ld, const char *who, const char *passwd ); +typedef LDAP_API(int) (LDAP_CALL *t_ldap_set_option)( LDAP *ld, int option, const void *optdata ); +typedef LDAP_API(char *) (LDAP_CALL *t_ldap_err2string)( int err ); +typedef LDAP_API(LDAP *) (LDAP_CALL *t_ldap_init)( const char *defhost, int defport ); +typedef LDAP_API(int) (LDAP_CALL *t_ldap_msgfree)( LDAPMessage *lm ); +typedef LDAP_API(char *) (LDAP_CALL *t_ldap_get_dn)( LDAP *ld, LDAPMessage *entry ); +typedef LDAP_API(LDAPMessage *) (LDAP_CALL *t_ldap_first_entry)( LDAP *ld, LDAPMessage *chain ); +typedef LDAP_API(char *) (LDAP_CALL *t_ldap_first_attribute)( LDAP *ld, LDAPMessage *entry, void **ptr ); +typedef LDAP_API(char *) (LDAP_CALL *t_ldap_next_attribute)( LDAP *ld, LDAPMessage *entry, void *ptr ); +typedef LDAP_API(int) (LDAP_CALL *t_ldap_search_s)( LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPMessage **res ); +typedef LDAP_API(void) (LDAP_CALL *t_ldap_value_free)( char **vals ); +typedef LDAP_API(char **) (LDAP_CALL *t_ldap_get_values)( LDAP *ld, LDAPMessage *entry, const char *target ); +typedef LDAP_API(void) (LDAP_CALL *t_ldap_memfree)( void *p ); +//------------------------------------------------------------------------------ +/** Struct containing the information on LDAP connection */ +struct LdapDefinition +{ + /** LDAP server name */ + rtl::OString mServer ; + /** LDAP server port number */ + sal_Int32 mPort ; + /** Repository base DN */ + rtl::OString mBaseDN ; + /** DN to use for "anonymous" connection */ + rtl::OString mAnonUser ; + /** Credentials to use for "anonymous" connection */ + rtl::OString mAnonCredentials ; + /** User Entity Object Class */ + rtl::OString mUserObjectClass; + /** User Entity Unique Attribute */ + rtl::OString mUserUniqueAttr; + } ; + +typedef std::map< rtl::OUString, rtl::OUString > LdapData; // key/value pairs + +/** Class encapulating all LDAP functionality */ +class LdapConnection +{ + friend struct LdapMessageHolder; +public: + + /** Default constructor */ + LdapConnection(void) : mConnection(NULL),mLdapDefinition() {} + /** Destructor, releases the connection */ + ~LdapConnection(void) ; + /** Make connection to LDAP server */ + void connectSimple(const LdapDefinition& aDefinition) + throw (ldap::LdapConnectionException, + ldap::LdapGenericException); + + /** + Gets LdapUserProfile from LDAP repository for specified user + @param aUser name of logged on user + @param aUserProfileMap Map containing LDAP->00o mapping + @param aUserProfile struct for holding OOo values + + @throws com::sun::star::ldap::LdapGenericException + if an LDAP error occurs. + */ + void getUserProfile(const rtl::OUString& aUser, LdapData * data) + throw (lang::IllegalArgumentException, + ldap::LdapConnectionException, + ldap::LdapGenericException); + + /** finds DN of user + @return DN of User + */ + rtl::OString findUserDn(const rtl::OString& aUser) + throw (lang::IllegalArgumentException, + ldap::LdapConnectionException, + ldap::LdapGenericException); + + void loadModule(); + + static t_ldap_err2string s_p_err2string; +private: + + void initConnection() + throw (ldap::LdapConnectionException); + void disconnect(); + /** + Indicates whether the connection is in a valid state. + @return sal_True if connection is valid, sal_False otherwise + */ + bool isValid(void) const { return mConnection != NULL ; } + + void connectSimple() + throw (ldap::LdapConnectionException, + ldap::LdapGenericException); + + /** LDAP connection object */ + LDAP* mConnection ; + LdapDefinition mLdapDefinition; + + static oslModule s_Ldap_Module; + static t_ldap_value_free s_p_value_free; + static t_ldap_get_values s_p_get_values; + static t_ldap_unbind_s s_p_unbind_s; + static t_ldap_simple_bind_s s_p_simple_bind_s; + static t_ldap_set_option s_p_set_option; + static t_ldap_init s_p_init; + static t_ldap_msgfree s_p_msgfree; + static t_ldap_get_dn s_p_get_dn; + static t_ldap_first_entry s_p_first_entry; + static t_ldap_first_attribute s_p_first_attribute; + static t_ldap_next_attribute s_p_next_attribute; + static t_ldap_search_s s_p_search_s; + + static t_ldap_memfree s_p_memfree; + +} ; +//------------------------------------------------------------------------------ +}} } + +#endif // EXTENSIONS_CONFIG_LDAP_LDAPUSERPROFILE_HXX_ diff --git a/extensions/source/config/ldap/ldapuserprofilebe.cxx b/extensions/source/config/ldap/ldapuserprofilebe.cxx new file mode 100644 index 000000000000..5826188c564d --- /dev/null +++ b/extensions/source/config/ldap/ldapuserprofilebe.cxx @@ -0,0 +1,280 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_extensions.hxx" + +#include "ldapaccess.hxx" +#include "ldapuserprofilebe.hxx" +#include <osl/file.hxx> +#include <osl/module.hxx> +#include <osl/process.h> +#include <rtl/ustrbuf.hxx> +#include <rtl/byteseq.h> + +#ifndef INCLUDED_RTL_INSTANCE_HXX_ +#include <rtl/instance.hxx> +#endif +#include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/Optional.hpp> +#include <osl/security.hxx> + +//============================================================================== +namespace extensions { namespace config { namespace ldap { + +LdapUserProfileBe::LdapUserProfileBe( const uno::Reference<uno::XComponentContext>& xContext) +: LdapProfileMutexHolder(), + BackendBase(mMutex) +{ + LdapDefinition aDefinition; + rtl::OUString loggedOnUser; + + // This whole rigmarole is to prevent an infinite recursion where reading + // the configuration for the backend would create another instance of the + // backend, which would try and read the configuration which would... + { + osl::Mutex & aInitMutex = rtl::Static< osl::Mutex, LdapUserProfileBe >::get(); + osl::MutexGuard aInitGuard(aInitMutex); + + static bool bReentrantCall; // = false + OSL_ENSURE(!bReentrantCall, "configuration: Ldap Backend constructor called reentrantly - probably a registration error."); + + if (!bReentrantCall) + { + try + { + bReentrantCall = true ; + if (!readLdapConfiguration( + css::uno::Reference< css::lang::XMultiServiceFactory >( + xContext->getServiceManager(), + css::uno::UNO_QUERY_THROW), + &aDefinition, &loggedOnUser)) + { + throw css::uno::RuntimeException( + rtl::OUString::createFromAscii("LdapUserProfileBe- LDAP not configured"), + NULL); + } + + bReentrantCall = false ; + } + catch (...) + { + bReentrantCall = false; + throw; + } + } + } + + LdapConnection connection; + connection.loadModule(); + connection.connectSimple(aDefinition); + connection.getUserProfile(loggedOnUser, &data_); +} +//------------------------------------------------------------------------------ +LdapUserProfileBe::~LdapUserProfileBe() +{ +} +//------------------------------------------------------------------------------ + +bool LdapUserProfileBe::readLdapConfiguration( + css::uno::Reference< css::lang::XMultiServiceFactory > const & factory, + LdapDefinition * definition, rtl::OUString * loggedOnUser) +{ + OSL_ASSERT(factory.is() && definition != 0 && loggedOnUser != 0); + const rtl::OUString kConfigurationProviderService( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationProvider")) ; + const rtl::OUString kReadOnlyViewService( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.ConfigurationAccess")) ; + const rtl::OUString kComponent( RTL_CONSTASCII_USTRINGPARAM("org.openoffice.LDAP/UserDirectory")); + const rtl::OUString kServerDefiniton(RTL_CONSTASCII_USTRINGPARAM ("ServerDefinition")); + const rtl::OUString kServer(RTL_CONSTASCII_USTRINGPARAM ("Server")); + const rtl::OUString kPort(RTL_CONSTASCII_USTRINGPARAM("Port")); + const rtl::OUString kBaseDN(RTL_CONSTASCII_USTRINGPARAM("BaseDN")); + const rtl::OUString kUser(RTL_CONSTASCII_USTRINGPARAM("SearchUser")); + const rtl::OUString kPassword(RTL_CONSTASCII_USTRINGPARAM("SearchPassword")); + const rtl::OUString kUserObjectClass(RTL_CONSTASCII_USTRINGPARAM("UserObjectClass")); + const rtl::OUString kUserUniqueAttr(RTL_CONSTASCII_USTRINGPARAM("UserUniqueAttribute")); + + uno::Reference< XInterface > xIface; + try + { + uno::Reference< lang::XMultiServiceFactory > xCfgProvider( + factory->createInstance(kConfigurationProviderService), + uno::UNO_QUERY); + OSL_ENSURE(xCfgProvider.is(),"LdapUserProfileBe: could not create the configuration provider"); + if (!xCfgProvider.is()) + return false; + + css::beans::NamedValue aPath(rtl::OUString::createFromAscii("nodepath"), uno::makeAny(kComponent) ); + + uno::Sequence< uno::Any > aArgs(1); + aArgs[0] <<= aPath; + + xIface = xCfgProvider->createInstanceWithArguments(kReadOnlyViewService, aArgs); + + uno::Reference<container::XNameAccess > xAccess(xIface, uno::UNO_QUERY_THROW); + xAccess->getByName(kServerDefiniton) >>= xIface; + + uno::Reference<container::XNameAccess > xChildAccess(xIface, uno::UNO_QUERY_THROW); + + if (!getLdapStringParam(xChildAccess, kServer, definition->mServer)) + return false; + if (!getLdapStringParam(xChildAccess, kBaseDN, definition->mBaseDN)) + return false; + + definition->mPort=0; + xChildAccess->getByName(kPort) >>= definition->mPort ; + if (definition->mPort == 0) + return false; + + if (!getLdapStringParam(xAccess, kUserObjectClass, definition->mUserObjectClass)) + return false; + if (!getLdapStringParam(xAccess, kUserUniqueAttr, definition->mUserUniqueAttr)) + return false; + + getLdapStringParam(xAccess, kUser, definition->mAnonUser); + getLdapStringParam(xAccess, kPassword, definition->mAnonCredentials); + } + catch (uno::Exception & e) + { + OSL_TRACE("LdapUserProfileBackend: access to configuration data failed: %s", + rtl::OUStringToOString( e.Message, RTL_TEXTENCODING_ASCII_US ).getStr() ); + return false; + } + + osl::Security aSecurityContext; + if (!aSecurityContext.getUserName(*loggedOnUser)) + OSL_TRACE("LdapUserProfileBackend - could not get Logged on user from system"); + + sal_Int32 nIndex = loggedOnUser->indexOf('/'); + if (nIndex > 0) + *loggedOnUser = loggedOnUser->copy(nIndex+1); + + //Remember to remove + OSL_TRACE("Logged on user is %s", rtl::OUStringToOString(*loggedOnUser,RTL_TEXTENCODING_ASCII_US).getStr()); + + return true; +} + +//------------------------------------------------------------------------------ +bool LdapUserProfileBe::getLdapStringParam( + uno::Reference<container::XNameAccess>& xAccess, + const rtl::OUString& aLdapSetting, + rtl::OString& aServerParameter) +{ + rtl::OUString sParam; + xAccess->getByName(aLdapSetting) >>= sParam; + aServerParameter = rtl::OUStringToOString(sParam, RTL_TEXTENCODING_ASCII_US); + + return aServerParameter.getLength() != 0; +} +//------------------------------------------------------------------------------ +void LdapUserProfileBe::setPropertyValue( + rtl::OUString const &, css::uno::Any const &) + throw ( + css::beans::UnknownPropertyException, css::beans::PropertyVetoException, + css::lang::IllegalArgumentException, css::lang::WrappedTargetException, + css::uno::RuntimeException) +{ + throw css::lang::IllegalArgumentException( + rtl::OUString( + RTL_CONSTASCII_USTRINGPARAM("setPropertyValue not supported")), + static_cast< cppu::OWeakObject * >(this), -1); +} + +css::uno::Any LdapUserProfileBe::getPropertyValue( + rtl::OUString const & PropertyName) + throw ( + css::beans::UnknownPropertyException, css::lang::WrappedTargetException, + css::uno::RuntimeException) +{ + for (sal_Int32 i = 0;;) { + sal_Int32 j = PropertyName.indexOf(',', i); + if (j == -1) { + j = PropertyName.getLength(); + } + if (j == i) { + throw css::beans::UnknownPropertyException( + PropertyName, static_cast< cppu::OWeakObject * >(this)); + } + LdapData::iterator k(data_.find(PropertyName.copy(i, j - i))); + if (k != data_.end()) { + return css::uno::makeAny( + css::beans::Optional< css::uno::Any >( + true, css::uno::makeAny(k->second))); + } + if (j == PropertyName.getLength()) { + break; + } + i = j + 1; + } + return css::uno::makeAny(css::beans::Optional< css::uno::Any >()); +} + +//------------------------------------------------------------------------------ +rtl::OUString SAL_CALL LdapUserProfileBe::getLdapUserProfileBeName(void) { + return rtl::OUString::createFromAscii("com.sun.star.comp.configuration.backend.LdapUserProfileBe") ; +} +//------------------------------------------------------------------------------ + +rtl::OUString SAL_CALL LdapUserProfileBe::getImplementationName(void) + throw (uno::RuntimeException) +{ + return getLdapUserProfileBeName() ; +} +//------------------------------------------------------------------------------ + +uno::Sequence<rtl::OUString> SAL_CALL LdapUserProfileBe::getLdapUserProfileBeServiceNames(void) +{ + uno::Sequence<rtl::OUString> aServices(1) ; + aServices[0] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.backend.LdapUserProfileBe")) ; + return aServices ; +} +//------------------------------------------------------------------------------ + +sal_Bool SAL_CALL LdapUserProfileBe::supportsService(const rtl::OUString& aServiceName) + throw (uno::RuntimeException) +{ + uno::Sequence< rtl::OUString > const svc = getLdapUserProfileBeServiceNames(); + + for(sal_Int32 i = 0; i < svc.getLength(); ++i ) + if(svc[i] == aServiceName) + return true; + return false; +} + +//------------------------------------------------------------------------------ + +uno::Sequence<rtl::OUString> +SAL_CALL LdapUserProfileBe::getSupportedServiceNames(void) + throw (uno::RuntimeException) +{ + return getLdapUserProfileBeServiceNames() ; +} +// --------------------------------------------------------------------------------------- +}}} +// --------------------------------------------------------------------------------------- + + diff --git a/extensions/source/config/ldap/ldapuserprofilebe.hxx b/extensions/source/config/ldap/ldapuserprofilebe.hxx new file mode 100644 index 000000000000..f19e9e275a55 --- /dev/null +++ b/extensions/source/config/ldap/ldapuserprofilebe.hxx @@ -0,0 +1,158 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef EXTENSIONS_CONFIG_LDAP_LDAPUSERPROFILEBE_HXX_ +#define EXTENSIONS_CONFIG_LDAP_LDAPUSERPROFILEBE_HXX_ + +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/lang/IllegalArgumentException.hpp> +#include <cppuhelper/compbase2.hxx> + +#include "ldapaccess.hxx" + +namespace extensions { namespace config { namespace ldap { + +namespace css = com::sun::star ; +namespace uno = css::uno ; +namespace lang = css::lang ; +namespace container = css::container; + +struct LdapDefinition; + +typedef cppu::WeakComponentImplHelper2<css::beans::XPropertySet, + lang::XServiceInfo> BackendBase ; + +struct LdapProfileMutexHolder { osl::Mutex mMutex; }; +/** + Implements the PlatformBackend service, a specialization of the + XPropertySet service for retreiving LDAP user profile + configuration settings from a LDAP repsoitory. + */ +class LdapUserProfileBe : private LdapProfileMutexHolder, public BackendBase +{ + public : + + LdapUserProfileBe(const uno::Reference<uno::XComponentContext>& xContext); + ~LdapUserProfileBe(void) ; + + // XServiceInfo + virtual rtl::OUString SAL_CALL + getImplementationName( ) + throw (uno::RuntimeException) ; + + virtual sal_Bool SAL_CALL + supportsService( const rtl::OUString& aServiceName ) + throw (uno::RuntimeException) ; + + virtual uno::Sequence<rtl::OUString> SAL_CALL + getSupportedServiceNames( ) + throw (uno::RuntimeException) ; + + // XPropertySet + virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL + getPropertySetInfo() throw (css::uno::RuntimeException) + { return css::uno::Reference< css::beans::XPropertySetInfo >(); } + + virtual void SAL_CALL setPropertyValue( + rtl::OUString const &, css::uno::Any const &) + throw ( + css::beans::UnknownPropertyException, + css::beans::PropertyVetoException, + css::lang::IllegalArgumentException, + css::lang::WrappedTargetException, css::uno::RuntimeException); + + virtual css::uno::Any SAL_CALL getPropertyValue( + rtl::OUString const & PropertyName) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException); + + virtual void SAL_CALL addPropertyChangeListener( + rtl::OUString const &, + css::uno::Reference< css::beans::XPropertyChangeListener > const &) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException) + {} + + virtual void SAL_CALL removePropertyChangeListener( + rtl::OUString const &, + css::uno::Reference< css::beans::XPropertyChangeListener > const &) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException) + {} + + virtual void SAL_CALL addVetoableChangeListener( + rtl::OUString const &, + css::uno::Reference< css::beans::XVetoableChangeListener > const &) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException) + {} + + virtual void SAL_CALL removeVetoableChangeListener( + rtl::OUString const &, + css::uno::Reference< css::beans::XVetoableChangeListener > const &) + throw ( + css::beans::UnknownPropertyException, + css::lang::WrappedTargetException, css::uno::RuntimeException) + {} + + /** + Provides the implementation name. + @return implementation name + */ + static rtl::OUString SAL_CALL getLdapUserProfileBeName(void) ; + /** + Provides the supported services names + @return service names + */ + static uno::Sequence<rtl::OUString> SAL_CALL + getLdapUserProfileBeServiceNames(void) ; + + private: + /** Check if LDAP is configured */ + bool readLdapConfiguration( + uno::Reference<lang::XMultiServiceFactory> const & factory, + LdapDefinition * definition, rtl::OUString * loggedOnUser); + + bool getLdapStringParam(uno::Reference<container::XNameAccess>& xAccess, + const rtl::OUString& aLdapSetting, + rtl::OString& aServerParameter); + + LdapData data_; +} ; +//------------------------------------------------------------------------------ +}}} + +#endif // EXTENSIONS_CONFIG_LDAP_LDAPUSERPROFILE_HXX_ diff --git a/extensions/source/config/ldap/makefile.mk b/extensions/source/config/ldap/makefile.mk new file mode 100644 index 000000000000..a27cb39b6225 --- /dev/null +++ b/extensions/source/config/ldap/makefile.mk @@ -0,0 +1,97 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. + +PRJNAME=extensions +TARGET=ldapbe +ENABLE_EXCEPTIONS=TRUE + +# Version +LDAP_MAJOR=2 + +# --- Settings --- + +.INCLUDE : settings.mk +DLLPRE = + +.IF "$(WITH_LDAP)" != "YES" +@all: + @echo "LDAP disabled." +.ENDIF + +.IF "$(LDAPSDKINCLUDES)" == "" + +.IF "$(SYSTEM_MOZILLA)" == "YES" && "$(WITH_OPENLDAP)" != "YES" +LDAPSDKINCLUDES = $(MOZ_LDAP_CFLAGS) +.ELSE +LDAPSDKINCLUDES = -I$(SOLARINCDIR)$/mozilla +.ENDIF +.ENDIF + +.IF "$(WITH_OPENLDAP)" == "YES" +CFLAGS += -DWITH_OPENLDAP -DLDAP_DEPRECATED +.ENDIF + +SOLARINC+= $(LDAPSDKINCLUDES) +# --- Files --- + + +SLOFILES=\ + $(SLO)$/ldapuserprofilebe.obj \ + $(SLO)$/ldapaccess.obj \ + $(SLO)$/componentdef.obj + +LIB1TARGET=$(SLB)$/_$(TARGET).lib +LIB1OBJFILES=$(SLOFILES) + +SHL1TARGET=$(TARGET)$(LDAP_MAJOR).uno +SHL1DEF=$(MISC)$/$(SHL1TARGET).def +SHL1LIBS=$(LIB1TARGET) +SHL1IMPLIB=i$(SHL1TARGET) +SHL1STDLIBS= \ + $(CPPUHELPERLIB) \ + $(CPPULIB) \ + $(SALHELPERLIB) \ + $(SALLIB) +.IF "$(OS)"=="FREEBSD" +SHL1STDLIBS+=-lcompat +# workaround for FreeBSD, which needs -llber50, too +.IF "$(WITH_OPENLDAP)" != "YES" +SHL1STDLIBS+=-Wl,-Bstatic -llber50 +.ENDIF +.ENDIF + +DEF1NAME=$(SHL1TARGET) +DEF1EXPORTFILE=exports.dxp +DEF1DES=Configuration: LDAP User Profile Backend + +# --- Targets --- + +.INCLUDE : target.mk +.INCLUDE : $(PRJ)$/util$/target.pmk + diff --git a/extensions/source/config/ldap/wrapldapinclude.hxx b/extensions/source/config/ldap/wrapldapinclude.hxx new file mode 100644 index 000000000000..80ae2e430dd9 --- /dev/null +++ b/extensions/source/config/ldap/wrapldapinclude.hxx @@ -0,0 +1,50 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifdef WNT +#pragma warning (push,1) +#pragma warning (disable:4668) +#endif + +#ifdef WITH_OPENLDAP +#include <ldap.h> +#ifndef LDAP_API +# define LDAP_API(rt) rt +#endif +#ifndef LDAP_CALL +# define LDAP_CALL +#endif +#else +#ifndef LDAP_INCLUDED +#define LDAP_INCLUDED +#include <ldap/ldap.h> +#endif // LDAP_INCLUDED +#endif + +#ifdef WNT +#pragma warning (pop) +#endif // WNT |