00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "ldapoperation.h"
00022 #include "kldap_config.h"
00023
00024 #include <kdebug.h>
00025
00026 #include <QtCore/QTime>
00027
00028 #include <stdlib.h>
00029 #ifdef HAVE_SYS_TIME_H
00030 #include <sys/time.h>
00031 #endif
00032
00033 #ifdef SASL2_FOUND
00034 #include <sasl/sasl.h>
00035 #endif
00036
00037 #ifdef LDAP_FOUND
00038 # ifndef HAVE_WINLDAP_H
00039 # include <lber.h>
00040 # include <ldap.h>
00041 # else
00042 # include <w32-ldap-help.h>
00043 # endif // HAVE_WINLDAP_H
00044 #endif // LDAP_FOUND
00045
00046 #include "ldapdefs.h"
00047
00048 using namespace KLDAP;
00049
00050 #ifdef LDAP_FOUND
00051 static void extractControls( LdapControls &ctrls, LDAPControl **pctrls );
00052 #endif // LDAP_FOUND
00053
00054
00055
00056
00057
00058 static int kldap_timeout_value( int msecs, int elapsed )
00059 {
00060 if ( msecs == -1 ) {
00061 return -1;
00062 }
00063
00064 int timeout = msecs - elapsed;
00065 return timeout < 0 ? 0 : timeout;
00066 }
00067
00068 class LdapOperation::LdapOperationPrivate
00069 {
00070 public:
00071 LdapOperationPrivate();
00072 ~LdapOperationPrivate();
00073 #ifdef LDAP_FOUND
00074 int processResult( int rescode, LDAPMessage *msg );
00075 int bind( const QByteArray &creds, SASL_Callback_Proc *saslproc, void *data, bool async );
00076 #endif
00077 LdapControls mClientCtrls, mServerCtrls, mControls;
00078 LdapObject mObject;
00079 QByteArray mExtOid, mExtData;
00080 QByteArray mServerCred;
00081 QString mMatchedDn;
00082 QList<QByteArray> mReferrals;
00083
00084 LdapConnection *mConnection;
00085 };
00086
00087 LdapOperation::LdapOperation()
00088 : d( new LdapOperationPrivate )
00089 {
00090 d->mConnection = 0;
00091 }
00092
00093 LdapOperation::LdapOperation( LdapConnection &conn )
00094 : d( new LdapOperationPrivate )
00095 {
00096 setConnection( conn );
00097 }
00098
00099 LdapOperation::~LdapOperation()
00100 {
00101 delete d;
00102 }
00103
00104 void LdapOperation::setConnection( LdapConnection &conn )
00105 {
00106 d->mConnection = &conn;
00107 }
00108
00109 LdapConnection &LdapOperation::connection()
00110 {
00111 return *d->mConnection;
00112 }
00113
00114 void LdapOperation::setClientControls( const LdapControls &ctrls )
00115 {
00116 d->mClientCtrls = ctrls;
00117 }
00118
00119 void LdapOperation::setServerControls( const LdapControls &ctrls )
00120 {
00121 d->mServerCtrls = ctrls;
00122 }
00123
00124 LdapControls LdapOperation::clientControls() const
00125 {
00126 return d->mClientCtrls;
00127 }
00128
00129 LdapControls LdapOperation::serverControls() const
00130 {
00131 return d->mServerCtrls;
00132 }
00133
00134 LdapObject LdapOperation::object() const
00135 {
00136 return d->mObject;
00137 }
00138
00139 LdapControls LdapOperation::controls() const
00140 {
00141 return d->mControls;
00142 }
00143
00144 QByteArray LdapOperation::extendedOid() const
00145 {
00146 return d->mExtOid;
00147 }
00148
00149 QByteArray LdapOperation::extendedData() const
00150 {
00151 return d->mExtData;
00152 }
00153
00154 QString LdapOperation::matchedDn() const
00155 {
00156 return d->mMatchedDn;
00157 }
00158
00159 QList<QByteArray> LdapOperation::referrals() const
00160 {
00161 return d->mReferrals;
00162 }
00163
00164 QByteArray LdapOperation::serverCred() const
00165 {
00166 return d->mServerCred;
00167 }
00168
00169 LdapOperation::LdapOperationPrivate::LdapOperationPrivate()
00170 {
00171 }
00172
00173 LdapOperation::LdapOperationPrivate::~LdapOperationPrivate()
00174 {
00175 }
00176
00177 #ifdef LDAP_FOUND
00178
00179 #ifdef SASL2_FOUND
00180 static int kldap_sasl_interact( sasl_interact_t *interact, LdapOperation::SASL_Data *data )
00181 {
00182 if ( data->proc ) {
00183 for ( ; interact->id != SASL_CB_LIST_END; interact++ ) {
00184 switch ( interact->id ) {
00185 case SASL_CB_GETREALM:
00186 data->creds.fields |= LdapOperation::SASL_Realm;
00187 break;
00188 case SASL_CB_AUTHNAME:
00189 data->creds.fields |= LdapOperation::SASL_Authname;
00190 break;
00191 case SASL_CB_PASS:
00192 data->creds.fields |= LdapOperation::SASL_Password;
00193 break;
00194 case SASL_CB_USER:
00195 data->creds.fields |= LdapOperation::SASL_Authzid;
00196 break;
00197 }
00198 }
00199 int retval;
00200 if ( ( retval = data->proc( data->creds, data->data ) ) ) {
00201 return retval;
00202 }
00203 }
00204
00205 QString value;
00206
00207 while ( interact->id != SASL_CB_LIST_END ) {
00208 value.clear();
00209 switch( interact->id ) {
00210 case SASL_CB_GETREALM:
00211 value = data->creds.realm;
00212 kDebug() << "SASL_REALM=" << value;
00213 break;
00214 case SASL_CB_AUTHNAME:
00215 value = data->creds.authname;
00216 kDebug() << "SASL_AUTHNAME=" << value;
00217 break;
00218 case SASL_CB_PASS:
00219 value = data->creds.password;
00220 kDebug() << "SASL_PASSWD=[hidden]";
00221 break;
00222 case SASL_CB_USER:
00223 value = data->creds.authzid;
00224 kDebug() << "SASL_AUTHZID=" << value;
00225 break;
00226 }
00227 if ( value.isEmpty() ) {
00228 interact->result = NULL;
00229 interact->len = 0;
00230 } else {
00231 interact->result = strdup( value.toUtf8() );
00232 interact->len = strlen( (const char *)interact->result );
00233 }
00234 interact++;
00235 }
00236 return KLDAP_SUCCESS;
00237 }
00238 #endif
00239
00240 int LdapOperation::LdapOperationPrivate::bind( const QByteArray &creds,
00241 SASL_Callback_Proc *saslproc,
00242 void *data, bool async )
00243 {
00244 Q_ASSERT( mConnection );
00245 LDAP *ld = (LDAP*) mConnection->handle();
00246 LdapServer server;
00247 server = mConnection->server();
00248
00249 int ret;
00250
00251 if ( server.auth() == LdapServer::SASL ) {
00252 #if defined( SASL2_FOUND ) && !defined( HAVE_WINLDAP_H )
00253 sasl_conn_t *saslconn = (sasl_conn_t *)mConnection->saslHandle();
00254 sasl_interact_t *client_interact = NULL;
00255 const char *out = NULL;
00256 uint outlen;
00257 const char *mechusing = NULL;
00258 struct berval ccred, *scred;
00259 int saslresult;
00260 QByteArray sdata = creds;
00261
00262 QString mech = server.mech();
00263 if ( mech.isEmpty() ) {
00264 mech = "DIGEST-MD5";
00265 }
00266
00267 SASL_Data sasldata;
00268 sasldata.proc = saslproc;
00269 sasldata.data = data;
00270 sasldata.creds.fields = 0;
00271 sasldata.creds.realm = server.realm();
00272 sasldata.creds.authname = server.user();
00273 sasldata.creds.authzid = server.bindDn();
00274 sasldata.creds.password = server.password();
00275
00276 do {
00277 if ( sdata.isEmpty() ) {
00278 do {
00279 saslresult = sasl_client_start( saslconn, mech.toLatin1(),
00280 &client_interact, &out, &outlen, &mechusing );
00281
00282 if ( saslresult == SASL_INTERACT ) {
00283 if ( kldap_sasl_interact( client_interact, &sasldata ) != KLDAP_SUCCESS ) {
00284 return KLDAP_SASL_ERROR;
00285 }
00286 }
00287 kDebug() << "sasl_client_start mech: "
00288 << mechusing << " outlen " << outlen
00289 << " result: " << saslresult;
00290 } while ( saslresult == SASL_INTERACT );
00291 if ( saslresult != SASL_CONTINUE && saslresult != SASL_OK ) {
00292 return KLDAP_SASL_ERROR;
00293 }
00294
00295 } else {
00296 kDebug() << "sasl_client_step";
00297 do {
00298 saslresult = sasl_client_step( saslconn, sdata.data(), sdata.size(),
00299 &client_interact, &out, &outlen );
00300 if ( saslresult == SASL_INTERACT ) {
00301 if ( kldap_sasl_interact( client_interact, &sasldata ) != KLDAP_SUCCESS ) {
00302 return KLDAP_SASL_ERROR;
00303 }
00304 }
00305 } while ( saslresult == SASL_INTERACT );
00306 kDebug() << "sasl_client_step result" << saslresult;
00307 if ( saslresult != SASL_CONTINUE && saslresult != SASL_OK ) {
00308 return KLDAP_SASL_ERROR;
00309 }
00310 }
00311
00312 ccred.bv_val = (char*) out;
00313 ccred.bv_len = outlen;
00314
00315 if ( async ) {
00316 kDebug() << "ldap_sasl_bind";
00317 int msgid;
00318 ret =
00319 ldap_sasl_bind( ld, server.bindDn().toUtf8().data(), mech.toLatin1(),
00320 &ccred, 0, 0, &msgid );
00321 if ( ret == 0 ) {
00322 ret = msgid;
00323 }
00324 kDebug() << "ldap_sasl_bind msgid" << ret;
00325 } else {
00326 kDebug() << "ldap_sasl_bind_s";
00327 ret =
00328 ldap_sasl_bind_s( ld, server.bindDn().toUtf8().data(), mech.toLatin1(),
00329 &ccred, 0, 0, &scred );
00330 kDebug() << "ldap_sasl_bind_s ret" << ret;
00331 if ( scred ) {
00332 sdata = QByteArray( scred->bv_val, scred->bv_len );
00333 } else {
00334 sdata = QByteArray();
00335 }
00336 }
00337 } while ( !async && ret == KLDAP_SASL_BIND_IN_PROGRESS );
00338 #else
00339 kError() << "SASL authentication is not available "
00340 << "(re-compile kldap with cyrus-sasl and OpenLDAP development).";
00341 return KLDAP_SASL_ERROR;
00342 #endif
00343 } else {
00344 QByteArray bindname, pass;
00345 struct berval ccred;
00346 if ( server.auth() == LdapServer::Simple ) {
00347 bindname = server.bindDn().toUtf8();
00348 pass = server.password().toUtf8();
00349 }
00350 ccred.bv_val = pass.data();
00351 ccred.bv_len = pass.size();
00352 kDebug() << "binding to server, bindname: " << bindname << " password: *****";
00353
00354 if ( async ) {
00355 kDebug() << "ldap_sasl_bind (simple)";
00356 #ifndef HAVE_WINLDAP_H
00357 int msgid = 0;
00358 ret = ldap_sasl_bind( ld, bindname.data(), 0, &ccred, 0, 0, &msgid );
00359 if ( ret == 0 ) {
00360 ret = msgid;
00361 }
00362 #else
00363 ret = ldap_simple_bind( ld, bindname.data(),pass.data() );
00364 #endif
00365 } else {
00366 kDebug() << "ldap_sasl_bind_s (simple)";
00367 #ifndef HAVE_WINLDAP_H
00368 ret = ldap_sasl_bind_s( ld, bindname.data(), 0, &ccred, 0, 0, 0 );
00369 #else
00370 ret = ldap_simple_bind_s( ld, bindname.data(), pass.data() );
00371 #endif
00372 }
00373 }
00374 return ret;
00375 }
00376
00377 int LdapOperation::LdapOperationPrivate::processResult( int rescode, LDAPMessage *msg )
00378 {
00379
00380 int retval;
00381 LDAP *ld = (LDAP*) mConnection->handle();
00382
00383 kDebug() << "rescode: " << rescode;
00384 switch ( rescode ) {
00385 case RES_SEARCH_ENTRY:
00386 {
00387
00388 mObject.clear();
00389 LdapAttrMap attrs;
00390 char *name;
00391 struct berval **bvals;
00392 BerElement *entry;
00393
00394 char *dn = ldap_get_dn( ld, msg );
00395 mObject.setDn( QString::fromUtf8( dn ) );
00396 ldap_memfree( dn );
00397
00398
00399 name = ldap_first_attribute( ld, msg, &entry );
00400 while ( name != 0 ) {
00401
00402 bvals = ldap_get_values_len( ld, msg, name );
00403 LdapAttrValue values;
00404 if ( bvals ) {
00405 for ( int i = 0; bvals[i] != 0; i++ ) {
00406 char *val = bvals[i]->bv_val;
00407 unsigned long len = bvals[i]->bv_len;
00408 values.append( QByteArray( val, len ) );
00409 }
00410 ldap_value_free_len( bvals );
00411 }
00412 attrs[ QString::fromLatin1( name ) ] = values;
00413 ldap_memfree( name );
00414
00415
00416 name = ldap_next_attribute( ld, msg, entry );
00417 }
00418 ber_free( entry, 0 );
00419 mObject.setAttributes( attrs );
00420 break;
00421 }
00422 case RES_SEARCH_REFERENCE:
00423
00424 rescode = 0;
00425 break;
00426 case RES_EXTENDED:
00427 {
00428 char *retoid;
00429 struct berval *retdata;
00430 retval = ldap_parse_extended_result( ld, msg, &retoid, &retdata, 0 );
00431 if ( retval != KLDAP_SUCCESS ) {
00432 ldap_msgfree( msg );
00433 return -1;
00434 }
00435 mExtOid = retoid ? QByteArray( retoid ) : QByteArray();
00436 mExtData = retdata ? QByteArray( retdata->bv_val, retdata->bv_len ) : QByteArray();
00437 ldap_memfree( retoid );
00438 ber_bvfree( retdata );
00439 break;
00440 }
00441 case RES_BIND:
00442 {
00443 struct berval *servercred = 0;
00444 #ifndef HAVE_WINLDAP_H
00445
00446 retval = ldap_parse_sasl_bind_result( ld, msg, &servercred, 0 );
00447 #else
00448 retval = KLDAP_SUCCESS;
00449 #endif
00450 if ( retval != KLDAP_SUCCESS && retval != KLDAP_SASL_BIND_IN_PROGRESS ) {
00451 kDebug() << "RES_BIND error: " << retval;
00452 ldap_msgfree( msg );
00453 return -1;
00454 }
00455 kDebug() << "RES_BIND rescode" << rescode << "retval:" << retval;
00456 if ( servercred ) {
00457 mServerCred = QByteArray( servercred->bv_val, servercred->bv_len );
00458 ber_bvfree( servercred );
00459 } else {
00460 mServerCred = QByteArray();
00461 }
00462 break;
00463 }
00464 default:
00465 {
00466 LDAPControl **serverctrls = 0;
00467 char *matcheddn = 0, *errmsg = 0;
00468 char **referralsp;
00469 int errcodep;
00470 retval =
00471 ldap_parse_result( ld, msg, &errcodep, &matcheddn, &errmsg, &referralsp,
00472 &serverctrls, 0 );
00473 kDebug() << "rescode" << rescode << "retval:" << retval
00474 << "matcheddn:" << matcheddn << "errcode:"
00475 << errcodep << "errmsg:" << errmsg;
00476 if ( retval != KLDAP_SUCCESS ) {
00477 ldap_msgfree( msg );
00478 return -1;
00479 }
00480 mControls.clear();
00481 if ( serverctrls ) {
00482 extractControls( mControls, serverctrls );
00483 ldap_controls_free( serverctrls );
00484 }
00485 mReferrals.clear();
00486 if ( referralsp ) {
00487 char **tmp = referralsp;
00488 while ( *tmp ) {
00489 mReferrals.append( QByteArray( *tmp ) );
00490 ldap_memfree( *tmp );
00491 tmp++;
00492 }
00493 ldap_memfree( (char *) referralsp );
00494 }
00495 mMatchedDn.clear();
00496 if ( matcheddn ) {
00497 mMatchedDn = QString::fromUtf8( matcheddn );
00498 ldap_memfree( matcheddn );
00499 }
00500 if ( errmsg ) {
00501 ldap_memfree( errmsg );
00502 }
00503 }
00504 }
00505
00506 ldap_msgfree( msg );
00507
00508 return rescode;
00509 }
00510
00511 static void addModOp( LDAPMod ***pmods, int mod_type, const QString &attr,
00512 const QByteArray *value = 0 )
00513 {
00514
00515
00516
00517 LDAPMod **mods;
00518
00519 mods = *pmods;
00520
00521 uint i = 0;
00522
00523 if ( mods == 0 ) {
00524 mods = (LDAPMod **)malloc( 2 * sizeof( LDAPMod * ) );
00525 mods[ 0 ] = (LDAPMod *)malloc( sizeof( LDAPMod ) );
00526 mods[ 1 ] = 0;
00527 memset( mods[ 0 ], 0, sizeof( LDAPMod ) );
00528 } else {
00529 while ( mods[ i ] != 0 &&
00530 ( strcmp( attr.toUtf8(), mods[i]->mod_type ) != 0 ||
00531 ( mods[ i ]->mod_op & ~LDAP_MOD_BVALUES ) != mod_type ) ) i++;
00532
00533 if ( mods[ i ] == 0 ) {
00534 mods = (LDAPMod **)realloc( mods, ( i + 2 ) * sizeof( LDAPMod * ) );
00535 if ( mods == 0 ) {
00536 kError() << "addModOp: realloc";
00537 return;
00538 }
00539 mods[ i + 1 ] = 0;
00540 mods[ i ] = (LDAPMod *) malloc( sizeof( LDAPMod ) );
00541 memset( mods[ i ], 0, sizeof( LDAPMod ) );
00542 }
00543 }
00544
00545 mods[ i ]->mod_op = mod_type | LDAP_MOD_BVALUES;
00546 if ( mods[ i ]->mod_type == 0 ) {
00547 mods[ i ]->mod_type = strdup( attr.toUtf8() );
00548 }
00549
00550 *pmods = mods;
00551
00552 if ( value == 0 ) {
00553 return;
00554 }
00555
00556 int vallen = value->size();
00557 BerValue *berval;
00558 berval = (BerValue *) malloc( sizeof( BerValue ) );
00559 berval -> bv_len = vallen;
00560 if ( vallen > 0 ) {
00561 berval -> bv_val = (char *) malloc( vallen );
00562 memcpy( berval -> bv_val, value->data(), vallen );
00563 } else {
00564 berval -> bv_val = 0;
00565 }
00566
00567 if ( mods[ i ] -> mod_vals.modv_bvals == 0 ) {
00568 mods[ i ]->mod_vals.modv_bvals =
00569 (BerValue **) malloc( sizeof( BerValue * ) * 2 );
00570 mods[ i ]->mod_vals.modv_bvals[ 0 ] = berval;
00571 mods[ i ]->mod_vals.modv_bvals[ 1 ] = 0;
00572
00573 } else {
00574 uint j = 0;
00575 while ( mods[ i ]->mod_vals.modv_bvals[ j ] != 0 ) {
00576 j++;
00577 }
00578 mods[ i ]->mod_vals.modv_bvals =
00579 (BerValue **)realloc( mods[ i ]->mod_vals.modv_bvals,
00580 ( j + 2 ) * sizeof( BerValue * ) );
00581 if ( mods[ i ]->mod_vals.modv_bvals == 0 ) {
00582 kError() << "addModOp: realloc";
00583 free( berval );
00584 return;
00585 }
00586 mods[ i ]->mod_vals.modv_bvals[ j ] = berval;
00587 mods[ i ]->mod_vals.modv_bvals[ j+1 ] = 0;
00588 kDebug() << j << ". new bervalue";
00589 }
00590 }
00591
00592 static void addControlOp( LDAPControl ***pctrls, const QString &oid,
00593 const QByteArray &value, bool critical )
00594 {
00595 LDAPControl **ctrls;
00596 LDAPControl *ctrl = (LDAPControl *) malloc( sizeof( LDAPControl ) );
00597
00598 ctrls = *pctrls;
00599
00600 kDebug() << "oid:'" << oid << "' val: '" << value << "'";
00601 int vallen = value.size();
00602 ctrl->ldctl_value.bv_len = vallen;
00603 if ( vallen ) {
00604 ctrl->ldctl_value.bv_val = (char *) malloc( vallen );
00605 memcpy( ctrl->ldctl_value.bv_val, value.data(), vallen );
00606 } else {
00607 ctrl->ldctl_value.bv_val = 0;
00608 }
00609 ctrl->ldctl_iscritical = critical;
00610 ctrl->ldctl_oid = strdup( oid.toUtf8() );
00611
00612 uint i = 0;
00613
00614 if ( ctrls == 0 ) {
00615 ctrls = (LDAPControl **)malloc ( 2 * sizeof( LDAPControl * ) );
00616 ctrls[ 0 ] = 0;
00617 ctrls[ 1 ] = 0;
00618 } else {
00619 while ( ctrls[ i ] != 0 ) {
00620 i++;
00621 }
00622 ctrls[ i + 1 ] = 0;
00623 ctrls =
00624 (LDAPControl **)realloc( ctrls, ( i + 2 ) * sizeof( LDAPControl * ) );
00625 }
00626 ctrls[ i ] = ctrl;
00627 *pctrls = ctrls;
00628 }
00629
00630 static void createControls( LDAPControl ***pctrls, const LdapControls &ctrls )
00631 {
00632 for ( int i = 0; i< ctrls.count(); ++i ) {
00633 addControlOp( pctrls, ctrls[i].oid(), ctrls[i].value(), ctrls[i].critical() );
00634 }
00635 }
00636
00637 static void extractControls( LdapControls &ctrls, LDAPControl **pctrls )
00638 {
00639 LDAPControl *ctrl;
00640 LdapControl control;
00641 int i = 0;
00642
00643 while ( pctrls[i] ) {
00644 ctrl = pctrls[ i ];
00645 control.setOid( QString::fromUtf8( ctrl->ldctl_oid ) );
00646 control.setValue( QByteArray( ctrl->ldctl_value.bv_val,
00647 ctrl->ldctl_value.bv_len ) );
00648 control.setCritical( ctrl->ldctl_iscritical );
00649 ctrls.append( control );
00650 i++;
00651 }
00652 }
00653
00654 int LdapOperation::bind( const QByteArray &creds, SASL_Callback_Proc *saslproc, void *data )
00655 {
00656 return d->bind( creds, saslproc, data, true );
00657 }
00658
00659 int LdapOperation::bind_s( SASL_Callback_Proc *saslproc, void *data )
00660 {
00661 return d->bind( QByteArray(), saslproc, data, false );
00662 }
00663
00664 int LdapOperation::search( const LdapDN &base, LdapUrl::Scope scope,
00665 const QString &filter, const QStringList &attributes )
00666 {
00667 Q_ASSERT( d->mConnection );
00668 LDAP *ld = (LDAP*) d->mConnection->handle();
00669
00670 char **attrs = 0;
00671 int msgid;
00672
00673 LDAPControl **serverctrls = 0, **clientctrls = 0;
00674 createControls( &serverctrls, d->mServerCtrls );
00675 createControls( &serverctrls, d->mClientCtrls );
00676
00677 int count = attributes.count();
00678 if ( count > 0 ) {
00679 attrs = static_cast<char**>( malloc( ( count + 1 ) * sizeof( char * ) ) );
00680 for ( int i=0; i<count; i++ ) {
00681 attrs[i] = strdup( attributes.at(i).toUtf8() );
00682 }
00683 attrs[count] = 0;
00684 }
00685
00686 int lscope = LDAP_SCOPE_BASE;
00687 switch ( scope ) {
00688 case LdapUrl::Base:
00689 lscope = LDAP_SCOPE_BASE;
00690 break;
00691 case LdapUrl::One:
00692 lscope = LDAP_SCOPE_ONELEVEL;
00693 break;
00694 case LdapUrl::Sub:
00695 lscope = LDAP_SCOPE_SUBTREE;
00696 break;
00697 }
00698
00699 kDebug() << "asyncSearch() base=\"" << base.toString()
00700 << "\" scope=" << (int)scope
00701 << "filter=\"" << filter
00702 << "\" attrs=" << attributes;
00703 int retval =
00704 ldap_search_ext( ld, base.toString().toUtf8().data(), lscope,
00705 filter.isEmpty() ? QByteArray( "objectClass=*" ).data() :
00706 filter.toUtf8().data(),
00707 attrs, 0, serverctrls, clientctrls, 0,
00708 d->mConnection->sizeLimit(), &msgid );
00709
00710 ldap_controls_free( serverctrls );
00711 ldap_controls_free( clientctrls );
00712
00713
00714 if ( count > 0 ) {
00715 for ( int i=0; i<count; i++ ) {
00716 free( attrs[i] );
00717 }
00718 free( attrs );
00719 }
00720
00721 if ( retval == 0 ) {
00722 retval = msgid;
00723 }
00724 return retval;
00725 }
00726
00727 int LdapOperation::add( const LdapObject &object )
00728 {
00729 Q_ASSERT( d->mConnection );
00730 LDAP *ld = (LDAP*) d->mConnection->handle();
00731
00732 int msgid;
00733 LDAPMod **lmod = 0;
00734
00735 LDAPControl **serverctrls = 0, **clientctrls = 0;
00736 createControls( &serverctrls, d->mServerCtrls );
00737 createControls( &serverctrls, d->mClientCtrls );
00738
00739 for ( LdapAttrMap::ConstIterator it = object.attributes().begin();
00740 it != object.attributes().end(); ++it ) {
00741 QString attr = it.key();
00742 for ( LdapAttrValue::ConstIterator it2 = (*it).begin(); it2 != (*it).end(); ++it2 ) {
00743 addModOp( &lmod, 0, attr, &(*it2) );
00744 }
00745 }
00746
00747 int retval =
00748 ldap_add_ext( ld, object.dn().toString().toUtf8().data(), lmod, serverctrls,
00749 clientctrls, &msgid );
00750
00751 ldap_controls_free( serverctrls );
00752 ldap_controls_free( clientctrls );
00753 ldap_mods_free( lmod, 1 );
00754 if ( retval == 0 ) {
00755 retval = msgid;
00756 }
00757 return retval;
00758 }
00759
00760 int LdapOperation::add_s( const LdapObject &object )
00761 {
00762 Q_ASSERT( d->mConnection );
00763 LDAP *ld = (LDAP*) d->mConnection->handle();
00764
00765 LDAPMod **lmod = 0;
00766
00767 LDAPControl **serverctrls = 0, **clientctrls = 0;
00768 createControls( &serverctrls, d->mServerCtrls );
00769 createControls( &serverctrls, d->mClientCtrls );
00770
00771 for ( LdapAttrMap::ConstIterator it = object.attributes().begin();
00772 it != object.attributes().end(); ++it ) {
00773 QString attr = it.key();
00774 for ( LdapAttrValue::ConstIterator it2 = (*it).begin(); it2 != (*it).end(); ++it2 ) {
00775 addModOp( &lmod, 0, attr, &(*it2) );
00776 }
00777 }
00778
00779 int retval =
00780 ldap_add_ext_s( ld, object.dn().toString().toUtf8().data(), lmod, serverctrls,
00781 clientctrls );
00782
00783 ldap_controls_free( serverctrls );
00784 ldap_controls_free( clientctrls );
00785 ldap_mods_free( lmod, 1 );
00786 return retval;
00787 }
00788
00789 int LdapOperation::add( const LdapDN &dn, const ModOps &ops )
00790 {
00791 Q_ASSERT( d->mConnection );
00792 LDAP *ld = (LDAP*) d->mConnection->handle();
00793
00794 int msgid;
00795 LDAPMod **lmod = 0;
00796
00797 LDAPControl **serverctrls = 0, **clientctrls = 0;
00798 createControls( &serverctrls, d->mServerCtrls );
00799 createControls( &serverctrls, d->mClientCtrls );
00800
00801 for ( int i = 0; i < ops.count(); ++i ) {
00802 for ( int j = 0; j < ops[i].values.count(); ++j ) {
00803 addModOp( &lmod, 0, ops[i].attr, &ops[i].values[j] );
00804 }
00805 }
00806
00807 int retval =
00808 ldap_add_ext( ld, dn.toString().toUtf8().data(), lmod, serverctrls,
00809 clientctrls, &msgid );
00810
00811 ldap_controls_free( serverctrls );
00812 ldap_controls_free( clientctrls );
00813 ldap_mods_free( lmod, 1 );
00814 if ( retval == 0 ) {
00815 retval = msgid;
00816 }
00817 return retval;
00818 }
00819
00820 int LdapOperation::add_s( const LdapDN &dn, const ModOps &ops )
00821 {
00822 Q_ASSERT( d->mConnection );
00823 LDAP *ld = (LDAP*) d->mConnection->handle();
00824
00825 LDAPMod **lmod = 0;
00826
00827 LDAPControl **serverctrls = 0, **clientctrls = 0;
00828 createControls( &serverctrls, d->mServerCtrls );
00829 createControls( &serverctrls, d->mClientCtrls );
00830
00831 for ( int i = 0; i < ops.count(); ++i ) {
00832 for ( int j = 0; j < ops[i].values.count(); ++j ) {
00833 addModOp( &lmod, 0, ops[i].attr, &ops[i].values[j] );
00834 }
00835 }
00836 kDebug() << dn.toString();
00837 int retval =
00838 ldap_add_ext_s( ld, dn.toString().toUtf8().data(), lmod, serverctrls,
00839 clientctrls );
00840
00841 ldap_controls_free( serverctrls );
00842 ldap_controls_free( clientctrls );
00843 ldap_mods_free( lmod, 1 );
00844 return retval;
00845 }
00846
00847 int LdapOperation::rename( const LdapDN &dn, const QString &newRdn,
00848 const QString &newSuperior, bool deleteold )
00849 {
00850 Q_ASSERT( d->mConnection );
00851 LDAP *ld = (LDAP*) d->mConnection->handle();
00852
00853 int msgid;
00854
00855 LDAPControl **serverctrls = 0, **clientctrls = 0;
00856 createControls( &serverctrls, d->mServerCtrls );
00857 createControls( &serverctrls, d->mClientCtrls );
00858
00859 int retval = ldap_rename( ld, dn.toString().toUtf8().data(), newRdn.toUtf8().data(),
00860 newSuperior.isEmpty() ? (char *) 0 : newSuperior.toUtf8().data(),
00861 deleteold, serverctrls, clientctrls, &msgid );
00862
00863 ldap_controls_free( serverctrls );
00864 ldap_controls_free( clientctrls );
00865
00866 if ( retval == 0 ) {
00867 retval = msgid;
00868 }
00869 return retval;
00870 }
00871
00872 int LdapOperation::rename_s( const LdapDN &dn, const QString &newRdn,
00873 const QString &newSuperior, bool deleteold )
00874 {
00875 Q_ASSERT( d->mConnection );
00876 LDAP *ld = (LDAP*) d->mConnection->handle();
00877
00878 LDAPControl **serverctrls = 0, **clientctrls = 0;
00879 createControls( &serverctrls, d->mServerCtrls );
00880 createControls( &serverctrls, d->mClientCtrls );
00881
00882 int retval = ldap_rename_s( ld, dn.toString().toUtf8().data(), newRdn.toUtf8().data(),
00883 newSuperior.isEmpty() ? (char *) 0 : newSuperior.toUtf8().data(),
00884 deleteold, serverctrls, clientctrls );
00885
00886 ldap_controls_free( serverctrls );
00887 ldap_controls_free( clientctrls );
00888
00889 return retval;
00890 }
00891
00892 int LdapOperation::del( const LdapDN &dn )
00893 {
00894 Q_ASSERT( d->mConnection );
00895 LDAP *ld = (LDAP*) d->mConnection->handle();
00896
00897 int msgid;
00898
00899 LDAPControl **serverctrls = 0, **clientctrls = 0;
00900 createControls( &serverctrls, d->mServerCtrls );
00901 createControls( &serverctrls, d->mClientCtrls );
00902
00903 int retval =
00904 ldap_delete_ext( ld, dn.toString().toUtf8().data(), serverctrls, clientctrls, &msgid );
00905
00906 ldap_controls_free( serverctrls );
00907 ldap_controls_free( clientctrls );
00908
00909 if ( retval == 0 ) {
00910 retval = msgid;
00911 }
00912 return retval;
00913 }
00914
00915 int LdapOperation::del_s( const LdapDN &dn )
00916 {
00917 Q_ASSERT( d->mConnection );
00918 LDAP *ld = (LDAP*) d->mConnection->handle();
00919
00920 LDAPControl **serverctrls = 0, **clientctrls = 0;
00921 createControls( &serverctrls, d->mServerCtrls );
00922 createControls( &serverctrls, d->mClientCtrls );
00923
00924 int retval = ldap_delete_ext_s( ld, dn.toString().toUtf8().data(), serverctrls, clientctrls );
00925
00926 ldap_controls_free( serverctrls );
00927 ldap_controls_free( clientctrls );
00928
00929 return retval;
00930 }
00931
00932 int LdapOperation::modify( const LdapDN &dn, const ModOps &ops )
00933 {
00934 Q_ASSERT( d->mConnection );
00935 LDAP *ld = (LDAP *)d->mConnection->handle();
00936
00937 int msgid;
00938 LDAPMod **lmod = 0;
00939
00940 LDAPControl **serverctrls = 0, **clientctrls = 0;
00941 createControls( &serverctrls, d->mServerCtrls );
00942 createControls( &serverctrls, d->mClientCtrls );
00943
00944 for ( int i = 0; i < ops.count(); ++i ) {
00945 int mtype = 0;
00946 switch ( ops[i].type ) {
00947 case Mod_None:
00948 mtype = 0;
00949 break;
00950 case Mod_Add:
00951 mtype = LDAP_MOD_ADD;
00952 break;
00953 case Mod_Replace:
00954 mtype = LDAP_MOD_REPLACE;
00955 break;
00956 case Mod_Del:
00957 mtype = LDAP_MOD_DELETE;
00958 break;
00959 }
00960 addModOp( &lmod, mtype, ops[i].attr, 0 );
00961 for ( int j = 0; j < ops[i].values.count(); ++j ) {
00962 addModOp( &lmod, mtype, ops[i].attr, &ops[i].values[j] );
00963 }
00964 }
00965
00966 int retval =
00967 ldap_modify_ext( ld, dn.toString().toUtf8().data(), lmod, serverctrls, clientctrls, &msgid );
00968
00969 ldap_controls_free( serverctrls );
00970 ldap_controls_free( clientctrls );
00971 ldap_mods_free( lmod, 1 );
00972 if ( retval == 0 ) {
00973 retval = msgid;
00974 }
00975 return retval;
00976 }
00977
00978 int LdapOperation::modify_s( const LdapDN &dn, const ModOps &ops )
00979 {
00980 Q_ASSERT( d->mConnection );
00981 LDAP *ld = (LDAP*) d->mConnection->handle();
00982
00983 LDAPMod **lmod = 0;
00984
00985 LDAPControl **serverctrls = 0, **clientctrls = 0;
00986 createControls( &serverctrls, d->mServerCtrls );
00987 createControls( &serverctrls, d->mClientCtrls );
00988
00989 for ( int i = 0; i < ops.count(); ++i ) {
00990 int mtype = 0;
00991 switch ( ops[i].type ) {
00992 case Mod_None:
00993 mtype = 0;
00994 break;
00995 case Mod_Add:
00996 mtype = LDAP_MOD_ADD;
00997 break;
00998 case Mod_Replace:
00999 mtype = LDAP_MOD_REPLACE;
01000 break;
01001 case Mod_Del:
01002 mtype = LDAP_MOD_DELETE;
01003 break;
01004 }
01005 addModOp( &lmod, mtype, ops[i].attr, 0 );
01006 for ( int j = 0; j < ops[i].values.count(); ++j ) {
01007 addModOp( &lmod, mtype, ops[i].attr, &ops[i].values[j] );
01008 }
01009 }
01010
01011 int retval =
01012 ldap_modify_ext_s( ld, dn.toString().toUtf8().data(), lmod, serverctrls, clientctrls );
01013
01014 ldap_controls_free( serverctrls );
01015 ldap_controls_free( clientctrls );
01016 ldap_mods_free( lmod, 1 );
01017 return retval;
01018 }
01019
01020 int LdapOperation::compare( const LdapDN &dn, const QString &attr, const QByteArray &value )
01021 {
01022 Q_ASSERT( d->mConnection );
01023 LDAP *ld = (LDAP*) d->mConnection->handle();
01024 int msgid;
01025
01026 LDAPControl **serverctrls = 0, **clientctrls = 0;
01027 createControls( &serverctrls, d->mServerCtrls );
01028 createControls( &serverctrls, d->mClientCtrls );
01029
01030 int vallen = value.size();
01031 BerValue *berval;
01032 berval = (BerValue *) malloc( sizeof( BerValue ) );
01033 berval -> bv_val = (char *) malloc( vallen );
01034 berval -> bv_len = vallen;
01035 memcpy( berval -> bv_val, value.data(), vallen );
01036
01037 int retval = ldap_compare_ext( ld, dn.toString().toUtf8().data(), attr.toUtf8().data(), berval,
01038 serverctrls, clientctrls, &msgid );
01039
01040 ber_bvfree( berval );
01041 ldap_controls_free( serverctrls );
01042 ldap_controls_free( clientctrls );
01043
01044 if ( retval == 0 ) {
01045 retval = msgid;
01046 }
01047 return retval;
01048 }
01049
01050 int LdapOperation::compare_s( const LdapDN &dn, const QString &attr, const QByteArray &value )
01051 {
01052 Q_ASSERT( d->mConnection );
01053 LDAP *ld = (LDAP*) d->mConnection->handle();
01054
01055 LDAPControl **serverctrls = 0, **clientctrls = 0;
01056 createControls( &serverctrls, d->mServerCtrls );
01057 createControls( &serverctrls, d->mClientCtrls );
01058
01059 int vallen = value.size();
01060 BerValue *berval;
01061 berval = (BerValue *) malloc( sizeof( BerValue ) );
01062 berval -> bv_val = (char *) malloc( vallen );
01063 berval -> bv_len = vallen;
01064 memcpy( berval -> bv_val, value.data(), vallen );
01065
01066 int retval = ldap_compare_ext_s( ld, dn.toString().toUtf8().data(), attr.toUtf8().data(), berval,
01067 serverctrls, clientctrls );
01068
01069 ber_bvfree( berval );
01070 ldap_controls_free( serverctrls );
01071 ldap_controls_free( clientctrls );
01072
01073 return retval;
01074 }
01075
01076 int LdapOperation::exop( const QString &oid, const QByteArray &data )
01077 {
01078 Q_ASSERT( d->mConnection );
01079 #if defined(HAVE_LDAP_EXTENDED_OPERATION) && defined(HAVE_LDAP_EXTENDED_OPERATION_PROTOTYPE)
01080 LDAP *ld = (LDAP*) d->mConnection->handle();
01081 int msgid;
01082
01083 LDAPControl **serverctrls = 0, **clientctrls = 0;
01084 createControls( &serverctrls, d->mServerCtrls );
01085 createControls( &serverctrls, d->mClientCtrls );
01086
01087 int vallen = data.size();
01088 BerValue *berval;
01089 berval = (BerValue *) malloc( sizeof( BerValue ) );
01090 berval -> bv_val = (char *) malloc( vallen );
01091 berval -> bv_len = vallen;
01092 memcpy( berval -> bv_val, data.data(), vallen );
01093
01094 int retval = ldap_extended_operation( ld, oid.toUtf8().data(), berval,
01095 serverctrls, clientctrls, &msgid );
01096
01097 ber_bvfree( berval );
01098 ldap_controls_free( serverctrls );
01099 ldap_controls_free( clientctrls );
01100
01101 if ( retval == 0 ) {
01102 retval = msgid;
01103 }
01104 return retval;
01105 #else
01106 kError() << "Your LDAP client libraries don't support extended operations.";
01107 return -1;
01108 #endif
01109 }
01110
01111 int LdapOperation::exop_s( const QString &oid, const QByteArray &data )
01112 {
01113 #if defined(HAVE_LDAP_EXTENDED_OPERATION) && defined(HAVE_LDAP_EXTENDED_OPERATION_PROTOTYPE)
01114 Q_ASSERT( d->mConnection );
01115 LDAP *ld = (LDAP*) d->mConnection->handle();
01116 BerValue *retdata;
01117 char *retoid;
01118
01119 LDAPControl **serverctrls = 0, **clientctrls = 0;
01120 createControls( &serverctrls, d->mServerCtrls );
01121 createControls( &serverctrls, d->mClientCtrls );
01122
01123 int vallen = data.size();
01124 BerValue *berval;
01125 berval = (BerValue *) malloc( sizeof( BerValue ) );
01126 berval -> bv_val = (char *) malloc( vallen );
01127 berval -> bv_len = vallen;
01128 memcpy( berval -> bv_val, data.data(), vallen );
01129
01130 int retval = ldap_extended_operation_s( ld, oid.toUtf8().data(), berval,
01131 serverctrls, clientctrls, &retoid, &retdata );
01132
01133 ber_bvfree( berval );
01134 ber_bvfree( retdata );
01135 free( retoid );
01136 ldap_controls_free( serverctrls );
01137 ldap_controls_free( clientctrls );
01138
01139 return retval;
01140 #else
01141 kError() << "Your LDAP client libraries don't support extended operations.";
01142 return -1;
01143 #endif
01144 }
01145
01146 int LdapOperation::abandon( int id )
01147 {
01148 Q_ASSERT( d->mConnection );
01149 LDAP *ld = (LDAP*) d->mConnection->handle();
01150
01151 LDAPControl **serverctrls = 0, **clientctrls = 0;
01152 createControls( &serverctrls, d->mServerCtrls );
01153 createControls( &serverctrls, d->mClientCtrls );
01154
01155 int retval = ldap_abandon_ext( ld, id, serverctrls, clientctrls );
01156
01157 ldap_controls_free( serverctrls );
01158 ldap_controls_free( clientctrls );
01159
01160 return retval;
01161 }
01162
01163 int LdapOperation::waitForResult( int id, int msecs )
01164 {
01165 Q_ASSERT( d->mConnection );
01166 LDAP *ld = (LDAP*) d->mConnection->handle();
01167
01168 LDAPMessage *msg;
01169 int rescode;
01170
01171 QTime stopWatch;
01172 stopWatch.start();
01173 int attempt( 1 );
01174 int timeout( 0 );
01175
01176 do {
01177
01178
01179 timeout = kldap_timeout_value( msecs, stopWatch.elapsed() );
01180 kDebug() << "(" << id << "," << msecs
01181 << "): Waiting" << timeout
01182 << "msecs for result. Attempt #" << attempt++;
01183 struct timeval tv;
01184 tv.tv_sec = timeout / 1000;
01185 tv.tv_usec = ( timeout % 1000 ) * 1000;
01186
01187
01188 rescode = ldap_result( ld, id, 0, timeout < 0 ? 0 : &tv, &msg );
01189 if ( rescode == -1 ) {
01190 return -1;
01191 }
01192
01193 if ( rescode != 0 ) {
01194
01195 return d->processResult( rescode, msg );
01196 }
01197 } while ( msecs == -1 || stopWatch.elapsed() < msecs );
01198
01199 return 0;
01200 }
01201
01202 #else
01203
01204 int LdapOperation::bind( const QByteArray &creds, SASL_Callback_Proc *saslproc, void *data )
01205 {
01206 kError() << "LDAP support not compiled";
01207 return -1;
01208 }
01209
01210 int LdapOperation::bind_s( SASL_Callback_Proc *saslproc, void *data )
01211 {
01212 kError() << "LDAP support not compiled";
01213 return -1;
01214 }
01215
01216 int LdapOperation::search( const LdapDN &base, LdapUrl::Scope scope,
01217 const QString &filter, const QStringList &attributes )
01218 {
01219 kError() << "LDAP support not compiled";
01220 return -1;
01221 }
01222
01223 int LdapOperation::add( const LdapObject &object )
01224 {
01225 kError() << "LDAP support not compiled";
01226 return -1;
01227 }
01228
01229 int LdapOperation::add_s( const LdapObject &object )
01230 {
01231 kError() << "LDAP support not compiled";
01232 return -1;
01233 }
01234
01235 int LdapOperation::add( const LdapDN &dn, const ModOps &ops )
01236 {
01237 kError() << "LDAP support not compiled";
01238 return -1;
01239 }
01240
01241 int LdapOperation::add_s( const LdapDN &dn, const ModOps &ops )
01242 {
01243 kError() << "LDAP support not compiled";
01244 return -1;
01245 }
01246
01247 int LdapOperation::rename( const LdapDN &dn, const QString &newRdn,
01248 const QString &newSuperior, bool deleteold )
01249 {
01250 kError() << "LDAP support not compiled";
01251 return -1;
01252 }
01253
01254 int LdapOperation::rename_s( const LdapDN &dn, const QString &newRdn,
01255 const QString &newSuperior, bool deleteold )
01256 {
01257 kError() << "LDAP support not compiled";
01258 return -1;
01259 }
01260
01261 int LdapOperation::del( const LdapDN &dn )
01262 {
01263 kError() << "LDAP support not compiled";
01264 return -1;
01265 }
01266
01267 int LdapOperation::del_s( const LdapDN &dn )
01268 {
01269 kError() << "LDAP support not compiled";
01270 return -1;
01271 }
01272
01273 int LdapOperation::modify( const LdapDN &dn, const ModOps &ops )
01274 {
01275 kError() << "LDAP support not compiled";
01276 return -1;
01277 }
01278
01279 int LdapOperation::modify_s( const LdapDN &dn, const ModOps &ops )
01280 {
01281 kError() << "LDAP support not compiled";
01282 return -1;
01283 }
01284
01285 int LdapOperation::compare( const LdapDN &dn, const QString &attr, const QByteArray &value )
01286 {
01287 kError() << "LDAP support not compiled";
01288 return -1;
01289 }
01290
01291 int LdapOperation::exop( const QString &oid, const QByteArray &data )
01292 {
01293 kError() << "LDAP support not compiled";
01294 return -1;
01295 }
01296
01297 int LdapOperation::compare_s( const LdapDN &dn, const QString &attr, const QByteArray &value )
01298 {
01299 kError() << "LDAP support not compiled";
01300 return -1;
01301 }
01302
01303 int LdapOperation::exop_s( const QString &oid, const QByteArray &data )
01304 {
01305 kError() << "LDAP support not compiled";
01306 return -1;
01307 }
01308
01309 int LdapOperation::waitForResult( int id, int msecs )
01310 {
01311 kError() << "LDAP support not compiled";
01312 return -1;
01313 }
01314
01315 int LdapOperation::abandon( int id )
01316 {
01317 kError() << "LDAP support not compiled";
01318 return -1;
01319 }
01320
01321 #endif