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