LCOV - code coverage report
Current view: top level - extensions/source/config/ldap - ldapaccess.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 86 0.0 %
Date: 2014-04-14 Functions: 0 10 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "ldapaccess.hxx"
      22             : 
      23             : #include <rtl/ustrbuf.hxx>
      24             : #include <rtl/strbuf.hxx>
      25             : 
      26             : 
      27             : namespace extensions { namespace config { namespace ldap {
      28             : 
      29             : 
      30             : typedef int LdapErrCode;
      31             : 
      32             : struct LdapMessageHolder
      33             : {
      34           0 :     LdapMessageHolder() : msg(0) {}
      35           0 :     ~LdapMessageHolder()
      36             :     {
      37           0 :         if (msg)
      38           0 :             ldap_msgfree(msg);
      39           0 :     }
      40             : 
      41             :     LDAPMessage * msg;
      42             : 
      43             : private:
      44             :     LdapMessageHolder(LdapMessageHolder const&);
      45             :     void operator=(LdapMessageHolder const&);
      46             : };
      47             : 
      48           0 : LdapConnection::~LdapConnection()
      49             : {
      50           0 :     if (isValid()) disconnect();
      51           0 : }
      52             : 
      53             : 
      54           0 : void LdapConnection::disconnect()
      55             : {
      56           0 :     if (mConnection != NULL)
      57             :     {
      58           0 :         ldap_unbind_s(mConnection) ;
      59           0 :         mConnection = NULL;
      60             :     }
      61           0 : }
      62             : 
      63             : 
      64           0 : static void checkLdapReturnCode(const sal_Char *aOperation,
      65             :                                 LdapErrCode aRetCode,
      66             :                                 LDAP * /*aConnection*/)
      67             : {
      68           0 :     if (aRetCode == LDAP_SUCCESS) { return ; }
      69             : 
      70             :     static const sal_Char *kNoSpecificMessage = "No additional information" ;
      71           0 :     OUStringBuffer message ;
      72             : 
      73           0 :     if (aOperation != NULL)
      74             :     {
      75           0 :         message.appendAscii(aOperation).appendAscii(": ") ;
      76             :     }
      77           0 :     message.appendAscii(ldap_err2string(aRetCode)).appendAscii(" (") ;
      78           0 :     sal_Char *stub = NULL ;
      79             : 
      80             : #ifndef LDAP_OPT_SIZELIMIT // for use with OpenLDAP
      81             :     ldap_get_lderrno(aConnection, NULL, &stub) ;
      82             : #endif
      83           0 :     if (stub != NULL)
      84             :     {
      85           0 :         message.appendAscii(stub) ;
      86             :         // It would seem the message returned is actually
      87             :         // not a copy of a string but rather some static
      88             :         // string itself. At any rate freeing it seems to
      89             :         // cause some undue problems at least on Windows.
      90             :         // This call is thus disabled for the moment.
      91             :         //ldap_memfree(stub) ;
      92             :     }
      93           0 :     else { message.appendAscii(kNoSpecificMessage) ; }
      94           0 :     message.appendAscii(")") ;
      95             :     throw ldap::LdapGenericException(message.makeStringAndClear(),
      96           0 :                                      NULL, aRetCode) ;
      97             : }
      98             : 
      99           0 : void  LdapConnection::connectSimple(const LdapDefinition& aDefinition)
     100             :    throw (ldap::LdapConnectionException, ldap::LdapGenericException)
     101             : {
     102             :     OSL_ENSURE(!isValid(), "Recoonecting an LDAP connection that is already established");
     103           0 :     if (isValid()) disconnect();
     104             : 
     105           0 :     mLdapDefinition = aDefinition;
     106           0 :     connectSimple();
     107           0 : }
     108             : 
     109           0 : void  LdapConnection::connectSimple()
     110             :    throw (ldap::LdapConnectionException, ldap::LdapGenericException)
     111             : {
     112           0 :     if (!isValid())
     113             :     {
     114             :         // Connect to the server
     115           0 :         initConnection() ;
     116             :         // Set Protocol V3
     117           0 :         int version = LDAP_VERSION3;
     118             :         ldap_set_option(mConnection,
     119             :                         LDAP_OPT_PROTOCOL_VERSION,
     120           0 :                         &version);
     121             : 
     122             : #ifdef LDAP_X_OPT_CONNECT_TIMEOUT // OpenLDAP doesn't support this and the func
     123             :         /* timeout is specified in milliseconds -> 4 seconds*/
     124             :         int timeout = 4000;
     125             : #ifdef WNT
     126             :         ldap_set_optionW( mConnection,
     127             :                         LDAP_X_OPT_CONNECT_TIMEOUT,
     128             :                         &timeout );
     129             : #else
     130             :         ldap_set_option( mConnection,
     131             :                         LDAP_X_OPT_CONNECT_TIMEOUT,
     132             :                         &timeout );
     133             : #endif
     134             : #endif
     135             : 
     136             :         // Do the bind
     137             : #ifdef WNT
     138             :         LdapErrCode retCode = ldap_simple_bind_sW(mConnection,
     139             :                                                (PWCHAR) mLdapDefinition.mAnonUser.getStr(),
     140             :                                                (PWCHAR) mLdapDefinition.mAnonCredentials.getStr() );
     141             : #else
     142             :         LdapErrCode retCode = ldap_simple_bind_s(mConnection,
     143             :                                                OUStringToOString( mLdapDefinition.mAnonUser, RTL_TEXTENCODING_UTF8 ).getStr(),
     144           0 :                                                OUStringToOString( mLdapDefinition.mAnonCredentials, RTL_TEXTENCODING_UTF8 ).getStr()) ;
     145             : #endif
     146             : 
     147           0 :         checkLdapReturnCode("SimpleBind", retCode, mConnection) ;
     148             :     }
     149           0 : }
     150             : 
     151           0 : void LdapConnection::initConnection()
     152             :     throw (ldap::LdapConnectionException)
     153             : {
     154           0 :     if (mLdapDefinition.mServer.isEmpty())
     155             :     {
     156           0 :         OUStringBuffer message ;
     157             : 
     158           0 :         message.appendAscii("Cannot initialise connection to LDAP: No server specified.") ;
     159           0 :         throw ldap::LdapConnectionException(message.makeStringAndClear(), NULL) ;
     160             :     }
     161             : 
     162           0 :     if (mLdapDefinition.mPort == 0) mLdapDefinition.mPort = LDAP_PORT;
     163             : 
     164             : #ifdef WNT
     165             :     mConnection = ldap_initW((PWCHAR) mLdapDefinition.mServer.getStr(),
     166             :                             mLdapDefinition.mPort) ;
     167             : #else
     168             :     mConnection = ldap_init(OUStringToOString( mLdapDefinition.mServer, RTL_TEXTENCODING_UTF8 ).getStr(),
     169           0 :                             mLdapDefinition.mPort) ;
     170             : #endif
     171           0 :     if (mConnection == NULL)
     172             :     {
     173           0 :         OUStringBuffer message ;
     174             : 
     175           0 :         message.appendAscii("Cannot initialise connection to LDAP server ") ;
     176           0 :         message.append(mLdapDefinition.mServer) ;
     177           0 :         message.appendAscii(":") ;
     178           0 :         message.append(mLdapDefinition.mPort) ;
     179             :         throw ldap::LdapConnectionException(message.makeStringAndClear(),
     180           0 :                                             NULL) ;
     181             :     }
     182           0 : }
     183             : 
     184           0 :  void LdapConnection::getUserProfile(
     185             :      const OUString& aUser, LdapData * data)
     186             :     throw (lang::IllegalArgumentException,
     187             :             ldap::LdapConnectionException, ldap::LdapGenericException)
     188             : {
     189             :     OSL_ASSERT(data != 0);
     190           0 :     if (!isValid()) { connectSimple(); }
     191             : 
     192           0 :     OUString aUserDn =findUserDn( aUser );
     193             : 
     194           0 :     LdapMessageHolder result;
     195             : #ifdef WNT
     196             :     LdapErrCode retCode = ldap_search_sW(mConnection,
     197             :                                       (PWCHAR) aUserDn.getStr(),
     198             :                                       LDAP_SCOPE_BASE,
     199             :                                       const_cast<PWCHAR>( L"(objectclass=*)" ),
     200             :                                       0,
     201             :                                       0, // Attributes + values
     202             :                                       &result.msg) ;
     203             : #else
     204             :     LdapErrCode retCode = ldap_search_s(mConnection,
     205             :                                       OUStringToOString( aUserDn, RTL_TEXTENCODING_UTF8 ).getStr(),
     206             :                                       LDAP_SCOPE_BASE,
     207             :                                       "(objectclass=*)",
     208             :                                       0,
     209             :                                       0, // Attributes + values
     210           0 :                                       &result.msg) ;
     211             : #endif
     212           0 :     checkLdapReturnCode("getUserProfile", retCode,mConnection) ;
     213             : 
     214             :     BerElement * ptr;
     215             : #ifdef WNT
     216             :     PWCHAR attr = ldap_first_attributeW(mConnection, result.msg, &ptr);
     217             :     while (attr) {
     218             :         PWCHAR * values = ldap_get_valuesW(mConnection, result.msg, attr);
     219             :         if (values) {
     220             :             const OUString aAttr( reinterpret_cast<sal_Unicode*>( attr ) );
     221             :             const OUString aValues( reinterpret_cast<sal_Unicode*>( *values ) );
     222             :             data->insert(
     223             :                 LdapData::value_type( aAttr, aValues ));
     224             :             ldap_value_freeW(values);
     225             :         }
     226             :         attr = ldap_next_attributeW(mConnection, result.msg, ptr);
     227             : #else
     228           0 :     char * attr = ldap_first_attribute(mConnection, result.msg, &ptr);
     229           0 :     while (attr) {
     230           0 :         char ** values = ldap_get_values(mConnection, result.msg, attr);
     231           0 :         if (values) {
     232             :             data->insert(
     233             :                 LdapData::value_type(
     234             :                     OStringToOUString(attr, RTL_TEXTENCODING_ASCII_US),
     235           0 :                     OStringToOUString(*values, RTL_TEXTENCODING_UTF8)));
     236           0 :             ldap_value_free(values);
     237             :         }
     238           0 :         attr = ldap_next_attribute(mConnection, result.msg, ptr);
     239             : #endif
     240           0 :     }
     241           0 : }
     242             : 
     243           0 :  OUString LdapConnection::findUserDn(const OUString& aUser)
     244             :     throw (lang::IllegalArgumentException,
     245             :             ldap::LdapConnectionException, ldap::LdapGenericException)
     246             : {
     247           0 :     if (!isValid()) { connectSimple(); }
     248             : 
     249           0 :     if (aUser.isEmpty())
     250             :     {
     251             :         throw lang::IllegalArgumentException(
     252             :             OUString("LdapConnection::findUserDn -User id is empty"),
     253           0 :                 NULL, 0) ;
     254             :     }
     255             : 
     256             : 
     257             : 
     258           0 :     OUStringBuffer filter( "(&(objectclass=" );
     259             : 
     260           0 :     filter.append( mLdapDefinition.mUserObjectClass ).append(")(") ;
     261           0 :     filter.append( mLdapDefinition.mUserUniqueAttr ).append("=").append(aUser).append("))") ;
     262             : 
     263           0 :     LdapMessageHolder result;
     264             : #ifdef WNT
     265             :     PWCHAR attributes [2] = { const_cast<PWCHAR>( L"1.1" ), NULL };
     266             :     LdapErrCode retCode = ldap_search_sW(mConnection,
     267             :                                       (PWCHAR) mLdapDefinition.mBaseDN.getStr(),
     268             :                                       LDAP_SCOPE_SUBTREE,
     269             :                                       (PWCHAR) filter.makeStringAndClear().getStr(), attributes, 0, &result.msg) ;
     270             : #else
     271           0 :     sal_Char * attributes [2] = { const_cast<sal_Char *>(LDAP_NO_ATTRS), NULL };
     272             :     LdapErrCode retCode = ldap_search_s(mConnection,
     273             :                                       OUStringToOString( mLdapDefinition.mBaseDN, RTL_TEXTENCODING_UTF8 ).getStr(),
     274             :                                       LDAP_SCOPE_SUBTREE,
     275           0 :                                       OUStringToOString( filter.makeStringAndClear(), RTL_TEXTENCODING_UTF8 ).getStr(), attributes, 0, &result.msg) ;
     276             : #endif
     277           0 :     checkLdapReturnCode("FindUserDn", retCode,mConnection) ;
     278           0 :     OUString userDn ;
     279           0 :     LDAPMessage *entry = ldap_first_entry(mConnection, result.msg) ;
     280             : 
     281           0 :     if (entry != NULL)
     282             :     {
     283             : #ifdef WNT
     284             :         PWCHAR charsDn = ldap_get_dnW(mConnection, entry) ;
     285             : 
     286             :         userDn = OUString( reinterpret_cast<const sal_Unicode*>( charsDn ) );
     287             :         ldap_memfreeW(charsDn) ;
     288             : #else
     289           0 :         sal_Char *charsDn = ldap_get_dn(mConnection, entry) ;
     290             : 
     291           0 :         userDn = OStringToOUString( charsDn, RTL_TEXTENCODING_UTF8 );
     292           0 :         ldap_memfree(charsDn) ;
     293             : #endif
     294             :     }
     295             :     else
     296             :     {
     297             :         OSL_FAIL( "LdapConnection::findUserDn-could not get DN for User ");
     298             :     }
     299             : 
     300           0 :     return userDn ;
     301             : }
     302             : 
     303             : 
     304             : 
     305             : } } } // extensions.config.ldap
     306             : 
     307             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10