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 #ifndef _PLDAP_H
00065 #define _PLDAP_H
00066
00067 #ifdef P_USE_PRAGMA
00068 #pragma interface
00069 #endif
00070
00071 #if P_LDAP
00072
00073 #include <ptlib/sockets.h>
00074
00075
00076 struct ldap;
00077 struct ldapmsg;
00078 struct ldapmod;
00079 struct berval;
00080
00081 class PLDAPStructBase;
00082
00083
00086 class PLDAPSession : public PObject
00087 {
00088 PCLASSINFO(PLDAPSession, PObject);
00089 public:
00092 PLDAPSession(
00093 const PString & defaultBaseDN = PString::Empty()
00094 );
00095
00098 ~PLDAPSession();
00099
00106 BOOL Open(
00107 const PString & server,
00108 WORD port = 0
00109 );
00110
00113 BOOL Close();
00114
00117 BOOL IsOpen() const { return ldapContext != NULL; }
00118
00121 BOOL SetOption(
00122 int optcode,
00123 int value
00124 );
00125
00128 BOOL SetOption(
00129 int optcode,
00130 void * value
00131 );
00132
00133 enum AuthenticationMethod {
00134 AuthSimple,
00135 AuthSASL,
00136 AuthKerberos,
00137 #ifdef SOLARIS
00138 NumAuthenticationMethod1,
00139 NumAuthenticationMethod2
00140 #else
00141 NumAuthenticationMethod
00142 #endif
00143 };
00144
00147 BOOL Bind(
00148 const PString & who = PString::Empty(),
00149 const PString & passwd = PString::Empty(),
00150 AuthenticationMethod authMethod = AuthSimple
00151 );
00152
00153 class ModAttrib : public PObject {
00154 PCLASSINFO(ModAttrib, PObject);
00155 public:
00156 enum Operation {
00157 Add,
00158 Replace,
00159 Delete,
00160 NumOperations
00161 };
00162
00163 protected:
00164 ModAttrib(
00165 const PString & name,
00166 Operation op = NumOperations
00167 );
00168
00169 public:
00170 const PString & GetName() const { return name; }
00171
00172 Operation GetOperation() const { return op; }
00173
00174 void SetLDAPMod(
00175 struct ldapmod & mod,
00176 Operation defaultOp
00177 );
00178
00179 protected:
00180 virtual BOOL IsBinary() const = 0;
00181 virtual void SetLDAPModVars(struct ldapmod & mod) = 0;
00182
00183 PString name;
00184 Operation op;
00185 };
00186
00187 class StringModAttrib : public ModAttrib {
00188 PCLASSINFO(StringModAttrib, ModAttrib);
00189 public:
00190 StringModAttrib(
00191 const PString & name,
00192 Operation op = NumOperations
00193 );
00194 StringModAttrib(
00195 const PString & name,
00196 const PString & value,
00197 Operation op = NumOperations
00198 );
00199 StringModAttrib(
00200 const PString & name,
00201 const PStringList & values,
00202 Operation op = NumOperations
00203 );
00204 void SetValue(
00205 const PString & value
00206 );
00207 void AddValue(
00208 const PString & value
00209 );
00210 protected:
00211 virtual BOOL IsBinary() const;
00212 virtual void SetLDAPModVars(struct ldapmod & mod);
00213
00214 PStringList values;
00215 PBaseArray<char *> pointers;
00216 };
00217
00218 class BinaryModAttrib : public ModAttrib {
00219 PCLASSINFO(BinaryModAttrib, ModAttrib);
00220 public:
00221 BinaryModAttrib(
00222 const PString & name,
00223 Operation op = Add
00224 );
00225 BinaryModAttrib(
00226 const PString & name,
00227 const PBYTEArray & value,
00228 Operation op = Add
00229 );
00230 BinaryModAttrib(
00231 const PString & name,
00232 const PList<PBYTEArray> & values,
00233 Operation op = Add
00234 );
00235 void SetValue(
00236 const PBYTEArray & value
00237 );
00238 void AddValue(
00239 const PBYTEArray & value
00240 );
00241 protected:
00242 virtual BOOL IsBinary() const;
00243 virtual void SetLDAPModVars(struct ldapmod & mod);
00244
00245 PList<PBYTEArray> values;
00246 PBaseArray<struct berval *> pointers;
00247 PBYTEArray bervals;
00248 };
00249
00252 BOOL Add(
00253 const PString & dn,
00254 const PList<ModAttrib> & attributes
00255 );
00256
00259 BOOL Add(
00260 const PString & dn,
00261 const PStringToString & attributes
00262 );
00263
00267 BOOL Add(
00268 const PString & dn,
00269 const PStringArray & attributes
00270 );
00271
00275 BOOL Add(
00276 const PString & dn,
00277 const PLDAPStructBase & data
00278 );
00279
00282 BOOL Modify(
00283 const PString & dn,
00284 const PList<ModAttrib> & attributes
00285 );
00286
00289 BOOL Modify(
00290 const PString & dn,
00291 const PStringToString & attributes
00292 );
00293
00297 BOOL Modify(
00298 const PString & dn,
00299 const PStringArray & attributes
00300 );
00301
00305 BOOL Modify(
00306 const PString & dn,
00307 const PLDAPStructBase & data
00308 );
00309
00312 BOOL Delete(
00313 const PString & dn
00314 );
00315
00316
00317 enum SearchScope {
00318 ScopeBaseOnly,
00319 ScopeSingleLevel,
00320 ScopeSubTree,
00321 NumSearchScope
00322 };
00323
00324 class SearchContext {
00325 public:
00326 SearchContext();
00327 ~SearchContext();
00328
00329 BOOL IsCompleted() const { return completed; }
00330
00331 private:
00332 int msgid;
00333 struct ldapmsg * result;
00334 struct ldapmsg * message;
00335 BOOL found;
00336 BOOL completed;
00337
00338 friend class PLDAPSession;
00339 };
00340
00343 BOOL Search(
00344 SearchContext & context,
00345 const PString & filter,
00346 const PStringArray & attributes = PStringList(),
00347 const PString & base = PString::Empty(),
00348 SearchScope scope = ScopeSubTree
00349 );
00350
00353 BOOL GetSearchResult(
00354 SearchContext & context,
00355 PStringToString & data
00356 );
00357
00360 BOOL GetSearchResult(
00361 SearchContext & context,
00362 const PString & attribute,
00363 PString & data
00364 );
00365
00368 BOOL GetSearchResult(
00369 SearchContext & context,
00370 const PString & attribute,
00371 PStringArray & data
00372 );
00373
00376 BOOL GetSearchResult(
00377 SearchContext & context,
00378 const PString & attribute,
00379 PArray<PBYTEArray> & data
00380 );
00381
00384 BOOL GetSearchResult(
00385 SearchContext & context,
00386 PLDAPStructBase & data
00387 );
00388
00391 PString GetSearchResultDN(
00392 SearchContext & context
00393 );
00394
00397 BOOL GetNextSearchResult(
00398 SearchContext & context
00399 );
00400
00405 PList<PStringToString> Search(
00406 const PString & filter,
00407 const PStringArray & attributes = PStringList(),
00408 const PString & base = PString::Empty(),
00409 SearchScope scope = ScopeSubTree
00410 );
00411
00412
00415 void SetBaseDN(
00416 const PString & dn
00417 ) { defaultBaseDN = dn; }
00418
00421 const PString & GetBaseDN() const { return defaultBaseDN; }
00422
00425 int GetErrorNumber() const { return errorNumber; }
00426
00429 PString GetErrorText() const;
00430
00433 struct ldap * GetOpenLDAP() const { return ldapContext; }
00434
00437 const PTimeInterval & GetTimeout() const { return timeout; }
00438
00441 void SetTimeout(
00442 const PTimeInterval & t
00443 ) { timeout = t; }
00444
00447 void SetSearchLimit(
00448 const unsigned s
00449 ) { searchLimit = s; }
00450
00451 protected:
00452 struct ldap * ldapContext;
00453 int errorNumber;
00454 unsigned protocolVersion;
00455 PString defaultBaseDN;
00456 unsigned searchLimit;
00457 PTimeInterval timeout;
00458 PString multipleValueSeparator;
00459 };
00460
00461
00462
00463 class PLDAPStructBase;
00464
00465 class PLDAPAttributeBase : public PObject
00466 {
00467 PCLASSINFO(PLDAPAttributeBase, PObject);
00468 public:
00469 PLDAPAttributeBase(const char * name, void * pointer, PINDEX size);
00470
00471 const char * GetName() const { return name; }
00472 BOOL IsBinary() const { return pointer != NULL; }
00473
00474 virtual void Copy(const PLDAPAttributeBase & other) = 0;
00475
00476 virtual PString ToString() const;
00477 virtual void FromString(const PString & str);
00478 virtual PBYTEArray ToBinary() const;
00479 virtual void FromBinary(const PArray<PBYTEArray> & data);
00480
00481 protected:
00482 const char * name;
00483 void * pointer;
00484 PINDEX size;
00485 };
00486
00487
00488 class PLDAPStructBase : public PObject {
00489 PCLASSINFO(PLDAPStructBase, PObject);
00490 protected:
00491 PLDAPStructBase();
00492 PLDAPStructBase & operator=(const PLDAPStructBase &);
00493 PLDAPStructBase & operator=(const PStringArray & array);
00494 PLDAPStructBase & operator=(const PStringToString & dict);
00495 private:
00496 PLDAPStructBase(const PLDAPStructBase &) { }
00497
00498 public:
00499 void PrintOn(ostream & strm) const;
00500
00501 PINDEX GetNumAttributes() const { return attributes.GetSize(); }
00502 PLDAPAttributeBase & GetAttribute(PINDEX idx) const { return attributes.GetDataAt(idx); }
00503 PLDAPAttributeBase * GetAttribute(const char * name) const { return attributes.GetAt(name); }
00504
00505 void AddAttribute(PLDAPAttributeBase * var);
00506 static PLDAPStructBase & GetInitialiser() { return *PAssertNULL(initialiserInstance); }
00507
00508 protected:
00509 void EndConstructor();
00510
00511 PDictionary<PString, PLDAPAttributeBase> attributes;
00512
00513 PLDAPStructBase * initialiserStack;
00514 static PMutex initialiserMutex;
00515 static PLDAPStructBase * initialiserInstance;
00516 };
00517
00518
00519 #define PLDAP_STRUCT_BEGIN(name) \
00520 class name : public PLDAPStructBase { \
00521 public: name() { EndConstructor(); } \
00522 public: name(const name & other) { EndConstructor(); operator=(other); } \
00523 public: name(const PStringArray & array) { EndConstructor(); operator=(array); } \
00524 public: name(const PStringToString & dict) { EndConstructor(); operator=(dict); } \
00525 public: name & operator=(const name & other) { PLDAPStructBase::operator=(other); return *this; } \
00526 public: name & operator=(const PStringArray & array) { PLDAPStructBase::operator=(array); return *this; } \
00527 public: name & operator=(const PStringToString & dict) { PLDAPStructBase::operator=(dict); return *this; } \
00528 PLDAP_ATTR_INIT(name, PString, objectClass, #name);
00529
00530 #define PLDAP_ATTRIBUTE(base, type, attribute, pointer, init) \
00531 public: type attribute; \
00532 private: struct PLDAPAttr_##attribute : public PLDAPAttributeBase { \
00533 PLDAPAttr_##attribute() \
00534 : PLDAPAttributeBase(#attribute, pointer, sizeof(type)), \
00535 instance(((base &)base::GetInitialiser()).attribute) \
00536 { init } \
00537 virtual void PrintOn (ostream & s) const { s << instance; } \
00538 virtual void ReadFrom(istream & s) { s >> instance; } \
00539 virtual void Copy(const PLDAPAttributeBase & other) \
00540 { instance = ((PLDAPAttr_##attribute &)other).instance; } \
00541 type & instance; \
00542 } pldapvar_##attribute
00543
00544 #define PLDAP_ATTR_SIMP(base, type, attribute) \
00545 PLDAP_ATTRIBUTE(base, type, attribute, NULL, ;)
00546
00547 #define PLDAP_ATTR_INIT(base, type, attribute, init) \
00548 PLDAP_ATTRIBUTE(base, type, attribute, NULL, instance = init;)
00549
00550 #define PLDAP_BINATTRIB(base, type, attribute) \
00551 PLDAP_ATTRIBUTE(base, type, attribute, &((base &)base::GetInitialiser()).attribute, ;)
00552
00553 #define PLDAP_STRUCT_END() \
00554 };
00555
00556 #endif // P_LDAP
00557
00558 #endif // _PLDAP_H
00559
00560
00561