|
|
|
/*
|
|
|
|
* Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu>
|
|
|
|
*
|
|
|
|
* This mProgram is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public
|
|
|
|
* License version 2 as published by the Free Software Foundation.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Library General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Library General Public License
|
|
|
|
* along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
**/
|
|
|
|
|
|
|
|
#include <tqstring.h>
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <kmdcodec.h>
|
|
|
|
#include <tdemessagebox.h>
|
|
|
|
#include <tdeio/tdentlm.h>
|
|
|
|
|
|
|
|
#include "kglobal_.h"
|
|
|
|
#include "kuserldap.h"
|
|
|
|
#include "misc.h"
|
|
|
|
#include "sha1.h"
|
|
|
|
|
|
|
|
#include "kuserldap.moc"
|
|
|
|
|
|
|
|
KUserLDAP::KUserLDAP(KUserPrefsBase *cfg) : KU::KUsers( cfg )
|
|
|
|
{
|
|
|
|
schemaversion = 0;
|
|
|
|
|
|
|
|
if ( mCfg->ldapssl() )
|
|
|
|
mUrl.setProtocol("ldaps");
|
|
|
|
else
|
|
|
|
mUrl.setProtocol("ldap");
|
|
|
|
|
|
|
|
mUrl.setHost( mCfg->ldaphost() );
|
|
|
|
mUrl.setPort( mCfg->ldapport() );
|
|
|
|
mUrl.setDn( mCfg->ldapuserbase() + "," + mCfg->ldapdn() );
|
|
|
|
if ( !mCfg->ldapanon() ) {
|
|
|
|
mUrl.setUser( mCfg->ldapuser() );
|
|
|
|
mUrl.setPass( mCfg->ldappassword() );
|
|
|
|
}
|
|
|
|
mUrl.setFilter( mCfg->ldapuserfilter() );
|
|
|
|
|
|
|
|
if ( mCfg->ldaptls() ) mUrl.setExtension( "x-tls", "" );
|
|
|
|
if ( mCfg->ldapsasl() ) {
|
|
|
|
mUrl.setExtension( "x-sasl", "" );
|
|
|
|
mUrl.setExtension( "x-mech", mCfg->ldapsaslmech() );
|
|
|
|
}
|
|
|
|
|
|
|
|
mUrl.setScope(TDEABC::LDAPUrl::One);
|
|
|
|
mUrl.setExtension("x-dir","base");
|
|
|
|
|
|
|
|
caps = Cap_Passwd | Cap_Disable_POSIX;
|
|
|
|
if ( mCfg->ldapshadow() ) caps |= Cap_Shadow;
|
|
|
|
if ( mCfg->ldapstructural() ==
|
|
|
|
KUserPrefsBase::EnumLdapstructural::inetOrgPerson )
|
|
|
|
caps |= Cap_InetOrg;
|
|
|
|
|
|
|
|
if ( mCfg->ldapsam() ) {
|
|
|
|
caps |= Cap_Samba;
|
|
|
|
domsid = mCfg->samdomsid();
|
|
|
|
}
|
|
|
|
|
|
|
|
reload();
|
|
|
|
}
|
|
|
|
|
|
|
|
KUserLDAP::~KUserLDAP()
|
|
|
|
{
|
|
|
|
mUsers.clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
void KUserLDAP::result( TDEIO::Job *job )
|
|
|
|
{
|
|
|
|
delete mProg;
|
|
|
|
mCancel = false;
|
|
|
|
if ( job->error() ) {
|
|
|
|
TQString errstr = job->errorString();
|
|
|
|
if ( !errstr.isEmpty() ) {
|
|
|
|
if ( ldif.isEmpty() )
|
|
|
|
KMessageBox::error( 0, errstr );
|
|
|
|
else
|
|
|
|
KMessageBox::detailedError( 0, errstr, TQString::fromUtf8( ldif, ldif.size()-1 ) );
|
|
|
|
}
|
|
|
|
mOk = false;
|
|
|
|
} else {
|
|
|
|
mOk = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KUserLDAP::data( TDEIO::Job *, const TQByteArray& data )
|
|
|
|
{
|
|
|
|
if ( data.size() ) {
|
|
|
|
mParser.setLDIF( data );
|
|
|
|
} else {
|
|
|
|
mParser.endLDIF();
|
|
|
|
}
|
|
|
|
|
|
|
|
TDEABC::LDIF::ParseVal ret;
|
|
|
|
TQString name, val;
|
|
|
|
TQByteArray value;
|
|
|
|
do {
|
|
|
|
ret = mParser.nextItem();
|
|
|
|
switch ( ret ) {
|
|
|
|
case TDEABC::LDIF::Item:
|
|
|
|
name = mParser.attr().lower();
|
|
|
|
value = mParser.val();
|
|
|
|
val = TQString::fromUtf8( value, value.size() );
|
|
|
|
if ( name == "objectclass" ) {
|
|
|
|
if ( val.lower() == "posixaccount" )
|
|
|
|
mUser->setCaps( mUser->getCaps() | KU::KUser::Cap_POSIX );
|
|
|
|
else if ( val.lower() == "sambasamaccount" )
|
|
|
|
mUser->setCaps( mUser->getCaps() | KU::KUser::Cap_Samba );
|
|
|
|
else if ( val.lower() != "inetorgperson" &&
|
|
|
|
val.lower() != "shadowaccount" &&
|
|
|
|
val.lower() != "account" )
|
|
|
|
mOc.append( val );
|
|
|
|
|
|
|
|
} else if ( name == "uidnumber" )
|
|
|
|
mUser->setUID( val.toLong() );
|
|
|
|
else if ( name == "gidnumber" )
|
|
|
|
mUser->setGID( val.toLong() );
|
|
|
|
else if ( name == "uid" || name == "userid" )
|
|
|
|
mUser->setName( val );
|
|
|
|
else if ( name == "sn" )
|
|
|
|
mUser->setSurname( val );
|
|
|
|
else if ( name == "mail" )
|
|
|
|
mUser->setEmail( val );
|
|
|
|
else if ( name == "homedirectory" )
|
|
|
|
mUser->setHomeDir( val );
|
|
|
|
else if ( name == "loginshell" )
|
|
|
|
mUser->setShell( val );
|
|
|
|
else if ( name == "postaladdress" )
|
|
|
|
mUser->setAddress( val );
|
|
|
|
else if ( name == "telephonenumber" ) {
|
|
|
|
if ( mUser->getOffice1().isEmpty() )
|
|
|
|
mUser->setOffice1( val );
|
|
|
|
else
|
|
|
|
mUser->setOffice2( val );
|
|
|
|
} else if ( name == "gecos" ) {
|
|
|
|
TQString name, f1, f2, f3;
|
|
|
|
parseGecos( TQCString( value.data(), value.size()+1 ), name, f1, f2, f3 );
|
|
|
|
if ( mUser->getFullName().isEmpty() ) mUser->setFullName( val );
|
|
|
|
if ( mUser->getOffice1().isEmpty() ) mUser->setOffice1( f1 );
|
|
|
|
if ( mUser->getOffice2().isEmpty() ) mUser->setOffice2( f1 );
|
|
|
|
if ( mUser->getAddress().isEmpty() ) mUser->setAddress( f1 );
|
|
|
|
} else if ( name == "cn" ) {
|
|
|
|
if ( mUser->getFullName().isEmpty() || mCfg->ldapcnfullname() )
|
|
|
|
mUser->setFullName( val );
|
|
|
|
if ( mUser->getName().isEmpty() )
|
|
|
|
mUser->setName( val );
|
|
|
|
} else if ( name == "displayname" ) {
|
|
|
|
mUser->setFullName( val );
|
|
|
|
} else if ( name == "userpassword" ) {
|
|
|
|
if ( !val.isEmpty() ) mUser->setDisabled( false );
|
|
|
|
mUser->setPwd( val );
|
|
|
|
} else if ( name == "shadowlastchange" ) {
|
|
|
|
if ( mUser->getLastChange() == 0 ) //sambapwdlastset is more precise
|
|
|
|
mUser->setLastChange( daysToTime( val.toLong() ) );
|
|
|
|
} else if ( name == "shadowmin" )
|
|
|
|
mUser->setMin( val.toInt() );
|
|
|
|
else if ( name == "shadowmax" )
|
|
|
|
mUser->setMax( val.toLong() );
|
|
|
|
else if ( name == "shadowwarning" )
|
|
|
|
mUser->setWarn( val.toLong() );
|
|
|
|
else if ( name == "shadowinactive" )
|
|
|
|
mUser->setInactive( val.toLong() );
|
|
|
|
else if ( name == "shadowexpire" )
|
|
|
|
mUser->setExpire( val.toLong() );
|
|
|
|
else if ( name == "shadowflag" )
|
|
|
|
mUser->setFlag( val.toLong() );
|
|
|
|
else if ( name == "sambaacctflags" ) {
|
|
|
|
if ( !val.contains( 'D' ) ) mUser->setDisabled( false );
|
|
|
|
} else if ( name == "sambasid" )
|
|
|
|
mUser->setSID( val );
|
|
|
|
else if ( name == "sambaprimarygroupsid" )
|
|
|
|
mUser->setPGSID( val );
|
|
|
|
else if ( name == "sambalmpassword" )
|
|
|
|
mUser->setLMPwd( val );
|
|
|
|
else if ( name == "sambantpassword" )
|
|
|
|
mUser->setNTPwd( val );
|
|
|
|
else if ( name == "sambahomepath" )
|
|
|
|
mUser->setHomePath( val );
|
|
|
|
else if ( name == "sambahomedrive" )
|
|
|
|
mUser->setHomeDrive( val );
|
|
|
|
else if ( name == "sambalogonscript" )
|
|
|
|
mUser->setLoginScript( val );
|
|
|
|
else if ( name == "sambaprofilepath" )
|
|
|
|
mUser->setProfilePath( val );
|
|
|
|
else if ( name == "sambauserworkstations" )
|
|
|
|
mUser->setWorkstations( val );
|
|
|
|
else if ( name == "sambadomainname" )
|
|
|
|
mUser->setDomain( val );
|
|
|
|
else if ( name == "sambapwdlastset" )
|
|
|
|
mUser->setLastChange( val.toLong() );
|
|
|
|
//these new attributes introduced around samba 3.0.6
|
|
|
|
else if ( name == "sambapasswordhistory" || name == "sambalogonhours" )
|
|
|
|
schemaversion = 1;
|
|
|
|
break;
|
|
|
|
case TDEABC::LDIF::EndEntry: {
|
|
|
|
KU::KUser emptyUser, *newUser;
|
|
|
|
kdDebug() << "new user: " << mUser->getName() << endl;
|
|
|
|
newUser = new KU::KUser( mUser );
|
|
|
|
mUsers.append( newUser );
|
|
|
|
if ( !mOc.isEmpty() ) {
|
|
|
|
mObjectClasses.insert( newUser, mOc );
|
|
|
|
kdDebug() << "user: " << newUser->getName() << " other objectclasses: " << mOc.join(",") << endl;
|
|
|
|
}
|
|
|
|
mOc.clear();
|
|
|
|
mUser->copy( &emptyUser );
|
|
|
|
mUser->setDisabled( true );
|
|
|
|
|
|
|
|
if ( ( mUsers.count() & 7 ) == 7 ) {
|
|
|
|
mProg->progressBar()->advance( mAdv );
|
|
|
|
if ( mProg->progressBar()->progress() == 0 ) mAdv = 1;
|
|
|
|
if ( mProg->progressBar()->progress() == mProg->progressBar()->totalSteps()-1 ) mAdv = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} while ( ret != TDEABC::LDIF::MoreData );
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KUserLDAP::reload()
|
|
|
|
{
|
|
|
|
kdDebug() << "kuserldap::reload()" << endl;
|
|
|
|
mObjectClasses.clear();
|
|
|
|
mOc.clear();
|
|
|
|
mUser = new KU::KUser();
|
|
|
|
mUser->setPwd( "" );
|
|
|
|
mUser->setSPwd( "" );
|
|
|
|
mParser.startParsing();
|
|
|
|
mCancel = true;
|
|
|
|
mProg = new KProgressDialog( 0, "", "", i18n("Loading Users From LDAP"), true );
|
|
|
|
mProg->setAutoClose( false );
|
|
|
|
mProg->progressBar()->setFormat("");
|
|
|
|
mProg->progressBar()->setTotalSteps( 100 );
|
|
|
|
mAdv = 1;
|
|
|
|
ldif = "";
|
|
|
|
|
|
|
|
TDEIO::Job *job = TDEIO::get( mUrl, true, false );
|
|
|
|
connect( job, TQT_SIGNAL( data( TDEIO::Job*, const TQByteArray& ) ),
|
|
|
|
this, TQT_SLOT( data( TDEIO::Job*, const TQByteArray& ) ) );
|
|
|
|
connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ),
|
|
|
|
this, TQT_SLOT( result( TDEIO::Job* ) ) );
|
|
|
|
// job->addMetaData( "SERVER_CTRL0", "1.2.840.113556.1.4.473 true: uidNumber");
|
|
|
|
mProg->exec();
|
|
|
|
if ( mCancel ) job->kill();
|
|
|
|
delete mUser;
|
|
|
|
return( mOk );
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KUserLDAP::getRDN(KU::KUser *user)
|
|
|
|
{
|
|
|
|
switch ( mCfg->ldapuserrdn() ) {
|
|
|
|
case KUserPrefsBase::EnumLdapuserrdn::uid:
|
|
|
|
return "uid=" + user->getName();
|
|
|
|
case KUserPrefsBase::EnumLdapuserrdn::uidNumber:
|
|
|
|
return "uidNumber=" + TQString::number( user->getUID() );
|
|
|
|
case KUserPrefsBase::EnumLdapuserrdn::cn: {
|
|
|
|
TQString cn = mCfg->ldapcnfullname() ? user->getFullName() : user->getName();
|
|
|
|
if ( cn.isEmpty() ) cn = user->getName();
|
|
|
|
return "cn=" + cn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
|
|
|
|
void KUserLDAP::createPassword( KU::KUser *user, const TQString &password )
|
|
|
|
{
|
|
|
|
switch ( mCfg->ldappasswordhash() ) {
|
|
|
|
case KUserPrefsBase::EnumLdappasswordhash::Clear:
|
|
|
|
user->setPwd( password );
|
|
|
|
break;
|
|
|
|
case KUserPrefsBase::EnumLdappasswordhash::CRYPT:
|
|
|
|
user->setPwd( "{CRYPT}" + encryptPass( password, false ) );
|
|
|
|
break;
|
|
|
|
case KUserPrefsBase::EnumLdappasswordhash::MD5: {
|
|
|
|
KMD5 md5( password.utf8() );
|
|
|
|
user->setPwd( "{MD5}" + md5.base64Digest() );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case KUserPrefsBase::EnumLdappasswordhash::SMD5: {
|
|
|
|
TQCString salt = genSalt( 4 );
|
|
|
|
TQCString pwd = password.utf8() + salt;
|
|
|
|
KMD5::Digest digest;
|
|
|
|
TQByteArray hash(20);
|
|
|
|
|
|
|
|
KMD5 md5( pwd );
|
|
|
|
md5.rawDigest( digest );
|
|
|
|
memcpy( hash.data(), digest, 16 );
|
|
|
|
memcpy( &(hash.data()[16]), salt.data(), 4 );
|
|
|
|
user->setPwd( "{SMD5}" + KCodecs::base64Encode( hash ) );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case KUserPrefsBase::EnumLdappasswordhash::SHA: {
|
|
|
|
struct sha1_ctx ctx;
|
|
|
|
TQByteArray hash(20);
|
|
|
|
|
|
|
|
sha1_init( &ctx );
|
|
|
|
sha1_update( &ctx, (const TQ_UINT8*) password.utf8().data(),
|
|
|
|
password.utf8().length() );
|
|
|
|
sha1_final( &ctx, (TQ_UINT8*) hash.data() );
|
|
|
|
user->setPwd( "{SHA}" + KCodecs::base64Encode( ( hash ) ) );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case KUserPrefsBase::EnumLdappasswordhash::SSHA: {
|
|
|
|
struct sha1_ctx ctx;
|
|
|
|
TQByteArray hash(24);
|
|
|
|
TQCString salt = genSalt( 4 );
|
|
|
|
TQCString pwd = password.utf8() + salt;
|
|
|
|
|
|
|
|
sha1_init( &ctx );
|
|
|
|
sha1_update( &ctx, (const TQ_UINT8*) pwd.data(), pwd.length() );
|
|
|
|
sha1_final( &ctx, (TQ_UINT8*) hash.data() );
|
|
|
|
memcpy( &(hash.data()[ 20 ]), salt.data(), 4 );
|
|
|
|
user->setPwd( "{SSHA}" + KCodecs::base64Encode( ( hash ) ) );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( caps & Cap_Samba ) {
|
|
|
|
TQ_UINT8 hex[33];
|
|
|
|
|
|
|
|
TQByteArray ntlmhash;
|
|
|
|
ntlmhash = KNTLM::ntlmHash( password );
|
|
|
|
unsigned char *hash = (unsigned char*) ntlmhash.data();
|
|
|
|
|
|
|
|
snprintf( (char*) &hex, 33,
|
|
|
|
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
|
|
|
|
hash[0], hash[1], hash[2], hash[3], hash[4], hash[5],
|
|
|
|
hash[6], hash[7], hash[8], hash[9], hash[10], hash[11],
|
|
|
|
hash[12], hash[13], hash[14], hash[15]);
|
|
|
|
|
|
|
|
user->setNTPwd( TQString::fromLatin1( (const char*) &hex, 32 ) );
|
|
|
|
|
|
|
|
if ( mCfg->lanmanhash() ) {
|
|
|
|
|
|
|
|
TQByteArray lmhash;
|
|
|
|
lmhash = KNTLM::lmHash( password );
|
|
|
|
unsigned char *hash = (unsigned char*) lmhash.data();
|
|
|
|
snprintf( (char*) &hex, 33,
|
|
|
|
"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
|
|
|
|
hash[0], hash[1], hash[2], hash[3], hash[4], hash[5],
|
|
|
|
hash[6], hash[7], hash[8], hash[9], hash[10], hash[11],
|
|
|
|
hash[12], hash[13], hash[14], hash[15]);
|
|
|
|
|
|
|
|
user->setLMPwd( TQString::fromLatin1( (const char*) &hex, 32 ) );
|
|
|
|
} else {
|
|
|
|
user->setLMPwd( "" );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void KUserLDAP::getLDIF( KU::KUser *user, bool mod )
|
|
|
|
{
|
|
|
|
TQString gecos, cn, pwd, samflags;
|
|
|
|
ldif.resize( 0 );
|
|
|
|
|
|
|
|
pwd = user->getPwd();
|
|
|
|
if ( user->getDisabled() ) pwd = "";
|
|
|
|
|
|
|
|
cn = mCfg->ldapcnfullname() ? user->getFullName() : user->getName();
|
|
|
|
if ( cn.isEmpty() ) cn = user->getName();
|
|
|
|
|
|
|
|
gecos = TQString::fromLatin1("%1,%2,%3,%4")
|
|
|
|
.arg(user->getFullName())
|
|
|
|
.arg(user->getOffice1())
|
|
|
|
.arg(user->getOffice2())
|
|
|
|
.arg(user->getAddress());
|
|
|
|
|
|
|
|
samflags = "[U";
|
|
|
|
samflags += user->getDisabled() ? 'D' : ' ';
|
|
|
|
samflags += " ]";
|
|
|
|
|
|
|
|
ldif = "";
|
|
|
|
|
|
|
|
if ( mod ) {
|
|
|
|
TQString oldrdn = getRDN( mUser );
|
|
|
|
TQString newrdn = getRDN( user );
|
|
|
|
|
|
|
|
if ( oldrdn != newrdn ) {
|
|
|
|
ldif = "dn: " + oldrdn.utf8() + "," + mUrl.dn().utf8() + "\n" +
|
|
|
|
"changetype: modrdn\n" +
|
|
|
|
"newrdn: " + newrdn.utf8() + "\n" +
|
|
|
|
"deleteoldrdn: 1\n\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ldif += "dn: " + getRDN( user ).utf8() + "," + mUrl.dn().utf8() + "\n";
|
|
|
|
if ( mod ) {
|
|
|
|
ldif += "changetype: modify\n";
|
|
|
|
ldif += "replace: objectClass\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( caps & Cap_InetOrg )
|
|
|
|
ldif += "objectClass: inetOrgPerson\n";
|
|
|
|
else
|
|
|
|
ldif += "objectClass: account\n";
|
|
|
|
|
|
|
|
if ( user->getCaps() & KU::KUser::Cap_POSIX ) {
|
|
|
|
ldif += "objectClass: posixAccount\n";
|
|
|
|
}
|
|
|
|
if ( ( caps & Cap_Shadow ) && ( user->getCaps() & KU::KUser::Cap_POSIX ) ) {
|
|
|
|
ldif += "objectClass: shadowAccount\n";
|
|
|
|
}
|
|
|
|
if ( ( caps & Cap_Samba ) && ( user->getCaps() & KU::KUser::Cap_Samba ) ) {
|
|
|
|
ldif += "objectClass: sambaSamAccount\n";
|
|
|
|
}
|
|
|
|
if ( mod && mObjectClasses.contains( mUser ) ) {
|
|
|
|
TQStringList ocs = mObjectClasses[ mUser ];
|
|
|
|
kdDebug() << user->getName() << " has additional objectclasses: " << ocs.join(",") << endl;
|
|
|
|
TQValueListIterator<TQString> it;
|
|
|
|
for ( it = ocs.begin(); it != ocs.end(); ++it ) {
|
|
|
|
ldif += "objectClass: ";
|
|
|
|
ldif += (*it).utf8();
|
|
|
|
ldif += "\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( mod ) ldif += "-\nreplace: cn\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "cn", cn )+"\n";
|
|
|
|
if ( caps & Cap_InetOrg ) {
|
|
|
|
if ( mod ) ldif += "-\nreplace: uid\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "uid", user->getName() ) + "\n";
|
|
|
|
} else {
|
|
|
|
if ( mod ) ldif += "-\nreplace: userid\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "userid", user->getName() ) + "\n";
|
|
|
|
}
|
|
|
|
if ( mod ) ldif += "-\n";
|
|
|
|
|
|
|
|
if ( ( user->getCaps() & KU::KUser::Cap_POSIX ) || ( caps & Cap_InetOrg ) ) {
|
|
|
|
if ( mod ) ldif += "replace: userpassword\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "userpassword", pwd )+"\n";
|
|
|
|
if ( mod ) ldif += "-\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( user->getCaps() & KU::KUser::Cap_POSIX ) {
|
|
|
|
if ( mod ) ldif += "replace: uidnumber\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "uidnumber",
|
|
|
|
TQString::number( user->getUID() ) )+"\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: gidnumber\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "gidnumber",
|
|
|
|
TQString::number( user->getGID() ) )+"\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: gecos\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "gecos", !mCfg->ldapgecos() ? TQCString() :
|
|
|
|
TQCString( gecos.latin1() ) )+"\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: homedirectory\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "homedirectory",
|
|
|
|
user->getHomeDir() )+"\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: loginshell\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "loginshell",
|
|
|
|
user->getShell() )+"\n";
|
|
|
|
if ( mod ) ldif += "-\n";
|
|
|
|
} else {
|
|
|
|
if ( mod ) {
|
|
|
|
ldif += "replace: uidnumber\n";
|
|
|
|
ldif += "-\nreplace: gidnumber\n";
|
|
|
|
ldif += "-\nreplace: homedirectory\n";
|
|
|
|
ldif += "-\nreplace: loginshell\n";
|
|
|
|
ldif += "-\nreplace: gecos\n";
|
|
|
|
ldif += "-\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( caps & Cap_InetOrg ) {
|
|
|
|
if ( mod ) ldif += "replace: sn\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sn", user->getSurname() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: mail\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "mail", user->getEmail() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: displayName\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "displayname", user->getFullName() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: postaladdress\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "postaladdress", user->getAddress() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: telephoneNumber\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "telephoneNumber", user->getOffice1() ) + "\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "telephoneNumber", user->getOffice2() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( caps & Cap_Samba ) {
|
|
|
|
if ( user->getCaps() & KU::KUser::Cap_Samba ) {
|
|
|
|
if ( mod ) ldif += "replace: sambadomainname\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambadomainname", user->getDomain() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambauserworkstations\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambauserworkstations", user->getWorkstations() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambahomepath\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambahomepath", user->getHomePath() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambahomedrive\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambahomedrive", user->getHomeDrive() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambalogonscript\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambalogonscript", user->getLoginScript() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambaprofilepath\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambaprofilepath", user->getProfilePath() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambalmpassword\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambalmpassword", user->getLMPwd() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambantpassword\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambantpassword", user->getNTPwd() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambasid\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambasid", user->getSID().getSID() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambaacctflags\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambaacctflags", samflags ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambaprimarygroupsid\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambaprimarygroupsid",
|
|
|
|
user->getPGSID().getSID() ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambapwdlastset\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "sambapwdlastset",
|
|
|
|
TQString::number( user->getLastChange() ) ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: sambakickofftime\n";
|
|
|
|
if ( user->getExpire() != -1 ) ldif +=
|
|
|
|
TDEABC::LDIF::assembleLine( "sambakickofftime",
|
|
|
|
TQString::number( user->getExpire() ) ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\n";
|
|
|
|
} else {
|
|
|
|
if ( mod ) {
|
|
|
|
ldif += "replace: sambahomepath\n";
|
|
|
|
ldif += "-\nreplace: sambahomedrive\n";
|
|
|
|
ldif += "-\nreplace: sambalogonscript\n";
|
|
|
|
ldif += "-\nreplace: sambaprofilepath\n";
|
|
|
|
ldif += "-\nreplace: sambalmpassword\n";
|
|
|
|
ldif += "-\nreplace: sambantpassword\n";
|
|
|
|
ldif += "-\nreplace: sambasid\n";
|
|
|
|
ldif += "-\nreplace: sambaacctflags\n";
|
|
|
|
ldif += "-\nreplace: sambaprimarygroupsid\n";
|
|
|
|
ldif += "-\nreplace: sambapwdlastset\n";
|
|
|
|
ldif += "-\nreplace: sambakickofftime\n";
|
|
|
|
ldif += "-\nreplace: sambalogontime\n";
|
|
|
|
ldif += "-\nreplace: sambalogofftime\n";
|
|
|
|
ldif += "-\nreplace: sambapwdcanchange\n";
|
|
|
|
ldif += "-\nreplace: sambapwdmustchange\n";
|
|
|
|
ldif += "-\nreplace: sambauserworkstations\n";
|
|
|
|
ldif += "-\nreplace: sambadomainname\n";
|
|
|
|
ldif += "-\nreplace: sambamungeddial\n";
|
|
|
|
ldif += "-\nreplace: sambabadpasswordcount\n";
|
|
|
|
ldif += "-\nreplace: sambabadpasswordtime\n";
|
|
|
|
ldif += "-\nreplace: sambadomainname\n";
|
|
|
|
if ( schemaversion > 0 ) {
|
|
|
|
ldif += "-\nreplace: sambapasswordhistory\n";
|
|
|
|
ldif += "-\nreplace: sambalogonhours\n";
|
|
|
|
}
|
|
|
|
ldif += "-\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( caps & Cap_Shadow ) {
|
|
|
|
if ( user->getCaps() & KU::KUser::Cap_POSIX ) {
|
|
|
|
if ( mod ) ldif += "replace: shadowlastchange\n"; //sambapwdlastset
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "shadowlastchange",
|
|
|
|
TQString::number( timeToDays( user->getLastChange() ) ) ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: shadowmin\n"; //sambaPwdCanChange
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "shadowmin",
|
|
|
|
TQString::number( user->getMin() ) ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: shadowmax\n"; //sambaPwdMustChange
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "shadowmax",
|
|
|
|
TQString::number( user->getMax() ) ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: shadowwarning\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "shadowwarning",
|
|
|
|
TQString::number( user->getWarn() ) ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: shadowinactive\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "shadowinactive",
|
|
|
|
TQString::number( user->getInactive() ) ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: shadowexpire\n"; //sambaKickoffTime
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "shadowexpire",
|
|
|
|
TQString::number( timeToDays( user->getExpire() ) ) ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\nreplace: shadowflag\n";
|
|
|
|
ldif += TDEABC::LDIF::assembleLine( "shadowflag",
|
|
|
|
TQString::number( user->getFlag() ) ) + "\n";
|
|
|
|
if ( mod ) ldif += "-\n";
|
|
|
|
} else {
|
|
|
|
if ( mod ) {
|
|
|
|
ldif += "replace: shadowlastchange\n";
|
|
|
|
ldif += "-\nreplace: shadowmin\n";
|
|
|
|
ldif += "-\nreplace: shadowmax\n";
|
|
|
|
ldif += "-\nreplace: shadowwarning\n";
|
|
|
|
ldif += "-\nreplace: shadowinactive\n";
|
|
|
|
ldif += "-\nreplace: shadowexpire\n";
|
|
|
|
ldif += "-\nreplace: shadowflag\n";
|
|
|
|
ldif += "-\n";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ldif += "\n";
|
|
|
|
// kdDebug() << "ldif: " << ldif << endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
void KUserLDAP::delData( KU::KUser *user )
|
|
|
|
{
|
|
|
|
ldif = "dn: " + getRDN( user ).utf8() + "," + mUrl.dn().utf8() + "\n" +
|
|
|
|
"changetype: delete\n\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
bool KUserLDAP::dbcommit()
|
|
|
|
{
|
|
|
|
mAddSucc.clear();
|
|
|
|
mDelSucc.clear();
|
|
|
|
mModSucc.clear();
|
|
|
|
mAdd.first();
|
|
|
|
mDel.first();
|
|
|
|
mAddUser = 0; mDelUser = 0; mUser = 0;
|
|
|
|
|
|
|
|
mProg = new KProgressDialog( 0, "", i18n("LDAP Operation"), "", true );
|
|
|
|
TDEIO::Job *job = TDEIO::put( mUrl, -1, false, false, false );
|
|
|
|
connect( job, TQT_SIGNAL( dataReq( TDEIO::Job*, TQByteArray& ) ),
|
|
|
|
this, TQT_SLOT( putData( TDEIO::Job*, TQByteArray& ) ) );
|
|
|
|
connect( job, TQT_SIGNAL( result( TDEIO::Job* ) ),
|
|
|
|
this, TQT_SLOT( result( TDEIO::Job* ) ) );
|
|
|
|
mProg->exec();
|
|
|
|
return( mOk );
|
|
|
|
}
|
|
|
|
|
|
|
|
void KUserLDAP::putData( TDEIO::Job *, TQByteArray& data )
|
|
|
|
{
|
|
|
|
ModIt mit = mMod.begin();
|
|
|
|
|
|
|
|
if ( mAddUser ) {
|
|
|
|
mAddSucc.append( mAddUser );
|
|
|
|
mAdd.remove();
|
|
|
|
mAddUser = 0;
|
|
|
|
}
|
|
|
|
if ( mDelUser ) {
|
|
|
|
kdDebug() << "delete ok for: " << mDelUser->getName() << endl;
|
|
|
|
mDelSucc.append( mDelUser );
|
|
|
|
if ( mObjectClasses.contains( mDelUser ) ) {
|
|
|
|
kdDebug() << "deleting additonal objectclasses!" << endl;
|
|
|
|
mObjectClasses.remove( mDelUser );
|
|
|
|
}
|
|
|
|
mDel.remove();
|
|
|
|
mDelUser = 0;
|
|
|
|
}
|
|
|
|
if ( mUser ) {
|
|
|
|
mModSucc.insert( mUser, mit.data() );
|
|
|
|
mMod.remove( mit );
|
|
|
|
mit = mMod.begin();
|
|
|
|
mUser = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( (mAddUser = mAdd.current()) ) {
|
|
|
|
getLDIF( mAddUser, false );
|
|
|
|
data = ldif;
|
|
|
|
} else if ( mit != mMod.end() ) {
|
|
|
|
mUser = mit.key();
|
|
|
|
getLDIF( &(mit.data()), true );
|
|
|
|
data = ldif;
|
|
|
|
} else if ( (mDelUser = mDel.current()) ) {
|
|
|
|
kdDebug() << "deleting: " << mDelUser->getName() << endl;
|
|
|
|
delData( mDelUser );
|
|
|
|
data = ldif;
|
|
|
|
} else
|
|
|
|
data.resize(0);
|
|
|
|
}
|