mirror of
https://bitbucket.org/smil3y/kde-playground.git
synced 2025-02-23 18:32:51 +00:00
469 lines
10 KiB
C++
469 lines
10 KiB
C++
/*
|
|
This file is part of libkldap.
|
|
Copyright (c) 2004-2006 Szombathelyi György <gyurco@freemail.hu>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Library General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Library General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include "ber.h"
|
|
#include "kldap_config.h"
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <QtCore/QList>
|
|
#include <qvarlengtharray.h>
|
|
|
|
#include <cstdarg>
|
|
|
|
#ifdef LDAP_FOUND
|
|
|
|
#ifdef Q_OS_SOLARIS //krazy:exclude=cpp
|
|
#define BC31 1
|
|
#endif
|
|
|
|
#ifndef HAVE_WINLDAP_H
|
|
#include <lber.h>
|
|
#include <ldap.h>
|
|
#else
|
|
#include <w32-ldap-help.h>
|
|
#endif
|
|
|
|
#ifndef LBER_USE_DER
|
|
#define LBER_USE_DER 1
|
|
#endif
|
|
|
|
#ifndef HAVE_BER_MEMFREE
|
|
# ifndef HAVE_WINLDAP_H
|
|
# define ber_memfree(x) ldap_memfree(x)
|
|
# else
|
|
# define ber_memfree(x) win_ldap_memfree(x)
|
|
# endif
|
|
#endif
|
|
|
|
#endif
|
|
|
|
using namespace KLDAP;
|
|
|
|
class Ber::BerPrivate
|
|
{
|
|
public:
|
|
#ifdef LDAP_FOUND
|
|
BerElement *mBer;
|
|
#endif
|
|
};
|
|
|
|
#ifdef LDAP_FOUND
|
|
Ber::Ber()
|
|
: d( new BerPrivate )
|
|
{
|
|
d->mBer = ber_alloc_t( LBER_USE_DER );
|
|
Q_ASSERT( d->mBer );
|
|
}
|
|
|
|
Ber::Ber( const QByteArray &value )
|
|
: d( new BerPrivate )
|
|
{
|
|
struct berval bv;
|
|
bv.bv_val = (char *) value.data();
|
|
bv.bv_len = value.size();
|
|
d->mBer = ber_init( &bv );
|
|
Q_ASSERT( d->mBer );
|
|
}
|
|
|
|
Ber::~Ber()
|
|
{
|
|
ber_free( d->mBer, 1 );
|
|
delete d;
|
|
}
|
|
|
|
Ber::Ber( const Ber &that )
|
|
: d( new BerPrivate )
|
|
{
|
|
struct berval *bv;
|
|
if ( ber_flatten( that.d->mBer, &bv ) == 0 ) {
|
|
d->mBer = ber_init( bv );
|
|
ber_bvfree( bv );
|
|
}
|
|
}
|
|
|
|
Ber &Ber::operator=( const Ber &that )
|
|
{
|
|
if ( this == &that ) {
|
|
return *this;
|
|
}
|
|
|
|
struct berval *bv;
|
|
if ( ber_flatten( that.d->mBer, &bv ) == 0 ) {
|
|
d->mBer = ber_init( bv );
|
|
ber_bvfree( bv );
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
QByteArray Ber::flatten() const
|
|
{
|
|
QByteArray ret;
|
|
struct berval *bv;
|
|
if ( ber_flatten( d->mBer, &bv ) == 0 ) {
|
|
ret = QByteArray( bv->bv_val, bv->bv_len );
|
|
ber_bvfree( bv );
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
int Ber::printf( const QString &format, ... )
|
|
{
|
|
char fmt[2];
|
|
va_list args;
|
|
va_start ( args, format );
|
|
fmt[1] = '\0';
|
|
|
|
int i = 0, ret = 0;
|
|
while ( i < format.length() ) {
|
|
fmt[0] = format[i].toLatin1();
|
|
i++;
|
|
switch ( fmt[0] ) {
|
|
case 'b':
|
|
case 'e':
|
|
case 'i':
|
|
{
|
|
ber_int_t v = va_arg( args, int );
|
|
ret = ber_printf( d->mBer, fmt, v );
|
|
break;
|
|
}
|
|
case 'B':
|
|
{
|
|
//FIXME: QBitArray vould be logical, but how to access the bits?
|
|
QByteArray *B = va_arg( args, QByteArray * );
|
|
int Bc = va_arg( args, int );
|
|
ret = ber_printf( d->mBer, fmt, B->data(), Bc );
|
|
break;
|
|
}
|
|
case 'o':
|
|
{
|
|
QByteArray *o = va_arg( args, QByteArray * );
|
|
ret = ber_printf( d->mBer, fmt, o->data(), o->size() );
|
|
break;
|
|
}
|
|
case 'O':
|
|
{
|
|
QByteArray *O = va_arg( args, QByteArray * );
|
|
struct berval bv;
|
|
bv.bv_val = (char *) O->data();
|
|
bv.bv_len = O->size();
|
|
ret = ber_printf( d->mBer, fmt, &bv );
|
|
break;
|
|
}
|
|
break;
|
|
case 's':
|
|
{
|
|
QByteArray *s = va_arg( args, QByteArray * );
|
|
ret = ber_printf( d->mBer, fmt, s->data() );
|
|
break;
|
|
}
|
|
break;
|
|
case 't':
|
|
{
|
|
unsigned int t = va_arg( args, unsigned int );
|
|
ret = ber_printf( d->mBer, fmt, t );
|
|
break;
|
|
}
|
|
break;
|
|
case 'v':
|
|
{
|
|
QList<QByteArray> *v = va_arg( args, QList<QByteArray> * );
|
|
QVarLengthArray<const char *> l( v->count()+1 );
|
|
int j;
|
|
for ( j = 0; j < v->count(); j++ ) {
|
|
l[j] = v->at( j ).data();
|
|
}
|
|
l[j] = 0;
|
|
ret = ber_printf( d->mBer, fmt, l.data() );
|
|
break;
|
|
}
|
|
case 'V':
|
|
{
|
|
QList<QByteArray> *V = va_arg( args, QList<QByteArray> * );
|
|
QVarLengthArray<struct berval *> bv ( V->count()+1 );
|
|
QVarLengthArray<struct berval> bvs( V->count( ) );
|
|
int j;
|
|
for ( j = 0; j < V->count(); j++ ) {
|
|
bvs[j].bv_val = (char *) V->at( j ).data();
|
|
bvs[j].bv_len = V->at( j ).size();
|
|
bv[j] = &bvs[j];
|
|
}
|
|
bv[V->count()] = 0;
|
|
ret = ber_printf( d->mBer, fmt, bv.data() );
|
|
break;
|
|
}
|
|
case 'n':
|
|
case '{':
|
|
case '}':
|
|
case '[':
|
|
case ']':
|
|
ret = ber_printf( d->mBer, fmt );
|
|
break;
|
|
default:
|
|
kWarning() << "Invalid BER format parameter: '" << fmt << "'";
|
|
ret = -1;
|
|
}
|
|
kDebug() << "ber_printf format:" << fmt << "ret:" << ret;
|
|
if ( ret == -1 ) {
|
|
break;
|
|
}
|
|
}
|
|
va_end( args );
|
|
return ret;
|
|
}
|
|
|
|
int Ber::scanf( const QString &format, ... )
|
|
{
|
|
char fmt[2];
|
|
va_list args;
|
|
va_start ( args, format );
|
|
fmt[1] = '\0';
|
|
|
|
int i = 0, ret = 0;
|
|
while ( i < format.length() ) {
|
|
fmt[0] = format[i].toLatin1();
|
|
i++;
|
|
switch ( fmt[0] ) {
|
|
case 'l':
|
|
case 'b':
|
|
case 'e':
|
|
case 'i':
|
|
{
|
|
int *v = va_arg( args, int * );
|
|
ret = ber_scanf( d->mBer, fmt, v );
|
|
break;
|
|
}
|
|
case 'B':
|
|
{
|
|
//FIXME: QBitArray vould be logical, but how to access the bits?
|
|
QByteArray *B = va_arg( args, QByteArray * );
|
|
int *Bc = va_arg( args, int * );
|
|
char *c;
|
|
ret = ber_scanf( d->mBer, fmt, &c, Bc );
|
|
if ( ret != -1 ) {
|
|
*B = QByteArray( c, ( *Bc + 7 ) / 8 );
|
|
ber_memfree( c );
|
|
}
|
|
break;
|
|
}
|
|
case 'o':
|
|
{
|
|
QByteArray *o = va_arg( args, QByteArray * );
|
|
struct berval bv;
|
|
ret = ber_scanf( d->mBer, fmt, &bv );
|
|
if ( ret != -1 ) {
|
|
*o = QByteArray( bv.bv_val, bv.bv_len );
|
|
ber_memfree( bv.bv_val );
|
|
}
|
|
break;
|
|
}
|
|
case 'O':
|
|
{
|
|
QByteArray *O = va_arg( args, QByteArray * );
|
|
struct berval *bv;
|
|
ret = ber_scanf( d->mBer, fmt, &bv );
|
|
if ( ret != -1 ) {
|
|
*O = QByteArray( bv->bv_val, bv->bv_len );
|
|
ber_bvfree( bv );
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
case 'm': //the same as 'O', just *bv should not be freed.
|
|
{
|
|
QByteArray *m = va_arg( args, QByteArray * );
|
|
struct berval *bv;
|
|
ret = ber_scanf( d->mBer, fmt, &bv );
|
|
if ( ret != -1 ) {
|
|
*m = QByteArray( bv->bv_val, bv->bv_len );
|
|
}
|
|
break;
|
|
}
|
|
case 'a':
|
|
{
|
|
QByteArray *a = va_arg( args, QByteArray * );
|
|
char *c;
|
|
ret = ber_scanf( d->mBer, fmt, &c );
|
|
if ( ret != -1 ) {
|
|
*a = QByteArray( c );
|
|
ber_memfree( c );
|
|
}
|
|
break;
|
|
}
|
|
|
|
case 's':
|
|
{
|
|
QByteArray *s = va_arg( args, QByteArray * );
|
|
char buf[255];
|
|
ber_len_t l = sizeof( buf );
|
|
ret = ber_scanf( d->mBer, fmt, &buf, &l );
|
|
if ( ret != -1 ) {
|
|
*s = QByteArray( buf, l );
|
|
}
|
|
break;
|
|
}
|
|
case 't':
|
|
case 'T':
|
|
{
|
|
unsigned int *t = va_arg( args, unsigned int * );
|
|
ret = ber_scanf( d->mBer, fmt, t );
|
|
break;
|
|
}
|
|
break;
|
|
case 'v':
|
|
{
|
|
QList<QByteArray> *v = va_arg( args, QList<QByteArray> * );
|
|
char **c, **c2;
|
|
ret = ber_scanf( d->mBer, fmt, &c );
|
|
if ( ret != -1 && c ) {
|
|
c2 = c;
|
|
while ( *c ) {
|
|
v->append( QByteArray( *c ) );
|
|
ber_memfree( *c );
|
|
c++;
|
|
}
|
|
ber_memfree( (char *) c2 );
|
|
}
|
|
break;
|
|
}
|
|
case 'V':
|
|
{
|
|
QList<QByteArray> *v = va_arg( args, QList<QByteArray> * );
|
|
struct berval **bv, **bv2;
|
|
ret = ber_scanf( d->mBer, fmt, &bv );
|
|
if ( ret != -1 && bv ) {
|
|
bv2 = bv;
|
|
while ( *bv ) {
|
|
v->append( QByteArray( ( *bv )->bv_val, ( *bv )->bv_len ) );
|
|
bv++;
|
|
}
|
|
ber_bvecfree( bv2 );
|
|
}
|
|
break;
|
|
}
|
|
case 'x':
|
|
case 'n':
|
|
case '{':
|
|
case '}':
|
|
case '[':
|
|
case ']':
|
|
ret = ber_scanf( d->mBer, fmt );
|
|
break;
|
|
default:
|
|
kWarning() << "Invalid BER format parameter: '" << fmt << "'";
|
|
ret = -1;
|
|
}
|
|
|
|
kDebug() << "ber_scanf format:" << fmt << "ret:" << ret;
|
|
if ( ret == -1 ) {
|
|
break;
|
|
}
|
|
|
|
}
|
|
va_end( args );
|
|
return ret;
|
|
}
|
|
|
|
unsigned int Ber::peekTag( int &size )
|
|
{
|
|
unsigned int ret;
|
|
ber_len_t len;
|
|
ret = ber_peek_tag( d->mBer, &len );
|
|
size = len;
|
|
return ret;
|
|
}
|
|
|
|
unsigned int Ber::skipTag( int &size )
|
|
{
|
|
unsigned int ret;
|
|
ber_len_t len;
|
|
ret = ber_skip_tag( d->mBer, &len );
|
|
size = len;
|
|
return ret;
|
|
}
|
|
#else
|
|
|
|
Ber::Ber()
|
|
: d( new BerPrivate )
|
|
{
|
|
kError() << "LDAP support not compiled";
|
|
}
|
|
|
|
Ber::Ber( const QByteArray & )
|
|
: d( new BerPrivate )
|
|
{
|
|
kError() << "LDAP support not compiled";
|
|
}
|
|
|
|
Ber::~Ber()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
Ber::Ber( const Ber & )
|
|
: d( new BerPrivate )
|
|
{
|
|
kError() << "LDAP support not compiled";
|
|
}
|
|
|
|
Ber &Ber::operator=( const Ber &that )
|
|
{
|
|
if ( this == &that ) {
|
|
return *this;
|
|
}
|
|
kError() << "LDAP support not compiled";
|
|
return *this;
|
|
}
|
|
|
|
QByteArray Ber::flatten() const
|
|
{
|
|
kError() << "LDAP support not compiled";
|
|
return QByteArray();
|
|
}
|
|
|
|
int Ber::printf( const QString &format, ... )
|
|
{
|
|
Q_UNUSED( format );
|
|
kError() << "LDAP support not compiled";
|
|
return -1;
|
|
}
|
|
|
|
int Ber::scanf( const QString &format, ... )
|
|
{
|
|
Q_UNUSED( format );
|
|
kError() << "LDAP support not compiled";
|
|
return -1;
|
|
}
|
|
|
|
unsigned int Ber::peekTag( int &size )
|
|
{
|
|
Q_UNUSED( size );
|
|
kError() << "LDAP support not compiled";
|
|
return 0;
|
|
}
|
|
|
|
unsigned int Ber::skipTag( int &size )
|
|
{
|
|
Q_UNUSED( size );
|
|
kError() << "LDAP support not compiled";
|
|
return 0;
|
|
}
|
|
|
|
#endif
|