on xenial help sign in
Don't lock screen for guest or nopasswordlogin user
commitd3551524c2f66a02a66e694b097468b506c70a0c authorMichael Terry <mike@mterry.name> dateTue 14 Mar 2017, 14:51 (10 years ago) parent593d500
7 files changed+128−18
cmake/modules/QmlTest.cmake+1−1 plugins/Unity/Session/dbusunitysessionservice.cpp+29−3 qml/Components/Dialogs.qml+5−4 qml/Shell.qml+3−1 tests/plugins/Unity/Session/CMakeLists.txt+13−1 tests/plugins/Unity/Session/preload.c+42 tests/plugins/Unity/Session/sessionbackendtest.cpp+35−8
cmake/modules/QmlTest.cmake+1−1
@@ -201,7 +201,7 @@ function(add_executable_test COMPONENT_NAME TARGET)
201201 add_qmltest_target(xvfbtest${COMPONENT_NAME} ${TARGET}
202202 COMMAND $<TARGET_FILE:xvfb-run> --server-args "-screen 0 1024x768x24" --auto-servernum ${qmltest_command}
203203 ${depends}
204− ENVIRONMENT QML2_IMPORT_PATH=${imports} ${QMLTEST_ENVIRONMENT} LD_PRELOAD=/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/mesa/libGL.so.1
204+ ENVIRONMENT QML2_IMPORT_PATH=${imports} LD_PRELOAD=/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}/mesa/libGL.so.1 ${QMLTEST_ENVIRONMENT}
205205 TARGETS ${xvfb_targets}
206206 )
207207 endif()
plugins/Unity/Session/dbusunitysessionservice.cpp+29−3
@@ -18,6 +18,7 @@
1818#include "dbusunitysessionservice.h"
1919
2020// system
21+#include <grp.h>
2122#include <sys/types.h>
2223#include <unistd.h>
2324#include <pwd.h>
@@ -211,6 +212,23 @@ public:
211212 QDBusConnection::SM_BUSNAME().asyncCall(msg);
212213 }
213214
215+ bool isUserInGroup(const QString &user, const QString &groupName) const
216+ {
217+ auto group = getgrnam(groupName.toUtf8().data());
218+
219+ if (group && group->gr_mem)
220+ {
221+ for (int i = 0; group->gr_mem[i]; ++i)
222+ {
223+ if (g_strcmp0(group->gr_mem[i], user.toUtf8().data()) == 0) {
224+ return true;
225+ }
226+ }
227+ }
228+
229+ return false;
230+ }
231+
214232private Q_SLOTS:
215233 void onPropertiesChanged(const QString &iface, const QVariantMap &changedProps, const QStringList &invalidatedProps)
216234 {
@@ -297,7 +315,13 @@ bool DBusUnitySessionService::CanShutdown() const
297315
298316bool DBusUnitySessionService::CanLock() const
299317{
300− return true; // FIXME
318+ auto user = UserName();
319+ if (user.startsWith(QStringLiteral("guest-")) ||
320+ d->isUserInGroup(user, QStringLiteral("nopasswdlogin"))) {
321+ return false;
322+ } else {
323+ return true;
324+ }
301325}
302326
303327QString DBusUnitySessionService::UserName() const
@@ -335,8 +359,10 @@ void DBusUnitySessionService::PromptLock()
335359 // Prompt as in quick. No locking animation needed. Usually used by
336360 // indicator-session in combination with a switch to greeter or other
337361 // user session.
338− Q_EMIT LockRequested();
339− Q_EMIT lockRequested();
362+ if (CanLock()) {
363+ Q_EMIT LockRequested();
364+ Q_EMIT lockRequested();
365+ }
340366}
341367
342368void DBusUnitySessionService::Lock()
qml/Components/Dialogs.qml+5−4
@@ -116,17 +116,17 @@ MouseArea {
116116
117117 GlobalShortcut { // lock screen
118118 shortcut: Qt.Key_ScreenSaver
119− onTriggered: LightDMService.greeter.showGreeter()
119+ onTriggered: root.unitySessionService.PromptLock()
120120 }
121121
122122 GlobalShortcut { // lock screen
123123 shortcut: Qt.ControlModifier|Qt.AltModifier|Qt.Key_L
124− onTriggered: LightDMService.greeter.showGreeter()
124+ onTriggered: root.unitySessionService.PromptLock()
125125 }
126126
127127 GlobalShortcut { // lock screen
128128 shortcut: Qt.MetaModifier|Qt.Key_L
129− onTriggered: LightDMService.greeter.showGreeter()
129+ onTriggered: root.unitySessionService.PromptLock()
130130 }
131131
132132 QtObject {
@@ -179,8 +179,9 @@ MouseArea {
179179 Button {
180180 width: parent.width
181181 text: i18n.ctr("Button: Lock the system", "Lock")
182+ visible: root.unitySessionService.CanLock()
182183 onClicked: {
183− LightDMService.greeter.showGreeter()
184+ root.unitySessionService.PromptLock();
184185 logoutDialog.hide();
185186 }
186187 Component.onCompleted: if (root.hasKeyboard) forceActiveFocus(Qt.TabFocusReason)
qml/Shell.qml+3−1
@@ -426,7 +426,9 @@ StyledItem {
426426 id: showGreeterDelayed
427427 interval: 1
428428 onTriggered: {
429− greeter.forceShow();
429+ // Go through the dbus service, because it has checks for whether
430+ // we are even allowed to lock or not.
431+ DBusUnitySessionService.PromptLock();
430432 }
431433 }
432434
tests/plugins/Unity/Session/CMakeLists.txt+13−1
@@ -33,6 +33,17 @@ install(TARGETS LightDMServer
3333 DESTINATION "${SHELL_PRIVATE_LIBDIR}/tests/plugins/Unity/Session"
3434 )
3535
36+### Preload
37+add_library(SessionBackendTestPreload SHARED
38+ preload.c
39+)
40+target_link_libraries(SessionBackendTestPreload
41+ ${GLIB_LIBRARIES}
42+ )
43+install(TARGETS SessionBackendTestPreload
44+ DESTINATION "${SHELL_PRIVATE_LIBDIR}/tests/plugins/Unity/Session"
45+ )
46+
3647### SessionBackendTest
3748add_executable(sessionbackendtestExec
3849 sessionbackendtest.cpp
@@ -48,7 +59,8 @@ install(TARGETS sessionbackendtestExec
4859)
4960
5061add_unity8_unittest(SessionBackend dbus-test-runner
51− ENVIRONMENT XDG_SESSION_PATH=/session
62+ ENVIRONMENT LD_PRELOAD=$<TARGET_FILE:SessionBackendTestPreload>
63+ XDG_SESSION_PATH=/session
5264 ARG_PREFIX "--parameter"
5365 ARGS
5466 --task $<TARGET_FILE:LightDMServer>
tests/plugins/Unity/Session/preload.cnew file+42
@@ -0,0 +1,42 @@
1+/*
2+ * Copyright © 2017 Canonical Ltd.
3+ *
4+ * This program is free software: you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License version 3 as
6+ * published by the Free Software Foundation.
7+ *
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.
12+ *
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
15+ *
16+ */
17+
18+#include <glib.h>
19+#include <grp.h>
20+#include <stdlib.h>
21+
22+const gchar *g_get_user_name(void)
23+{
24+ // The normal glib version parses pwent entries
25+ return g_getenv("TEST_USER");
26+}
27+
28+struct group *getgrnam(const char *group_name)
29+{
30+ static struct group rv = {NULL, NULL, 0, NULL};
31+
32+ if (rv.gr_name) {
33+ g_free(rv.gr_name);
34+ g_strfreev(rv.gr_mem);
35+ }
36+
37+ rv.gr_name = g_strdup(group_name);
38+ rv.gr_passwd = NULL;
39+ rv.gr_gid = 9999;
40+ rv.gr_mem = g_strsplit(g_getenv("TEST_NOPASSWD_USERS"), ",", 0);
41+ return &rv;
42+}
tests/plugins/Unity/Session/sessionbackendtest.cpp+35−8
@@ -53,6 +53,11 @@ private Q_SLOTS:
5353 QDBusConnection::sessionBus());
5454 }
5555
56+ void init() {
57+ qputenv("TEST_USER", "testuser");
58+ qputenv("TEST_NOPASSWD_USERS", "");
59+ }
60+
5661 void testUnitySessionLogoutRequested_data() {
5762 QTest::addColumn<QString>("method");
5863 QTest::addColumn<QString>("signal");
@@ -138,14 +143,7 @@ private Q_SLOTS:
138143
139144 void testUserName() {
140145 DBusUnitySessionService dbusUnitySessionService;
141− QCoreApplication::processEvents(); // to let the service register on DBus
142−
143− QProcess * proc = new QProcess(this);
144− proc->start("id -un", QProcess::ReadOnly);
145− proc->waitForFinished();
146− const QByteArray out = proc->readAll().trimmed();
147−
148− QCOMPARE(dbusUnitySessionService.UserName(), QString::fromUtf8(out));
146+ QCOMPARE(dbusUnitySessionService.UserName(), QString("testuser"));
149147 }
150148
151149 void testRealName() {
@@ -162,6 +160,35 @@ private Q_SLOTS:
162160 }
163161 }
164162
163+ void testCanLock() {
164+ DBusUnitySessionService dbusUnitySessionService;
165+
166+ qputenv("TEST_USER", "testuser");
167+ QVERIFY(dbusUnitySessionService.CanLock());
168+
169+ qputenv("TEST_USER", "guest-abcdef"); // guest-* can't lock
170+ QVERIFY(!dbusUnitySessionService.CanLock());
171+
172+ qputenv("TEST_USER", "testuser");
173+ qputenv("TEST_NOPASSWD_USERS", "testuser"); // nopasswdlogin can't lock
174+ QVERIFY(!dbusUnitySessionService.CanLock());
175+ }
176+
177+ void testPromptLockRespectsCanLock() {
178+ DBusUnitySessionService dbusUnitySessionService;
179+
180+ QSignalSpy spy(&dbusUnitySessionService, SIGNAL(lockRequested()));
181+ QVERIFY(dbusUnitySessionService.CanLock());
182+ dbusUnitySessionService.PromptLock();
183+ QCOMPARE(spy.count(), 1);
184+
185+ spy.clear();
186+ qputenv("TEST_USER", "guest-abcdef");
187+ QVERIFY(!dbusUnitySessionService.CanLock());
188+ dbusUnitySessionService.PromptLock();
189+ QCOMPARE(spy.count(), 0);
190+ }
191+
165192private:
166193 QDBusInterface *dbusUnitySession;
167194};