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