Skip to content

Commit df7c5a2

Browse files
calsys456zccrs
authored andcommitted
feat: Starting sessions other than treeland using ddm
This commit enables starting sessions other than treeland with ddm. It use treeland as greeter to handle user login. Once user logged in, it kills the wayland compositor and start the desired user session.
1 parent 4b07884 commit df7c5a2

File tree

9 files changed

+133
-21
lines changed

9 files changed

+133
-21
lines changed

data/scripts/Xsetup

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
11
#!/bin/sh
22
# Xsetup - run as root before the login dialog appears
33

4+
# Allow all client connect to the Xorg server. Since our X server is started as
5+
# root, but sessions are started as user.
6+
xhost +

src/auth/Auth.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,16 @@ namespace DDM {
6565
QLocalSocket *socket { nullptr };
6666
QString displayServerCmd;
6767
QString sessionPath { };
68+
Session::Type sessionType { Session::UnknownSession };
69+
QString sessionFileName { };
6870
QString user { };
6971
QString password { };
7072
QByteArray cookie { };
7173
bool autologin { false };
7274
bool greeter { false };
7375
bool singleMode { false };
7476
bool identifyOnly { false };
77+
bool skipAuth { false };
7578
QProcessEnvironment environment { };
7679
qint64 id { 0 };
7780
static qint64 lastId;
@@ -317,6 +320,18 @@ namespace DDM {
317320
return d->sessionId;
318321
}
319322

323+
Session::Type Auth::sessionType() const {
324+
return d->sessionType;
325+
}
326+
327+
QString Auth::sessionFileName() const {
328+
return d->sessionFileName;
329+
}
330+
331+
bool Auth::isSingleMode() const {
332+
return d->singleMode;
333+
}
334+
320335
bool Auth::isActive() const {
321336
return d->child->state() != QProcess::NotRunning;
322337
}
@@ -394,6 +409,14 @@ namespace DDM {
394409
}
395410
}
396411

412+
void Auth::setSessionType(const Session::Type type) {
413+
d->sessionType = type;
414+
}
415+
416+
void Auth::setSessionFileName(const QString &fileName) {
417+
d->sessionFileName = fileName;
418+
}
419+
397420
int Auth::tty() const {
398421
return d->tty;
399422
}
@@ -424,6 +447,12 @@ namespace DDM {
424447
}
425448
}
426449

450+
void Auth::setSkipAuth(bool on) {
451+
if (on != d->skipAuth) {
452+
d->skipAuth = on;
453+
}
454+
}
455+
427456
void Auth::start() {
428457
QStringList args;
429458
args << QStringLiteral("--socket") << SocketServer::instance()->fullServerName();
@@ -442,6 +471,8 @@ namespace DDM {
442471
args << QStringLiteral("--single-mode");
443472
if (d->identifyOnly)
444473
args << QStringLiteral("--identify-only");
474+
if (d->skipAuth)
475+
args << QStringLiteral("--skip-auth");
445476
d->child->start(QStringLiteral("%1/ddm-helper").arg(QStringLiteral(LIBEXEC_INSTALL_DIR)), args);
446477
}
447478

@@ -453,7 +484,13 @@ namespace DDM {
453484
d->child->terminate();
454485

455486
// wait for finished
456-
if (!d->child->waitForFinished(5000))
487+
// TODO: Cut off the waiting.
488+
// The code will be executed when user trying to start sessions other
489+
// than treeland, which will stop the currentAuth and start a new one.
490+
// This process involves the removal of seatd client, which needs a
491+
// small amount of time to wait. Consider to make this process under
492+
// control.
493+
if (!d->child->waitForFinished(500))
457494
d->child->kill();
458495
}
459496
}

src/auth/Auth.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323

2424
#include "AuthRequest.h"
2525
#include "AuthPrompt.h"
26+
#include "Session.h"
2627

