PTLib
Version 2.10.4
|
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: 22443 $ 00027 * $Author: rjongbloed $ 00028 * $Date: 2009-04-20 18:47:22 -0500 (Mon, 20 Apr 2009) $ 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 & obj) : PObject(obj) { } 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 & /*attrib*/) {}; 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 /*userData*/) const { return new className; } 00554 virtual PStringArray GetDeviceNames(int /*userData*/) 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 00562 00563 #define PLDAP_STRUCT_BEGIN(name) \ 00564 class name : public PLDAPStructBase { \ 00565 public: name() : PLDAPStructBase() { EndConstructor(); } \ 00566 public: name(const name & other) : PLDAPStructBase() { EndConstructor(); operator=(other); } \ 00567 public: name(const PStringArray & array) : PLDAPStructBase() { EndConstructor(); operator=(array); } \ 00568 public: name(const PStringToString & dict) : PLDAPStructBase() { EndConstructor(); operator=(dict); } \ 00569 public: name & operator=(const name & other) { PLDAPStructBase::operator=(other); return *this; } \ 00570 public: name & operator=(const PStringArray & array) { PLDAPStructBase::operator=(array); return *this; } \ 00571 public: name & operator=(const PStringToString & dict) { PLDAPStructBase::operator=(dict); return *this; } \ 00572 PLDAP_ATTR_INIT(name, PString, objectClass, #name); 00573 00574 #define PLDAP_ATTRIBUTE(base, type, attribute, pointer, init) \ 00575 public: type attribute; \ 00576 private: struct PLDAPAttr_##attribute : public PLDAPAttributeBase { \ 00577 PLDAPAttr_##attribute() \ 00578 : PLDAPAttributeBase(#attribute, pointer, sizeof(type)), \ 00579 instance(((base &)base::GetInitialiser()).attribute) \ 00580 { init } \ 00581 virtual void PrintOn (ostream & s) const { s << instance; } \ 00582 virtual void ReadFrom(istream & s) { s >> instance; } \ 00583 virtual void Copy(const PLDAPAttributeBase & other) \ 00584 { instance = ((PLDAPAttr_##attribute &)other).instance; } \ 00585 type & instance; \ 00586 } pldapvar_##attribute 00587 00588 #define PLDAP_ATTR_SIMP(base, type, attribute) \ 00589 PLDAP_ATTRIBUTE(base, type, attribute, NULL, ;) 00590 00591 #define PLDAP_ATTR_INIT(base, type, attribute, init) \ 00592 PLDAP_ATTRIBUTE(base, type, attribute, NULL, instance = init;) 00593 00594 #define PLDAP_BINATTRIB(base, type, attribute) \ 00595 PLDAP_ATTRIBUTE(base, type, attribute, &((base &)base::GetInitialiser()).attribute, ;) 00596 00597 #define PLDAP_STRUCT_END() \ 00598 }; 00599 00600 #endif // P_LDAP 00601 00602 #endif // PTLIB_PLDAP_H 00603 00604 00605 // End of file ////////////////////////////////////////////////////////////////