Back to index

nordugrid-arc-nox  1.1.0~rc6
Public Member Functions | Private Member Functions | Private Attributes | Static Private Attributes | Friends
Arc::LDAPQuery Class Reference

LDAPQuery class; querying of LDAP servers. More...

#include <LDAPQuery.h>

Collaboration diagram for Arc::LDAPQuery:
Collaboration graph
[legend]

List of all members.

Public Member Functions

 LDAPQuery (const std::string &ldaphost, int ldapport, int timeout, bool anonymous=true, const std::string &usersn="")
 Constructs a new LDAPQuery object and sets connection options.
 ~LDAPQuery ()
 Destructor.
bool Query (const std::string &base, const std::string &filter="(objectclass=*)", const std::list< std::string > &attributes=std::list< std::string >(), URL::Scope scope=URL::subtree)
 Queries the ldap server.
bool Result (ldap_callback callback, void *ref)
 Retrieves the result of the query from the ldap-server.

Private Member Functions

bool Connect ()
bool SetConnectionOptions (int version)
bool HandleResult (ldap_callback callback, void *ref)
void HandleSearchEntry (LDAPMessage *msg, ldap_callback callback, void *ref)

Private Attributes

std::string host
int port
bool anonymous
std::string usersn
int timeout
ldap * connection
int messageid

Static Private Attributes

static Logger logger

Friends

int my_sasl_interact (ldap *, unsigned int, void *, void *)

Detailed Description

LDAPQuery class; querying of LDAP servers.

Definition at line 36 of file LDAPQuery.h.


Constructor & Destructor Documentation

Arc::LDAPQuery::LDAPQuery ( const std::string &  ldaphost,
int  ldapport,
int  timeout,
bool  anonymous = true,
const std::string &  usersn = "" 
)

Constructs a new LDAPQuery object and sets connection options.

The connection is first established when calling Query.

Definition at line 268 of file LDAPQuery.cpp.

    : host(ldaphost),
      port(ldapport),
      anonymous(anonymous),
      usersn(usersn),
      timeout(timeout),
      connection(NULL),
      messageid(0) {}

Destructor.

Will disconnect from the ldapserver if still connected.

Definition at line 282 of file LDAPQuery.cpp.

                        {

    if (connection) {
      ldap_unbind_ext(connection, NULL, NULL);
      connection = NULL;
    }
  }

Member Function Documentation

bool Arc::LDAPQuery::Connect ( ) [private]

