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.
25 #include <kio/kntlm.h>
26 #include <kldap/ldapdn.h>
28 #include "ku_userldap.h"
32 KU_UserLDAP::KU_UserLDAP(KU_PrefsBase
*cfg
) : KU_Users( cfg
)
36 if ( mCfg
->ldapssl() )
37 mUrl
.setProtocol("ldaps");
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
)
72 if ( mCfg
->ldapsam() ) {
74 domsid
= mCfg
->samdomsid();
78 KU_UserLDAP::~KU_UserLDAP()
82 void KU_UserLDAP::result( KJob
*job
)
84 kDebug() << "LDAP result: " << job
->error() << endl
;
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;
92 mErrorString
= i18n("Unknown error"); //this is better than nothing (?)
100 void KU_UserLDAP::data( KIO::Job
*, const QByteArray
& data
)
103 mParser
.setLdif( data
);
108 KLDAP::Ldif::ParseValue ret
;
112 ret
= mParser
.nextItem();
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" )
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
);
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 );
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" )
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" )
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
;
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;
231 } while ( ret
!= KLDAP::Ldif::MoreData
);
234 bool KU_UserLDAP::reload()
236 kDebug() << "kuserldap::reload()" << endl
;
237 mErrorString
= mErrorDetails
= QString();
238 mObjectClasses
.clear();
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 );
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");
258 if ( mProg
->wasCanceled() ) job
->kill();
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();
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
);
285 case KU_PrefsBase::EnumLdappasswordhash::CRYPT
:
286 user
.setPwd( "{CRYPT}" + encryptPass( password
, false ) );
288 case KU_PrefsBase::EnumLdappasswordhash::MD5
: {
289 KMD5
md5( password
.toUtf8() );
290 user
.setPwd( "{MD5}" + md5
.base64Digest() );
293 case KU_PrefsBase::EnumLdappasswordhash::SMD5
: {
294 QByteArray salt
= genSalt( 4 );
295 QByteArray pwd
= password
.toUtf8() + salt
;
297 QByteArray
hash(20, 0);
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
) );
306 case KU_PrefsBase::EnumLdappasswordhash::SHA
: {
308 QByteArray
hash(20, 0);
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
) ) );
317 case KU_PrefsBase::EnumLdappasswordhash::SSHA
: {
319 QByteArray
hash(24, 0);
320 QByteArray salt
= genSalt( 4 );
321 QByteArray pwd
= password
.toUtf8() + salt
;
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
) ) );
332 if ( caps
& Cap_Samba
) {
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() ) {
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 ) );
365 QByteArray
KU_UserLDAP::getLDIF( const KU_User
&user
, int oldindex
) const
367 QString gecos
, cn
, pwd
, samflags
;
370 bool mod
= ( oldindex
!= -1 );
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());
385 samflags
+= user
.getDisabled() ? 'D' : ' ';
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";
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();
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";
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";
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";
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";
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";
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";
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";
598 kDebug() << "ldif: " << QString::fromUtf8(ldif
) << endl
;
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";
609 bool KU_UserLDAP::dbcommit()
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
* ) ) );
635 void KU_UserLDAP::putData( KIO::Job
*, QByteArray
& data
)
637 switch ( mLastOperation
) {
639 mModSucc
.insert( mModIt
.key(), mModIt
.value() );
643 mAddSucc
.append( mAdd
.at( mAddIndex
) );
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
);
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
;
673 mProg
->setValue( mProg
->value() + 1 );
676 #include "ku_userldap.moc"