xldaplite.cpp

00001 /*
00002   This file is part of the KDE libraries
00003   Copyright (c) 2005 Willem Verschuur <willverschuur@yahoo.com>
00004   Copyright (c) 2006 Helio Chissini de Castro <helio@kde.org>
00005 
00006   This library is free software; you can redistribute it and/or
00007   modify it under the terms of the GNU Library General Public
00008   License as published by the Free Software Foundation; either
00009   version 2 of the License, or (at your option) any later version.
00010 
00011   This library is distributed in the hope that it will be useful,
00012   but WITHOUT ANY WARRANTY; without even the implied warranty of
00013   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014   Library General Public License for more details.
00015 
00016   You should have received a copy of the GNU Library General Public License
00017   along with this library; see the file COPYING.LIB.  If not, write to
00018   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019   Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include <qfile.h>
00023 #include <qmap.h>
00024 #include <qregexp.h>
00025 #include <unistd.h>
00026 #include <iostream>
00027 
00028 #include "xldaplite.h"
00029 
00030 #ifndef LDAP_CONF
00031 #define LDAP_CONF "/etc/ldap.conf"
00032 #endif
00033 
00034 #ifndef LDAP_SECRET
00035 #define LDAP_SECRET "/etc/ldap.secret"
00036 #endif
00037 
00038 xLDAPconnection::xLDAPconnection()
00039 {
00040     
00041     m_Connection = 0;
00042     
00043 }
00044 
00045 
00046 
00047 xLDAPconnection::~xLDAPconnection()
00048 {
00049     if (m_Connection)
00050     {
00051         disconnect();
00052     }
00053 }
00054 
00055 
00056 
00057 bool xLDAPconnection::connect()
00058 {
00059 
00060     // close existing connection
00061     if (m_Connection)
00062     {
00063         disconnect();
00064     }
00065 
00066     QFile conf(LDAP_CONF);
00067     QMap<QString,QString> config;
00068   
00069     if (!conf.open(IO_ReadOnly)) 
00070     {
00071         //std::cerr << "Cannot open " << LDAP_CONF << std::endl;
00072         return false;
00073     }
00074 
00075     QTextStream confs(&conf);
00076     
00077     while (!confs.atEnd()) 
00078     {
00079         QString line = confs.readLine();
00080         if (line.contains(QRegExp("^\\s*[a-z]+\\s+.+"))) 
00081         {
00082             QStringList strs=QStringList::split(QRegExp("\\s+"),line);
00083             config[strs[0]] = strs[1];
00084         }
00085     }
00086     
00087     if (geteuid()==0) 
00088     {
00089         
00090         QFile secretFile( LDAP_SECRET );
00091         
00092         if (!secretFile.open(IO_ReadOnly)) 
00093         {
00094             std::cerr << "Cannot find " << LDAP_SECRET << std::endl; 
00095             return false;
00096         }
00097         
00098         QTextStream secretStream(&secretFile);
00099         m_RootPassword = secretStream.readLine();
00100         
00101     }
00102 
00103     // configure parameters 
00104     QString host = config["host"];
00105     int port = 389;
00106     
00107     if (config.contains("port")) 
00108     {
00109         port = config["port"].toInt();
00110     }
00111     
00112     // create ldap connection
00113     m_Connection = ldap_init(host.latin1(), port);
00114 
00115     if (!m_Connection) return false;
00116 
00117     int version = LDAP_VERSION3;
00118     
00119     if (config.contains("ldap_version"))
00120         version = config["ldap_version"].toInt();
00121    
00122     // configure connection
00123     int ret;
00124     if ((ret = ldap_set_option(m_Connection, LDAP_OPT_PROTOCOL_VERSION, &version)) != LDAP_SUCCESS) 
00125     {
00126         std::cerr << "ldap_set_option" << ldap_err2string(ret) << std::endl;
00127         return false;
00128     } 
00129 
00130     // root binding
00131     if (getuid==0 && config.contains("rootbinddn")) 
00132     {
00133         if ( LDAP_SUCCESS != ldap_bind_s( m_Connection,
00134                                           config["rootbinddn"].latin1(),
00135                                           m_RootPassword.latin1(), 
00136                                           LDAP_AUTH_SIMPLE ) )
00137         {
00138             std::cerr << "Root bind failed" << std::endl;
00139             return false;
00140         }
00141         // should be utf8....
00142     } 
00143     else 
00144     {
00145         if (LDAP_SUCCESS != (ret = ldap_simple_bind_s(m_Connection,NULL,NULL)))
00146         {
00147             std::cerr << "Anonymous bind failed" << std::endl;
00148             return false;
00149         }
00150         // there are also SASL, and kerberos
00151     }
00152     
00153     // configure scope
00154     m_Scope = LDAP_SCOPE_SUBTREE;
00155     
00156     if (config.contains("scope")) 
00157     {
00158         if (config["scope"] == "sub");
00159         else if (config["scope"] == "one")
00160             m_Scope = LDAP_SCOPE_ONELEVEL;
00161         else if (config["scope"] == "base")
00162             m_Scope = LDAP_SCOPE_BASE;
00163         else 
00164         {
00165             std::cerr << "bad value for scope in ldap.conf: " << config["scope"].latin1() << std::endl;
00166             return false;
00167         }
00168     }
00169     
00170     // configure base
00171     if (!config.contains("base")) 
00172     {
00173         std::cerr << "base is not defined in ldap.conf" << std::endl;
00174         return false;
00175     }
00176     
00177     m_Base = config["base"];
00178 
00179     // return successful
00180     return true;
00181 
00182 }
00183 
00184 
00185 
00186 void xLDAPconnection::disconnect()
00187 {
00188 
00189     // the connection doesnt exist
00190     if (!m_Connection) return;
00191 
00192     // drop connection
00193     ldap_unbind(m_Connection);
00194     m_Connection = 0;
00195 
00196     return;
00197 
00198 }
00199 
00200 
00201 
00202 xLDAPquery::xLDAPquery( xLDAPconnection& connection,
00203                         const QString& filter,
00204                         const QString& pbasedn,
00205                         char** attributes )
00206 {
00207 
00208     // initialize vars
00209     QString basedn;
00210     
00211     if (pbasedn.isNull())
00212     {
00213         basedn = connection.m_Base;
00214     }
00215     else
00216     {
00217         basedn = pbasedn;
00218     }
00219     
00220     m_Connection = &connection;
00221 
00222     // execute search
00223     m_Result = ldap_search_s(   m_Connection->m_Connection,
00224                                 basedn.latin1(),
00225                                 m_Connection->m_Scope,
00226                                 filter.latin1(),   
00227                                 attributes,
00228                                 0, // return attrs & values
00229                                 &m_Query   );
00230 
00231     // output an error if query failed
00232     //if (m_Result != LDAP_SUCCESS) 
00233         //std::cerr << "ldap_search: " << ldap_err2string(m_Result) << std::endl;
00234 
00235 }
00236 
00237 
00238 
00239 xLDAPquery::~xLDAPquery()
00240 {
00241     if (m_Query)
00242     {
00243         ldap_msgfree(m_Query);
00244         m_Query = 0;
00245     }
00246 }
00247 
00248 
00249 
00250 xLDAPiterator::xLDAPiterator(xLDAPquery& query)
00251 {
00252     
00253     // initialize vars
00254     m_Query = &query;
00255     m_Entry = 0;   // used by element iterator (this)
00256     m_Element = 0; // used by attribute iterator
00257 
00258     // fix error handling 
00259     // if (!m_Connection) return false;
00260     // if (!m_Message) return false;
00261     
00262     // point to first element in query result
00263     m_Entry = ldap_first_entry(m_Query->m_Connection->m_Connection, m_Query->m_Query);
00264     
00265 }
00266 
00267 
00268 
00269 xLDAPiterator::~xLDAPiterator()
00270 {
00271 
00272     clearElement();
00273 }
00274 
00275 
00276 
00277 void xLDAPiterator::clearElement()
00278 {
00279 
00280     if (m_Element)
00281     {
00282         ber_free(m_Element, 0);
00283         m_Element = 0;
00284     }
00285 
00286 }
00287 
00288 
00289 
00290 xLDAPiterator::operator bool ()
00291 {
00292     return (m_Entry != 0);
00293 }
00294 
00295 
00296 
00297 void xLDAPiterator::operator ++ ()
00298 {
00299     m_Entry = ldap_next_entry(m_Query->m_Connection->m_Connection, m_Entry);
00300 }
00301 
00302 
00303 
00304 xLDAPattribute::xLDAPattribute(xLDAPiterator& iter)
00305 {
00306 
00307     // initialize class vars
00308     m_Iterator = &iter;
00309     m_Attribute = 0;
00310     m_Values = 0;
00311     m_CurrentValue = 0;
00312 
00313     // free previous element's attribute data 
00314     if (m_Iterator->m_Element)
00315     {
00316         m_Iterator->clearElement();
00317     }
00318 
00319     // get first attribute
00320     m_Attribute = ldap_first_attribute( m_Iterator->m_Query->m_Connection->m_Connection, 
00321                                         m_Iterator->m_Entry, 
00322                                         &m_Iterator->m_Element);
00323 
00324 }
00325 
00326 
00327 
00328 xLDAPattribute::~xLDAPattribute()
00329 {
00330     clearAttribute();
00331 }
00332 
00333 
00334 
00335 void xLDAPattribute::clearAttribute()
00336 {
00337 
00338     if (m_Attribute)
00339     {
00340         ldap_memfree(m_Attribute);
00341         m_Attribute = 0;
00342     }
00343     
00344     if (m_Values)
00345     {
00346         clearValues();
00347     }
00348 
00349 }
00350 
00351 
00352 
00353 xLDAPattribute::operator bool ()
00354 {
00355     return (m_Attribute != 0);
00356 }
00357 
00358 
00359 
00360 void xLDAPattribute::operator ++ ()
00361 {
00362 
00363     clearAttribute();
00364     m_Attribute = ldap_next_attribute( m_Iterator->m_Query->m_Connection->m_Connection, 
00365                                        m_Iterator->m_Entry, 
00366                                        m_Iterator->m_Element );
00367 
00368 }
00369 
00370 
00371 
00372 const char* xLDAPattribute::firstValue()
00373 {
00374     if (m_Values)
00375     {
00376         clearValues();
00377     }
00378 
00379     m_Values = ldap_get_values (  m_Iterator->m_Query->m_Connection->m_Connection, 
00380                                   m_Iterator->m_Entry, 
00381                                   m_Attribute );
00382 
00383     m_CurrentValue = m_Values;
00384     return *m_CurrentValue;
00385 }
00386 
00387 
00388 const char* xLDAPattribute::nextValue()
00389 {
00390     m_CurrentValue++;
00391     return *m_CurrentValue;
00392 }
00393 
00394 
00395 
00396 void xLDAPattribute::clearValues()
00397 {
00398     if (m_Values)
00399     {
00400         ldap_value_free(m_Values);
00401         m_Values = 0;
00402     }
00403 }
00404 
KDE Home | KDE Accessibility Home | Description of Access Keys