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
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 #ifndef _PLDAP_H
00074 #define _PLDAP_H
00075
00076 #ifdef P_USE_PRAGMA
00077 #pragma interface
00078 #endif
00079
00080 #if P_LDAP
00081
00082 #include <ptlib/sockets.h>
00083 #include <ptlib/pluginmgr.h>
00084 #include <map>
00085 #include <list>
00086
00087 struct ldap;
00088 struct ldapmsg;
00089 struct ldapmod;
00090 struct berval;
00091
00092 class PLDAPStructBase;
00093
00094
00097 class PLDAPSession : public PObject
00098 {
00099 PCLASSINFO(PLDAPSession, PObject);
00100 public:
00103 PLDAPSession(
00104 const PString & defaultBaseDN = PString::Empty()
00105 );
00106
00109 ~PLDAPSession();
00110
00117 BOOL Open(
00118 const PString & server,
00119 WORD port = 0
00120 );
00121
00124 BOOL Close();
00125
00128 BOOL IsOpen() const { return ldapContext != NULL; }
00129
00132 BOOL SetOption(
00133 int optcode,
00134 int value
00135 );
00136
00139 BOOL SetOption(
00140 int optcode,
00141 void * value
00142 );
00143
00144 enum AuthenticationMethod {
00145 AuthSimple,
00146 AuthSASL,
00147 AuthKerberos,
00148 #ifdef SOLARIS
00149 NumAuthenticationMethod1,
00150 NumAuthenticationMethod2
00151 #else
00152 NumAuthenticationMethod
00153 #endif
00154 };
00155
00158 BOOL Bind(
00159 const PString & who = PString::Empty(),
00160 const PString & passwd = PString::Empty(),
00161 AuthenticationMethod authMethod = AuthSimple
00162 );
00163
00164 class ModAttrib : public PObject {
00165 PCLASSINFO(ModAttrib, PObject);
00166 public:
00167 enum Operation {
00168 Add,
00169 Replace,
00170 Delete,
00171 NumOperations
00172 };
00173
00174 protected:
00175 ModAttrib(
00176 const PString & name,
00177 Operation op = NumOperations
00178 );
00179
00180 public:
00181 const PString & GetName() const { return name; }
00182
00183 Operation GetOperation() const { return op; }
00184
00185 void SetLDAPMod(
00186 struct ldapmod & mod,
00187 Operation defaultOp
00188 );
00189
00190 protected:
00191 virtual BOOL IsBinary() const = 0;
00192 virtual void SetLDAPModVars(struct ldapmod & mod) = 0;
00193
00194 PString name;
00195 Operation op;
00196 };
00197
00198 class StringModAttrib : public ModAttrib {
00199 PCLASSINFO(StringModAttrib, ModAttrib);
00200 public:
00201 StringModAttrib(
00202 const PString & name,
00203 Operation op = NumOperations
00204 );
00205 StringModAttrib(
00206 const PString & name,
00207 const PString & value,
00208 Operation op = NumOperations
00209 );
00210 StringModAttrib(
00211 const PString & name,
00212 const PStringList & values,
00213 Operation op = NumOperations
00214 );
00215 void SetValue(
00216 const PString & value
00217 );
00218 void AddValue(
00219 const PString & value
00220 );
00221 protected:
00222 virtual BOOL IsBinary() const;
00223 virtual void SetLDAPModVars(struct ldapmod & mod);
00224
00225 PStringList values;
00226 PBaseArray<char *> pointers;
00227 };
00228
00229 class BinaryModAttrib : public ModAttrib {
00230 PCLASSINFO(BinaryModAttrib, ModAttrib);
00231 public:
00232 BinaryModAttrib(
00233 const PString & name,
00234 Operation op = Add
00235 );
00236 BinaryModAttrib(
00237 const PString & name,
00238 const PBYTEArray & value,
00239 Operation op = Add
00240 );
00241 BinaryModAttrib(
00242 const PString & name,
00243 const PList<PBYTEArray> & values,
00244 Operation op = Add
00245 );
00246 void SetValue(
00247 const PBYTEArray & value
00248 );
00249 void AddValue(
00250 const PBYTEArray & value
00251 );
00252 protected:
00253 virtual BOOL IsBinary() const;
00254 virtual void SetLDAPModVars(struct ldapmod & mod);
00255
00256 PList<PBYTEArray> values;
00257 PBaseArray<struct berval *> pointers;
00258 PBYTEArray bervals;
00259 };
00260
00263 BOOL Add(
00264 const PString & dn,
00265 const PList<ModAttrib> & attributes
00266 );
00267
00270 BOOL Add(
00271 const PString & dn,
00272 const PStringToString & attributes
00273 );
00274
00278 BOOL Add(
00279 const PString & dn,
00280 const PStringArray & attributes
00281 );
00282
00286 BOOL Add(
00287 const PString & dn,
00288 const PLDAPStructBase & data
00289 );
00290
00293 BOOL Modify(
00294 const PString & dn,
00295 const PList<ModAttrib> & attributes
00296 );
00297
00300 BOOL Modify(
00301 const PString & dn,
00302 const PStringToString & attributes
00303 );
00304
00308 BOOL Modify(
00309 const PString & dn,
00310 const PStringArray & attributes
00311 );
00312
00316 BOOL Modify(
00317 const PString & dn,
00318 const PLDAPStructBase & data
00319 );
00320
00323 BOOL Delete(
00324 const PString & dn
00325 );
00326
00327
00328 enum SearchScope {
00329 ScopeBaseOnly,
00330 ScopeSingleLevel,
00331 ScopeSubTree,
00332 NumSearchScope
00333 };
00334
00335 class SearchContext {
00336 public:
00337 SearchContext();
00338 ~SearchContext();
00339
00340 BOOL IsCompleted() const { return completed; }
00341
00342 private:
00343 int msgid;
00344 struct ldapmsg * result;
00345 struct ldapmsg * message;
00346 BOOL found;
00347 BOOL completed;
00348
00349 friend class PLDAPSession;
00350 };
00351
00354 BOOL Search(
00355 SearchContext & context,
00356 const PString & filter,
00357 const PStringArray & attributes = PStringList(),
00358 const PString & base = PString::Empty(),
00359 SearchScope scope = ScopeSubTree
00360 );
00361
00364 BOOL GetSearchResult(
00365 SearchContext & context,
00366 PStringToString & data
00367 );
00368
00371 BOOL GetSearchResult(
00372 SearchContext & context,
00373 const PString & attribute,
00374 PString & data
00375 );
00376
00379 BOOL GetSearchResult(
00380 SearchContext & context,
00381 const PString & attribute,
00382 PStringArray & data
00383 );
00384
00387 BOOL GetSearchResult(
00388 SearchContext & context,
00389 const PString & attribute,
00390 PArray<PBYTEArray> & data
00391 );
00392
00395 BOOL GetSearchResult(
00396 SearchContext & context,
00397 PLDAPStructBase & data
00398 );
00399
00402 PString GetSearchResultDN(
00403 SearchContext & context
00404 );
00405
00408 BOOL GetNextSearchResult(
00409 SearchContext & context
00410 );
00411
00416 PList<PStringToString> Search(
00417 const PString & filter,
00418 const PStringArray & attributes = PStringList(),
00419 const PString & base = PString::Empty(),
00420 SearchScope scope = ScopeSubTree
00421 );
00422
00423
00426 void SetBaseDN(
00427 const PString & dn
00428 ) { defaultBaseDN = dn; }
00429
00432 const PString & GetBaseDN() const { return defaultBaseDN; }
00433
00436 int GetErrorNumber() const { return errorNumber; }
00437
00440 PString GetErrorText() const;
00441
00444 struct ldap * GetOpenLDAP() const { return ldapContext; }
00445
00448 const PTimeInterval & GetTimeout() const { return timeout; }
00449
00452 void SetTimeout(
00453 const PTimeInterval & t
00454 ) { timeout = t; }
00455
00458 void SetSearchLimit(
00459 const unsigned s
00460 ) { searchLimit = s; }
00461
00462 protected:
00463 struct ldap * ldapContext;
00464 int errorNumber;
00465 unsigned protocolVersion;
00466 PString defaultBaseDN;
00467 unsigned searchLimit;
00468 PTimeInterval timeout;
00469 PString multipleValueSeparator;
00470 };
00471
00472
00473
00474 class PLDAPStructBase;
00475
00476 class PLDAPAttributeBase : public PObject
00477 {
00478 PCLASSINFO(PLDAPAttributeBase, PObject);
00479 public:
00480 PLDAPAttributeBase(const char * name, void * pointer, PINDEX size);
00481
00482 const char * GetName() const { return name; }
00483 BOOL IsBinary() const { return pointer != NULL; }
00484
00485 virtual void Copy(const PLDAPAttributeBase & other) = 0;
00486
00487 virtual PString ToString() const;
00488 virtual void FromString(const PString & str);
00489 virtual PBYTEArray ToBinary() const;
00490 virtual void FromBinary(const PArray<PBYTEArray> & data);
00491
00492 protected:
00493 const char * name;
00494 void * pointer;
00495 PINDEX size;
00496 };
00497
00498
00499 class PLDAPStructBase : public PObject {
00500 PCLASSINFO(PLDAPStructBase, PObject);
00501 protected:
00502 PLDAPStructBase();
00503 PLDAPStructBase & operator=(const PLDAPStructBase &);
00504 PLDAPStructBase & operator=(const PStringArray & array);
00505 PLDAPStructBase & operator=(const PStringToString & dict);
00506 private:
00507 PLDAPStructBase(const PLDAPStructBase &) { }
00508
00509 public:
00510 void PrintOn(ostream & strm) const;
00511
00512 PINDEX GetNumAttributes() const { return attributes.GetSize(); }
00513 PLDAPAttributeBase & GetAttribute(PINDEX idx) const { return attributes.GetDataAt(idx); }
00514 PLDAPAttributeBase * GetAttribute(const char * name) const { return attributes.GetAt(name); }
00515
00516 void AddAttribute(PLDAPAttributeBase * var);
00517 static PLDAPStructBase & GetInitialiser() { return *PAssertNULL(initialiserInstance); }
00518
00519 protected:
00520 void EndConstructor();
00521
00522 PDictionary<PString, PLDAPAttributeBase> attributes;
00523
00524 PLDAPStructBase * initialiserStack;
00525 static PMutex initialiserMutex;
00526 static PLDAPStructBase * initialiserInstance;
00527 };
00528
00530
00531 class PLDAPSchema : public PObject
00532 {
00533 public:
00534 PLDAPSchema();
00535
00536 enum AttributeType {
00537 AttibuteUnknown = -1,
00538 AttributeString,
00539 AttributeBinary,
00540 AttributeNumeric
00541 };
00542
00543 class Attribute
00544 {
00545 public:
00546 Attribute() : m_type(AttibuteUnknown) { }
00547 Attribute(const PString & name, AttributeType type);
00548 PString m_name;
00549 AttributeType m_type;
00550 };
00551
00552 typedef std::list<Attribute> attributeList;
00553
00554 static PLDAPSchema * CreateSchema(const PString & schemaname, PPluginManager * pluginMgr = NULL);
00555 static PStringList GetSchemaNames(PPluginManager * pluginMgr = NULL);
00556 static PStringList GetSchemaFriendlyNames(const PString & schema, PPluginManager * pluginMgr = NULL);
00557
00558 void OnReceivedAttribute(const PString & attribute, const PString & value);
00559
00560 void OnSendSchema(PList<PLDAPSession::ModAttrib> & attributes,
00561 PLDAPSession::ModAttrib::Operation op=PLDAPSession::ModAttrib::Add);
00562
00563 void LoadSchema();
00564
00565 PStringList SchemaName() { return PStringList(); }
00566 virtual void AttributeList(attributeList & ) {};
00567
00568
00569 PStringList GetAttributeList();
00570 BOOL Exists(const PString & attribute);
00571
00572 BOOL SetAttribute(const PString & attribute, const PString & value);
00573 BOOL SetAttribute(const PString & attribute, const PBYTEArray & value);
00574
00575 BOOL GetAttribute(const PString & attribute, PString & value);
00576 BOOL GetAttribute(const PString & attribute, PBYTEArray & value);
00577
00578 AttributeType GetAttributeType(const PString & attribute);
00579
00580
00581 protected:
00582 typedef std::map<PString,PString> ldapAttributes;
00583 typedef std::map<PString,PBYTEArray> ldapBinAttributes;
00584
00585
00586 attributeList attributelist;
00587 ldapAttributes attributes;
00588 ldapBinAttributes binattributes;
00589 };
00590
00591
00592 template <class className> class LDAPPluginServiceDescriptor : public PDevicePluginServiceDescriptor
00593 {
00594 public:
00595 virtual PObject * CreateInstance(int ) const { return new className; }
00596 virtual PStringList GetDeviceNames(int ) const { return className::SchemaName(); }
00597 };
00598
00599 #define LDAP_Schema(name) \
00600 static LDAPPluginServiceDescriptor<##name##_schema> ##name##_schema_descriptor; \
00601 PCREATE_PLUGIN(##name##_schema, PLDAPSchema, &##name##_schema_descriptor); \
00602 PWLIB_STATIC_LOAD_PLUGIN(##name##_schema, PLDAPSchema); \
00603
00605
00606 #define PLDAP_STRUCT_BEGIN(name) \
00607 class name : public PLDAPStructBase { \
00608 public: name() { EndConstructor(); } \
00609 public: name(const name & other) { EndConstructor(); operator=(other); } \
00610 public: name(const PStringArray & array) { EndConstructor(); operator=(array); } \
00611 public: name(const PStringToString & dict) { EndConstructor(); operator=(dict); } \
00612 public: name & operator=(const name & other) { PLDAPStructBase::operator=(other); return *this; } \
00613 public: name & operator=(const PStringArray & array) { PLDAPStructBase::operator=(array); return *this; } \
00614 public: name & operator=(const PStringToString & dict) { PLDAPStructBase::operator=(dict); return *this; } \
00615 PLDAP_ATTR_INIT(name, PString, objectClass, #name);
00616
00617 #define PLDAP_ATTRIBUTE(base, type, attribute, pointer, init) \
00618 public: type attribute; \
00619 private: struct PLDAPAttr_##attribute : public PLDAPAttributeBase { \
00620 PLDAPAttr_##attribute() \
00621 : PLDAPAttributeBase(#attribute, pointer, sizeof(type)), \
00622 instance(((base &)base::GetInitialiser()).attribute) \
00623 { init } \
00624 virtual void PrintOn (ostream & s) const { s << instance; } \
00625 virtual void ReadFrom(istream & s) { s >> instance; } \
00626 virtual void Copy(const PLDAPAttributeBase & other) \
00627 { instance = ((PLDAPAttr_##attribute &)other).instance; } \
00628 type & instance; \
00629 } pldapvar_##attribute
00630
00631 #define PLDAP_ATTR_SIMP(base, type, attribute) \
00632 PLDAP_ATTRIBUTE(base, type, attribute, NULL, ;)
00633
00634 #define PLDAP_ATTR_INIT(base, type, attribute, init) \
00635 PLDAP_ATTRIBUTE(base, type, attribute, NULL, instance = init;)
00636
00637 #define PLDAP_BINATTRIB(base, type, attribute) \
00638 PLDAP_ATTRIBUTE(base, type, attribute, &((base &)base::GetInitialiser()).attribute, ;)
00639
00640 #define PLDAP_STRUCT_END() \
00641 };
00642
00643 #endif // P_LDAP
00644
00645 #endif // _PLDAP_H
00646
00647
00648