1 /* 2 This file is part of libkldap. 3 SPDX-FileCopyrightText: 2004-2006 Szombathelyi György <gyurco@freemail.hu> 4 5 SPDX-License-Identifier: LGPL-2.0-or-later 6 */ 7 8 #pragma once 9 10 #include "kldap_export.h" 11 #include "ldapconnection.h" 12 #include "ldapcontrol.h" 13 #include "ldapdn.h" 14 #include "ldapobject.h" 15 #include "ldapserver.h" 16 #include "ldapurl.h" 17 18 #include <QByteArray> 19 #include <QList> 20 #include <QString> 21 22 #include <memory> 23 24 namespace KLDAP 25 { 26 /** 27 * @brief 28 * This class allows sending an ldap operation 29 * (search, rename, modify, delete, compare, exop) to an LDAP server. 30 */ 31 class KLDAP_EXPORT LdapOperation 32 { 33 public: 34 using ModType = enum { Mod_None, Mod_Add, Mod_Replace, Mod_Del }; 35 36 using ResultType = enum { 37 RES_BIND = 0x61, 38 RES_SEARCH_ENTRY = 0x64, 39 RES_SEARCH_REFERENCE = 0x73, 40 RES_SEARCH_RESULT = 0x65, 41 RES_MODIFY = 0x67, 42 RES_ADD = 0x69, 43 RES_DELETE = 0x69, 44 RES_MODDN = 0x6d, 45 RES_COMPARE = 0x6f, 46 RES_EXTENDED = 0x78, 47 RES_EXTENDED_PARTIAL = 0x79 48 }; 49 50 using ModOp = struct { 51 ModType type; 52 QString attr; 53 QList<QByteArray> values; 54 }; 55 56 using ModOps = QVector<ModOp>; 57 58 enum SASL_Fields { SASL_Authname = 0x1, SASL_Authzid = 0x2, SASL_Realm = 0x4, SASL_Password = 0x8 }; 59 60 struct SASL_Credentials { 61 int fields; 62 QString authname; 63 QString authzid; 64 QString realm; 65 QString password; 66 }; 67 68 using SASL_Callback_Proc = int(SASL_Credentials &, void *); 69 70 struct SASL_Data { 71 SASL_Callback_Proc *proc; 72 void *data; 73 SASL_Credentials creds; 74 }; 75 76 LdapOperation(); 77 LdapOperation(LdapConnection &conn); 78 ~LdapOperation(); 79 80 /** 81 * Sets the connection object. Without living connection object, 82 * LDAP operations are not possible. 83 * @param the connection object to set 84 */ 85 void setConnection(LdapConnection &conn); 86 /** 87 * Returns the connection object. 88 */ 89 LdapConnection &connection(); 90 /** 91 * Sets the client controls which will sent with each operation. 92 */ 93 void setClientControls(const LdapControls &ctrls); 94 /** 95 * Sets the server controls which will sent with each operation. 96 */ 97 void setServerControls(const LdapControls &ctrls); 98 /** 99 * Returns the client controls (which set by setClientControls()). 100 */ 101 Q_REQUIRED_RESULT LdapControls clientControls() const; 102 /** 103 * Returns the server controls (which set by setServerControls()). 104 */ 105 Q_REQUIRED_RESULT LdapControls serverControls() const; 106 107 /** 108 * Binds to the server which specified in the connection object. 109 * Can do simple or SASL bind. Returns a message id if successful, negative value if not. 110 */ 111 Q_REQUIRED_RESULT int bind(const QByteArray &creds = QByteArray(), SASL_Callback_Proc *saslproc = nullptr, void *data = nullptr); 112 113 /** 114 * Binds to the server which specified in the connection object. 115 * Can do simple or SASL bind. This is the synchronous version. 116 * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. 117 */ 118 Q_REQUIRED_RESULT int bind_s(SASL_Callback_Proc *saslproc = nullptr, void *data = nullptr); 119 120 /** 121 * Starts a search operation with the given base DN, scope, filter and 122 * result attributes. Returns a message id if successful, -1 if not. 123 */ 124 Q_REQUIRED_RESULT int search(const LdapDN &base, LdapUrl::Scope scope, const QString &filter, const QStringList &attrs); 125 /** 126 * Starts an addition operation. 127 * Returns a message id if successful, -1 if not. 128 * @param object the additional operation to start 129 */ 130 Q_REQUIRED_RESULT int add(const LdapObject &object); 131 /** 132 * Adds the specified object to the LDAP database. 133 * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. 134 * @param object the object to add to LDAP database 135 */ 136 Q_REQUIRED_RESULT int add_s(const LdapObject &object); 137 /** 138 * Starts an addition operation. This version accepts ModOps not LdapObject. 139 * Returns a message id if successful, -1 if not. 140 * @param dn the LdapDN operation to start 141 * @param ops the ModOps operation to start 142 */ 143 Q_REQUIRED_RESULT int add(const LdapDN &dn, const ModOps &ops); 144 /** 145 * Adds the specified object to the LDAP database. This version accepts ModOps not LdapObject. 146 * This is the synchronous version. 147 * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. 148 * @param dn the LdapDN object to add 149 * @param ops the ModOps object to add 150 */ 151 Q_REQUIRED_RESULT int add_s(const LdapDN &dn, const ModOps &ops); 152 /** 153 * Starts a modrdn operation on given DN, changing its RDN to newRdn, 154 * changing its parent to newSuperior (if it's not empty), and deletes 155 * the old dn if deleteold is true. 156 * Returns a message id if successful, -1 if not. 157 */ 158 Q_REQUIRED_RESULT int rename(const LdapDN &dn, const QString &newRdn, const QString &newSuperior, bool deleteold = true); 159 /** 160 * Performs a modrdn operation on given DN, changing its RDN to newRdn, 161 * changing its parent to newSuperior (if it's not empty), and deletes 162 * the old dn if deleteold is true. This is the synchronous version. 163 * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. 164 */ 165 Q_REQUIRED_RESULT int rename_s(const LdapDN &dn, const QString &newRdn, const QString &newSuperior, bool deleteold = true); 166 /** 167 * Starts a delete operation on the given DN. 168 * Returns a message id if successful, -1 if not. 169 */ 170 Q_REQUIRED_RESULT int del(const LdapDN &dn); 171 /** 172 * Deletes the given DN. This is the synchronous version. 173 * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. 174 * @param dn the dn to delete 175 */ 176 Q_REQUIRED_RESULT int del_s(const LdapDN &dn); 177 /** 178 * Starts a modify operation on the given DN. 179 * Returns a message id if successful, -1 if not. 180 * @param dn the DN to start modify operation on 181 */ 182 Q_REQUIRED_RESULT int modify(const LdapDN &dn, const ModOps &ops); 183 /** 184 * Performs a modify operation on the given DN. 185 * This is the synchronous version. 186 * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. 187 */ 188 Q_REQUIRED_RESULT int modify_s(const LdapDN &dn, const ModOps &ops); 189 /** 190 * Starts a compare operation on the given DN, compares the specified 191 * attribute with the given value. 192 * Returns a message id if successful, -1 if not. 193 */ 194 Q_REQUIRED_RESULT int compare(const LdapDN &dn, const QString &attr, const QByteArray &value); 195 /** 196 * Performs a compare operation on the given DN, compares the specified 197 * attribute with the given value. This is the synchronous version. 198 * Returns KLDAP_COMPARE_TRUE if the entry contains the attribute value 199 * and KLDAP_COMPARE_FALSE if it does not. Otherwise, some error code 200 * is returned. 201 */ 202 Q_REQUIRED_RESULT int compare_s(const LdapDN &dn, const QString &attr, const QByteArray &value); 203 /** 204 * Starts an extended operation specified with oid and data. 205 * Returns a message id if successful, -1 if not. 206 */ 207 Q_REQUIRED_RESULT int exop(const QString &oid, const QByteArray &data); 208 /** 209 * Performs an extended operation specified with oid and data. 210 * This is the synchronous version. 211 * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. 212 */ 213 Q_REQUIRED_RESULT int exop_s(const QString &oid, const QByteArray &data); 214 /** 215 * Abandons a long-running operation. Requires the message id. 216 */ 217 Q_REQUIRED_RESULT int abandon(int id); 218 /** 219 * Waits for up to \p msecs milliseconds for a result message from the LDAP 220 * server. If \p msecs is -1, then this function will block indefinitely. 221 * If \p msecs is 0, then this function will return immediately, that is it 222 * will perform a poll for a result message. 223 * 224 * Returns the type of the result LDAP message (RES_XXX constants). 225 * -1 if error occurred, 0 if the timeout value elapsed. Note! 226 * Return code -1 means that fetching the message resulted in error, 227 * not the LDAP operation error. Call connection().ldapErrorCode() to 228 * determine if the operation succeeded. 229 */ 230 Q_REQUIRED_RESULT int waitForResult(int id, int msecs = -1); 231 /** 232 * Returns the result object if result() returned RES_SEARCH_ENTRY. 233 */ 234 Q_REQUIRED_RESULT LdapObject object() const; 235 /** 236 * Returns the server controls from the returned ldap message (grabbed 237 * by result()). 238 */ 239 Q_REQUIRED_RESULT LdapControls controls() const; 240 /** 241 * Returns the OID of the extended operation response (result 242 * returned RES_EXTENDED). 243 */ 244 Q_REQUIRED_RESULT QByteArray extendedOid() const; 245 /** 246 * Returns the data from the extended operation response (result 247 * returned RES_EXTENDED). 248 */ 249 Q_REQUIRED_RESULT QByteArray extendedData() const; 250 /** 251 * The server might supply a matched DN string in the message indicating 252 * how much of a name in a request was recognized. This can be grabbed by 253 * matchedDn(). 254 */ 255 Q_REQUIRED_RESULT QString matchedDn() const; 256 /** 257 * This function returns the referral strings from the parsed message 258 * (if any). 259 */ 260 Q_REQUIRED_RESULT QList<QByteArray> referrals() const; 261 /** 262 * Returns the server response for a bind request (result 263 * returned RES_BIND). 264 */ 265 Q_REQUIRED_RESULT QByteArray serverCred() const; 266 267 private: 268 class LdapOperationPrivate; 269 std::unique_ptr<LdapOperationPrivate> const d; 270 271 Q_DISABLE_COPY(LdapOperation) 272 }; 273 } 274 275