1// OpenLDAP: pkg/ldap/contrib/ldapc++/src/LDAPBindRequest.cpp,v 1.6.8.3 2008/04/14 23:09:26 quanah Exp
2/*
3 * Copyright 2000-2007, OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5 */
6
7#include <ldap.h>
8
9#include "debug.h"
10
11#include "LDAPBindRequest.h"
12#include "LDAPException.h"
13#include "SaslInteractionHandler.h"
14#include "SaslInteraction.h"
15
16#include <cstdlib>
17#include <sasl/sasl.h>
18
19using namespace std;
20
21LDAPBindRequest::LDAPBindRequest(const LDAPBindRequest& req) :
22        LDAPRequest(req){
23    DEBUG(LDAP_DEBUG_CONSTRUCT, "LDAPBindRequest::LDAPBindRequest(&)" << endl);
24    m_dn=req.m_dn;
25    m_cred=req.m_cred;
26    m_mech=req.m_mech;
27}
28
29LDAPBindRequest::LDAPBindRequest(const string& dn,const string& passwd,
30        LDAPAsynConnection *connect, const LDAPConstraints *cons,
31        bool isReferral) : LDAPRequest(connect, cons, isReferral){
32   DEBUG(LDAP_DEBUG_CONSTRUCT,"LDAPBindRequest::LDAPBindRequest()" << endl);
33   DEBUG(LDAP_DEBUG_CONSTRUCT | LDAP_DEBUG_PARAMETER, "   dn:" << dn << endl
34           << "   passwd:" << passwd << endl);
35    m_dn = dn;
36    m_cred = passwd;
37    m_mech = "";
38}
39
40LDAPBindRequest::~LDAPBindRequest(){
41    DEBUG(LDAP_DEBUG_DESTROY,"LDAPBindRequest::~LDAPBindRequest()" << endl);
42}
43
44LDAPMessageQueue* LDAPBindRequest::sendRequest(){
45    DEBUG(LDAP_DEBUG_TRACE,"LDAPBindRequest::sendRequest()" << endl);
46    int msgID=0;
47
48    const char* mech = (m_mech == "" ? 0 : m_mech.c_str());
49    BerValue* tmpcred=0;
50    if(m_cred != ""){
51        char* tmppwd = (char*) malloc( (m_cred.size()+1) * sizeof(char));
52        m_cred.copy(tmppwd,string::npos);
53        tmppwd[m_cred.size()]=0;
54        tmpcred=ber_bvstr(tmppwd);
55    }else{
56        tmpcred=(BerValue*) malloc(sizeof(BerValue));
57        tmpcred->bv_len=0;
58        tmpcred->bv_val=0;
59    }
60    const char* dn = 0;
61    if(m_dn != ""){
62        dn = m_dn.c_str();
63    }
64    LDAPControl** tmpSrvCtrls=m_cons->getSrvCtrlsArray();
65    LDAPControl** tmpClCtrls=m_cons->getClCtrlsArray();
66    int err=ldap_sasl_bind(m_connection->getSessionHandle(),dn,
67            mech, tmpcred, tmpSrvCtrls, tmpClCtrls, &msgID);
68    LDAPControlSet::freeLDAPControlArray(tmpSrvCtrls);
69    LDAPControlSet::freeLDAPControlArray(tmpClCtrls);
70    ber_bvfree(tmpcred);
71
72    if(err != LDAP_SUCCESS){
73        throw LDAPException(err);
74    }else{
75        m_msgID=msgID;
76        return new LDAPMessageQueue(this);
77    }
78}
79
80LDAPSaslBindRequest::LDAPSaslBindRequest(const std::string& mech,
81        const std::string& cred,
82        LDAPAsynConnection *connect,
83        const LDAPConstraints *cons,
84        bool isReferral) : LDAPRequest(connect, cons, isReferral),m_mech(mech), m_cred(cred) {}
85
86LDAPMessageQueue* LDAPSaslBindRequest::sendRequest()
87{
88    DEBUG(LDAP_DEBUG_TRACE,"LDAPSaslBindRequest::sendRequest()" << endl);
89    int msgID=0;
90
91    BerValue tmpcred;
92    tmpcred.bv_val = (char*) malloc( m_cred.size() * sizeof(char));
93    m_cred.copy(tmpcred.bv_val,string::npos);
94    tmpcred.bv_len = m_cred.size();
95
96    LDAPControl** tmpSrvCtrls=m_cons->getSrvCtrlsArray();
97    LDAPControl** tmpClCtrls=m_cons->getClCtrlsArray();
98    int err=ldap_sasl_bind(m_connection->getSessionHandle(), "", m_mech.c_str(),
99            &tmpcred, tmpSrvCtrls, tmpClCtrls, &msgID);
100    LDAPControlSet::freeLDAPControlArray(tmpSrvCtrls);
101    LDAPControlSet::freeLDAPControlArray(tmpClCtrls);
102    free(tmpcred.bv_val);
103
104    if(err != LDAP_SUCCESS){
105        throw LDAPException(err);
106    }else{
107        m_msgID=msgID;
108        return new LDAPMessageQueue(this);
109    }
110}
111
112LDAPSaslBindRequest::~LDAPSaslBindRequest()
113{
114    DEBUG(LDAP_DEBUG_DESTROY,"LDAPSaslBindRequest::~LDAPSaslBindRequest()" << endl);
115}
116
117LDAPSaslInteractiveBind::LDAPSaslInteractiveBind( const std::string& mech,
118        int flags, SaslInteractionHandler *sih, LDAPAsynConnection *connect,
119        const LDAPConstraints *cons, bool isReferral) :
120            LDAPRequest(connect, cons, isReferral),
121            m_mech(mech), m_flags(flags), m_sih(sih), m_res(0)
122{
123}
124
125static int my_sasl_interact(LDAP *l, unsigned flags, void *cbh, void *interact)
126{
127    DEBUG(LDAP_DEBUG_TRACE, "LDAPSaslInteractiveBind::my_sasl_interact()"
128            << std::endl );
129    std::list<SaslInteraction*> interactions;
130
131    sasl_interact_t *iter = (sasl_interact_t*) interact;
132    while ( iter->id != SASL_CB_LIST_END ) {
133        SaslInteraction *si = new SaslInteraction(iter);
134        interactions.push_back( si );
135        iter++;
136    }
137    ((SaslInteractionHandler*)cbh)->handleInteractions(interactions);
138    return LDAP_SUCCESS;
139}
140
141/* This kind of fakes an asynchronous operation, ldap_sasl_interactive_bind_s
142 * is synchronous */
143LDAPMessageQueue *LDAPSaslInteractiveBind::sendRequest()
144{
145    DEBUG(LDAP_DEBUG_TRACE, "LDAPSaslInteractiveBind::sendRequest()" <<
146            m_mech << std::endl);
147
148    LDAPControl** tmpSrvCtrls=m_cons->getSrvCtrlsArray();
149    LDAPControl** tmpClCtrls=m_cons->getClCtrlsArray();
150    int res = ldap_sasl_interactive_bind_s( m_connection->getSessionHandle(),
151            "", m_mech.c_str(), tmpSrvCtrls, tmpClCtrls, m_flags,
152            my_sasl_interact, m_sih );
153
154    DEBUG(LDAP_DEBUG_TRACE, "ldap_sasl_interactive_bind_s returned: "
155            << res << std::endl);
156    if(res != LDAP_SUCCESS){
157        throw LDAPException(res);
158    } else {
159        m_res = new LDAPResult(LDAPMsg::BIND_RESPONSE, res, "");
160    }
161    return new LDAPMessageQueue(this);
162}
163
164LDAPMsg* LDAPSaslInteractiveBind::getNextMessage() const
165{
166    return m_res;
167}
168
169LDAPSaslInteractiveBind::~LDAPSaslInteractiveBind()
170{
171    DEBUG(LDAP_DEBUG_DESTROY,"LDAPSaslInteractiveBind::~LDAPSaslInteractiveBind()" << endl);
172}
173
174