/**************************************************************
 * 
 * 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
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the 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(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

