#include "namereplace.h" #include #include #include #include #include #include #define SOURCE_FILE "/opt/openslx/lightdm/login-regexp" #define LOOKUP_PROCESS "/opt/openslx/pam/get_username" static QList< QPair< QRegularExpression, QString > > list; static inline int find(QChar c, int start, const QString& line) { do { int next = line.indexOf(c, start); if (next == -1) return -1; if (line.at(next - 1) != '\\') return next; start = next + 1; } while (true); } void NameReplace::loadSubs() { int idx = 0; QFile inputFile(SOURCE_FILE); if (!inputFile.open(QIODevice::ReadOnly)) return; QTextStream in(&inputFile); in.setCodec("UTF-8"); while (!in.atEnd()) { QString line = in.readLine(); idx++; if (line.isEmpty()) continue; QChar delim = line.at(0); int first = find(delim, 1, line); if (first == -1) continue; int second = find(delim, first + 1, line); if (second == -1) continue; QString regex = line.mid(1, first - 1).replace(QString("\\") + delim, QString(delim)); QString replace = line.mid(first + 1, second - first - 1).replace(QString("\\") + delim, QString(delim)); QString flags = line.mid(second + 1); // ... QRegularExpression::PatternOptions opts = QRegularExpression::NoPatternOption; if (flags.contains("i")) { opts |= QRegularExpression::CaseInsensitiveOption; } QRegularExpression re(regex, opts); if (!re.isValid()) { qWarning() << "Invalid regex:" << regex << "on line" << idx; continue; } list.append(QPair(re, replace)); } inputFile.close(); } void NameReplace::replace(QString& input) { if (!list.isEmpty()) { // First, apply user defined replacement for (auto &brumm : list) { input = input.replace(brumm.first, brumm.second); } } // Now, prefix names that start with a digit, since systemd/logind refuses // to work with those in more recent versions. It was never a good idea to // do this anyways, but now we don't have a choice, since sessions without // a proper systemd user instance will become more and more broken in the // future. if (*input.constData() >= '0' && *input.constData() <= '9') { input = QLatin1String("_x_") + input; } // Finally, look up the proper casing of the desired username, as some // servers (AD) are case insensitive, which can lead to problems if what the // user entered doesn't exactly match what it's actually spelled like // server-side. QProcess getCaps; getCaps.start(LOOKUP_PROCESS, QStringList(input)); getCaps.waitForFinished(8000); QString output = QString::fromLocal8Bit(getCaps.readAllStandardOutput()); int idx = output.indexOf('\n'); if (idx != -1) { output = output.left(idx); } if (output.length() == input.length()) { input = output; } else { qDebug() << "Not replacing" << input << "by" << output; } }