1 /*
2     SPDX-FileCopyrightText: 2010-2021 Laurent Montel <montel@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6 
7 #include "ldap.h"
8 #include "restoreldapsettingsjob.h"
9 #include <KLDAP/AddHostDialog>
10 #include <KLDAP/LdapClientSearchConfig>
11 #include <KLDAP/LdapClientSearchConfigReadConfigJob>
12 #include <KLDAP/LdapClientSearchConfigWriteConfigJob>
13 
14 #include <KConfig>
15 #include <KConfigGroup>
16 #include <KLocalizedString>
17 
Ldap(QObject * parent)18 Ldap::Ldap(QObject *parent)
19     : SetupObject(parent)
20     , m_clientSearchConfig(new KLDAP::LdapClientSearchConfig)
21 {
22 }
23 
~Ldap()24 Ldap::~Ldap()
25 {
26     delete m_clientSearchConfig;
27 }
28 
config() const29 KConfig *Ldap::config() const
30 {
31     return m_clientSearchConfig->config();
32 }
33 
create()34 void Ldap::create()
35 {
36     // TODO: use ldapclientsearchconfig to write config
37     Q_EMIT info(i18n("Setting up LDAP server..."));
38 
39     if (m_server.isEmpty()) {
40         Q_EMIT error(i18n("Needed parameters are missing for LDAP config: server '%1'", m_server));
41         if (m_editMode) {
42             edit();
43         }
44         return;
45     }
46 
47     QString host = m_server;
48 
49     // Figure out the basedn
50     QString basedn = m_baseDn.isEmpty() ? host : m_baseDn;
51     if (m_baseDn.isEmpty() && !m_user.isEmpty()) {
52         // If the user gave a full email address, the domain name
53         // of that overrides the server name for the ldap dn
54         const QString user = m_user;
55         int pos = user.indexOf(QLatin1Char('@'));
56         if (pos > 0) {
57             const QString h = user.mid(pos + 1);
58             if (!h.isEmpty()) {
59                 // The user did type in a domain on the email address. Use that
60                 basedn = h;
61                 host = h;
62             }
63         }
64     }
65 
66     basedn.replace(QLatin1Char('.'), QStringLiteral(",dc="));
67 
68     if (!basedn.startsWith(QLatin1String("dc="))) {
69         basedn.prepend(QLatin1String("dc="));
70     }
71 
72     // Set the changes
73     KConfig *c = config();
74     KConfigGroup group = c->group(QStringLiteral("LDAP"));
75     bool hasMyServer = false;
76     const int selHosts = group.readEntry("NumSelectedHosts", 0);
77     for (int i = 0; i < selHosts && !hasMyServer; ++i) {
78         if (group.readEntry(QStringLiteral("SelectedHost%1").arg(i), QString()) == host) {
79             hasMyServer = true;
80             m_entry = i;
81         }
82     }
83 
84     if (!hasMyServer) {
85         m_entry = selHosts;
86         group.writeEntry(QStringLiteral("NumSelectedHosts"), selHosts + 1);
87         group.writeEntry(QStringLiteral("SelectedHost%1").arg(selHosts), host);
88         group.writeEntry(QStringLiteral("SelectedBase%1").arg(selHosts), basedn);
89         group.writeEntry(QStringLiteral("SelectedPort%1").arg(selHosts), m_port);
90         group.writeEntry(QStringLiteral("SelectedVersion%1").arg(selHosts), m_version);
91         group.writeEntry(QStringLiteral("SelectedSecurity%1").arg(selHosts), securityString());
92 
93         if (m_pageSize > 0) {
94             group.writeEntry(QStringLiteral("SelectedPageSize%1").arg(selHosts), m_pageSize);
95         }
96 
97         if (m_timeLimit > 0) {
98             group.writeEntry(QStringLiteral("SelectedTimeLimit%1").arg(selHosts), m_timeLimit);
99         }
100 
101         if (m_sizeLimit > 0) {
102             group.writeEntry(QStringLiteral("SelectedSizeLimit%1").arg(selHosts), m_sizeLimit);
103         }
104 
105         if (!m_authMethod.isEmpty()) {
106             group.writeEntry(QStringLiteral("SelectedAuth%1").arg(selHosts), m_authMethod);
107             group.writeEntry(QStringLiteral("SelectedBind%1").arg(selHosts), m_bindDn);
108             group.writeEntry(QStringLiteral("SelectedPwdBind%1").arg(selHosts), m_password);
109             group.writeEntry(QStringLiteral("SelectedRealm%1").arg(selHosts), m_realm);
110             group.writeEntry(QStringLiteral("SelectedUser%1").arg(selHosts), m_user);
111             group.writeEntry(QStringLiteral("SelectedMech%1").arg(selHosts), m_mech);
112         }
113         c->sync();
114     }
115     if (m_editMode) {
116         edit();
117     }
118     Q_EMIT finished(i18n("LDAP set up."));
119 }
120 
securityString()121 QString Ldap::securityString()
122 {
123     switch (m_security) {
124     case KLDAP::LdapServer::None:
125         return QStringLiteral("None");
126     case KLDAP::LdapServer::SSL:
127         return QStringLiteral("SSL");
128     case KLDAP::LdapServer::TLS:
129         return QStringLiteral("TLS");
130     }
131     return {};
132 }
133 
destroy()134 void Ldap::destroy()
135 {
136     Q_EMIT info(i18n("LDAP not configuring."));
137     if (m_entry >= 0) {
138         KConfig *c = config();
139         auto job = new RestoreLdapSettingsJob(this);
140         job->setEntry(m_entry);
141         job->setConfig(c);
142         connect(job, &RestoreLdapSettingsJob::restoreDone, this, &Ldap::slotRestoreDone);
143         job->start();
144     }
145 }
146 
slotRestoreDone()147 void Ldap::slotRestoreDone()
148 {
149     Q_EMIT info(i18n("Removed LDAP entry."));
150 }
151 
edit()152 void Ldap::edit()
153 {
154     if (m_entry < 0) {
155         Q_EMIT error(i18n("No config found to edit"));
156         return;
157     }
158 
159     KLDAP::LdapServer server;
160     KLDAP::LdapClientSearchConfig clientSearchConfig;
161     KConfigGroup group = clientSearchConfig.config()->group(QStringLiteral("LDAP"));
162 
163     auto *job = new KLDAP::LdapClientSearchConfigReadConfigJob(this);
164     connect(job, &KLDAP::LdapClientSearchConfigReadConfigJob::configLoaded, this, [this, group](KLDAP::LdapServer server) {
165         KLDAP::AddHostDialog dlg(&server, nullptr);
166 
167         if (dlg.exec() && !server.host().isEmpty()) { // krazy:exclude=crashy
168             auto job = new KLDAP::LdapClientSearchConfigWriteConfigJob;
169             job->setActive(true);
170             job->setConfig(group);
171             job->setServer(server);
172             job->setServerIndex(m_entry);
173             job->start();
174         }
175     });
176     job->setActive(true);
177     job->setConfig(group);
178     job->setServerIndex(m_entry);
179     job->start();
180 }
181 
setUser(const QString & user)182 void Ldap::setUser(const QString &user)
183 {
184     m_user = user;
185 }
186 
setServer(const QString & server)187 void Ldap::setServer(const QString &server)
188 {
189     m_server = server;
190 }
191 
setBaseDn(const QString & baseDn)192 void Ldap::setBaseDn(const QString &baseDn)
193 {
194     m_baseDn = baseDn;
195 }
196 
setAuthenticationMethod(const QString & meth)197 void Ldap::setAuthenticationMethod(const QString &meth)
198 {
199     m_authMethod = meth;
200 }
201 
setBindDn(const QString & bindDn)202 void Ldap::setBindDn(const QString &bindDn)
203 {
204     m_bindDn = bindDn;
205 }
206 
setPassword(const QString & password)207 void Ldap::setPassword(const QString &password)
208 {
209     m_password = password;
210 }
211 
setPageSize(const int pageSize)212 void Ldap::setPageSize(const int pageSize)
213 {
214     m_pageSize = pageSize;
215 }
216 
setPort(const int port)217 void Ldap::setPort(const int port)
218 {
219     m_port = port;
220 }
221 
setRealm(const QString & realm)222 void Ldap::setRealm(const QString &realm)
223 {
224     m_realm = realm;
225 }
226 
setSaslMech(const QString & saslmech)227 void Ldap::setSaslMech(const QString &saslmech)
228 {
229     m_mech = saslmech;
230 }
231 
setSecurity(const KLDAP::LdapServer::Security security)232 void Ldap::setSecurity(const KLDAP::LdapServer::Security security)
233 {
234     m_security = security;
235 }
236 
setSizeLimit(const int sizeLimit)237 void Ldap::setSizeLimit(const int sizeLimit)
238 {
239     m_sizeLimit = sizeLimit;
240 }
241 
setTimeLimit(const int timeLimit)242 void Ldap::setTimeLimit(const int timeLimit)
243 {
244     m_timeLimit = timeLimit;
245 }
246 
setVersion(const int version)247 void Ldap::setVersion(const int version)
248 {
249     m_version = version;
250 }
251 
setEditMode(const bool editMode)252 void Ldap::setEditMode(const bool editMode)
253 {
254     m_editMode = editMode;
255 }
256