diff options
Diffstat (limited to 'kuser/kuser.cpp')
-rw-r--r-- | kuser/kuser.cpp | 1053 |
1 files changed, 1053 insertions, 0 deletions
diff --git a/kuser/kuser.cpp b/kuser/kuser.cpp new file mode 100644 index 0000000..2fd9ff1 --- /dev/null +++ b/kuser/kuser.cpp @@ -0,0 +1,1053 @@ +/* + * Copyright (c) 1998 Denis Perchine <dyp@perchine.com> + * Copyright (c) 2004 Szombathelyi György <gyurco@freemail.hu> + * Former maintainer: Adriaan de Groot <groot@kde.org> + * + * This program 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 "globals.h" + +#include <errno.h> +#include <sys/types.h> +#include <sys/file.h> +#include <stdlib.h> +#ifdef HAVE_UNISTD_H +#include <unistd.h> +#endif +#ifdef HAVE_SYS_STAT_H +#include <sys/stat.h> +#endif +#include <fcntl.h> +#include <qstring.h> +#include <qdir.h> + +#include "kglobal_.h" +#include "kuser.h" +#include "misc.h" +#include <kstandarddirs.h> +#include <kmessagebox.h> +#include <kprocess.h> +#include <kdebug.h> +#include <kio/netaccess.h> +#include <kurl.h> + +// class KUser + +KU::KUser::KUser() +{ + p_change = 0; + p_expire = -1; + p_uid = 0; + p_gid = 100; + + s_min = 0; + s_max = 99999; + s_warn = 7; + s_inact = -1; +// s_flag = 0; + caps = 0; + isCreateHome = false; + isCreateMailBox = false; + isCopySkel = false; + isDeleteHome = false; + isDeleteMailBox = false; + + isDisabled = true; +} + +KU::KUser::KUser(const KU::KUser *user) +{ + copy(user); +} + +void KU::KUser::copy(const KU::KUser *user) +{ + if ( user != this ) { + caps = user->caps; + p_name = user->p_name; + p_surname = user->p_surname; + p_email = user->p_email; + p_pwd = user->p_pwd; + p_dir = user->p_dir; + p_shell = user->p_shell; + p_fname = user->p_fname; + p_office = user->p_office; + p_ophone = user->p_ophone; + p_hphone = user->p_hphone; + p_class = user->p_class; + p_change = user->p_change; + p_expire = user->p_expire; + p_office1 = user->p_office1; + p_office2 = user->p_office2; + p_address = user->p_address; + + p_uid = user->p_uid; + p_gid = user->p_gid; + + s_pwd = user->s_pwd; + s_min = user->s_min; + s_max = user->s_max; + s_warn = user->s_warn; + s_inact = user->s_inact; + s_flag = user->s_flag; + + sam_lmpwd = user->sam_lmpwd; + sam_ntpwd = user->sam_ntpwd; + sam_loginscript = user->sam_loginscript; + sam_profile = user->sam_profile; + sam_homedrive = user->sam_homedrive; + sam_homepath = user->sam_homepath; + sam_workstations = user->sam_workstations; + sam_domain = user->sam_domain; + sid = user->sid; + pgroup_sid = user->pgroup_sid; + + isCreateHome = user->isCreateHome; + isCreateMailBox = user->isCreateMailBox; + isDeleteHome = user->isDeleteHome; + isDeleteMailBox = user->isDeleteMailBox; + isCopySkel = user->isCopySkel; + isDisabled = user->isDisabled; + } +} + +KU::KUser::~KUser() +{ +} + +void KU::KUser::setCaps( int data ) +{ + caps = data; +} + +int KU::KUser::getCaps() +{ + return caps; +} + +bool KU::KUser::getDeleteHome() +{ + return isDeleteHome; +} + +bool KU::KUser::getDeleteMailBox() +{ + return isDeleteMailBox; +} + +bool KU::KUser::getCreateHome() +{ + return isCreateHome; +} + +bool KU::KUser::getCreateMailBox() +{ + return isCreateMailBox; +} + +bool KU::KUser::getCopySkel() +{ + return isCopySkel; +} + +const QString &KU::KUser::getName() const +{ + return p_name; +} + +const QString &KU::KUser::getSurname() const +{ + return p_surname; +} + +const QString &KU::KUser::getEmail() const +{ + return p_email; +} + +const QString &KU::KUser::getPwd() const +{ + return p_pwd; +} + +const QString &KU::KUser::getHomeDir() const +{ + return p_dir; +} + +const QString &KU::KUser::getShell() const +{ + return p_shell; +} + +const QString &KU::KUser::getFullName() const +{ + return p_fname; +} + +bool KU::KUser::getDisabled() const +{ + return isDisabled; +} + +// FreeBSD apparently uses the GECOS fields differently than other Unices. +// Create some better named functions to make the FreeBSD code clear +const QString &KU::KUser::getOffice() const +{ + return p_office; +} + +const QString &KU::KUser::getWorkPhone() const +{ + return p_ophone; +} + +const QString &KU::KUser::getHomePhone() const +{ + return p_hphone; +} + +// New fields needed for the FreeBSD /etc/master.passwd file +const QString &KU::KUser::getClass() const +{ + return p_class; +} + +const QString &KU::KUser::getOffice1() const +{ + return p_office1; +} + +const QString &KU::KUser::getOffice2() const +{ + return p_office2; +} + +const QString &KU::KUser::getAddress() const +{ + return p_address; +} + +uid_t KU::KUser::getUID() const +{ + return p_uid; +} + +gid_t KU::KUser::getGID() const +{ + return p_gid; +} + +const QString &KU::KUser::getSPwd() const +{ + return s_pwd; +} + +time_t KU::KUser::getLastChange() const +{ + return p_change; +} + +int KU::KUser::getMin() const +{ + return s_min; +} + +int KU::KUser::getMax() const +{ + return s_max; +} + +int KU::KUser::getWarn() const +{ + return s_warn; +} + +int KU::KUser::getInactive() const +{ + return s_inact; +} + +int KU::KUser::getFlag() const +{ + return s_flag; +} + +time_t KU::KUser::getExpire() const +{ + return p_expire; +} + +const QString &KU::KUser::getLMPwd() const // sam_lmpwd, +{ + return sam_lmpwd; +} + +const QString &KU::KUser::getNTPwd() const //sam_ntpwd, +{ + return sam_ntpwd; +} + +const QString &KU::KUser::getLoginScript() const //sam_loginscript, +{ + return sam_loginscript; +} + +const QString &KU::KUser::getProfilePath() const // sam_profile, +{ + return sam_profile; +} + +const QString &KU::KUser::getHomeDrive() const //sam_homedrive, +{ + return sam_homedrive; +} + +const QString &KU::KUser::getHomePath() const //sam_homepath; +{ + return sam_homepath; +} + +const QString &KU::KUser::getWorkstations() const //sam_workstation; +{ + return sam_workstations; +} + +const QString &KU::KUser::getDomain() const //sam_domain; +{ + return sam_domain; +} + +const SID &KU::KUser::getSID() const //sid, +{ + return sid; +} + +const SID &KU::KUser::getPGSID() const //pgroup_sid; +{ + return pgroup_sid; +} + +void KU::KUser::setName(const QString &data) +{ + p_name = data; +} + +void KU::KUser::setSurname(const QString &data) +{ + p_surname = data; +} + +void KU::KUser::setEmail(const QString &data) +{ + p_email = data; +} + +void KU::KUser::setPwd(const QString &data) +{ + p_pwd = data; +} + +void KU::KUser::setHomeDir(const QString &data) +{ + p_dir = data; +} + +void KU::KUser::setShell(const QString &data) +{ + p_shell = data; +} + +void KU::KUser::setFullName(const QString &data) +{ + p_fname = data; +} + +void KU::KUser::setDisabled(bool data) +{ + isDisabled = data; +} + +// FreeBSD apparently uses the GECOS fields differently than other Unices. +// Create some better named functions to make the FreeBSD code clear +void KU::KUser::setOffice(const QString &data) +{ + p_office = data; +} + +void KU::KUser::setWorkPhone(const QString &data) +{ + p_ophone = data; +} + +void KU::KUser::setHomePhone(const QString &data) +{ + p_hphone = data; +} + +// New fields needed for the FreeBSD /etc/master.passwd file +void KU::KUser::setClass(const QString &data) +{ + p_class = data; +} + +void KU::KUser::setLastChange(time_t data) +{ + p_change = data; +} + +void KU::KUser::setExpire(time_t data) +{ + p_expire = data; +} + +void KU::KUser::setOffice1(const QString &data) +{ + p_office1 = data; +} + +void KU::KUser::setOffice2(const QString &data) +{ + p_office2 = data; +} + +void KU::KUser::setAddress(const QString &data) +{ + p_address = data; +} + +void KU::KUser::setUID(uid_t data) +{ + p_uid = data; +} + +void KU::KUser::setGID(gid_t data) +{ + p_gid = data; +} + +void KU::KUser::setSPwd(const QString &data) +{ + s_pwd = data; +} + +void KU::KUser::setMin(int data) +{ + s_min = data; +} + +void KU::KUser::setMax(int data) +{ + s_max = data; +} + +void KU::KUser::setWarn(int data) +{ + s_warn = data; +} + +void KU::KUser::setInactive(int data) +{ + s_inact = data; +} + +void KU::KUser::setLMPwd( const QString &data ) // sam_lmpwd, +{ + sam_lmpwd = data; +} + +void KU::KUser::setNTPwd( const QString &data ) //sam_ntpwd, +{ + sam_ntpwd = data; +} + +void KU::KUser::setLoginScript( const QString &data ) //sam_loginscript, +{ + sam_loginscript = data; +} + +void KU::KUser::setProfilePath( const QString &data) // sam_profile, +{ + sam_profile = data; +} + +void KU::KUser::setHomeDrive( const QString &data ) //sam_homedrive, +{ + sam_homedrive = data; +} + +void KU::KUser::setHomePath( const QString &data ) //sam_homepath; +{ + sam_homepath = data; +} + +void KU::KUser::setWorkstations( const QString &data ) //sam_workstation; +{ + sam_workstations = data; +} + +void KU::KUser::setDomain( const QString &data ) //sam_domain +{ + sam_domain = data; +} + +void KU::KUser::setSID( const SID &data ) //sid, +{ + sid = data; +} + +void KU::KUser::setPGSID( const SID &data ) //pgroup_sid; +{ + pgroup_sid = data; +} + +void KU::KUser::setFlag(int data) +{ + s_flag = data; +} + +void KU::KUser::setCreateHome(bool data) +{ + isCreateHome = data; +} + +void KU::KUser::setCreateMailBox(bool data) +{ + isCreateMailBox = data; +} + +void KU::KUser::setCopySkel(bool data) +{ + isCopySkel = data; +} + +void KU::KUser::setDeleteHome(bool data) +{ + isDeleteHome = data; +} + +void KU::KUser::setDeleteMailBox(bool data) +{ + isDeleteMailBox = data; +} + +int KU::KUser::createHome() +{ + + if(p_dir.isNull() || p_dir.isEmpty()) { + KMessageBox::sorry( 0, i18n("Cannot create home folder for %1: it is null or empty.").arg(p_name) ); + return(0); + } + if (mkdir(QFile::encodeName(p_dir), 0700) != 0) { + if (errno != EEXIST) + { + KMessageBox::error( 0, i18n("Cannot create home folder %1.\nError: %2").arg(p_dir).arg(QString::fromLocal8Bit(strerror(errno))) ); + return(0); + } + } + + if (chown(QFile::encodeName(p_dir), p_uid, p_gid) != 0) { + KMessageBox::error( 0, i18n("Cannot change owner of home folder %1.\nError: %2").arg(p_dir).arg(QString::fromLocal8Bit(strerror(errno))) ); + return(1); + } + + if (chmod(QFile::encodeName(p_dir), KU_HOMEDIR_PERM) != 0) { + KMessageBox::error( 0, i18n("Cannot change permissions on home folder %1.\nError: %2").arg(p_dir).arg(QString::fromLocal8Bit(strerror(errno))) ); + return(1); + } + return(1); +} + +int KU::KUser::tryCreate(const QString &dir) +{ + struct stat sb; + int rc = 0; + + rc = stat(QFile::encodeName(dir), &sb); + if (rc == 0) { + if (S_ISDIR(sb.st_mode)) { + if (KMessageBox::warningContinueCancel( 0, + i18n("Folder %1 already exists!\nWill make %2 owner and change permissions.\nDo you want to continue?").arg(dir).arg(p_name), + QString::null, KStdGuiItem::cont() ) == KMessageBox::Continue) { + + if (chown(QFile::encodeName(dir), p_uid, p_gid) != 0) { + KMessageBox::error( 0, i18n("Cannot change owner of %1 folder.\nError: %2") .arg(dir).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + return(0); + } else { + KMessageBox::information( 0, i18n("Folder %1 left 'as is'.\nVerify ownership and permissions for user %2 who may not be able to log in!").arg(dir).arg(p_name) ); + return(-1); + } + } else { + KMessageBox::information( 0, i18n("%1 exists and is not a folder. User %2 will not be able to log in!").arg(dir).arg(p_name) ); + return(-1); + } + } else { + if (errno == ENOENT) { + if (mkdir(QFile::encodeName(dir), 0700) != 0) { + KMessageBox::error( 0, i18n("Cannot create %1 folder.\nError: %2").arg(dir).arg(QString::fromLocal8Bit(strerror(errno)))); + return(-1); + } + if (chown(QFile::encodeName(dir), p_uid, p_gid) != 0) { + KMessageBox::error( 0, i18n("Cannot change owner of %1 folder.\nError: %2").arg(dir).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + return(0); + } else { + KMessageBox::error( 0, i18n("stat call on %1 failed.\nError: %2").arg(dir).arg(QString::fromLocal8Bit(strerror(errno))) ); + return(-1); + } + } +} + +int KU::KUser::createMailBox() +{ + QString mailboxpath; + int fd; + mailboxpath = QFile::decodeName(MAIL_SPOOL_DIR) + "/" + p_name; + if((fd = open(QFile::encodeName(mailboxpath), O_CREAT|O_EXCL|O_WRONLY, + S_IRUSR|S_IWUSR)) < 0) { + if (errno != EEXIST) + { + KMessageBox::error( 0, i18n("Cannot create %1: %2") + .arg(mailboxpath) + .arg(QString::fromLocal8Bit(strerror(errno))) ); + return -1; + } + } + + close(fd); + + if (chown(QFile::encodeName(mailboxpath), p_uid, KU_MAILBOX_GID) != 0) { + KMessageBox::error( 0, i18n("Cannot change owner on mailbox: %1\nError: %2") + .arg(mailboxpath).arg(QString::fromLocal8Bit(strerror(errno))) ); + return -1; + } + + if (chmod(QFile::encodeName(mailboxpath), KU_MAILBOX_PERM) != 0) { + KMessageBox::error( 0, i18n("Cannot change permissions on mailbox: %1\nError: %2") + .arg(mailboxpath).arg(QString::fromLocal8Bit(strerror(errno))) ); + return -1; + } + + return 0; +} + +void KU::KUser::copyDir(const QString &srcPath, const QString &dstPath) +{ + mode_t mode; + QDir s(srcPath); + QDir d(dstPath); + + QString dot = QString::fromLatin1("."); + QString dotdot = QString::fromLatin1(".."); + + s.setFilter( QDir::All | QDir::Hidden | QDir::System ); + + for (uint i=0; i<s.count(); i++) { + QString name(s[i]); + + if (name == dot) + continue; + if (name == dotdot) + continue; + + QString filename(s.filePath(name)); + + QFileInfo info(filename); + mode = 0; + if ( info.permission(QFileInfo::ReadOwner) ) mode |= S_IRUSR; + if ( info.permission(QFileInfo::WriteOwner) ) mode |= S_IWUSR; + if ( info.permission(QFileInfo::ExeOwner) ) mode |= S_IXUSR; + if ( info.permission(QFileInfo::ReadGroup) ) mode |= S_IRGRP; + if ( info.permission(QFileInfo::WriteGroup) ) mode |= S_IWGRP; + if ( info.permission(QFileInfo::ExeGroup) ) mode |= S_IXGRP; + if ( info.permission(QFileInfo::ReadOther) ) mode |= S_IROTH; + if ( info.permission(QFileInfo::WriteOther) ) mode |= S_IWOTH; + if ( info.permission(QFileInfo::ExeOther) ) mode |= S_IXOTH; + + if ( info.isSymLink() ) { + QString link = info.readLink(); + + if (symlink(QFile::encodeName(link),QFile::encodeName(d.filePath(name))) != 0) { + KMessageBox::error( 0, i18n("Error creating symlink %1.\nError: %2") + .arg(d.filePath(s[i])).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + } else if ( info.isDir() ) { + QDir dir(filename); + + d.mkdir(name, FALSE); + copyDir(s.filePath(name), d.filePath(name)); + + if (chown(QFile::encodeName(d.filePath(name)), p_uid, p_gid) != 0) { + KMessageBox::error( 0, i18n("Cannot change owner of folder %1.\nError: %2") + .arg(d.filePath(s[i])).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + + if (chmod(QFile::encodeName(d.filePath(name)), mode) != 0) { + KMessageBox::error( 0, i18n("Cannot change permissions on folder %1.\nError: %2") + .arg(d.filePath(s[i])).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + + } else { + if (copyFile(filename, d.filePath(name)) == -1) { + continue; + } + + if (chown(QFile::encodeName(d.filePath(name)), p_uid, p_gid) != 0) { + KMessageBox::error( 0, i18n("Cannot change owner of file %1.\nError: %2") + .arg(d.filePath(s[i])).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + + if (chmod(QFile::encodeName(d.filePath(name)), mode) != 0) { + KMessageBox::error( 0, i18n("Cannot change permissions on file %1.\nError: %2") + .arg(d.filePath(s[i])).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + } + } +} + +int KU::KUser::copySkel() +{ + QDir s(QFile::decodeName(SKELDIR)); + QDir d(p_dir); + mode_t mode; + + if (!s.exists()) { + KMessageBox::error( 0, i18n("Folder %1 does not exist, cannot copy skeleton for %2.").arg(s.absPath()).arg(p_name) ); + return (-1); + } + + if (!d.exists()) { + KMessageBox::error( 0, i18n("Folder %1 does not exist, cannot copy skeleton.").arg(d.absPath()) ); + return (-1); + } + + mode = umask(0007); + copyDir(s.absPath(), d.absPath()); + umask( mode ); + + return 0; +} + +int KU::KUser::removeHome() +{ + struct stat sb; + + if (!stat(QFile::encodeName(p_dir), &sb)) + if (S_ISDIR(sb.st_mode) && sb.st_uid == p_uid) { + if (!KIO::NetAccess::del(KURL::fromPathOrURL(p_dir))) { + KMessageBox::error( 0, i18n("Cannot remove home folder %1.\nError: %2") + .arg(p_dir).arg(KIO::NetAccess::lastErrorString()) ); + } + } else { + KMessageBox::error( 0, i18n("Removal of home folder %1 failed (uid = %2, gid = %3).").arg(p_dir).arg(sb.st_uid).arg(sb.st_gid) ); + } + else { + KMessageBox::error( 0, i18n("stat call on file %1 failed.\nError: %2") + .arg(p_dir).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + + return 0; +} + +//TODO: remove at jobs too. + +int KU::KUser::removeCrontabs() +{ + QString file; + QString command; + + file = QFile::decodeName(CRONTAB_DIR) + "/" + p_name; + if ( access(QFile::encodeName(file), F_OK) == 0 ) { + command = QString::fromLatin1("crontab -u %1 -r").arg(KProcess::quote(p_name)); + if ( system(QFile::encodeName(command)) != 0 ) { + KMessageBox::error( 0, i18n("Cannot remove crontab %1.\nError: %2") + .arg(command).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + } + + return 0; +} + +int KU::KUser::removeMailBox() +{ + QString file; + + file = QFile::decodeName(MAIL_SPOOL_DIR) + "/" + p_name; + if (remove(QFile::encodeName(file)) != 0) { + KMessageBox::error( 0, i18n("Cannot remove mailbox %1.\nError: %2") + .arg(file).arg(QString::fromLocal8Bit(strerror(errno))) ); + } + + return 0; +} + +int KU::KUser::removeProcesses() +{ + // be paranoid -- kill all processes owned by that user, if not root. + + if (p_uid != 0) + switch (fork()) { + case 0: + setuid(p_uid); + kill(-1, 9); + _exit(0); + break; + case -1: + KMessageBox::error( 0, + i18n("Cannot fork while trying to kill processes for uid %1.").arg(p_uid) ); + break; + } + + return 0; +} + +KU::KUsers::KUsers(KUserPrefsBase *cfg) +{ + mUsers.setAutoDelete(TRUE); + mCfg = cfg; +} + +KU::KUsers::~KUsers() +{ + mUsers.clear(); +} + +const QString &KU::KUsers::getDOMSID() const +{ + return domsid; +} + +void KU::KUsers::parseGecos( const char *gecos, QString &name, + QString &field1, QString &field2, QString &field3 ) +{ + int no = 0; + const char *s = gecos; + const char *pos = NULL; + // At least one part of the string exists + for(;;) { + pos = strchr(s, ','); + QString val; + if(pos == NULL) + val = QString::fromLocal8Bit(s); + else + val = QString::fromLocal8Bit(s, (int)(pos-s)); + + switch(no) { + case 0: name = val; break; + case 1: field1 = val; break; + case 2: field2 = val; break; + case 3: field3 = val; break; + } + if(pos == NULL) break; + s = pos+1; + no++; + } +} + +void KU::KUsers::fillGecos(KU::KUser *user, const char *gecos) +{ + QString name,field1,field2,field3; + parseGecos( gecos, name, field1, field2, field3 ); + user->setFullName( name ); + caps & Cap_BSD ? user->setOffice( field1 ) : user->setOffice1( field1 ); + caps & Cap_BSD ? user->setWorkPhone( field2 ) : user->setOffice2( field2 ); + caps & Cap_BSD ? user->setHomePhone( field3 ) : user->setAddress( field3 ); +} + +bool KU::KUsers::doCreate(KU::KUser *user) +{ + QString h_dir; + + if(user->getCreateMailBox()) { + user->createMailBox(); + user->setCreateMailBox(false); + } + + if(user->getCreateHome()) { + if(user->createHome()) { + user->setCreateHome(false); + } else { + return false; // if createHome fails, copySkel is irrelevant! + } + + if(user->getCopySkel()) { + if((user->copySkel()) == 0) { + user->setCopySkel(false); + } + } + + } + return TRUE; +} + +bool KU::KUsers::doDelete( KU::KUser *user ) +{ + kdDebug() << "delete user: " << user->getName() << " uid: " << user->getUID() << endl; + if ( user->isDeleteHome ) { + user->removeHome(); + user->removeCrontabs(); + } + if ( user->isDeleteMailBox ) + user->removeMailBox(); +/* + user->removeProcesses(); +*/ + return TRUE; +} + +KU::KUser *KU::KUsers::lookup(const QString & name) +{ + KU::KUser *user; + QPtrListIterator<KU::KUser> it( mUsers ); + + while ( (user = it.current()) != 0 && user->getName() != name ) ++it; + return user; +} + +KU::KUser *KU::KUsers::lookup(uid_t uid) +{ + KU::KUser *user; + QPtrListIterator<KU::KUser> it( mUsers ); + + while ( (user = it.current()) != 0 && user->getUID() != uid ) ++it; + return user; +} + +KU::KUser *KU::KUsers::lookup_sam( const SID &sid ) +{ + KU::KUser *user; + QPtrListIterator<KU::KUser> it( mUsers ); + + while ( (user = it.current()) != 0 && user->getSID() != sid ) ++it; + return user; +} + +KU::KUser *KU::KUsers::lookup_sam( const QString &sid ) +{ + KU::KUser *user; + QPtrListIterator<KU::KUser> it( mUsers ); + + while ( (user = it.current()) != 0 && user->getSID().getSID() != sid ) ++it; + return user; +} + +KU::KUser *KU::KUsers::lookup_sam( uint rid ) +{ + KU::KUser *user; + QPtrListIterator<KU::KUser> it( mUsers ); + + while ( (user = it.current()) != 0 && user->getSID().getRID() != rid ) ++it; + return user; +} + +uid_t KU::KUsers::first_free() +{ + uid_t t; + + for (t = mCfg->firstUID() ; t<65534; t++) + if (lookup(t) == NULL) + return t; + + return NO_FREE; +} + +uint KU::KUsers::first_free_sam() +{ + uint t; + + for (t = 1000; t<65534; t++) + if (lookup_sam(t) == NULL) + return t; + + return 0; +} + +uint KU::KUsers::count() const +{ + return mUsers.count(); +} + +KU::KUser *KU::KUsers::operator[](uint num) +{ + return mUsers.at(num); +} + +KU::KUser *KU::KUsers::first() +{ + return mUsers.first(); +} + +KU::KUser *KU::KUsers::next() +{ + return mUsers.next(); +} + +void KU::KUsers::add(KU::KUser *user) +{ + mAdd.append( user ); +} + +void KU::KUsers::del(KU::KUser *user) +{ + mDel.append( user ); +} + +void KU::KUsers::mod(KU::KUser *uold, const KU::KUser &unew) +{ + mMod.insert( uold, unew ); +} + +void KU::KUsers::commit() +{ + kdDebug() << "KU::KUsers::commit()" << endl; + KU::KUser *user; + DelIt dit( mDelSucc ); + AddIt ait( mAddSucc ); + ModIt mit = mModSucc.begin(); + +//commit modifications + while ( mit != mModSucc.end() ) { + *(mit.key()) = mit.data(); + mit++; + } +//commit deletes + while ( (user = dit.current()) != 0 ) { + ++dit; + doDelete( user ); + mUsers.remove( user ); + } +//commit additions + while ( (user = ait.current()) != 0 ) { + ++ait; + doCreate( user ); + mUsers.append( user ); + } + +//clear the unsuccessful modifications + cancelMods(); +} + +void KU::KUsers::cancelMods() +{ + KU::KUser *user; + while ( (user = mAdd.first()) ) { + delete user; + mAdd.remove(); + } + mDel.clear(); + mMod.clear(); +} |