• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

KLDAP Library

  • sources
  • kde-4.14
  • kdepimlibs
  • kldap
ldif.cpp
1 /*
2  This file is part of libkldap.
3  Copyright (c) 2004-2006 Szombathelyi György <gyurco@freemail.hu>
4 
5  This library is free software; you can redistribute it and/or
6  modify it under the terms of the GNU Library General Public
7  License as published by the Free Software Foundation; either
8  version 2 of the License, or (at your option) any later version.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include "ldif.h"
22 
23 #include <kdebug.h>
24 
25 using namespace KLDAP;
26 
27 class Ldif::LdifPrivate
28 {
29  public:
30  int mModType;
31  bool mDelOldRdn, mUrl;
32  LdapDN mDn;
33  QString mAttr, mNewRdn, mNewSuperior, mOid;
34  QByteArray mLdif, mValue;
35  EntryType mEntryType;
36 
37  bool mIsNewLine, mIsComment, mCritical;
38  ParseValue mLastParseValue;
39  uint mPos, mLineNumber;
40  QByteArray mLine;
41 };
42 
43 Ldif::Ldif() : d( new LdifPrivate )
44 {
45  startParsing();
46 }
47 
48 Ldif::Ldif( const Ldif &that ) : d( new LdifPrivate )
49 {
50  *d = *that.d;
51 
52  startParsing();
53 }
54 
55 Ldif &Ldif::operator=( const Ldif &that )
56 {
57  if ( this == &that ) {
58  return *this;
59  }
60 
61  *d = *that.d;
62 
63  return *this;
64 }
65 
66 Ldif::~Ldif()
67 {
68  delete d;
69 }
70 
71 QByteArray Ldif::assembleLine( const QString &fieldname,
72  const QByteArray &value,
73  uint linelen, bool url )
74 {
75  bool safe = false;
76  bool isDn;
77  QByteArray result;
78 
79  if ( url ) {
80  result = fieldname.toUtf8() + ":< " + value;
81  } else {
82  isDn = fieldname.toLower() == QLatin1String("dn");
83  //SAFE-INIT-CHAR
84  if ( value.size() > 0 && value[0] > 0 && value[0] != '\n' &&
85  value[0] != '\r' && value[0] != ':' && value[0] != '<' ) safe = true;
86 
87  //SAFE-CHAR
88  if ( safe ) {
89  for ( int i=1; i < value.size(); i++ ) {
90  //allow utf-8 in Distinguished Names
91  if ( ( isDn && value[i] == 0 ) ||
92  ( !isDn && value[i] <= 0 ) ||
93  value[i] == '\r' || value[i] == '\n' ) {
94  safe = false;
95  break;
96  }
97  }
98  }
99 
100  if ( value.size() == 0 ) {
101  safe = true;
102  }
103 
104  if ( safe ) {
105  result = fieldname.toUtf8() + ": " + value;
106  } else {
107  result = fieldname.toUtf8() + ":: " + value.toBase64();
108  }
109 
110  if ( linelen > 0 ) {
111  int i = (uint)( fieldname.length() + 2 ) > linelen ? fieldname.length() + 2 : linelen;
112  while ( i < result.length() ) {
113  result.insert( i, "\n " );
114  i += linelen+2;
115  }
116  }
117  }
118  return result;
119 }
120 
121 QByteArray Ldif::assembleLine( const QString &fieldname, const QString &value,
122  uint linelen, bool url )
123 {
124  return assembleLine( fieldname, value.toUtf8(), linelen, url );
125 }
126 
127 bool Ldif::splitLine( const QByteArray &line, QString &fieldname, QByteArray &value )
128 {
129  int position;
130  QByteArray tmp;
131  int linelen;
132 
133 // kDebug() << "line:" << QString::fromUtf8(line);
134 
135  position = line.indexOf( ":" );
136  if ( position == -1 ) {
137  // strange: we did not find a fieldname
138  fieldname = QLatin1String("");
139  value = line.trimmed();
140 // kDebug() << "value :" << value[0];
141  return false;
142  }
143 
144  linelen = line.size();
145  fieldname = QString::fromUtf8( line.left( position ).trimmed() );
146 
147  if ( linelen > ( position + 1 ) && line[ position + 1 ] == ':' ) {
148  // String is BASE64 encoded -> decode it now.
149  if ( linelen <= ( position + 3 ) ) {
150  value.resize( 0 );
151  return false;
152  }
153  value = QByteArray::fromBase64( line.mid( position + 3 ) );
154  return false;
155  }
156 
157  if ( linelen > ( position + 1 ) && line[ position + 1 ] == '<' ) {
158  // String is an URL.
159  if ( linelen <= ( position + 3 ) ) {
160  value.resize( 0 );
161  return false;
162  }
163  value = QByteArray::fromBase64( line.mid( position + 3 ) );
164  return true;
165  }
166 
167  if ( linelen <= ( position + 2 ) ) {
168  value.resize( 0 );
169  return false;
170  }
171  value = line.mid( position + 2 );
172  return false;
173 }
174 
175 bool Ldif::splitControl( const QByteArray &line, QString &oid, bool &critical,
176  QByteArray &value )
177 {
178  QString tmp;
179  critical = false;
180  bool url = splitLine( line, tmp, value );
181 
182  kDebug() << "value:" << QString::fromUtf8( value, value.size() );
183  if ( tmp.isEmpty() ) {
184  tmp = QString::fromUtf8( value, value.size() );
185  value.resize( 0 );
186  }
187  if ( tmp.endsWith( QLatin1String( "true" ) ) ) {
188  critical = true;
189  tmp.truncate( tmp.length() - 5 );
190  } else if ( tmp.endsWith( QLatin1String( "false" ) ) ) {
191  critical = false;
192  tmp.truncate( tmp.length() - 6 );
193  }
194  oid = tmp;
195  return url;
196 }
197 
198 Ldif::ParseValue Ldif::processLine()
199 {
200 
201  if ( d->mIsComment ) {
202  return None;
203  }
204 
205  ParseValue retval = None;
206  if ( d->mLastParseValue == EndEntry ) {
207  d->mEntryType = Entry_None;
208  }
209 
210  d->mUrl = splitLine( d->mLine, d->mAttr, d->mValue );
211 
212  QString attrLower = d->mAttr.toLower();
213 
214  switch ( d->mEntryType ) {
215  case Entry_None:
216  if ( attrLower == QLatin1String( "version" ) ) {
217  if ( !d->mDn.isEmpty() ) {
218  retval = Err;
219  }
220  } else if ( attrLower == QLatin1String( "dn" ) ) {
221  kDebug() << "ldapentry dn:" << QString::fromUtf8( d->mValue, d->mValue.size() );
222  d->mDn = LdapDN( QString::fromUtf8( d->mValue, d->mValue.size() ) );
223  d->mModType = Mod_None;
224  retval = NewEntry;
225  } else if ( attrLower == QLatin1String( "changetype" ) ) {
226  if ( d->mDn.isEmpty() ) {
227  retval = Err;
228  } else {
229  QString tmpval = QString::fromUtf8( d->mValue, d->mValue.size() );
230  kDebug() << "changetype:" << tmpval;
231  if ( tmpval == QLatin1String( "add" ) ) {
232  d->mEntryType = Entry_Add;
233  } else if ( tmpval == QLatin1String( "delete" ) ) {
234  d->mEntryType = Entry_Del;
235  } else if ( tmpval == QLatin1String( "modrdn" ) || tmpval == QLatin1String( "moddn" ) ) {
236  d->mNewRdn.clear();
237  d->mNewSuperior.clear();
238  d->mDelOldRdn = true;
239  d->mEntryType = Entry_Modrdn;
240  } else if ( tmpval == QLatin1String( "modify" ) ) {
241  d->mEntryType = Entry_Mod;
242  } else {
243  retval = Err;
244  }
245  }
246  } else if ( attrLower == QLatin1String( "control" ) ) {
247  d->mUrl = splitControl( d->mValue, d->mOid, d->mCritical, d->mValue );
248  retval = Control;
249  } else if ( !d->mAttr.isEmpty() && d->mValue.size() > 0 ) {
250  d->mEntryType = Entry_Add;
251  retval = Item;
252  }
253  break;
254  case Entry_Add:
255  if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
256  retval = EndEntry;
257  } else {
258  retval = Item;
259  }
260  break;
261  case Entry_Del:
262  if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
263  retval = EndEntry;
264  } else {
265  retval = Err;
266  }
267  break;
268  case Entry_Mod:
269  if ( d->mModType == Mod_None ) {
270  kDebug() << "new modtype" << d->mAttr;
271  if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
272  retval = EndEntry;
273  } else if ( attrLower == QLatin1String( "add" ) ) {
274  d->mModType = Mod_Add;
275  } else if ( attrLower == QLatin1String( "replace" ) ) {
276  d->mModType = Mod_Replace;
277  d->mAttr = QString::fromUtf8( d->mValue, d->mValue.size() );
278  d->mValue = QByteArray();
279  retval = Item;
280  } else if ( attrLower == QLatin1String( "delete" ) ) {
281  d->mModType = Mod_Del;
282  d->mAttr = QString::fromUtf8( d->mValue, d->mValue.size() );
283  d->mValue = QByteArray();
284  retval = Item;
285  } else {
286  retval = Err;
287  }
288  } else {
289  if ( d->mAttr.isEmpty() ) {
290  if ( QString::fromUtf8( d->mValue, d->mValue.size() ) == QLatin1String("-") ) {
291  d->mModType = Mod_None;
292  } else if ( d->mValue.size() == 0 ) {
293  retval = EndEntry;
294  } else {
295  retval = Err;
296  }
297  } else {
298  retval = Item;
299  }
300  }
301  break;
302  case Entry_Modrdn:
303  if ( d->mAttr.isEmpty() && d->mValue.size() == 0 ) {
304  retval = EndEntry;
305  } else if ( attrLower == QLatin1String( "newrdn" ) ) {
306  d->mNewRdn = QString::fromUtf8( d->mValue, d->mValue.size() );
307  } else if ( attrLower == QLatin1String( "newsuperior" ) ) {
308  d->mNewSuperior = QString::fromUtf8( d->mValue, d->mValue.size() );
309  } else if ( attrLower == QLatin1String( "deleteoldrdn" ) ) {
310  if ( d->mValue.size() > 0 && d->mValue[0] == '0' ) {
311  d->mDelOldRdn = false;
312  } else if ( d->mValue.size() > 0 && d->mValue[0] == '1' ) {
313  d->mDelOldRdn = true;
314  } else {
315  retval = Err;
316  }
317  } else {
318  retval = Err;
319  }
320  break;
321  }
322  return retval;
323 }
324 
325 Ldif::ParseValue Ldif::nextItem()
326 {
327  ParseValue retval = None;
328  char c=0;
329 
330  while ( retval == None ) {
331  if ( d->mPos < (uint)d->mLdif.size() ) {
332  c = d->mLdif[d->mPos];
333  d->mPos++;
334  if ( d->mIsNewLine && c == '\r' ) {
335  continue; //handle \n\r line end
336  }
337  if ( d->mIsNewLine && ( c == ' ' || c == '\t' ) ) { //line folding
338  d->mIsNewLine = false;
339  continue;
340  }
341  if ( d->mIsNewLine ) {
342  d->mIsNewLine = false;
343  retval = processLine();
344  d->mLastParseValue = retval;
345  d->mLine.resize( 0 );
346  d->mIsComment = ( c == '#' );
347  }
348  if ( c == '\n' || c == '\r' ) {
349  d->mLineNumber++;
350  d->mIsNewLine = true;
351  continue;
352  }
353  } else {
354  retval = MoreData;
355  break;
356  }
357 
358  if ( !d->mIsComment ) {
359  d->mLine += c;
360  }
361  }
362  return retval;
363 }
364 
365 void Ldif::endLdif()
366 {
367  QByteArray tmp( 3, '\n' );
368  d->mLdif = tmp;
369  d->mPos = 0;
370 }
371 
372 void Ldif::startParsing()
373 {
374  d->mPos = d->mLineNumber = 0;
375  d->mDelOldRdn = false;
376  d->mEntryType = Entry_None;
377  d->mModType = Mod_None;
378  d->mDn = LdapDN();
379  d->mNewRdn.clear();
380  d->mNewSuperior.clear();
381  d->mLine = QByteArray();
382  d->mIsNewLine = false;
383  d->mIsComment = false;
384  d->mLastParseValue = None;
385 }
386 
387 void Ldif::setLdif( const QByteArray &ldif )
388 {
389  d->mLdif = ldif;
390  d->mPos = 0;
391 }
392 
393 Ldif::EntryType Ldif::entryType() const
394 {
395  return d->mEntryType;
396 }
397 
398 int Ldif::modType() const
399 {
400  return d->mModType;
401 }
402 
403 LdapDN Ldif::dn() const
404 {
405  return d->mDn;
406 }
407 
408 QString Ldif::newRdn() const
409 {
410  return d->mNewRdn;
411 }
412 
413 QString Ldif::newSuperior() const
414 {
415  return d->mNewSuperior;
416 }
417 
418 bool Ldif::delOldRdn() const
419 {
420  return d->mDelOldRdn;
421 }
422 
423 QString Ldif::attr() const
424 {
425  return d->mAttr;
426 }
427 
428 QByteArray Ldif::value() const
429 {
430  return d->mValue;
431 }
432 
433 bool Ldif::isUrl() const
434 {
435  return d->mUrl;
436 }
437 
438 bool Ldif::isCritical() const
439 {
440  return d->mCritical;
441 }
442 
443 QString Ldif::oid() const
444 {
445  return d->mOid;
446 }
447 
448 uint Ldif::lineNumber() const
449 {
450  return d->mLineNumber;
451 }
QString::truncate
void truncate(int position)
KLDAP::Ldif::oid
QString oid() const
Returns the OID when modType() returned Control.
Definition: ldif.cpp:443
QByteArray::trimmed
QByteArray trimmed() const
QByteArray
KLDAP::Ldif::lineNumber
uint lineNumber() const
Returns the line number which the parser processes.
Definition: ldif.cpp:448
KLDAP::Ldif::newRdn
QString newRdn() const
Returns the new Relative Distinguished Name if modType() returned Entry_Modrdn.
Definition: ldif.cpp:408
KLDAP::Ldif::isUrl
bool isUrl() const
Returns if val() is an url.
Definition: ldif.cpp:433
QByteArray::insert
QByteArray & insert(int i, char ch)
QByteArray::length
int length() const
KLDAP::Ldif::endLdif
void endLdif()
Indicates the end of the Ldif file/stream.
Definition: ldif.cpp:365
KLDAP::Ldif::processLine
ParseValue processLine()
Process one Ldif line.
Definition: ldif.cpp:198
KLDAP::Ldif::assembleLine
static QByteArray assembleLine(const QString &fieldname, const QByteArray &value, uint linelen=0, bool url=false)
Assembles fieldname and value into a valid Ldif line, BASE64 encodes the value if necessary and optio...
Definition: ldif.cpp:71
QByteArray::resize
void resize(int size)
QByteArray::indexOf
int indexOf(char ch, int from) const
QString::fromUtf8
QString fromUtf8(const char *str, int size)
KLDAP::Ldif::value
QByteArray value() const
Returns the attribute value.
Definition: ldif.cpp:428
KLDAP::Ldif::startParsing
void startParsing()
Starts the parsing of a new Ldif.
Definition: ldif.cpp:372
KLDAP::Ldif::modType
int modType() const
Returns the LDAP modify request type if entryType() returned Entry_Mod.
Definition: ldif.cpp:398
QString::isEmpty
bool isEmpty() const
QString::endsWith
bool endsWith(const QString &s, Qt::CaseSensitivity cs) const
KLDAP::Ldif::attr
QString attr() const
Returns the attribute name.
Definition: ldif.cpp:423
QString
KLDAP::Ldif::splitLine
static bool splitLine(const QByteArray &line, QString &fieldname, QByteArray &value)
Splits one line from an Ldif file to attribute and value components.
Definition: ldif.cpp:127
QByteArray::mid
QByteArray mid(int pos, int len) const
QString::toLower
QString toLower() const
KLDAP::Ldif::dn
LdapDN dn() const
Returns the Distinguished Name of the current entry.
Definition: ldif.cpp:403
KLDAP::Ldif::setLdif
void setLdif(const QByteArray &ldif)
Sets a chunk of Ldif.
Definition: ldif.cpp:387
KLDAP::Ldif::delOldRdn
bool delOldRdn() const
Returns if the delete of the old RDN is required.
Definition: ldif.cpp:418
QByteArray::left
QByteArray left(int len) const
KLDAP::Ldif::nextItem
ParseValue nextItem()
Process the Ldif until a complete item can be returned.
Definition: ldif.cpp:325
QLatin1String
QByteArray::fromBase64
QByteArray fromBase64(const QByteArray &base64)
KLDAP::Ldif::newSuperior
QString newSuperior() const
Returns the new parent of the entry if modType() returned Entry_Modrdn.
Definition: ldif.cpp:413
QString::length
int length() const
KLDAP::Ldif::entryType
EntryType entryType() const
Returns the requested LDAP operation extracted from the current entry.
Definition: ldif.cpp:393
QByteArray::toBase64
QByteArray toBase64() const
KLDAP::Ldif::splitControl
static bool splitControl(const QByteArray &line, QString &oid, bool &critical, QByteArray &value)
Splits a control specification (without the "control:" directive)
Definition: ldif.cpp:175
QByteArray::size
int size() const
KLDAP::Ldif
Ldif.
Definition: ldif.h:40
KLDAP::Ldif::isCritical
bool isCritical() const
Returns the criticality level when modType() returned Control.
Definition: ldif.cpp:438
QString::toUtf8
QByteArray toUtf8() const
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:37:58 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KLDAP Library

Skip menu "KLDAP Library"
  • Main Page
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal