00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
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 Bind(
00117       const PString & who = PString::Empty(),
00118       const PString & passwd = PString::Empty(),
00119       AuthenticationMethod authMethod = AuthSimple
00120     );
00121 
00122     class ModAttrib : public PObject {
00123         PCLASSINFO(ModAttrib, PObject);
00124       public:
00125         enum Operation {
00126           Add,
00127           Replace,
00128           Delete,
00129           NumOperations
00130         };
00131 
00132       protected:
00133         ModAttrib(
00134           const PString & name,
00135           Operation op = NumOperations
00136         );
00137 
00138       public:
00139         const PString & GetName() const { return name; }
00140 
00141         Operation GetOperation() const { return op; }
00142 
00143         void SetLDAPMod(
00144           struct ldapmod & mod,
00145           Operation defaultOp
00146         );
00147 
00148       protected:
00149         virtual PBoolean IsBinary() const = 0;
00150         virtual void SetLDAPModVars(struct ldapmod & mod) = 0;
00151 
00152         PString   name;
00153         Operation op;
00154     };
00155 
00156     class StringModAttrib : public ModAttrib {
00157         PCLASSINFO(StringModAttrib, ModAttrib);
00158       public:
00159         StringModAttrib(
00160           const PString & name,
00161           Operation op = NumOperations
00162         );
00163         StringModAttrib(
00164           const PString & name,
00165           const PString & value,
00166           Operation op = NumOperations
00167         );
00168         StringModAttrib(
00169           const PString & name,
00170           const PStringList & values,
00171           Operation op = NumOperations
00172         );
00173         void SetValue(
00174           const PString & value
00175         );
00176         void AddValue(
00177           const PString & value
00178         );
00179       protected:
00180         virtual PBoolean IsBinary() const;
00181         virtual void SetLDAPModVars(struct ldapmod & mod);
00182 
00183         PStringArray values;
00184         PBaseArray<char *> pointers;
00185     };
00186 
00187     class BinaryModAttrib : public ModAttrib {
00188         PCLASSINFO(BinaryModAttrib, ModAttrib);
00189       public:
00190         BinaryModAttrib(
00191           const PString & name,
00192           Operation op = Add
00193         );
00194         BinaryModAttrib(
00195           const PString & name,
00196           const PBYTEArray & value,
00197           Operation op = Add
00198         );
00199         BinaryModAttrib(
00200           const PString & name,
00201           const PArray<PBYTEArray> & values,
00202           Operation op = Add
00203         );
00204         void SetValue(
00205           const PBYTEArray & value
00206         );
00207         void AddValue(
00208           const PBYTEArray & value
00209         );
00210       protected:
00211         virtual PBoolean IsBinary() const;
00212         virtual void SetLDAPModVars(struct ldapmod & mod);
00213 
00214         PArray<PBYTEArray> values;
00215         PBaseArray<struct berval *> pointers;
00216         PBYTEArray bervals;
00217     };
00218 
00221     PBoolean Add(
00222       const PString & dn,
00223       const PArray<ModAttrib> & attributes
00224     );
00225 
00228     PBoolean Add(
00229       const PString & dn,
00230       const PStringToString & attributes
00231     );
00232 
00236     PBoolean Add(
00237       const PString & dn,
00238       const PStringArray & attributes
00239     );
00240 
00244     PBoolean Add(
00245       const PString & dn,
00246       const PLDAPStructBase & data
00247     );
00248 
00251     PBoolean Modify(
00252       const PString & dn,
00253       const PArray<ModAttrib> & attributes
00254     );
00255 
00258     PBoolean Modify(
00259       const PString & dn,
00260       const PStringToString & attributes
00261     );
00262 
00266     PBoolean Modify(
00267       const PString & dn,
00268       const PStringArray & attributes
00269     );
00270 
00274     PBoolean Modify(
00275       const PString & dn,
00276       const PLDAPStructBase & data
00277     );
00278 
00281     PBoolean Delete(
00282       const PString & dn
00283     );
00284 
00285 
00286     enum SearchScope {
00287       ScopeBaseOnly,
00288       ScopeSingleLevel,
00289       ScopeSubTree,
00290       NumSearchScope
00291     };
00292 
00293     class SearchContext {
00294       public:
00295         SearchContext();
00296         ~SearchContext();
00297 
00298         PBoolean IsCompleted() const { return completed; }
00299 
00300       private:
00301         int              msgid;
00302         struct ldapmsg * result;
00303         struct ldapmsg * message;
00304         PBoolean             found;
00305         PBoolean             completed;
00306 
00307       friend class PLDAPSession;
00308     };
00309 
00312     PBoolean Search(
00313       SearchContext & context,
00314       const PString & filter,
00315       const PStringArray & attributes = PStringList(),
00316       const PString & base = PString::Empty(),
00317       SearchScope scope = ScopeSubTree
00318     );
00319 
00322     PBoolean GetSearchResult(
00323       SearchContext & context,
00324       PStringToString & data
00325     );
00326 
00329     PBoolean GetSearchResult(
00330       SearchContext & context,
00331       const PString & attribute,
00332       PString & data
00333     );
00334 
00337     PBoolean GetSearchResult(
00338       SearchContext & context,
00339       const PString & attribute,
00340       PStringArray & data
00341     );
00342 
00345     PBoolean GetSearchResult(
00346       SearchContext & context,
00347       const PString & attribute,
00348       PArray<PBYTEArray> & data
00349     );
00350 
00353     PBoolean GetSearchResult(
00354       SearchContext & context,
00355       PLDAPStructBase & data
00356     );
00357 
00360     PString GetSearchResultDN(
00361       SearchContext & context
00362     );
00363 
00366     PBoolean GetNextSearchResult(
00367       SearchContext & context
00368     );
00369 
00374     PList<PStringToString> Search(
00375       const PString & filter,
00376       const PStringArray & attributes = PStringList(),
00377       const PString & base = PString::Empty(),
00378       SearchScope scope = ScopeSubTree
00379     );
00380 
00381 
00384     void SetBaseDN(
00385       const PString & dn
00386     ) { defaultBaseDN = dn; }
00387 
00390     const PString & GetBaseDN() const { return defaultBaseDN; }
00391 
00394     int GetErrorNumber() const { return errorNumber; }
00395 
00398     PString GetErrorText() const;
00399 
00402     struct ldap * GetOpenLDAP() const { return ldapContext; }
00403 
00406     const PTimeInterval & GetTimeout() const { return timeout; }
00407 
00410     void SetTimeout(
00411       const PTimeInterval & t
00412     ) { timeout = t; }
00413 
00416      void SetSearchLimit(
00417       const unsigned s
00418     ) { searchLimit = s; }
00419 
00420   protected:
00421     struct ldap * ldapContext;
00422     int           errorNumber;
00423     unsigned      protocolVersion;
00424     PString       defaultBaseDN;
00425     unsigned      searchLimit;
00426     PTimeInterval timeout;
00427     PString       multipleValueSeparator;
00428 };
00429 
00430 
00431 
00432 class PLDAPStructBase;
00433 
00434 class PLDAPAttributeBase : public PObject
00435 {
00436     PCLASSINFO(PLDAPAttributeBase, PObject);
00437   public:
00438     PLDAPAttributeBase(const char * name, void * pointer, PINDEX size);
00439 
00440     const char * GetName() const { return name; }
00441     PBoolean IsBinary() const { return pointer != NULL; }
00442 
00443     virtual void Copy(const PLDAPAttributeBase & other) = 0;
00444 
00445     virtual PString ToString() const;
00446     virtual void FromString(const PString & str);
00447     virtual PBYTEArray ToBinary() const;
00448     virtual void FromBinary(const PArray<PBYTEArray> & data);
00449 
00450   protected:
00451     const char * name;
00452     void       * pointer;
00453     PINDEX       size;
00454 };
00455 
00456 
00457 class PLDAPStructBase : public PObject {
00458     PCLASSINFO(PLDAPStructBase, PObject);
00459   protected:
00460     PLDAPStructBase();
00461     PLDAPStructBase & operator=(const PLDAPStructBase &);
00462     PLDAPStructBase & operator=(const PStringArray & array);
00463     PLDAPStructBase & operator=(const PStringToString & dict);
00464   private:
00465     PLDAPStructBase(const PLDAPStructBase &) { }
00466 
00467   public:
00468     void PrintOn(ostream & strm) const;
00469 
00470     PINDEX GetNumAttributes() const { return attributes.GetSize(); }
00471     PLDAPAttributeBase & GetAttribute(PINDEX idx) const { return attributes.GetDataAt(idx); }
00472     PLDAPAttributeBase * GetAttribute(const char * name) const { return attributes.GetAt(name); }
00473 
00474     void AddAttribute(PLDAPAttributeBase * var);
00475     static PLDAPStructBase & GetInitialiser() { return *PAssertNULL(initialiserInstance); }
00476 
00477   protected:
00478     void EndConstructor();
00479 
00480     PDictionary<PString, PLDAPAttributeBase> attributes;
00481 
00482     PLDAPStructBase        * initialiserStack;
00483     static PMutex            initialiserMutex;
00484     static PLDAPStructBase * initialiserInstance;
00485 };
00486 
00488 
00489 class PLDAPSchema : public PObject
00490 {
00491   public:
00492     PLDAPSchema();
00493 
00494     enum AttributeType {
00495         AttibuteUnknown = -1,
00496         AttributeString,
00497         AttributeBinary,
00498         AttributeNumeric
00499     };
00500 
00501     class Attribute
00502     {
00503     public:
00504         Attribute() : m_type(AttibuteUnknown) { }
00505         Attribute(const PString & name, AttributeType type);
00506         PString       m_name;
00507         AttributeType m_type;
00508     };
00509 
00510     typedef std::list<Attribute> attributeList;
00511 
00512     static PLDAPSchema * CreateSchema(const PString & schemaname, PPluginManager * pluginMgr = NULL);
00513     static PStringList GetSchemaNames(PPluginManager * pluginMgr = NULL);
00514     static PStringList GetSchemaFriendlyNames(const PString & schema, PPluginManager * pluginMgr = NULL);
00515 
00516     void OnReceivedAttribute(const PString & attribute, const PString & value);
00517 
00518     void OnSendSchema(PArray<PLDAPSession::ModAttrib> & attributes,
00519         PLDAPSession::ModAttrib::Operation op=PLDAPSession::ModAttrib::Add);
00520 
00521     void LoadSchema();
00522 
00523     PStringList SchemaName() { return PStringList(); }
00524     virtual void AttributeList(attributeList & ) {};
00525 
00526 
00527     PStringList GetAttributeList();
00528     PBoolean Exists(const PString & attribute);
00529 
00530     PBoolean SetAttribute(const PString & attribute, const PString & value);
00531     PBoolean SetAttribute(const PString & attribute, const PBYTEArray & value);
00532 
00533     PBoolean GetAttribute(const PString & attribute, PString & value);
00534     PBoolean GetAttribute(const PString & attribute, PBYTEArray & value);
00535 
00536     AttributeType GetAttributeType(const PString & attribute);
00537 
00538 
00539   protected:
00540     typedef std::map<PString,PString> ldapAttributes;
00541     typedef std::map<PString,PBYTEArray> ldapBinAttributes;
00542 
00543 
00544     attributeList           attributelist;
00545     ldapAttributes          attributes;
00546     ldapBinAttributes       binattributes;   
00547 };
00548 
00549 
00550 template <class className> class LDAPPluginServiceDescriptor : public PDevicePluginServiceDescriptor
00551 {
00552   public:
00553     virtual PObject *    CreateInstance(int ) const { return new className; }
00554     virtual PStringArray GetDeviceNames(int ) const { return className::SchemaName(); } 
00555 };
00556 
00557 #define LDAP_Schema(name)    \
00558   static LDAPPluginServiceDescriptor<name##_schema> name##_schema_descriptor; \
00559   PCREATE_PLUGIN(name##_schema, PLDAPSchema, &name##_schema_descriptor); \
00560   PWLIB_STATIC_LOAD_PLUGIN(name##_schema, PLDAPSchema); \
00561 
00563 
00564 #define PLDAP_STRUCT_BEGIN(name) \
00565   class name : public PLDAPStructBase { \
00566     public: name() : PLDAPStructBase() { EndConstructor(); } \
00567     public: name(const name & other) : PLDAPStructBase() { EndConstructor(); operator=(other); } \
00568     public: name(const PStringArray & array) : PLDAPStructBase() { EndConstructor(); operator=(array); } \
00569     public: name(const PStringToString & dict) : PLDAPStructBase() { EndConstructor(); operator=(dict); } \
00570     public: name & operator=(const name & other) { PLDAPStructBase::operator=(other); return *this; } \
00571     public: name & operator=(const PStringArray & array) { PLDAPStructBase::operator=(array); return *this; } \
00572     public: name & operator=(const PStringToString & dict) { PLDAPStructBase::operator=(dict); return *this; } \
00573     PLDAP_ATTR_INIT(name, PString, objectClass, #name);
00574 
00575 #define PLDAP_ATTRIBUTE(base, type, attribute, pointer, init) \
00576     public: type attribute; \
00577     private: struct PLDAPAttr_##attribute : public PLDAPAttributeBase { \
00578       PLDAPAttr_##attribute() \
00579         : PLDAPAttributeBase(#attribute, pointer, sizeof(type)), \
00580           instance(((base &)base::GetInitialiser()).attribute) \
00581         { init } \
00582       virtual void PrintOn (ostream & s) const { s << instance; } \
00583       virtual void ReadFrom(istream & s)       { s >> instance; } \
00584       virtual void Copy(const PLDAPAttributeBase & other) \
00585                     { instance = ((PLDAPAttr_##attribute &)other).instance; } \
00586       type & instance; \
00587     } pldapvar_##attribute
00588 
00589 #define PLDAP_ATTR_SIMP(base, type, attribute) \
00590         PLDAP_ATTRIBUTE(base, type, attribute, NULL, ;)
00591 
00592 #define PLDAP_ATTR_INIT(base, type, attribute, init) \
00593         PLDAP_ATTRIBUTE(base, type, attribute, NULL, instance = init;)
00594 
00595 #define PLDAP_BINATTRIB(base, type, attribute) \
00596         PLDAP_ATTRIBUTE(base, type, attribute, &((base &)base::GetInitialiser()).attribute, ;)
00597 
00598 #define PLDAP_STRUCT_END() \
00599   };
00600 
00601 #endif // P_LDAP
00602 
00603 #endif // PTLIB_PLDAP_H
00604 
00605 
00606