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 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 & ) {};
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 ) const { return new className; }
00558 virtual PStringArray GetDeviceNames(int ) 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