SVN_SILENT made messages (.desktop file)
[kdeadmin.git] / kuser / ku_userldap.cpp
blob6eea1add44cfd4e08794edbba8969b104eb07577
1 /*
2 * Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu>
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 **/
20 #include <QByteArray>
21 #include <QLabel>
22 #include <QCryptographicHash>
24 #include <kdebug.h>
25 #include <klocale.h>
26 #include <kio/kntlm.h>
27 #include <kldap/ldapdefs.h>
28 #include <kldap/ldapdn.h>
29 #include <kldap/ldapconnection.h>
30 #include <kldap/ldapoperation.h>
32 #include "ku_userldap.h"
33 #include "ku_misc.h"
35 KU_UserLDAP::KU_UserLDAP(KU_PrefsBase *cfg) : KU_Users( cfg )
37 schemaversion = 0;
39 if ( mCfg->ldapssl() )
40 mUrl.setProtocol("ldaps");
41 else
42 mUrl.setProtocol("ldap");
44 mUrl.setHost( mCfg->ldaphost() );
45 mUrl.setPort( mCfg->ldapport() );
46 mUrl.setDn( KLDAP::LdapDN( mCfg->ldapuserbase() + ',' + mCfg->ldapdn() ) );
47 if ( !mCfg->ldapanon() ) {
48 mUrl.setUser( mCfg->ldapuser() );
49 mUrl.setPass( mCfg->ldappassword() );
50 QString binddn = mCfg->ldapbinddn();
51 if ( !binddn.isEmpty() )
52 mUrl.setExtension( "bindname",binddn );
54 mUrl.setFilter( mCfg->ldapuserfilter() );
56 if ( mCfg->ldaptls() ) mUrl.setExtension( "x-tls", "" );
57 if ( mCfg->ldapsasl() ) {
58 mUrl.setExtension( "x-sasl", "" );
59 mUrl.setExtension( "x-mech", mCfg->ldapsaslmech() );
62 mUrl.setScope(KLDAP::LdapUrl::One);
63 mUrl.setExtension("x-dir","base");
65 if ( mCfg->ldaptimelimit() )
66 mUrl.setExtension("x-timelimit",QString::number(mCfg->ldaptimelimit()));
67 if ( mCfg->ldapsizelimit() )
68 mUrl.setExtension("x-sizelimit",QString::number(mCfg->ldapsizelimit()));
69 if ( mCfg->ldappagesize() )
70 mUrl.setExtension("x-pagesize",QString::number(mCfg->ldappagesize()));
72 caps = Cap_Passwd | Cap_Disable_POSIX;
73 if ( mCfg->ldapshadow() ) caps |= Cap_Shadow;
74 if ( mCfg->ldapstructural() == KU_PrefsBase::EnumLdapstructural::inetOrgPerson )
75 caps |= Cap_InetOrg;
77 if ( mCfg->ldapsam() ) {
78 caps |= Cap_Samba;
79 domsid = mCfg->samdomsid();
83 KU_UserLDAP::~KU_UserLDAP()
87 void KU_UserLDAP::result( KLDAP::LdapSearch *search )
89 kDebug() << "LDAP result: " << search->error() << " " << search->errorString();
90 mProg->hide();
92 if ( search->error() ) {
93 mErrorString = KLDAP::LdapConnection::errorString(search->error());
94 mErrorDetails = search->errorString();
95 mOk = false;
96 } else {
97 mOk = true;
101 void KU_UserLDAP::data( KLDAP::LdapSearch *, const KLDAP::LdapObject& data )
103 KU_User user;
104 QStringList objectclasses;
106 KLDAP::LdapAttrMap attrs = data.attributes();
107 for ( KLDAP::LdapAttrMap::ConstIterator it = attrs.constBegin(); it != attrs.constEnd(); ++it ) {
108 QString name = it.key().toLower();
109 if ( name == "objectclass" ) {
110 for ( KLDAP::LdapAttrValue::ConstIterator it2 = (*it).constBegin(); it2 != (*it).constEnd(); ++it2 ) {
111 if ( (*it2).toLower() == "posixaccount" )
112 user.setCaps( user.getCaps() | KU_User::Cap_POSIX );
113 else if ( (*it2).toLower() == "sambasamaccount" )
114 user.setCaps( user.getCaps() | KU_User::Cap_Samba );
115 else if ( (*it2).toLower() != "inetorgperson" &&
116 (*it2).toLower() != "shadowaccount" &&
117 (*it2).toLower() != "account" )
118 objectclasses.append( (*it2) );
120 continue;
123 KLDAP::LdapAttrValue values = (*it);
124 if ( values.isEmpty() ) continue;
125 QString val = QString::fromUtf8( values.first(), values.first().size() );
126 if ( name == "uidnumber" )
127 user.setUID( val.toLong() );
128 else if ( name == "gidnumber" )
129 user.setGID( val.toLong() );
130 else if ( name == "uid" || name == "userid" )
131 user.setName( val );
132 else if ( name == "sn" )
133 user.setSurname( val );
134 else if ( name == "mail" )
135 user.setEmail( val );
136 else if ( name == "homedirectory" )
137 user.setHomeDir( val );
138 else if ( name == "loginshell" )
139 user.setShell( val );
140 else if ( name == "postaladdress" )
141 user.setAddress( val );
142 else if ( name == "telephonenumber" ) {
143 user.setOffice1( val );
144 if ( values.size() > 1 )
145 user.setOffice2( QString::fromUtf8( values[1], values[1].size() ) );
146 } else if ( name == "gecos" ) {
147 QString name, f1, f2, f3;
148 parseGecos( values.first(), name, f1, f2, f3 );
149 if ( user.getFullName().isEmpty() ) user.setFullName( val );
150 if ( user.getOffice1().isEmpty() ) user.setOffice1( f1 );
151 if ( user.getOffice2().isEmpty() ) user.setOffice2( f1 );
152 if ( user.getAddress().isEmpty() ) user.setAddress( f1 );
153 } else if ( name == "cn" ) {
154 if ( user.getFullName().isEmpty() || mCfg->ldapcnfullname() )
155 user.setFullName( val );
156 if ( user.getName().isEmpty() )
157 user.setName( val );
158 } else if ( name == "displayname" ) {
159 user.setFullName( val );
160 } else if ( name == "userpassword" ) {
161 if ( !val.isEmpty() ) user.setDisabled( false );
162 user.setPwd( val );
163 } else if ( name == "shadowlastchange" ) {
164 if ( user.getLastChange() == 0 ) //sambapwdlastset is more precise
165 user.setLastChange( daysToTime( val.toLong() ) );
166 } else if ( name == "shadowmin" )
167 user.setMin( val.toInt() );
168 else if ( name == "shadowmax" )
169 user.setMax( val.toLong() );
170 else if ( name == "shadowwarning" )
171 user.setWarn( val.toLong() );
172 else if ( name == "shadowinactive" )
173 user.setInactive( val.toLong() );
174 else if ( name == "shadowexpire" )
175 user.setExpire( val.toLong() );
176 else if ( name == "shadowflag" )
177 user.setFlag( val.toLong() );
178 else if ( name == "sambaacctflags" ) {
179 if ( !val.contains( 'D' ) ) user.setDisabled( false );
180 } else if ( name == "sambasid" )
181 user.setSID( val );
182 else if ( name == "sambaprimarygroupsid" )
183 user.setPGSID( val );
184 else if ( name == "sambalmpassword" )
185 user.setLMPwd( val );
186 else if ( name == "sambantpassword" )
187 user.setNTPwd( val );
188 else if ( name == "sambahomepath" )
189 user.setHomePath( val );
190 else if ( name == "sambahomedrive" )
191 user.setHomeDrive( val );
192 else if ( name == "sambalogonscript" )
193 user.setLoginScript( val );
194 else if ( name == "sambaprofilepath" )
195 user.setProfilePath( val );
196 else if ( name == "sambauserworkstations" )
197 user.setWorkstations( val );
198 else if ( name == "sambadomainname" )
199 user.setDomain( val );
200 else if ( name == "sambapwdlastset" )
201 user.setLastChange( val.toLong() );
202 //these new attributes introduced around samba 3.0.6
203 else if ( name == "sambapasswordhistory" || name == "sambalogonhours" )
204 schemaversion = 1;
208 kDebug() << "new user: " << user.getName();
209 if ( !objectclasses.isEmpty() ) {
210 mObjectClasses.insert( count(), objectclasses );
211 kDebug() << "user: " << user.getName() << " other objectclasses: " << objectclasses.join(",");
213 append( user );
215 if ( ( count() & 7 ) == 7 ) {
216 mProg->setValue( mProg->value() + mAdv );
217 if ( mProg->value() == 0 ) mAdv = 1;
218 if ( mProg->value() == mProg->maximum()-1 ) mAdv = -1;
222 bool KU_UserLDAP::reload()
224 kDebug() << "KU_UserLDAP::reload()";
225 mErrorString = mErrorDetails = QString();
226 mObjectClasses.clear();
227 mProg = new QProgressDialog( 0 );
228 mProg->setLabel( new QLabel( i18n("Loading Users From LDAP") ) );
229 mProg->setAutoClose( false );
230 mProg->setAutoReset( false );
231 mProg->setMaximum( 100 );
232 mAdv = 1;
233 mOk = true;
234 mProg->show();
235 qApp->processEvents();
236 KLDAP::LdapSearch search;
238 connect( &search,
239 SIGNAL( data( KLDAP::LdapSearch*, const KLDAP::LdapObject& ) ),
240 this, SLOT ( data ( KLDAP::LdapSearch*, const KLDAP::LdapObject&) ) );
241 connect( &search,
242 SIGNAL( result( KLDAP::LdapSearch* ) ),
243 this, SLOT ( result ( KLDAP::LdapSearch* ) ) );
245 if (search.search( mUrl )) {
246 mProg->exec();
247 if ( mProg->wasCanceled() ) search.abandon();
248 } else {
249 kDebug() << "search failed";
250 mOk = false;
251 mErrorString = KLDAP::LdapConnection::errorString(search.error());
252 mErrorDetails = search.errorString();
254 delete mProg;
255 return( mOk );
258 QString KU_UserLDAP::getRDN(const KU_User &user) const
260 switch ( mCfg->ldapuserrdn() ) {
261 case KU_PrefsBase::EnumLdapuserrdn::uid:
262 return "uid=" + user.getName();
263 case KU_PrefsBase::EnumLdapuserrdn::uidNumber:
264 return "uidNumber=" + QString::number( user.getUID() );
265 case KU_PrefsBase::EnumLdapuserrdn::cn: {
266 QString cn = mCfg->ldapcnfullname() ? user.getFullName() : user.getName();
267 if ( cn.isEmpty() ) cn = user.getName();
268 return "cn=" + cn;
271 return "";
274 void KU_UserLDAP::createPassword( KU_User &user, const QString &password )
276 switch ( mCfg->ldappasswordhash() ) {
277 case KU_PrefsBase::EnumLdappasswordhash::Clear:
278 user.setPwd( password );
279 break;
280 case KU_PrefsBase::EnumLdappasswordhash::CRYPT:
281 user.setPwd( "{CRYPT}" + encryptPass( password, false ) );
282 break;
283 case KU_PrefsBase::EnumLdappasswordhash::MD5: {
284 QCryptographicHash md5(QCryptographicHash::Md5);
285 md5.addData( password.toUtf8() );
286 user.setPwd( "{MD5}" + md5.result().toBase64() );
287 break;
289 case KU_PrefsBase::EnumLdappasswordhash::SMD5: {
290 QCryptographicHash md5(QCryptographicHash::Md5);
291 QByteArray salt = genSalt( 8 );
292 QByteArray pwd = password.toUtf8() + salt;
294 md5.addData( pwd );
295 user.setPwd( "{SMD5}" + (md5.result() + salt).toBase64() );
296 break;
298 case KU_PrefsBase::EnumLdappasswordhash::SHA: {
299 QCryptographicHash sha1(QCryptographicHash::Sha1);
301 sha1.addData( password.toUtf8() );
302 user.setPwd( "{SHA}" + sha1.result().toBase64() );
303 break;
305 case KU_PrefsBase::EnumLdappasswordhash::SSHA: {
306 QCryptographicHash sha1(QCryptographicHash::Sha1);
308 QByteArray salt = genSalt( 8 );
309 QByteArray pwd = password.toUtf8() + salt;
311 sha1.addData( pwd );
312 user.setPwd( "{SSHA}" + (sha1.result() + salt).toBase64() );
313 break;
317 if ( caps & Cap_Samba ) {
318 quint8 hex[33];
320 QByteArray ntlmhash;
321 ntlmhash = KNTLM::ntlmHash( password );
322 unsigned char *hash = (unsigned char*) ntlmhash.data();
324 snprintf( (char*) &hex, 33,
325 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
326 hash[0], hash[1], hash[2], hash[3], hash[4], hash[5],
327 hash[6], hash[7], hash[8], hash[9], hash[10], hash[11],
328 hash[12], hash[13], hash[14], hash[15]);
330 user.setNTPwd( QString::fromLatin1( (const char*) &hex, 32 ) );
332 if ( mCfg->lanmanhash() ) {
334 QByteArray lmhash;
335 lmhash = KNTLM::lmHash( password );
336 unsigned char *hash = (unsigned char*) lmhash.data();
337 snprintf( (char*) &hex, 33,
338 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
339 hash[0], hash[1], hash[2], hash[3], hash[4], hash[5],
340 hash[6], hash[7], hash[8], hash[9], hash[10], hash[11],
341 hash[12], hash[13], hash[14], hash[15]);
343 user.setLMPwd( QString::fromLatin1( (const char*) &hex, 32 ) );
344 } else {
345 user.setLMPwd( "" );
350 void KU_UserLDAP::createModStruct( const KU_User &user, int oldindex, KLDAP::LdapOperation::ModOps &ops)
352 QString gecos, cn, pwd, samflags;
353 QList<QByteArray> vals;
355 bool mod = ( oldindex != -1 );
357 pwd = user.getPwd();
358 if ( user.getDisabled() ) pwd = "";
360 cn = mCfg->ldapcnfullname() ? user.getFullName() : user.getName();
361 if ( cn.isEmpty() ) cn = user.getName();
363 gecos = QString::fromLatin1("%1,%2,%3,%4")
364 .arg(user.getFullName())
365 .arg(user.getOffice1())
366 .arg(user.getOffice2())
367 .arg(user.getAddress());
369 samflags = "[U";
370 samflags += user.getDisabled() ? 'D' : ' ';
371 samflags += " ]";
373 vals.append( caps & Cap_InetOrg ? "inetOrgPerson" : "account" );
374 if ( user.getCaps() & KU_User::Cap_POSIX ) {
375 vals.append( "posixAccount" );
377 if ( ( caps & Cap_Shadow ) && ( user.getCaps() & KU_User::Cap_POSIX ) ) {
378 vals.append( "shadowAccount" );
380 if ( ( caps & Cap_Samba ) && ( user.getCaps() & KU_User::Cap_Samba ) ) {
381 vals.append( "sambaSamAccount" );
384 if ( mod && mObjectClasses.contains( oldindex ) ) {
385 QStringList ocs = mObjectClasses[ oldindex ];
386 kDebug() << user.getName() << " has additional objectclasses: " << ocs.join(",");
387 QStringList::iterator it;
388 for ( it = ocs.begin(); it != ocs.end(); ++it ) {
389 vals.append( (*it).toUtf8() );
392 ku_add2ops( ops, "objectClass", vals );
393 vals.clear();
395 ku_add2ops( ops, "cn", cn.toUtf8() );
396 ku_add2ops( ops, caps & Cap_InetOrg ? "uid" : "userid", user.getName().toUtf8() );
398 if ( ( user.getCaps() & KU_User::Cap_POSIX ) || ( caps & Cap_InetOrg ) ) {
399 ku_add2ops( ops, "userpassword", pwd.toUtf8(), true );
402 if ( user.getCaps() & KU_User::Cap_POSIX ) {
403 ku_add2ops( ops, "uidnumber", QString::number(user.getUID()).toUtf8() );
404 ku_add2ops( ops, "gidnumber", QString::number(user.getGID()).toUtf8() );
405 ku_add2ops( ops, "gecos", !mCfg->ldapgecos() ? QByteArray() : QByteArray( gecos.toLatin1() ) );
406 ku_add2ops( ops, "homedirectory", user.getHomeDir().toUtf8() );
407 ku_add2ops( ops, "loginshell", user.getShell().toUtf8() );
408 } else if (mod) {
409 ku_add2ops( ops, "uidnumber" );
410 ku_add2ops( ops, "gidnumber" );
411 ku_add2ops( ops, "gecos" );
412 ku_add2ops( ops, "homedirectory" );
413 ku_add2ops( ops, "loginshell" );
416 if ( caps & Cap_InetOrg ) {
417 ku_add2ops( ops, "sn", user.getSurname().toUtf8() );
418 ku_add2ops( ops, "mail", user.getEmail().toUtf8() );
419 ku_add2ops( ops, "displayName", user.getFullName().toUtf8() );
420 ku_add2ops( ops, "postaladdress", user.getAddress().toUtf8() );
421 vals.append( user.getOffice1().toUtf8() );
422 vals.append( user.getOffice2().toUtf8() );
423 ku_add2ops( ops, "telephoneNumber", vals );
424 vals.clear();
427 if ( caps & Cap_Samba ) {
428 if ( user.getCaps() & KU_User::Cap_Samba ) {
429 ku_add2ops( ops, "sambadomainname", user.getDomain().toUtf8() );
430 ku_add2ops( ops, "sambauserworkstations", user.getWorkstations().toUtf8() );
431 ku_add2ops( ops, "sambahomepath", user.getHomePath().toUtf8() );
432 ku_add2ops( ops, "sambahomedrive", user.getHomeDrive().toUtf8() );
433 ku_add2ops( ops, "sambalogonscript", user.getLoginScript().toUtf8() );
434 ku_add2ops( ops, "sambaprofilepath", user.getProfilePath().toUtf8() );
435 ku_add2ops( ops, "sambalmpassword", user.getLMPwd().toUtf8() );
436 ku_add2ops( ops, "sambantpassword", user.getNTPwd().toUtf8() );
437 ku_add2ops( ops, "sambasid", user.getSID().getSID().toUtf8() );
438 ku_add2ops( ops, "sambaacctflags", samflags.toUtf8() );
439 ku_add2ops( ops, "sambaprimarygroupsid", user.getPGSID().getSID().toUtf8() );
440 ku_add2ops( ops, "sambapwdlastset", QString::number( user.getLastChange() ).toUtf8() );
441 if ( user.getExpire() != -1 )
442 vals.append( QString::number( user.getExpire() ).toUtf8() );
443 ku_add2ops( ops, "sambakickofftime", vals );
444 vals.clear();
445 } else if (mod) {
446 ku_add2ops( ops, "sambadomainname" );
447 ku_add2ops( ops, "sambauserworkstations" );
448 ku_add2ops( ops, "sambahomepath" );
449 ku_add2ops( ops, "sambahomedrive" );
450 ku_add2ops( ops, "sambalogonscript" );
451 ku_add2ops( ops, "sambaprofilepath" );
452 ku_add2ops( ops, "sambalmpassword" );
453 ku_add2ops( ops, "sambantpassword" );
454 ku_add2ops( ops, "sambasid" );
455 ku_add2ops( ops, "sambaacctflags" );
456 ku_add2ops( ops, "sambaprimarygroupsid" );
457 ku_add2ops( ops, "sambapwdlastset" );
458 ku_add2ops( ops, "sambakickofftime" );
459 if ( schemaversion > 0 ) {
460 ku_add2ops( ops, "sambapasswordhistory" );
461 ku_add2ops( ops, "sambalogonhours" );
466 if ( caps & Cap_Shadow ) {
467 if ( user.getCaps() & KU_User::Cap_POSIX ) {
468 ku_add2ops( ops, "shadowlastchange", QString::number( timeToDays( user.getLastChange() ) ).toUtf8() );
469 ku_add2ops( ops, "shadowmin", QString::number( user.getMin() ).toUtf8() );
470 ku_add2ops( ops, "shadowmax", QString::number( user.getMax() ).toUtf8() );
471 ku_add2ops( ops, "shadowwarning", QString::number( user.getWarn() ).toUtf8() );
472 ku_add2ops( ops, "shadowinactive", QString::number( user.getInactive() ).toUtf8() );
473 ku_add2ops( ops, "shadowexpire", QString::number( timeToDays( user.getExpire() ) ).toUtf8() );
474 ku_add2ops( ops, "shadowflag", QString::number( user.getFlag() ).toUtf8() );
475 } else if (mod) {
476 ku_add2ops( ops, "shadowlastchange" );
477 ku_add2ops( ops, "shadowmin" );
478 ku_add2ops( ops, "shadowmax" );
479 ku_add2ops( ops, "shadowwarning" );
480 ku_add2ops( ops, "shadowinactive" );
481 ku_add2ops( ops, "shadowexpire" );
482 ku_add2ops( ops, "shadowflag" );
487 bool KU_UserLDAP::dbcommit()
489 mAddSucc.clear();
490 mDelSucc.clear();
491 mModSucc.clear();
492 mErrorString = mErrorDetails = QString();
494 KLDAP::LdapConnection conn( mUrl );
496 if ( conn.connect() != KLDAP_SUCCESS ) {
497 mErrorString = conn.connectionError();
498 return false;
501 KLDAP::LdapOperation op( conn );
503 if ( op.bind_s() != KLDAP_SUCCESS ) {
504 mErrorString = KLDAP::LdapConnection::errorString(conn.ldapErrorCode());
505 mErrorDetails = conn.ldapErrorString();
506 return false;
509 KLDAP::LdapOperation::ModOps ops;
511 mProg = new QProgressDialog( 0 );
512 mProg->setLabel( new QLabel(i18n("LDAP Operation") ) );
513 mProg->setAutoClose( false );
514 mProg->setAutoReset( false );
515 mProg->setMaximum( mAdd.count() + mDel.count() + mMod.count() );
517 //modify
518 for ( KU_Users::ModList::Iterator it = mMod.begin(); it != mMod.end(); ++it ) {
519 QString oldrdn = getRDN( at( it.key() ) );
520 QString newrdn = getRDN( it.value() );
522 if ( oldrdn != newrdn ) {
523 int ret = op.rename_s( KLDAP::LdapDN( oldrdn + ',' + mUrl.dn().toString() ),
524 newrdn,
525 mUrl.dn().toString().toUtf8(),
526 true );
528 if ( ret != KLDAP_SUCCESS ) {
529 mErrorString = KLDAP::LdapConnection::errorString(conn.ldapErrorCode());
530 mErrorDetails = conn.ldapErrorString();
531 delete mProg;
532 return false;
536 ops.clear();
537 createModStruct( it.value(), it.key(), ops );
538 int ret = op.modify_s( KLDAP::LdapDN( getRDN( it.value() ) + ',' + mUrl.dn().toString() ), ops );
539 if ( ret != KLDAP_SUCCESS ) {
540 mErrorString = KLDAP::LdapConnection::errorString(conn.ldapErrorCode());
541 mErrorDetails = conn.ldapErrorString();
542 delete mProg;
543 return false;
544 } else {
545 mModSucc.insert( it.key(), it.value() );
549 //add
550 for ( KU_Users::AddList::Iterator it = mAdd.begin(); it != mAdd.end(); ++it ) {
551 ops.clear();
552 createModStruct( (*it), -1, ops );
553 kDebug() << "add name: " << (*it).getName();
554 int ret = op.add_s( KLDAP::LdapDN( getRDN( (*it) ) + ',' + mUrl.dn().toString() ), ops );
555 if ( ret != KLDAP_SUCCESS ) {
556 mErrorString = KLDAP::LdapConnection::errorString(conn.ldapErrorCode());
557 mErrorDetails = conn.ldapErrorString();
558 delete mProg;
559 return false;
560 } else {
561 mAddSucc.append( (*it) );
565 //del
566 for ( KU_Users::DelList::Iterator it = mDel.begin(); it != mDel.end(); ++it ) {
567 kDebug() << "delete name: " << at((*it)).getName();
568 int ret = op.del_s( KLDAP::LdapDN( getRDN( at((*it)) ) + ',' + mUrl.dn().toString() ) );
569 if ( ret != KLDAP_SUCCESS ) {
570 mErrorString = KLDAP::LdapConnection::errorString(conn.ldapErrorCode());
571 mErrorDetails = conn.ldapErrorString();
572 delete mProg;
573 return false;
574 } else {
575 mDelSucc.append( (*it) );
579 delete mProg;
580 return true;
583 #include "ku_userldap.moc"