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