# pldap.h

Go to the documentation of this file.

    00001 /*
    00002  * pldap.h
    00003  *
    00004  * Lightweight Directory Access Protocol interface class.
    00005  *
    00006  * Portable Windows Library
    00007  *
    00008  * Copyright (c) 1993-2003 Equivalence Pty. Ltd.
    00009  *
    00010  * The contents of this file are subject to the Mozilla Public License
    00011  * Version 1.0 (the "License"); you may not use this file except in
    00012  * compliance with the License. You may obtain a copy of the License at
    00013  * http://www.mozilla.org/MPL/
    00014  *
    00015  * Software distributed under the License is distributed on an "AS IS"
    00016  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
    00017  * the License for the specific language governing rights and limitations
    00018  * under the License.
    00019  *
    00020  * The Original Code is Portable Windows Library.
    00021  *
    00022  * The Initial Developer of the Original Code is Equivalence Pty. Ltd.
    00023  *
    00024  * Contributor(s): ______________________________________.
    00025  *
    00026  * $Revision: 27535 $
    00027  * $Author: rjongbloed $
    00028  * $Date: 2012-04-26 02:48:22 -0500 (Thu, 26 Apr 2012) $
    00029  */
    00030
    00031 #ifndef PTLIB_PLDAP_H
    00032 #define PTLIB_PLDAP_H
    00033
    00034 #ifdef P_USE_PRAGMA
    00035 #pragma interface
    00036 #endif
    00037
    00038 #if defined(P_LDAP) && !defined(_WIN32_WCE)
    00039
    00040 #include <ptlib/sockets.h>
    00041 #include <ptlib/pluginmgr.h>
    00042 #include <map>
    00043 #include <list>
    00044
    00045 struct ldap;
    00046 struct ldapmsg;
    00047 struct ldapmod;
    00048 struct berval;
    00049
    00050 class PLDAPStructBase;
    00051
    00052
    00055 class PLDAPSession : public PObject
    00056 {
    00057   PCLASSINFO(PLDAPSession, PObject);
    00058   public:
    00061     PLDAPSession(
    00062       const PString & defaultBaseDN = PString::Empty()
    00063     );
    00064
    00067     ~PLDAPSession();
    00068
    00075     PBoolean Open(
    00076       const PString & server,
    00077       WORD port = 0
    00078     );
    00079
    00082     PBoolean Close();
    00083
    00086     PBoolean IsOpen() const { return ldapContext != NULL; }
    00087
    00090     PBoolean SetOption(
    00091       int optcode,
    00092       int value
    00093     );
    00094
    00097     PBoolean SetOption(
    00098       int optcode,
    00099       void * value
    00100     );
    00101
    00102     enum AuthenticationMethod {
    00103       AuthSimple,
    00104       AuthSASL,
    00105       AuthKerberos,
    00106 #ifdef SOLARIS
    00107       NumAuthenticationMethod1,
    00108       NumAuthenticationMethod2
    00109 #else
    00110       NumAuthenticationMethod
    00111 #endif
    00112     };
    00113
    00116     PBoolean StartTLS();
    00117
    00120     PBoolean Bind(
    00121       const PString & who = PString::Empty(),
    00122       const PString & passwd = PString::Empty(),
    00123       AuthenticationMethod authMethod = AuthSimple
    00124     );
    00125
    00126     class ModAttrib : public PObject {
    00127         PCLASSINFO(ModAttrib, PObject);
    00128       public:
    00129         enum Operation {
    00130           Add,
    00131           Replace,
    00132           Delete,
    00133           NumOperations
    00134         };
    00135
    00136       protected:
    00137         ModAttrib(
    00138           const PString & name,
    00139           Operation op = NumOperations
    00140         );
    00141
    00142       public:
    00143         const PString & GetName() const { return name; }
    00144
    00145         Operation GetOperation() const { return op; }
    00146
    00147         void SetLDAPMod(
    00148           struct ldapmod & mod,
    00149           Operation defaultOp
    00150         );
    00151
    00152       protected:
    00153         virtual PBoolean IsBinary() const = 0;
    00154         virtual void SetLDAPModVars(struct ldapmod & mod) = 0;
    00155
    00156         PString   name;
    00157         Operation op;
    00158     };
    00159
    00160     class StringModAttrib : public ModAttrib {
    00161         PCLASSINFO(StringModAttrib, ModAttrib);
    00162       public:
    00163         StringModAttrib(
    00164           const PString & name,
    00165           Operation op = NumOperations
    00166         );
    00167         StringModAttrib(
    00168           const PString & name,
    00169           const PString & value,
    00170           Operation op = NumOperations
    00171         );
    00172         StringModAttrib(
    00173           const PString & name,
    00174           const PStringList & values,
    00175           Operation op = NumOperations
    00176         );
    00177         void SetValue(
    00178           const PString & value
    00179         );
    00180         void AddValue(
    00181           const PString & value
    00182         );
    00183       protected:
    00184         virtual PBoolean IsBinary() const;
    00185         virtual void SetLDAPModVars(struct ldapmod & mod);
    00186
    00187         PStringArray values;
    00188         PBaseArray<char *> pointers;
    00189     };
    00190
    00191     class BinaryModAttrib : public ModAttrib {
    00192         PCLASSINFO(BinaryModAttrib, ModAttrib);
    00193       public:
    00194         BinaryModAttrib(
    00195           const PString & name,
    00196           Operation op = Add
    00197         );
    00198         BinaryModAttrib(
    00199           const PString & name,
    00200           const PBYTEArray & value,
    00201           Operation op = Add
    00202         );
    00203         BinaryModAttrib(
    00204           const PString & name,
    00205           const PArray<PBYTEArray> & values,
    00206           Operation op = Add
    00207         );
    00208         void SetValue(
    00209           const PBYTEArray & value
    00210         );
    00211         void AddValue(
    00212           const PBYTEArray & value
    00213         );
    00214       protected:
    00215         virtual PBoolean IsBinary() const;
    00216         virtual void SetLDAPModVars(struct ldapmod & mod);
    00217
    00218         PArray<PBYTEArray> values;
    00219         PBaseArray<struct berval *> pointers;
    00220         PBYTEArray bervals;
    00221     };
    00222
    00225     PBoolean Add(
    00226       const PString & dn,
    00227       const PArray<ModAttrib> & attributes
    00228     );
    00229
    00232     PBoolean Add(
    00233       const PString & dn,
    00234       const PStringToString & attributes
    00235     );
    00236
    00240     PBoolean Add(
    00241       const PString & dn,
    00242       const PStringArray & attributes
    00243     );
    00244
    00248     PBoolean Add(
    00249       const PString & dn,
    00250       const PLDAPStructBase & data
    00251     );
    00252
    00255     PBoolean Modify(
    00256       const PString & dn,
    00257       const PArray<ModAttrib> & attributes
    00258     );
    00259
    00262     PBoolean Modify(
    00263       const PString & dn,
    00264       const PStringToString & attributes
    00265     );
    00266
    00270     PBoolean Modify(
    00271       const PString & dn,
    00272       const PStringArray & attributes
    00273     );
    00274
    00278     PBoolean Modify(
    00279       const PString & dn,
    00280       const PLDAPStructBase & data
    00281     );
    00282
    00285     PBoolean Delete(
    00286       const PString & dn
    00287     );
    00288
    00289
    00290     enum SearchScope {
    00291       ScopeBaseOnly,
    00292       ScopeSingleLevel,
    00293       ScopeSubTree,
    00294       NumSearchScope
    00295     };
    00296
    00297     class SearchContext {
    00298       public:
    00299         SearchContext();
    00300         ~SearchContext();
    00301
    00302         PBoolean IsCompleted() const { return completed; }
    00303
    00304       private:
    00305         int              msgid;
    00306         struct ldapmsg * result;
    00307         struct ldapmsg * message;
    00308         PBoolean             found;
    00309         PBoolean             completed;
    00310
    00311       friend class PLDAPSession;
    00312     };
    00313
    00316     PBoolean Search(
    00317       SearchContext & context,
    00318       const PString & filter,
    00319       const PStringArray & attributes = PStringList(),
    00320       const PString & base = PString::Empty(),
    00321       SearchScope scope = ScopeSubTree
    00322     );
    00323
    00326     PBoolean GetSearchResult(
    00327       SearchContext & context,
    00328       PStringToString & data
    00329     );
    00330
    00333     PBoolean GetSearchResult(
    00334       SearchContext & context,
    00335       const PString & attribute,
    00336       PString & data
    00337     );
    00338
    00341     PBoolean GetSearchResult(
    00342       SearchContext & context,
    00343       const PString & attribute,
    00344       PStringArray & data
    00345     );
    00346
    00349     PBoolean GetSearchResult(
    00350       SearchContext & context,
    00351       const PString & attribute,
    00352       PArray<PBYTEArray> & data
    00353     );
    00354
    00357     PBoolean GetSearchResult(
    00358       SearchContext & context,
    00359       PLDAPStructBase & data
    00360     );
    00361
    00364     PString GetSearchResultDN(
    00365       SearchContext & context
    00366     );
    00367
    00370     PBoolean GetNextSearchResult(
    00371       SearchContext & context
    00372     );
    00373
    00378     PList<PStringToString> Search(
    00379       const PString & filter,
    00380       const PStringArray & attributes = PStringList(),
    00381       const PString & base = PString::Empty(),
    00382       SearchScope scope = ScopeSubTree
    00383     );
    00384
    00385
    00388     void SetBaseDN(
    00389       const PString & dn
    00390     ) { defaultBaseDN = dn; }
    00391
    00394     const PString & GetBaseDN() const { return defaultBaseDN; }
    00395
    00398     int GetErrorNumber() const { return errorNumber; }
    00399
    00402     PString GetErrorText() const;
    00403
    00406     struct ldap * GetOpenLDAP() const { return ldapContext; }
    00407
    00410     const PTimeInterval & GetTimeout() const { return timeout; }
    00411
    00414     void SetTimeout(
    00415       const PTimeInterval & t
    00416     ) { timeout = t; }
    00417
    00420      void SetSearchLimit(
    00421       const unsigned s
    00422     ) { searchLimit = s; }
    00423
    00424   protected:
    00425     struct ldap * ldapContext;
    00426     int           errorNumber;
    00427     unsigned      protocolVersion;
    00428     PString       defaultBaseDN;
    00429     unsigned      searchLimit;
    00430     PTimeInterval timeout;
    00431     PString       multipleValueSeparator;
    00432 };
    00433
    00434
    00435
    00436 class PLDAPStructBase;
    00437
    00438 class PLDAPAttributeBase : public PObject
    00439 {
    00440     PCLASSINFO(PLDAPAttributeBase, PObject);
    00441   public:
    00442     PLDAPAttributeBase(const char * name, void * pointer, PINDEX size);
    00443
    00444     const char * GetName() const { return name; }
    00445     PBoolean IsBinary() const { return pointer != NULL; }
    00446
    00447     virtual void Copy(const PLDAPAttributeBase & other) = 0;
    00448
    00449     virtual PString ToString() const;
    00450     virtual void FromString(const PString & str);
    00451     virtual PBYTEArray ToBinary() const;
    00452     virtual void FromBinary(const PArray<PBYTEArray> & data);
    00453
    00454   protected:
    00455     const char * name;
    00456     void       * pointer;
    00457     PINDEX       size;
    00458 };
    00459
    00460
    00461 class PLDAPStructBase : public PObject {
    00462     PCLASSINFO(PLDAPStructBase, PObject);
    00463   protected:
    00464     PLDAPStructBase();
    00465     PLDAPStructBase & operator=(const PLDAPStructBase &);
    00466     PLDAPStructBase & operator=(const PStringArray & array);
    00467     PLDAPStructBase & operator=(const PStringToString & dict);
    00468   private:
    00469     PLDAPStructBase(const PLDAPStructBase & obj) : PObject(obj) { }
    00470
    00471   public:
    00472     void PrintOn(ostream & strm) const;
    00473
    00474     PINDEX GetNumAttributes() const { return attributes.GetSize(); }
    00475     PLDAPAttributeBase & GetAttribute(PINDEX idx) const { return attributes.GetDataAt(idx); }
    00476     PLDAPAttributeBase * GetAttribute(const char * name) const { return attributes.GetAt(name); }
    00477
    00478     void AddAttribute(PLDAPAttributeBase * var);
    00479     static PLDAPStructBase & GetInitialiser() { return *PAssertNULL(initialiserInstance); }
    00480
    00481   protected:
    00482     void EndConstructor();
    00483
    00484     PDictionary<PString, PLDAPAttributeBase> attributes;
    00485
    00486     PLDAPStructBase        * initialiserStack;
    00487     static PMutex            initialiserMutex;
    00488     static PLDAPStructBase * initialiserInstance;
    00489 };
    00490
    00492
    00493 class PLDAPSchema : public PObject
    00494 {
    00495   public:
    00496     PLDAPSchema();
    00497
    00498     enum AttributeType {
    00499         AttibuteUnknown = -1,
    00500         AttributeString,
    00501         AttributeBinary,
    00502         AttributeNumeric
    00503     };
    00504
    00505     class Attribute
    00506     {
    00507     public:
    00508         Attribute() : m_type(AttibuteUnknown) { }
    00509         Attribute(const PString & name, AttributeType type);
    00510         PString       m_name;
    00511         AttributeType m_type;
    00512     };
    00513
    00514     typedef std::list<Attribute> attributeList;
    00515
    00516     static PLDAPSchema * CreateSchema(const PString & schemaname, PPluginManager * pluginMgr = NULL);
    00517     static PStringList GetSchemaNames(PPluginManager * pluginMgr = NULL);
    00518     static PStringList GetSchemaFriendlyNames(const PString & schema, PPluginManager * pluginMgr = NULL);
    00519
    00520     void OnReceivedAttribute(const PString & attribute, const PString & value);
    00521
    00522     void OnSendSchema(PArray<PLDAPSession::ModAttrib> & attributes,
    00523         PLDAPSession::ModAttrib::Operation op=PLDAPSession::ModAttrib::Add);
    00524
    00525     void LoadSchema();
    00526
    00527     PStringList SchemaName() { return PStringList(); }
    00528     virtual void AttributeList(attributeList & /*attrib*/) {};
    00529
    00530
    00531     PStringList GetAttributeList();
    00532     PBoolean Exists(const PString & attribute);
    00533
    00534     PBoolean SetAttribute(const PString & attribute, const PString & value);
    00535     PBoolean SetAttribute(const PString & attribute, const PBYTEArray & value);
    00536
    00537     PBoolean GetAttribute(const PString & attribute, PString & value);
    00538     PBoolean GetAttribute(const PString & attribute, PBYTEArray & value);
    00539
    00540     AttributeType GetAttributeType(const PString & attribute);
    00541
    00542
    00543   protected:
    00544     typedef std::map<PString,PString> ldapAttributes;
    00545     typedef std::map<PString,PBYTEArray> ldapBinAttributes;
    00546
    00547
    00548     attributeList           attributelist;
    00549     ldapAttributes          attributes;
    00550     ldapBinAttributes       binattributes;
    00551 };
    00552
    00553
    00554 template <class className> class LDAPPluginServiceDescriptor : public PDevicePluginServiceDescriptor
    00555 {
    00556   public:
    00557     virtual PObject *    CreateInstance(int /*userData*/) const { return new className; }
    00558     virtual PStringArray GetDeviceNames(int /*userData*/) const { return className::SchemaName(); }
    00559 };
    00560
    00561 #define LDAP_Schema(name)    \
    00562   static LDAPPluginServiceDescriptor<name##_schema> name##_schema_descriptor; \
    00563   PCREATE_PLUGIN(name##_schema, PLDAPSchema, &name##_schema_descriptor)
    00564
    00566
    00567 #define PLDAP_STRUCT_BEGIN(name) \
    00568   class name : public PLDAPStructBase { \
    00569     public: name() : PLDAPStructBase() { EndConstructor(); } \
    00570     public: name(const name & other) : PLDAPStructBase() { EndConstructor(); operator=(other); } \
    00571     public: name(const PStringArray & array) : PLDAPStructBase() { EndConstructor(); operator=(array); } \
    00572     public: name(const PStringToString & dict) : PLDAPStructBase() { EndConstructor(); operator=(dict); } \
    00573     public: name & operator=(const name & other) { PLDAPStructBase::operator=(other); return *this; } \
    00574     public: name & operator=(const PStringArray & array) { PLDAPStructBase::operator=(array); return *this; } \
    00575     public: name & operator=(const PStringToString & dict) { PLDAPStructBase::operator=(dict); return *this; } \
    00576     PLDAP_ATTR_INIT(name, PString, objectClass, #name);
    00577
    00578 #define PLDAP_ATTRIBUTE(base, type, attribute, pointer, init) \
    00579     public: type attribute; \
    00580     private: struct PLDAPAttr_##attribute : public PLDAPAttributeBase { \
    00581       PLDAPAttr_##attribute() \
    00582         : PLDAPAttributeBase(#attribute, pointer, sizeof(type)), \
    00583           instance(((base &)base::GetInitialiser()).attribute) \
    00584         { init } \
    00585       virtual void PrintOn (ostream & s) const { s << instance; } \
    00586       virtual void ReadFrom(istream & s)       { s >> instance; } \
    00587       virtual void Copy(const PLDAPAttributeBase & other) \
    00588                     { instance = ((PLDAPAttr_##attribute &)other).instance; } \
    00589       type & instance; \
    00590     } pldapvar_##attribute
    00591
    00592 #define PLDAP_ATTR_SIMP(base, type, attribute) \
    00593         PLDAP_ATTRIBUTE(base, type, attribute, NULL, ;)
    00594
    00595 #define PLDAP_ATTR_INIT(base, type, attribute, init) \
    00596         PLDAP_ATTRIBUTE(base, type, attribute, NULL, instance = init;)
    00597
    00598 #define PLDAP_BINATTRIB(base, type, attribute) \
    00599         PLDAP_ATTRIBUTE(base, type, attribute, &((base &)base::GetInitialiser()).attribute, ;)
    00600
    00601 #define PLDAP_STRUCT_END() \
    00602   };
    00603
    00604 #endif // P_LDAP
    00605
    00606 #endif // PTLIB_PLDAP_H
    00607
    00608
    00609 // End of file ////////////////////////////////////////////////////////////////