You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1054 lines
22 KiB
1054 lines
22 KiB
/*
|
|
* 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 <tqstring.h>
|
|
#include <tqdir.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 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.").tqarg(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").tqarg(p_dir).tqarg(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").tqarg(p_dir).tqarg(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").tqarg(p_dir).tqarg(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?").tqarg(dir).tqarg(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") .tqarg(dir).tqarg(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!").tqarg(dir).tqarg(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!").tqarg(dir).tqarg(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").tqarg(dir).tqarg(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").tqarg(dir).tqarg(TQString::fromLocal8Bit(strerror(errno))) );
|
|
}
|
|
return(0);
|
|
} else {
|
|
KMessageBox::error( 0, i18n("stat call on %1 failed.\nError: %2").tqarg(dir).tqarg(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")
|
|
.tqarg(mailboxpath)
|
|
.tqarg(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")
|
|
.tqarg(mailboxpath).tqarg(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")
|
|
.tqarg(mailboxpath).tqarg(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; i<s.count(); i++) {
|
|
TQString name(s[i]);
|
|
|
|
if (name == dot)
|
|
continue;
|
|
if (name == dotdot)
|
|
continue;
|
|
|
|
TQString filename(s.filePath(name));
|
|
|
|
TQFileInfo info(filename);
|
|
mode = 0;
|
|
if ( info.permission(TQFileInfo::ReadOwner) ) mode |= S_IRUSR;
|
|
if ( info.permission(TQFileInfo::WriteOwner) ) mode |= S_IWUSR;
|
|
if ( info.permission(TQFileInfo::ExeOwner) ) mode |= S_IXUSR;
|
|
if ( info.permission(TQFileInfo::ReadGroup) ) mode |= S_IRGRP;
|
|
if ( info.permission(TQFileInfo::WriteGroup) ) mode |= S_IWGRP;
|
|
if ( info.permission(TQFileInfo::ExeGroup) ) mode |= S_IXGRP;
|
|
if ( info.permission(TQFileInfo::ReadOther) ) mode |= S_IROTH;
|
|
if ( info.permission(TQFileInfo::WriteOther) ) mode |= S_IWOTH;
|
|
if ( info.permission(TQFileInfo::ExeOther) ) mode |= S_IXOTH;
|
|
|
|
if ( info.isSymLink() ) {
|
|
TQString link = info.readLink();
|
|
|
|
if (symlink(TQFile::encodeName(link),TQFile::encodeName(d.filePath(name))) != 0) {
|
|
KMessageBox::error( 0, i18n("Error creating symlink %1.\nError: %2")
|
|
.tqarg(d.filePath(s[i])).tqarg(TQString::fromLocal8Bit(strerror(errno))) );
|
|
}
|
|
} else if ( info.isDir() ) {
|
|
TQDir dir(filename);
|
|
|
|
d.mkdir(name, FALSE);
|
|
copyDir(s.filePath(name), d.filePath(name));
|
|
|
|
if (chown(TQFile::encodeName(d.filePath(name)), p_uid, p_gid) != 0) {
|
|
KMessageBox::error( 0, i18n("Cannot change owner of folder %1.\nError: %2")
|
|
.tqarg(d.filePath(s[i])).tqarg(TQString::fromLocal8Bit(strerror(errno))) );
|
|
}
|
|
|
|
if (chmod(TQFile::encodeName(d.filePath(name)), mode) != 0) {
|
|
KMessageBox::error( 0, i18n("Cannot change permissions on folder %1.\nError: %2")
|
|
.tqarg(d.filePath(s[i])).tqarg(TQString::fromLocal8Bit(strerror(errno))) );
|
|
}
|
|
|
|
} else {
|
|
if (copyFile(filename, d.filePath(name)) == -1) {
|
|
continue;
|
|
}
|
|
|
|
if (chown(TQFile::encodeName(d.filePath(name)), p_uid, p_gid) != 0) {
|
|
KMessageBox::error( 0, i18n("Cannot change owner of file %1.\nError: %2")
|
|
.tqarg(d.filePath(s[i])).tqarg(TQString::fromLocal8Bit(strerror(errno))) );
|
|
}
|
|
|
|
if (chmod(TQFile::encodeName(d.filePath(name)), mode) != 0) {
|
|
KMessageBox::error( 0, i18n("Cannot change permissions on file %1.\nError: %2")
|
|
.tqarg(d.filePath(s[i])).tqarg(TQString::fromLocal8Bit(strerror(errno))) );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int KU::KUser::copySkel()
|
|
{
|
|
TQDir s(TQFile::decodeName(SKELDIR));
|
|
TQDir d(p_dir);
|
|
mode_t mode;
|
|
|
|
if (!s.exists()) {
|
|
KMessageBox::error( 0, i18n("Folder %1 does not exist, cannot copy skeleton for %2.").tqarg(s.absPath()).tqarg(p_name) );
|
|
return (-1);
|
|
}
|
|
|
|
if (!d.exists()) {
|
|
KMessageBox::error( 0, i18n("Folder %1 does not exist, cannot copy skeleton.").tqarg(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(TQFile::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")
|
|
.tqarg(p_dir).tqarg(KIO::NetAccess::lastErrorString()) );
|
|
}
|
|
} else {
|
|
KMessageBox::error( 0, i18n("Removal of home folder %1 failed (uid = %2, gid = %3).").tqarg(p_dir).tqarg(sb.st_uid).tqarg(sb.st_gid) );
|
|
}
|
|
else {
|
|
KMessageBox::error( 0, i18n("stat call on file %1 failed.\nError: %2")
|
|
.tqarg(p_dir).tqarg(TQString::fromLocal8Bit(strerror(errno))) );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//TODO: remove at jobs too.
|
|
|
|
int KU::KUser::removeCrontabs()
|
|
{
|
|
TQString file;
|
|
TQString command;
|
|
|
|
file = TQFile::decodeName(CRONTAB_DIR) + "/" + p_name;
|
|
if ( access(TQFile::encodeName(file), F_OK) == 0 ) {
|
|
command = TQString::fromLatin1("crontab -u %1 -r").tqarg(KProcess::quote(p_name));
|
|
if ( system(TQFile::encodeName(command)) != 0 ) {
|
|
KMessageBox::error( 0, i18n("Cannot remove crontab %1.\nError: %2")
|
|
.tqarg(command).tqarg(TQString::fromLocal8Bit(strerror(errno))) );
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int KU::KUser::removeMailBox()
|
|
{
|
|
TQString file;
|
|
|
|
file = TQFile::decodeName(MAIL_SPOOL_DIR) + "/" + p_name;
|
|
if (remove(TQFile::encodeName(file)) != 0) {
|
|
KMessageBox::error( 0, i18n("Cannot remove mailbox %1.\nError: %2")
|
|
.tqarg(file).tqarg(TQString::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.").tqarg(p_uid) );
|
|
break;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
KU::KUsers::KUsers(KUserPrefsBase *cfg)
|
|
{
|
|
mUsers.setAutoDelete(TRUE);
|
|
mCfg = cfg;
|
|
}
|
|
|
|
KU::KUsers::~KUsers()
|
|
{
|
|
mUsers.clear();
|
|
}
|
|
|
|
const TQString &KU::KUsers::getDOMSID() const
|
|
{
|
|
return domsid;
|
|
}
|
|
|
|
void KU::KUsers::parseGecos( const char *gecos, TQString &name,
|
|
TQString &field1, TQString &field2, TQString &field3 )
|
|
{
|
|
int no = 0;
|
|
const char *s = gecos;
|
|
const char *pos = NULL;
|
|
// At least one part of the string exists
|
|
for(;;) {
|
|
pos = strchr(s, ',');
|
|
TQString val;
|
|
if(pos == NULL)
|
|
val = TQString::fromLocal8Bit(s);
|
|
else
|
|
val = TQString::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)
|
|
{
|
|
TQString 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)
|
|
{
|
|
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<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;
|
|
TQPtrListIterator<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;
|
|
TQPtrListIterator<KU::KUser> 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<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;
|
|
TQPtrListIterator<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();
|
|
}
|