2 * KFontInst - KDE Font Installer
4 * Copyright 2003-2008 Craig Drummond <craig@kde.org>
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; see the file COPYING. If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
24 #include "PolicyKitMechanism.h"
25 #include <QtCore/QDebug>
26 #include <QtCore/QHash>
27 #include <QtCore/QSocketNotifier>
28 #include <QtCore/QCoreApplication>
29 #include <KDE/KGlobal>
30 #include <polkit-dbus/polkit-dbus.h>
32 K_GLOBAL_STATIC(PolicyKitMechanism
, instancePtr
)
34 // We have another 'theInstance' pointer, because during the
35 // init() of PolicyKitMechanismPrivate, the polkitContextAddWatch
36 // callback is triggered. This function cant use
37 // PolicyKitMechanism::instance() - as this would cause another instance
38 // to be created, causing a recursion...
39 static PolicyKitMechanism
*theInstance
=0L;
41 static int polkitContextAddWatch(PolKitContext
*, int fd
)
43 qDebug() << "PolicyKitMechanism - Adding watch " << fd
;
45 theInstance
->addWatch(fd
);
49 static void polkitContextRemoveWatch(PolKitContext
*, int fd
)
51 qDebug() << "PolicyKitMechanism - Removing watch " << fd
;
53 theInstance
->removeWatch(fd
);
56 class PolicyKitMechanismPrivate
60 PolicyKitMechanismPrivate()
66 pkContext
= polkit_context_new();
70 qDebug() << "PolicyKitMechanism - Could not get a new PolKitContext.";
71 QCoreApplication::quit();
74 //TODO: handle name owner changed signal
76 polkit_context_set_load_descriptions(pkContext
);
78 //TODO: polkit_context_set_config_changed
80 polkit_context_set_io_watch_functions(pkContext
, polkitContextAddWatch
, polkitContextRemoveWatch
);
82 PolKitError
* pkError
;
84 if (!polkit_context_init(pkContext
, &pkError
))
86 QString
msg("PolicyKitMechanism - Could not initialize PolKitContext");
87 if (polkit_error_is_set(pkError
))
88 qDebug() << msg
<< ": " << polkit_error_get_error_message(pkError
);
91 QCoreApplication::quit();
94 polkit_context_ref(pkContext
);
97 DBusConnection
*dbusCon
;
99 dbus_error_init(&dbusError
);
100 dbusCon
= dbus_bus_get(DBUS_BUS_SYSTEM
, &dbusError
);
102 pkTracker
= polkit_tracker_new();
103 polkit_tracker_set_system_bus_connection(pkTracker
, dbusCon
);
104 polkit_tracker_init(pkTracker
);
105 polkit_tracker_ref(pkTracker
);
108 virtual ~PolicyKitMechanismPrivate()
110 QHash
<QString
, PolKitAction
*>::iterator
it(pkActions
.begin()),
111 end(pkActions
.end());
114 polkit_action_unref(it
.value());
116 QHash
<int, QSocketNotifier
*>::iterator
wit(contextWatches
.begin()),
117 wend(contextWatches
.end());
119 for(; wit
!=wend
; ++wit
)
122 polkit_context_unref(pkContext
);
123 polkit_tracker_unref(pkTracker
);
126 PolKitContext
*pkContext
;
127 PolKitTracker
*pkTracker
;
128 QHash
<QString
, PolKitAction
*> pkActions
;
129 QHash
<int, QSocketNotifier
*> contextWatches
;
132 PolicyKitMechanism
* PolicyKitMechanism::instance()
137 PolicyKitMechanism::PolicyKitMechanism()
138 : d_ptr(new PolicyKitMechanismPrivate())
144 PolicyKitMechanism::~PolicyKitMechanism()
150 PolKitResult
PolicyKitMechanism::canDoAction(const QString
&action
, unsigned int pid
)
152 Q_D(PolicyKitMechanism
);
154 qDebug() << "PolicyKitMechanism - canDoAction " << action
<< ' ' << pid
;
156 PolKitAction
*pkAction
=getAction(action
);
160 qWarning() << "PolicyKitMechanism - Could not create action.";
161 return POLKIT_RESULT_NO
;
165 dbus_error_init(&dbusError
);
166 PolKitCaller
*pkCaller
=polkit_tracker_get_caller_from_pid(d
->pkTracker
, pid
, &dbusError
);
169 qWarning() << "PolicyKitMechanism - Could not define caller from pid";
170 return POLKIT_RESULT_NO
;
172 PolKitResult pkResult
;
173 PolKitError
*pkError
= NULL
;
175 pkResult
= polkit_context_is_caller_authorized(d
->pkContext
, pkAction
, pkCaller
, true, &pkError
);
176 polkit_caller_unref(pkCaller
);
178 if (polkit_error_is_set(pkError
))
180 qWarning() << "PolicyKitMechanism - Could not determine if caller is authorized for this action.";
181 return POLKIT_RESULT_NO
;
187 PolKitResult
PolicyKitMechanism::canDoAction(const QString
&action
, const QString
&dbusName
)
189 Q_D(PolicyKitMechanism
);
191 qDebug() << "PolicyKitMechanism - canDoAction " << action
<< ' ' << dbusName
;
193 PolKitAction
*pkAction
=getAction(action
);
197 qWarning() << "PolicyKitMechanism - Could not create action.";
198 return POLKIT_RESULT_NO
;
202 dbus_error_init(&dbusError
);
203 PolKitCaller
*pkCaller
=polkit_tracker_get_caller_from_dbus_name(d
->pkTracker
, dbusName
.toLatin1().constData(), &dbusError
);
206 qWarning() << "PolicyKitMechanism - Could not define caller from pid";
207 return POLKIT_RESULT_NO
;
209 PolKitResult pkResult
;
210 PolKitError
*pkError
= NULL
;
212 pkResult
= polkit_context_is_caller_authorized(d
->pkContext
, pkAction
, pkCaller
, true, &pkError
);
213 polkit_caller_unref(pkCaller
);
215 if (polkit_error_is_set(pkError
))
217 qWarning() << "PolicyKitMechanism - Could not determine if caller is authorized for this action.";
218 return POLKIT_RESULT_NO
;
224 void PolicyKitMechanism::removeAction(const QString
&action
)
226 Q_D(PolicyKitMechanism
);
228 QHash
<QString
, PolKitAction
*>::iterator
it(d
->pkActions
.find(action
));
230 if(d
->pkActions
.end()!=it
)
232 polkit_action_unref(it
.value());
233 d
->pkActions
.erase(it
);
237 PolKitAction
* PolicyKitMechanism::getAction(const QString
&action
)
239 Q_D(PolicyKitMechanism
);
241 QHash
<QString
, PolKitAction
*>::iterator
it(d
->pkActions
.find(action
));
242 PolKitAction
*pkAction
=0L;
244 if(d
->pkActions
.end()==it
)
246 pkAction
=polkit_action_new();
247 if(!pkAction
|| !polkit_action_set_action_id(pkAction
, action
.toLatin1().constData()))
250 d
->pkActions
[action
]=pkAction
;
258 void PolicyKitMechanism::contextWatchActivated(int fd
)
260 Q_D(PolicyKitMechanism
);
261 Q_ASSERT(d
->contextWatches
.contains(fd
));
262 qDebug() << "PolicyKitMechanism - Context watch activated";
263 polkit_context_io_func(d
->pkContext
, fd
);
266 void PolicyKitMechanism::addWatch(int fd
)
268 Q_D(PolicyKitMechanism
);
270 QSocketNotifier
*notify
= new QSocketNotifier(fd
, QSocketNotifier::Read
);
271 d
->contextWatches
[fd
] = notify
;
273 notify
->connect(notify
, SIGNAL(activated(int)), theInstance
, SLOT(contextWatchActivated(int)));
276 void PolicyKitMechanism::removeWatch(int fd
)
278 Q_D(PolicyKitMechanism
);
280 Q_ASSERT(d
->contextWatches
.contains(fd
));
281 delete d
->contextWatches
[fd
];
282 d
->contextWatches
.remove(fd
);
285 #include "PolicyKitMechanism.moc"