Definition at line 300 of file LDAPQuery.cpp.

                          {

    const int version = LDAP_VERSION3;

    logger.msg(VERBOSE, "LDAPQuery: Initializing connection to %s:%d",
               host, port);

    if (connection) {
      logger.msg(ERROR, "LDAP connection already open to %s", host);
      return false;
    }

    ldap_lock()->lock();
#ifdef HAVE_LDAP_INITIALIZE
    ldap_initialize(&connection,
                    ("ldap://" + host + ':' + tostring(port)).c_str());
#else
#ifdef USE_WIN32_LDAP_API
    connection = ldap_init(const_cast<char *>(host.c_str()), port);
#else
    connection = ldap_init(host.c_str(), port);
#endif
#endif
    ldap_lock()->unlock();

    if (!connection) {
      logger.msg(ERROR, "Could not open LDAP connection to %s", host);
      return false;
    }

    if (!SetConnectionOptions(version)) {
      ldap_unbind_ext(connection, NULL, NULL);
      connection = NULL;
      return false;
    }

    ldap_bind_arg* arg = new ldap_bind_arg;

    arg->connection = connection;
    arg->loglevel = logger.getThreshold();
    arg->valid = true;
    arg->anonymous = anonymous;
    arg->usersn = usersn;

    if (!Arc::CreateThreadFunction(&ldap_bind_with_timeout, arg)) {
      arg->release(); arg->release();
      connection = NULL;
      logger.msg(ERROR, "Failed to create ldap bind thread (%s)", host);
      return false;
    }

    if (!arg->cond.wait(1000 * (timeout + 1))) {
      arg->release();
      connection = NULL;
      logger.msg(ERROR, "Ldap bind timeout (%s)", host);
      return false;
    }

    if (!arg->valid) {
      arg->release();
      connection = NULL;
      logger.msg(ERROR, "Failed to bind to ldap server (%s)", host);
      return false;
    }
    arg->connection = NULL; // keep connection up
    arg->release();

    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

bool Arc::LDAPQuery::HandleResult ( ldap_callback  callback,
void *  ref 
) [private]

Definition at line 549 of file LDAPQuery.cpp.

                                                                {

    logger.msg(VERBOSE, "LDAPQuery: Getting results from %s", host);

    if (!messageid) {
      logger.msg(ERROR, "Error: no LDAP query started to %s", host);
      return false;
    }

    timeval tout;
    tout.tv_sec = timeout;
    tout.tv_usec = 0;

    bool done = false;
    int ldresult = 0;
    LDAPMessage *res = NULL;

    while (!done && (ldresult = ldap_result(connection,
                                            messageid,
                                            LDAP_MSG_ONE,
                                            &tout,
                                            &res)) > 0) {
#ifdef USE_WIN32_LDAP_API
      if (ldap_count_entries(connection, res) == 0) {
        done = true;
        continue;
      }
#endif
      for (LDAPMessage *msg = ldap_first_message(connection, res); msg;
           msg = ldap_next_message(connection, msg)) {

        switch (ldap_msgtype(msg)) {
        case LDAP_RES_SEARCH_ENTRY:
          HandleSearchEntry(msg, callback, ref);
          break;

        case LDAP_RES_SEARCH_RESULT:
          done = true;
          break;
        } // switch
      } // for
      ldap_msgfree(res);
    }

    if (ldresult == 0) {
      logger.msg(ERROR, "LDAP query timed out: %s", host);
      return false;
    }

    if (ldresult == -1) {
      logger.msg(ERROR, "%s (%s)", ldap_err2string(ldresult), host);
      return false;
    }

    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:

void Arc::LDAPQuery::HandleSearchEntry ( LDAPMessage *  msg,
ldap_callback  callback,
void *  ref 
) [private]

Definition at line 607 of file LDAPQuery.cpp.

                                               {
    char *dn = ldap_get_dn(connection, msg);
    callback("dn", dn, ref);
    if (dn)
      ldap_memfree(dn);

    BerElement *ber = NULL;
    for (char *attr = ldap_first_attribute(connection, msg, &ber);
         attr; attr = ldap_next_attribute(connection, msg, ber)) {
      BerValue **bval;
      if ((bval = ldap_get_values_len(connection, msg, attr))) {
        for (int i = 0; bval[i]; i++)
          callback(attr, (bval[i]->bv_val ? bval[i]->bv_val : ""), ref);
        ber_bvecfree(bval);
      }
      ldap_memfree(attr);
    }
    if (ber)
      ber_free(ber, 0);
  }

Here is the caller graph for this function:

bool Arc::LDAPQuery::Query ( const std::string &  base,
const std::string &  filter = "(objectclass=*)",
const std::list< std::string > &  attributes = std::list<std::string>(),
URL::Scope  scope = URL::subtree 
)

Queries the ldap server.

Definition at line 465 of file LDAPQuery.cpp.

                                        {

    if (!Connect())
      return false;

    logger.msg(VERBOSE, "LDAPQuery: Querying %s", host);

    logger.msg(DEBUG, "  base dn: %s", base);
    if (!filter.empty())
      logger.msg(DEBUG, "  filter: %s", filter);
    if (!attributes.empty()) {
      logger.msg(DEBUG, "  attributes:");
      for (std::list<std::string>::const_iterator vs = attributes.begin();
           vs != attributes.end(); vs++)
        logger.msg(DEBUG, "    %s", *vs);
    }

    timeval tout;
    tout.tv_sec = timeout;
    tout.tv_usec = 0;

    char *filt = (char*)filter.c_str();

    char **attrs;
    if (attributes.empty())
      attrs = NULL;
    else {
      attrs = new char*[attributes.size() + 1];
      int i = 0;
      for (std::list<std::string>::const_iterator vs = attributes.begin();
           vs != attributes.end(); vs++, i++)
        attrs[i] = (char*)vs->c_str();
      attrs[i] = NULL;
    }

    int ldresult = ldap_search_ext(connection,
#ifdef USE_WIN32_LDAP_API
                                   const_cast<char *>(base.c_str()),
#else
                                   base.c_str(),
#endif
                                   scope,
                                   filt,
                                   attrs,
                                   0,
                                   NULL,
                                   NULL,
#ifdef USE_WIN32_LDAP_API
                                   timeout,
#else
                                   &tout,
#endif
                                   0,
                                   &messageid);

    if (attrs)
      delete[] attrs;

    if (ldresult != LDAP_SUCCESS) {
      logger.msg(ERROR, "%s (%s)", ldap_err2string(ldresult), host);
      ldap_unbind_ext(connection, NULL, NULL);
      connection = NULL;
      return false;
    }

    return true;
  }

Here is the call graph for this function:

bool Arc::LDAPQuery::Result ( ldap_callback  callback,
void *  ref 
)

Retrieves the result of the query from the ldap-server.

Definition at line 537 of file LDAPQuery.cpp.

                                                          {

    bool result = HandleResult(callback, ref);

    ldap_unbind_ext(connection, NULL, NULL);
    connection = NULL;
    messageid = 0;

    return result;
  }

Here is the call graph for this function:

bool Arc::LDAPQuery::SetConnectionOptions ( int  version) [private]

Definition at line 371 of file LDAPQuery.cpp.

                                                  {

    timeval tout;
    tout.tv_sec = timeout;
    tout.tv_usec = 0;

#ifdef LDAP_OPT_NETWORK_TIMEOUT
    // solaris does not have LDAP_OPT_NETWORK_TIMEOUT
    if (ldap_set_option(connection, LDAP_OPT_NETWORK_TIMEOUT, &tout) !=
        LDAP_OPT_SUCCESS) {
      logger.msg(ERROR,
                 "Could not set LDAP network timeout (%s)", host);
      return false;
    }
#endif

    if (ldap_set_option(connection, LDAP_OPT_TIMELIMIT, &timeout) !=
        LDAP_OPT_SUCCESS) {
      logger.msg(ERROR,
                 "Could not set LDAP timelimit (%s)", host);
      return false;
    }

    if (ldap_set_option(connection, LDAP_OPT_PROTOCOL_VERSION, &version) !=
        LDAP_OPT_SUCCESS) {
      logger.msg(ERROR,
                 "Could not set LDAP protocol version (%s)", host);
      return false;
    }

    return true;
  }

Here is the call graph for this function:

Here is the caller graph for this function:


Friends And Related Function Documentation

int my_sasl_interact ( ldap *  ,
unsigned  int,
void *  ,
void *   
) [friend]

Member Data Documentation

bool Arc::LDAPQuery::anonymous [private]

Definition at line 79 of file LDAPQuery.h.

ldap* Arc::LDAPQuery::connection [private]

Definition at line 83 of file LDAPQuery.h.

std::string Arc::LDAPQuery::host [private]

Definition at line 77 of file LDAPQuery.h.

Logger Arc::LDAPQuery::logger [static, private]

Definition at line 90 of file LDAPQuery.h.

Definition at line 87 of file LDAPQuery.h.

int Arc::LDAPQuery::port [private]

Definition at line 78 of file LDAPQuery.h.

int Arc::LDAPQuery::timeout [private]

Definition at line 81 of file LDAPQuery.h.

std::string Arc::LDAPQuery::usersn [private]

Definition at line 80 of file LDAPQuery.h.


The documentation for this class was generated from the following files: