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

Generated by: LCOV version 1.11