2 * Copyright (c) 1998 Denis Perchine <dyp@perchine.com>
3 * Copyright (c) 2004 Szombathelyi GyĂśrgy <gyurco@freemail.hu>
4 * Former maintainer: Adriaan de Groot <groot@kde.org>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License version 2 as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB. If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
23 #include <ku_config.h>
25 #include <sys/types.h>
31 #ifdef HAVE_SYS_STAT_H
37 #include <QSharedData>
39 #include <kstandarddirs.h>
40 #include <kmessagebox.h>
43 #include <kio/netaccess.h>
50 KU_User_Private::KU_User_Private()
64 CreateMailBox
= false;
67 DeleteMailBox
= false;
76 d
= new KU_User_Private
;
79 KU_User::KU_User(const KU_User
*user
)
81 d
= new KU_User_Private
;
85 void KU_User::copy(const KU_User
*user
)
92 bool KU_User::operator ==(const KU_User
&other
) const
94 if ( getUID() == other
.getUID() &&
95 getName() == other
.getName() )
105 KU_PROPERTY_IMPL(KU_User
,int,Caps
)
106 KU_PROPERTY_IMPL(KU_User
,QString
,Name
)
107 KU_PROPERTY_IMPL(KU_User
,QString
,Surname
)
108 KU_PROPERTY_IMPL(KU_User
,QString
,Email
)
109 KU_PROPERTY_IMPL(KU_User
,QString
,Pwd
)
110 KU_PROPERTY_IMPL(KU_User
,QString
,HomeDir
)
111 KU_PROPERTY_IMPL(KU_User
,QString
,Shell
)
112 KU_PROPERTY_IMPL(KU_User
,QString
,FullName
)
113 KU_PROPERTY_IMPL(KU_User
,uid_t
,UID
)
114 KU_PROPERTY_IMPL(KU_User
,uid_t
,GID
)
115 KU_PROPERTY_IMPL(KU_User
,bool,Disabled
)
119 KU_PROPERTY_IMPL(KU_User
,QString
,Office
)
120 KU_PROPERTY_IMPL(KU_User
,QString
,WorkPhone
)
121 KU_PROPERTY_IMPL(KU_User
,QString
,HomePhone
)
122 KU_PROPERTY_IMPL(KU_User
,QString
,Class
)
124 KU_PROPERTY_IMPL(KU_User
,QString
,Office1
)
125 KU_PROPERTY_IMPL(KU_User
,QString
,Office2
)
126 KU_PROPERTY_IMPL(KU_User
,QString
,Address
)
129 KU_PROPERTY_IMPL(KU_User
,QString
,SPwd
)
130 KU_PROPERTY_IMPL(KU_User
,time_t,Expire
)
131 KU_PROPERTY_IMPL(KU_User
,time_t,LastChange
)
132 KU_PROPERTY_IMPL(KU_User
,int,Min
)
133 KU_PROPERTY_IMPL(KU_User
,int,Max
)
134 KU_PROPERTY_IMPL(KU_User
,int,Warn
)
135 KU_PROPERTY_IMPL(KU_User
,int,Inactive
)
136 KU_PROPERTY_IMPL(KU_User
,int,Flag
)
139 KU_PROPERTY_IMPL(KU_User
,QString
, LMPwd
)
140 KU_PROPERTY_IMPL(KU_User
,QString
, NTPwd
)
141 KU_PROPERTY_IMPL(KU_User
,QString
, LoginScript
)
142 KU_PROPERTY_IMPL(KU_User
,QString
, ProfilePath
)
143 KU_PROPERTY_IMPL(KU_User
,QString
, HomeDrive
)
144 KU_PROPERTY_IMPL(KU_User
,QString
, HomePath
)
145 KU_PROPERTY_IMPL(KU_User
,QString
, Workstations
)
146 KU_PROPERTY_IMPL(KU_User
,QString
, Domain
)
147 KU_PROPERTY_IMPL(KU_User
,SID
, SID
)
148 KU_PROPERTY_IMPL(KU_User
,SID
, PGSID
)
151 KU_PROPERTY_IMPL(KU_User
,bool, CreateHome
)
152 KU_PROPERTY_IMPL(KU_User
,bool, CreateMailBox
)
153 KU_PROPERTY_IMPL(KU_User
,bool, CopySkel
)
154 KU_PROPERTY_IMPL(KU_User
,bool, DeleteHome
)
155 KU_PROPERTY_IMPL(KU_User
,bool, DeleteMailBox
)
157 int KU_User::createHome()
160 if(d
->HomeDir
.isNull() || d
->HomeDir
.isEmpty()) {
161 KMessageBox::sorry( 0, i18n("Cannot create home folder for %1: it is null or empty.", d
->Name
) );
164 if (mkdir(QFile::encodeName(d
->HomeDir
), 0700) != 0) {
167 KMessageBox::error( 0, i18n("Cannot create home folder %1.\nError: %2", d
->HomeDir
, QString::fromLocal8Bit(strerror(errno
))) );
172 if (chown(QFile::encodeName(d
->HomeDir
), d
->UID
, d
->GID
) != 0) {
173 KMessageBox::error( 0, i18n("Cannot change owner of home folder %1.\nError: %2", d
->HomeDir
, QString::fromLocal8Bit(strerror(errno
))) );
177 if (chmod(QFile::encodeName(d
->HomeDir
), KU_HOMEDIR_PERM
) != 0) {
178 KMessageBox::error( 0, i18n("Cannot change permissions on home folder %1.\nError: %2", d
->HomeDir
, QString::fromLocal8Bit(strerror(errno
))) );
184 int KU_User::tryCreate(const QString
&dir
)
189 rc
= stat(QFile::encodeName(dir
), &sb
);
191 if (S_ISDIR(sb
.st_mode
)) {
192 if (KMessageBox::warningContinueCancel( 0,
193 i18n("Folder %1 already exists.\nWill make %2 owner and change permissions.\nDo you want to continue?", dir
, d
->Name
),
194 QString(), KStandardGuiItem::cont() ) == KMessageBox::Continue
) {
196 if (chown(QFile::encodeName(dir
), d
->UID
, d
->GID
) != 0) {
197 KMessageBox::error( 0, i18n("Cannot change owner of %1 folder.\nError: %2" , dir
, QString::fromLocal8Bit(strerror(errno
))) );
201 KMessageBox::information( 0, i18n("Folder %1 left 'as is'.\nVerify ownership and permissions for user %2 who may not be able to log in.", dir
, d
->Name
) );
205 KMessageBox::information( 0, i18n("%1 exists and is not a folder. User %2 will not be able to log in.", dir
, d
->Name
) );
209 if (errno
== ENOENT
) {
210 if (mkdir(QFile::encodeName(dir
), 0700) != 0) {
211 KMessageBox::error( 0, i18n("Cannot create %1 folder.\nError: %2", dir
, QString::fromLocal8Bit(strerror(errno
))));
214 if (chown(QFile::encodeName(dir
), d
->UID
, d
->GID
) != 0) {
215 KMessageBox::error( 0, i18n("Cannot change owner of %1 folder.\nError: %2", dir
, QString::fromLocal8Bit(strerror(errno
))) );
219 KMessageBox::error( 0, i18n("stat call on %1 failed.\nError: %2", dir
, QString::fromLocal8Bit(strerror(errno
))) );
225 int KU_User::createMailBox()
229 mailboxpath
= QFile::decodeName(MAIL_SPOOL_DIR
) + '/' + d
->Name
;
230 if((fd
= open(QFile::encodeName(mailboxpath
), O_CREAT
|O_EXCL
|O_WRONLY
,
231 S_IRUSR
|S_IWUSR
)) < 0) {
234 KMessageBox::error( 0, i18n("Cannot create %1: %2",
236 QString::fromLocal8Bit(strerror(errno
))) );
243 if (chown(QFile::encodeName(mailboxpath
), d
->UID
, KU_MAILBOX_GID
) != 0) {
244 KMessageBox::error( 0, i18n("Cannot change owner on mailbox: %1\nError: %2",
245 mailboxpath
, QString::fromLocal8Bit(strerror(errno
))) );
249 if (chmod(QFile::encodeName(mailboxpath
), KU_MAILBOX_PERM
) != 0) {
250 KMessageBox::error( 0, i18n("Cannot change permissions on mailbox: %1\nError: %2",
251 mailboxpath
, QString::fromLocal8Bit(strerror(errno
))) );
258 int KU_User::copySkel()
260 QDir
source(QFile::decodeName(SKELDIR
));
261 QDir
dest(d
->HomeDir
);
264 if (!source
.exists()) {
265 KMessageBox::error( 0, i18n("Folder %1 does not exist, cannot copy skeleton for %2.", source
.absolutePath(), d
->Name
) );
269 if (!dest
.exists()) {
270 KMessageBox::error( 0, i18n("Folder %1 does not exist, cannot copy skeleton.", dest
.absolutePath()) );
275 copyDir(source
.absolutePath(), dest
.absolutePath(), d
->UID
, d
->GID
);
281 int KU_User::removeHome()
285 if (!stat(QFile::encodeName(d
->HomeDir
), &sb
))
286 if (S_ISDIR(sb
.st_mode
) && sb
.st_uid
== d
->UID
) {
287 if (!KIO::NetAccess::del(KUrl(d
->HomeDir
),0L)) {
288 KMessageBox::error( 0, i18n("Cannot remove home folder %1.\nError: %2",
289 d
->HomeDir
, KIO::NetAccess::lastErrorString()) );
292 KMessageBox::error( 0, i18n("Removal of home folder %1 failed (uid = %2, gid = %3).", d
->HomeDir
, sb
.st_uid
, sb
.st_gid
) );
295 KMessageBox::error( 0, i18n("stat call on file %1 failed.\nError: %2",
296 d
->HomeDir
, QString::fromLocal8Bit(strerror(errno
))) );
302 //TODO: remove at jobs too.
304 int KU_User::removeCrontabs()
309 file
= QFile::decodeName(CRONTAB_DIR
) + '/' + d
->Name
;
310 if ( access(QFile::encodeName(file
), F_OK
) == 0 ) {
311 command
= QString::fromLatin1("crontab -u %1 -r").arg(KShell::quoteArg(d
->Name
));
312 if ( system(QFile::encodeName(command
)) != 0 ) {
313 KMessageBox::error( 0, i18n("Cannot remove crontab %1.\nError: %2",
314 command
, QString::fromLocal8Bit(strerror(errno
))) );
321 int KU_User::removeMailBox()
325 file
= QFile::decodeName(MAIL_SPOOL_DIR
) + '/' + d
->Name
;
326 if (remove(QFile::encodeName(file
)) != 0) {
327 KMessageBox::error( 0, i18n("Cannot remove mailbox %1.\nError: %2",
328 file
, QString::fromLocal8Bit(strerror(errno
))) );
334 KU_Users::KU_Users(KU_PrefsBase
*cfg
)
339 KU_Users::~KU_Users()
343 const QString
&KU_Users::getDOMSID() const
348 void KU_Users::parseGecos( const char *gecos
, QString
&name
,
349 QString
&field1
, QString
&field2
, QString
&field3
)
352 const char *s
= gecos
;
353 const char *pos
= NULL
;
354 // At least one part of the string exists
356 pos
= strchr(s
, ',');
359 val
= QString::fromLocal8Bit(s
);
361 val
= QString::fromLocal8Bit(s
, (int)(pos
-s
));
364 case 0: name
= val
; break;
365 case 1: field1
= val
; break;
366 case 2: field2
= val
; break;
367 case 3: field3
= val
; break;
369 if(pos
== NULL
) break;
375 void KU_Users::fillGecos(KU_User
&user
, const char *gecos
)
377 QString name
,field1
,field2
,field3
;
378 parseGecos( gecos
, name
, field1
, field2
, field3
);
379 user
.setFullName( name
);
380 caps
& Cap_BSD
? user
.setOffice( field1
) : user
.setOffice1( field1
);
381 caps
& Cap_BSD
? user
.setWorkPhone( field2
) : user
.setOffice2( field2
);
382 caps
& Cap_BSD
? user
.setHomePhone( field3
) : user
.setAddress( field3
);
385 bool KU_Users::doCreate(KU_User
*user
)
389 if(user
->getCreateMailBox()) {
390 user
->createMailBox();
391 user
->setCreateMailBox(false);
394 if(user
->getCreateHome()) {
395 if(user
->createHome()) {
396 user
->setCreateHome(false);
398 return false; // if createHome fails, copySkel is irrelevant!
401 if(user
->getCopySkel()) {
402 if((user
->copySkel()) == 0) {
403 user
->setCopySkel(false);
411 bool KU_Users::doDelete( KU_User
*user
)
413 kDebug() << "delete user: " << user
->getName() << " uid: " << user
->getUID();
414 if ( user
->getDeleteHome() ) {
416 user
->removeCrontabs();
418 if ( user
->getDeleteMailBox() )
419 user
->removeMailBox();
424 int KU_Users::lookup(const QString
& name
) const
426 for ( int i
= 0; i
<count(); i
++ ) {
427 if ( at(i
).getName() == name
) return i
;
432 int KU_Users::lookup(uid_t uid
) const
434 for ( int i
= 0; i
<count(); i
++ ) {
435 if ( at(i
).getUID() == uid
) return i
;
440 int KU_Users::lookup_sam( const SID
&sid
) const
442 for ( int i
= 0; i
<count(); i
++ ) {
443 if ( at(i
).getSID() == sid
) return i
;
448 int KU_Users::lookup_sam( const QString
&sid
) const
450 for ( int i
= 0; i
<count(); i
++ ) {
451 if ( at(i
).getSID().getSID() == sid
) return i
;
456 int KU_Users::lookup_sam( uint rid
) const
458 for ( int i
= 0; i
<count(); i
++ ) {
459 if ( at(i
).getSID().getRID() == rid
) return i
;
464 uid_t
KU_Users::first_free() const
468 for (t
= mCfg
->firstUID() ; t
<65534; t
++)
475 uint
KU_Users::first_free_sam() const
479 for (t
= 1000; t
<65534; t
++)
480 if (lookup_sam(t
) == -1)
486 void KU_Users::add(const KU_User
&user
)
491 void KU_Users::del( int index
)
493 mDel
.append( index
);
496 void KU_Users::mod(int index
, const KU_User
&newuser
)
498 mMod
.insert( index
, newuser
);
501 void KU_Users::commit()
503 kDebug() << "KU_Users::commit()";
505 for ( ModList::Iterator it
= mModSucc
.begin(); it
!= mModSucc
.end(); ++it
) {
506 replace(it
.key(),*it
);
508 for ( AddList::Iterator it
= mAddSucc
.begin(); it
!= mAddSucc
.end(); ++it
) {
511 for ( DelList::Iterator it
= mDelSucc
.begin(); it
!= mDelSucc
.end(); ++it
) {
517 void KU_Users::cancelMods()