⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pldap.cxx

📁 sloedgy open sip stack source code
💻 CXX
📖 第 1 页 / 共 2 页
字号:
/*
 * pldap.cxx
 *
 * Lightweight Directory Access Protocol interface class.
 *
 * Portable Windows Library
 *
 * Copyright (c) 1993-2003 Equivalence Pty. Ltd.
 *
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 *
 * The Original Code is Portable Windows Library.
 *
 * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
 *
 * Contributor(s): ______________________________________.
 *
 * $Log: pldap.cxx,v $
 * Revision 1.2  2007/06/04 16:06:44  joegenbaclor
 * *** empty log message ***
 *
 * Revision 1.1  2006/06/29 04:18:03  joegenbaclor
 * *** empty log message ***
 *
 * Revision 1.20  2006/01/16 19:52:05  dsandras
 * Applied patch from Brian Lu <brian lu sun com> to allow compilation on
 * Solaris using SUN's LDAP. Thanks!!
 *
 * Revision 1.19  2005/09/18 13:01:43  dominance
 * fixed pragma warnings when building with gcc.
 *
 * Revision 1.18  2005/08/31 15:21:34  dominance
 * fix building with recent OpenLDAP
 *
 * Revision 1.17  2004/05/24 12:02:49  csoutheren
 * Add function to permit setting a limit on the number of results returned
 * from an LDAP query. Change the default number of results to unlimited,
 * rather than MAX_INT which apparently is clamped to some arbitrary low value.
 * Thanks to Damien Sandras
 *
 * Revision 1.16  2004/04/09 06:52:17  rjongbloed
 * Removed #pargma linker command for /delayload of DLL as documentations sais that
 *   you cannot do this.
 *
 * Revision 1.15  2004/02/23 23:52:19  csoutheren
 * Added pragmas to avoid every Windows application needing to include libs explicitly
 *
 * Revision 1.14  2004/02/04 09:37:00  rjongbloed
 * Fixed memory leak and race condition, thanks Rossano Ravelli
 *
 * Revision 1.13  2004/01/17 17:45:29  csoutheren
 * Changed to use PString::MakeEmpty
 *
 * Revision 1.12  2003/07/15 12:12:11  csoutheren
 * Added support for multiple values in a single attribute string
 *    Thanks to Ravelli Rossano
 *
 * Revision 1.11  2003/07/12 00:10:40  csoutheren
 * Fixed problem where Modify routines were calling Add, thanks to Ravelli Rossano
 *
 * Revision 1.10  2003/06/06 09:14:01  dsandras
 *
 * Test that a search result has been returned before calling ldapresult2error.
 *
 * Revision 1.9  2003/06/05 23:17:52  rjongbloed
 * Changed default operation timeout to 30 seconds.
 *
 * Revision 1.8  2003/06/05 05:29:30  rjongbloed
 * Fixed LDAP bind authentication methods, thanks Ravelli Rossano
 *
 * Revision 1.7  2003/04/17 08:34:48  robertj
 * Changed LDAP structure output so if field is empty it leaves it out
 *   altogether rather then encoding an empty string, some servers barf.
 *
 * Revision 1.6  2003/04/16 08:00:19  robertj
 * Windoes psuedo autoconf support
 *
 * Revision 1.5  2003/04/07 11:59:52  robertj
 * Fixed search function returning an error if can't find anything for filter.
 *
 * Revision 1.4  2003/04/01 07:05:16  robertj
 * Added ability to specify host:port in opening an LDAP server
 *
 * Revision 1.3  2003/03/31 03:32:53  robertj
 * Major addition of functionality.
 *
 */

#ifdef __GNUC__
#pragma implementation "pldap.h"
#endif

#include <ptlib.h>

#include <ptlib/sockets.h>
#include <ptclib/pldap.h>

////////////////////////////////////////////////
/// Get rid of LNK4221: no public symbols found; 
/// archive member will be inaccessible
const char * pldap_file_content = NULL;
////////////////////////////////////////////////

#if P_LDAP

#define LDAP_DEPRECATED 1
#include <ldap.h>


#if defined(_MSC_VER)
#pragma comment(lib, P_LDAP_LIBRARY)
#endif

///////////////////////////////////////////////////////////////////////////////

PLDAPSession::PLDAPSession(const PString & baseDN)
  : ldapContext(NULL),
    errorNumber(LDAP_SUCCESS),
    protocolVersion(LDAP_VERSION3),
    defaultBaseDN(baseDN),
    searchLimit(0),
    timeout(0, 30),
    multipleValueSeparator('\n')
{
}


PLDAPSession::~PLDAPSession()
{
  Close();
}


