office-gobmx/extensions/source/config/ldap/ldapaccess.cxx
Luboš Luňák 1946794ae0 mass removal of rtl:: prefixes for O(U)String*
Modules sal, salhelper, cppu, cppuhelper, codemaker (selectively) and odk
have kept them, in order not to break external API (the automatic using declaration
is LO-internal).

Change-Id: I588fc9e0c45b914f824f91c0376980621d730f09
2013-04-07 14:23:11 +02:00

307 lines
11 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice:
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership. The ASF licenses this file to you under the Apache
* License, Version 2.0 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
#include "ldapaccess.hxx"
#include <rtl/ustrbuf.hxx>
#include <rtl/strbuf.hxx>
namespace extensions { namespace config { namespace ldap {
//------------------------------------------------------------------------------
typedef int LdapErrCode;
//------------------------------------------------------------------------------
struct LdapMessageHolder
{
LdapMessageHolder() : msg(0) {}
~LdapMessageHolder()
{
if (msg)
ldap_msgfree(msg);
}
LDAPMessage * msg;
private:
LdapMessageHolder(LdapMessageHolder const&);
void operator=(LdapMessageHolder const&);
};
//------------------------------------------------------------------------------
LdapConnection::~LdapConnection()
{
if (isValid()) disconnect();
}
//------------------------------------------------------------------------------
void LdapConnection::disconnect()
{
if (mConnection != NULL)
{
ldap_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" ;
OUStringBuffer message ;
if (aOperation != NULL)
{
message.appendAscii(aOperation).appendAscii(": ") ;
}
message.appendAscii(ldap_err2string(aRetCode)).appendAscii(" (") ;
sal_Char *stub = NULL ;
#ifndef LDAP_OPT_SIZELIMIT // for use with OpenLDAP
ldap_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.
//ldap_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;
ldap_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;
#ifdef WNT
ldap_set_optionW( mConnection,
LDAP_X_OPT_CONNECT_TIMEOUT,
&timeout );
#else
ldap_set_option( mConnection,
LDAP_X_OPT_CONNECT_TIMEOUT,
&timeout );
#endif
#endif
// Do the bind
#ifdef WNT
LdapErrCode retCode = ldap_simple_bind_sW(mConnection,
(PWCHAR) mLdapDefinition.mAnonUser.getStr(),
(PWCHAR) mLdapDefinition.mAnonCredentials.getStr() );
#else
LdapErrCode retCode = ldap_simple_bind_s(mConnection,
OUStringToOString( mLdapDefinition.mAnonUser, RTL_TEXTENCODING_UTF8 ).getStr(),
OUStringToOString( mLdapDefinition.mAnonCredentials, RTL_TEXTENCODING_UTF8 ).getStr()) ;
#endif
checkLdapReturnCode("SimpleBind", retCode, mConnection) ;
}
}
//------------------------------------------------------------------------------
void LdapConnection::initConnection()
throw (ldap::LdapConnectionException)
{
if (mLdapDefinition.mServer.isEmpty())
{
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;
#ifdef WNT
mConnection = ldap_initW((PWCHAR) mLdapDefinition.mServer.getStr(),
mLdapDefinition.mPort) ;
#else
mConnection = ldap_init(OUStringToOString( mLdapDefinition.mServer, RTL_TEXTENCODING_UTF8 ).getStr(),
mLdapDefinition.mPort) ;
#endif
if (mConnection == NULL)
{
OUStringBuffer message ;
message.appendAscii("Cannot initialise connection to LDAP server ") ;
message.append(mLdapDefinition.mServer) ;
message.appendAscii(":") ;
message.append(mLdapDefinition.mPort) ;
throw ldap::LdapConnectionException(message.makeStringAndClear(),
NULL) ;
}
}
//------------------------------------------------------------------------------
void LdapConnection::getUserProfile(
const OUString& aUser, LdapData * data)
throw (lang::IllegalArgumentException,
ldap::LdapConnectionException, ldap::LdapGenericException)
{
OSL_ASSERT(data != 0);
if (!isValid()) { connectSimple(); }
OUString aUserDn =findUserDn( aUser );
LdapMessageHolder result;
#ifdef WNT
LdapErrCode retCode = ldap_search_sW(mConnection,
(PWCHAR) aUserDn.getStr(),
LDAP_SCOPE_BASE,
const_cast<PWCHAR>( L"(objectclass=*)" ),
0,
0, // Attributes + values
&result.msg) ;
#else
LdapErrCode retCode = ldap_search_s(mConnection,
OUStringToOString( aUserDn, RTL_TEXTENCODING_UTF8 ).getStr(),
LDAP_SCOPE_BASE,
"(objectclass=*)",
0,
0, // Attributes + values
&result.msg) ;
#endif
checkLdapReturnCode("getUserProfile", retCode,mConnection) ;
BerElement * ptr;
#ifdef WNT
PWCHAR attr = ldap_first_attributeW(mConnection, result.msg, &ptr);
while (attr) {
PWCHAR * values = ldap_get_valuesW(mConnection, result.msg, attr);
if (values) {
const OUString aAttr( reinterpret_cast<sal_Unicode*>( attr ) );
const OUString aValues( reinterpret_cast<sal_Unicode*>( *values ) );
data->insert(
LdapData::value_type( aAttr, aValues ));
ldap_value_freeW(values);
}
attr = ldap_next_attributeW(mConnection, result.msg, ptr);
#else
char * attr = ldap_first_attribute(mConnection, result.msg, &ptr);
while (attr) {
char ** values = ldap_get_values(mConnection, result.msg, attr);
if (values) {
data->insert(
LdapData::value_type(
OStringToOUString(attr, RTL_TEXTENCODING_ASCII_US),
OStringToOUString(*values, RTL_TEXTENCODING_UTF8)));
ldap_value_free(values);
}
attr = ldap_next_attribute(mConnection, result.msg, ptr);
#endif
}
}
//------------------------------------------------------------------------------
OUString LdapConnection::findUserDn(const OUString& aUser)
throw (lang::IllegalArgumentException,
ldap::LdapConnectionException, ldap::LdapGenericException)
{
if (!isValid()) { connectSimple(); }
if (aUser.isEmpty())
{
throw lang::IllegalArgumentException(
OUString("LdapConnection::findUserDn -User id is empty"),
NULL, 0) ;
}
OUStringBuffer filter( "(&(objectclass=" );
filter.append( mLdapDefinition.mUserObjectClass ).append(")(") ;
filter.append( mLdapDefinition.mUserUniqueAttr ).append("=").append(aUser).append("))") ;
LdapMessageHolder result;
#ifdef WNT
PWCHAR attributes [2] = { const_cast<PWCHAR>( L"1.1" ), NULL };
LdapErrCode retCode = ldap_search_sW(mConnection,
(PWCHAR) mLdapDefinition.mBaseDN.getStr(),
LDAP_SCOPE_SUBTREE,
(PWCHAR) filter.makeStringAndClear().getStr(), attributes, 0, &result.msg) ;
#else
sal_Char * attributes [2] = { const_cast<sal_Char *>(LDAP_NO_ATTRS), NULL };
LdapErrCode retCode = ldap_search_s(mConnection,
OUStringToOString( mLdapDefinition.mBaseDN, RTL_TEXTENCODING_UTF8 ).getStr(),
LDAP_SCOPE_SUBTREE,
OUStringToOString( filter.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr(), attributes, 0, &result.msg) ;
#endif
checkLdapReturnCode("FindUserDn", retCode,mConnection) ;
OUString userDn ;
LDAPMessage *entry = ldap_first_entry(mConnection, result.msg) ;
if (entry != NULL)
{
#ifdef WNT
PWCHAR charsDn = ldap_get_dnW(mConnection, entry) ;
userDn = OUString( reinterpret_cast<const sal_Unicode*>( charsDn ) );
ldap_memfreeW(charsDn) ;
#else
sal_Char *charsDn = ldap_get_dn(mConnection, entry) ;
userDn = OStringToOUString( charsDn, RTL_TEXTENCODING_UTF8 );
ldap_memfree(charsDn) ;
#endif
}
else
{
OSL_FAIL( "LdapConnection::findUserDn-could not get DN for User ");
}
return userDn ;
}
//------------------------------------------------------------------------------
} } } // extensions.config.ldap
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */