SVN_SILENT made messages (.desktop file)
[kdeadmin.git] / kuser / ku_userldap.cpp
blob819af336a93b73d5e000beff8833baa59c75c379
1 /*
2 * Copyright (c) 2004 Szombathelyi GyĂśrgy <gyurco@freemail.hu>
4 * This mProgram is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public
6 * License version 2 as published by the Free Software Foundation.
8 * This library is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Library General Public License for more details.
13 * You should have received a copy of the GNU Library General Public License
14 * along with this library; see the file COPYING.LIB. If not, write to
15 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 * Boston, MA 02110-1301, USA.
17 **/
19 #include <QByteArray>
20 #include <QLabel>
22 #include <kdebug.h>
23 #include <klocale.h>
24 #include <kcodecs.h>
25 #include <kio/kntlm.h>
26 #include <kldap/ldapdn.h>
28 #include "ku_userldap.h"
29 #include "ku_misc.h"
30 #include "sha1.h"
32 KU_UserLDAP::KU_UserLDAP(KU_PrefsBase *cfg) : KU_Users( cfg )
34 schemaversion = 0;
36 if ( mCfg->ldapssl() )
37 mUrl.setProtocol("ldaps");
38 else
39 mUrl.setProtocol("ldap");
41 mUrl.setHost( mCfg->ldaphost() );
42 mUrl.setPort( mCfg->ldapport() );
43 mUrl.setDn( KLDAP::LdapDN( mCfg->ldapuserbase() + "," + mCfg->ldapdn() ) );
44 if ( !mCfg->ldapanon() ) {
45 mUrl.setUser( mCfg->ldapuser() );
46 mUrl.setPass( mCfg->ldappassword() );
48 mUrl.setFilter( mCfg->ldapuserfilter() );
50 if ( mCfg->ldaptls() ) mUrl.setExtension( "x-tls", "" );
51 if ( mCfg->ldapsasl() ) {
52 mUrl.setExtension( "x-sasl", "" );
53 mUrl.setExtension( "x-mech", mCfg->ldapsaslmech() );
56 mUrl.setScope(KLDAP::LdapUrl::One);
57 mUrl.setExtension("x-dir","base");
59 if ( mCfg->ldaptimelimit() )
60 mUrl.setExtension("x-timelimit",QString::number(mCfg->ldaptimelimit()));
61 if ( mCfg->ldapsizelimit() )
62 mUrl.setExtension("x-sizelimit",QString::number(mCfg->ldapsizelimit()));
63 if ( mCfg->ldappagesize() )
64 mUrl.setExtension("x-pagesize",QString::number(mCfg->ldappagesize()));
66 caps = Cap_Passwd | Cap_Disable_POSIX;
67 if ( mCfg->ldapshadow() ) caps |= Cap_Shadow;
68 if ( mCfg->ldapstructural() ==
69 KU_PrefsBase::EnumLdapstructural::inetOrgPerson )
70 caps |= Cap_InetOrg;
72 if ( mCfg->ldapsam() ) {
73 caps |= Cap_Samba;
74 domsid = mCfg->samdomsid();
78 KU_UserLDAP::~KU_UserLDAP()
82 void KU_UserLDAP::result( KJob *job )
84 kDebug() << "LDAP result: " << job->error() << endl;
85 mProg->hide();
86 if ( job->error() && job->error() != KIO::ERR_USER_CANCELED ) {
87 QString errstr = job->errorString();
88 if ( !errstr.isEmpty() ) {
89 mErrorString = errstr;
90 // mErrorDetails = ldif;
91 } else {
92 mErrorString = i18n("Unknown error"); //this is better than nothing (?)
94 mOk = false;
95 } else {
96 mOk = true;
100 void KU_UserLDAP::data( KIO::Job *, const QByteArray& data )
102 if ( data.size() ) {
103 mParser.setLdif( data );
104 } else {
105 mParser.endLdif();
108 KLDAP::Ldif::ParseValue ret;
109 QString name, val;
110 QByteArray value;
111 do {
112 ret = mParser.nextItem();
113 switch ( ret ) {
114 case KLDAP::Ldif::Item:
115 name = mParser.attr().toLower();
116 value = mParser.value();
117 val = QString::fromUtf8( value, value.size() );
118 if ( name == "objectclass" ) {
119 if ( val.toLower() == "posixaccount" )
120 mUser.setCaps( mUser.getCaps() | KU_User::Cap_POSIX );
121 else if ( val.toLower() == "sambasamaccount" )
122 mUser.setCaps( mUser.getCaps() | KU_User::Cap_Samba );
123 else if ( val.toLower() != "inetorgperson" &&
124 val.toLower() != "shadowaccount" &&
125 val.toLower() != "account" )
126 mOc.append( val );
128 } else if ( name == "uidnumber" )
129 mUser.setUID( val.toLong() );
130 else if ( name == "gidnumber" )
131 mUser.setGID( val.toLong() );
132 else if ( name == "uid" || name == "userid" )
133 mUser.setName( val );
134 else if ( name == "sn" )
135 mUser.setSurname( val );
136 else if ( name == "mail" )
137 mUser.setEmail( val );
138 else if ( name == "homedirectory" )
139 mUser.setHomeDir( val );
140 else if ( name == "loginshell" )
141 mUser.setShell( val );
142 else if ( name == "postaladdress" )
143 mUser.setAddress( val );
144 else if ( name == "telephonenumber" ) {
145 if ( mUser.getOffice1().isEmpty() )
146 mUser.setOffice1( val );
147 else
148 mUser.setOffice2( val );
149 } else if ( name == "gecos" ) {
150 QString name, f1, f2, f3;
151 parseGecos( QByteArray( value.data(), value.size()+1 ), name, f1, f2, f3 );
152 if ( mUser.getFullName().isEmpty() ) mUser.setFullName( val );
153 if ( mUser.getOffice1().isEmpty() ) mUser.setOffice1( f1 );
154 if ( mUser.getOffice2().isEmpty() ) mUser.setOffice2( f1 );
155 if ( mUser.getAddress().isEmpty() ) mUser.setAddress( f1 );
156 } else if ( name == "cn" ) {
157 if ( mUser.getFullName().isEmpty() || mCfg->ldapcnfullname() )
158 mUser.setFullName( val );
159 if ( mUser.getName().isEmpty() )
160 mUser.setName( val );
161 } else if ( name == "displayname" ) {
162 mUser.setFullName( val );
163 } else if ( name == "userpassword" ) {
164 if ( !val.isEmpty() ) mUser.setDisabled( false );
165 mUser.setPwd( val );
166 } else if ( name == "shadowlastchange" ) {
167 if ( mUser.getLastChange() == 0 ) //sambapwdlastset is more precise
168 mUser.setLastChange( daysToTime( val.toLong() ) );
169 } else if ( name == "shadowmin" )
170 mUser.setMin( val.toInt() );
171 else if ( name == "shadowmax" )
172 mUser.setMax( val.toLong() );
173 else if ( name == "shadowwarning" )
174 mUser.setWarn( val.toLong() );
175 else if ( name == "shadowinactive" )
176 mUser.setInactive( val.toLong() );
177 else if ( name == "shadowexpire" )
178 mUser.setExpire( val.toLong() );
179 else if ( name == "shadowflag" )
180 mUser.setFlag( val.toLong() );
181 else if ( name == "sambaacctflags" ) {
182 if ( !val.contains( 'D' ) ) mUser.setDisabled( false );
183 } else if ( name == "sambasid" )
184 mUser.setSID( val );
185 else if ( name == "sambaprimarygroupsid" )
186 mUser.setPGSID( val );
187 else if ( name == "sambalmpassword" )
188 mUser.setLMPwd( val );
189 else if ( name == "sambantpassword" )
190 mUser.setNTPwd( val );
191 else if ( name == "sambahomepath" )
192 mUser.setHomePath( val );
193 else if ( name == "sambahomedrive" )
194 mUser.setHomeDrive( val );
195 else if ( name == "sambalogonscript" )
196 mUser.setLoginScript( val );
197 else if ( name == "sambaprofilepath" )
198 mUser.setProfilePath( val );
199 else if ( name == "sambauserworkstations" )
200 mUser.setWorkstations( val );
201 else if ( name == "sambadomainname" )
202 mUser.setDomain( val );
203 else if ( name == "sambapwdlastset" )
204 mUser.setLastChange( val.toLong() );
205 //these new attributes introduced around samba 3.0.6
206 else if ( name == "sambapasswordhistory" || name == "sambalogonhours" )
207 schemaversion = 1;
208 break;
209 case KLDAP::Ldif::EndEntry: {
210 kDebug() << "new user: " << mUser.getName() << endl;
211 if ( !mOc.isEmpty() ) {
212 mObjectClasses.insert( count(), mOc );
213 kDebug() << "user: " << mUser.getName() << " other objectclasses: " << mOc.join(",") << endl;
215 mOc.clear();
216 append( mUser );
217 mUser = KU_User();
218 mUser.setDisabled( true );
220 if ( ( count() & 7 ) == 7 ) {
221 mProg->setValue( mProg->value() + mAdv );
222 if ( mProg->value() == 0 ) mAdv = 1;
223 if ( mProg->value() == mProg->maximum()-1 ) mAdv = -1;
226 break;
228 default:
229 break;
231 } while ( ret != KLDAP::Ldif::MoreData );
234 bool KU_UserLDAP::reload()
236 kDebug() << "kuserldap::reload()" << endl;
237 mErrorString = mErrorDetails = QString();
238 mObjectClasses.clear();
239 mOc.clear();
240 mUser = KU_User();
241 mUser.setPwd( "" );
242 mUser.setSPwd( "" );
243 mParser.startParsing();
244 mProg = new QProgressDialog( 0 );
245 mProg->setLabel( new QLabel( i18n("Loading Users From LDAP") ) );
246 mProg->setAutoClose( false );
247 mProg->setAutoReset( false );
248 mProg->setMaximum( 100 );
249 mAdv = 1;
251 KIO::Job *job = KIO::get( mUrl, true, false );
252 connect( job, SIGNAL( data( KIO::Job*, const QByteArray& ) ),
253 this, SLOT( data( KIO::Job*, const QByteArray& ) ) );
254 connect( job, SIGNAL( result( KJob* ) ),
255 this, SLOT( result( KJob* ) ) );
256 // job->addMetaData( "SERVER_CTRL0", "1.2.840.113556.1.4.473 true: uidNumber");
257 mProg->exec();
258 if ( mProg->wasCanceled() ) job->kill();
259 delete mProg;
260 return( mOk );
263 QString KU_UserLDAP::getRDN(const KU_User &user) const
265 switch ( mCfg->ldapuserrdn() ) {
266 case KU_PrefsBase::EnumLdapuserrdn::uid:
267 return "uid=" + user.getName();
268 case KU_PrefsBase::EnumLdapuserrdn::uidNumber:
269 return "uidNumber=" + QString::number( user.getUID() );
270 case KU_PrefsBase::EnumLdapuserrdn::cn: {
271 QString cn = mCfg->ldapcnfullname() ? user.getFullName() : user.getName();
272 if ( cn.isEmpty() ) cn = user.getName();
273 return "cn=" + cn;
276 return "";
279 void KU_UserLDAP::createPassword( KU_User &user, const QString &password )
281 switch ( mCfg->ldappasswordhash() ) {
282 case KU_PrefsBase::EnumLdappasswordhash::Clear:
283 user.setPwd( password );
284 break;
285 case KU_PrefsBase::EnumLdappasswordhash::CRYPT:
286 user.setPwd( "{CRYPT}" + encryptPass( password, false ) );
287 break;
288 case KU_PrefsBase::EnumLdappasswordhash::MD5: {
289 KMD5 md5( password.toUtf8() );
290 user.setPwd( "{MD5}" + md5.base64Digest() );
291 break;
293 case KU_PrefsBase::EnumLdappasswordhash::SMD5: {
294 QByteArray salt = genSalt( 4 );
295 QByteArray pwd = password.toUtf8() + salt;
296 KMD5::Digest digest;
297 QByteArray hash(20, 0);
299 KMD5 md5( pwd );
300 md5.rawDigest( digest );
301 memcpy( hash.data(), digest, 16 );
302 memcpy( &(hash.data()[16]), salt.data(), 4 );
303 user.setPwd( "{SMD5}" + KCodecs::base64Encode( hash ) );
304 break;
306 case KU_PrefsBase::EnumLdappasswordhash::SHA: {
307 struct sha1_ctx ctx;
308 QByteArray hash(20, 0);
310 sha1_init( &ctx );
311 sha1_update( &ctx, (const quint8*) password.toUtf8().data(),
312 password.toUtf8().length() );
313 sha1_final( &ctx, (quint8*) hash.data() );
314 user.setPwd( "{SHA}" + KCodecs::base64Encode( ( hash ) ) );
315 break;
317 case KU_PrefsBase::EnumLdappasswordhash::SSHA: {
318 struct sha1_ctx ctx;
319 QByteArray hash(24, 0);
320 QByteArray salt = genSalt( 4 );
321 QByteArray pwd = password.toUtf8() + salt;
323 sha1_init( &ctx );
324 sha1_update( &ctx, (const quint8*) pwd.data(), pwd.length() );
325 sha1_final( &ctx, (quint8*) hash.data() );
326 memcpy( &(hash.data()[ 20 ]), salt.data(), 4 );
327 user.setPwd( "{SSHA}" + KCodecs::base64Encode( ( hash ) ) );
328 break;
332 if ( caps & Cap_Samba ) {
333 quint8 hex[33];
335 QByteArray ntlmhash;
336 ntlmhash = KNTLM::ntlmHash( password );
337 unsigned char *hash = (unsigned char*) ntlmhash.data();
339 snprintf( (char*) &hex, 33,
340 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
341 hash[0], hash[1], hash[2], hash[3], hash[4], hash[5],
342 hash[6], hash[7], hash[8], hash[9], hash[10], hash[11],
343 hash[12], hash[13], hash[14], hash[15]);
345 user.setNTPwd( QString::fromLatin1( (const char*) &hex, 32 ) );
347 if ( mCfg->lanmanhash() ) {
349 QByteArray lmhash;
350 lmhash = KNTLM::lmHash( password );
351 unsigned char *hash = (unsigned char*) lmhash.data();
352 snprintf( (char*) &hex, 33,
353 "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
354 hash[0], hash[1], hash[2], hash[3], hash[4], hash[5],
355 hash[6], hash[7], hash[8], hash[9], hash[10], hash[11],
356 hash[12], hash[13], hash[14], hash[15]);
358 user.setLMPwd( QString::fromLatin1( (const char*) &hex, 32 ) );
359 } else {
360 user.setLMPwd( "" );
365 QByteArray KU_UserLDAP::getLDIF( const KU_User &user, int oldindex ) const
367 QString gecos, cn, pwd, samflags;
368 QByteArray ldif;
370 bool mod = ( oldindex != -1 );
372 pwd = user.getPwd();
373 if ( user.getDisabled() ) pwd = "";
375 cn = mCfg->ldapcnfullname() ? user.getFullName() : user.getName();
376 if ( cn.isEmpty() ) cn = user.getName();
378 gecos = QString::fromLatin1("%1,%2,%3,%4")
379 .arg(user.getFullName())
380 .arg(user.getOffice1())
381 .arg(user.getOffice2())
382 .arg(user.getAddress());
384 samflags = "[U";
385 samflags += user.getDisabled() ? 'D' : ' ';
386 samflags += " ]";
388 ldif = "";
390 if ( mod ) {
391 QString oldrdn = getRDN( at( oldindex ) );
392 QString newrdn = getRDN( user );
394 if ( oldrdn != newrdn ) {
395 ldif = "dn: " + oldrdn.toUtf8() + "," + mUrl.dn().toString().toUtf8() + "\n" +
396 "changetype: modrdn\n" +
397 KLDAP::Ldif::assembleLine( "newrdn", newrdn ) + "\n" +
398 KLDAP::Ldif::assembleLine( "newSuperior", mUrl.dn().toString().toUtf8() )+ "\n" +
399 "deleteoldrdn: 1\n\n";
403 ldif += "dn: " + getRDN( user ).toUtf8() + "," + mUrl.dn().toString().toUtf8() + "\n";
404 if ( oldindex != -1 ) {
405 ldif += "changetype: modify\n";
406 ldif += "replace: objectClass\n";
409 if ( caps & Cap_InetOrg )
410 ldif += "objectClass: inetOrgPerson\n";
411 else
412 ldif += "objectClass: account\n";
414 if ( user.getCaps() & KU_User::Cap_POSIX ) {
415 ldif += "objectClass: posixAccount\n";
417 if ( ( caps & Cap_Shadow ) && ( user.getCaps() & KU_User::Cap_POSIX ) ) {
418 ldif += "objectClass: shadowAccount\n";
420 if ( ( caps & Cap_Samba ) && ( user.getCaps() & KU_User::Cap_Samba ) ) {
421 ldif += "objectClass: sambaSamAccount\n";
424 if ( mod && mObjectClasses.contains( oldindex ) ) {
425 QStringList ocs = mObjectClasses[ oldindex ];
426 kDebug() << user.getName() << " has additional objectclasses: " << ocs.join(",") << endl;
427 QStringList::iterator it;
428 for ( it = ocs.begin(); it != ocs.end(); ++it ) {
429 ldif += "objectClass: ";
430 ldif += (*it).toUtf8();
431 ldif += "\n";
435 if ( mod ) ldif += "-\nreplace: cn\n";
436 ldif += KLDAP::Ldif::assembleLine( "cn", cn )+"\n";
437 if ( caps & Cap_InetOrg ) {
438 if ( mod ) ldif += "-\nreplace: uid\n";
439 ldif += KLDAP::Ldif::assembleLine( "uid", user.getName() ) + "\n";
440 } else {
441 if ( mod ) ldif += "-\nreplace: userid\n";
442 ldif += KLDAP::Ldif::assembleLine( "userid", user.getName() ) + "\n";
444 if ( mod ) ldif += "-\n";
446 if ( ( user.getCaps() & KU_User::Cap_POSIX ) || ( caps & Cap_InetOrg ) ) {
447 if ( mod ) ldif += "replace: userpassword\n";
448 ldif += KLDAP::Ldif::assembleLine( "userpassword", pwd )+"\n";
449 if ( mod ) ldif += "-\n";
452 if ( user.getCaps() & KU_User::Cap_POSIX ) {
453 if ( mod ) ldif += "replace: uidnumber\n";
454 ldif += KLDAP::Ldif::assembleLine( "uidnumber",
455 QString::number( user.getUID() ) )+"\n";
456 if ( mod ) ldif += "-\nreplace: gidnumber\n";
457 ldif += KLDAP::Ldif::assembleLine( "gidnumber",
458 QString::number( user.getGID() ) )+"\n";
459 if ( mod ) ldif += "-\nreplace: gecos\n";
460 ldif += KLDAP::Ldif::assembleLine( "gecos", !mCfg->ldapgecos() ? QByteArray() :
461 QByteArray( gecos.toLatin1() ) )+"\n";
462 if ( mod ) ldif += "-\nreplace: homedirectory\n";
463 ldif += KLDAP::Ldif::assembleLine( "homedirectory",
464 user.getHomeDir() )+"\n";
465 if ( mod ) ldif += "-\nreplace: loginshell\n";
466 ldif += KLDAP::Ldif::assembleLine( "loginshell",
467 user.getShell() )+"\n";
468 if ( mod ) ldif += "-\n";
469 } else {
470 if ( mod ) {
471 ldif += "replace: uidnumber\n";
472 ldif += "-\nreplace: gidnumber\n";
473 ldif += "-\nreplace: homedirectory\n";
474 ldif += "-\nreplace: loginshell\n";
475 ldif += "-\nreplace: gecos\n";
476 ldif += "-\n";
480 if ( caps & Cap_InetOrg ) {
481 if ( mod ) ldif += "replace: sn\n";
482 ldif += KLDAP::Ldif::assembleLine( "sn", user.getSurname() ) + "\n";
483 if ( mod ) ldif += "-\nreplace: mail\n";
484 ldif += KLDAP::Ldif::assembleLine( "mail", user.getEmail() ) + "\n";
485 if ( mod ) ldif += "-\nreplace: displayName\n";
486 ldif += KLDAP::Ldif::assembleLine( "displayname", user.getFullName() ) + "\n";
487 if ( mod ) ldif += "-\nreplace: postaladdress\n";
488 ldif += KLDAP::Ldif::assembleLine( "postaladdress", user.getAddress() ) + "\n";
489 if ( mod ) ldif += "-\nreplace: telephoneNumber\n";
490 ldif += KLDAP::Ldif::assembleLine( "telephoneNumber", user.getOffice1() ) + "\n";
491 ldif += KLDAP::Ldif::assembleLine( "telephoneNumber", user.getOffice2() ) + "\n";
492 if ( mod ) ldif += "-\n";
495 if ( caps & Cap_Samba ) {
496 if ( user.getCaps() & KU_User::Cap_Samba ) {
497 if ( mod ) ldif += "replace: sambadomainname\n";
498 ldif += KLDAP::Ldif::assembleLine( "sambadomainname", user.getDomain() ) + "\n";
499 if ( mod ) ldif += "-\nreplace: sambauserworkstations\n";
500 ldif += KLDAP::Ldif::assembleLine( "sambauserworkstations", user.getWorkstations() ) + "\n";
501 if ( mod ) ldif += "-\nreplace: sambahomepath\n";
502 ldif += KLDAP::Ldif::assembleLine( "sambahomepath", user.getHomePath() ) + "\n";
503 if ( mod ) ldif += "-\nreplace: sambahomedrive\n";
504 ldif += KLDAP::Ldif::assembleLine( "sambahomedrive", user.getHomeDrive() ) + "\n";
505 if ( mod ) ldif += "-\nreplace: sambalogonscript\n";
506 ldif += KLDAP::Ldif::assembleLine( "sambalogonscript", user.getLoginScript() ) + "\n";
507 if ( mod ) ldif += "-\nreplace: sambaprofilepath\n";
508 ldif += KLDAP::Ldif::assembleLine( "sambaprofilepath", user.getProfilePath() ) + "\n";
509 if ( mod ) ldif += "-\nreplace: sambalmpassword\n";
510 ldif += KLDAP::Ldif::assembleLine( "sambalmpassword", user.getLMPwd() ) + "\n";
511 if ( mod ) ldif += "-\nreplace: sambantpassword\n";
512 ldif += KLDAP::Ldif::assembleLine( "sambantpassword", user.getNTPwd() ) + "\n";
513 if ( mod ) ldif += "-\nreplace: sambasid\n";
514 ldif += KLDAP::Ldif::assembleLine( "sambasid", user.getSID().getSID() ) + "\n";
515 if ( mod ) ldif += "-\nreplace: sambaacctflags\n";
516 ldif += KLDAP::Ldif::assembleLine( "sambaacctflags", samflags ) + "\n";
517 if ( mod ) ldif += "-\nreplace: sambaprimarygroupsid\n";
518 ldif += KLDAP::Ldif::assembleLine( "sambaprimarygroupsid",
519 user.getPGSID().getSID() ) + "\n";
520 if ( mod ) ldif += "-\nreplace: sambapwdlastset\n";
521 ldif += KLDAP::Ldif::assembleLine( "sambapwdlastset",
522 QString::number( user.getLastChange() ) ) + "\n";
523 if ( mod ) ldif += "-\nreplace: sambakickofftime\n";
524 if ( user.getExpire() != -1 ) ldif +=
525 KLDAP::Ldif::assembleLine( "sambakickofftime",
526 QString::number( user.getExpire() ) ) + "\n";
527 if ( mod ) ldif += "-\n";
528 } else {
529 if ( mod ) {
530 ldif += "replace: sambahomepath\n";
531 ldif += "-\nreplace: sambahomedrive\n";
532 ldif += "-\nreplace: sambalogonscript\n";
533 ldif += "-\nreplace: sambaprofilepath\n";
534 ldif += "-\nreplace: sambalmpassword\n";
535 ldif += "-\nreplace: sambantpassword\n";
536 ldif += "-\nreplace: sambasid\n";
537 ldif += "-\nreplace: sambaacctflags\n";
538 ldif += "-\nreplace: sambaprimarygroupsid\n";
539 ldif += "-\nreplace: sambapwdlastset\n";
540 ldif += "-\nreplace: sambakickofftime\n";
541 ldif += "-\nreplace: sambalogontime\n";
542 ldif += "-\nreplace: sambalogofftime\n";
543 ldif += "-\nreplace: sambapwdcanchange\n";
544 ldif += "-\nreplace: sambapwdmustchange\n";
545 ldif += "-\nreplace: sambauserworkstations\n";
546 ldif += "-\nreplace: sambadomainname\n";
547 ldif += "-\nreplace: sambamungeddial\n";
548 ldif += "-\nreplace: sambabadpasswordcount\n";
549 ldif += "-\nreplace: sambabadpasswordtime\n";
550 ldif += "-\nreplace: sambadomainname\n";
551 if ( schemaversion > 0 ) {
552 ldif += "-\nreplace: sambapasswordhistory\n";
553 ldif += "-\nreplace: sambalogonhours\n";
555 ldif += "-\n";
560 if ( caps & Cap_Shadow ) {
561 if ( user.getCaps() & KU_User::Cap_POSIX ) {
562 if ( mod ) ldif += "replace: shadowlastchange\n"; //sambapwdlastset
563 ldif += KLDAP::Ldif::assembleLine( "shadowlastchange",
564 QString::number( timeToDays( user.getLastChange() ) ) ) + "\n";
565 if ( mod ) ldif += "-\nreplace: shadowmin\n"; //sambaPwdCanChange
566 ldif += KLDAP::Ldif::assembleLine( "shadowmin",
567 QString::number( user.getMin() ) ) + "\n";
568 if ( mod ) ldif += "-\nreplace: shadowmax\n"; //sambaPwdMustChange
569 ldif += KLDAP::Ldif::assembleLine( "shadowmax",
570 QString::number( user.getMax() ) ) + "\n";
571 if ( mod ) ldif += "-\nreplace: shadowwarning\n";
572 ldif += KLDAP::Ldif::assembleLine( "shadowwarning",
573 QString::number( user.getWarn() ) ) + "\n";
574 if ( mod ) ldif += "-\nreplace: shadowinactive\n";
575 ldif += KLDAP::Ldif::assembleLine( "shadowinactive",
576 QString::number( user.getInactive() ) ) + "\n";
577 if ( mod ) ldif += "-\nreplace: shadowexpire\n"; //sambaKickoffTime
578 ldif += KLDAP::Ldif::assembleLine( "shadowexpire",
579 QString::number( timeToDays( user.getExpire() ) ) ) + "\n";
580 if ( mod ) ldif += "-\nreplace: shadowflag\n";
581 ldif += KLDAP::Ldif::assembleLine( "shadowflag",
582 QString::number( user.getFlag() ) ) + "\n";
583 if ( mod ) ldif += "-\n";
584 } else {
585 if ( mod ) {
586 ldif += "replace: shadowlastchange\n";
587 ldif += "-\nreplace: shadowmin\n";
588 ldif += "-\nreplace: shadowmax\n";
589 ldif += "-\nreplace: shadowwarning\n";
590 ldif += "-\nreplace: shadowinactive\n";
591 ldif += "-\nreplace: shadowexpire\n";
592 ldif += "-\nreplace: shadowflag\n";
593 ldif += "-\n";
597 ldif += "\n";
598 kDebug() << "ldif: " << QString::fromUtf8(ldif) << endl;
599 return ldif;
602 QByteArray KU_UserLDAP::delData( const KU_User &user ) const
604 QByteArray ldif = "dn: " + getRDN( user ).toUtf8() + "," + mUrl.dn().toString().toUtf8() + "\n" +
605 "changetype: delete\n\n";
606 return ldif;
609 bool KU_UserLDAP::dbcommit()
611 mAddSucc.clear();
612 mDelSucc.clear();
613 mModSucc.clear();
614 mAddIndex = 0;
615 mDelIndex = 0;
616 mModIt = mMod.begin();
617 mLastOperation = None;
618 mErrorString = mErrorDetails = QString();
620 mProg = new QProgressDialog( 0 );
621 mProg->setLabel( new QLabel(i18n("LDAP Operation") ) );
622 mProg->setAutoClose( false );
623 mProg->setAutoReset( false );
624 mProg->setMaximum( mAdd.count() + mDel.count() + mMod.count() );
625 KIO::Job *job = KIO::put( mUrl, -1, false, false, false );
626 connect( job, SIGNAL( dataReq( KIO::Job*, QByteArray& ) ),
627 this, SLOT( putData( KIO::Job*, QByteArray& ) ) );
628 connect( job, SIGNAL( result( KJob* ) ),
629 this, SLOT( result( KJob* ) ) );
630 mProg->exec();
631 delete mProg;
632 return( mOk );
635 void KU_UserLDAP::putData( KIO::Job *, QByteArray& data )
637 switch ( mLastOperation ) {
638 case Mod:
639 mModSucc.insert( mModIt.key(), mModIt.value() );
640 mModIt++;
641 break;
642 case Add:
643 mAddSucc.append( mAdd.at( mAddIndex ) );
644 mAddIndex++;
645 break;
646 case Del: {
647 int deleteindex = mDel.at( mDelIndex );
649 if ( mObjectClasses.contains( deleteindex ) ) {
650 kDebug() << "deleting additonal objectclasses!" << endl;
651 mObjectClasses.remove( deleteindex );
653 mDelSucc.append( deleteindex );
654 mDelIndex++;
655 break;
657 default:
658 break;
661 if ( mModIt != mMod.end() ) {
662 data = getLDIF( mModIt.value(), mModIt.key() );
663 mLastOperation = Mod;
664 } else if ( mDelIndex < mDel.count() ) {
665 data = delData( at(mDel.at( mDelIndex ) ));
666 mLastOperation = Del;
667 } else if ( mAddIndex < mAdd.count() ) {
668 data = getLDIF( mAdd.at( mAddIndex ), -1 );
669 mLastOperation = Add;
670 } else {
671 data.resize( 0 );
673 mProg->setValue( mProg->value() + 1 );
676 #include "ku_userldap.moc"