BOOL PLDAPSession::Open(const PString & server, WORD port)
{
  Close();

  PString host = server;
  PINDEX colon = server.Find(':');
  if (colon != P_MAX_INDEX) {
    host = server.Left(colon);
    port = PIPSocket::GetPortByService(server.Mid(colon+1), "tcp");
  }

  ldapContext = ldap_init(server, port);
  if (!IsOpen())
    return FALSE;

  SetOption(LDAP_OPT_PROTOCOL_VERSION, protocolVersion);
  return TRUE;
}


BOOL PLDAPSession::Close()
{
  if (!IsOpen())
    return FALSE;

  ldap_unbind(ldapContext);
  ldapContext = NULL;
  return TRUE;
}


BOOL PLDAPSession::SetOption(int optcode, int value)
{
  if (!IsOpen())
    return FALSE;

  return ldap_set_option(ldapContext, optcode, &value);
}


BOOL PLDAPSession::SetOption(int optcode, void * value)
{
  if (!IsOpen())
    return FALSE;

  return ldap_set_option(ldapContext, optcode, value);
}


BOOL PLDAPSession::Bind(const PString & who,
                        const PString & passwd,
                        AuthenticationMethod authMethod)
{
  if (!IsOpen())
    return FALSE;

  const char * whoPtr;
  if (who.IsEmpty())
    whoPtr = NULL;
  else
    whoPtr = who;

#ifdef SOLARIS
  static const int AuthMethodCode[NumAuthenticationMethod2] = {
    LDAP_AUTH_SIMPLE, LDAP_AUTH_SASL, LDAP_AUTH_KRBV41_30, LDAP_AUTH_KRBV42_30
#else
  static const int AuthMethodCode[NumAuthenticationMethod] = {
    LDAP_AUTH_SIMPLE, LDAP_AUTH_SASL, LDAP_AUTH_KRBV4
#endif
  };
  errorNumber = ldap_bind_s(ldapContext, whoPtr, passwd, AuthMethodCode[authMethod]);
  return errorNumber == LDAP_SUCCESS;
}


PLDAPSession::ModAttrib::ModAttrib(const PString & n, Operation o)
  : name(n),
    op(o)
{
}


void PLDAPSession::ModAttrib::SetLDAPMod(struct ldapmod & mod, Operation defaultOp)
{
  mod.mod_type = (char *)(const char *)name;

  Operation realOp = op == NumOperations ? defaultOp : op;
  static const int OpCode[NumOperations] = {
    LDAP_MOD_ADD, LDAP_MOD_REPLACE, LDAP_MOD_DELETE
  };
  mod.mod_op = OpCode[realOp];

  if (IsBinary())
    mod.mod_op |= LDAP_MOD_BVALUES;

  SetLDAPModVars(mod);
}


PLDAPSession::StringModAttrib::StringModAttrib(const PString & name,
                                               Operation op)
  : ModAttrib(name, op)
{
}


PLDAPSession::StringModAttrib::StringModAttrib(const PString & name,
                                               const PString & value,
                                               Operation op)
  : ModAttrib(name, op)
{
  AddValue(value);
}


PLDAPSession::StringModAttrib::StringModAttrib(const PString & name,
                                               const PStringList & vals,
                                               Operation op)
  : ModAttrib(name, op),
    values(vals)
{
}


void PLDAPSession::StringModAttrib::SetValue(const PString & value)
{
  values.RemoveAll();
  values.AppendString(value);
}


void PLDAPSession::StringModAttrib::AddValue(const PString & value)
{
  values.AppendString(value);
}


BOOL PLDAPSession::StringModAttrib::IsBinary() const
{
  return FALSE;
}


void PLDAPSession::StringModAttrib::SetLDAPModVars(struct ldapmod & mod)
{
  pointers.SetSize(values.GetSize()+1);
  PINDEX i;
  for (i = 0; i < values.GetSize(); i++)
    pointers[i] = values[i].GetPointer();
  pointers[i] = NULL;
  mod.mod_values = pointers.GetPointer();
}


PLDAPSession::BinaryModAttrib::BinaryModAttrib(const PString & name,
                                               Operation op)
  : ModAttrib(name, op)
{
}


PLDAPSession::BinaryModAttrib::BinaryModAttrib(const PString & name,
                                               const PBYTEArray & value,
                                               Operation op)
  : ModAttrib(name, op)
{
  AddValue(value);
}


PLDAPSession::BinaryModAttrib::BinaryModAttrib(const PString & name,
                                               const PList<PBYTEArray> & vals,
                                               Operation op)
  : ModAttrib(name, op),
    values(vals)
{
}


void PLDAPSession::BinaryModAttrib::SetValue(const PBYTEArray & value)
{
  values.RemoveAll();
  values.Append(new PBYTEArray(value));
}


void PLDAPSession::BinaryModAttrib::AddValue(const PBYTEArray & value)
{
  values.Append(new PBYTEArray(value));
}


BOOL PLDAPSession::BinaryModAttrib::IsBinary() const
{
  return TRUE;
}


void PLDAPSession::BinaryModAttrib::SetLDAPModVars(struct ldapmod & mod)
{
  pointers.SetSize(values.GetSize()+1);
  bervals.SetSize(values.GetSize()*sizeof(berval));
  berval * ber = (berval *)bervals.GetPointer();
  PINDEX i;
  for (i = 0; i < values.GetSize(); i++) {
    ber[i].bv_val = (char *)values[i].GetPointer();
    ber[i].bv_len = values[i].GetSize();
    pointers[i] = &ber[i];
  }
  pointers[i] = NULL;
  mod.mod_bvalues = pointers.GetPointer();
}


static LDAPMod ** CreateLDAPModArray(const PList<PLDAPSession::ModAttrib> & attributes,
                                     PLDAPSession::ModAttrib::Operation defaultOp,
                                     PBYTEArray & storage)
{
  PINDEX count = attributes.GetSize();
  storage.SetSize(count*sizeof(LDAPMod) + (count+1)*sizeof(LDAPMod *));

  LDAPMod ** attrs = (LDAPMod **)storage.GetPointer();
  LDAPMod *  attr  = (LDAPMod * )&attrs[count+1];
  for (PINDEX i = 0; i < count; i++) {
    attrs[i] = &attr[i];
    attributes[i].SetLDAPMod(attr[i], defaultOp);
  }

  return attrs;
}


static PList<PLDAPSession::ModAttrib> AttribsFromDict(const PStringToString & attributes)
{
  PList<PLDAPSession::ModAttrib> attrs;

  for (PINDEX i = 0; i < attributes.GetSize(); i++)
    attrs.Append(new PLDAPSession::StringModAttrib(attributes.GetKeyAt(i),
                                                   attributes.GetDataAt(i).Lines()));

  return attrs;
}


static PList<PLDAPSession::ModAttrib> AttribsFromArray(const PStringArray & attributes)
{
  PList<PLDAPSession::ModAttrib> attrs;

  for (PINDEX i = 0; i < attributes.GetSize(); i++) {
    PString attr = attributes[i];
    PINDEX equal = attr.Find('=');
    if (equal != P_MAX_INDEX)
      attrs.Append(new PLDAPSession::StringModAttrib(attr.Left(equal),
                                                     attr.Mid(equal+1).Lines()));
  }

  return attrs;
}


static PList<PLDAPSession::ModAttrib> AttribsFromStruct(const PLDAPStructBase & attributes)
{
  PList<PLDAPSession::ModAttrib> attrs;

  for (PINDEX i = 0; i < attributes.GetNumAttributes(); i++) {
    PLDAPAttributeBase & attr = attributes.GetAttribute(i);
    if (attr.IsBinary())
      attrs.Append(new PLDAPSession::BinaryModAttrib(attr.GetName(), attr.ToBinary()));
    else {
      PString str = attr.ToString();
      if (!str)
        attrs.Append(new PLDAPSession::StringModAttrib(attr.GetName(), str));
    }
  }

  return attrs;
}


BOOL PLDAPSession::Add(const PString & dn, const PList<ModAttrib> & attributes)
{
  if (!IsOpen())
    return FALSE;

  PBYTEArray storage;
  int msgid;
  errorNumber = ldap_add_ext(ldapContext,
                             dn,
                             CreateLDAPModArray(attributes, ModAttrib::Add, storage),
                             NULL,
                             NULL,
                             &msgid);
  if (errorNumber != LDAP_SUCCESS)
    return FALSE;

  P_timeval tval = timeout;
  LDAPMessage * result = NULL;
  ldap_result(ldapContext, msgid, LDAP_MSG_ALL, tval, &result);
  if (result)
    errorNumber = ldap_result2error(ldapContext, result, TRUE);

  return errorNumber == LDAP_SUCCESS;
}


BOOL PLDAPSession::Add(const PString & dn, const PStringToString & attributes)
{
  return Add(dn, AttribsFromDict(attributes));
}


BOOL PLDAPSession::Add(const PString & dn, const PStringArray & attributes)
{
  return Add(dn, AttribsFromArray(attributes));
}


BOOL PLDAPSession::Add(const PString & dn, const PLDAPStructBase & attributes)
{
  return Add(dn, AttribsFromStruct(attributes));
}


BOOL PLDAPSession::Modify(const PString & dn, const PList<ModAttrib> & attributes)
{
  if (!IsOpen())
    return FALSE;

  PBYTEArray storage;
  int msgid;
  errorNumber = ldap_modify_ext(ldapContext,
                                dn,
                                CreateLDAPModArray(attributes, ModAttrib::Replace, storage),
                                NULL,
                                NULL,
                                &msgid);
  if (errorNumber != LDAP_SUCCESS)
    return FALSE;

  P_timeval tval = timeout;
  LDAPMessage * result = NULL;
  ldap_result(ldapContext, msgid, LDAP_MSG_ALL, tval, &result);
  if (result)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -