File indexing completed on 2024-12-15 04:50:17

0001 /*
0002   This file is part of libkldap.
0003   SPDX-FileCopyrightText: 2004-2006 Szombathelyi György <gyurco@freemail.hu>
0004 
0005   SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #pragma once
0009 
0010 #include <QByteArray>
0011 #include <QString>
0012 
0013 #include "kldap_core_export.h"
0014 #include "ldapdn.h"
0015 
0016 // clazy:excludeall=copyable-polymorphic
0017 
0018 namespace KLDAPCore
0019 {
0020 /**
0021  * Ldif
0022  *
0023  * Ldif implements an RFC 2849 compliant Ldif parser. Ldif files are used to
0024  * represent directory information on LDAP-based servers, or to describe a set
0025  * of changes which are to be applied to a directory.
0026  */
0027 
0028 class KLDAP_CORE_EXPORT Ldif
0029 {
0030 public:
0031     using ParseValue = enum { None, NewEntry, EndEntry, Item, Control, Err, MoreData };
0032 
0033     using EntryType = enum { Entry_None, Entry_Add, Entry_Del, Entry_Mod, Entry_Modrdn };
0034 
0035     using ModType = enum { Mod_None, Mod_Add, Mod_Replace, Mod_Del };
0036 
0037     Ldif();
0038 
0039     Ldif(const Ldif &that);
0040     Ldif &operator=(const Ldif &that);
0041 
0042     ~Ldif();
0043 
0044     /**
0045      * Assembles fieldname and value into a valid Ldif line, BASE64 encodes the
0046      * value if necessary and optionally splits into more lines.
0047      * @param fieldname The name of the entry.
0048      * @param value The value of the entry.
0049      * @param linelen Maximum length of the lines in the result.
0050      * @param url If true, encode value as url ( use :< ).
0051      */
0052     [[nodiscard]] static QByteArray assembleLine(const QString &fieldname, const QByteArray &value, uint linelen = 0, bool url = false);
0053     /**
0054      * This is the same as the above function, the only difference that
0055      * this accepts QString as the value.
0056      */
0057     [[nodiscard]] static QByteArray assembleLine(const QString &fieldname, const QString &value, uint linelen = 0, bool url = false);
0058 
0059     /**
0060      * Splits one line from an Ldif file to attribute and value components.
0061      * @return true if value is an URL, false otherwise
0062      */
0063     [[nodiscard]] static bool splitLine(const QByteArray &line, QString &fieldname, QByteArray &value);
0064 
0065     /**
0066      * Splits a control specification (without the "control:" directive)
0067      * @param line is the control directive
0068      * @param oid will contain the OID
0069      * @param critical will contain the criticality of control
0070      * @param value is the control value
0071      */
0072     [[nodiscard]] static bool splitControl(const QByteArray &line, QString &oid, bool &critical, QByteArray &value);
0073 
0074     /**
0075      * Starts the parsing of a new Ldif
0076      */
0077     void startParsing();
0078 
0079     /**
0080      * Process one Ldif line
0081      */
0082     [[nodiscard]] ParseValue processLine();
0083 
0084     /**
0085      * Process the Ldif until a complete item can be returned
0086      * @return NewEntry if a new DN encountered, Item if a new item returned,
0087      * Err if the Ldif contains error, EndEntry if the parser reached the end
0088      * of the current entry and MoreData if the parser encountered the end of
0089      * the current chunk of the Ldif.
0090      *
0091      * If you want to finish the parsing after receiving MoreData, then call
0092      * endLdif(), so the parser can safely flush the current entry.
0093      */
0094     [[nodiscard]] ParseValue nextItem();
0095 
0096     /**
0097      * Sets a chunk of Ldif. Call before startParsing(), or if nextItem()
0098      * returned MoreData.
0099      * @param ldif the Ldif chunk to set
0100      */
0101     void setLdif(const QByteArray &ldif);
0102 
0103     /**
0104      * Indicates the end of the Ldif file/stream. Call if nextItem() returned
0105      * MoreData, but actually you don't have more data.
0106      */
0107     void endLdif();
0108 
0109     /**
0110      * Returns the requested LDAP operation extracted from the current entry.
0111      */
0112     [[nodiscard]] EntryType entryType() const;
0113 
0114     /**
0115      * Returns the LDAP modify request type if entryType() returned Entry_Mod.
0116      */
0117     [[nodiscard]] int modType() const;
0118 
0119     /**
0120      * Returns the Distinguished Name of the current entry.
0121      */
0122     [[nodiscard]] LdapDN dn() const;
0123 
0124     /**
0125      * Returns the new Relative Distinguished Name if modType() returned
0126      * Entry_Modrdn.
0127      */
0128     [[nodiscard]] QString newRdn() const;
0129 
0130     /**
0131      * Returns the new parent of the entry if modType() returned Entry_Modrdn.
0132      */
0133     QString newSuperior() const;
0134 
0135     /**
0136      * Returns if the delete of the old RDN is required.
0137      */
0138     [[nodiscard]] bool delOldRdn() const;
0139 
0140     /**
0141      * Returns the attribute name.
0142      */
0143     [[nodiscard]] QString attr() const;
0144 
0145     /**
0146      * Returns the attribute value.
0147      */
0148     [[nodiscard]] QByteArray value() const;
0149 
0150     /**
0151      * Returns if val() is an url
0152      */
0153     [[nodiscard]] bool isUrl() const;
0154 
0155     /**
0156      * Returns the criticality level when modType() returned Control.
0157      */
0158     [[nodiscard]] bool isCritical() const;
0159 
0160     /**
0161      * Returns the OID when modType() returned Control.
0162      */
0163     [[nodiscard]] QString oid() const;
0164 
0165     /**
0166      * Returns the line number which the parser processes.
0167      */
0168     [[nodiscard]] uint lineNumber() const;
0169 
0170 private:
0171     class LdifPrivate;
0172     std::unique_ptr<LdifPrivate> const d;
0173 };
0174 }