2728
#include <QtCore/QObject>
2829
#include <QtCore/QProcessEnvironment>
@@ -97,12 +98,15 @@ namespace DDM {
9798
bool isGreeter() const;
9899
bool verbose() const;
99100
bool identifyOnly() const;
101+
bool isSingleMode() const;
100102
const QByteArray &cookie() const;
101103
const QString &user() const;
102104
const QString &session() const;
103105
const QString &password() const;
104106
AuthRequest *request();
105107
QString sessionId() const;
108+
Session::Type sessionType() const;
109+
QString sessionFileName() const;
106110
int tty() const;
107111

108112
void setTTY(int tty);
@@ -146,6 +150,8 @@ namespace DDM {
146150
void setVerbose(bool on = true);
147151

148152
void setIdentifyOnly(bool on = false);
153+
154+
void setSkipAuth(bool on = true);
149155
/**
150156
* Sets the user which will then authenticate
151157
* @param user username
@@ -179,7 +185,11 @@ namespace DDM {
179185
*/
180186
void setSingleMode(bool on = true);
181187

182-
void setSessionId(const QString& sessionId);
188+
void setSessionId(const QString &sessionId);
189+
190+
void setSessionType(const Session::Type type);
191+
192+
void setSessionFileName(const QString &fileName);
183193

184194
public Q_SLOTS:
185195
/**

src/daemon/Display.cpp

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -590,11 +590,13 @@ namespace DDM {
590590
}
591591

592592
auth->setUser(user);
593+
auth->setSessionType(session.type());
594+
auth->setSessionFileName(session.fileName());
593595
if (m_reuseSessionId.isNull()) {
594596
auth->setSession(session.exec());
595597
}
596598
auth->insertEnvironment(env);
597-
auth->setSingleMode(m_displayServerType == DisplayServerType::SingleCompositerServerType);
599+
auth->setSingleMode(session.isSingleMode());
598600
auth->start();
599601
}
600602

@@ -634,22 +636,61 @@ namespace DDM {
634636
else
635637
stateConfig.Last.User.setDefault();
636638
if (mainConfig.Users.RememberLastSession.get())
637-
stateConfig.Last.Session.set(auth->session());
639+
stateConfig.Last.Session.set(auth->sessionFileName());
638640
else
639641
stateConfig.Last.Session.setDefault();
640642
stateConfig.save();
641643

642-
if (m_displayServerType == DisplayServerType::SingleCompositerServerType) {
644+
if (auth->isSingleMode()) {
643645
auto* server = reinterpret_cast<SingleWaylandDisplayServer*>(m_displayServer);
644646
server->onLoginSucceeded(user);
647+
switchToUser(auth->user());
645648
} else {
646649
if (m_socket) {
647650
emit loginSucceeded(m_socket, user);
648651
daemonApp->displayManager()->setLastSession(auth->sessionId());
649652
}
650-
}
653+
if (auth->identifyOnly())
654+
return;
651655

652-
switchToUser(auth->user());
656+
// Stop the original suit of displayServer since it has finished its job.
657+
disconnect(m_displayServer, &DisplayServer::stopped, this, &Display::stop);
658+
m_displayServer->stop();
659+
delete m_displayServer;
660+
m_greeter->stop();
661+
delete m_greeter;
662+
m_currentAuth->stop();
663+
m_socketServer->stop();
664+
delete m_socketServer;
665+
666+
// Start the target displayServer
667+
m_terminalId = m_sessionTerminalId = fetchAvailableVt();
668+
m_started = false;
669+
670+
if (auth->sessionType() == Session::X11Session) {
671+
m_displayServer = new XorgDisplayServer(this);
672+
m_displayServerType = X11DisplayServerType;
673+
} else {
674+
m_displayServer = new WaylandDisplayServer(this);
675+
m_displayServerType = WaylandDisplayServerType;
676+
}
677+
connect(m_displayServer, &DisplayServer::started, this, &Display::displayServerStarted);
678+
connect(m_displayServer, &DisplayServer::stopped, this, &Display::stop);
679+
680+
m_socketServer = new SocketServer(this);
681+
682+
// The greeter here is used to start user session.
683+
m_greeter = new Greeter(this);
684+
m_greeter->setDisplayServerCommand(auth->session());
685+
m_greeter->setUser(user);
686+
m_greeter->setSkipAuth();
687+
688+
connect(m_greeter, &Greeter::failed, this, &Display::stop);
689+
connect(m_greeter, &Greeter::displayServerFailed, this, &Display::displayServerFailed);
690+
connect(m_greeter, &Greeter::succeed, this, &Display::stop);
691+
692+
m_displayServer->start();
693+
}
653694
}
654695
m_socket = nullptr;
655696
}
@@ -711,7 +752,8 @@ namespace DDM {
711752
}
712753
}
713754

714-
if (status != Auth::HELPER_AUTH_ERROR && m_displayServerType != DisplayServerType::SingleCompositerServerType)
755+
// Don't restart display when ddm-helper crashed (exit code 9)
756+
if (status != Auth::HELPER_AUTH_ERROR && status != Auth::HelperExitStatus(9) && m_displayServerType != DisplayServerType::SingleCompositerServerType)
715757
stop();
716758
}
717759

@@ -730,7 +772,7 @@ namespace DDM {
730772
void Display::slotSessionStarted(bool success) {
731773
qDebug() << "Session started" << success;
732774
Auth* auth = qobject_cast<Auth*>(sender());
733-
if (m_displayServerType == SingleCompositerServerType) {
775+
if (auth->isSingleMode()) {
734776
switchToUser(auth->user());
735777
}
736778

src/daemon/Greeter.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,14 @@ namespace DDM {
8383
m_singleMode = on;
8484
}
8585

86+
void Greeter::setUser(const QString &user) {
87+
m_user = user;
88+
}
89+
90+
void Greeter::setSkipAuth(bool on) {
91+
m_skipAuth = on;
92+
}
93+
8694
void Greeter::setUserActivated(bool active) {
8795
m_userActivated = active;
8896
}
@@ -226,7 +234,8 @@ namespace DDM {
226234
if (m_display->displayServerType() == Display::X11DisplayServerType) {
227235
env.insert(QStringLiteral("DISPLAY"), m_display->name());
228236
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("xcb"));
229-
m_auth->setCookie(qobject_cast<XorgDisplayServer*>(displayServer)->cookie());
237+
if (m_display->sessionType() == "x11")
238+
m_auth->setCookie(qobject_cast<XorgDisplayServer*>(displayServer)->cookie());
230239
} else if (m_display->displayServerType() == Display::WaylandDisplayServerType) {
231240
env.insert(QStringLiteral("QT_QPA_PLATFORM"), QStringLiteral("wayland"));
232241
env.insert(QStringLiteral("QT_WAYLAND_SHELL_INTEGRATION"), QStringLiteral("fullscreen-shell-v1"));
@@ -240,7 +249,7 @@ namespace DDM {
240249
qDebug() << "Greeter starting...";
241250

242251
// start greeter
243-
m_auth->setUser(QStringLiteral("dde"));
252+
m_auth->setUser(m_user);
244253
QString displayServerCmd = m_displayServerCmd;
245254
if (m_singleMode) {
246255
displayServerCmd += " --lockscreen";
@@ -255,6 +264,10 @@ namespace DDM {
255264
return true;
256265
}
257266

267+
if (m_skipAuth) {
268+
m_auth->setSkipAuth();
269+
}
270+
258271
m_auth->start();
259272

260273
m_tryTimer->start();
@@ -371,6 +384,8 @@ namespace DDM {
371384
Q_EMIT ttyFailed();
372385
} else if (status == Auth::HELPER_SESSION_ERROR) {
373386
Q_EMIT failed();
387+
} else if (status == Auth::HELPER_SUCCESS) {
388+
Q_EMIT succeed();
374389
}
375390
}
376391

src/daemon/Greeter.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ namespace DDM {
4242
void setSocket(const QString &socket);
4343
void setTheme(const QString &theme);
4444
void setSingleMode(bool on = true);
45+
void setUser(const QString &user);
46+
void setSkipAuth(bool on = true);
4547
void setUserActivated(bool active);
4648

4749
QString displayServerCommand() const;
@@ -67,6 +69,7 @@ namespace DDM {
6769
void ttyFailed();
6870
void failed();
6971
void displayServerFailed();
72+
void succeed();
7073
void greeterStarted();
7174

7275
private:
@@ -75,6 +78,8 @@ namespace DDM {
7578
bool m_userActivated { false };
7679
int m_currentRetry { 0 };
7780
int m_maxRetry{ 3 };
81+
QString m_user = QStringLiteral("dde");
82+
bool m_skipAuth { false };
7883

7984
Display * const m_display { nullptr };
8085
QString m_socket;

src/helper/HelperApp.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ namespace DDM {
123123
m_backend->setIdentifyOnly(true);
124124
}
125125

126+
if ((pos = args.indexOf(QStringLiteral("--skip-auth"))) >= 0) {
127+
m_skipAuth = true;
128+
}
129+
126130
if (server.isEmpty() || m_id <= 0) {
127131
qCritical() << "This application is not supposed to be executed manually";
128132
exit(Auth::HELPER_OTHER_ERROR);
@@ -163,7 +167,7 @@ namespace DDM {
163167
}
164168

165169
Q_ASSERT(getuid() == 0);
166-
if (!m_backend->authenticate()) {
170+
if (!m_skipAuth && !m_backend->authenticate()) {
167171
authenticated(QString());
168172

169173
// write failed login to btmp

src/helper/HelperApp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ namespace DDM {
6767
QString m_user { };
6868
// TODO: get rid of this in a nice clean way along the way with moving to user session X server
6969
QByteArray m_cookie { };
70+
bool m_skipAuth = false;
7071

7172
/*!
7273
\brief Write utmp/wtmp/btmp records when a user logs in

src/helper/UserSession.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,14 +122,9 @@ namespace DDM {
122122
}
123123

124124
qInfo() << "Starting X11 session:" << m_displayServerCmd << command;
125-
if (m_displayServerCmd.isEmpty()) {
126-
auto args = QProcess::splitCommand(command);
127-
setProgram(args.takeFirst());
128-
setArguments(args);
129-
} else {
130-
setProgram(QStringLiteral(LIBEXEC_INSTALL_DIR "/ddm-helper-start-x11user"));
131-
setArguments({m_displayServerCmd, command});
132-
}
125+
auto args = QProcess::splitCommand(m_displayServerCmd);
126+
setProgram(args.takeFirst());
127+
setArguments(args);
133128
QProcess::start();
134129

135130
} else if (env.value(QStringLiteral("XDG_SESSION_TYPE")) == QLatin1String("wayland")) {
@@ -238,7 +233,7 @@ namespace DDM {
238233

239234
// take control of the tty
240235
if (takeControl) {
241-
if (ioctl(STDIN_FILENO, TIOCSCTTY, 0) < 0) {
236+
if (ioctl(STDIN_FILENO, TIOCSCTTY, 1) < 0) {
242237
const auto error = strerror(errno);
243238
qCritical().nospace() << "Failed to take control of " << ttyString << " (" << QFileInfo(ttyString).owner() << "): " << error;
244239
_exit(Auth::HELPER_TTY_ERROR);

0 commit comments

Comments
 (0)