/* * Copyright (c) 1998 Denis Perchine * Copyright (c) 2004 Szombathelyi György * Former maintainer: Adriaan de Groot * * 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 #include #include #include #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #include #include #include #include "kglobal_.h" #include "kuser.h" #include "misc.h" #include #include #include #include #include #include // 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 TQString &KU::KUser::getName() const { return p_name; } const TQString &KU::KUser::getSurname() const { return p_surname; } const TQString &KU::KUser::getEmail() const { return p_email; } const TQString &KU::KUser::getPwd() const { return p_pwd; } const TQString &KU::KUser::getHomeDir() const { return p_dir; } const TQString &KU::KUser::getShell() const { return p_shell; } const TQString &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 TQString &KU::KUser::getOffice() const { return p_office; } const TQString &KU::KUser::getWorkPhone() const { return p_ophone; } const TQString &KU::KUser::getHomePhone() const { return p_hphone; } // New fields needed for the FreeBSD /etc/master.passwd file const TQString &KU::KUser::getClass() const { return p_class; } const TQString &KU::KUser::getOffice1() const { return p_office1; } const TQString &KU::KUser::getOffice2() const { return p_office2; } const TQString &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 TQString &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 TQString &KU::KUser::getLMPwd() const // sam_lmpwd, { return sam_lmpwd; } const TQString &KU::KUser::getNTPwd() const //sam_ntpwd, { return sam_ntpwd; } const TQString &KU::KUser::getLoginScript() const //sam_loginscript, { return sam_loginscript; } const TQString &KU::KUser::getProfilePath() const // sam_profile, { return sam_profile; } const TQString &KU::KUser::getHomeDrive() const //sam_homedrive, { return sam_homedrive; } const TQString &KU::KUser::getHomePath() const //sam_homepath; { return sam_homepath; } const TQString &KU::KUser::getWorkstations() const //sam_workstation; { return sam_workstations; } const TQString &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 TQString &data) { p_name = data; } void KU::KUser::setSurname(const TQString &data) { p_surname = data; } void KU::KUser::setEmail(const TQString &data) { p_email = data; } void KU::KUser::setPwd(const TQString &data) { p_pwd = data; } void KU::KUser::setHomeDir(const TQString &data) { p_dir = data; } void KU::KUser::setShell(const TQString &data) { p_shell = data; } void KU::KUser::setFullName(const TQString &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 TQString &data) { p_office = data; } void KU::KUser::setWorkPhone(const TQString &data) { p_ophone = data; } void KU::KUser::setHomePhone(const TQString &data) { p_hphone = data; } // New fields needed for the FreeBSD /etc/master.passwd file void KU::KUser::setClass(const TQString &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 TQString &data) { p_office1 = data; } void KU::KUser::setOffice2(const TQString &data) { p_office2 = data; } void KU::KUser::setAddress(const TQString &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 TQString &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 TQString &data ) // sam_lmpwd, { sam_lmpwd = data; } void KU::KUser::setNTPwd( const TQString &data ) //sam_ntpwd, { sam_ntpwd = data; } void KU::KUser::setLoginScript( const TQString &data ) //sam_loginscript, { sam_loginscript = data; } void KU::KUser::setProfilePath( const TQString &data) // sam_profile, { sam_profile = data; } void KU::KUser::setHomeDrive( const TQString &data ) //sam_homedrive, { sam_homedrive = data; } void KU::KUser::setHomePath( const TQString &data ) //sam_homepath; { sam_homepath = data; } void KU::KUser::setWorkstations( const TQString &data ) //sam_workstation; { sam_workstations = data; } void KU::KUser::setDomain( const TQString &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(TQFile::encodeName(p_dir), 0700) != 0) { if (errno != EEXIST) { KMessageBox::error( 0, i18n("Cannot create home folder %1.\nError: %2").arg(p_dir).arg(TQString::fromLocal8Bit(strerror(errno))) ); return(0); } } if (chown(TQFile::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(TQString::fromLocal8Bit(strerror(errno))) ); return(1); } if (chmod(TQFile::encodeName(p_dir), KU_HOMEDIR_PERM) != 0) { KMessageBox::error( 0, i18n("Cannot change permissions on home folder %1.\nError: %2").arg(p_dir).arg(TQString::fromLocal8Bit(strerror(errno))) ); return(1); } return(1); } int KU::KUser::tryCreate(const TQString &dir) { struct stat sb; int rc = 0; rc = stat(TQFile::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), TQString(), KStdGuiItem::cont() ) == KMessageBox::Continue) { if (chown(TQFile::encodeName(dir), p_uid, p_gid) != 0) { KMessageBox::error( 0, i18n("Cannot change owner of %1 folder.\nError: %2") .arg(dir).arg(TQString::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(TQFile::encodeName(dir), 0700) != 0) { KMessageBox::error( 0, i18n("Cannot create %1 folder.\nError: %2").arg(dir).arg(TQString::fromLocal8Bit(strerror(errno)))); return(-1); } if (chown(TQFile::encodeName(dir), p_uid, p_gid) != 0) { KMessageBox::error( 0, i18n("Cannot change owner of %1 folder.\nError: %2").arg(dir).arg(TQString::fromLocal8Bit(strerror(errno))) ); } return(0); } else { KMessageBox::error( 0, i18n("stat call on %1 failed.\nError: %2").arg(dir).arg(TQString::fromLocal8Bit(strerror(errno))) ); return(-1); } } } int KU::KUser::createMailBox() { TQString mailboxpath; int fd; mailboxpath = TQFile::decodeName(MAIL_SPOOL_DIR) + "/" + p_name; if((fd = open(TQFile::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(TQString::fromLocal8Bit(strerror(errno))) ); return -1; } } close(fd); if (chown(TQFile::encodeName(mailboxpath), p_uid, KU_MAILBOX_GID) != 0) { KMessageBox::error( 0, i18n("Cannot change owner on mailbox: %1\nError: %2") .arg(mailboxpath).arg(TQString::fromLocal8Bit(strerror(errno))) ); return -1; } if (chmod(TQFile::encodeName(mailboxpath), KU_MAILBOX_PERM) != 0) { KMessageBox::error( 0, i18n("Cannot change permissions on mailbox: %1\nError: %2") .arg(mailboxpath).arg(TQString::fromLocal8Bit(strerror(errno))) ); return -1; } return 0; } void KU::KUser::copyDir(const TQString &srcPath, const TQString &dstPath) { mode_t mode; TQDir s(srcPath); TQDir d(dstPath); TQString dot = TQString::fromLatin1("."); TQString dotdot = TQString::fromLatin1(".."); s.setFilter( TQDir::All | TQDir::Hidden | TQDir::System ); for (uint i=0; isetFullName( 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) { TQString 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 TQString & name) { KU::KUser *user; TQPtrListIterator it( mUsers ); while ( (user = it.current()) != 0 && user->getName() != name ) ++it; return user; } KU::KUser *KU::KUsers::lookup(uid_t uid) { KU::KUser *user; TQPtrListIterator 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; TQPtrListIterator it( mUsers ); while ( (user = it.current()) != 0 && user->getSID() != sid ) ++it; return user; } KU::KUser *KU::KUsers::lookup_sam( const TQString &sid ) { KU::KUser *user; TQPtrListIterator 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; TQPtrListIterator 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(); }