Fix two issues reported by Christoph Bartoschek ('Suspicious code in revision 867140...
[kdenetwork.git] / filesharing / simple / fileshare.cpp
blob9feb03a35de814f4489a9c0186ccbec39c31d7ba
1 /*
2 Copyright (c) 2002 Laurent Montel <montel@kde.org>
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2 of the License, or
6 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 #include <unistd.h>
19 #include <qlayout.h>
20 #include <qlabel.h>
21 #include <qdir.h>
22 #include <qradiobutton.h>
23 #include <qcheckbox.h>
25 //Added by qt3to4:
26 #include <QPixmap>
27 #include <QVBoxLayout>
28 #include <QTextStream>
29 #include <QBoxLayout>
30 #include <Q3PtrList>
32 #include <kpushbutton.h>
33 #include <kdebug.h>
34 #include <kdialog.h>
35 #include <kgenericfactory.h>
36 #include <k3listview.h>
37 #include <kiconloader.h>
38 #include <knfsshare.h>
39 #include <ksambashare.h>
40 #include <kfileshare.h>
41 #include <kstandarddirs.h>
42 #include <kconfig.h>
43 #include <kmessagebox.h>
44 #include <kuser.h>
45 #include <kurl.h>
46 #include <kprocess.h>
47 #include <krichtextlabel.h>
48 #include <KVBox>
50 #include "propertiespage.h"
51 #include "nfsfile.h"
52 #include "sambafile.h"
54 #include "controlcenter.h"
55 #include "fileshare.h"
56 #include "groupconfigdlg.h"
59 K_PLUGIN_FACTORY(ShareFactory, registerPlugin<KFileShareConfig>();)
60 K_EXPORT_PLUGIN(ShareFactory("kcmfileshare"))
63 #define FILESHARECONF "/etc/security/fileshare.conf"
64 #define FILESHARE_DEBUG 5009
66 KFileShareConfig::KFileShareConfig(QWidget *parent, const QVariantList &):
67 KCModule(ShareFactory::componentData(), parent/*, name*/)
69 KGlobal::locale()->insertCatalog("kfileshare");
71 QBoxLayout* layout = new QVBoxLayout(this,0,
72 KDialog::spacingHint());
75 QVButtonGroup *box = new QVButtonGroup( i18n("File Sharing"), this );
76 box->layout()->setSpacing( KDialog::spacingHint() );
77 layout->addWidget(box);
78 noSharing=new QRadioButton( i18n("Do &not allow users to share files"), box );
79 sharing=new QRadioButton( i18n("&Allow users to share files from their HOME folder"), box);
81 m_ccgui = new ControlCenterGUI(this);
82 connect( m_ccgui, SIGNAL( changed()), this, SLOT(configChanged()));
83 connect( m_ccgui->allowedUsersBtn, SIGNAL( clicked()),
84 this, SLOT(allowedUsersBtnClicked()));
86 QString path = QString::fromLocal8Bit( getenv( "PATH" ) );
87 path += QString::fromLatin1( ":/usr/sbin" );
88 QString sambaExec = KStandardDirs::findExe( QString::fromLatin1("smbd"), path );
89 QString nfsExec = KStandardDirs::findExe( QString::fromLatin1("rpc.nfsd"), path );
91 if ( nfsExec.isEmpty() && sambaExec.isEmpty())
93 m_ccgui->shareGrp->setDisabled(true);
94 m_ccgui->sharedFoldersGroupBox->setDisabled(true);
96 else
98 if (nfsExec.isEmpty()) {
99 m_ccgui->nfsChk->setDisabled(true);
100 m_ccgui->nfsChk->setChecked(false);
101 m_ccgui->nfsChk->setToolTip(i18n("No NFS server installed on this system"));
104 if (sambaExec.isEmpty()) {
105 m_ccgui->sambaChk->setDisabled(true);
106 m_ccgui->sambaChk->setChecked(false);
107 m_ccgui->sambaChk->setToolTip(i18n("No Samba server installed on this system"));
110 m_ccgui->infoLbl->hide();
111 layout->addWidget(m_ccgui);
112 updateShareListView();
113 connect( KNFSShare::instance(), SIGNAL( changed()),
114 this, SLOT(updateShareListView()));
115 connect( KSambaShare::instance(), SIGNAL( changed()),
116 this, SLOT(updateShareListView()));
121 if((getuid() == 0) ||
122 ((KFileShare::shareMode() == KFileShare::Advanced) &&
123 (KFileShare::authorization() == KFileShare::Authorized)))
125 connect( m_ccgui->addShareBtn, SIGNAL(clicked()),
126 this, SLOT(addShareBtnClicked()));
127 connect( m_ccgui->changeShareBtn, SIGNAL(clicked()),
128 this, SLOT(changeShareBtnClicked()));
129 connect( m_ccgui->removeShareBtn, SIGNAL(clicked()),
130 this, SLOT(removeShareBtnClicked()));
131 m_ccgui->listView->setSelectionMode(Q3ListView::Extended);
132 m_ccgui->shareBtnPnl->setEnabled(true);
136 if (getuid()==0) {
137 setButtons(Help|Apply);
138 } else {
139 setButtons(Help);
140 m_ccgui->shareGrp->setDisabled( true );
143 load();
146 void KFileShareConfig::updateShareListView()
148 m_ccgui->listView->clear();
149 KNFSShare* nfs = KNFSShare::instance();
150 KSambaShare* samba = KSambaShare::instance();
152 QStringList dirs = nfs->sharedDirectories();
153 QStringList sambaDirs = samba->sharedDirectories();
155 for ( QStringList::ConstIterator it = sambaDirs.begin(); it != sambaDirs.end(); ++it ) {
156 // Do not insert duplicates
157 if (nfs->isDirectoryShared(*it))
158 continue;
160 dirs += *it;
163 QPixmap folderPix = SmallIcon("folder", 0, KIconLoader::DefaultState, QStringList());
164 QPixmap okPix = SmallIcon("dialog-ok");
165 QPixmap cancelPix = SmallIcon("dialog-cancel");
167 for ( QStringList::Iterator it = dirs.begin(); it != dirs.end(); ++it ) {
168 K3ListViewItem* item = new K3ListViewItem(m_ccgui->listView);
169 item->setText(0,*it);
170 item->setPixmap(0, folderPix);
172 if (samba->isDirectoryShared(*it))
173 item->setPixmap(1,okPix);
174 else
175 item->setPixmap(1,cancelPix);
177 if (nfs->isDirectoryShared(*it))
178 item->setPixmap(2,okPix);
179 else
180 item->setPixmap(2,cancelPix);
186 void KFileShareConfig::allowedUsersBtnClicked() {
187 GroupConfigDlg dlg(this,m_fileShareGroup,m_restricted,m_rootPassNeeded,
188 m_ccgui->simpleRadio->isChecked());
189 if (dlg.exec() == QDialog::Accepted) {
190 m_fileShareGroup = dlg.fileShareGroup().name();
191 m_restricted = dlg.restricted();
192 m_rootPassNeeded = dlg.rootPassNeeded();
193 configChanged();
199 void KFileShareConfig::load()
201 KConfig config(QString::fromLatin1(FILESHARECONF), KConfig::SimpleConfig);
203 m_ccgui->shareGrp->setChecked( config.group("").readEntry("FILESHARING", "yes") == "yes" );
205 m_restricted = config.group("").readEntry("RESTRICT", "yes") == "yes";
207 if (config.group("").readEntry("SHARINGMODE", "simple") == "simple")
208 m_ccgui->simpleRadio->setChecked(true);
209 else
210 m_ccgui->advancedRadio->setChecked(true);
212 m_fileShareGroup = config.group("").readEntry("FILESHAREGROUP", "fileshare");
214 m_ccgui->sambaChk->setChecked(
215 config.group("").readEntry("SAMBA", "yes") == "yes");
217 m_ccgui->nfsChk->setChecked(
218 config.group("").readEntry("NFS", "yes") == "yes");
220 m_rootPassNeeded = config.group("").readEntry("ROOTPASSNEEDED", "yes") == "yes";
222 m_smbConf = KSambaShare::instance()->smbConfPath();
225 bool KFileShareConfig::addGroupAccessesToFile(const QString & file) {
226 KProcess chgrp;
227 chgrp << "chgrp" << m_fileShareGroup << file;
228 KProcess chmod;
229 chmod << "chmod" << "g=rw" << file;
231 if (chgrp.execute()) {
232 kDebug(FILESHARE_DEBUG) << "KFileShareConfig::addGroupAccessesToFile: chgrp failed";
233 return false;
237 if(chmod.execute()) {
238 kDebug(FILESHARE_DEBUG) << "KFileShareConfig::addGroupAccessesToFile: chmod failed";
239 return false;
242 return true;
246 bool KFileShareConfig::removeGroupAccessesFromFile(const QString & file) {
247 KProcess chgrp;
248 chgrp << "chgrp" << "root" << file;
249 KProcess chmod;
250 chmod << "chmod" << "g=r" << file;
252 if (chgrp.execute()) {
253 kDebug(FILESHARE_DEBUG) << "KFileShareConfig::removeGroupAccessesFromFile: chgrp failed";
254 return false;
258 if(chmod.execute()) {
259 kDebug(FILESHARE_DEBUG) << "KFileShareConfig::removeGroupAccessesFromFile: chmod failed";
260 return false;
263 return true;
267 bool KFileShareConfig::setGroupAccesses() {
268 if (m_rootPassNeeded || ! m_ccgui->sambaChk->isChecked()) {
269 if (!removeGroupAccessesFromFile(KSambaShare::instance()->smbConfPath()))
270 return false;
273 if (m_rootPassNeeded || ! m_ccgui->nfsChk->isChecked()) {
274 if (!removeGroupAccessesFromFile(KNFSShare::instance()->exportsPath()))
275 return false;
278 if (! m_rootPassNeeded && m_ccgui->sambaChk->isChecked()) {
279 if (!addGroupAccessesToFile(KSambaShare::instance()->smbConfPath()))
280 return false;
283 if (! m_rootPassNeeded && m_ccgui->nfsChk->isChecked()) {
284 if (!addGroupAccessesToFile(KNFSShare::instance()->exportsPath()))
285 return false;
289 return true;
292 void KFileShareConfig::save()
294 setGroupAccesses();
296 QDir dir("/etc/security");
297 if ( !dir.exists())
298 dir.mkdir("/etc/security");
300 QFile file(FILESHARECONF);
301 if ( ! file.open(QIODevice::WriteOnly)) {
302 KMessageBox::detailedError(this,
303 i18n("Could not save settings."),
304 i18n("Could not open file '%1' for writing: %2", QString(FILESHARECONF),
305 file.errorString() ),
306 i18n("Saving Failed"));
307 return;
311 QTextStream stream(&file);
313 stream << "FILESHARING=";
314 stream << (m_ccgui->shareGrp->isChecked() ? "yes" : "no");
316 stream << "\nRESTRICT=";
317 stream << (m_restricted ? "yes" : "no");
319 stream << "\nSHARINGMODE=";
320 stream << (m_ccgui->simpleRadio->isChecked() ? "simple" : "advanced");
322 stream << "\nFILESHAREGROUP=";
323 stream << m_fileShareGroup;
325 stream << "\nSAMBA=";
326 stream << (m_ccgui->sambaChk->isChecked() ? "yes" : "no");
328 stream << "\nNFS=";
329 stream << (m_ccgui->nfsChk->isChecked() ? "yes" : "no");
331 stream << "\nROOTPASSNEEDED=";
332 stream << (m_rootPassNeeded ? "yes" : "no");
334 stream << "\nSMBCONF=";
335 stream << m_smbConf;
337 file.close();
340 void KFileShareConfig::defaults()
342 m_ccgui->shareGrp->setChecked( false );
345 QString KFileShareConfig::quickHelp() const
347 return i18n("<h1>File Sharing</h1><p>This module can be used "
348 "to enable file sharing over the network using "
349 "the \"Network File System\" (NFS) or SMB in Konqueror. "
350 "The latter enables you to share your files with Windows(R) "
351 "computers on your network.</p>");
354 void KFileShareConfig::addShareBtnClicked() {
355 showShareDialog(KFileItemList());
359 PropertiesPageDlg::PropertiesPageDlg(QWidget*parent, KFileItemList files)
360 : KDialog(parent)
362 setObjectName("sharedlg");
363 setModal(true);
364 setButtons(Ok|Cancel);
365 setDefaultButton(Ok);
366 setCaption(i18n("Share Folder"));
367 showButtonSeparator(true);
368 KVBox* vbox = new KVBox(this);
369 setMainWidget(vbox);
371 m_page = new PropertiesPage(vbox,files,true);
372 connect(this,SIGNAL(okClicked()),this,SLOT(slotOk()));
375 bool PropertiesPageDlg::hasChanged() {
376 return m_page->hasChanged();
379 void PropertiesPageDlg::slotOk() {
380 if (hasChanged()) {
381 if (!m_page->save())
382 return;
385 KDialog::accept();
390 void KFileShareConfig::showShareDialog(const KFileItemList & files) {
391 PropertiesPageDlg* dlg = new PropertiesPageDlg(this,files);
392 if (dlg->exec() == QDialog::Accepted) {
393 if ( dlg->hasChanged() ) {
394 updateShareListView();
397 delete dlg;
400 void KFileShareConfig::changeShareBtnClicked() {
401 KFileItemList files;
402 QList<Q3ListViewItem *> items = m_ccgui->listView->selectedItems();
404 foreach ( Q3ListViewItem* item, items ) {
405 files.append(KFileItem(KUrl(item->text(0)),"",0));
408 showShareDialog(files);
411 void KFileShareConfig::removeShareBtnClicked() {
413 QList<Q3ListViewItem*> items = m_ccgui->listView->selectedItems();
415 bool nfs = false;
416 bool samba = false;
418 foreach ( Q3ListViewItem*item, items ) {
420 if (KNFSShare::instance()->isDirectoryShared(item->text(0)))
421 nfs = true;
423 if (KSambaShare::instance()->isDirectoryShared(item->text(0)))
424 samba = true;
427 NFSFile nfsFile(KNFSShare::instance()->exportsPath());
428 if (nfs) {
429 kDebug(FILESHARE_DEBUG) << "KFileShareConfig::removeShareBtnClicked: nfs = true";
430 nfsFile.load();
431 foreach ( Q3ListViewItem*item, items ) {
432 nfsFile.removeEntryByPath(item->text(0));
436 SambaFile smbFile(KSambaShare::instance()->smbConfPath(),false);
437 if (samba) {
438 kDebug(FILESHARE_DEBUG) << "KFileShareConfig::removeShareBtnClicked: samba = true";
439 smbFile.load();
440 foreach ( Q3ListViewItem*item, items ) {
441 smbFile.removeShareByPath(item->text(0));
445 PropertiesPage::save(&nfsFile, &smbFile, nfs,samba);
447 updateShareListView();
450 #include "fileshare.moc"